Browse Source

Merge branch 'feature-hashurls'

n1474335 8 years ago
parent
commit
d8051ce9a2
4 changed files with 50 additions and 29 deletions
  1. 31 0
      src/core/Utils.js
  2. 13 24
      src/web/App.js
  3. 5 4
      src/web/ControlsWaiter.js
  4. 1 1
      src/web/static/ga.html

+ 31 - 0
src/core/Utils.js

@@ -981,6 +981,37 @@ const Utils = {
     },
 
 
+    /**
+     * Parses URI parameters into a JSON object.
+     *
+     * @param {string} paramStr - The serialised query or hash section of a URI
+     * @returns {object}
+     *
+     * @example
+     * // returns {a: 'abc', b: '123'}
+     * Utils.parseURIParams("?a=abc&b=123")
+     * Utils.parseURIParams("#a=abc&b=123")
+     */
+    parseURIParams: function(paramStr) {
+        if (paramStr === "") return {};
+
+        // Cut off ? or # and split on &
+        const params = paramStr.substr(1).split("&");
+
+        const result = {};
+        for (let i = 0; i < params.length; i++) {
+            const param = params[i].split("=");
+            if (param.length !== 2) {
+                result[params[i]] = true;
+            } else {
+                result[param[0]] = decodeURIComponent(param[1].replace(/\+/g, " "));
+            }
+        }
+
+        return result;
+    },
+
+
     /**
      * Actual modulo function, since % is actually the remainder function in JS.
      *

+ 13 - 24
src/web/App.js

@@ -399,39 +399,28 @@ App.prototype.addFavourite = function(name) {
  * Checks for input and recipe in the URI parameters and loads them if present.
  */
 App.prototype.loadURIParams = function() {
-    // Load query string from URI
-    this.queryString = (function(a) {
-        if (a === "") return {};
-        const b = {};
-        for (let i = 0; i < a.length; i++) {
-            const p = a[i].split("=");
-            if (p.length !== 2) {
-                b[a[i]] = true;
-            } else {
-                b[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " "));
-            }
-        }
-        return b;
-    })(window.location.search.substr(1).split("&"));
+    // Load query string or hash from URI (depending on which is populated)
+    const params = window.location.search || window.location.hash;
+    this.uriParams = Utils.parseURIParams(params);
 
     // Pause auto-bake while loading but don't modify `this.autoBake_`
     // otherwise `manualBake` cannot trigger.
     this.autoBakePause = true;
 
-    // Read in recipe from query string
-    if (this.queryString.recipe) {
+    // Read in recipe from URI params
+    if (this.uriParams.recipe) {
         try {
-            const recipeConfig = JSON.parse(this.queryString.recipe);
+            const recipeConfig = JSON.parse(this.uriParams.recipe);
             this.setRecipeConfig(recipeConfig);
         } catch (err) {}
-    } else if (this.queryString.op) {
+    } else if (this.uriParams.op) {
         // If there's no recipe, look for single operations
         this.manager.recipe.clearRecipe();
         try {
-            this.manager.recipe.addOperation(this.queryString.op);
+            this.manager.recipe.addOperation(this.uriParams.op);
         } catch (err) {
             // If no exact match, search for nearest match and add that
-            const matchedOps = this.manager.ops.filterOperations(this.queryString.op, false);
+            const matchedOps = this.manager.ops.filterOperations(this.uriParams.op, false);
             if (matchedOps.length) {
                 this.manager.recipe.addOperation(matchedOps[0].name);
             }
@@ -439,15 +428,15 @@ App.prototype.loadURIParams = function() {
             // Populate search with the string
             const search = document.getElementById("search");
 
-            search.value = this.queryString.op;
+            search.value = this.uriParams.op;
             search.dispatchEvent(new Event("search"));
         }
     }
 
-    // Read in input data from query string
-    if (this.queryString.input) {
+    // Read in input data from URI params
+    if (this.uriParams.input) {
         try {
-            const inputData = Utils.fromBase64(this.queryString.input);
+            const inputData = Utils.fromBase64(this.uriParams.input);
             this.setInput(inputData);
         } catch (err) {}
     }

+ 5 - 4
src/web/ControlsWaiter.js

@@ -174,20 +174,21 @@ ControlsWaiter.prototype.generateStateUrl = function(includeRecipe, includeInput
     const inputStr = Utils.toBase64(this.app.getInput(), "A-Za-z0-9+/"); // B64 alphabet with no padding
 
     includeRecipe = includeRecipe && (recipeConfig.length > 0);
-    includeInput = includeInput && (inputStr.length > 0) && (inputStr.length < 8000);
+    // Only inlcude input if it is less than 50KB (51200 * 4/3 as it is Base64 encoded)
+    includeInput = includeInput && (inputStr.length > 0) && (inputStr.length <= 68267);
 
     const params = [
         includeRecipe ? ["recipe", recipeStr] : undefined,
         includeInput ? ["input", inputStr] : undefined,
     ];
 
-    const query = params
+    const hash = params
        .filter(v => v)
        .map(([key, value]) => `${key}=${encodeURIComponent(value)}`)
        .join("&");
 
-    if (query) {
-        return `${link}?${query}`;
+    if (hash) {
+        return `${link}#${hash}`;
     }
 
     return link;

+ 1 - 1
src/web/static/ga.html

@@ -9,7 +9,7 @@
 
   ga('create', 'UA-85682716-2', 'auto');
 
-  // Specifying location.pathname here overrides the default URL which would include arguments.
+  // Specifying location.pathname here overrides the default URL which could include arguments.
   // This method prevents Google Analytics from logging any recipe or input data in the URL.
   ga('send', 'pageview', location.pathname);