var mutationObserver, intersectionObserver, intersectionOptions, options,
    authuser;

function removeChildNodes(node) {
  while (node.firstChild) {
    node.removeChild(node.firstChild);
  }
}

function getNParent(node, n) {
  if (n <= 0) return node;
  if (!('parentNode' in node)) return null;
  return getNParent(node.parentNode, n - 1);
}

function parseUrl(url) {
  var forum_a = url.match(/forum\/([0-9]+)/i);
  var thread_a = url.match(/thread\/([0-9]+)/i);

  if (forum_a === null || thread_a === null) {
    return false;
  }

  return {
    'forum': forum_a[1],
    'thread': thread_a[1],
  };
}

function createExtBadge() {
  var badge = document.createElement('div');
  badge.classList.add('TWPT-badge');
  badge.setAttribute(
      'title', chrome.i18n.getMessage('inject_extension_badge_helper', [
        chrome.i18n.getMessage('appName')
      ]));

  var badgeI = document.createElement('i');
  badgeI.classList.add('material-icon-i', 'material-icons-extended');
  badgeI.textContent = 'repeat';

  badge.append(badgeI);
  return badge;
}

function addProfileHistoryLink(node, type, query) {
  var urlpart = encodeURIComponent('query=' + query);
  var authuserpart =
      (authuser == '0' ? '' : '?authuser=' + encodeURIComponent(authuser));
  var container = document.createElement('div');
  container.style.margin = '3px 0';

  var link = document.createElement('a');
  link.setAttribute(
      'href',
      'https://support.google.com/s/community/search/' + urlpart +
          authuserpart);
  link.innerText = chrome.i18n.getMessage('inject_previousposts_' + type);

  container.appendChild(link);
  node.appendChild(container);
}

function applyDragAndDropFix(node) {
  console.debug('Adding link drag&drop fix to ', node);
  node.addEventListener('drop', e => {
    if (e.dataTransfer.types.includes('text/uri-list')) {
      e.stopImmediatePropagation();
      console.debug('Stopping link drop event propagation.');
    }
  }, true);
}

function nodeIsReadToggleBtn(node) {
  return ('tagName' in node) && node.tagName == 'MATERIAL-BUTTON' &&
      node.getAttribute('debugid') !== null &&
      (node.getAttribute('debugid') == 'mark-read-button' ||
       node.getAttribute('debugid') == 'mark-unread-button') &&
      ('parentNode' in node) && node.parentNode !== null &&
      ('parentNode' in node.parentNode) &&
      node.parentNode.querySelector('[debugid="batchlock"]') === null &&
      node.parentNode.parentNode !== null &&
      ('tagName' in node.parentNode.parentNode) &&
      node.parentNode.parentNode.tagName == 'EC-BULK-ACTIONS';
}

function injectDarkModeButton(rightControl) {
  var darkThemeSwitch = document.createElement('material-button');
  darkThemeSwitch.classList.add('TWPT-dark-theme', 'TWPT-btn--with-badge');
  darkThemeSwitch.setAttribute('button', '');
  darkThemeSwitch.setAttribute(
      'title', chrome.i18n.getMessage('inject_ccdarktheme_helper'));

  darkThemeSwitch.addEventListener('click', e => {
    chrome.storage.sync.get(null, currentOptions => {
      currentOptions.ccdarktheme_switch_status =
          !options.ccdarktheme_switch_status;
      chrome.storage.sync.set(currentOptions, _ => {
        location.reload();
      });
    });
  });

  var switchContent = document.createElement('div');
  switchContent.classList.add('content');

  var icon = document.createElement('material-icon');

  var i = document.createElement('i');
  i.classList.add('material-icon-i', 'material-icons-extended');
  i.textContent = 'brightness_4';

  icon.appendChild(i);
  switchContent.appendChild(icon);
  darkThemeSwitch.appendChild(switchContent);

  var badgeContent = createExtBadge();

  darkThemeSwitch.appendChild(badgeContent);

  rightControl.style.width =
      (parseInt(window.getComputedStyle(rightControl).width) + 58) + 'px';
  rightControl.insertAdjacentElement('afterbegin', darkThemeSwitch);
}

