aboutsummaryrefslogtreecommitdiff
path: root/files/ru/mozilla/add-ons/sdk/guides/скрипты_содержимого/index.html
diff options
context:
space:
mode:
Diffstat (limited to 'files/ru/mozilla/add-ons/sdk/guides/скрипты_содержимого/index.html')
-rw-r--r--files/ru/mozilla/add-ons/sdk/guides/скрипты_содержимого/index.html519
1 files changed, 0 insertions, 519 deletions
diff --git a/files/ru/mozilla/add-ons/sdk/guides/скрипты_содержимого/index.html b/files/ru/mozilla/add-ons/sdk/guides/скрипты_содержимого/index.html
deleted file mode 100644
index 59832331e8..0000000000
--- a/files/ru/mozilla/add-ons/sdk/guides/скрипты_содержимого/index.html
+++ /dev/null
@@ -1,519 +0,0 @@
----
-title: Скрипты Content Scripts
-slug: Mozilla/Add-ons/SDK/Guides/Скрипты_содержимого
-tags:
- - Content script
- - Дополнение
-translation_of: Archive/Add-ons/Add-on_SDK/Guides/Content_Scripts
----
-<article id="wikiArticle">
-<p>{{AddonSidebar}}</p>
-
-<div class="blockIndicator warning">
-<p>Support for extensions using XUL/XPCOM or the Add-on SDK was removed in Firefox 57, released November 2017. As there is no supported version of Firefox enabling these technologies, this page will be removed by December 2020.</p>
-</div>
-
-<p>{{LegacyAddonsNotice}}</p>
-
-<p>Многим дополнениям (add-on) необходим доступ к веб-страницам и возможность их изменения. Но основной код дополнения не имеет прямого доступа к веб-содержимому. Взамен, SDK-дополнений необходим способ в коде, который даст доступ к веб-содержимому в отдельных скриптах, которые называются <code>content scripts</code> (скрипты содержимого). Эта страница описывает как разрабатывать и реализовывать <code>content scripts</code>.</p>
-
-<p>Скрипты <code>content scripts</code>, вероятно, один из наиболее сбивающих с толку аспектов при работе с SDK, но вам они скорее всего будут нужны. Существуют пять основных принципов:</p>
-
-<ul>
- <li>расширения основного кода, включая "main.js" и другие модули в "lib", могут использовать SDK <a href="/en-US/Add-ons/SDK/High-Level_APIs">верхнего-уровня</a> и <a href="/en-US/Add-ons/SDK/Low-Level_APIs">нижнего-уровня</a> API, но не имеют доступа к веб-содержимому напрямую;</li>
- <li>скрипты <code>content scripts </code><a href="/en-US/Add-ons/SDK/Guides/Two_Types_of_Scripts#API_Access_for_Add-on_Code_and_Content_Scripts">не могут использовать API в SDK</a> (нет доступа к глобальным <code>exports</code>, <code>require</code>) но есть доступ к веб-содержимому;</li>
- <li>API в SDK которые используют <code>content scripts</code>, например <a href="/en-US/Add-ons/SDK/High-Level_APIs/page-mod">page-mod</a> и <a href="/en-US/Add-ons/SDK/High-Level_APIs/tabs">tabs</a>, предоставляют функции, которые позволяют коду расширения загружать скрипты содержимого в веб-страницы;</li>
- <li>скрипты <code>content scripts </code>могут быть загружены как строки, но чаще они хранятся как отдельные файлы в папке "data". jpm не создаёт каталог "data" по умолчанию, поэтому вы должны создать его и положить туда ваши скрипты;</li>
- <li>API передачи сообщений позволяет основному коду и скриптам <code>content scripts </code>взаимодействовать друг с другом.</li>
-</ul>
-
-<p>Следующее дополнение (полностью завершённое) показывает эти принципы. "main.js" прикрепляет <code>content scripts</code> к текущей вкладке, используя модуль <a href="/en-US/Add-ons/SDK/High-Level_APIs/tabs">tabs</a>. В этом случае, <code>content scripts</code> передаётся, как строка. Скрипт <code>content scripts</code> просто заменяет содержимое страницы:</p>
-
-<pre class="brush: js">// main.js
-var tabs = require("sdk/tabs");
-var contentScriptString = 'document.body.innerHTML = "&lt;h1&gt;this page has been eaten&lt;/h1&gt;";'
-
-tabs.activeTab.attach({
- contentScript: contentScriptString
-});</pre>
-
-<p>Следующие высокоуровневые SDK-модули, могут использовать скрипты <code>content scripts </code>для изменения веб-страниц:</p>
-
-<ul>
- <li><a href="/en-US/Add-ons/SDK/High-Level_APIs/page-mod">page-mod</a>: позволяет вам прикреплять <code>content scripts</code> к веб-страницам, которые соответствуют заданному URL шаблону.</li>
- <li><a href="/en-US/Add-ons/SDK/High-Level_APIs/tabs">tabs</a>: экспортирует объект <code>Tab</code> для работы с вкладкой браузера. <code>Tab-объект включает</code> функцию <a href="/en-US/Add-ons/SDK/High-Level_APIs/tabs#attach(options)"><code>attach()</code></a>, которая позволяет прикрепить <code>content scripts</code> ко вкладке.</li>
- <li><a href="/en-US/Add-ons/SDK/High-Level_APIs/page-worker">page-worker</a>: позволяет вам получить страницу, без отображения её. Вы можете прикрепить <code>content scripts</code> к странице, чтобы иметь доступ и возможность изменять DOM страницы.</li>
- <li><a href="/en-US/Add-ons/SDK/High-Level_APIs/context-menu">context-menu</a>: использует <code>content scripts</code> для взаимодействия со страницей, в которой вызывается меню.</li>
-</ul>
-
-<p>В дополнение к этому, некоторые SDK компоненты пользовательского интерфейса - <code>panel, sidebar, frame</code> - заданы в помощью HTML, и необходимо использовать отдельные скрипты для взаимодействия с их контентом. В большинстве случаев они похожи на скрипты <code>content scripts</code>, но в данной статье они не описываются. Для изучения способов взаимодействия с данными модулями пользовательского интерфейса обратитесь к документации: <a href="/en-US/Add-ons/SDK/High-Level_APIs/panel">panel</a>, <a href="/en-US/Add-ons/SDK/Low-Level_APIs/ui_sidebar">sidebar</a>, <a href="/en-US/Add-ons/SDK/Low-Level_APIs/ui_frame">frame</a>.</p>
-
-<p>Почти все примеры дополнений, представленных в этом руководстве, доступны в полнофункциональном, но минимально необходимом, виде. На GitHub: <a href="https://github.com/mdn/addon-sdk-content-scripts">addon-sdk-content-scripts repository</a>.</p>
-
-<h2 id="Загрузка_content_scripts">Загрузка content scripts</h2>
-
-<article id="wikiArticle">
-<p>Вы можете загрузить одиночный скрипт посредством задания строкового атрибута <code>contentScript</code> или <code>contentScriptFile.</code> Атрибут<code> contentScript</code> определяет строковое значение как сам скрипт:</p>
-
-<pre class="brush: js">// main.js
-
-var pageMod = require("sdk/page-mod");
-var contentScriptValue = 'document.body.innerHTML = ' +
- ' "&lt;h1&gt;Page matches ruleset&lt;/h1&gt;";';
-
-pageMod.PageMod({
- include: "*.mozilla.org",
- contentScript: contentScriptValue
-});</pre>
-
-<p>Атрибут <code>contentScriptFile</code> определяет строковое значение как путь к ресурсу<code>://<em>URL-путь к скрипту, который находится в подкаталоге вашего дополнения</em>.</code> jpm не создаёт папку "data" по умолчанию, поэтому вы должны добавить её и положить внутрь файл <code>content scripts</code>.</p>
-
-<p>Следующее дополнение использует URL для ссылки на файл "content-script.js", находящийся в папке <code>data </code>в корне дополнения.</p>
-
-<pre class="brush: js">// main.js
-
-var data = require("sdk/self").data;
-var pageMod = require("sdk/page-mod");
-
-pageMod.PageMod({
- include: "*.mozilla.org",
- contentScriptFile: data.url("content-script.js")
-});</pre>
-
-<pre class="brush: js">// content-script.js
-
-document.body.innerHTML = "&lt;h1&gt;Page matches ruleset&lt;/h1&gt;";</pre>
-
-<div class="note">
-<p>Начиная с Firefox 34 и далее , вы можете использовать "./content-script.js" как синоним для self.data.url("content-script.js"). Поэтому можно переписать код main.js, указанный выше, следующим образом:</p>
-
-<pre class="brush: js">var pageMod = require("sdk/page-mod");
-
-pageMod.PageMod({
- include: "*.mozilla.org",
- contentScriptFile: "./content-script.js"
-});
-</pre>
-</div>
-
-<div class="warning">
-<p>Настоятельно рекоммендуется использовать  <code>contentScript </code>только для очень простых скриптов или статичных строк: если это не так, то могут возникнуть проблемы с принятием Вашего дополнения на AMO (<span class="st">addons.<em>mozilla</em>.org</span>).</p>
-
-<p>Содержите ваши скрипты в отдельном файле и загружайте их, используя <code>contentScriptFile</code>. Это сделает ваш код проще в поддержке, отладке, безопаснее, удобочитаемее.</p>
-</div>
-
-<p>Для любого из параметров<code> contentScript</code> или <code>contentScriptFile</code> вы можете загружать несколько скриптов, передавая массив строк:</p>
-
-<pre class="brush: js">// main.js
-
-var tabs = require("sdk/tabs");
-
-tabs.on('ready', function(tab) {
- tab.attach({
- contentScript: ['document.body.style.border = "5px solid red";', 'window.alert("hi");']
- });
-});
-</pre>
-
-<pre class="brush: js">// main.js
-
-var data = require("sdk/self").data;
-var pageMod = require("sdk/page-mod");
-
-pageMod.PageMod({
- include: "*.mozilla.org",
- contentScriptFile: [data.url("jquery.min.js"), data.url("my-content-script.js")]
-});</pre>
-
-<p>Если так сделать, то скрипты смогут взаимодействовать друг с другом, как скрипты загружаемые на одной web-странице.</p>
-
-<p>Можно использовать параметры <code>contentScript</code> and <code>contentScriptFile </code>одновременно. В таком случае скрипты, загружаемые <code>contentScriptFile</code>  загрузятся до <code>contentScript. </code>Это похволяет загружать библиотеки JavaScript, такие как jQuery по URL, а затем использвать их в простом скрипте, загруженном через <code>contentScript</code>:</p>
-
-<pre class="brush: js">// main.js
-
-var data = require("sdk/self").data;
-var pageMod = require("sdk/page-mod");
-
-var contentScriptString = '$("body").html("&lt;h1&gt;Page matches ruleset&lt;/h1&gt;");';
-
-pageMod.PageMod({
- include: "*.mozilla.org",
- contentScript: contentScriptString,
- contentScriptFile: data.url("jquery.js")
-});</pre>
-
-<div class="warning">
-<p>Настоятельно рекоммендуется использовать  <code>contentScript </code>только для очень простых скриптов или статичных строк: если это не так, то могут возникнуть проблемы с принятием Вашего дополнения на AMO (<span class="st">addons.<em>mozilla</em>.org</span>).</p>
-
-<p>Содержите ваши скрипты в отдельном файле и загружайте их, используя <code>contentScriptFile</code>. Это сделает ваш код проще в поддержке, отладке, безопаснее, удобочитаемее.</p>
-</div>
-
-<h3 id="Определение_момента_(времени)_подключения_скрипта">Определение момента (времени) подключения скрипта</h3>
-
-<p>Опция <code>contentScriptWhen </code>определяет момент, когда <code>content script</code> должен быть загружен. Возможные варианты:</p>
-
-<ul>
- <li><code>"start"</code>: загрузить сразу после того, как элемент документа страницы вставляется в DOM. В таком случае DOM-контент ещё пока не загружен, поэтому скрипт не может работать с ним.</li>
- <li><code>"ready"</code>: загрузить скрипт после того, как DOM страницы загружен: то есть в точке активации событий <a href="https://developer.mozilla.org/en/Gecko-Specific_DOM_Events">DOMContentLoaded</a>. В этот момент content scripts уже могут взаимодействовать с DOM-контентом, но загрузка внешних CSS и картинок ещё могла не завершиться.</li>
- <li><code>"end"</code>: загрузить скрипт после завершения загрузки всего контента (DOM, JS, CSS, картинки), в то время, как активируется событие <a href="https://developer.mozilla.org/en/DOM/window.onload">window.onload event</a>.</li>
-</ul>
-
-<p>Значение по умолчанию <code>"<strong>end</strong>"</code>.</p>
-
-<p>Обратите внимание, что <a href="/en-US/Add-ons/SDK/High-Level_APIs/tabs#attach(options)"><code>tab.attach()</code></a> не имеет параметра <code>contentScriptWhen</code>, потому что он обычно вызывается после загрузки страницы.<a href="/en-US/Add-ons/SDK/High-Level_APIs/tabs#attach(options)"><code> </code></a></p>
-
-<h3 id="Передача_конфигурационных_опций">Передача конфигурационных опций</h3>
-
-<p><code>Атрибут contentScriptOptions</code> это JSON-объект, который используется скриптом как read-only значение доступное через свойство <code><a href="/en-US/Add-ons/SDK/Guides/Content_Scripts/self">self</a>.options</code>:</p>
-
-<pre class="brush: js">// main.js
-
-var tabs = require("sdk/tabs");
-
-tabs.on('ready', function(tab) {
- tab.attach({
- contentScript: 'window.alert(self.options.message);',
- contentScriptOptions: {"message" : "hello world"}
- });
-});</pre>
-
-<p>Могут быть использованы любые варианты JSON-объектов (object, array, string, etc.).</p>
-
-<h2 id="Доступ_к_DOM">Доступ к DOM</h2>
-
-<p>Скрипты <code>content scripts</code> могут иметь доступ к DOM страницы, конечно, только те скрипты, которые уже загрузились на странице. При этом скрипты content scripts изолированы от скриптов web-страницы:</p>
-
-<ul>
- <li>content scripts не видят объектов JavaScript, добавленных скриптами web-страницы.</li>
- <li>Если скриты web-страницы переопределят поведения каких-либо DOM-объектов, то скрипты <code>content script</code> обнаружат исходное поведение.</li>
-</ul>
-
-<p>То же происходит в обратную сторону: скрипты web-страницы не увидят объектов JavaScript, добавленных скриптами <code>content scripts</code>.</p>
-
-<p>Например, рассмотрим страницу, где скрипты web-страницы создают переменную <code>foo </code>в объекте <code>window</code>:</p>
-
-<pre class="brush: html">&lt;!DOCTYPE html"&gt;
-&lt;html&gt;
- &lt;head&gt;
- &lt;script&gt;
- window.foo = "hello from page script"
- &lt;/script&gt;
- &lt;/head&gt;
-&lt;/html&gt;</pre>
-
-<p>Другой скрипт (но тоже page-script), загруженный на страницу после этого скрипта (указанного выше), будет иметь доступ к foo. Но скрипт <code>content script</code> нет:</p>
-
-<pre class="brush: js">// main.js
-
-var tabs = require("sdk/tabs");
-var mod = require("sdk/page-mod");
-var self = require("sdk/self");
-
-var pageUrl = self.data.url("page.html")
-
-var pageMod = mod.PageMod({
- include: pageUrl,
- contentScript: "console.log(window.foo);"
-})
-
-tabs.open(pageUrl);</pre>
-
-<pre>console.log: my-addon: null
-</pre>
-
-<p>Есть веские причины для изоляции. Во-первых, из <code>content script</code> не утекают объекты в web-страницу, что потенциально является дырой в безопасности. Во-вторых, <code>content scripts</code> могут не беспокоиться о пересечении объектов с объектами, созданных скриптами web-страницы.</p>
-
-<p>Такая изоляция необходима, например, в случае, если web-страница загружает библиотеку jQuery, но <code>content script</code> не увидит объектов, созданных этой библиотекой. В этом случае content script может добавить свою собственный jQuery-объект, который не пересечётся со страничным объектом.</p>
-
-<h3 id="Взаимодействие_со_скриптами_web-страницы">Взаимодействие со скриптами web-страницы</h3>
-
-<p>Обычно изоляция content scripts и page scripts (скрипты web-страницы) необходима. Но иногда вы захотите наладить такое взаимодействие: вы можете захотеть иметь общие объекты между <code>content scripts</code> и <code>page scripts</code> или передевать между ними сообщения. Если появится такая необходимость, то прочтите о <a href="/en-US/Add-ons/SDK/Guides/Content_Scripts/Interacting_with_page_scripts">взаимодействии со скриптами web-страницы</a> (<a href="/en-US/Add-ons/SDK/Guides/Content_Scripts/Interacting_with_page_scripts">interacting with page scripts</a>).</p>
-
-<h3 id="Прослушивание_событий">Прослушивание событий</h3>
-
-<p>Вы можете прослушивать события DOM в скриптах <code>content scripts</code> также, как в обычных скриптах web-страницы. Но есть два важных отличия:</p>
-
-<p>Первое. Если вы определите слушатель через передачу строки в функцию<a href="https://developer.mozilla.org/en/DOM/element.setAttribute"><code> setAttribute()</code></a>, то слушатель будет вызываться в контексте web-страницы, поэтому он не будет иметь доступа ни к каким переменным, определённым в <code>content script</code>.</p>
-
-<p>Например, при выполнении в данном <code>content script</code> появится ошибка "theMessage is not defined":</p>
-
-<pre class="brush: js">var theMessage = "Hello from content script!";
-anElement.setAttribute("onclick", "alert(theMessage);");</pre>
-
-<p>Второе. Если вы определите слушатель напрямую через <a href="/en-US/docs/Web/API/GlobalEventHandlers">GlobalEventHandlers</a>, например на <code>onclick</code>, то такое определение может быть переопределено на web-странице. Например, здесь представлен add-on, который пытается добавить обработчик click-события при помощи присвоения <code>window.onclick</code>:</p>
-
-<pre class="brush: js">var myScript = "window.onclick = function() {" +
- " console.log('unsafewindow.onclick: ' + window.document.title);" +
- "}";
-
-require("sdk/page-mod").PageMod({
- include: "*",
- contentScript: myScript,
- contentScriptWhen: "start"
-});</pre>
-
-<p>Это всё будет прекрасно работать на многих страницах, но не сработает там, где также присваивается <code>onclick</code>:</p>
-
-<pre class="brush: html">&lt;html&gt;
- &lt;head&gt;
- &lt;/head&gt;
- &lt;body&gt;
- &lt;script&gt;
- window.onclick = function() {
- window.alert("it's my click now!");
- }
- &lt;/script&gt;
- &lt;/body&gt;
-&lt;/html&gt;</pre>
-
-<p>По этим причинам, лучший вариант для добавления слушалелей это использование <a href="https://developer.mozilla.org/en/DOM/element.addEventListener"><code>addEventListener()</code></a>, определяющем функцию:</p>
-
-<pre class="brush: js">var theMessage = "Hello from content script!";
-
-anElement.onclick = function() {
- alert(theMessage);
-};
-
-anotherElement.addEventListener("click", function() {
- alert(theMessage);
-});</pre>
-
-<h2 id="Взаимодействие_с_скриптом_дополнения_(add-on)">Взаимодействие с скриптом дополнения (add-on)</h2>
-
-<p>Для организации взаимодействия друг с другом скрипта дополнения (<code>add-on script</code>) и скрипта <code>content script</code> нужно обоим дать доступ к объекту <code>port</code>.</p>
-
-<ul>
- <li>для отправки сообщений используется <code>port.emit()</code></li>
- <li>для получения сообщений - <code>port.on()</code></li>
-</ul>
-
-<p><img alt="" src="https://mdn.mozillademos.org/files/7873/content-scripting-overview.png" style="display: block; margin-left: auto; margin-right: auto;">Сообщения асинхронны: то есть, отправитель не ждёт ответа от получателя, а только отправляет сообщение и продолжает работать дальше.</p>
-
-<p>Вот пример простого дополнения, которое отправляет сообщение скрипту <code>content script, используя port</code>:</p>
-
-<pre class="brush: js">// main.js
-
-var tabs = require("sdk/tabs");
-var self = require("sdk/self");
-
-tabs.on("ready", function(tab) {
- var worker = tab.attach({
- contentScriptFile: self.data.url("content-script.js")
- });
- worker.port.emit("alert", "Message from the add-on");
-});
-
-tabs.open("http://www.mozilla.org");</pre>
-
-<pre class="brush: js">// content-script.js
-
-self.port.on("alert", function(message) {
- window.alert(message);
-});</pre>
-
-<div class="note">
-<p>Модуль <code>context-menu</code> не использует данную модель коммуникации. Для изучения варианта взаимодействия скриптов <code>content scripts</code>, загруженных с использованием <code>context-menu</code>, смотрите <a href="/en-US/Add-ons/SDK/High-Level_APIs/context-menu">context-menu documentation</a>. </p>
-</div>
-
-<h3 id="Доступ_к_порту_в_content_script">Доступ к порту в content script</h3>
-
-<p>В скрипте <code>content script</code> объект <code>port </code>доступен через свойство глобального объекта <a href="/en-US/Add-ons/SDK/Guides/Content_Scripts/self"><code>self</code></a>.  Чтобы послать сообщение из <code>content script</code>:</p>
-
-<pre class="brush: js">self.port.emit("myContentScriptMessage", myContentScriptMessagePayload);</pre>
-
-<p>Чтобы получить сообщение из кода дополнения:</p>
-
-<pre class="brush: js">self.port.on("myAddonMessage", function(myAddonMessagePayload) {
- // Handle the message
-});</pre>
-
-<div class="note">
-<p><span>Учтите, что глобальный объект <a href="/en-US/Add-ons/SDK/Guides/Content_Scripts/self"><code>self</code></a> совершенно отличается от модуля <a href="https://developer.mozilla.org/en-US/Add-ons/SDK/High-Level_APIs/self"><code>self</code> module</a>, предоставляющим API дополнению для доступа к его файлам и ID.</span></p>
-</div>
-
-<h3 id="Доступ_к_порту_в_скрипте_дополнения_(add-on_script)">Доступ к порту в скрипте дополнения (add-on script)</h3>
-
-<p>В коде дополнения канал взаимодействия между дополнением и конкретным <code>content script</code> инкапсулируется посредством объекта <a href="https://developer.mozilla.org/en-US/Add-ons/SDK/Low-Level_APIs/content_worker"><code>worker</code></a>. Поэтому объект <code>port </code>для для связи со скриптом content script это свойство связанного worker.</p>
-
-<p>Тем не менее, объект worker не расширен на код дополнения так же, как в других модулях.</p>
-
-<h4 id="Сообщения_из_page-worker">Сообщения из<code> page-worker</code></h4>
-
-<p>Объект <code>page-worker</code> интегрирует в себе <code>worker API</code>. Поэтому для получения сообщений от скрипта content script, ассоциированного с <code>page-worker нужно использовать </code><code>pageWorker.port.on()</code>:</p>
-
-<pre class="brush: js">// main.js
-
-var self = require("sdk/self");
-
-var pageWorker = require("sdk/page-worker").Page({
-  contentScriptFile: self.data.url("content-script.js"),
-  contentURL: "http://en.wikipedia.org/wiki/Internet"
-});
-
-pageWorker.port.on("first-para", function(firstPara) {
-  console.log(firstPara);
-});</pre>
-
-<p>Для отправки пользовательских сообщений их дополнения нужно вызвать <code>pageWorker.port.emit()</code>:</p>
-
-<pre class="brush: js">// main.js
-
-var self = require("sdk/self");
-
-var pageWorker = require("sdk/page-worker").Page({
-  contentScriptFile: self.data.url("content-script.js"),
-  contentURL: "http://en.wikipedia.org/wiki/Internet"
-});
-
-pageWorker.port.on("first-para", function(firstPara) {
-  console.log(firstPara);
-});
-
-pageWorker.port.emit("get-first-para");</pre>
-
-<pre class="brush: js">// content-script.js
-
-self.port.on("get-first-para", getFirstPara);
-
-function getFirstPara() {
- var paras = document.getElementsByTagName("p");
- if (paras.length &gt; 0) {
- var firstPara = paras[0].textContent;
- self.port.emit("first-para", firstPara);
- }
-}</pre>
-
-<h4 id="Сообщения_из_page-mod">Сообщения из <code>page-mod</code></h4>
-
-<p>Один объект <code>page-mod</code> может привязать свои скрипты к нескольким страницам, каждая из них со своим контекстом, в котором запускаются <code>content scripts</code>. Поэтому для каждой страницы необходим отдельный канал (<code>worker</code>) связи.</p>
-
-<p><code>page-mod</code> не интегрирует в себе <code>worker API напрямую</code>. Вместо этого, когда скрипт <code>content script</code> привязывается к странице, <code>page-mod</code> бросает событие <code>attach</code> тому слушателю, который связан с worker. Создавая слушатель для события <code>attach</code>, вы можете получить доступ через объект <code>port </code>к тому скрипту <code>content scripts</code>, который связан с нужной страницей (через <code>page-mod)</code>:</p>
-
-<pre class="brush: js">// main.js
-
-var pageMods = require("sdk/page-mod");
-var self = require("sdk/self");
-
-var pageMod = pageMods.PageMod({
-  include: ['*'],
-  contentScriptFile: self.data.url("content-script.js"),
-  onAttach: startListening
-});
-
-function startListening(worker) {
-  worker.port.on('click', function(html) {
-    worker.port.emit('warning', 'Do not click this again');
-  });
-}</pre>
-
-<pre class="brush: js">// content-script.js
-
-window.addEventListener('click', function(event) {
- self.port.emit('click', event.target.toString());
- event.stopPropagation();
- event.preventDefault();
-}, false);
-
-self.port.on('warning', function(message) {
- window.alert(message);
-});
-</pre>
-
-<p>В дополнении, описанном выше, есть два сообщения:</p>
-
-<ul>
- <li><code>click</code> отправляется из <code>page-mod</code> в дополнение, когда пользователь кликает на элемент на web-странице</li>
- <li><code>warning</code> отправляет прикольную строчку обратно в объект <code>page-mod</code></li>
-</ul>
-
-<h4 id="Сообщения_из_Tab.attach()">Сообщения из <code>Tab.attach()</code></h4>
-
-<p>Функция <code>Tab.attach()</code> возвращает <code>worker</code>, который можно использовать для связи со скриптом content script(s).</p>
-
-<p>Следующее дополнение добавляет кнопку в Firefox: когда пользователь надимает её, то дополнение привязывает скрипт <code>content script</code> к активной вкладке, отправляет этому скрипту сообщение "my-addon-message" и ждёт ответ "my-script-response":</p>
-
-<pre class="brush: js">//main.js
-
-var tabs = require("sdk/tabs");
-var buttons = require("sdk/ui/button/action");
-var self = require("sdk/self");
-
-buttons.ActionButton({
- id: "attach-script",
- label: "Attach the script",
- icon: "./icon-16.png",
- onClick: attachScript
-});
-
-function attachScript() {
- var worker = tabs.activeTab.attach({
- contentScriptFile: self.data.url("content-script.js")
- });
- worker.port.on("my-script-response", function(response) {
- console.log(response);
- });
- worker.port.emit("my-addon-message", "Message from the add-on");
-}
-</pre>
-
-<pre class="brush: js">// content-script.js
-
-self.port.on("my-addon-message", handleMessage);
-
-function handleMessage(message) {
- alert(message);
- self.port.emit("my-script-response", "Response from content script");
-}</pre>
-
-<h3 id="Описание_port_API">Описание port API</h3>
-
-<p>Смотрите <a href="/en-US/Add-ons/SDK/Guides/Content_Scripts/port">reference page for the <code>port</code> object</a>.</p>
-</article>
-
-<h3 id="Описание_postMessage_API">Описание postMessage API</h3>
-
-<p>До того, как был введён объект port, дополнения и <code>content scripts </code>общались следующим образом, используя различные API:</p>
-
-<ul>
- <li>скрипт content script <code>вызывал self.postMessage()</code> для отправки и <code>self.on()</code> для получения</li>
- <li>дополнение (add-on) вызывал <code>worker.postMessage()</code> для отправки и <code>worker.on()</code> для получения</li>
-</ul>
-
-<p>Данный API до сих пор доступно и <a href="/en-US/Add-ons/SDK/Guides/Content_Scripts/using_postMessage">документировано</a>, но желательно использовать <code>port API</code>, описанный здесь выше. Исключением является модуль <a href="/en-US/Add-ons/SDK/High-Level_APIs/context-menu">context-menu</a>, который ещё использует <code>postMessage</code>.</p>
-
-<h3 id="Взаимодействие_скриптов_content_script_со_скриптами_content_script">Взаимодействие скриптов content script со скриптами content script</h3>
-
-<p>Скрипты <code>content scripts</code> могут взаимодействовать друг с другом напрямую если они загружены в одном контексте. Например, если один вызов <code>Tab.attach()</code> привязывает два скрипта <code>content scripts</code>, то они видят друг друга напрямую, как если два скрипта загружены на одну страницу. Но если вызвать <code>Tab.attach()</code> дважды, привязывая <code>content scripts</code> каждый раз, то они уже не будут загружены в одном контексте, и дожны взаимодействовать способами как скрипты из разных контекстов. Один из вариантом это пересылать сообщения через основной код дополнения, используя port API с передачей сообщения другим скриптам <code>context script</code>. Этои вариант будет работать независимо от контекста, в котором загружен скрипт <code>content script</code>.</p>
-
-<p>В отдельном случае, когда два скрипта загружены на одной странице, существует возможность для обоих скриптов <code>content scripts</code> взаимодействовать друг с другом, используя<a href="https://developer.mozilla.org/en-US/Add-ons/SDK/Guides/Content_Scripts/Communicating_With_Other_Scripts#Using_the_DOM_postMessage_API"> DOM postMessage() API</a> или <a href="https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent">CustomEvent</a>. Следующее дополнение показывает как скрипт <code>content script</code>, добавленный через <code>page-mod</code>, получает событие CustomEvent, отправленное из <a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/SDK/High-Level_APIs/context-menu">context-menu</a>, когда элемент меню был кликнут. Скрипт <code>page-mod</code> будет отображать алерт с URL той ссылки, по которой было отображено контекстное меню. URL передан в скрипт <code>page-mod</code> с использованием CustomEvent.</p>
-
-<pre><code>var pageMod = require("sdk/page-mod");
-pageMod.PageMod({
- include: "*.mozilla.org",
- contentScript: 'function contextMenuAlert(href) {'
- + ' window.alert("The context menu was clicked on URL:\\n" + href);'
- + '};'
- + 'window.addEventListener("myAddonId-contextMenu-clicked",'
- + ' function(event){contextMenuAlert(event.detail);});'
-});
-
-let cm = require("sdk/context-menu");
-cm.Item({
- label: "Alert URL",
- context: [
- cm.URLContext(["*.mozilla.org"]),
- cm.SelectorContext("a[href]")
- ],
- contentScript: 'self.on("click", function (node, data) {'
- + ' var event = new CustomEvent("myAddonId-contextMenu-clicked",'
- + ' {detail:node.href});'
- + ' window.dispatchEvent(event);'
- + '});'
-});</code></pre>
-
-<h2 id="Междоменные_скрипты_content_script">Междоменные скрипты <code>content script</code></h2>
-
-<p>По умолчанию скрипты <code>content script </code>не имеют никаких междоменных привилегий. В частности, они не имеют доступа к содержимому в <code>iframe</code>, если содержимое получено из другого домена, или выполняются междоменные XMLHttpRequests.</p>
-
-<p>Однако, вы можете разрешить эти функции для заданных доменов, путём добавления их в <a href="/en-US/Add-ons/SDK/Tools/package_json">package.json</a> дополнения в ключе <code>"cross-domain-content"</code>, который расположен в ключе <code>"permissions"</code>. Смотрите статью <a href="/en-US/Add-ons/SDK/Guides/Content_Scripts/Cross_Domain_Content_Scripts">междоменные скрипты содержимого</a>.</p>
-</article>