記事

Last Modified:

Google ChromeでFirefoxのuserContent.cssを共用する #OS

FirefoxのuserContent.cssをGoogle Chromeと共有したい。

解決

CSSにJavaScriptを埋め込む #JavaScript #CSS @robarioを適用したuserContent.cssはJavaScriptとして実行できるので、Tampermonkeyに以下のスクリプトを登録(本文は無し)。

// ==UserScript==
// @name userContent.css
// @include *
// @require file:///Users/robario/.firefox/chrome/userContent.css
// ==/UserScript==

※Tampermonkey for Chrome では拡張機能の設定から「ファイルのURLへのアクセスを許可する」にチェックが必要

userContent.cssは取得したCSSをstyle要素として埋め込むように記述。

//*
const userContentCSS = `*/{}

ここにスタイルシート

//*`.replace(/^[*][/][{][}]/, '').replace(/[/][/][*]$/, '');
const style = document.createElement('style');
style.innerText = userContentCSS;
document.body.appendChild(style);

これで適用はされるが、userContent.cssでおそらく使われているであろう@document規則は解釈されないのでスタイルが当たらない。 そこで、@document規則をJavaScriptで解釈し、現在のページで適用すべき@document@media allに置換して適用させるようにした。

//*
const userContentCSS = `*/{}

ここにスタイルシート

//*`.replace(/^[*][/][{][}]/, '').replace(/[/][/][*]$/, '');

const escapeRegExp = string => string.replace(/[.*+?^=!:${}()|\[\]\/\\]/g, '\\$&');
const methods = {
  'url': arg => new RegExp('^' + escapeRegExp(arg) + '$').test(location.href),
  'url-prefix': arg => new RegExp('^' + escapeRegExp(arg)).test(location.href),
  'domain': arg => new RegExp('^(?:[^.]+[.])*' + escapeRegExp(arg) + '$').test(location.hostname),
  'regexp': arg => new RegExp('^' + arg + '$').test(location.href),
};
const style = document.createElement('style');
style.innerText = userContentCSS.replace(/@(?:-moz-)?document\s*([^{]+)/g, ($0, rules) => {
  rules = rules.replace(/(url|url-prefix|domain|regexp)[(](.+?)[)]\s*(,\s*(?=url|url-prefix|domain|regexp)|$)/g, ($0, method, arg, rest) => {
    if (arg[0] !== arg[arg.length - 1] || arg[0] !== '"' && arg[0] !== "'") {
      arg = "'" + arg + "'";
    }
    if (rest[0] === ',') {
      rest = ' ||' + rest.slice(1);
    }
    return `methods['${method}'](${arg})${rest}`;
  });
  if (eval(rules)) {
    console.info('apply userContent.css', $0);
    return '@media all';
  } else {
    return $0;
  }
});
document.body.appendChild(style);