浏览代码

refactor: extract more isXXX functions

tophf 4 年之前
父节点
当前提交
ea5cce5fcf

+ 1 - 1
src/injected/content/bridge.js

@@ -95,7 +95,7 @@ const bridge = {
     let res = handle === true
       ? sendCmd(cmd, data)
       : node::handle(data, realm || INJECT_PAGE);
-    if (res && isPromise(res)) {
+    if (isPromise(res)) {
       res = await res;
     }
     if (callbackId) {

+ 3 - 2
src/injected/safe-globals-injected.js

@@ -20,9 +20,10 @@ export const WINDOW_FOCUS = 'window.focus';
 export const NS_HTML = 'http://www.w3.org/1999/xhtml';
 export const CALLBACK_ID = '__CBID';
 
-export const isPromise = val => val::objectToString() === '[object Promise]';
-
 export const isFunction = val => typeof val === 'function';
+export const isObject = val => val !== null && typeof val === 'object';
+export const isPromise = val => val && val::objectToString() === '[object Promise]';
+export const isString = val => typeof val === 'string';
 
 export const getOwnProp = (obj, key) => (
   obj::hasOwnProperty(key)

+ 7 - 7
src/injected/web/gm-api.js

@@ -46,8 +46,8 @@ export function makeGmApi() {
      * @returns {String} listenerId
      */
     GM_addValueChangeListener(key, fn) {
-      if (typeof key !== 'string') key = `${key}`;
-      if (typeof fn !== 'function') return;
+      if (!isString(key)) key = `${key}`;
+      if (!isFunction(fn)) return;
       const keyHooks = changeHooks[this.id] || (changeHooks[this.id] = createNullObj());
       const hooks = keyHooks[key] || (keyHooks[key] = createNullObj());
       const i = objectValues(hooks)::indexOf(fn);
@@ -97,7 +97,7 @@ export function makeGmApi() {
       // not using ... as it calls Babel's polyfill that calls unsafe Object.xxx
       const opts = createNullObj();
       let onload;
-      if (typeof arg1 === 'string') {
+      if (isString(arg1)) {
         opts.url = arg1;
         opts.name = name;
       } else if (arg1) {
@@ -112,7 +112,7 @@ export function makeGmApi() {
           'ontimeout',
         ]);
       }
-      if (!name || typeof name !== 'string') {
+      if (!name || !isString(name)) {
         throw new ErrorSafe('Required parameter "name" is missing or not a string.');
       }
       assign(opts, {
@@ -135,7 +135,7 @@ export function makeGmApi() {
      * @returns {HTMLElement} it also has .then() so it should be compatible with TM
      */
     GM_addElement(parent, tag, attributes) {
-      return typeof parent === 'string'
+      return isString(parent)
         ? webAddElement(null, parent, tag, this)
         : webAddElement(parent, tag, attributes, this);
     },
@@ -149,14 +149,14 @@ export function makeGmApi() {
     },
     GM_openInTab(url, options) {
       return onTabCreate(
-        options && typeof options === 'object'
+        isObject(options)
           ? assign(createNullObj(), options, { url })
           : { active: !options, url },
         this,
       );
     },
     GM_notification(text, title, image, onclick) {
-      const options = typeof text === 'object' ? text : {
+      const options = isObject(text) ? text : {
         __proto__: null,
         text,
         title,

+ 12 - 13
src/injected/web/gm-global-wrapper.js

@@ -4,8 +4,7 @@ import { FastLookup } from './util-web';
 
 /** The index strings that look exactly like integers can't be forged
  * but for example '011' doesn't look like 11 so it's allowed */
-const isFrameIndex = (key, isString) => isString
-  && key >= 0 && key <= 0xFFFF_FFFE && key === `${+key}`;
+const isFrameIndex = key => key >= 0 && key <= 0xFFFF_FFFE && key === `${+key}`;
 
 const globalKeysSet = FastLookup();
 const globalKeys = (function makeGlobalKeys() {
@@ -14,7 +13,7 @@ const globalKeys = (function makeGlobalKeys() {
   // True if `names` is usable as is, but FF is bugged: its names have duplicates
   let ok = !IS_FIREFOX;
   names::forEach(key => {
-    if (isFrameIndex(key, true)) {
+    if (isFrameIndex(key)) {
       ok = false;
     } else {
       globalKeysSet.add(key);
@@ -24,7 +23,7 @@ const globalKeys = (function makeGlobalKeys() {
      FF content mode: `global` is different, some props e.g. `isFinite` are defined only there */
   if (global !== window) {
     getOwnPropertyNames(global)::forEach(key => {
-      if (!isFrameIndex(key, true)) {
+      if (!isFrameIndex(key)) {
         globalKeysSet.add(key);
         ok = false;
       }
@@ -167,11 +166,12 @@ export function makeGlobalWrapper(local) {
      when trying to clone its recursive properties like `self` and `window`. */
   safeDefineProperty(local, toStringTag, { get: () => 'Window' });
   const wrapper = new ProxySafe(local, {
+    __proto__: null,
     defineProperty(_, name, desc) {
-      const isString = typeof name === 'string';
-      if (!isFrameIndex(name, isString)) {
+      const isStr = isString(name);
+      if (!isStr || !isFrameIndex(name)) {
         safeDefineProperty(local, name, desc);
-        if (isString) setEventHandler(name);
+        if (isStr) setEventHandler(name);
         delete readonlys[name];
       }
       return true;
@@ -212,15 +212,15 @@ export function makeGlobalWrapper(local) {
     ownKeys: () => makeOwnKeys(local, globals),
     preventExtensions() {},
     set(_, name, value) {
-      const isString = typeof name === 'string';
+      const isStr = isString(name);
       let readonly = readonlys[name];
       if (readonly === 1) {
         readonly = globals.has(name) ? 2 : 0;
         readonlys[name] = readonly;
       }
-      if (!readonly && !isFrameIndex(name, isString)) {
+      if (!readonly && (!isStr || !isFrameIndex(name))) {
         local[name] = value;
-        if (isString) setEventHandler(name, value, globals, events);
+        if (isStr) setEventHandler(name, value, globals, events);
       }
       return true;
     },
@@ -268,15 +268,14 @@ function resolveProp(name, wrapper, globals, local) {
     boundMethods[name] = value;
   }
   const canCopy = value || name in inheritedKeys || globals.has(name);
-  if (!value && (canCopy || isFrameIndex(name, typeof name === 'string'))) {
+  if (!value && (canCopy || isString(name) && isFrameIndex(name))) {
     value = global[name];
   }
   if (value === window) {
     value = wrapper;
   }
   if (canCopy && (
-    isFunction(value)
-    || typeof value === 'object' && value && name !== 'event'
+    isFunction(value) || isObject(value) && name !== 'event'
     // window.event contains the current event so it's always different
   )) {
     local[name] = value;

+ 1 - 1
src/injected/web/requests.js

@@ -94,7 +94,7 @@ async function start(req, context, fileName) {
     fileName,
     data: data == null && []
       // `binary` is for TM/GM-compatibility + non-objects = must use a string `data`
-      || (opts.binary || typeof data !== 'object') && [`${data}`]
+      || (opts.binary || !isObject(data)) && [`${data}`]
       // FF56+ can send any cloneable data directly, FF52-55 can't due to https://bugzil.la/1371246
       || IS_FIREFOX && bridge.ua.browserVersion >= 56 && [data]
       // TODO: support huge data by splitting it to multiple messages

+ 1 - 1
src/injected/web/util-web.js

@@ -10,7 +10,7 @@ const { toString: numberToString } = 0;
  */
 const isArray = obj => obj
   && typeof obj.length === 'number'
-  && typeof obj.splice === 'function';
+  && isFunction(obj.splice);
 // Reference: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON#Polyfill
 const escMap = {
   '"': '\\"',