Skip to content

Commit

Permalink
Add observers that report changes better
Browse files Browse the repository at this point in the history
  • Loading branch information
ahmad-PH committed Feb 11, 2024
1 parent 34e6850 commit dd926e6
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 22 deletions.
6 changes: 6 additions & 0 deletions src/contentScript/components/App/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,12 @@ export default function App() {
tab.signature.originalTitle,
tab.signature.originalFaviconUrl
));
if (!newDocumentTitle) {
tab.restoreTitle();
}
if (!newDocumentFavicon) {
tab.restoreFavicon();
}
setIsVisible(false);
}
};
Expand Down
7 changes: 5 additions & 2 deletions src/contentScript/contentScript.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,15 @@ import log from "../log";
let uiInsertedIntoDOM = false;
let root = null;

let tabInitializationPromise = tab.initializeForMainContentScript();

async function insertUIIntoDOM() {
if (uiInsertedIntoDOM === false) {
// await tab.initializeForMainContentScript();
await tabInitializationPromise;
const rootElement = document.createElement(ROOT_TAG_NAME);
document.body.appendChild(rootElement);
root = createRoot(rootElement);
await tab.initializeForMainContentScript();
root.render(
<TabContext.Provider value={tab}>
<App/>
Expand All @@ -26,7 +29,7 @@ async function insertUIIntoDOM() {
uiInsertedIntoDOM = true;
}
}

(function initializeUIListeners() {
async function chromeListener(message, _sender, _sendResponse) {
if (message.command === COMMAND_OPEN_RENAME_DIALOG) {
Expand Down
55 changes: 54 additions & 1 deletion src/contentScript/initializationContentScript.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import bgScriptApi from "./backgroundScriptApi";
import tab from "./tab";

const log = getLogger('InitializationContentScript', 'debug');
const olog = getLogger('Observer', 'debug');

/**
* Update tab signature when the contentScript loads
Expand All @@ -29,5 +30,57 @@ const log = getLogger('InitializationContentScript', 'debug');

const newSignature = new TabSignature(title, favicon, originalTitle, originalFaviconUrl);
log.debug('setting signature to:', newSignature);
await tab.setSignature(newSignature, false, false);
// await tab.setSignature(newSignature, false, false);





// Title Observer:
let titleMutationObserver = new MutationObserver((mutations) => {
olog.debug('titleMutationObserver callback called', mutations);
mutations.forEach((mutation) => {
if (mutation.target.nodeName === 'TITLE') {
const newTitle = document.title;
olog.debug('TITLE mutation detected, newTitle:', newTitle);
}
});
});

const titleElement = document.querySelector('head > title');
// rplog.debug('title element:', titleElement)
if (titleElement) {
titleMutationObserver.observe(titleElement, { subtree: true, characterData: true, childList: true });
}

// Favicon Observer:
let faviconMutationObserver = new MutationObserver((mutations) => {
olog.debug('faviconMutationObserver callback called', mutations);
mutations.forEach((mutation) => {
if (mutation.type === 'childList' && mutation.target === document.head) {
olog.debug('Children of <head> have changed');
['addedNodes', 'removedNodes'].forEach((nodeType) => {
mutation[nodeType].forEach((node) => {
if (node.nodeName === 'LINK') {
olog.debug(nodeType + ' LINK detected:');
const newHref = node.href;
if (newHref.length > 100) {
olog.debug('LINK href:', newHref.substring(0, 40) + '...');
} else {
olog.debug('LINK href:', newHref);
}
}
});

});
}
});
});

const headElement = document.querySelector('head');
olog.debug('head element:', headElement);
if (headElement) {
faviconMutationObserver.observe(headElement, { subtree: true, childList: true, attributes: true });
}

})();
32 changes: 16 additions & 16 deletions src/contentScript/tab.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ export class Tab {
// Check if a favicon link element already exists
log.debug('setDocumentFavicon called with faviconUrl:',
faviconUrl ? faviconUrl.substring(0, 15) : faviconUrl, preserve);
if (preserve) {
this.preserveFavicon(faviconUrl);
}
let faviconLinks = document.querySelectorAll(faviconLinksCSSQuery);

faviconLinks.forEach(link => {
Expand All @@ -75,44 +78,41 @@ export class Tab {
link.rel = 'icon';
link.href = faviconUrl;
document.getElementsByTagName('head')[0].appendChild(link);

if (preserve) {
this.preserveFavicon(faviconUrl);
}
}

restoreTitle(originalTitle) {
log.debug('restoreDocumentTitle called with originalTitle:', originalTitle);
restoreTitle() {
log.debug('restoreDocumentTitle called with originalTitle:', this.signature.originalTitle);
this.disconnectTabTitlePreserver();
if (originalTitle !== document.title) {
this.setTitle(originalTitle, false);
if (this.signature.originalTitle !== document.title) {
this.setTitle(this.signature.originalTitle, false);
}
}

async restoreFavicon(originalFaviconUrl) {
log.debug('restoreDocumentFavicon called with originalFaviconUrl:', originalFaviconUrl);
async restoreFavicon() {
log.debug('restoreDocumentFavicon called with originalFaviconUrl:', this.signature.originalFaviconUrl);
this.disconnectFaviconPreserver();
if (originalFaviconUrl !== (await bgScriptApi.getFaviconUrl())) {
this.setFavicon(originalFaviconUrl, false);
if (this.signature.originalFaviconUrl !== (await bgScriptApi.getFaviconUrl())) {
this.setFavicon(this.signature.originalFaviconUrl, false);
}
}

/**
* @param {TabSignature} signature - The signature to set. If the title or favicon are not truthy,
* they will be restored to their original form.
* they will be divorced from the values shown in the chrome UI (the preservers will be disconnected).
* This will not restore them to their original values.
*/
async setSignature(signature, preserve = true, save = true) {
log.debug('setDocumentSignature called with signature:', signature);
if (signature.title) {
this.setTitle(signature.title, preserve);
} else {
this.restoreTitle(signature.originalTitle);
this.disconnectTabTitlePreserver();
}

if (signature.favicon) {
this.setFavicon(Favicon.fromDTO(signature.favicon).getUrl(), preserve);
} else {
this.restoreFavicon(signature.originalFaviconUrl);
this.disconnectFaviconPreserver();
}

if (save) {
Expand Down Expand Up @@ -144,7 +144,7 @@ export class Tab {
mutations.forEach((mutation) => {
if (mutation.target.nodeName === 'TITLE') {
const newTitle = document.title;
plog.debug('TITLE mutation detected', newTitle);
plog.debug('TITLE mutation detected', newTitle, 'while desriedTitle is:', desiredTitle);
if (newTitle !== desiredTitle) {
document.title = desiredTitle;
}
Expand Down
2 changes: 1 addition & 1 deletion src/log.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export function getLogger(name, level) {
const originalMethod = logger[method];

logger[method] = function (message, ...args) {
originalMethod.call(logger, `${name}: ${message}`, ...args);
originalMethod.call(logger, `#${name}: ${message}`, ...args);
};
});

Expand Down
20 changes: 18 additions & 2 deletions tests/e2e/seleniumTests.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ const fs = require('fs').promises;
const { DriverUtils } = require('./driverUtils.js');
const { ROOT_ELEMENT_ID, INPUT_BOX_ID, SEARCH_BAR_ID, SEARCH_RESULTS_ID } = require('../../src/config.js');

// eslint-disable-next-line no-unused-vars
const SECONDS = 1000;
// eslint-disable-next-line no-unused-vars
const MINUTES = 60 * SECONDS;

jest.setTimeout(10 * SECONDS);

describe('Selenium UI Tests', () => {
Expand Down Expand Up @@ -60,6 +64,7 @@ describe('Selenium UI Tests', () => {
if (driver) {
const logs = await driver.manage().logs().get(logging.Type.BROWSER);
const extensionPrefix = 'chrome-extension://klljeoabgpehcibnkgcfaipponlgpkfc/';
// eslint-disable-next-line no-unused-vars
const extensionLogs = logs.filter(log => (
log.message.startsWith(extensionPrefix) && log.message.includes('#')
)).map(log => log.message.replace(extensionPrefix, ''));
Expand Down Expand Up @@ -213,11 +218,13 @@ describe('Selenium UI Tests', () => {

test('Restores original favicon when empty favicon passed', async () => {
await driver.get(googleUrl);
await driver.sleep(1 * SECONDS);
// await driver.sleep(1 * SECONDS);
await driverUtils.setFavicon('🎂');
await driverUtils.removeFavicon();
// await driver.sleep(2 * SECONDS);
// await driver.sleep(20 * MINUTES);
await driverUtils.assertFaviconUrl(googleFavicon);
});
}, 30 * MINUTES);

test('Title Preserver keeps the title the same', async () => {
// This test is mainly written to emulate what Facebook does (revert the title to its original)
Expand All @@ -229,4 +236,13 @@ describe('Selenium UI Tests', () => {
const actualTitle = await driverUtils.getTitle();
expect(actualTitle).toBe('New title');
});


test("Title won't flash to the original, when switching between pages", async () => {
await driver.get(urls[0]);
await driverUtils.renameTab('New title');
await driver.sleep(5 * SECONDS);
await driver.get(urls[1]);
await driver.sleep(5 * SECONDS);
}, 100 * SECONDS);
});

0 comments on commit dd926e6

Please sign in to comment.