function addBatchLockBtn(readToggle) {
  var clone = readToggle.cloneNode(true);
  clone.setAttribute('debugid', 'batchlock');
  clone.classList.add('TWPT-btn--with-badge');
  clone.setAttribute('title', chrome.i18n.getMessage('inject_lockbtn'));
  clone.querySelector('material-icon').setAttribute('icon', 'lock');
  clone.querySelector('i.material-icon-i').textContent = 'lock';

  var badge = createExtBadge();
  clone.append(badge);

  clone.addEventListener('click', function() {
    var modal = document.querySelector('.pane[pane-id="default-1"]');

    var dialog = document.createElement('material-dialog');
    dialog.setAttribute('role', 'dialog');
    dialog.setAttribute('aria-modal', 'true');
    dialog.classList.add('TWPT-dialog');

    var header = document.createElement('header');
    header.setAttribute('role', 'presentation');
    header.classList.add('TWPT-dialog-header');

    var title = document.createElement('div');
    title.classList.add('TWPT-dialog-header--title', 'title');
    title.textContent = chrome.i18n.getMessage('inject_lockbtn');

    header.append(title);

    var main = document.createElement('main');
    main.setAttribute('role', 'presentation');
    main.classList.add('TWPT-dialog-main');

    var p = document.createElement('p');
    p.textContent = chrome.i18n.getMessage('inject_lockdialog_desc');

    main.append(p);

    dialog.append(header, main);

    var footers = [['lock', 'unlock', 'cancel'], ['reload', 'close']];

    for (var i = 0; i < footers.length; ++i) {
      var footer = document.createElement('footer');
      footer.setAttribute('role', 'presentation');
      footer.classList.add('TWPT-dialog-footer');
      footer.setAttribute('data-footer-id', i);

      if (i > 0) footer.classList.add('is-hidden');

      footers[i].forEach(action => {
        var btn = document.createElement('material-button');
        btn.setAttribute('role', 'button');
        btn.classList.add('TWPT-dialog-footer-btn');
        if (i == 1) btn.classList.add('is-disabled');

        switch (action) {
          case 'lock':
          case 'unlock':
            btn.addEventListener('click', _ => {
              if (btn.classList.contains('is-disabled')) return;
              var message = {
                action,
                prefix: 'TWPT-batchlock',
              };
              window.postMessage(message, '*');
            });
            break;

          case 'cancel':
          case 'close':
            btn.addEventListener('click', _ => {
              if (btn.classList.contains('is-disabled')) return;
              modal.classList.remove('visible');
              modal.style.display = 'none';
              removeChildNodes(modal);
            });
            break;

          case 'reload':
            btn.addEventListener('click', _ => {
              if (btn.classList.contains('is-disabled')) return;
              window.location.reload()
            });
            break;
        }

        var content = document.createElement('div');
        content.classList.add('content', 'TWPT-dialog-footer-btn--content');
        content.textContent =
            chrome.i18n.getMessage('inject_lockdialog_btn_' + action);

        btn.append(content);
        footer.append(btn);
      });

      var clear = document.createElement('div');
      clear.style.clear = 'both';

      footer.append(clear);
      dialog.append(footer);
    }

    removeChildNodes(modal);
    modal.append(dialog);
    modal.classList.add('visible', 'modal');
    modal.style.display = 'flex';
  });

  var duplicateBtn =
      readToggle.parentNode.querySelector('[debugid="mark-duplicate-button"]');
  if (duplicateBtn)
    duplicateBtn.parentNode.insertBefore(
        clone, (duplicateBtn.nextSibling || duplicateBtn));
  else
    readToggle.parentNode.insertBefore(
        clone, (readToggle.nextSibling || readToggle));
}

