FIX: Don't double-escape ampersands in Instagram URLs (#417)

FIX: Don’t double-escape ampersands in Instagram URLs (#417)

Fixes Instagram thumbnails

diff --git a/spec/fixtures/instagram.response b/spec/fixtures/instagram.response
index 626cefa..6c3d4e7 100644
--- a/spec/fixtures/instagram.response
+++ b/spec/fixtures/instagram.response
@@ -1,7 +1,7 @@
-
 <!DOCTYPE html>
 <html lang="en" class="no-js not-logged-in client-root">
-    <head><meta charset="utf-8">
+    <head>
+        <meta charset="utf-8">
         <meta http-equiv="X-UA-Compatible" content="IE=edge">
 
         <title>
@@ -10,68 +10,173 @@ National Geographic on Instagram: “Photo @ladzinski / Adorableness aside, comp
 
 
         <meta name="robots" content="noimageindex, noarchive">
+        <meta name="apple-mobile-web-app-status-bar-style" content="default">
         <meta name="mobile-web-app-capable" content="yes">
-        <meta name="theme-color" content="#000000">
-        <meta id="viewport" name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, minimum-scale=1, maximum-scale=1, viewport-fit=cover">
-
-
+        <meta name="theme-color" content="#ffffff">
+        <meta id="viewport" name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, viewport-fit=cover">
         <link rel="manifest" href="/data/manifest.json">
 
+        <link rel="preload" href="/static/bundles/metro/ConsumerUICommons.css/376c16df040f.css" as="style" type="text/css" crossorigin="anonymous" />
+<link rel="preload" href="/static/bundles/metro/ConsumerAsyncCommons.css/b89a1ccfaa6e.css" as="style" type="text/css" crossorigin="anonymous" />
+<link rel="preload" href="/static/bundles/metro/Consumer.css/aa65d84a486c.css" as="style" type="text/css" crossorigin="anonymous" />
+<link rel="preload" href="/static/bundles/metro/PostPageContainer.css/e8e152153a56.css" as="style" type="text/css" crossorigin="anonymous" />
+<link rel="preload" href="/static/bundles/metro/Vendor.js/5a56d51ae30f.js" as="script" type="text/javascript" crossorigin="anonymous" />
+<link rel="preload" href="/static/bundles/metro/en_US.js/75c323f42cee.js" as="script" type="text/javascript" crossorigin="anonymous" />
+<link rel="preload" href="/static/bundles/metro/ConsumerLibCommons.js/c278d02f018f.js" as="script" type="text/javascript" crossorigin="anonymous" />
+<link rel="preload" href="/static/bundles/metro/ConsumerUICommons.js/adadc46dad46.js" as="script" type="text/javascript" crossorigin="anonymous" />
+<link rel="preload" href="/static/bundles/metro/ConsumerAsyncCommons.js/05fde2fa93ee.js" as="script" type="text/javascript" crossorigin="anonymous" />
+<link rel="preload" href="/static/bundles/metro/Consumer.js/342978c8bbac.js" as="script" type="text/javascript" crossorigin="anonymous" />
+<link rel="preload" href="/static/bundles/metro/PostPageContainer.js/d76471f2ff47.js" as="script" type="text/javascript" crossorigin="anonymous" />
 
-          <link href="https://graph.instagram.com" rel="preconnect" crossorigin>
 
 
-
-        <link rel="preload" href="/static/bundles/base/PostPageContainer.js/16997e92e097.js" as="script" type="text/javascript" crossorigin="anonymous" />
-
         <script type="text/javascript">
         (function() {
-            var docElement = document.documentElement;
-            var classRE = new RegExp('(^|\\s)no-js(\\s|$)');
-            var className = docElement.className;
-            docElement.className = className.replace(classRE, '$1js$2');
-        })();
-        </script>
+  var docElement = document.documentElement;
+  var classRE = new RegExp('(^|\\s)no-js(\\s|$)');
+  var className = docElement.className;
+  docElement.className = className.replace(classRE, '$1js$2');
+})();
+</script>
         <script type="text/javascript">
