如何使用 IE 插件将样式注入页面
How to inject styles to a page using IE addon
我正在尝试转换 content script I wrote for Google Chrome into an IE Addon, mainly using the code in this answer。
我需要注入一个样式表,然后我找到了一个 way to do it using Javascript。我想我也许可以使用 C# 来做同样的事情。这是我的代码:
[ComVisible(true)]
[Guid(/* replaced */)]
[ClassInterface(ClassInterfaceType.None)]
public class SimpleBHO: IObjectWithSite
{
private WebBrowser webBrowser;
void webBrowser_DocumentComplete(object pDisp, ref object URL)
{
var document2 = webBrowser.Document as IHTMLDocument2;
var document3 = webBrowser.Document as IHTMLDocument3;
// trying to add a '<style>' element to the header. this does not work.
var style = document2.createElement("style");
style.innerHTML = ".foo { background-color: red; }";// this line is the culprit!
style.setAttribute("type", "text/css");
var headCollection = document3.getElementsByTagName("head");
var head = headCollection.item(0, 0) as IHTMLDOMNode;
var result = head.appendChild(style as IHTMLDOMNode);
// trying to repace an element in the body. this part works if
// adding style succeeds.
var journalCollection = document3.getElementsByName("elem_id");
var journal = journalCollection.item(0, 0) as IHTMLElement;
journal.innerHTML = "<div class=\"foo\">Replaced!</div>";
// trying to execute some JavaScript. this part works as well if
// adding style succeeds.
document2.parentWindow.execScript("alert('Hi!')");
}
int IObjectWithSite.SetSite(object site)
{
if (site != null)
{
webBrowser = (WebBrowser)site;
webBrowser.DocumentComplete += new DWebBrowserEvents2_DocumentCompleteEventHandler(webBrowser_DocumentComplete);
}
else
{
webBrowser.DocumentComplete -= new DWebBrowserEvents2_DocumentCompleteEventHandler(webBrowser_DocumentComplete);
webBrowser = null;
}
return 0;
}
/* some code (e.g.: IObjectWithSite.SetSite) omitted to improve clarity */
}
如果我只是注释掉下面一行...
style.innerHTML = ".foo { background-color: red; }";
...其余代码完美执行(替换元素#elem_id
并执行我注入的JavaScript)。
我在尝试注入样式表时做错了什么?这甚至可能吗?
编辑: 我发现我试图注入的站点 CSS 请求文档模式 5,并且当兼容性视图被 禁用时,我的代码完美运行。但是,即使 enabled?
,我该如何让它工作呢?
经过大量试验,我发现只有使用 JavaScript 来注入样式表的故障安全方法才能使用 IHTMLWindow2.execScript()
执行。
我使用了以下 JavaScript:
var style = document.createElement('style');
document.getElementsByTagName('head')[0].appendChild(style);
var sheet = style.styleSheet || style.sheet;
if (sheet.insertRule) {
sheet.insertRule('.foo { background-color: red; }', 0);
} else if (sheet.addRule) {
sheet.addRule('.foo', 'background-color: red;', 0);
}
以上 JavaScript 以下列方式执行:
// This code is written inside a BHO written in C#
var document2 = webBrowser.Document as IHTMLDocument2;
document2.parentWindow.execScript(@"
/* Here, we have the same JavaScript mentioned above */
var style = docu....
...
}");
document2.parentWindow.execScript("alert('Hi!')");
我正在尝试转换 content script I wrote for Google Chrome into an IE Addon, mainly using the code in this answer。
我需要注入一个样式表,然后我找到了一个 way to do it using Javascript。我想我也许可以使用 C# 来做同样的事情。这是我的代码:
[ComVisible(true)]
[Guid(/* replaced */)]
[ClassInterface(ClassInterfaceType.None)]
public class SimpleBHO: IObjectWithSite
{
private WebBrowser webBrowser;
void webBrowser_DocumentComplete(object pDisp, ref object URL)
{
var document2 = webBrowser.Document as IHTMLDocument2;
var document3 = webBrowser.Document as IHTMLDocument3;
// trying to add a '<style>' element to the header. this does not work.
var style = document2.createElement("style");
style.innerHTML = ".foo { background-color: red; }";// this line is the culprit!
style.setAttribute("type", "text/css");
var headCollection = document3.getElementsByTagName("head");
var head = headCollection.item(0, 0) as IHTMLDOMNode;
var result = head.appendChild(style as IHTMLDOMNode);
// trying to repace an element in the body. this part works if
// adding style succeeds.
var journalCollection = document3.getElementsByName("elem_id");
var journal = journalCollection.item(0, 0) as IHTMLElement;
journal.innerHTML = "<div class=\"foo\">Replaced!</div>";
// trying to execute some JavaScript. this part works as well if
// adding style succeeds.
document2.parentWindow.execScript("alert('Hi!')");
}
int IObjectWithSite.SetSite(object site)
{
if (site != null)
{
webBrowser = (WebBrowser)site;
webBrowser.DocumentComplete += new DWebBrowserEvents2_DocumentCompleteEventHandler(webBrowser_DocumentComplete);
}
else
{
webBrowser.DocumentComplete -= new DWebBrowserEvents2_DocumentCompleteEventHandler(webBrowser_DocumentComplete);
webBrowser = null;
}
return 0;
}
/* some code (e.g.: IObjectWithSite.SetSite) omitted to improve clarity */
}
如果我只是注释掉下面一行...
style.innerHTML = ".foo { background-color: red; }";
...其余代码完美执行(替换元素#elem_id
并执行我注入的JavaScript)。
我在尝试注入样式表时做错了什么?这甚至可能吗?
编辑: 我发现我试图注入的站点 CSS 请求文档模式 5,并且当兼容性视图被 禁用时,我的代码完美运行。但是,即使 enabled?
,我该如何让它工作呢?经过大量试验,我发现只有使用 JavaScript 来注入样式表的故障安全方法才能使用 IHTMLWindow2.execScript()
执行。
我使用了以下 JavaScript:
var style = document.createElement('style');
document.getElementsByTagName('head')[0].appendChild(style);
var sheet = style.styleSheet || style.sheet;
if (sheet.insertRule) {
sheet.insertRule('.foo { background-color: red; }', 0);
} else if (sheet.addRule) {
sheet.addRule('.foo', 'background-color: red;', 0);
}
以上 JavaScript 以下列方式执行:
// This code is written inside a BHO written in C#
var document2 = webBrowser.Document as IHTMLDocument2;
document2.parentWindow.execScript(@"
/* Here, we have the same JavaScript mentioned above */
var style = docu....
...
}");
document2.parentWindow.execScript("alert('Hi!')");