var avatars = {
  isFilterSetUp: false,
  privateForums: [],

  // Gets a list of private forums. If it is already cached, the cached list is
  // returned; otherwise it is also computed and cached.
  getPrivateForums() {
    return new Promise((resolve, reject) => {
      if (this.isFilterSetUp) return resolve(this.privateForums);

      if (!document.documentElement.hasAttribute('data-startup'))
        return reject('[threadListAvatars] Couldn\'t get startup data.');

      var startupData =
          JSON.parse(document.documentElement.getAttribute('data-startup'));
      var forums = startupData?.['1']?.['2'];
      if (forums === undefined)
        return reject(
            '[threadListAvatars] Couldn\'t retrieve forums from startup data.');

      for (var f of forums) {
        var forumId = f?.['2']?.['1']?.['1'];
        var forumVisibility = f?.['2']?.['18'];
        if (forumId === undefined || forumVisibility === undefined) {
          console.warn(
              '[threadListAvatars] Coudln\'t retrieve forum id and/or forum visibility for the following forum:',
              f);
          continue;
        }

        // forumVisibility's value 1 means "PUBLIC".
        if (forumVisibility != 1) this.privateForums.push(forumId);
      }

      // Forum 51488989 is marked as public but it is in fact private.
      this.privateForums.push('51488989');

      this.isFilterSetUp = true;
      return resolve(this.privateForums);
    });
  },

  // Some threads belong to private forums, and this feature will not be able to
  // get its avatars since it makes an anonymomus call to get the contents of
  // the thread.
  //
  // This function returns whether avatars should be retrieved depending on if
  // the thread belongs to a known private forum.
  shouldRetrieveAvatars(thread) {
    return this.getPrivateForums().then(privateForums => {
      return !privateForums.includes(thread.forum);
    });
  },

  // Get an array with the first |num| messages from the thread |thread|.
  getFirstMessages(thread, num = 15) {
    return CCApi(
               'ViewThread', {
                 1: thread.forum,
                 2: thread.thread,
                 // options
                 3: {
                   // pagination
                   1: {
                     2: num,  // maxNum
                   },
                   3: true,    // withMessages
                   5: true,    // withUserProfile
                   10: false,  // withPromotedMessages
                   16: false,  // withThreadNotes
                   18: true,   // sendNewThreadIfMoved
                 }
               },
               // |authentication| is false because otherwise this would mark
               // the thread as read as a side effect, and that would mark all
               // threads in the list as read.
               //
               // Due to the fact that we have to call this endpoint
               // anonymously, this means we can't retrieve information about
               // threads in private forums.
               /* authentication = */ false)
        .then(data => {
          var numMessages = data?.['1']?.['8'];
          if (numMessages == undefined)
            throw new Error(
                'Request to view thread doesn\'t include the number of messages');
          if (numMessages == 0) return [];

          var messages = data?.['1']['3'];
          if (messages == undefined)
            throw new Error(
                'numMessages was ' + numMessages +
                ' but the response didn\'t include any message.');
          return messages;
        });
  },

  // Get a list of at most |num| avatars for thread |thread|
  getVisibleAvatars(thread, num = 3) {
    return this.shouldRetrieveAvatars(thread).then(shouldRetrieve => {
      if (!shouldRetrieve) {
        console.debug('[threadListAvatars] Skipping thread', thread);
        return [];
      }

      return this.getFirstMessages(thread).then(messages => {
        var avatarUrls = [];
        for (var m of messages) {
          var url = m?.['3']?.['1']?.['2'];

          if (url === undefined) continue;
          if (!avatarUrls.includes(url)) avatarUrls.push(url);
          if (avatarUrls.length == 3) break;
        }

        return avatarUrls;
      });
    });
  },

  // Inject avatars for thread summary (thread item) |node| in a thread list.
  inject(node) {
    var header = node.querySelector(
        'ec-thread-summary .main-header .panel-description a.header');
    if (header === null) {
      console.error(
          '[threadListAvatars] Header is not present in the thread item\'s DOM.');
      return;
    }

    var thread = parseUrl(header.href);
    if (thread === false) {
      console.error('[threadListAvatars] Thread\'s link cannot be parsed.');
      return;
    }

    this.getVisibleAvatars(thread)
        .then(avatarUrls => {
          var avatarsContainer = document.createElement('div');
          avatarsContainer.classList.add('TWPT-avatars');

          var count = Math.floor(Math.random() * 4);

          for (var i = 0; i < avatarUrls.length; ++i) {
            var avatar = document.createElement('div');
            avatar.classList.add('TWPT-avatar');
            avatar.style.backgroundImage = 'url(\'' + avatarUrls[i] + '\')';
            avatarsContainer.appendChild(avatar);
          }

          header.appendChild(avatarsContainer);
        })
        .catch(err => {
          console.error(
              '[threadListAvatars] Could not retrieve avatars for thread',
              thread, err);
        });
  },
};

