Проблема с добавлением кнопки плюс одна в окно XUL

Я пытаюсь добавить кнопку плюс одна в окно XUL, но получаю такую ​​ошибку:

Error: Permission denied for <https://plusone.google.com> to call method ChromeWindow.postMessage
Source file: https://ssl.gstatic.com/webclient/js/gc/22431124-0a127465/googleapis.client__plusone.js
Line: 14

Я добавляю iframe в https://plusone.google.com/u/0/_/+1/fastbutton?url= ...

Есть ли способ добавить кнопку +1 в окно XUL и заставить его принимать postMessage?


Аддон, который я пытаюсь разработать, показан на изображении ниже. Единственная проблема в том, что он не регистрирует клик из-за разрешения.

+ 1 любой

bootstrap.js (bootstrap-vsdoc.js)

/// <reference path="bootstrap-vsdoc.js" />

/// <summary>
/// Made by Bruno Leonardo Michels
/// </summary>

var watcher = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
                        .getService(Components.interfaces.nsIWindowWatcher);

var listenOpen = {
    observe : function(cWindow, cEvent) {
        if (cEvent != "domwindowopened") return;
            cWindow.addEventListener("load", start, false);
    }
};

function startup(data, reason) {
    watcher.registerNotification(listenOpen);

    var mWindows = watcher.getWindowEnumerator();
    while (mWindows.hasMoreElements()) {
        start(mWindows.getNext());
    }
}
function shutdown(data, reason) {
    watcher.unregisterNotification(listenOpen);

    var mWindows = watcher.getWindowEnumerator();
    while (mWindows.hasMoreElements()) {
        end(mWindows.getNext());
    }
}
function install(data, reason) {

}
function uninstall(data, reason) {

}

/// #region Methods

function getWindow(cWindow)
{
    try
    {
        if (cWindow instanceof Components.interfaces.nsIDOMEvent)
        {
            cWindow = cWindow.currentTarget;
        }
        if (cWindow.document.documentElement.getAttribute("windowtype") != "navigator:browser")
            return;
    }
    catch(ex) { }

    return cWindow;
}

function ajaxGet(cWindow, url, cb)
{
    var xmlhttp;
    xmlhttp = new cWindow.XMLHttpRequest();
    xmlhttp.open("GET", url, true);
    xmlhttp.onreadystatechange=function()
    {
        if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
        {
            cb(xmlhttp);
        }
    };
    xmlhttp.send();
}

var eventList = [];
function bind(gBrowser, cWindow, target, eventName, fn)
{
    var ev = function(e) { fn(gBrowser, cWindow, e); };
    eventList.push(ev);
    target.addEventListener(eventName, eventList[eventList.length-1], false);
}
function unbind(target, eventName, fn)
{
    var b = target.removeEventListener ?
        function( elem, type, handle ) {
            if ( elem.removeEventListener ) {
                elem.removeEventListener( type, handle, false );
            }
        } :
        function( elem, type, handle ) {
            if ( elem.detachEvent ) {
                elem.detachEvent( "on" + type, handle );
            }
        };

    b(target, eventName, fn);
}
function unbindAll(target, eventName)
{
    for (var i in eventList)
    {
        unbind(target, eventName, eventList[i]);
    }
}

/// #endregion

/// #region Events

