22.05.2008, 04:53
|
Новичок на форуме
|
|
Регистрация: 22.05.2008
Сообщений: 8
|
|
Расширение к FF
Вот скрипт расширения к FF
<?xml version="1.0"?>
<overlay id="sample"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/x-javascript">
<![CDATA[
function repl() {
alert('I am sample extension!');
}
window.addEventListener("load", repl, true);
]]>
</script>
<statusbar id="status-bar">
<statusbarpanel id="my-panel" label="Sample extension work."/>
</statusbar>
</overlay>
Он срабатывает после загрузки в браузер каждого нового документа.
Задача: В функции repl() получить текст первого скрипта в загруженном документе. Как построить строку обращения?
Помогите, плиз, кто в курсе.
Последний раз редактировалось Андрей Параничев, 06.01.2009 в 19:14.
Причина: Пользуйтесь bb-тегами [js] и [html] для оформления листингов кода в теле сообщения
|
|
22.05.2008, 11:47
|
Новичок на форуме
|
|
Регистрация: 22.05.2008
Сообщений: 8
|
|
Этот вопрос снимается. Строка обращения выглядит так
s=content.document.getElementsByTagName("script")[i].text;
и в переменной s содержимое скрипта.
Однако, теперь новая проблема.
Модифицируем s и присваиваем
content.document.getElementsByTagName("script")[i].text=s;
Инспектор DOM показывает измененный текст, однако в загруженной странице содержимое скрипта не изменилось и на выполнение запускается исходный вариант.
Как же заставить работать измененный скрипт?
|
|
22.05.2008, 11:53
|
Профессор
|
|
Регистрация: 18.04.2008
Сообщений: 152
|
|
Vladimir, не знаток я ксула, но посоветую удалять первый скрипт и создавать вместо него новый.
|
|
23.05.2008, 21:22
|
Новичок на форуме
|
|
Регистрация: 22.05.2008
Сообщений: 8
|
|
Спасибо. Однако, не могу найти подходящих методов для удаления старого и вставки нового скриптов. Поиски продолжаю, но может кто уже знает, подскажите, плиз.
|
|
24.05.2008, 00:41
|
|
|
Регистрация: 21.02.2008
Сообщений: 1,250
|
|
Читайте туториалы DOM. Всё, что вам надо сделать, это сделать removeChild() для этого элемента <script>, а затем, создав новый вставить его через appendChild(). Это будет выглядеть примерно так (возможны ошибки, поэтому лучше сами прочтите материалы по этой теме):
var scriptElement = document.getElementsByTagName('script')[0];
var newScriptElement = document.createElement('script');
// Выполняем действия с новым элементом скрипт:
newScriptElement.type = 'text/javascript';
if(scriptElement.parentNode)
{
var scriptParent = scriptElement.parentNode;
scriptParent.removeChild(scriptElement);
scriptParent.appendChild(newScriptElement);
}
Пока писал мне пришла в голову идея лучше. Собственно, зачем вам вставлять тег скрипт через javascript в тело html? Если только для того, что бы выполнить модифицированный код, то воспользуйтесь функцией eval(), например так:
var scriptElement = document.getElementsByTagName("script")[0];
var scriptContent = scriptElement.text;
// ... Тут выполняем действия с scriptContent ...
eval(scriptContent);
А если вам нужно "хранить" этот скрипт, то подходящим контейнером не обязательно должен быть какой-то элемент html, храните её в переменной.
Последний раз редактировалось Андрей Параничев, 24.05.2008 в 01:21.
|
|
24.05.2008, 11:30
|
Новичок на форуме
|
|
Регистрация: 22.05.2008
Сообщений: 8
|
|
Спасибо за развернутый ответ. Я смотрел туториалы DOM и XUL. Перебробовал множество вариантов. Проблема, однако, в том, что скрипт расширения находится в chrome, а скрипт, который надо изменить - в основном документе. Т.е. сначала я получаю в хроме текст скрипта основного документа как
s=content.document.getElementsByTagName("script")[0].text;
это работает.
затем я меняю скрипт в переменной "s" и делаю обратное присвоение
сontent.document.getElementsByTagName("script")[0].text=s;
Инспектор DOM показывает измененный текст скрипта, однако страница в браузере прежняя - без учета изменений. replaceChild дает тот же результат.
Ставлю эксперимент - просто хочу удалить скрипт с главной страницы:
node=content.document.getElementsByTagName("script ")[0];
node.parentNode.removeChild(node);
Инспектор DOM показывает дерево уже без скрипта, но в браузере страница прежняя - со скриптом.
Нашел, что якобы для возможности модификации основного документа в XUL файле (где находится скрипт расширения) должен быть тэг
<browser type="content-primary"/>
Вставил. Все без изменений.
Получается, что все изменения отображаются только в дереве DOM и никак не затрагивают самого, загруженного в браузер, документа.
Но изменить-то нужно именно его. А как? Чего не хватает?
(То, что ума не хватает, то понятно).
Чего не хватает в хромовом скрипте. Или в XUL файле.
Может защиту какую-то снять надо с основного документа или дать ксуловскому скрипту какие-то привилегии?
|
|
24.05.2008, 15:34
|
|
|
Регистрация: 21.02.2008
Сообщений: 1,250
|
|
Vladimir,
Давайте немного разберёмся. Во-первых, все изменения и, собственно, текущее состояние документа отражено только в DOM. Значит, удалив <script> из DOM он удалится из текущего открытого документа. Вполне ожидаемо, что если вы посмотрите html код этого документа он будет первоначальный. Т.к. все изменения происходят только с текущим экземпляром, а не его "исходным" файлом. Хотя думаю вопрос не в этом. Во-вторых, удалив <script> мы не удаляем уже выполнившийся в нём код, так что если в нем была объявлена какая-то функция, она будет работать, даже после удаления этого элемента со страницы. И в третьих, если я не ошибаюсь, если вставить в DOM элемент <script>, содержащий javascript-код, этот код всё равно не будет выполнен. Этим способом можно только прикрепить <script> с определённым src, но не переписать уже загруженный код, а для выполнения кода есть функция eval().
Попробуйте подробнее описать задачу, которая перед вам стоит, наверно ответ тогда будет найден быстрее. Как я понимаю, вам надо переделать загруженный в страницу код, что-бы он выполнялся вместо уже загруженного кода? Тогда вы можете переопределить его, выполнив изменённый через eval() - все функции переопределятся и при их вызове будет выполнятся уже изменённый код.
|
|
24.05.2008, 16:32
|
Новичок на форуме
|
|
Регистрация: 22.05.2008
Сообщений: 8
|
|
Полное описание задачи.
Есть такая страница которая грузится в FF с какого-то сайта.
<html>
<head>
<title>Test page 1</title>
<script>
function hiName() {
alert("Hi Nickolay!");
}
</script>
</head>
<body onLoad="hiName()">
<p>This is the body text.
</body>
</html>
Задача: Средствами браузера изменить содержимое скрипта таким образом, чтобы после загрузки страницы
в окне alert функцией "hiName()" был выведен текст "Hi Vladimir!", а не "Hi Nickolay!".
Очевидно, что заменить "Nikolay" на "Vladimir" нужно после окончания загрузки страницы в браузер, но перед
тем как будет выполнена функция "hiName()" по событию "onLoad" тэга "body".
Пытаемся решить эту задачу с помощью небольшого расширения к FF.
Гвоздем расширения является файл sample.xul в котором находится скрипт расширения.
<?xml version="1.0"?>
<overlay id="sample"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<browser type="content-primary"/>
<script type="application/x-javascript">
<![CDATA[
function repl() {
var s=content.document.getElementsByTagName("script");
for (i=0;i<s.length;++i) {
node=s[i];
if (node.text) {
t=node.text;
e=t.indexOf('Nikolay');
if (e > 0) {
z=t.replace('Nikolay','Vladimir');
node.text=z;
}
}
}
}
window.addEventListener("load", repl, true);
]]>
</script>
<statusbar id="status-bar">
<statusbarpanel id="my-panel" label="Sample extension work."/>
</statusbar>
</overlay>
В результате текст скрипта в дереве DOM содержит "Vladimir", но все равно в главной странице работает скрипт
с "Nickolay".
Строки
ex="<script language=javascript1.2>"+z+"hiName()</script>";
eval(ex);
вставленные после строки
node.text=z;
нечего не изменили.
Метод "replaceChild" вместо "node.text=z" дает тот же результат.
Вроде как все заколдованное.
Как расколдовать и заставить его делать то, что нужно?
|
|
24.05.2008, 16:40
|
|
|
Регистрация: 21.02.2008
Сообщений: 1,250
|
|
Vladimir,
Получается, что ваша основная задача не в том, чтобы заменить скрипт на изменённый, а опередить событие document.body.onLoad(), которое срабатывает до window.addEventListener("load", repl, true). Тут надо подумать.
|
|
24.05.2008, 18:04
|
Новичок на форуме
|
|
Регистрация: 22.05.2008
Сообщений: 8
|
|
Я думаю, что событие document.body.onLoad() срабатывает после window.addEventListener("load", repl, true). Я так думаю потому, что если добавить в ксуловский скрипт после строки
node.text=z;
строку
alert('Ok.');
то "Ok" будет выведено до того, как появится "Hi Nickolay!".
|
|
|
|