var autoRefresh = {
  isLookingForUpdates: false,
  isUpdatePromptShown: false,
  lastTimestamp: null,
  filter: null,
  path: null,
  snackbar: null,
  interval: null,
  firstCallTimeout: null,
  intervalMs: 3 * 60 * 1000,   // 3 minutes
  firstCallDelayMs: 3 * 1000,  // 3 seconds
  getStartupData() {
    return JSON.parse(
        document.querySelector('html').getAttribute('data-startup'));
  },
  isOrderedByTimestampDescending() {
    var startup = this.getStartupData();
    // Returns orderOptions.by == TIMESTAMP && orderOptions.desc == true
    return (
        startup?.[1]?.[1]?.[3]?.[14]?.[1] == 1 &&
        startup?.[1]?.[1]?.[3]?.[14]?.[2] == true);
  },
  getCustomFilter(path) {
    var searchRegex = /^\/s\/community\/search\/([^\/]*)/;
    var matches = path.match(searchRegex);
    if (matches !== null && matches.length > 1) {
      var search = decodeURIComponent(matches[1]);
      var params = new URLSearchParams(search);
      return params.get('query') || '';
    }

    return '';
  },
  filterHasOverride(filter, override) {
    var escapedOverride = override.replace(/([^\w\d\s])/gi, '\\$1');
    var regex = new RegExp('[^a-zA-Z0-9]?' + escapedOverride + ':');
    return regex.test(filter);
  },
  getFilter(path) {
    var query = this.getCustomFilter(path);

    // Note: This logic has been copied and adapted from the
    // _buildQuery$1$threadId function in the Community Console
    var conditions = '';
    var startup = this.getStartupData();

    // TODO(avm99963): if the selected forums are changed without reloading the
    // page, this will get the old selected forums. Fix this.
    var forums = startup?.[1]?.[1]?.[3]?.[8] ?? [];
    if (!this.filterHasOverride(query, 'forum') && forums !== null &&
        forums.length > 0)
      conditions += ' forum:(' + forums.join(' | ') + ')';

    var langs = startup?.[1]?.[1]?.[3]?.[5] ?? [];
    if (!this.filterHasOverride(query, 'lang') && langs !== null &&
        langs.length > 0)
      conditions += ' lang:(' + langs.map(l => '"' + l + '"').join(' | ') + ')';

    if (query.length !== 0 && conditions.length !== 0)
      return '(' + query + ')' + conditions;
    return query + conditions;
  },
  getLastTimestamp() {
    var APIRequestUrl = 'https://support.google.com/s/community/api/ViewForum' +
        (authuser == '0' ? '' : '?authuser=' + encodeURIComponent(authuser));

    return fetch(APIRequestUrl, {
             'headers': {
               'content-type': 'text/plain; charset=utf-8',
             },
             'body': JSON.stringify({
               1: '0',  // TODO: Change, when only a forum is selected, it
                        // should be set here
               2: {
                 1: {
                   2: 2,
                 },
                 2: {
                   1: 1,
                   2: true,
                 },
                 12: this.filter,
               },
             }),
             'method': 'POST',
             'mode': 'cors',
             'credentials': 'include',
           })
        .then(res => {
          if (res.status == 200 || res.status == 400) {
            return res.json().then(data => ({
                                     status: res.status,
                                     body: data,
                                   }));
          } else {
            throw new Error('Status code ' + res.status + ' was not expected.');
          }
        })
        .then(res => {
          if (res.status == 400) {
            throw new Error(
                res.body[4] ||
                ('Response status: 400. Error code: ' + res.body[2]));
          }

          return res.body;
        })
        .then(body => {
          var timestamp = body?.[1]?.[2]?.[0]?.[2]?.[17];
          if (timestamp === undefined)
            throw new Error(
                'Unexpected body of response (' +
                (body?.[1]?.[2]?.[0] === undefined ?
                     'no threads were returned' :
                     'the timestamp value is not present in the first thread') +
                ').');

          return timestamp;
        });
    // TODO(avm99963): Add retry mechanism (sometimes thread lists are empty,
    // but when loading the next page the thread appears).
    //
    // NOTE(avm99963): It seems like loading the first 2 threads instead of only
    // the first one fixes this (empty lists are now rarely returned).
  },
  unregister() {
    console.debug('autorefresh_list: unregistering');

    if (!this.isLookingForUpdates) return;

    window.clearTimeout(this.firstCallTimeout);
    window.clearInterval(this.interval);
    this.isUpdatePromptShown = false;
    this.isLookingForUpdates = false;
  },
  showUpdatePrompt() {
    this.snackbar.classList.remove('TWPT-hidden');
    document.title = '[!!!] ' + document.title.replace('[!!!] ', '');
    this.isUpdatePromptShown = true;
  },
  hideUpdatePrompt() {
    this.snackbar.classList.add('TWPT-hidden');
    document.title = document.title.replace('[!!!] ', '');
    this.isUpdatePromptShown = false;
  },
  injectUpdatePrompt() {
    var pane = document.createElement('div');
    pane.classList.add('TWPT-pane-for-snackbar');

    var snackbar = document.createElement('material-snackbar-panel');
    snackbar.classList.add('TWPT-snackbar');
    snackbar.classList.add('TWPT-hidden');

    var ac = document.createElement('div');
    ac.classList.add('TWPT-animation-container');

    var nb = document.createElement('div');
    nb.classList.add('TWPT-notification-bar');

    var ft = document.createElement('focus-trap');

    var content = document.createElement('div');
    content.classList.add('TWPT-focus-content-wrapper');

    var badge = createExtBadge();

    var message = document.createElement('div');
    message.classList.add('TWPT-message');
    message.textContent =
        chrome.i18n.getMessage('inject_autorefresh_list_snackbar_message');

    var action = document.createElement('div');
    action.classList.add('TWPT-action');
    action.textContent =
        chrome.i18n.getMessage('inject_autorefresh_list_snackbar_action');

    action.addEventListener('click', e => {
      this.hideUpdatePrompt();
      document.querySelector('.app-title-button').click();
    });

    content.append(badge, message, action);
    ft.append(content);
    nb.append(ft);
    ac.append(nb);
    snackbar.append(ac);
    pane.append(snackbar);
    document.getElementById('default-acx-overlay-container').append(pane);
    this.snackbar = snackbar;
  },
  checkUpdate() {
    if (location.pathname != this.path) {
      this.unregister();
      return;
    }

    if (this.isUpdatePromptShown) return;

    console.debug('Checking for update at: ', new Date());

    this.getLastTimestamp()
        .then(timestamp => {
          if (timestamp != this.lastTimestamp) this.showUpdatePrompt();
        })
        .catch(
            err => console.error(
                'Coudln\'t get last timestamp (while updating): ', err));
  },
  firstCall() {
    console.debug(
        'autorefresh_list: now performing first call to finish setup (filter: [' +
        this.filter + '])');

    if (location.pathname != this.path) {
      this.unregister();
      return;
    }

    this.getLastTimestamp()
        .then(timestamp => {
          this.lastTimestamp = timestamp;
          var checkUpdateCallback = this.checkUpdate.bind(this);
          this.interval =
              window.setInterval(checkUpdateCallback, this.intervalMs);
        })
        .catch(
            err => console.error(
                'Couldn\'t get last timestamp (while setting up): ', err));
  },
  setUp() {
    if (!this.isOrderedByTimestampDescending()) return;

    this.unregister();

    console.debug('autorefresh_list: starting set up...');

    if (this.snackbar === null) this.injectUpdatePrompt();
    this.isLookingForUpdates = true;
    this.path = location.pathname;
    this.filter = this.getFilter(this.path);

    var firstCall = this.firstCall.bind(this);
    this.firstCallTimeout = window.setTimeout(firstCall, this.firstCallDelayMs);
  },
};

