Переменная CKEditor доступна в консоли, но не из пользовательского скрипта Chrome? - PullRequest
2 голосов
/ 29 января 2012

Я пишу пользовательский скрипт Chrome для локального автоматического сохранения содержимого в CKEditor . Я использую этот плагин автосохранения CKEditor в качестве вдохновения.

Я написал функцию, которая запускается каждые полсекунды (через интервал) для регистрации обработчика события CKEditor:

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 не определен» в операторе if (CKEDITOR).

Между тем, если я зайду в консоль Chrome и наберу CKEDITOR, консоль напечатает ожидаемый объект.

Что мне не хватает? Редактор встроен в iframe; может ли это повлиять на определение объема? Или я борюсь с песочницей Chrome здесь? И если да, есть ли какой-нибудь другой способ, которым я могу копаться в CKEditor, чтобы извлекать контент каждую секунду, или что-то делать для автоматического сохранения?

Я еще не пробовал скрипт в Firefox; это следующий в моем списке.

Стоит отметить: я давний начинающий JavaScript. Так что я мог бы легко делать что-то глупое с областью видимости или что-то подобное.

1 Ответ

2 голосов
/ 29 января 2012

Согласно этому небольшому обучающему видео на YouTube, все 3 "устройства" отделены друг от друга, чтобы предотвратить атаки XSS со стороны пользовательского скрипта на браузер / веб-сайт и наоборот. Хотя пользовательские сценарии / сценарии содержимого выполняются в контексте веб-сайта, они по-прежнему хранятся отдельно от фактического контекста сценария веб-сайта. Вы можете легко подтвердить это, просто попытавшись получить доступ, например, к jQuery из скрипта контента. Как и CKEditor, он не будет доступен.

Итак, что я придумал, чтобы справиться с этим, так это использование скрипта контента для включения внешних JavaScripts в тег head. AFAIK, это невозможно для файлов непосредственно в корневом каталоге расширения, поэтому я взял удаленный сервер для размещения своих файлов.

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


(Отредактировано OP, поэтому я могу выбрать этот ответ и правильно направить карму)

Этот ответ, в сочетании с некоторыми предложениями и ссылками в комментариях, в итоге привел меня туда, где я должен был быть.

Я получил следующую функцию:

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, но подозреваю, что шаблон может работать в скрипте GreaseMonkey, развернутом через расширение Chrome TamperMonkey, при условии, что URL-адрес внедряемого сценария размещен где-то достижимым.

FTR, как выясняется, мне фактически не нужно было переходить на iframe - переменная CKEDITOR была определена в документе верхнего уровня, но просто не была видна из-за правил песочницы Chrome

...