Add manual check before starting mutationObserver
Sometimes, when starting the mutationObserver, watched nodes have
already been added and are therefore not detected.
This change is a follow-up change to change
https://gerrit.avm99963.com/c/infinitegforums/+/1041 which fixes the
same thing for the mutationObserver at
//src/content_scripts/console_inject.js.
Bug: #21
Change-Id: I6ea3308abc10a66ef4dd2572f9e40cab9d6e4d7b
diff --git a/src/content_scripts/console_inject.js b/src/content_scripts/console_inject.js
index d39f814..5b80a38 100644
--- a/src/content_scripts/console_inject.js
+++ b/src/content_scripts/console_inject.js
@@ -175,70 +175,99 @@
clone, (readToggle.nextSibling || readToggle));
}
+function injectPreviousPostsLinks(node) {
+ var nameElement = node.querySelector('.name span');
+ if (nameElement !== null) {
+ var forumId = location.href.split('/forum/')[1].split('/')[0] || '0';
+
+ var name = escapeUsername(nameElement.textContent);
+ var query1 = encodeURIComponent(
+ '(creator:"' + name + '" | replier:"' + name + '") forum:' + forumId);
+ var query2 = encodeURIComponent(
+ '(creator:"' + name + '" | replier:"' + name + '") forum:any');
+
+ var container = document.createElement('div');
+ container.classList.add('TWPT-previous-posts');
+
+ var badge = createExtBadge();
+ container.appendChild(badge);
+
+ var linkContainer = document.createElement('div');
+ linkContainer.classList.add('TWPT-previous-posts--links');
+
+ addProfileHistoryLink(linkContainer, 'forum', query1);
+ addProfileHistoryLink(linkContainer, 'all', query2);
+
+ container.appendChild(linkContainer);
+
+ node.querySelector('.main-card-content').appendChild(container);
+ } else {
+ console.warn('[previousposts] Couldn\'t find the username element.');
+ }
+}
+
+const watchedNodesSelectors = [
+ // Load more bar (for the "load more"/"load all" buttons)
+ '.load-more-bar',
+
+ // Container inside ec-user (user profile view)
+ 'ec-user > div',
+
+ // Rich text editor
+ 'ec-movable-dialog',
+ 'ec-rich-text-editor',
+
+ // Read/unread bulk action in the list of thread, for the batch lock feature
+ 'ec-bulk-actions material-button[debugid="mark-read-button"]',
+ 'ec-bulk-actions material-button[debugid="mark-unread-button"]',
+];
+
+function handleCandidateNode(node) {
+ if (typeof node.classList !== 'undefined') {
+ // Set up the intersectionObserver for the "load more" button inside a
+ // thread
+ if (options.thread && node.classList.contains('load-more-bar')) {
+ intersectionObserver.observe(node.querySelector('.load-more-button'));
+ }
+
+ // Set up the intersectionObserver for the "load all" button inside a thread
+ if (options.threadall && node.classList.contains('load-more-bar')) {
+ intersectionObserver.observe(node.querySelector('.load-all-button'));
+ }
+
+ // Show the "previous posts" links
+ // Here we're selecting the 'ec-user > div' element (unique child)
+ if (options.history && ('parentNode' in node) && node.parentNode !== null &&
+ ('tagName' in node.parentNode) &&
+ node.parentNode.tagName == 'EC-USER') {
+ injectPreviousPostsLinks(node);
+ }
+
+ // Fix the drag&drop issue with the rich text editor
+ //
+ // We target both tags because in different contexts different
+ // elements containing the text editor get added to the DOM structure.
+ // Sometimes it's a EC-MOVABLE-DIALOG which already contains the
+ // EC-RICH-TEXT-EDITOR, and sometimes it's the EC-RICH-TEXT-EDITOR
+ // directly.
+ if (options.ccdragndropfix && ('tagName' in node) &&
+ (node.tagName == 'EC-MOVABLE-DIALOG' ||
+ node.tagName == 'EC-RICH-TEXT-EDITOR')) {
+ applyDragAndDropFix(node);
+ }
+
+ // Inject the batch lock button in the thread list
+ if (options.batchlock && nodeIsReadToggleBtn(node)) {
+ addBatchLockBtn(node);
+ }
+ }
+}
+
function mutationCallback(mutationList, observer) {
mutationList.forEach((mutation) => {
if (mutation.type == 'childList') {
mutation.addedNodes.forEach(function(node) {
- if (typeof node.classList !== 'undefined') {
- if (options.thread && node.classList.contains('load-more-bar')) {
- intersectionObserver.observe(
- node.querySelector('.load-more-button'));
- }
-
- if (options.threadall && node.classList.contains('load-more-bar')) {
- intersectionObserver.observe(
- node.querySelector('.load-all-button'));
- }
-
- if (options.history && ('parentNode' in node) &&
- node.parentNode !== null && ('tagName' in node.parentNode) &&
- node.parentNode.tagName == 'EC-USER') {
- var nameElement = node.querySelector('.name span');
- if (nameElement !== null) {
- var forumId =
- location.href.split('/forum/')[1].split('/')[0] || '0';
-
- var name = escapeUsername(nameElement.textContent);
- var query1 = encodeURIComponent(
- '(creator:"' + name + '" | replier:"' + name +
- '") forum:' + forumId);
- var query2 = encodeURIComponent(
- '(creator:"' + name + '" | replier:"' + name +
- '") forum:any');
-
- var container = document.createElement('div');
- container.classList.add('TWPT-previous-posts');
-
- var badge = createExtBadge();
- container.appendChild(badge);
-
- var linkContainer = document.createElement('div');
- linkContainer.classList.add('TWPT-previous-posts--links');
-
- addProfileHistoryLink(linkContainer, 'forum', query1);
- addProfileHistoryLink(linkContainer, 'all', query2);
-
- container.appendChild(linkContainer);
-
- node.querySelector('.main-card-content').appendChild(container);
- }
- }
-
- // We target both tags because in different contexts different
- // elements containing the text editor get added to the DOM structure.
- // Sometimes it's a EC-MOVABLE-DIALOG which already contains the
- // EC-RICH-TEXT-EDITOR, and sometimes it's the EC-RICH-TEXT-EDITOR
- // directly.
- if (options.ccdragndropfix && ('tagName' in node) &&
- (node.tagName == 'EC-MOVABLE-DIALOG' ||
- node.tagName == 'EC-RICH-TEXT-EDITOR')) {
- applyDragAndDropFix(node);
- }
-
- if (options.batchlock && nodeIsReadToggleBtn(node)) {
- addBatchLockBtn(node);
- }
- }
+ handleCandidateNode(node);
});
}
});
@@ -270,6 +299,12 @@
JSON.parse(document.querySelector('html').getAttribute('data-startup'));
authuser = startup[2][1] || '0';
+ // Before starting the mutation Observer, check whether we missed any
+ // mutations by manually checking whether some watched nodes already exist.
+ var cssSelectors = watchedNodesSelectors.join(',');
+ document.querySelectorAll(cssSelectors)
+ .forEach(node => handleCandidateNode(node));
+
mutationObserver = new MutationObserver(mutationCallback);
mutationObserver.observe(document.body, observerOptions);