function isDarkThemeOn() {
  if (!options.ccdarktheme) return false;

  if (options.ccdarktheme_mode == 'switch')
    return options.ccdarktheme_switch_status;

  return window.matchMedia &&
      window.matchMedia('(prefers-color-scheme: dark)').matches;
}

var unifiedProfilesFix = {
  checkIframe(iframe) {
    var srcRegex = /support.*\.google\.com\/profile\//;
    return srcRegex.test(iframe.src ?? '');
  },
  fixIframe(iframe) {
    console.info('[unifiedProfilesFix] Fixing unified profiles iframe');
    var url = new URL(iframe.src);
    url.searchParams.set('dark', 1);
    iframe.src = url.href;
  },
};

function injectPreviousPostsLinks(nameElement) {
  var mainCardContent = getNParent(nameElement, 3);
  if (mainCardContent === null) {
    console.error(
        '[previousposts] Couldn\'t find |.main-card-content| element.');
    return;
  }

  var forumId = location.href.split('/forum/')[1].split('/')[0] || '0';

  var nameTag =
      (nameElement.tagName == 'EC-DISPLAY-NAME-EDITOR' ?
           nameElement.querySelector('.top-section > span') ?? nameElement :
           nameElement);
  var name = escapeUsername(nameTag.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);

  mainCardContent.appendChild(container);
}