-        (function() {
-          if ('PerformanceObserver' in window && 'PerformancePaintTiming' in window) {
-            window.__bufferedPerformance = [];
-            var ob = new PerformanceObserver(function(e) {
-              window.__bufferedPerformance.push.apply(window.__bufferedPerformance,e.getEntries());
-            });
-            ob.observe({entryTypes:['paint']});
+(function() {
+  if ('PerformanceObserver' in window && 'PerformancePaintTiming' in window) {
+    window.__bufferedPerformance = [];
+    var ob = new PerformanceObserver(function(e) {
+      window.__bufferedPerformance.push.apply(window.__bufferedPerformance,e.getEntries());
+    });
+    ob.observe({entryTypes:['paint']});
+  }
+
+  window.__bufferedErrors = [];
+  window.onerror = function(message, url, line, column, error) {
+    window.__bufferedErrors.push({
+      message: message,
+      url: url,
+      line: line,
+      column: column,
+      error: error
+    });
+    return false;
+  };
+  window.__initialData = {
+    pending: true,
+    waiting: []
+  };
+  function asyncFetchSharedData(extra) {
+    var sharedDataReq = new XMLHttpRequest();
+    sharedDataReq.onreadystatechange = function() {
+          if (sharedDataReq.readyState === 4) {
+            if(sharedDataReq.status === 200){
+              var sharedData = JSON.parse(sharedDataReq.responseText);
+              window.__initialDataLoaded(sharedData, extra);
+            }
           }
-        })();
-        </script>
-
-                <link rel="apple-touch-icon-precomposed" sizes="76x76" href="/static/images/ico/apple-touch-icon-76x76-precomposed.png/932e4d9af891.png">
-                <link rel="apple-touch-icon-precomposed" sizes="120x120" href="/static/images/ico/apple-touch-icon-120x120-precomposed.png/004705c9353f.png">
-                <link rel="apple-touch-icon-precomposed" sizes="152x152" href="/static/images/ico/apple-touch-icon-152x152-precomposed.png/82467bc9bcce.png">
-                <link rel="apple-touch-icon-precomposed" sizes="167x167" href="/static/images/ico/apple-touch-icon-167x167-precomposed.png/515cb4eeeeee.png">
-                <link rel="apple-touch-icon-precomposed" sizes="180x180" href="/static/images/ico/apple-touch-icon-180x180-precomposed.png/94fd767f257b.png">
+        }
+    sharedDataReq.open('GET', '/data/shared_data/', true);
+    sharedDataReq.send(null);
+  }
+  function notifyLoaded(item, data) {
+    item.pending = false;
+    item.data = data;
+    for (var i = 0;i < item.waiting.length; ++i) {
+      item.waiting[i].resolve(item.data);
+    }
+    item.waiting = [];
+  }
+  function notifyError(item, msg) {
+    item.pending = false;
+    item.error = new Error(msg);
+    for (var i = 0;i < item.waiting.length; ++i) {
+      item.waiting[i].reject(item.error);
+    }
+    item.waiting = [];
+  }
+  window.__initialDataLoaded = function(initialData, extraData) {
+    if (extraData) {
+      for (var key in extraData) {
+        initialData[key] = extraData[key];
+      }
+    }
+    notifyLoaded(window.__initialData, initialData);
+  };
+  window.__initialDataError = function(msg) {
+    notifyError(window.__initialData, msg);
+  };
+  window.__additionalData = {};
+  window.__pendingAdditionalData = function(paths) {
+    for (var i = 0;i < paths.length; ++i) {
+      window.__additionalData[paths[i]] = {
+        pending: true,
+        waiting: []
+      };
+    }
+  };
+  window.__additionalDataLoaded = function(path, data) {
+    if (path in window.__additionalData) {
+      notifyLoaded(window.__additionalData[path], data);
+    } else {
+      console.error('Unexpected additional data loaded "' + path + '"');
+    }
+  };
+  window.__additionalDataError = function(path, msg) {
+    if (path in window.__additionalData) {
+      notifyError(window.__additionalData[path], msg);
+    } else {
+      console.error('Unexpected additional data encountered an error "' + path + '": ' + msg);
+    }
+  };
+
+})();
+</script><script type="text/javascript">
+
+/*
+ Copyright 2018 Google Inc. All Rights Reserved.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software

[... diff too long, it was truncated ...]

GitHub sha: 0bf1ccd8