Improve intersectionObserver reliability

This change adds the initialization of the intersectionObserver via the
mutationObserver if the |.scrollable-content| element doesn't exist yet
when the script is loaded.

Bug: #21
Change-Id: Id75f7e326f705e21e5e6f4ddccedaf86064c9595
diff --git a/src/content_scripts/console_inject.js b/src/content_scripts/console_inject.js
index 8d79277..ab0abca 100644
--- a/src/content_scripts/console_inject.js
+++ b/src/content_scripts/console_inject.js
@@ -1,4 +1,5 @@
-var mutationObserver, intersectionObserver, options, authuser;
+var mutationObserver, intersectionObserver, intersectionOptions, options,
+    authuser;
 
 function removeChildNodes(node) {
   while (node.firstChild) {
@@ -215,6 +216,9 @@
 }
 
 const watchedNodesSelectors = [
+  // App container (used to set up the intersection observer)
+  'ec-app',
+
   // Load more bar (for the "load more"/"load all" buttons)
   '.load-more-bar',
 
@@ -232,15 +236,33 @@
 
 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
+    if (typeof intersectionObserver === 'undefined' && ('tagName' in node) &&
+        node.tagName == 'EC-APP') {
+      intersectionOptions = {
+        root: node.querySelector('.scrollable-content'),
+        rootMargin: '0px',
+        threshold: 1.0,
+      };
+
+      intersectionObserver =
+          new IntersectionObserver(intersectionCallback, intersectionOptions);
     }
 
-    // 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'));
+    // 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
@@ -291,12 +313,6 @@
 var observerOptions = {
   childList: true,
   subtree: true,
-}
-
-var intersectionOptions = {
-  root: document.querySelector('.scrollable-content'),
-  rootMargin: '0px',
-  threshold: 1.0,
 };
 
 chrome.storage.sync.get(null, function(items) {
@@ -307,7 +323,8 @@
   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.
+  // mutations by manually checking whether some watched nodes already
+  // exist.
   var cssSelectors = watchedNodesSelectors.join(',');
   document.querySelectorAll(cssSelectors)
       .forEach(node => handleCandidateNode(node));
@@ -315,9 +332,6 @@
   mutationObserver = new MutationObserver(mutationCallback);
   mutationObserver.observe(document.body, observerOptions);
 
-  intersectionObserver =
-      new IntersectionObserver(intersectionCallback, intersectionOptions);
-
   if (options.fixedtoolbar) {
     injectStyles(
         'ec-bulk-actions{position: sticky; top: 0; background: var(--TWPT-primary-background, #fff); z-index: 96;}');