// Send a request to mark the current thread as read
function markCurrentThreadAsRead() {
  console.debug(
      '[forceMarkAsRead] %cTrying to mark a thread as read.',
      'color: #1a73e8;');

  var threadRegex =
      /\/s\/community\/?.*\/forum\/([0-9]+)\/?.*\/thread\/([0-9]+)/;

  var url = location.href;
  var matches = url.match(threadRegex);
  if (matches !== null && matches.length > 2) {
    var forumId = matches[1];
    var threadId = matches[2];

    console.debug('[forceMarkAsRead] Thread details:', {forumId, threadId});

    return CCApi(
               'ViewThread', {
                 1: forumId,
                 2: threadId,
                 // options
                 3: {
                   // pagination
                   1: {
                     2: 0,  // maxNum
                   },
                   3: false,   // withMessages
                   5: false,   // withUserProfile
                   6: true,    // withUserReadState
                   9: false,   // withRequestorProfile
                   10: false,  // withPromotedMessages
                   11: false,  // withExpertResponder
                 },
               },
               true, authuser)
        .then(thread => {
          if (thread?.[1]?.[6] === true) {
            console.debug(
                '[forceMarkAsRead] This thread is already marked as read, but marking it as read anyways.');
          }

          var lastMessageId = thread?.[1]?.[2]?.[10];

          console.debug('[forceMarkAsRead] lastMessageId is:', lastMessageId);

          if (lastMessageId === undefined)
            throw new Error(
                'Couldn\'t find lastMessageId in the ViewThread response.');

          return CCApi(
              'SetUserReadStateBulk', {
                1: [{
                  1: forumId,
                  2: threadId,
                  3: lastMessageId,
                }],
              },
              true, authuser);
        })
        .then(_ => {
          console.debug(
              '[forceMarkAsRead] %cSuccessfully set as read!',
              'color: #1e8e3e;');
        })
        .catch(err => {
          console.error(
              '[forceMarkAsRead] Error while marking current thread as read: ',
              err);
        });
  } else {
    console.error(
        '[forceMarkAsRead] Couldn\'t retrieve forumId and threadId from the current URL.',
        url);
  }
}

const watchedNodesSelectors = [
  // App container (used to set up the intersection observer and inject the dark
  // mode button)
  'ec-app',

  // Load more bar (for the "load more"/"load all" buttons)
  '.load-more-bar',

  // Username span/editor inside ec-user (user profile view)
  'ec-user .main-card .header > .name > span',
  'ec-user .main-card .header > .name > ec-display-name-editor',

  // 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"]',

  // Thread list items (used to inject the avatars)
  'li',

  // Thread list (used for the autorefresh feature)
  'ec-thread-list',

  // Unified profile iframe
  'iframe',

  // Thread component
  'ec-thread',
];

