CKEditor变量在控制台中可用,但不是从Chrome用户脚本? [英] CKEditor variable is available in console, but not from a Chrome userscript?

查看:315
本文介绍了CKEditor变量在控制台中可用,但不是从Chrome用户脚本?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个Chrome用户脚本,以在本地自动保存CKEditor中的内容。我使用此CKEditor自动保存插件作为灵感。

I'm writing a Chrome userscript to locally auto-save content in a CKEditor. I'm using this CKEditor auto-save plugin as inspiration.

我写了一个函数,每隔半秒触发一次(通过间隔)注册 CKEditor 事件处理程序:

I have written a function that fires every half second (via an interval) to register the CKEditor event handler:

var intervalId = window.setInterval(function() {
    if (CKEDITOR) {
        window.clearInterval(intervalId);
        CKEDITOR.plugins.add("user-script-auto-save", {
            init : function(editor) {
                editor.on('key', startTimer);
            }
        });
    }
}, 500);

但是,它从未正确完成,并抱怨CKEDITOR未定义 c> if(CKEDITOR)语句。

However, it never properly completes, and complains that "CKEDITOR is undefined" on the if (CKEDITOR) statement.

同时,如果我进入Chrome的控制台并输入 CKEDITOR ,控制台打印出期望的对象。

Meanwhile, if I drop into Chrome's console and type CKEDITOR, the console prints out the expected object.

我缺少什么?编辑器嵌入在iframe中;可能对范围界定有影响?还是我在这里打击Chrome的沙箱?如果是这样,有没有其他方法,我可以挖掘CKEditor拉出内容每秒或什么做自动保存?

What am I missing? The editor is embedded within an iframe; might that have an impact on scoping? Or am I fighting against Chrome's sandboxing here? And if so, is there some other way I can dig into CKEditor to pull out the content every second or something to do the auto-saves?

我还没有尝试在Firefox中的脚本;这是我的列表中的下一个。

I have not yet tried the script in Firefox; that's next on my list.

值得注意的是:我是一个长期的JavaScript新手。

Worth noting: I'm a long-time JavaScript novice. So I could easily be doing something dumb with scoping or something like that.

推荐答案

根据这个小教程视频,所有3个设备彼此分离,以防止用户的XSS攻击脚本到浏览器/网站,反之亦然。尽管用户脚本/内容脚本在网站的上下文中运行,但它们仍然与实际网站脚本上下文分离。您可以通过简单地尝试从内容脚本访问例如jQuery来容易地认可这一点。就像CKEditor一样,它将不可用。

According to this little tutorial video on YouTube, all the 3 "devices" are separated from each other in order to prevent XSS attacks from the user script to the browser / website and vice versa. Although the user scripts / content scripts are running in the website's context, they are still kept separated from the actual website script context. You can easily acknowledge this by simply trying to access for example jQuery from a content script. Just as the CKEditor, it will not be available.

因此,为了解决这个问题,我使用内容脚本来包含外部JavaScript头标签。 AFAIK,这是不可能的文件直接在扩展的根目录,所以我已经采取了远程服务器托管我的文件。

So what I've come up with in order to deal with this is using the content script to include external JavaScripts in the head tag. AFAIK, this is not possible for files directly in the extension's root directory, so I've taken a remote server to host my files.

我不知道这个是最好的方法,我认为这是一个丑陋的绕过,可能的方式到强大和残疾的Chromium项目一段时间。

I'm not sure if this is the best approach and I think it is an ugly bypass, possibly way to powerfull and disabled by the Chromium Project some time.

(由OP编辑,所以我可以选择这个答案并适当地路由karma)

(Edited by OP, so I can select this answer and route karma appropriately)

这个答案,加上评论中的一些建议和链接

This answer, combined with some of the suggestions and links in the comments, ended up getting me to where I needed to be.

我最终得到了以下函数:

I ended up with the following function:

var insertScriptIntoDocument = function(scriptUrl, doc) {
    // inspired by http://blog.afterthedeadline.com/2010/05/14/how-to-jump-through-hoops-and-make-a-chrome-extension/
    var scriptText = doc.createTextNode(
        '(function(loc) {                                                    \
    var embeddedScript = document.createElement("script");                   \
    embeddedScript.type = "text/javascript";                                 \
    embeddedScript.src = loc;                                                \
    document.getElementsByTagName("head")[0].appendChild(embeddedScript);    \
})("' + scriptUrl + '");');

    var injectorElement = doc.createElement('script');
    injectorElement.appendChild(scriptText);
    doc.body.appendChild(injectorElement);
};

用法如下:

var embeddedScriptUrl = chrome.extension.getURL("embedded-script.js");
insertScriptIntoDocument(embeddedScriptUrl, document);

现在,但我怀疑这种模式可能在通过Chrome TamperMonkey扩展部署的GreaseMonkey脚本中工作,只要要嵌入的脚本的URL托管在某处可达。

For now, I'm executing this from within a Chrome extension, but I suspect that the pattern might work in a GreaseMonkey script deployed via the Chrome TamperMonkey extension provided that the URL of the script to be embedded was hosted somewhere reachable.

FTR,事实证明,我实际上不需要访问iframe - CKEDITOR变量是在顶级文档中定义的,但是因为 Chrome沙箱的规则

FTR, as it turns out, I did not actually need to get to the iframe -- the CKEDITOR variable was defined in the top-level document, but was simply not visible because of the rules of the Chrome sandbox

这篇关于CKEditor变量在控制台中可用,但不是从Chrome用户脚本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