Change CSS of the content of an iframe, that has src=“about:blank”, on Chrome

廉价感情. 提交于 2019-12-06 05:54:49

Yes, scripting for iframes with src="about:blank" can be tricky as the normal userscript mechanisms do not work the same. (Currently, @match about:blank does not work, but it would be a bad idea to use it here anyway, since it would have global side effects.)

Fortunately, on Chrome, iframes with src="about:blank" almost always have a documentElement by the time a Tampermonkey script runs, so you do not normally need to wait if you are just adding CSS.

Here is a complete working script, that styles that first iframe:

// ==UserScript==
// @name    _Style iframe with src="about:blank"
// @match   https://mail.google.com/tasks/canvas
// @grant   none
// ==/UserScript==

//-- Adjust the following selector to match your page's particulars, if needed.
var targetFrame = document.querySelector ("iframe[src='about:blank']")
if (targetFrame) {
    addStyleToFrame (
        `* {color: red !important}`
        , targetFrame
    );
}

function addStyleToFrame (cssStr, frmNode) {
    var D               = frmNode.contentDocument;
    var newNode         = D.createElement ('style');
    newNode.textContent = cssStr;

    var targ    = D.getElementsByTagName ('head')[0] || D.body || D.documentElement;
    targ.appendChild (newNode);
}



If the <iframe> tag is javascript created, or other delays hamper the above...

Use the iframeSelector parameter of waitForKeyElements to work around that.

The trick is to pick a node that always appears in the finished iframe, and pass that to waitForKeyElements.
The node should be unique.
But for the following example I used .goog-toolbar:first as a quick first attempt.

Here is that complete working script:

// ==UserScript==
// @name     _Style iframe with src="about:blank"
// @match    https://mail.google.com/tasks/canvas
// @require  https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js
// @require  https://gist.github.com/raw/2625891/waitForKeyElements.js
// @grant    GM_addStyle
// @grant    GM.getValue
// ==/UserScript==
//- The @grant directives are needed to restore the proper sandbox.

const desiredStyles = `* {color: red !important;}`;

waitForKeyElements (
    ".goog-toolbar:first",
    addCSS_Style,
    false,
    "iframe[src='about:blank']"
);

function addCSS_Style (jNode) {
    var frmBody = jNode.closest ("body");
    //-- Optionally add a check here to avoid duplicate <style> nodes.
    frmBody.append (`<style>${desiredStyles}</style>`);
}



Notes:

  1. GM_addStyle() will not work in this case, so we add styles with a frame-aware function.
  2. Google pages use: multiple, nested iframes; complex page (re)mangling; and HTML with poor "info scent". In short they are evil, ever-shifting, and can be a pain to script for. So, this simple example will work, but that's all that's in scope for this question. For more complex scenarios, open a new question and have plenty of beer money on hand.
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!