我正在为Firefox创建一个简单的引导插件。我需要捕获当前的URL从浏览器通过侧边栏与一个按钮单击。
我的<<p> em> bootstrap.js :const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
Cu.import('resource://gre/modules/Services.jsm');
Cu.import("resource://gre/modules/NetUtil.jsm");
Cu.import("resource://gre/modules/FileUtils.jsm");
/*start - windowlistener*/
var windowListener = {
//DO NOT EDIT HERE
onOpenWindow: function (aXULWindow) {
// Wait for the window to finish loading
let aDOMWindow =aXULWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowInternal||Ci.nsIDOMWindow);
aDOMWindow.addEventListener("load", function () {
aDOMWindow.removeEventListener("load", arguments.callee, false);
windowListener.loadIntoWindow(aDOMWindow, aXULWindow);
}, false);
},
onCloseWindow: function (aXULWindow) {},
onWindowTitleChange: function (aXULWindow, aNewTitle) {},
register: function () {
// Load into any existing windows
let XULWindows = Services.wm.getXULWindowEnumerator(null);
while (XULWindows.hasMoreElements()) {
let aXULWindow = XULWindows.getNext();
let aDOMWindow = aXULWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowInternal || Ci.nsIDOMWindow);
windowListener.loadIntoWindow(aDOMWindow, aXULWindow);
}
// Listen to new windows
Services.wm.addListener(windowListener);
},
unregister: function () {
// Unload from any existing windows
let XULWindows = Services.wm.getXULWindowEnumerator(null);
while (XULWindows.hasMoreElements()) {
let aXULWindow = XULWindows.getNext();
let aDOMWindow = aXULWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowInternal || Ci.nsIDOMWindow);
windowListener.unloadFromWindow(aDOMWindow, aXULWindow);
}
//Stop listening so future added windows dont get this attached
Services.wm.removeListener(windowListener);
},
//END - DO NOT EDIT HERE
loadIntoWindow: function (aDOMWindow, aXULWindow) {
if (!aDOMWindow) {
return;
}
//START - EDIT BELOW HERE
var browser = aDOMWindow.document.querySelector('#browser')
if (browser) {
var splitter = aDOMWindow.document.createElement('splitter');
var propsToSet = {
id: 'demo-sidebar-with-html_splitter',
//I'm just copying what Mozilla does for their social sidebar splitter
// I left it out, but you can leave it in to see how you can style
// the splitter
class: 'sidebar-splitter'
}
for (var p in propsToSet) {
splitter.setAttribute(p, propsToSet[p]);
}
var sidebar = aDOMWindow.document.createElement('vbox');
var propsToSet = {
id: 'demo-sidebar-with-html_sidebar',
//Mozilla uses persist width here, I don't know what it does and can't
// see it how makes a difference so I left it out
//persist: 'width'
}
for (var p in propsToSet) {
sidebar.setAttribute(p, propsToSet[p]);
}
var htmlVal = loadJsonHTML(0);
var sidebarBrowser = aDOMWindow.document.createElement('browser');
var propsToSet = {
id: 'demo-sidebar-with-html_browser',
type: 'content',
context: 'contentAreaContextMenu',
disableglobalhistory: 'true',
tooltip: 'aHTMLTooltip',
autoscrollpopup: 'autoscroller',
flex: '1', //do not remove this
//you should change these widths to how you want
style: 'min-width: 14em; width: 18em; max-width: 36em;',
//or just set this to some URL like http://www.bing.com/
src: 'data:text/html,'+ htmlVal
}
for (var p in propsToSet) {
sidebarBrowser.setAttribute(p, propsToSet[p]);
}
browser.appendChild(splitter);
sidebar.appendChild(sidebarBrowser);
browser.appendChild(sidebar);
}
//END - EDIT BELOW HERE
},
unloadFromWindow: function (aDOMWindow, aXULWindow) {
if (!aDOMWindow) {
return;
}
//START - EDIT BELOW HERE
var splitter = aDOMWindow.document
.querySelector('#demo-sidebar-with-html_splitter');
if (splitter) {
var sidebar = aDOMWindow.document
.querySelector('#demo-sidebar-with-html_sidebar');
splitter.parentNode.removeChild(splitter);
sidebar.parentNode.removeChild(sidebar);
}
//END - EDIT BELOW HERE
}
};
/*end - windowlistener*/
function startup(aData, aReason) {
windowListener.register();
}
function shutdown(aData, aReason) {
if (aReason == APP_SHUTDOWN) return;
windowListener.unregister();
}
function loadJsonHTML(val=0){
var fileContent = "";
var localFile = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
//full path is okay if directory exists
localFile.initWithPath("/Users/tinuy/Desktop/test_addodn/input.txt");
//otherwise specify directory, create it if necessary, and append leaf.
//localFile.initWithPath("C:UserstinuyDocumentstestinput.txt");
if ( localFile.exists() == false ) {
fileContent = "File does not exist";
}
var istream = Cc["@mozilla.org/network/file-input-stream;1"]
.createInstance(Ci.nsIFileInputStream);
istream.init(localFile, 0x01, 4, null);
var fileScriptableIO = Cc["@mozilla.org/scriptableinputstream;1"]
.createInstance(Ci.nsIScriptableInputStream);
fileScriptableIO.init(istream);
// parse the XML into our internal document
istream.QueryInterface(Ci.nsILineInputStream);
//fileContent = fileScriptableIO.read( '1' );
var csize = 0;
while ((csize = fileScriptableIO.available()) != 0) {
fileContent += fileScriptableIO.read( csize );
}
var array = fileContent.split("&");
fileScriptableIO.close();
istream.close();
return makeHTML(array[val], val);
}
function makeHTML(value, key){
var arrValues = value.split(",");
var htmlContent = '<div name="content" class="content">' +
'<p> Name :' + arrValues[0] + '</p>';
htmlContent += '<p> Price :' + arrValues[2] + '</p>';
htmlContent += '<p> Color :' + arrValues[3] + '</p>';
htmlContent += '<p> UID :' + arrValues[1] + '</p>';
htmlContent += '<p><input type="radio" name="valid" value="yes" />Yes ' +
'<input type="radio" name="valid" value="no" /> No</p>' +
'<p><input type="text" placeholder="Reason" name="checkreason"></p>' +
'<p><input type="text" placeholder="Feedback" name="feedback"></p>' +
'</div><div><button name="load" type="button" id="loadit" onclick="loadHtml()" ' +
'loadurl="'+arrValues[4]+'">Load</button> <button name="save" type="button">' +
'Save </button> <button name="next" type="button" key="'+key+'">Next </button> ' +
'</div> <script> function loadHtml() {' +
'var a = gBrowser.contentWindow.location.href ;alert(a);' +
'} </script>';
return htmlContent;
}
function install() {}
function uninstall() {}
我尝试了从firefox侧边栏扩展获取当前页面URL的所有建议,但都不起作用
然而,从您已经设置的事实来看:
var propsToSet = {
id: 'demo-sidebar-with-html_browser',
type: 'content', //<---------------------------This
<browser>
, type
到content
,我假设两件事之一:
- 您实际上并没有试图从您通过
src
属性加载到<browser>
的代码中获得活动选项卡的URI。- 如果是这种情况,请参阅我对"如何通过e10s附加组件获得活动选项卡位置"的回答。在这种情况下,您运行的上下文应该允许您使用该答案中的代码。
这个可能的假设,#1,并不适用于你的代码。 - 您希望访问已经加载到侧边栏的
<browser>
中的URI表单代码,并且不知道将<browser>
type
设置为content
对加载到<browser>
的代码施加的限制。- 看起来你正试图从
<browser>
中的代码访问当前选项卡的URL。您应该考虑重组您的代码,以便访问chrome特权不需要从<browser>
中的内容。换句话说,如果可能的话,您应该编写这样的代码,使您不需要直接从您插入的<browser>
中运行的代码访问URL或其他信息。然而,这样做最终可能会变得更加复杂。
- 看起来你正试图从
获得chrome权限在<browser>
你添加:
设置<browser>
type
为content
是为了:
内容浏览器。浏览器内部加载的内容不允许访问它上面的chrome。
设置<browser>
type
为chrome
是为了:
(默认行为):一个浏览器,旨在通过chrome://URI加载特权内容。不要使用来自web的内容,因为这可能会导致严重的安全问题!
设置<browser>
type
为chrome
,命令如下:
var propsToSet = {
id: 'demo-sidebar-with-html_browser',
type: 'chrome', //<---------------------------This
Noitidart提供的代码接近于您所需要的。但是,它需要稍加修改,因为gBrowser.currentURI
是一个nsIURI,而不是字符串)。因此,您需要使用gBrowser.currentURI.spec
。您可以通过将makeHTML()
更改为:
来使其工作。function makeHTML(value, key){
var arrValues = value.split(",");
var htmlContent = '<html><head></head>'
+ '<body style="background-color: white;">'
+ ' <div name="content" class="content">'
+ ' <p> Name :' + arrValues[0] + '</p>';
htmlContent += '<p> Price :' + arrValues[2] + '</p>';
htmlContent += '<p> Color :' + arrValues[3] + '</p>';
htmlContent += '<p> UID :' + arrValues[1] + '</p>';
htmlContent +=
' <p><input type="radio" name="valid" value="yes" />Yes '
+ ' <input type="radio" name="valid" value="no" /> No</p>'
+ ' <p><input type="text" placeholder="Reason" name="checkreason" /></p>'
+ ' <p><input type="text" placeholder="Feedback" name="feedback" /></p>'
+ ' </div>'
+ ' <div>'
+ ' <button name="load" type="button" id="loadit" onclick="loadHtml()" '
+ ' loadurl="' + arrValues[4] + '">Load</button>'
+ ' <button name="save" type="button">Save </button>'
+ ' <button name="next" type="button" key="' + key + '">Next </button>'
+ ' </div>'
+ ' <script>'
+ ' function loadHtml() {'
+ ' const Cu = Components.utils;'
+ ' Cu.import("resource://gre/modules/Services.jsm");'
+ ' var win = Services.wm.getMostRecentWindow("navigator:browser");'
+ ' if (win) {'
+ ' var url = win.gBrowser.currentURI.spec;'
+ ' alert("URL=" + url);'
+ ' }'
+ ' }'
+ ' </script>'
+ '</body></html>';
return htmlContent;
}
安全问题:
您可能会遇到一些非常重要的安全问题。仅从您想要当前页面的URL这一事实就可以看出,您可能很快就会遇到这些真正的问题。这取决于你要做的到底是什么。鉴于你没有提供这些信息,我就不打算太深入地讨论问题是什么了。但是,你应该阅读"Firefox开发人员安全基础"one_answers"扩展中的安全最佳实践"
关于侧边栏的附加信息:
你应该认真地考虑创建一个基于SDK的附加组件,而不是一个引导组件,并使用ui/侧边栏API。
如果你感兴趣,我创建了一些代码,可以用来创建一个"侧边栏",位于活动选项卡的顶部,左侧,右侧或底部,或在一个单独的窗口(类似于devtools面板将做什么)。创建的侧边栏与当前活动选项卡相关联,而不是所有选项卡(我想我应该把它作为一个选项,让它与所有选项卡相关联,或者只是当前选项卡)在我的回答:"如何在Firefox中使用XUL创建一个底部停靠面板?"one_answers"Firefox扩展,窗口相关的侧边栏"