sizzle / gm4-polyfill

// ==UserScript==
// @author Anthony Lieuallen (https://github.com/arantius)
// @exclude  *
// ==UserLibrary==
// @name         gm4-polyfill
// @description  This helper script bridges compatibility between the Greasemonkey 4 APIs and existing/legacy APIs.
// @license      MIT; https://raw.githubusercontent.com/greasemonkey/gm4-polyfill/master/LICENSE
// @copyright    2017, Anthony Lieuallen (https://github.com/arantius)
// @version      +d58c4f6
// @version      20171114.0.0
// ==/UserScript==
// ==/UserLibrary==
// ==OpenUserJS==
// @author         sizzle
// @collaborator   Marti
// ==/OpenUserJS==

if (typeof GM == 'undefined') {
  GM = {};
}


if (typeof GM_addStyle == 'undefined') {
  this.GM_addStyle = (aCss) => {
    'use strict';
    let head = document.getElementsByTagName('head')[0];
    if (head) {
      let style = document.createElement('style');
      style.setAttribute('type', 'text/css');
      style.textContent = aCss;
      head.appendChild(style);
      return style;
    }
    return null;
  };
}


if (typeof GM_registerMenuCommand == 'undefined') {
  this.GM_registerMenuCommand = (caption, commandFunc, accessKey) => {
    if (!document.body) {
      console.error('GM_registerMenuCommand got no body.');
      return;
    }
    let contextMenu = document.body.getAttribute('contextmenu');
    let menu = (contextMenu ? document.querySelector('menu#' + contextMenu) : null);
    if (!menu) {
      menu = document.createElement('menu');
      menu.setAttribute('id', 'gm-registered-menu');
      menu.setAttribute('type', 'context');
      document.body.appendChild(menu);
      document.body.setAttribute('contextmenu', 'gm-registered-menu');
    }
    let menuItem = document.createElement('menuitem');
    menuItem.textContent = caption;
    menuItem.addEventListener('click', commandFunc, true);
    menu.appendChild(menuItem);
  };
}


Object.entries({
  'log': console.log,
  'info': GM_info,
}).forEach(([newKey, old]) => {
  if (old && (typeof GM[newKey] == 'undefined')) {
    GM[newKey] = old;
  }
});


Object.entries({
  'GM_addStyle': 'addStyle',
  'GM_deleteValue': 'deleteValue',
  'GM_getResourceURL': 'getResourceUrl',
  'GM_getValue': 'getValue',
  'GM_listValues': 'listValues',
  'GM_notification': 'notification',
  'GM_openInTab': 'openInTab',
  'GM_registerMenuCommand': 'registerMenuCommand',
  'GM_setClipboard': 'setClipboard',
  'GM_setValue': 'setValue',
  'GM_xmlhttpRequest': 'xmlHttpRequest',
}).forEach(([oldKey, newKey]) => {
  let old = this[oldKey];
  if (old && (typeof GM[newKey] == 'undefined')) {
    GM[newKey] = function() {
      return new Promise((resolve, reject) => {
        try {
          resolve(old.apply(this, arguments));
        } catch (e) {
          reject(e);
        }
      });
    };
  }
});