Przeglądaj źródła

fix: transform `custom._*` fields, add `custom.excludeMatch`

Gerald 8 lat temu
rodzic
commit
44b309f121

+ 25 - 3
src/background/utils/db.js

@@ -53,6 +53,25 @@ function openDatabase() {
   });
   });
 }
 }
 
 
+function transformScript(script) {
+  // XXX transform custom fields used in v2.6.1-
+  if (script) {
+    const { custom } = script;
+    [
+      ['origInclude', '_include'],
+      ['origMatch', '_match'],
+      ['origExclude', '_exclude'],
+      ['origExcludeMatch', '_excludeMatch'],
+    ].forEach(([key, oldKey]) => {
+      if (typeof custom[key] === 'undefined') {
+        custom[key] = custom[oldKey] !== false;
+        delete custom[oldKey];
+      }
+    });
+  }
+  return script;
+}
+
 export function getScript(id, cTx) {
 export function getScript(id, cTx) {
   const tx = cTx || db.transaction('scripts');
   const tx = cTx || db.transaction('scripts');
   const os = tx.objectStore('scripts');
   const os = tx.objectStore('scripts');
@@ -60,7 +79,8 @@ export function getScript(id, cTx) {
     os.get(id).onsuccess = e => {
     os.get(id).onsuccess = e => {
       resolve(e.target.result);
       resolve(e.target.result);
     };
     };
-  });
+  })
+  .then(transformScript);
 }
 }
 
 
 export function queryScript(id, meta, cTx) {
 export function queryScript(id, meta, cTx) {
@@ -71,7 +91,8 @@ export function queryScript(id, meta, cTx) {
     tx.objectStore('scripts').index('uri').get(uri).onsuccess = e => {
     tx.objectStore('scripts').index('uri').get(uri).onsuccess = e => {
       resolve(e.target.result);
       resolve(e.target.result);
     };
     };
-  });
+  })
+  .then(transformScript);
 }
 }
 
 
 export function getScriptData(id) {
 export function getScriptData(id) {
@@ -436,6 +457,7 @@ export function getScriptsByIndex(index, options, cTx, mapEach) {
       const { result } = e.target;
       const { result } = e.target;
       if (result) {
       if (result) {
         let { value } = result;
         let { value } = result;
+        value = transformScript(value);
         if (mapEach) value = mapEach(value);
         if (mapEach) value = mapEach(value);
         list.push(value);
         list.push(value);
         result.continue();
         result.continue();
@@ -506,7 +528,7 @@ export function parseScript(data) {
       res.data.message = i18n('msgInstalled');
       res.data.message = i18n('msgInstalled');
     }
     }
     updateProps(script, data.more);
     updateProps(script, data.more);
-    updateProps(script.custom, data.custom);
+    Object.assign(script.custom, data.custom);
     script.meta = meta;
     script.meta = meta;
     script.code = data.code;
     script.code = data.code;
     script.uri = getNameURI(script);
     script.uri = getNameURI(script);

+ 6 - 1
src/background/utils/script.js

@@ -54,7 +54,12 @@ export function parseMeta(code) {
 
 
 export function newScript() {
 export function newScript() {
   const script = {
   const script = {
-    custom: {},
+    custom: {
+      origInclude: true,
+      origExclude: true,
+      origMatch: true,
+      origExcludeMatch: true,
+    },
     enabled: 1,
     enabled: 1,
     update: 1,
     update: 1,
     code: `\
     code: `\

+ 5 - 7
src/background/utils/tester.js

@@ -39,13 +39,10 @@ export function testMatch(url, rules) {
 
 
 export function testScript(url, script) {
 export function testScript(url, script) {
   const { custom, meta } = script;
   const { custom, meta } = script;
-  const mat = mergeLists(custom._match !== false && meta.match, custom.match);
-  const inc = mergeLists(custom._include !== false && meta.include, custom.include);
-  const exc = mergeLists(custom._exclude !== false && meta.exclude, custom.exclude);
-  const excMat = mergeLists(
-    custom._excludeMatch !== false && meta.excludeMatch,
-    custom.excludeMatch,
-  );
+  const mat = mergeLists(custom.origMatch && meta.match, custom.match);
+  const inc = mergeLists(custom.origInclude && meta.include, custom.include);
+  const exc = mergeLists(custom.origExclude && meta.exclude, custom.exclude);
+  const excMat = mergeLists(custom.origExcludeMatch && meta.excludeMatch, custom.excludeMatch);
   // match all if no @match or @include rule
   // match all if no @match or @include rule
   let ok = !mat.length && !inc.length;
   let ok = !mat.length && !inc.length;
   // @match
   // @match
@@ -126,6 +123,7 @@ export function testBlacklist(url) {
   return blacklistRules.some(re => re.test(url));
   return blacklistRules.some(re => re.test(url));
 }
 }
 export function resetBlacklist(list) {
 export function resetBlacklist(list) {
+  // XXX compatible with {Array} list in v2.6.1-
   blacklistRules = (Array.isArray(list) ? list : (list || '').split('\n'))
   blacklistRules = (Array.isArray(list) ? list : (list || '').split('\n'))
   .map(line => {
   .map(line => {
     const item = line.trim();
     const item = line.trim();

+ 13 - 9
src/options/views/edit.vue

@@ -47,7 +47,7 @@
               <legend>
               <legend>
                 <span v-text="i18n('labelInclude')"></span>
                 <span v-text="i18n('labelInclude')"></span>
                 <label>
                 <label>
-                  <input type=checkbox v-model="custom.keepInclude">
+                  <input type=checkbox v-model="custom.origInclude">
                   <span v-text="i18n('labelKeepInclude')"></span>
                   <span v-text="i18n('labelKeepInclude')"></span>
                 </label>
                 </label>
               </legend>
               </legend>
@@ -58,7 +58,7 @@
               <legend>
               <legend>
                 <span v-text="i18n('labelMatch')"></span>
                 <span v-text="i18n('labelMatch')"></span>
                 <label>
                 <label>
-                  <input type=checkbox v-model="custom.keepMatch">
+                  <input type=checkbox v-model="custom.origMatch">
                   <span v-text="i18n('labelKeepMatch')"></span>
                   <span v-text="i18n('labelKeepMatch')"></span>
                 </label>
                 </label>
               </legend>
               </legend>
@@ -69,7 +69,7 @@
               <legend>
               <legend>
                 <span v-text="i18n('labelExclude')"></span>
                 <span v-text="i18n('labelExclude')"></span>
                 <label>
                 <label>
-                  <input type=checkbox v-model="custom.keepExclude">
+                  <input type=checkbox v-model="custom.origExclude">
                   <span v-text="i18n('labelKeepExclude')"></span>
                   <span v-text="i18n('labelKeepExclude')"></span>
                 </label>
                 </label>
               </legend>
               </legend>
@@ -249,16 +249,18 @@ export default {
         'homepageURL',
         'homepageURL',
         'updateURL',
         'updateURL',
         'downloadURL',
         'downloadURL',
+        'origInclude',
+        'origExclude',
+        'origMatch',
+        'origExcludeMatch',
       ].reduce((value, key) => {
       ].reduce((value, key) => {
         value[key] = custom[key];
         value[key] = custom[key];
         return value;
         return value;
       }, {
       }, {
-        keepInclude: custom._include !== false,
-        keepMatch: custom._match !== false,
-        keepExclude: custom._exclude !== false,
         include: fromList(custom.include),
         include: fromList(custom.include),
         match: fromList(custom.match),
         match: fromList(custom.match),
         exclude: fromList(custom.exclude),
         exclude: fromList(custom.exclude),
+        excludeMatch: fromList(custom.excludeMatch),
         runAt: custom.runAt || custom['run-at'] || '',
         runAt: custom.runAt || custom['run-at'] || '',
       });
       });
       this.$nextTick(() => {
       this.$nextTick(() => {
@@ -278,16 +280,18 @@ export default {
         'homepageURL',
         'homepageURL',
         'updateURL',
         'updateURL',
         'downloadURL',
         'downloadURL',
+        'origInclude',
+        'origExclude',
+        'origMatch',
+        'origExcludeMatch',
       ].reduce((val, key) => {
       ].reduce((val, key) => {
         val[key] = custom[key];
         val[key] = custom[key];
         return val;
         return val;
       }, {
       }, {
-        _include: custom.keepInclude,
-        _match: custom.keepMatch,
-        _exclude: custom.keepExclude,
         include: toList(custom.include),
         include: toList(custom.include),
         match: toList(custom.match),
         match: toList(custom.match),
         exclude: toList(custom.exclude),
         exclude: toList(custom.exclude),
+        excludeMatch: toList(custom.excludeMatch),
       });
       });
       return sendMessage({
       return sendMessage({
         cmd: 'ParseScript',
         cmd: 'ParseScript',

+ 56 - 36
test/background/tester.js

@@ -4,24 +4,34 @@ import cache from 'src/background/utils/cache';
 
 
 test.onFinish(cache.destroy);
 test.onFinish(cache.destroy);
 
 
+function buildScript(props) {
+  return Object.assign({
+    custom: {
+      origInclude: true,
+      origExclude: true,
+      origMatch: true,
+      origExcludeMatch: true,
+    },
+    meta: {},
+  }, props);
+}
+
 test('scheme', t => {
 test('scheme', t => {
   t.test('should match all', q => {
   t.test('should match all', q => {
-    const script = {
-      custom: {},
+    const script = buildScript({
       meta: {
       meta: {
         match: [
         match: [
           '*://*/*',
           '*://*/*',
         ],
         ],
       },
       },
-    };
+    });
     q.ok(testScript('https://www.google.com/', script), 'should match `http | https`');
     q.ok(testScript('https://www.google.com/', script), 'should match `http | https`');
     q.notOk(testScript('file:///Users/Gerald/file', script), 'should not match `file`');
     q.notOk(testScript('file:///Users/Gerald/file', script), 'should not match `file`');
     q.end();
     q.end();
   });
   });
 
 
   t.test('should match exact', q => {
   t.test('should match exact', q => {
-    const script = {
-      custom: {},
+    const script = buildScript({
       meta: {
       meta: {
         match: [
         match: [
           'http://*/*',
           'http://*/*',
@@ -29,7 +39,7 @@ test('scheme', t => {
           'file:///*',
           'file:///*',
         ],
         ],
       },
       },
-    };
+    });
     q.ok(testScript('http://www.google.com/', script), 'should match `http`');
     q.ok(testScript('http://www.google.com/', script), 'should match `http`');
     q.notOk(testScript('https://www.google.com/', script), 'should not match `https`');
     q.notOk(testScript('https://www.google.com/', script), 'should not match `https`');
     q.ok(testScript('file:///Users/Gerald/file', script), 'should match `file`');
     q.ok(testScript('file:///Users/Gerald/file', script), 'should match `file`');
@@ -42,14 +52,13 @@ test('scheme', t => {
 
 
 test('host', t => {
 test('host', t => {
   t.test('should match domain', q => {
   t.test('should match domain', q => {
-    const script = {
-      custom: {},
+    const script = buildScript({
       meta: {
       meta: {
         match: [
         match: [
           '*://docs.google.com/',
           '*://docs.google.com/',
         ],
         ],
       },
       },
-    };
+    });
     q.ok(testScript('https://docs.google.com/', script), 'should match exact domain name');
     q.ok(testScript('https://docs.google.com/', script), 'should match exact domain name');
     q.notOk(testScript('https://sub.docs.google.com/', script), 'should not match subdomains');
     q.notOk(testScript('https://sub.docs.google.com/', script), 'should not match subdomains');
     q.notOk(testScript('https://docs.google.com.cn/', script), 'should not match suffixed domains');
     q.notOk(testScript('https://docs.google.com.cn/', script), 'should not match suffixed domains');
@@ -57,14 +66,13 @@ test('host', t => {
   });
   });
 
 
   t.test('should match subdomains', q => {
   t.test('should match subdomains', q => {
-    const script = {
-      custom: {},
+    const script = buildScript({
       meta: {
       meta: {
         match: [
         match: [
           '*://*.google.com/',
           '*://*.google.com/',
         ],
         ],
       },
       },
-    };
+    });
     q.ok(testScript('https://www.google.com/', script), 'should match subdomains');
     q.ok(testScript('https://www.google.com/', script), 'should match subdomains');
     q.ok(testScript('https://a.b.google.com/', script), 'should match subdomains');
     q.ok(testScript('https://a.b.google.com/', script), 'should match subdomains');
     q.ok(testScript('https://google.com/', script), 'should match specified domain');
     q.ok(testScript('https://google.com/', script), 'should match specified domain');
@@ -77,28 +85,26 @@ test('host', t => {
 
 
 test('path', t => {
 test('path', t => {
   t.test('should match any', q => {
   t.test('should match any', q => {
-    const script = {
-      custom: {},
+    const script = buildScript({
       meta: {
       meta: {
         match: [
         match: [
           'https://www.google.com/*',
           'https://www.google.com/*',
         ],
         ],
       },
       },
-    };
+    });
     q.ok(testScript('https://www.google.com/', script), 'should match `/`');
     q.ok(testScript('https://www.google.com/', script), 'should match `/`');
     q.ok(testScript('https://www.google.com/hello/world', script), 'should match any');
     q.ok(testScript('https://www.google.com/hello/world', script), 'should match any');
     q.end();
     q.end();
   });
   });
 
 
   t.test('should match exact', q => {
   t.test('should match exact', q => {
-    const script = {
-      custom: {},
+    const script = buildScript({
       meta: {
       meta: {
         match: [
         match: [
           'https://www.google.com/a/b/c',
           'https://www.google.com/a/b/c',
         ],
         ],
       },
       },
-    };
+    });
     q.ok(testScript('https://www.google.com/a/b/c', script), 'should match exact');
     q.ok(testScript('https://www.google.com/a/b/c', script), 'should match exact');
     q.notOk(testScript('https://www.google.com/a/b/c/d', script), 'should match exact');
     q.notOk(testScript('https://www.google.com/a/b/c/d', script), 'should match exact');
     q.end();
     q.end();
@@ -109,29 +115,27 @@ test('path', t => {
 
 
 test('include', t => {
 test('include', t => {
   t.test('should include any', q => {
   t.test('should include any', q => {
-    const script = {
-      custom: {},
+    const script = buildScript({
       meta: {
       meta: {
         include: [
         include: [
           '*',
           '*',
         ],
         ],
       },
       },
-    };
+    });
     q.ok(testScript('https://www.google.com/', script), 'should match `http | https`');
     q.ok(testScript('https://www.google.com/', script), 'should match `http | https`');
     q.ok(testScript('file:///Users/Gerald/file', script), 'should match `file`');
     q.ok(testScript('file:///Users/Gerald/file', script), 'should match `file`');
     q.end();
     q.end();
   });
   });
 
 
   t.test('should include by regexp', q => {
   t.test('should include by regexp', q => {
-    const script = {
-      custom: {},
+    const script = buildScript({
       meta: {
       meta: {
         include: [
         include: [
           'https://www.google.com/*',
           'https://www.google.com/*',
           'https://twitter.com/*',
           'https://twitter.com/*',
         ],
         ],
       },
       },
-    };
+    });
     q.ok(testScript('https://www.google.com/', script), 'should match `/`');
     q.ok(testScript('https://www.google.com/', script), 'should match `/`');
     q.ok(testScript('https://www.google.com/hello/world', script), 'include by prefix');
     q.ok(testScript('https://www.google.com/hello/world', script), 'include by prefix');
     q.notOk(testScript('https://www.hello.com/', script), 'not include by prefix');
     q.notOk(testScript('https://www.hello.com/', script), 'not include by prefix');
@@ -141,8 +145,7 @@ test('include', t => {
 
 
 test('exclude', t => {
 test('exclude', t => {
   t.test('should exclude any', q => {
   t.test('should exclude any', q => {
-    const script = {
-      custom: {},
+    const script = buildScript({
       meta: {
       meta: {
         match: [
         match: [
           '*://*/*',
           '*://*/*',
@@ -151,14 +154,13 @@ test('exclude', t => {
           '*',
           '*',
         ],
         ],
       },
       },
-    };
+    });
     q.notOk(testScript('https://www.google.com/', script), 'should exclude `http | https`');
     q.notOk(testScript('https://www.google.com/', script), 'should exclude `http | https`');
     q.end();
     q.end();
   });
   });
 
 
   t.test('should include by regexp', q => {
   t.test('should include by regexp', q => {
-    const script = {
-      custom: {},
+    const script = buildScript({
       meta: {
       meta: {
         match: [
         match: [
           '*://*/*',
           '*://*/*',
@@ -168,7 +170,7 @@ test('exclude', t => {
           'https://twitter.com/*',
           'https://twitter.com/*',
         ],
         ],
       },
       },
-    };
+    });
     q.notOk(testScript('https://www.google.com/', script), 'should exclude `/`');
     q.notOk(testScript('https://www.google.com/', script), 'should exclude `/`');
     q.notOk(testScript('https://www.google.com/hello/world', script), 'exclude by prefix');
     q.notOk(testScript('https://www.google.com/hello/world', script), 'exclude by prefix');
     q.ok(testScript('https://www.hello.com/', script), 'not exclude by prefix');
     q.ok(testScript('https://www.hello.com/', script), 'not exclude by prefix');
@@ -178,8 +180,7 @@ test('exclude', t => {
 
 
 test('exclude-match', t => {
 test('exclude-match', t => {
   t.test('should exclude any', q => {
   t.test('should exclude any', q => {
-    const script = {
-      custom: {},
+    const script = buildScript({
       meta: {
       meta: {
         match: [
         match: [
           '*://*/*',
           '*://*/*',
@@ -188,14 +189,13 @@ test('exclude-match', t => {
           '*://*/*',
           '*://*/*',
         ],
         ],
       },
       },
-    };
+    });
     q.notOk(testScript('https://www.google.com/', script), 'should exclude `http | https`');
     q.notOk(testScript('https://www.google.com/', script), 'should exclude `http | https`');
     q.end();
     q.end();
   });
   });
 
 
   t.test('should include by regexp', q => {
   t.test('should include by regexp', q => {
-    const script = {
-      custom: {},
+    const script = buildScript({
       meta: {
       meta: {
         match: [
         match: [
           '*://*/*',
           '*://*/*',
@@ -205,7 +205,7 @@ test('exclude-match', t => {
           'https://twitter.com/*',
           'https://twitter.com/*',
         ],
         ],
       },
       },
-    };
+    });
     q.notOk(testScript('https://www.google.com/', script), 'should exclude `/`');
     q.notOk(testScript('https://www.google.com/', script), 'should exclude `/`');
     q.notOk(testScript('https://www.google.com/hello/world', script), 'exclude by prefix');
     q.notOk(testScript('https://www.google.com/hello/world', script), 'exclude by prefix');
     q.ok(testScript('https://www.hello.com/', script), 'not exclude by prefix');
     q.ok(testScript('https://www.hello.com/', script), 'not exclude by prefix');
@@ -213,6 +213,26 @@ test('exclude-match', t => {
   });
   });
 });
 });
 
 
+test('custom', t => {
+  t.test('should ignore original rules', q => {
+    const script = buildScript({
+      custom: {
+        match: [
+          'https://twitter.com/*',
+        ],
+      },
+      meta: {
+        match: [
+          'https://www.google.com/*',
+        ],
+      },
+    });
+    q.ok(testScript('https://twitter.com/', script), 'should match custom rules');
+    q.notOk(testScript('https://www.google.com/', script), 'should not match original rules');
+    q.end();
+  });
+});
+
 test('blacklist', t => {
 test('blacklist', t => {
   t.test('should exclude match rules', q => {
   t.test('should exclude match rules', q => {
     resetBlacklist(`\
     resetBlacklist(`\