瀏覽代碼

fix(options): fix Firefox path issues

Firefox will decode slashes in URL automatically, which breaks confirm page.
Gerald 8 年之前
父節點
當前提交
cfd5142431

+ 6 - 4
src/background/requests.js

@@ -191,7 +191,7 @@ browser.webRequest.onBeforeSendHeaders.addListener(function (details) {
 
 browser.webRequest.onBeforeRequest.addListener(function (req) {
   // onBeforeRequest is fired for local files too
-  if (/\.user\.js([\?#]|$)/.test(req.url)) {
+  if (req.method === 'GET' && /\.user\.js([\?#]|$)/.test(req.url)) {
     // {cancel: true} will redirect to a blocked view
     var noredirect = {redirectUrl: 'javascript:history.back()'};
     var x = new XMLHttpRequest();
@@ -204,10 +204,12 @@ browser.webRequest.onBeforeRequest.addListener(function (req) {
     }
     if ((!x.status || x.status == 200) && !/^\s*</.test(x.responseText)) {
       cache.set(req.url, x.responseText);
-      var url = browser.runtime.getURL('/options/index.html') + '#confirm/' + encodeURIComponent(req.url);
+      // Firefox: slashes are decoded automatically by Firefox, thus cannot be
+      // used as separators
+      var url = browser.runtime.getURL('/options/index.html') + '#confirm?u=' + encodeURIComponent(req.url);
       if (req.tabId < 0) browser.tabs.create({url: url});
       else browser.tabs.get(req.tabId).then(function (tab) {
-        browser.tabs.create({url: url + '/' + encodeURIComponent(tab.url)});
+        browser.tabs.create({url: url + '&f=' + encodeURIComponent(tab.url)});
       });
       return noredirect;
     }
@@ -215,7 +217,7 @@ browser.webRequest.onBeforeRequest.addListener(function (req) {
 }, {
   urls: ['<all_urls>'],
   types: ['main_frame'],
-}, ['blocking', 'requestBody']);
+}, ['blocking']);
 
 module.exports = {
   getRequestId: getRequestId,

+ 30 - 24
src/options/app.js

@@ -38,21 +38,31 @@ function initMain() {
     },
   });
 }
+function parseLocation(pathInfo) {
+  var parts = pathInfo.split('?');
+  var path = parts[0];
+  var query = (parts[1] || '').split('&').reduce(function (res, seq) {
+    if (seq) {
+      var parts = seq.split('=');
+      res[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]);
+    }
+    return res;
+  }, {});
+  return {path: path, query: query};
+}
 function loadHash() {
-  var hash = location.hash.slice(1);
-  Object.keys(routes).find(function (key) {
-    var test = routes[key];
-    var params = test(hash);
-    if (params) {
-      hashData.type = key;
-      hashData.params = params;
-      if (init[key]) {
-        init[key]();
-        init[key] = null;
-      }
-      return true;
+  var loc = parseLocation(location.hash.slice(1));
+  var route = routes[loc.path];
+  if (route) {
+    hashData.type = route.key;
+    hashData.params = loc.query;
+    if (route.init) {
+      route.init();
+      route.init = null;
     }
-  });
+  } else {
+    location.hash = '';
+  }
 }
 function initCustomCSS() {
   var style;
@@ -80,18 +90,14 @@ var store = Object.assign(utils.store, {
   scripts: [],
   sync: [],
 });
-var init = {
-  Main: initMain,
-};
 var routes = {
-  Main: utils.routeTester([
-    '',
-    'main/:tab',
-  ]),
-  Confirm: utils.routeTester([
-    'confirm/:url',
-    'confirm/:url/:referer',
-  ]),
+  '': {
+    key: 'Main',
+    init: initMain,
+  },
+  confirm: {
+    key: 'Confirm',
+  },
 };
 var hashData = {
   type: null,

+ 0 - 28
src/options/utils/index.js

@@ -1,31 +1,3 @@
-function routeTester(paths) {
-  var routes = paths.map(function (path) {
-    var names = [];
-    path = path.replace(/:(\w+)/g, function (_param, name) {
-      names.push(name);
-      return '([^/]+)';
-    });
-    return {
-      re: new RegExp('^' + path + '$'),
-      names: names,
-    };
-  });
-  return function (url) {
-    var length = routes.length;
-    for (var i = 0; i < length; i ++) {
-      var route = routes[i];
-      var matches = url.match(route.re);
-      if (matches) {
-        return route.names.reduce(function (params, name, i) {
-          params[name] = decodeURIComponent(matches[i + 1]);
-          return params;
-        }, {});
-      }
-    }
-  };
-}
-
-exports.routeTester = routeTester;
 exports.store = {};
 exports.features = require('./features');
 

+ 4 - 4
src/options/views/confirm.js

@@ -34,7 +34,7 @@ module.exports = {
   },
   computed: {
     isLocal: function () {
-      return /^file:\/\/\//.test(this.params.url);
+      return /^file:\/\/\//.test(this.params.u);
     },
   },
   mounted: function () {
@@ -49,7 +49,7 @@ module.exports = {
       var _this = this;
       _this.installable = false;
       var oldCode = _this.code;
-      return _this.getScript(_this.params.url)
+      return _this.getScript(_this.params.u)
       .then(function (code) {
         if (changedOnly && oldCode === code) return Promise.reject();
         _this.code = code;
@@ -156,8 +156,8 @@ module.exports = {
       _.sendMessage({
         cmd:'ParseScript',
         data:{
-          url: _this.params.url,
-          from: _this.params.referer,
+          url: _this.params.u,
+          from: _this.params.f,
           code: _this.code,
           require: _this.require,
           resources: _this.resources,

+ 3 - 3
src/options/views/main.html

@@ -4,11 +4,11 @@
     <h1 v-text="i18n('extName')"></h1>
     <hr>
     <div class=sidemenu>
-      <a href="#main/Installed" :class="{active:tab==='Main'}" v-text="i18n('sideMenuInstalled')"></a>
-      <a href="#main/Settings" :class="{active:tab==='Settings'}" v-feature="'settings'">
+      <a href="#?t=Installed" :class="{active:tab==='Main'}" v-text="i18n('sideMenuInstalled')"></a>
+      <a href="#?t=Settings" :class="{active:tab==='Settings'}" v-feature="'settings'">
         <span v-text="i18n('sideMenuSettings')" class="feature-text"></span>
       </a>
-      <a href="#main/About" :class="{active:tab==='About'}" v-text="i18n('sideMenuAbout')"></a>
+      <a href="#?t=About" :class="{active:tab==='About'}" v-text="i18n('sideMenuAbout')"></a>
     </div>
   </aside>
   <component :is="tab"></component>

+ 1 - 1
src/options/views/main.js

@@ -15,7 +15,7 @@ module.exports = {
   components: components,
   computed: {
     tab: function () {
-      var tab = this.params.tab;
+      var tab = this.params.t;
       if (!components[tab]) tab = 'Main';
       return tab;
     },

+ 1 - 1
src/options/views/tab-installed.js

@@ -43,7 +43,7 @@ module.exports = {
       var url = prompt(_.i18n('hintInputURL'));
       if (url && ~url.indexOf('://')) {
         browser.tabs.create({
-          url: browser.runtime.getURL('/options/index.html') + '#confirm/' + encodeURIComponent(url),
+          url: browser.runtime.getURL(browser.runtime.getManifest().options_page) + '#confirm?u=' + encodeURIComponent(url),
         });
       }
     },