I'm trying this code to apply new design on the Google Tasks page with the extension Tampermonkey.
When I try html{ display: none !important }
then It displays nothing as the html
tag is not under iframe
.
however, I couldn't modify under iframe[src="about:blank"]
element.
How should I modify to make it work?
shot 1. : Doesn't work for inside of iframe[src="about:blank"]
// ==UserScript==
// @name test
// @match https://mail.google.com/tasks/canvas
// @match about:blank
// @grant GM_addStyle
// ==/UserScript==
GM_addStyle ( `
* {color: red !important}
` );
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:
GM_addStyle()
will not work in this case, so we add styles with a frame-aware function.
- 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.