Browse Source

feat: cache script info on confirm

Gerald 8 years ago
parent
commit
805eca3f50

+ 6 - 3
src/background/app.js

@@ -1,7 +1,7 @@
 import { i18n, defaultImage } from 'src/common';
 import * as sync from './sync';
 import { getRequestId, httpRequest, abortRequest } from './utils/requests';
-import { getCache } from './utils/cache';
+import cache from './utils/cache';
 import { newScript, parseMeta } from './utils/script';
 import { setClipboard } from './utils/clipboard';
 import { getOption, setOption, hookOptions, getAllOptions } from './utils/options';
@@ -152,8 +152,11 @@ const commands = {
   SyncAuthorize: sync.authorize,
   SyncRevoke: sync.revoke,
   SyncStart: sync.sync,
-  GetFromCache(data) {
-    return getCache(data) || null;
+  CacheLoad(data) {
+    return cache.get(data) || null;
+  },
+  CacheHit(data) {
+    cache.hit(data.key, data.lifetime);
   },
   Notification(data) {
     return browser.notifications.create({

+ 3 - 4
src/background/utils/cache.js

@@ -1,6 +1,5 @@
 import initCache from 'src/common/cache';
 
-const cache = initCache();
-
-export const getCache = cache.get;
-export const setCache = cache.set;
+export default initCache({
+  lifetime: 10 * 1000,
+});

+ 13 - 9
src/background/utils/requests.js

@@ -1,5 +1,5 @@
 import { getUniqId } from 'src/common';
-import { setCache } from './cache';
+import cache from './cache';
 
 const requests = {};
 const verify = {};
@@ -209,17 +209,21 @@ browser.webRequest.onBeforeRequest.addListener(req => {
       return;
     }
     if ((!x.status || x.status === 200) && !/^\s*</.test(x.responseText)) {
-      setCache(req.url, x.responseText);
+      cache.put(req.url, x.responseText, 3000);
+      const confirmInfo = {
+        url: req.url,
+      };
+      const confirmKey = getUniqId();
       // Firefox: slashes are decoded automatically by Firefox, thus cannot be
       // used as separators
       const optionsURL = browser.runtime.getURL(browser.runtime.getManifest().options_page);
-      const url = `${optionsURL}#confirm?u=${encodeURIComponent(req.url)}`;
-      if (req.tabId < 0) browser.tabs.create({ url });
-      else {
-        browser.tabs.get(req.tabId).then(tab => {
-          browser.tabs.create({ url: `${url}&f=${encodeURIComponent(tab.url)}` });
-        });
-      }
+      const url = `${optionsURL}#confirm?id=${confirmKey}`;
+      (req.tabId < 0 ? Promise.resolve() : browser.tabs.get(req.tabId))
+      .then(tab => {
+        confirmInfo.from = tab && tab.url;
+        cache.put(`confirm-${confirmKey}`, confirmInfo);
+        browser.tabs.create({ url });
+      });
       return noredirect;
     }
   }

+ 11 - 6
src/common/cache.js

@@ -1,19 +1,21 @@
+const defaults = {
+  lifetime: 3000,
+};
+
 export default function initCache(options) {
   const cache = {};
-  const { lifetime: defaultLifetime } = options || {
-    lifetime: 3000,
-  };
-  return { get, put, del, has };
+  const { lifetime: defaultLifetime } = options || defaults;
+  return { get, put, del, has, hit };
   function get(key, def) {
     const item = cache[key];
     return item ? item.value : def;
   }
-  function put(key, value, lifetime = defaultLifetime) {
+  function put(key, value, lifetime) {
     del(key);
     if (value) {
       cache[key] = {
         value,
-        timer: lifetime > 0 && setTimeout(del, lifetime, key),
+        timer: setTimeout(del, lifetime || defaultLifetime, key),
       };
     }
   }
@@ -27,4 +29,7 @@ export default function initCache(options) {
   function has(key) {
     return !!cache[key];
   }
+  function hit(key, lifetime) {
+    put(key, get(key), lifetime);
+  }
 }

+ 41 - 7
src/options/views/confirm.vue

@@ -20,7 +20,7 @@
         <button v-text="i18n('buttonClose')" @click="close"></button>
       </div>
       <h1><span v-text="i18n('labelInstall')"></span> - <span v-text="i18n('extName')"></span></h1>
-      <div class="ellipsis confirm-url" :title="query.u" v-text="query.u"></div>
+      <div class="ellipsis confirm-url" :title="info.url" v-text="info.url"></div>
       <div class="ellipsis confirm-msg" v-text="message"></div>
     </div>
     <div class="frame-block flex-auto p-rel">
@@ -63,6 +63,7 @@ export default {
       commands: {
         cancel: this.close,
       },
+      info: {},
     };
   },
   computed: {
@@ -70,18 +71,51 @@ export default {
       return this.store.route.query;
     },
     isLocal() {
-      return /^file:\/\/\//.test(this.query.u);
+      return /^file:\/\/\//.test(this.info.url);
     },
   },
   mounted() {
     this.message = this.i18n('msgLoadingData');
-    this.loadData().then(this.parseMeta);
+    this.loadInfo()
+    .then(() => {
+      const id = this.store.route.query.id;
+      this.guard = setInterval(() => {
+        sendMessage({
+          cmd: 'CacheHit',
+          data: {
+            key: `confirm-${id}`,
+          },
+        });
+      }, 5000);
+    }, () => {
+      this.close();
+      return Promise.reject();
+    })
+    .then(this.loadData)
+    .then(this.parseMeta);
+  },
+  beforeDestroy() {
+    if (this.guard) {
+      clearInterval(this.guard);
+      this.guard = null;
+    }
   },
   methods: {
+    loadInfo() {
+      const id = this.store.route.query.id;
+      return sendMessage({
+        cmd: 'CacheLoad',
+        data: `confirm-${id}`,
+      })
+      .then(info => {
+        if (!info) return Promise.reject();
+        this.info = info;
+      });
+    },
     loadData(changedOnly) {
       this.installable = false;
       const { code: oldCode } = this;
-      return this.getScript(this.query.u)
+      return this.getScript(this.info.url)
       .then(code => {
         if (changedOnly && oldCode === code) return Promise.reject();
         this.code = code;
@@ -160,7 +194,7 @@ export default {
     },
     getScript(url) {
       return sendMessage({
-        cmd: 'GetFromCache',
+        cmd: 'CacheLoad',
         data: url,
       })
       .then(text => text || Promise.reject())
@@ -180,8 +214,8 @@ export default {
         cmd: 'ParseScript',
         data: {
           code: this.code,
-          url: this.query.u,
-          from: this.query.f,
+          url: this.info.url,
+          from: this.info.from,
           require: this.require,
           resources: this.resources,
         },