Browse Source

feat: add `@noframes` support

close #263
Gerald 8 years ago
parent
commit
bcefb3adaa

+ 2 - 2
src/background/utils/db.js

@@ -1,6 +1,6 @@
-import { i18n, request, buffer2string, getFullUrl } from 'src/common';
+import { i18n, request, buffer2string, getFullUrl, isRemote } from 'src/common';
 import { objectGet, objectSet } from 'src/common/object';
-import { getNameURI, isRemote, parseMeta, newScript } from './script';
+import { getNameURI, parseMeta, newScript } from './script';
 import { testScript, testBlacklist } from './tester';
 import { register } from './init';
 import patchDB from './patch-db';

+ 41 - 22
src/background/utils/script.js

@@ -1,5 +1,3 @@
-export { isRemote } from 'src/common';
-
 const metaStart = '==UserScript==';
 const metaEnd = '==/UserScript==';
 
@@ -9,17 +7,43 @@ export function isUserScript(text) {
   return true;
 }
 
+const arrayType = {
+  default: () => [],
+  transform: (res, val) => {
+    res.push(val);
+    return res;
+  },
+};
+const defaultType = {
+  default: () => null,
+  transform: (res, val) => (res == null ? val : res),
+};
+const metaTypes = {
+  include: arrayType,
+  exclude: arrayType,
+  match: arrayType,
+  excludeMatch: arrayType,
+  require: arrayType,
+  resource: {
+    default: () => ({}),
+    transform: (res, val) => {
+      const pair = val.match(/^(\w\S*)\s+(.*)/);
+      if (pair) res[pair[1]] = pair[2];
+      return res;
+    },
+  },
+  grant: arrayType,
+  noframes: {
+    default: () => false,
+    transform: () => true,
+  },
+};
 export function parseMeta(code) {
-  // initialize meta, specify those with multiple values allowed
-  const meta = {
-    include: [],
-    exclude: [],
-    match: [],
-    excludeMatch: [],
-    require: [],
-    resource: [],
-    grant: [],
-  };
+  // initialize meta
+  const meta = Object.keys(metaTypes)
+  .reduce((res, key) => Object.assign(res, {
+    [key]: metaTypes[key].default(),
+  }), {});
   let flag = -1;
   code.replace(/(?:^|\n)\/\/\s*([@=]\S+)(.*)/g, (_match, group1, group2) => {
     if (flag < 0 && group1 === metaStart) {
@@ -34,18 +58,13 @@ export function parseMeta(code) {
       const camelKey = keyName.replace(/[-_](\w)/g, (m, g) => g.toUpperCase());
       const key = locale ? `${camelKey}:${locale.toLowerCase()}` : camelKey;
       const val = group2.trim();
-      const data = meta[key];
-      // multiple values allowed
-      if (data && data.push) data.push(val);
-      // only first value will be stored
-      else if (!(key in meta)) meta[key] = val;
+      const metaType = metaTypes[key] || defaultType;
+      let oldValue = meta[key];
+      if (typeof oldValue === 'undefined') oldValue = metaType.default();
+      meta[key] = metaType.transform(oldValue, val);
     }
   });
-  meta.resources = {};
-  meta.resource.forEach(line => {
-    const pair = line.match(/^(\w\S*)\s+(.*)/);
-    if (pair) meta.resources[pair[1]] = pair[2];
-  });
+  meta.resources = meta.resource;
   delete meta.resource;
   // @homepageURL: compatible with @homepage
   if (!meta.homepageURL && meta.homepage) meta.homepageURL = meta.homepage;

+ 8 - 7
src/injected/content/index.js

@@ -56,24 +56,25 @@ export default function initialize(contentId, webId) {
 
   return sendMessage({ cmd: 'GetInjected', data: window.location.href })
   .then(data => {
-    let needInject = false;
     if (data.scripts) {
-      data.scripts.forEach(script => {
+      data.scripts = data.scripts.filter(script => {
         ids.push(script.props.id);
-        if (script.config.enabled) {
+        if ((IS_TOP || !script.meta.noframes) && script.config.enabled) {
           badge.number += 1;
-          needInject = true;
+          return true;
         }
+        return false;
       });
     }
+    badge.ready = true;
+    getPopup();
+    setBadge();
+    const needInject = data.scripts && data.scripts.length;
     if (needInject) {
       bridge.ready.then(() => {
         bridge.post({ cmd: 'LoadScripts', data });
       });
     }
-    badge.ready = true;
-    getPopup();
-    setBadge();
     return needInject;
   });
 }

+ 6 - 8
src/injected/web/index.js

@@ -90,14 +90,12 @@ function onLoadScripts(data) {
   };
   if (data.scripts) {
     forEach(data.scripts, script => {
-      if (script && script.config.enabled) {
-        // XXX: use camelCase since v2.6.3
-        const runAt = script.custom.runAt || script.custom['run-at']
-          || script.meta.runAt || script.meta['run-at'];
-        const list = listMap[runAt] || end;
-        list.push(script);
-        store.values[script.props.id] = data.values[script.props.id];
-      }
+      // XXX: use camelCase since v2.6.3
+      const runAt = script.custom.runAt || script.custom['run-at']
+        || script.meta.runAt || script.meta['run-at'];
+      const list = listMap[runAt] || end;
+      list.push(script);
+      store.values[script.props.id] = data.values[script.props.id];
     });
     run(start);
   }