function handleCandidateNode(node) {
  if (typeof node.classList !== 'undefined') {
    if (('tagName' in node) && node.tagName == 'EC-APP') {
      // Set up the intersectionObserver
      if (typeof intersectionObserver === 'undefined') {
        var scrollableContent = node.querySelector('.scrollable-content');
        if (scrollableContent !== null) {
          intersectionOptions = {
            root: scrollableContent,
            rootMargin: '0px',
            threshold: 1.0,
          };

          intersectionObserver = new IntersectionObserver(
              intersectionCallback, intersectionOptions);
        }
      }

      // Inject the dark mode button
      if (options.ccdarktheme && options.ccdarktheme_mode == 'switch') {
        var rightControl = node.querySelector('header .right-control');
        if (rightControl !== null) injectDarkModeButton(rightControl);
      }
    }

    // Start the intersectionObserver for the "load more"/"load all" buttons
    // inside a thread
    if ((options.thread || options.threadall) &&
        node.classList.contains('load-more-bar')) {
      if (typeof intersectionObserver !== 'undefined') {
        if (options.thread)
          intersectionObserver.observe(node.querySelector('.load-more-button'));
        if (options.threadall)
          intersectionObserver.observe(node.querySelector('.load-all-button'));
      } else {
        console.warn(
            '[infinitescroll] ' +
            'The intersectionObserver is not ready yet.');
      }
    }

    // Show the "previous posts" links
    //   Here we're selecting the 'ec-user > div' element (unique child)
    if (options.history &&
        (node.matches('ec-user .main-card .header > .name > span') ||
         node.matches(
             'ec-user .main-card .header > .name > ec-display-name-editor'))) {
      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);
    }

    // Inject avatar links to threads in the thread list
    if (options.threadlistavatars && ('tagName' in node) &&
        (node.tagName == 'LI') &&
        node.querySelector('ec-thread-summary') !== null) {
      avatars.inject(node);
    }

    // Set up the autorefresh list feature
    if (options.autorefreshlist && ('tagName' in node) &&
        node.tagName == 'EC-THREAD-LIST') {
      autoRefresh.setUp();
    }

    // Redirect unified profile iframe to dark version if applicable
    if (node.tagName == 'IFRAME' && isDarkThemeOn() &&
        unifiedProfilesFix.checkIframe(node)) {
      unifiedProfilesFix.fixIframe(node);
    }

    // Force mark thread as read
    if (options.forcemarkasread && node.tagName == 'EC-THREAD') {
      markCurrentThreadAsRead();
    }
  }
}

function handleRemovedNode(node) {
  // Remove snackbar when exiting thread list view
  if (options.autorefreshlist && 'tagName' in node &&
      node.tagName == 'EC-THREAD-LIST') {
    autoRefresh.hideUpdatePrompt();
  }
}

function mutationCallback(mutationList, observer) {
  mutationList.forEach((mutation) => {
    if (mutation.type == 'childList') {
      mutation.addedNodes.forEach(function(node) {
        handleCandidateNode(node);
      });

      mutation.removedNodes.forEach(function(node) {
        handleRemovedNode(node);
      });
    }
  });
}

function intersectionCallback(entries, observer) {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      entry.target.click();
    }
  });
};

var observerOptions = {
  childList: true,
  subtree: true,
};

chrome.storage.sync.get(null, function(items) {
  options = items;

  var startup =
      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);

  if (options.fixedtoolbar) {
    injectStyles(
        'ec-bulk-actions{position: sticky; top: 0; background: var(--TWPT-primary-background, #fff); z-index: 96;}');
  }

  if (options.increasecontrast) {
    injectStyles(
        '.thread-summary.read:not(.checked){background: var(--TWPT-thread-read-background, #ecedee)!important;}');
  }

  if (options.stickysidebarheaders) {
    injectStyles(
        'material-drawer .main-header{background: var(--TWPT-drawer-background, #fff)!important; position: sticky; top: 0; z-index: 1;}');
  }

  if (options.enhancedannouncementsdot) {
    injectStylesheet(
        chrome.runtime.getURL('injections/enhanced_announcements_dot.css'));
  }

  if (options.repositionexpandthread) {
    injectStylesheet(
        chrome.runtime.getURL('injections/reposition_expand_thread.css'));
  }

  if (options.ccforcehidedrawer) {
    var drawer = document.querySelector('material-drawer');
    if (drawer !== null && drawer.classList.contains('mat-drawer-expanded')) {
      document.querySelector('.material-drawer-button').click();
    }
  }

  if (options.batchlock) {
    injectScript(chrome.runtime.getURL('injections/batchlock_inject.js'));
    injectStylesheet(chrome.runtime.getURL('injections/batchlock_inject.css'));
  }

  if (options.threadlistavatars) {
    injectStylesheet(
        chrome.runtime.getURL('injections/thread_list_avatars.css'));
  }

  if (options.autorefreshlist) {
    injectStylesheet(chrome.runtime.getURL('injections/autorefresh_list.css'));
  }
});
