LINUX.ORG.RU

С помощью юзер-скрипта заменить одну функцию на сайте


0

1

Есть один сайт (точнее движок), на нём есть скрипт, в котором есть функция, которая работает ну очень медленно. Я написал оптимизированную версию, в которой используется линейный алгоритм вместо квадратичного, но проблема в том, как бы её прикрутить.

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

★★★

Нужно как-то вклиниться между определением функции и её вызовом и сделать что-то вроде window.func_name = my_function. Возможно, что вклиниться и не получится – если определение и вызов функции идут в одном и том же скрипте, и между ними нет ничего, за что можно зацепиться.

Miguel ★★★★★
()
Ответ на: комментарий от Miguel

Да, они идут в одном скрипте... Может как-то можно весь файл скрипта подменить на мой?

Yareg ★★★
() автор топика

Если она в глобальной области видимости, то в Опере есть opera.defineMagicFunction(). В Fx не знаю :}

Deleted
()
Ответ на: комментарий от Miguel

Вроде бы они отрабатывают по домконтентлоадед, который раньше онлоад, но простое виндоу.нужнаяфункция = функшн(...) { ...; }; не хочет работать.

Yareg ★★★
() автор топика
Ответ на: комментарий от Yareg

Насколько я помню свои опыты с greasemonkey, скрипты отрабатывают после загрузки страницы.

Hoodoo ★★★★★
()

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

OramahMaalhur
()
Ответ на: комментарий от Yareg

>простое виндоу.нужнаяфункция

А браузер какой? Firefox + Greasemonkey?

Тогда сначала попробуй unsafeWindow.нужнаяфункция = ...

Если не пойдет, можешь попробовать встроить свой скрипт прямо на страницу, как это делает, например, LORTreeView для Chrome.

proud_anon ★★★★★
()
Ответ на: комментарий от proud_anon

>Тогда сначала попробуй unsafeWindow.нужнаяфункция = ...

То что нужно! Только пришлось ещё перед всеми вызовами глобальных объектов, в том числе jqur'ного $ ставить unsafeWindow.

Только проблема теперь в, в файрфоксе оно работает, а в хромиуме не очень похоже, что работает. Я попробовал вставить вот такую функцию для кроссбраузерности, найденную где-то:

[code=javascript]
function testGM() {
var isGM = typeof GM_getValue != 'undefined' && typeof GM_getValue('a', 'b') != 'undefined';
if(typeof(unsafeWindow) == 'undefined') { unsafeWindow = window; }
if(!isGM) { log = function(msg) { try { unsafeWindow.console.log(msg); } catch(e) {} }; } else { log = GM_log; }
if(window.opera) log = opera.postError;
setValue = isGM ? GM_setValue : function(name, value) { return localStorage.setItem(name, value) };
getValue = isGM ? GM_getValue : function(name, def) { var s = localStorage.getItem(name); return s == null ? def : s };
}
[/code]

но, похоже, оно не работает так, как мне нужно...

Yareg ★★★
() автор топика
Ответ на: комментарий от Yareg

>Только пришлось ещё перед всеми вызовами глобальных объектов, в том числе jqur'ного $ ставить unsafeWindow.

Это потому, что в переменной window, которую видит юзерскрипт в Greasemonkey, находится XrayWrapper, которым чего-то там изолирует. А «настоящий» DOMWindow находится в window.wrappedJSObject. Переменная unsafeWindow равна window.wrappedJSObject. Подробнее про это все читайте в Wiki Greasemonkey, если хотите.

Хромиум предоставляет доступ к window, а для совместимости с Greasemonkey, конвертируя скрипт в расширение, делает так:

(function(unsafeWindow) {
   //Тут код вашего юзерскрипта
})(window);

Таким образом, все вроде бы должно работать, но есть одно маленькое но. Расширения Chrome (по крайней мере, того типа, в который превращаются юзерскрипты) не могут получить доступа к переменным и функциям, определенным на странице. Поэтому у вас и не работает.

Можете попробовать обращаться только к элементам DOM, это сработает.

Еще можете, как я уже писал, добавлять на страницу элемент <script>, переопределяющий нужную функцию. Он уже будет целиком в контексте страницы. Не думаю, что для этого нужно будет сильно переделывать имеющийся скрипт, просто сделайте что-то типа:
var document = unsafeWindow.document;
var script = document.createElement("script");
script.appendChild(document.createTextNode(yourfunction.toString())); //Или через innerHTML
document.body.appendChild(script);
Что касается вашей функции для совместимости, то вам от нее, скорее всего, будет нужна только совместимость window/unsafeWindow, если только не используете специальных функций Greasemonkey.

Может быть, кто-то знает, как умнее сделать.

proud_anon ★★★★★
()
Ответ на: комментарий от proud_anon

>Не думаю, что для этого нужно будет сильно переделывать имеющийся скрипт
Ну, только учесть нужно, что в контексте страницы не будет определено unsafeWindow, убедитесь, что переменная определена внутри добавляемой функции.

proud_anon ★★★★★
()
Ответ на: комментарий от proud_anon

>Расширения Chrome (по крайней мере, того типа, в который превращаются юзерскрипты) не могут получить доступа к переменным и функциям, определенным на странице.

Уточню: не могут получить доступ напрямую, как вы сейчас пытаетесь, но могут получить его через DOM (например, вызвать слушатель событий, установленный хоть скриптом на странице, хоть другим юзерскриптом).

proud_anon ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.