function start(cWindow) {
    cWindow = getWindow(cWindow);

    if (!cWindow) return;

    with (cWindow)
    {
        bind(gBrowser, cWindow, gBrowser.tabContainer, "TabAttrModified", tabChange);

        var window = cWindow;
        var document = cWindow.document;

        var url = window.location.href;
        if (!/^http/i.test(url))url="http://www.orkutmanager.net/";
        var urlE= window.encodeURIComponent(url);

        var iconsBar = document.getElementById("urlbar-icons");

        function insScript(w)
        {
            var sc = document.createElement("script");
            sc.src = "https://apis.google.com/js/plusone.js";
            sc.type= "text/javascript";
            sc.setAttribute("extension", "plusoneany");
            (document.lastChild).appendChild(sc);
        }
        insScript(this);
        insScript(this.parent);
        insScript(this.top);

        var button = document.createElement("iframe");
        button.id = "extensions.plusoneany.button";
        button.setAttribute("src", "https://plusone.google.com/u/0/_/+1/fastbutton?url=" + urlE +
            "&size=small&count=true&hl=en-US&_methods=onPlusOne%2C_ready%2C_close%2C_open%2C_resizeMe");
        button.setAttribute("class", "urlbar-icon extensions-plusoneany");
        button.setAttribute("style", "border:0;padding:0;margin:0;width:70px;height:16px;");

        iconsBar.insertBefore(button, iconsBar.lastChild);
    }
}
function end(cWindow) {
    try
    {
        unbindAll(gBrowser.tabContainer, "TabAttrModified");
    }
    catch(ex){}

    try
    {
        var elements = cWindow.document.getElementsByClassName("extensions-plusoneany");

        for (var i in elements)
        {
            elements[i].parentNode.removeChild(elements[i]);
        }
    }
    catch(ex){}
}

function tabChange(gBrowser, cWindow, e) {
    var win = gBrowser.selectedBrowser.contentWindow;
    var uns = gBrowser.selectedBrowser.contentWindow.wrappedJSObject;

    uns.clearTimeout(uns.PlusOneAnyTimeout);

    uns.PlusOneAnyTimeout = uns.setTimeout(function() {
        var url = win.location.href;
        if (!/^http/i.test(url))url="http://www.orkutmanager.net/";
        var urlE= uns.encodeURIComponent(url);

        try {
            var ifr = cWindow.document.getElementById("extensions.plusoneany.button");
            ifr.setAttribute("src", "https://plusone.google.com/u/0/_/+1/fastbutton?url=" + urlE +
                "&size=small&count=true&hl=en-US&_methods=onPlusOne%2C_ready%2C_close%2C_open%2C_resizeMe");
        }catch(ex){}
    }, 500);
}

/// #endregion

person BrunoLM    schedule 24.07.2011    source источник
comment
Вы пытались принудительно указать type для content / chrome?   -  person systempuntoout    schedule 02.08.2011


Ответы (4)


@systempuntoout прав в том, что теоретически установка атрибута типа iframe в "content" должна исправить это. Однако в прошлом у меня были проблемы с этим. Это может сработать, но я думаю, что XUL в этом отношении немного глючит. Если бы это был я, я бы встроил элемент XUL ‹browser> вместо XUL ‹iframe> и загрузил бы статическую HTML-страницу в браузер (т.е. вызвав browser.loadURI), который содержит код, который я хочу запустить (в данном случае iframe с параметром src, равным "https: //plusone.google.com ..."). Таким образом, ваш код будет работать как реальное содержимое, как и в главном окне содержимого браузера.

Вы можете записать HTML-страницу на диск (поскольку часть источника iframe создается динамически), а затем ссылаться на нее с помощью URL-адреса file: //. Поскольку в этом случае код будет довольно коротким, вы даже можете попробовать использовать URI данных, что избавит вас от необходимости записывать временный файл на диск.

Другими словами, вы должны создать HTML-файл (в памяти или на диске) с:

<html>
<body>
<iframe src="https://plusone.google.com..." />
</body>
</html>

Затем вы должны создать элемент ‹browser>, как вы это делаете сейчас для iframe, вставить его в свой XUL-документ и вызвать для него loadURI (), ссылаясь на файл HTML (через file: или data: URI).

person Matthew Gertner    schedule 02.08.2011

Я бы попытался указать type, добавив эту строку:

ifr.setAttribute("type","content");
person systempuntoout    schedule 02.08.2011

Я думаю, это может быть полезно, это может быть проблема, с которой вы столкнулись.

Как использовать window.postMessage в разных доменах?

person shelman    schedule 27.07.2011

Чрезвычайно злой ответ, но нельзя ли просто получить содержимое https://apis.google.com/js/plusone.js и затем оценить его? Это Google, что может пойти не так;]

person tomdemuyt    schedule 01.08.2011