diff options
author | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:42:52 -0500 |
---|---|---|
committer | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:42:52 -0500 |
commit | 074785cea106179cb3305637055ab0a009ca74f2 (patch) | |
tree | e6ae371cccd642aa2b67f39752a2cdf1fd4eb040 /files/ru/mozilla/add-ons | |
parent | da78a9e329e272dedb2400b79a3bdeebff387d47 (diff) | |
download | translated-content-074785cea106179cb3305637055ab0a009ca74f2.tar.gz translated-content-074785cea106179cb3305637055ab0a009ca74f2.tar.bz2 translated-content-074785cea106179cb3305637055ab0a009ca74f2.zip |
initial commit
Diffstat (limited to 'files/ru/mozilla/add-ons')
77 files changed, 11873 insertions, 0 deletions
diff --git a/files/ru/mozilla/add-ons/add-on_guidelines/index.html b/files/ru/mozilla/add-ons/add-on_guidelines/index.html new file mode 100644 index 0000000000..5be041195c --- /dev/null +++ b/files/ru/mozilla/add-ons/add-on_guidelines/index.html @@ -0,0 +1,121 @@ +--- +title: Add-on guidelines +slug: Mozilla/Add-ons/Add-on_guidelines +translation_of: 'https://extensionworkshop.com/documentation/publish/add-on-policies/' +--- +<p>These add-on guidelines were created to foster an open and diverse add-on developer community while ensuring an excellent user experience. They apply to all add-ons and add-on updates regardless of where they are hosted, and also apply to customizations performed by installers that configure Firefox without using an add-on. Add-ons hosted on <a class="external text" href="https://addons.mozilla.org/" rel="nofollow">AMO</a> are subject to <a href="https://addons.mozilla.org/developers/docs/policies" title="https://addons.mozilla.org/developers/docs/policies">additional policies</a>.</p> + +<h2 id="Be_Transparent">Be Transparent</h2> + +<ul> + <li>Add-ons must either be installed using the add-on web install system, or be approved by the user using the <a class="external text" href="https://blog.mozilla.org/addons/2011/08/11/strengthening-user-control-of-add-ons/" rel="nofollow">install opt-in dialog</a>. + + <ul> + <li>We want our users to know what they are installing so that they are not unpleasantly surprised by changes they did not expect. We also want them to know what to remove if they decide not to keep it.</li> + <li>Add-ons installed through application installers should <a class="external text" href="/en-US/docs/Adding_Extensions_using_the_Windows_Registry" rel="nofollow">use the Windows Registry</a> or equivalent global install methods so that Firefox displays the opt-in screen. The opt-in screen must not be tampered with in any way, including overlaying additional information or images on top of it.</li> + </ul> + </li> + <li>Add-ons must always be possible to uninstall or disable from the Add-ons Manager. + <ul> + <li>Add-ons installed globally using the Windows registry or global extension directories cannot be uninstalled (<a class="external text" href="https://bugzilla.mozilla.org/show_bug.cgi?id=640775" rel="nofollow">bug 640775</a>), but they can be disabled to the same effect.</li> + </ul> + </li> + <li>Add-ons must use a <a class="external text" href="/en-US/docs/Install_manifests#id" rel="nofollow">single unique ID</a> during their entire lifetime. + <ul> + <li>Using the same ID for multiple products, or multiple IDs for a single product, can lead to problems with automatic updates as well as blocklisting conflicts. Add-ons may change their IDs due to ownership changes, as they commonly use an email address-like format (<em>e.g.,</em> personasplus@mozilla.com).</li> + </ul> + </li> + <li>Add-ons must not use brand names, trademarks, or other terms in ways that deceive users. Using Mozilla trademarks must follow <a class="external text" href="http://www.mozilla.org/foundation/trademarks/policy.html" rel="nofollow">our trademark policy</a>.</li> + <li>Add-ons should clearly communicate their intended purpose and active features, including features introduced through updates. + <ul> + <li>While we understand and support add-on developers who choose to monetize their products, this should not come at the expense of users' browsing experience. If an add-on inserts advertisements, affiliate codes, sponsored search results, or the like, into web pages, the user should be made aware of this when the add-on is installed. Likewise, if some features require payment to use, or require payment to remain active after a trial period, users should be made aware of this.</li> + </ul> + </li> +</ul> + +<h2 id="Be_Respectful_to_Users">Be Respectful to Users</h2> + +<ul> + <li>Add-ons must remove all introduced code, executables, and application configuration changes when they are uninstalled. + <ul> + <li>Uninstalling an add-on using the regular uninstall process should generally suffice. This guideline primarily applies to changes made to preferences such as the homepage, default search URL, network settings, and so forth. These preferences should be restored to their previous values when the add-on is uninstalled. Most add-ons can easily accomplish this by making such changes via a <a class="external text" href="/en-US/docs/Building_an_Extension#Defaults_Files" rel="nofollow">default preferences file</a>.</li> + </ul> + </li> + <li>Add-ons should respect the users' choices and not make unexpected changes, or limit users' ability to revert them. + <ul> + <li>For instance, users generally do not expect an add-on to change the Firefox homepage. Asking users to opt-in to such extra changes is recommended. Making them difficult or impossible to revert is strongly discouraged.</li> + </ul> + </li> + <li>Add-ons should make it clear how private user data is being used. + <ul> + <li>Add-ons which send user data over the Internet should generally provide a Privacy Policy, ideally concise and easily readable.</li> + </ul> + </li> + <li>Add-on developers should provide a mechanism for them to be contacted. + <ul> + <li>While developers are not required to provide a support channel for users, it is recommended. All add-on developers should have a contact form or public email address so that they can be contacted in case of emergencies, such as guideline violations that could lead to blocklisting.</li> + </ul> + </li> +</ul> + +<h2 id="Be_Safe">Be Safe</h2> + +<ul> + <li>Add-ons must not cause harm to users' data, system, or online identities.</li> + <li>Add-ons must not transmit users' private data unsafely, or expose it to third parties unnecessarily. + <ul> + <li>Private data should always be sent over a secure connection. This includes browsing data such as visited URLs and bookmarks.</li> + <li>Making the browser easier to fingerprint by adding text to the User-Agent string or adding custom headers is also a privacy concern, and should be avoided.</li> + </ul> + </li> + <li>Add-ons must not create or expose application or system vulnerabilities. + <ul> + <li>Security bugs happen, but once discovered they need to be addressed immediately. A popular add-on with a security vulnerability is a valuable attack vector for hackers, and in such cases we will move quickly to blocklist the add-on if there is no prompt response from the developer.</li> + </ul> + </li> + <li>Add-ons must not tamper with the application or blocklist update systems.</li> + <li>Add-ons should not store any browsing data while in Private Browsing Mode. + <ul> + <li>It's worth stressing that PBM is about avoiding storing<em>local</em> data while browsing, not about sending data elsewhere. To learn more about PBM we recommend reading <a class="external text" href="http://ehsanakhgari.org/tag/privatebrowsing" rel="nofollow">Ehsan's blog posts</a> about it.</li> + </ul> + </li> +</ul> + +<h2 id="Be_Stable">Be Stable</h2> + +<ul> + <li>Add-ons must not cause hangs or crashes.</li> + <li>Add-ons should not break or disable core application features. + <ul> + <li>This includes features like tabbed browsing, Private Browsing Mode, and the location bar. Add-ons that are specifically meant to do this are exempt.</li> + </ul> + </li> + <li>Add-ons should not cause memory leaks, or unnecessarily consume large amounts of memory.</li> + <li>Add-ons should not slow down the application or system significantly.</li> + <li>Add-ons should not consume network resources to an extent that affects regular application usage. + <ul> + <li>Downloading large amounts of data without user awareness can significantly disrupt regular browsing, and may result in unexpected charges for users who have network usage limitations (notably on mobile).</li> + </ul> + </li> +</ul> + +<h2 id="Exceptions">Exceptions</h2> + +<ul> + <li>Add-ons can break some of these guidelines if that's their intended purpose and there isn't malicious intent (<em>e.g.,</em> a security exploit proof of concept).</li> + <li>Add-ons deployed by administrators within workplaces, schools, kiosks, and so forth, are exempt from most guidelines.</li> + <li>As add-ons can only run clean up code if they are uninstalled while Firefox is running and they are enabled, we do not require that they attempt to clean up after themselves when they are uninstalled under other circumstances. Application installers that configure Firefox without add-ons should revert any changes when uninstalled.</li> + <li>Add-ons may leave behind preferences changes in private preference branches which do not affect Firefox when the add-on is not active, so that any previous add-on configuration is not lost if the user decides to re-install the add-on in the future.</li> +</ul> + +<p>Other exceptions may apply.</p> + +<h2 id="Enforcement">Enforcement</h2> + +<p>Add-ons that do not follow these guidelines may qualify for blocklisting, depending on the extent of the violations. Guidelines qualified with the word<em>must</em> are especially important, and violations thereof will most likely result in a blocklisting nomination.</p> + +<p>The Add-ons Team will do their best to contact the add-on's developers and provide a reasonable time frame for the problems to be corrected before a block is put in place. If an add-on is considered malicious or its developers have proven unreachable or unresponsive, or in case of repeat violations, blocklisting may be immediate.</p> + +<p>Guideline violations should be <a class="external text" href="https://bugzilla.mozilla.org/enter_bug.cgi?product=Tech%20Evangelism&component=Add-ons" rel="nofollow">reported via Bugzilla</a>, under Tech Evangelism > Add-ons. Questions can be posted in the <a class="external text" href="irc://irc.mozilla.org/addons" rel="nofollow">#addons IRC channel</a>.</p> + +<p>These guidelines may change in the future. All updates will be announced in the <a class="external text" href="https://blog.mozilla.org/addons/" rel="nofollow">Add-ons Blog</a>.</p> diff --git a/files/ru/mozilla/add-ons/amo/index.html b/files/ru/mozilla/add-ons/amo/index.html new file mode 100644 index 0000000000..0845e54e3d --- /dev/null +++ b/files/ru/mozilla/add-ons/amo/index.html @@ -0,0 +1,11 @@ +--- +title: AMO +slug: Mozilla/Add-ons/AMO +tags: + - NeedsTranslation + - TopicStub +translation_of: Mozilla/Add-ons/AMO +--- +<p>{{AddonSidebar}}</p> + +<p>Content to be added.</p> diff --git a/files/ru/mozilla/add-ons/amo/policy/index.html b/files/ru/mozilla/add-ons/amo/policy/index.html new file mode 100644 index 0000000000..7baca9debb --- /dev/null +++ b/files/ru/mozilla/add-ons/amo/policy/index.html @@ -0,0 +1,22 @@ +--- +title: AMO Policies +slug: Mozilla/Add-ons/AMO/Policy +tags: + - NeedsTranslation + - TopicStub +translation_of: Mozilla/Add-ons/AMO/Policy +--- +<p>{{AddonSidebar}}</p> + +<p>Mozilla стремится обеспечить отличный опыт для наших пользователей и разработчиков надстроек. Перед отправкой своего дополнения ознакомьтесь с приведенными ниже правилами.</p> + + +<dl> + <dd></dd><dt><a href="/Mozilla/Add-ons/AMO/Policy/Agreement">Пакт о разработке</a></dt> +<dd>Effective January 5, 2016</dd> <dt><a href="/Mozilla/Add-ons/AMO/Policy/Reviews">Обзор процесса</a></dt> +<dd>Add-ons extend the core capabilities of Firefox, allowing users to modify and personalize their Web experience. A healthy add-on ecosystem, built on trust, is vital for developers to be successful and users to feel safe making Firefox their own. For these reasons, Mozilla requires all add-ons to comply with the following set of policies on acceptable practices. The below is not intended to serve as legal advice, nor is it intended to serve as a comprehensive list of terms to include in your add-on’s privacy policy.</dd> <dt><a href="/Mozilla/Add-ons/AMO/Policy/Featured">Избранные дополнения</a></dt> +<dd>How up-and-coming add-ons become featured and what's involved in the process. </dd> <dt><a href="/Mozilla/Add-ons/AMO/Policy/Contact">Связаться с нами</a></dt> +<dd>Add-ons allow developers to extend and modify the functionality of Firefox.</dd> <br> + <strong><a href="https://developer.mozilla.org/en-US/Add-ons#Contact_us">Связаться с нами </a></strong><br> + Как связаться с нами в отношении этих политик или вашего дополнения. +</dl> diff --git a/files/ru/mozilla/add-ons/code_snippets/index.html b/files/ru/mozilla/add-ons/code_snippets/index.html new file mode 100644 index 0000000000..d7e42cd381 --- /dev/null +++ b/files/ru/mozilla/add-ons/code_snippets/index.html @@ -0,0 +1,148 @@ +--- +title: Code snippets +slug: Mozilla/Add-ons/Code_snippets +tags: + - Add-ons + - Code snippets + - Extensions + - NeedsTranslation + - TopicStub +translation_of: Archive/Add-ons/Code_snippets +--- +<p> </p> + +<div class="warning"> +<p>Дополнения с использованием методов, описанных в этом документе, считаются устаревшей технологией в Firefox. Не используйте эти методы для разработки новых дополнений. Используйте вместо этого <a href="https://developer.mozilla.org/en-US/Add-ons/WebExtensions">WebExtensions</a>. Если вы поддерживаете надстройку, которая использует описанные здесь методы, рассмотрите возможность переноса ее на использование WebExtensions.</p> + +<p><strong>Начиная с <a href="https://wiki.mozilla.org/RapidRelease/Calendar">Firefox 53</a>, никакие новые устаревшие дополнения не будут приниматься addons.mozilla.org (AMO) для Firefox на ПК и Firefox для Android.</strong></p> + +<p><strong>Начиная с <a href="https://wiki.mozilla.org/RapidRelease/Calendar">Firefox 57</a>, только дополнения разработанные на основе WebExtensions API будут поддерживаться для Firefox на ПК и Firefox для Android. </strong></p> + +<p> Даже до Firefox 57 изменения, появляющиеся на платформе Firefox, нарушат многие устаревшие расширения. Эти изменения включают многопроцессорные Firefox (e10s), песочницу и несколько процессов контента. Устаревшие расширения, на которые влияют эти изменения, должны мигрировать, чтобы использовать API WebExtensions, если они могут. Дополнительную информацию см. в <a href="https://blog.mozilla.org/addons/2017/02/16/the-road-to-firefox-57-compatibility-milestones/">документе "Признаки совместимости"</a>.</p> + +<p>Страница wiki, содержащая <a href="https://wiki.mozilla.org/Add-ons/developer/communication">ресурсы, пути миграции, рабочие часы и т.д.</a>, доступна, чтобы помочь разработчикам перейти на новые технологии.</p> +</div> + +<p> </p> + +<p>This is a quick list of useful code snippets (small code samples) available for developers of extensions for the various Mozilla applications. Many of these samples can also be used in XULRunner applications, as well as in actual Mozilla code itself.</p> + +<p>These examples demonstrate how to accomplish basic tasks that might not be immediately obvious.</p> + +<h2 id="General" name="General">General</h2> + +<dl> + <dt><a href="/en-US/docs/Code_snippets/From_articles" title="/en-US/docs/Code_snippets/From_articles">Examples and demos from MDN articles</a></dt> + <dd>A collection of examples and demos from articles.</dd> + <dt><a href="/en-US/docs/Code_snippets/Windows" title="/en-US/docs/Code_snippets/Windows">Window code</a></dt> + <dd>Opening and manipulating windows</dd> + <dt><a href="/en-US/docs/Code_snippets/Toolbar" title="/en-US/docs/Code_snippets/Toolbar">Toolbar</a></dt> + <dd>Toolbar related code</dd> + <dt><a href="/en-US/docs/Code_snippets/Sidebar" title="/en-US/docs/Code_snippets/Sidebar">Sidebar</a></dt> + <dd>Sidebar related code</dd> + <dt><a href="/en-US/docs/Code_snippets/Forms">Forms</a></dt> + <dd>Forms related code</dd> + <dt><a href="/en-US/docs/Code_snippets/XML" title="/en-US/docs/Code_snippets/XML">XML</a></dt> + <dd>Code used to parse, write, manipulate, etc. XML</dd> + <dt><a href="/en-US/docs/Code_snippets/File_I_O" title="/en-US/docs/Code_snippets/File_I/O">File I/O</a></dt> + <dd>Code used to read, write and process files</dd> + <dt><a href="/en-US/docs/Code_snippets/Drag_&_Drop" title="/en-US/docs/Code_snippets/Drag_&_Drop">Drag & Drop</a></dt> + <dd>Code used to setup and handle drag and drop events</dd> + <dt><a href="/en-US/docs/Code_snippets/Dialogs_and_Prompts" title="/en-US/docs/Code_snippets/Dialogs_and_Prompts">Dialogs</a></dt> + <dd>Code used to display and process dialog boxes</dd> + <dt><a href="/en-US/docs/Code_snippets/Alerts_and_Notifications" title="/en-US/docs/Code snippets/Alerts and Notifications">Alerts and Notifications </a></dt> + <dd>Modal and non-modal ways to notify users</dd> + <dt><a href="/en-US/docs/Code_snippets/Preferences" title="/en-US/docs/Code_snippets/Preferences">Preferences</a></dt> + <dd>Code used to read, write, and modify preferences</dd> + <dt><a href="/en-US/docs/Code_snippets/JS_XPCOM" title="/en-US/docs/Code_snippets/JS_XPCOM">JS XPCOM</a></dt> + <dd>Code used to define and call XPCOM components in JavaScript</dd> + <dt><a href="/en-US/docs/Code_snippets/Running_applications" title="/en-US/docs/Code_snippets/Running_applications">Running applications</a></dt> + <dd>Code used to run other applications</dd> + <dt><a href="/en-US/docs/Code_snippets/Canvas" title="/en-US/docs/Code_snippets/Canvas"><code><canvas></code> related</a></dt> + <dd><a href="/en-US/docs/HTML/Canvas" title="/en-US/docs/HTML/Canvas">WHAT WG Canvas</a>-related code</dd> + <dt><a href="/en-US/docs/Signing_a_XPI" title="/en-US/docs/Signing_a_XPI">Signing a XPI</a></dt> + <dd>How to sign an XPI with PKI</dd> + <dt><a href="/en-US/docs/Code_snippets/Threads">Delayed Execution</a></dt> + <dd>Performing background operations.</dd> + <dt><a href="/en-US/docs/Code_snippets/Miscellaneous" title="/en-US/docs/Code_snippets/Miscellaneous">Miscellaneous</a></dt> + <dd>Miscellaneous useful code fragments</dd> + <dt><a href="/en-US/docs/Code_snippets/HTML_to_DOM" title="/en-US/docs/Code_snippets/HTML_to_DOM">HTML to DOM</a></dt> + <dd>Using a hidden browser element to parse HTML to a window's DOM</dd> +</dl> + +<h2 id="javascript-libraries" name="javascript-libraries">JavaScript libraries</h2> + +<p>Here are some JavaScript libraries that may come in handy.</p> + +<dl> + <dt><a href="/en-US/docs/Code_snippets/StringView" title="/en-US/docs/Code_snippets/StringView">StringView</a></dt> + <dd>A library that implements a <code>StringView</code> view for <a href="/en-US/docs/Web/JavaScript/Typed_arrays" title="/en-US/docs/Web/JavaScript/Typed_arrays">JavaScript typed arrays</a>. This lets you access data in typed arrays using C-like string functions.</dd> + <dt><a href="/en-US/Add-ons/Code_snippets/Rosetta" title="/en-US/docs/Code_snippets/Rosetta">Rosetta</a></dt> + <dd>By default, the only possible standardized scripting language for HTML is <strong>ECMAScript</strong>. Hence, if you are going to use another scripting language you might expect that most of the browsers will not recognize it. Nevertheless, the increasing computational power of modern browsers together with the introduction of <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays">typed arrays</a> in ECMAScript allow us, in theory, to build full <a class="external external-icon" href="http://en.wikipedia.org/wiki/Virtual_machine">virtual machines</a> in pure ECMAScript. Therefore, it is also possible, in theory, to use ECMAScript for a smaller task: parsing exotic programming languages (i.e., creating compilers). This snippets shows a possible way to start from.</dd> +</dl> + +<h2 id="Browser-oriented_code" name="Browser-oriented_code">Browser-oriented code</h2> + +<dl> + <dt><a href="/en-US/docs/Code_snippets/Tabbed_browser" title="/en-US/docs/Code_snippets/Tabbed_browser">Tabbed browser code</a> (Firefox/SeaMonkey)</dt> + <dd>Basic operations, such as page loading, with the tabbed browser, which is the heart of Mozilla's browser applications</dd> + <dt><a href="/en-US/docs/Code_snippets/Cookies" title="/en-US/docs/Code_snippets/Cookies">Cookies</a></dt> + <dd>Reading, writing, modifying, and removing cookies</dd> + <dt><a href="/en-US/docs/Code_snippets/Page_Loading" title="/en-US/docs/Code_snippets/Page_Loading">Page Loading</a></dt> + <dd>Code used to load pages, reload pages, and listen for page loads</dd> + <dt><a href="/en-US/docs/Code_snippets/Interaction_between_privileged_and_non-privileged_pages" title="/en-US/docs/Code_snippets/Interaction_between_privileged_and_non-privileged_pages">Interaction between privileged and non-privileged code</a></dt> + <dd>How to communicate from extensions to websites and vice-versa.</dd> + <dt><a href="/en-US/docs/Code_snippets/Downloading_Files" title="/en-US/docs/Code_snippets/Downloading_Files">Downloading Files</a></dt> + <dd>Code to download files, images, and to monitor download progress</dd> + <dt><a href="/en-US/docs/Code_snippets/Password_Manager" title="/en-US/docs/Code_snippets/Password_Manager">Password Manager</a></dt> + <dd>Code used to read and write passwords to/from the integrated password manager</dd> + <dt><a href="/en-US/docs/Code_snippets/Bookmarks" title="/en-US/docs/Code_snippets/Bookmarks">Bookmarks</a></dt> + <dd>Code used to read and write bookmarks</dd> + <dt><a href="/en-US/docs/Code_snippets/JavaScript_Debugger_Service" title="/en-US/docs/Code_snippets/JavaScript_Debugger_Service">JavaScript Debugger Service</a></dt> + <dd>Code used to interact with the JavaScript Debugger Service</dd> +</dl> + +<h2 id="SVG" name="SVG">SVG</h2> + +<dl> + <dt><a href="/en-US/docs/Code_snippets/SVG_General" title="/en-US/docs/Code_snippets/SVG_General">General</a></dt> + <dd>General information and utilities</dd> + <dt><a href="/en-US/docs/Code_snippets/SVG_Animation" title="/en-US/docs/Code_snippets/SVG_Animation">SVG Animation</a></dt> + <dd>Animate SVG using JavaScript and SMIL</dd> + <dt><a href="/en-US/docs/Code_snippets/SVG_Interacting_with_script" title="/en-US/docs/Code_snippets/SVG_Interacting_with_script">SVG Interacting with Script</a></dt> + <dd>Using JavaScript and DOM events to create interactive SVG</dd> + <dt><a href="/en-US/docs/Code_snippets/Embedding_SVG" title="/en-US/docs/Code_snippets/Embedding_SVG">Embedding SVG in HTML and XUL</a></dt> + <dd>Using SVG to enhance HTML or XUL based markup</dd> +</dl> + +<h2 id="XUL_Widgets" name="XUL_Widgets">XUL Widgets</h2> + +<dl> + <dt><a href="/en-US/docs/Code_snippets/HTML_in_XUL_for_rich_tooltips" title="/en-US/docs/Code_snippets/HTML_in_XUL_for_rich_tooltips">HTML in XUL for Rich Tooltips</a></dt> + <dd>Dynamically embed HTML into a XUL element to attain markup in a tooltip</dd> + <dt><a href="/en-US/docs/Code_snippets/Label_and_description" title="/en-US/docs/Code_snippets/Label_and_description">Label and description</a></dt> + <dd>Special uses and line breaking examples</dd> + <dt><a href="/en-US/docs/Code_snippets/Tree" title="/en-US/docs/Code_snippets/Tree">Tree</a></dt> + <dd>Setup and manipulation of trees using XUL and JS</dd> + <dt><a href="/en-US/docs/Code_snippets/Scrollbar" title="/en-US/docs/Code_snippets/Scrollbar">Scrollbar</a></dt> + <dd>Changing style of scrollbars. Applies to scrollbars in browser and iframe as well.</dd> + <dt><a href="/en-US/docs/Code_snippets/Autocomplete" title="/en-US/docs/Code_snippets/Autocomplete">Autocomplete</a></dt> + <dd>Code used to enable form autocomplete in a browser</dd> + <dt><a href="/en-US/docs/Code_snippets/Boxes" title="/en-US/docs/Code_snippets/Boxes">Boxes</a></dt> + <dd>Tips and tricks when using boxes as containers</dd> + <dt><a class="internal" href="/en-US/docs/Code_snippets/Tabbox" title="/en-US/docs/Code snippets/Tabbox">Tabbox</a></dt> + <dd>Removing and manipulating tabs in a tabbox</dd> +</dl> + +<h2 id="Windows-specific" name="Windows-specific">Windows-specific</h2> + +<dl> + <dt><a href="/en-US/docs/Code_snippets/Finding_Window_Handles" title="/en-US/docs/Code_snippets/Finding_Window_Handles">Finding Window Handles (HWND)</a> (Firefox)</dt> + <dd>How to use Windows API calls to find various kinds of Mozilla window handles. Window handles can be used for IPC and Accessibility purposes.</dd> + <dt><a href="/en-US/docs/Accessing_the_Windows_Registry_Using_XPCOM" title="/en-US/docs/Accessing_the_Windows_Registry_Using_XPCOM">Using the Windows Registry with XPCOM</a></dt> + <dd>How to read, write, modify, delete, enumerate, and watch registry keys and values.</dd> +</dl> + +<h2 id="External_links" name="External_links">External links</h2> + +<p>The content at <a class="external" href="http://kb.mozillazine.org/Category:Example_code">MozillaZine Example Code</a> is slowly being moved here, but you can still find useful examples there for now.</p> diff --git a/files/ru/mozilla/add-ons/code_snippets/куки/index.html b/files/ru/mozilla/add-ons/code_snippets/куки/index.html new file mode 100644 index 0000000000..7a77657bdb --- /dev/null +++ b/files/ru/mozilla/add-ons/code_snippets/куки/index.html @@ -0,0 +1,36 @@ +--- +title: Cookies +slug: Mozilla/Add-ons/Code_snippets/куки +translation_of: Archive/Add-ons/Code_snippets/Cookies +--- +<h3 id="Reading_existing_cookies" name="Reading_existing_cookies">Чтение существующих cookie</h3> + +<p>Cookie для данного хоста, как объекты <code><a href="https://developer.mozilla.org/ru/docs/Mozilla/Add-ons/Code_snippets/%D0%BA%D1%83%D0%BA%D0%B8" title="">nsICookie2</a></code>, могут быть пронумерированны так:</p> + +<pre class="brush: js">let enum = Services.cookies.getCookiesFromHost("example.com"); +while (enum.hasMoreElements()) { + var cookie = e.getNext().QueryInterface(Ci.nsICookie2); + dump(cookie.host + ";" + cookie.name + "=" + cookie.value + "\n"); +} +</pre> + +<p>Все cookie, вне зависимости от хоста, могут быть пронумерированны с помощью <code>Services.cookies.enumerator</code>, а не <code>getCookiesFromHost()</code>.</p> + +<h3 id="Setting_a_cookie" name="Setting_a_cookie">Настраивание cookie</h3> + +<p>Следующий код показывает как настроить cookie в Firefox.</p> + +<pre class="brush: js">Services.cookies.add(".host.example.com", "/cookie-path", "cookie_name", "cookie_value", is_secure, is_http_only, is_session, expiry_date); +</pre> + +<h3 id="See_also" name="See_also">Смотрите также</h3> + +<ul> + <li>{{ Domxref("document.cookie") }}</li> + <li>{{ Interface("nsICookie") }}</li> + <li>{{ Interface("nsICookie2") }}</li> + <li>{{ Interface("nsICookieService") }}</li> + <li>{{ Interface("nsICookieManager") }}</li> + <li>{{ Interface("nsICookieManager2") }}</li> + <li><a href="/en/Web_Development/HTTP_cookies" title="HTTP cookies">HTTP cookies</a></li> +</ul> diff --git a/files/ru/mozilla/add-ons/firefox_for_android/index.html b/files/ru/mozilla/add-ons/firefox_for_android/index.html new file mode 100644 index 0000000000..a636438acb --- /dev/null +++ b/files/ru/mozilla/add-ons/firefox_for_android/index.html @@ -0,0 +1,82 @@ +--- +title: Устаревшие расширения для Firefox для Android +slug: Mozilla/Add-ons/Firefox_for_Android +tags: + - NeedsTranslation + - TopicStub +translation_of: Archive/Add-ons/Legacy_Firefox_for_Android +--- +<p>Firefox для Android поддерживает надстройки, используя ту же <a href="/ru/Add-ons" title="ru/Extensions">систему расширения</a>, что и все другие приложения на базе Gecko. Вы можете использовать <a href="https://addons.mozilla.org/en-US/developers/docs/sdk/latest/dev-guide/tutorials/mobile.html">SDK Add-on</a> или создать <a href="/en-US/Add-ons/Bootstrapped_extensions">вручную bootstrap-дополнения</a>. Вы даже можете создавать традиционные перезагружаемые дополнения, хотя предпочтительны и другие два подхода.</p> + +<p>Дополнения, которые работают с настольным Firefox, <strong>не</strong> работают автоматически в Firefox для Android:</p> + +<ul> + <li>В пользовательском интерфейсе нет видимого XUL, поэтому вы не можете использовать наложение для создания пользовательского интерфейса.</li> + <li>Внутренний код и объекты, такие как <code>gBrowser</code>, не существуют. Посмотрите на Firefox в файле <a class="external" href="http://mxr.mozilla.org/mozilla-central/source/mobile/android/chrome/content/browser.js" title="http://mxr.mozilla.org/mozilla-central/source/mobile/android/chrome/content/browser.js"><code>browser.js </code></a>Android, чтобы узнать о внутренних компонентах. Значительная часть той же фундаментальной функциональности существует.</li> + <li>Службы, такие как <code>nsIPromptService</code> и <code>nsIAlertsService</code>, реализованы для использования собственного пользовательского интерфейса Android.</li> + <li>Существует простой объект JavaScript, называемый <a href="https://developer.mozilla.org/en/Extensions/Mobile/API/NativeWindow" title="en/Extensions/Mobile/NativeWindow"><code>NativeWindow</code></a>, который позволяет вам манипулировать частями пользовательского интерфейса Android.</li> +</ul> + +<p>Следующие статьи предоставляют помощь в разработке расширений для Firefox на Android. Кроме того, обратитесь к <a class="internal" href="/en-US/Add-ons" title="En/Extensions">общей документации по расширениям</a>, которая применяется ко всем приложениям Mozilla</p> + +<div class="column-container"> +<div class="column-half"> +<h3 id="Учебники">Учебники</h3> + +<dl> + <dt><a href="/en-US/Add-ons/Firefox_for_Android/Walkthrough">Прохождение</a></dt> + <dd>Разработка, упаковка и установка простого дополнения для Firefox для Android.</dd> + <dt><a href="/en-US/Add-ons/Firefox_for_Android/Firefox_Hub_Walkthrough">Прохождение Firefox Hub</a></dt> + <dd>Как разработать Firefox Hub add-on и добавить его в Firefox для Android (главная страница).</dd> + <dt><a href="/en-US/Add-ons/SDK/Tutorials/Mobile_development">Add-on SDK</a></dt> + <dd>Как разрабатывать дополнения Firefox для Android с помощью Add-on SDK.</dd> +</dl> + +<h3 id="Образец_кода">Образец кода</h3> + +<dl> + <dt><a href="/en-US/Add-ons/Firefox_for_Android/Code_snippets">Фрагменты кода</a></dt> + <dd>Образцы кода для общих задач.</dd> + <dt><a href="/en-US/Add-ons/Firefox_for_Android/Initialization_and_Cleanup">Инициализация и очистка</a></dt> + <dd>Как инициализировать ваше дополнение при его запуске и очистке при его закрытии.</dd> + <dt><a href="https://github.com/mozilla/firefox-for-android-addons">Firefox для Android Add-ons в репозитории Github</a></dt> + <dd>Коллекция модулей JS, кода примера и плагинов-репозиториев, которые помогут вам создавать надстройки для Firefox для Android.</dd> +</dl> +</div> + +<div class="column-half"> +<h3 id="Справка_по_API">Справка по API</h3> + +<dl> + <dt><a class="internal" href="/en-US/Add-ons/Firefox_for_Android/API/NativeWindow"><code>NativeWindow</code></a></dt> + <dd>Создайте собственные виджеты пользовательского интерфейса Android.</dd> + <dt><a href="/en-US/Add-ons/Firefox_for_Android/API/BrowserApp"><code>BrowserApp</code></a></dt> + <dd>Доступ к вкладкам браузера и веб-содержимому, которое они размещают.</dd> + <dt><a class="internal" href="/en-US/Add-ons/Firefox_for_Android/API/Prompt.jsm"><code>Prompt.jsm</code></a></dt> + <dd>Вывод встроенного диалогового окна Android.</dd> + <dt><a href="/en-US/Add-ons/Firefox_for_Android/API/HelperApps.jsm"><code>HelperApps.jsm</code></a></dt> + <dd>Запросить и запустить собственные приложения, установленные в системе.</dd> + <dt><a href="/en-US/Add-ons/Firefox_for_Android/API/Notifications.jsm"><code>Notifications.jsm</code></a></dt> + <dd>Использование внешних свойств уведомлений системы Android.</dd> + <dt><a href="/en-US/Add-ons/Firefox_for_Android/API/Home.jsm"><code>Home.jsm</code></a></dt> + <dd>Настройка домашней страницы.</dd> + <dt><a href="/en-US/Add-ons/Firefox_for_Android/API/HomeProvider.jsm"><code>HomeProvider.jsm</code></a></dt> + <dd>Сохранять данные для отображения на главной странице.</dd> + <dt> </dt> +</dl> +</div> +</div> + +<p><code> </code></p> + +<div> +<div id="tap-translate"> </div> +</div> + +<div> +<div id="tap-translate"> </div> +</div> + +<div> +<div id="tap-translate"> </div> +</div> diff --git a/files/ru/mozilla/add-ons/how_to_convert_an_overlay_extension_to_restartless/index.html b/files/ru/mozilla/add-ons/how_to_convert_an_overlay_extension_to_restartless/index.html new file mode 100644 index 0000000000..ae42b11ad1 --- /dev/null +++ b/files/ru/mozilla/add-ons/how_to_convert_an_overlay_extension_to_restartless/index.html @@ -0,0 +1,395 @@ +--- +title: How to convert an overlay extension to restartless +slug: Mozilla/Add-ons/How_to_convert_an_overlay_extension_to_restartless +translation_of: Archive/Add-ons/How_to_convert_an_overlay_extension_to_restartless +--- +<div class="note"> +<p>This article is a step-by-step tutorial on how to convert an old <a href="https://developer.mozilla.org/en-US/Add-ons/Overlay_Extensions">overlay-based extension</a> into a <a href="https://developer.mozilla.org/en-US/Add-ons/Bootstrapped_extensions">restartless (bootstrapped) extension</a> that is also extractionless.</p> +</div> + +<h2 id="Requirements">Requirements</h2> + +<p>First off, what kind of <a href="https://developer.mozilla.org/en-US/Add-ons">add-on</a> are we talking about here? Well, <a href="https://developer.mozilla.org/en-US/docs/XUL_Overlays">XUL overlays</a> and windows, <a href="https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules">JSM files</a>, <a href="https://developer.mozilla.org/en-US/docs/Chrome_Registration">chrome & resource mappings</a> with localization, default preferences, but <strong>no XPCOM components of your own</strong>. Some of that will have to be replaced and the rest will need to be loaded differently.</p> + +<p>Next, what's the minimum version of Firefox we should require (preferably an <a href="https://www.mozilla.org/firefox/organizations/">ESR</a>)? This guide targets <strong>Firefox 17 ESR or later</strong> (or anything else Gecko 17+, such as SeaMonkey 2.14+). This is<em>two</em> ESRs back (as of this writing), which should be plenty. Using the current Firefox ESR, stable version, or Nightly is generally a better idea if given the option, but some users take forever to upgrade.</p> + +<p>There will be no usage of the <a href="/en-US/Add-ons/SDK">Add-on SDK</a> or any other external libraries here. Everything will use APIs available in Firefox 17+ or code provided here.</p> + +<h2 id="Step_1_Use_Services.jsm">Step 1: Use Services.jsm</h2> + +<p>If you load one of Mozilla's internal <a href="https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules">JSM files</a>, for example <a href="https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/Services.jsm">Services.jsm</a>, you'll do so via privileged JavaScript code like this:</p> + +<pre class="brush: js">Components.utils.import("resource://gre/modules/Services.jsm");</pre> + +<p>From here on out, it is assumed you've imported Services.jsm somewhere at the top of whatever file you're in and will be using it in all code examples. The examples will also assume that you know how to properly add instructions to your add-on's <a href="https://developer.mozilla.org/en-US/docs/Chrome_Registration">chrome.manifest</a> to add and remove resource, chrome, locale, & etc. mappings, so that you can access your files with custom paths such as:</p> + +<pre>resource://myAddon/filename.ext +chrome://myAddon/content/filename.ext</pre> + +<h2 id="Step_2_No_more_resource_URIs_for_files_internal_to_your_bundle">Step 2: No more resource:// URIs for files internal to your <a href="/en-US/docs/Bundles">bundle</a></h2> + +<p>Unfortunately, resource mappings in your chrome.manifest are <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=675372">still not usable</a> in restartless add-ons, which looks bad, but only because Mozilla is still using resource:// URIs internally and in examples. Resource mappings for files in the mozilla distribution, such as Services.jsm (above), will continue to work. In overlay extensions, you can place a resource mapping in the chrome.manifest for your add-on and load your own JSM from resource:// URIs. It's a great way to modularize your code that's been available since Firefox 3. You can use chrome:// URIs with "<a href="https://developer.mozilla.org/en-US/docs/Components.utils.import">Components.utils.import()</a>" just fine; in fact you've been able to since Firefox 4. However, because it was implemented first for only file:// and resource:// but not chrome://, everyone who learned of this new feature learned that you had to load JSM from resource:// URIs and just stuck with that forever. It does still work if you don't have restartlessness to worry about, though the protocol (or scheme, or whatever term you prefer) really should be avoided at this point. The resource:// protocol actually <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=903959">bleeds into content</a> which allows webpages to detect installed add-ons using the protocol, which is not particularly fantastic (just the static file contents, not any loaded script/data).</p> + +<h3 id="Step_2a_Load_your_JSM_from_chrome">Step 2a: Load your JSM from chrome://</h3> + +<p>Now with that preface out of the way, this part is easy: drop support for Firefox 3.x if you haven't already, move your JSM files to wherever you've got your <a href="https://developer.mozilla.org/en-US/docs/Chrome_Registration#content">chrome mapping</a> to for your XUL overlay and/or windows, import your files from that new chrome mapped path instead of the old resource one, and remove your "resource" line from your chrome.manifest file. It's probably a good idea to do this even if you aren't going fully restartless / extractionless due to the previously mentioned exposure to content of resource mappings.</p> + +<p>Also, drop support for Firefox 4 through 9 while you're at it. Prior to Firefox 10, the chrome.manifest file you rely on wasn't loaded automatically for restartless add-ons. Hacks were required, and probably a bad idea.</p> + +<h3 id="Step_2b_Audit_any_remaining_resource_URI_usage_internal_to_your_extension">Step 2b: Audit any remaining resource:// URI usage internal to your extension</h3> + +<p>If you don't need resource:// URIs for anything else, then you may be able to skip the next step. If not, see if you still can't do things any other way. As with JSMs, a chrome:// URI may be more appropriate. If you want to also make your add-on extractionless then you may need "step 3" if you're loading files with nsIFileInputStream or something similar, or a jar: URI might work. If not, a file:// URI might be fine for you. Restartless add-ons can easily get a <a href="https://developer.mozilla.org/en-US/Add-ons/Bootstrapped_extensions#Bootstrap_data">URI for their install location</a> on startup, so you should look into what you can do with that.</p> + +<h2 id="Step_3_No_more_nsIFile_access_for_files_internal_to_your_bundle">Step 3: No more <a href="/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIFile">nsIFile</a> access for files internal to your bundle</h2> + +<p>For an extractionless extension, access to files internal to your bundle will not be possible using the nsIFile interface.</p> + +<p>If you need to read data, or otherwise access files within your bundle, there are two options. The first is to use the <a href="/en-US/docs/XPCOM_Interface_Reference/nsIZipReader">nsIZipReader</a> interface which permits continuing to use <a href="/en-US/docs/XPCOM_Interface_Reference/nsIInputStream">nsIInputStream</a>s, etc. The second is to re-code to use <a href="https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest">XMLHttpRequest</a>.</p> + +<p>A file:// URI to the install location, or .xpi file, is available in <code>installPath</code> property of the <a href="https://developer.mozilla.org/en-US/Add-ons/Bootstrapped_extensions#Bootstrap_data">bootstrap data structure</a> passed to the <code>startup()</code>, <code>shutdown()</code>, <code>install()</code>, and <code>uninstall()</code> functions in what will be your bootstrap.js file <em>(see below)</em>.</p> + +<p>How to get and load the data of of your add-on's files using the <a href="https://developer.mozilla.org/en-US/Add-ons/Add-on_Manager/AddonManager">Add-on Manager API</a>:</p> + +<pre class="brush: js">// This is the OLD way of getting one of your files +const myAddonID = ...; // Just store a constant with your ID +Components.utils.import("resource://gre/modules/AddonManager.jsm"); +AddonManager.getAddonByID(myAddonID,function(addon) { + var file = Services.io.newURI("resource://myAddon/filename.ext",null,null) + .QueryInterface(Components.interfaces.nsIFileURL) + .file; + var stream = Components.classes["@mozilla.org/network/file-input-stream;1"] + .createInstance(Components.interfaces.nsIFileInputStream) + .QueryInterface(Components.interfaces.nsISeekableStream); + stream.init(file, 0x01, 0444, 0); // read-only, read by owner/group/others, normal behavior + /* do stuff */ +});</pre> + +<p>This bit of code is paraphrased and probably not to be recommended as-is, but it should work. (note that the usage of an <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Values,_variables,_and_literals#Integers">octal integer literal</a>, while standard for handling permissions, is dangerous and deprecated; usage of use <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/Strict_mode#Converting_mistakes_into_errors">ES5 strict mode</a> to disable this and other foot-guns is recommended) If you need to read/manipulate binary data, a <a href="/en-US/docs/XPCOM_Interface_Reference/nsIBinaryInputStream">nsIBinaryInputStream</a> instance is what you'll use on that stream (e.g. 32-bit integers, or fun stuff like <a href="https://flagfox.wordpress.com/2011/02/12/apparently-javascript-cant-do-64-bit-math/">48-bit integers</a>). Not ideal, but it works and performs more than sufficiently well. All of that code above is no longer viable if you also go extractionless (which you should).</p> + +<h3 id="Step_3a_Option_1_Use_nsIZipReader">Step 3a: Option 1: Use <a href="/en-US/docs/XPCOM_Interface_Reference/nsIZipReader">nsIZipReader</a></h3> + +<pre class="brush: js">let zipReader = Components.classes["@mozilla.org/libjar/zip-reader;1"] + .createInstance(Components.interfaces.nsIZipReader); +zipReader.open(addonData.installPath); +... +</pre> + +<p>From there you can open <a href="/en-US/docs/XPCOM_Interface_Reference/nsIInputStream">nsIInputStream</a>s, extract files, or perform some other functions. Worst case would be that you extract a file to a temporary location and then use nsIFile operations upon the extracted file.</p> + +<h3 id="Step_3b_Option_2_Use_XMLHttpRequest">Step 3b: Option 2: Use <a href="https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest">XMLHttpRequest</a></h3> + +<p>Now, how do we replace that? The answer to that question is to <strong>load your file from a chrome:// URI using XMLHttpRequest</strong>. You may now have another question: wait, what does this have to do with <a href="/en-US/docs/XML">XML</a> or <a href="/en-US/docs/Web/HTTP">HTTP</a>? The answer to that question is, of course, <em>nothing</em>. <a href="https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest">XMLHttpRequest</a> is an API created by Microsoft, adopted by Mozilla and other vendors, and hacked into a Swiss Army knife of file loading. You can use it in a web page to fetch a file from your server and you can use it in your add-on to fetch a local file from your installation. The name is a vestigial structure that just makes things confusing. It is nonetheless the "Correct" and best way to do things. It's available in the global for a window, but in JSM you'll need to fetch it from an interface:</p> + +<pre class="brush: js">const XMLHttpRequest = Components.Constructor("@mozilla.org/xmlextras/xmlhttprequest;1", + "nsIXMLHttpRequest");</pre> + +<p>Here's how to load a file using it:</p> + +<pre class="brush: js">function loadFile(url,type,returnresult) +{ + var request = new XMLHttpRequest(); + request.open("GET", url, true); // async=true + request.responseType = type; + request.onerror = function(event) { + logErrorMessage("Error attempting to load: " + url); + returnresult(null); + }; + request.onload = function(event) { + if (request.response) + returnresult(request.response); + else + request.onerror(event); + }; + request.send(); +} +loadFile("chrome://myAddon/content/filename.ext",dataType,function(data) { + /* do stuff with data */ +});</pre> + +<p>Note: When using XMLHttpRequest to access a file:// URL the <code>request.status</code> is not properly set to <code>200</code> to indicate success. In such cases, <code>request.readyState == 4</code>, <code>request.status == 0</code> and <code>request.response</code> will evaluate to true.</p> + +<p>If your file is text, use "text" as your data type. If you're getting <a href="https://developer.mozilla.org/en-US/docs/JSON">JSON</a> this way make sure to explicitly set the type as "text" if you intend to parse it yourself. Even though it says that the default type is "text", Firefox will attempt to autodetect and fail, resulting in an error message in the console. This doesn't seem to break anything, but it is easily avoidable by being explicit with the type. <a href="https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#Properties">MDN says</a> you can set the type to "json" instead, if you prefer to have it parse things for you.</p> + +<p>If your file is not text or JSON, then you're going to want to read binary data. The new way to do this is to use <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays">JavaScript typed arrays</a>. Specify "arraybuffer" as your data type to get one from your XMLHttpRequest. To access that data you're going to need a data view to look at your typed array with. Data that's homogeneous might get away with using something like Uint32Array or one of the other standard typed array views, but it's probably a bad idea. <strong>The basic typed array views are not endian-safe.</strong> This is incredibly stupid. You'd think such an important new JavaScript feature made available for web content and chrome alike would at least have a way to set and keep track of <a href="https://en.wikipedia.org/wiki/Endianness">endianness</a>, but no, it doesn't. Don't use any of the <a href="https://developer.mozilla.org/en-US/docs/Web/API/ArrayBufferView#Typed_array_subclasses">basic typed arrays</a> for any data you did not earlier write into them in the same program session. Also, they're not particularly helpful if your data isn't all of the exact same type (which it probably isn't).</p> + +<p>The solution to read arbitrary binary data, of various sizes, in an endian-safe way, is to use <a href="https://developer.mozilla.org/en-US/docs/Web/API/DataView">DataView</a>. The other typed array stuff is viable in Firefox 4+. This wasn't added until Firefox 15. If you were using nsIBinaryInputStream or anything similar, figuring out DataView will be fairly straightforward. Just read the docs and it's pretty simple. It will probably be notably faster than whatever you were doing before.</p> + +<p>Reportedly <a href="/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest#Using_XMLHttpRequest_from_JavaScript_modules_.2F_XPCOM_components">XMLHttpRequest doesn't work reliably when used in JSM under versions of Firefox less than 16</a>, however as previously mentioned, this guide should be taken as requiring Firefox 17+.</p> + +<h2 id="Step_4_Manually_handle_default_preferences">Step 4: Manually handle default preferences</h2> + +<p>Normal extensions load <a href="https://developer.mozilla.org/en-US/docs/Default_Preferences">default preferences</a> from a standardized file automatically. Restartless extensions <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=564675">don't</a> (for no good reason). This part is fairly easy to implement yourself, at least. Here are some functions to handle this:</p> + +<pre class="brush: js">function getGenericPref(branch,prefName) +{ + switch (branch.getPrefType(prefName)) + { + default: + case 0: return undefined; // PREF_INVALID + case 32: return getUCharPref(prefName,branch); // PREF_STRING + case 64: return branch.getIntPref(prefName); // PREF_INT + case 128: return branch.getBoolPref(prefName); // PREF_BOOL + } +} +function setGenericPref(branch,prefName,prefValue) +{ + switch (typeof prefValue) + { + case "string": + setUCharPref(prefName,prefValue,branch); + return; + case "number": + branch.setIntPref(prefName,prefValue); + return; + case "boolean": + branch.setBoolPref(prefName,prefValue); + return; + } +} +function setDefaultPref(prefName,prefValue) +{ + var defaultBranch = Services.prefs.getDefaultBranch(null); + setGenericPref(defaultBranch,prefName,prefValue); +} +function getUCharPref(prefName,branch) // Unicode getCharPref +{ + branch = branch ? branch : Services.prefs; + return branch.getComplexValue(prefName, Components.interfaces.nsISupportsString).data; +} +function setUCharPref(prefName,text,branch) // Unicode setCharPref +{ + var string = Components.classes["@mozilla.org/supports-string;1"] + .createInstance(Components.interfaces.nsISupportsString); + string.data = text; + branch = branch ? branch : Services.prefs; + branch.setComplexValue(prefName, Components.interfaces.nsISupportsString, string); +}</pre> + +<p>Just grab the above, move your default preferences file to your chrome mapping, and then do the following line once during your startup:</p> + +<pre class="brush: js">Services.scriptloader.loadSubScript("chrome://myAddon/content/defaultprefs.js", + {pref:setDefaultPref} ); +</pre> + +<p>That's it. Once you've got the machinery to load and save preferences without having to jump through the various pref type hoops the actual preferences API sends you through, loading the actual preferences file is one line. I'd generally still recommend using the type specific functions for each pref individually, but to load the defaults just use the generic functions above and it's quite simple. The other generic functions are provided above in case you need them. Unfortunately, the built in APIs for dealing with preferences are missing this basic stuff, and its plain text handling doesn't work with Unicode properly.</p> + +<h3 id="Step_4a_Another_way_to_handle_default_preferences">Step 4a: Another way to handle default preferences</h3> + +<p>If you want to keep your preference file in <strong>defaults/preferences/</strong>, the approach above only works as long as your extension is unpacked. For packed extensions (the default), you can either load a module similar to Firebug’s <a href="https://github.com/firebug/firebug/blob/master/extension/modules/prefLoader.js">prefLoader.js</a> or load this <a href="https://gist.github.com/oshybystyi/8cf882bc8b0c9a95a116">workaround module</a>.</p> + +<h2 id="Step_5_No_more_internal_JAR_files">Step 5: No more internal JAR files</h2> + +<p>You know how I've been mentioning extractionless add-ons every once in a while thus far? Well, you should probably consider switching to be extractionless when you go restartless. An old-style add-on installer is packaged something like this:</p> + +<pre>myAddon.xpi file (glorified ZIP) +└─ chrome.manifest +└─ install.rdf +└─ chrome folder + └─ myAddon folder + └─ content.jar file + └─ content folder (most files go here) + └─ locale folder (your locale files go here)</pre> + +<p>In versions of Firefox prior to 4.0 (Gecko 2.0), the XPI would be extracted into a folder in your profile's extensions folder. In current versions it stays unextracted as an XPI. If you were using input streams you already had to deal with this because they weren't an option without extraction. Opting-out to extractionlessness is done via the "unpack" flag in <a href="https://developer.mozilla.org/en-US/Add-ons/Install_Manifests">install.rdf</a>.</p> + +<p>Why the internal JAR? Well, two reasons:</p> + +<ol> + <li>Prior to extractionless add-ons, all of your files got extracted. Putting them in one single JAR file made all your stuff load in one file read, which was faster. Extractionless XPIs are bascially a standardization of this idea.</li> + <li>XPI files are glorified ZIPs, and ZIP compression is horrible. Doing an<em>uncompressed</em> internal JAR (aka, another ZIP) acts like a poor-man's <a href="https://en.wikipedia.org/wiki/Solid_archive">solid archive</a> and significantly boosts the overall compression ratio of the XPI, resulting in smaller installers and updates.</li> +</ol> + +<p>So, it's pretty much internal JAR<em>or</em> extractionless XPI. Well, <strong>you can't use an internal JAR anymore</strong>. Firefox aggressively caches add-on data a bit too much. Your restartless add-on won't actually reload some types of files if they are in a JAR and the add-on is updated without a restart. The big culprits are JSM files and locale files (namely property files), though in some situations this is true for dynamically loaded image files too. You're still going to have to manually clear the chrome cache on add-on shutdown to work around this, but that doesn't seem to be enough with an internal JAR. So, time to switch to extractionless, too. See <a href="https://developer.mozilla.org/en-US/Add-ons/Install_Manifests#unpack">here</a> for the list of stuff you can't have in addition to no resource:// URIs or file:// URIs to files inside your XPI.</p> + +<p>If you actually can't find a way to go fully extractionless, you could hack together some combination of internal JAR(s) and extracted files. It can be done. However, you really should go extractionless. Firefox profiles aren't the pristine environment they're supposed to be. Software that pretends to be designed to protect security or privacy that some users have installed will sometimes delete files. There have been plenty of reports of add-on franken-installs with files of two versions mixed together. This might be due to malware or a bug in Firefox. In any case, I have noticed a significant improvement in reliability by going fully extractionless. Installing and updating a single file is far more idiot-proof.</p> + +<h2 id="Step_6_No_more_XUL_overlays">Step 6: No more XUL overlays</h2> + +<p>Ok, now we're getting into some more drastic changes. You won't be able to use your chrome.manifest to load XUL overlays anymore with a restartless add-on. You could look into <a href="https://developer.mozilla.org/en-US/docs/Web/API/document.loadOverlay">dynamically loading</a> and unloading your overlay, however dynamically manipulating the DOM of your XUL window is usually the more straightforward route.</p> + +<p>Figure out what XUL elements you need to create for your add-on to add your interface, where it needs to go into a XUL window, and how to do it. Docs: <a href="https://developer.mozilla.org/en-US/docs/Web/API/document.getElementById">document.getElementByID()</a>, <a href="https://developer.mozilla.org/en-US/docs/Web/API/document.createElement">document.createElement()</a>, <a href="https://developer.mozilla.org/en-US/docs/Web/API/element">Element reference</a>, <a href="https://developer.mozilla.org/en-US/docs/Web/API/Node">Node reference</a> (DOM elements are also nodes).</p> + +<p>You'll need to write two functions. One to take a XUL window object and then create and add your elements, and then another to find your elements and remove them from the window object. The former will need to be run on add-on startup and the later on add-on shutdown. Until you get your bootstrap.js running you should use a basic overlay onto the XUL window with an event listener for "load" to catch overlay load and then run your manual UI construction function.</p> + +<h3 id="Step_6a._Details_on_adding_elements_dynamically_to_chrome_XUL_window">Step 6a. Details on adding elements dynamically to chrome XUL window</h3> + +<p>There is a way that makes constructing of UI a lot similar to the way it was made with XUL overlay. It involves using <a href="https://github.com/firebug/firebug.sdk/blob/master/lib/core/xul.js">firebug.sdk</a>. The next is example of the code:</p> + +<pre class="brush: js">var overlay = + TOOLBARBUTTON(toolbarButtonAttrs, + PANEL({'id': 'thepanel', 'type': 'arrow'}, + HBOX({'align': 'start'}, + VBOX( + HBOX({'class': 'pixel-hbox'}, + DESCRIPTION({'value': this.stringBundle.GetStringFromName('firexPixel.opacity')}), + HTMLINPUT({'id': 'opacity-range', 'type': 'range', 'min': '0', 'max': '10'}) + ), + HBOX({'id': 'pixel-coords', 'class': 'pixel-hbox'}, + LABEL({'control': 'coord-x', 'value': 'X:'}), + TEXTBOX({'id': 'coord-x', 'class': 'coord-box', 'placeholder' : '0'}), + LABEL({'control': 'coord-y', 'value': 'Y:'}), + TEXTBOX({'id': 'coord-y', 'class': 'coord-box', 'placeholder': '0'}) + ... +</pre> + +<p>That way you build elements hierarchy with not much interaction with DOM, plus you can see tag properties and it children in a nice, structured way, just like in overlay.xul. You can find working example <a href="https://github.com/oshybystyi/FireX-Pixel-Perfect/blob/issue-5-make-addon-restartless/content/ui.jsm#L94">here</a>. It involves using of firebug.sdk xul.js with <a href="https://github.com/oshybystyi/FireX-Pixel-Perfect/blob/issue-5-make-addon-restartless/content/lib/xul.js">few modifications</a>.</p> + +<h2 id="Step_7_Manually_handle_global_CSS_Stylesheets">Step 7: Manually handle global CSS Stylesheets</h2> + +<p>Any Global CSS style sheets which you are using will need to be registered upon load and unregistered when your extension is unloaded. Any CSS files used in any of your own XUL files will function normally without any extra work needed.</p> + +<pre class="brush: js">Components.utils.import("resource://gre/modules/Services.jsm"); +var styleSheets = ["chrome://myExtension/skin/myStyleSheet.css"]; + +function startup(data,reason) +{ +... + // Load stylesheets + let styleSheetService= Components.classes["@mozilla.org/content/style-sheet-service;1"] + .getService(Components.interfaces.nsIStyleSheetService); + for (let i=0,len=styleSheets.length;i<len;i++) { + let styleSheetURI = Services.io.newURI(styleSheets[i], null, null); + styleSheetService.loadAndRegisterSheet(styleSheetURI, styleSheetService.<code>AUTHOR_SHEET</code>); + } +... +} + +function shutdown(data,reason) +{ +... + // Unload stylesheets + let styleSheetService = Components.classes["@mozilla.org/content/style-sheet-service;1"] + .getService(Components.interfaces.nsIStyleSheetService); + for (let i=0,len=styleSheets.length;i<len;i++) { + let styleSheetURI = Services.io.newURI(styleSheets[i], null, null); + if (styleSheetService.sheetRegistered(styleSheetURI, styleSheetService.<code>AUTHOR_SHEET</code>)) { + styleSheetService.unregisterSheet(styleSheetURI, styleSheetService.<code>AUTHOR_SHEET</code>); + } + } +... +</pre> + +<h2 id="Step_8_Window_icons">Step 8: Window icons</h2> + +<p>Firefox does not scan the <code>chrome/icons/default</code> directory of restartless or extrationless extensions for <a href="/en-US/docs/Window_icons">window icons</a>. If you are using custom window icons, they will need to be moved to <code>%MozDir%/icons/default/</code> upon load of your extension. Removal upon unload is not required, but you must be able to handle overwriting them upon load. This is because your <code>unload()</code> will not always be called prior to an upgrade (e.g. upgrade might take place while the application is not running). Further, this is a generic location for icons and the icon may still be in use by a different profile. Thus, you will probably want to use version numbers in the icon name (the ID of the window for which the icon exists).</p> + +<h2 id="Step_9_bootstrap.js">Step 9: bootstrap.js</h2> + +<p>A <a href="/en-US/docs/Extensions/bootstrap.js">bootstrap.js</a> file in the root of your XPI, next to your chrome.manifest and install.rdf, will be the <a href="https://developer.mozilla.org/en-US/Add-ons/Bootstrapped_extensions#Bootstrap_entry_points">heart</a> of your restartless add-on. Think of it as main.c, but for JavaScript based Firefox restartless add-ons. A basic bootstrap.js file:</p> + +<pre class="brush: js">Components.utils.import("resource://gre/modules/Services.jsm"); +function startup(data,reason) { + Components.utils.import("chrome://myAddon/content/myModule.jsm"); + myModule.startup(); // Do whatever initial startup stuff you need to do + + forEachOpenWindow(loadIntoWindow); + Services.wm.addListener(WindowListener); +} +function shutdown(data,reason) { + if (reason == APP_SHUTDOWN) + return; + + forEachOpenWindow(unloadFromWindow); + Services.wm.removeListener(WindowListener); + + myModule.shutdown(); // Do whatever shutdown stuff you need to do on addon disable + + Components.utils.unload("chrome://myAddon/content/myModule.jsm"); // Same URL as above + + // HACK WARNING: The Addon Manager does not properly clear all addon related caches on update; + // in order to fully update images and locales, their caches need clearing here + Services.obs.notifyObservers(null, "chrome-flush-caches", null); +} +function install(data,reason) { } +function uninstall(data,reason) { } +function loadIntoWindow(window) { +/* call/move your UI construction function here */ +} +function unloadFromWindow(window) { +/* call/move your UI tear down function here */ +} +function forEachOpenWindow(todo) // Apply a function to all open browser windows +{ + var windows = Services.wm.getEnumerator("navigator:browser"); + while (windows.hasMoreElements()) + todo(windows.getNext().QueryInterface(Components.interfaces.nsIDOMWindow)); +} +var WindowListener = +{ + onOpenWindow: function(xulWindow) + { + var window = xulWindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor) + .getInterface(Components.interfaces.nsIDOMWindow); + function onWindowLoad() + { + window.removeEventListener("load",onWindowLoad); + if (window.document.documentElement.getAttribute("windowtype") == "navigator:browser") + loadIntoWindow(window); + } + window.addEventListener("load",onWindowLoad); + }, + onCloseWindow: function(xulWindow) { }, + onWindowTitleChange: function(xulWindow, newTitle) { } +}; +</pre> + +<p>As mentioned above, <a href="https://developer.mozilla.org/en-US/docs/Components.utils.unload">Components.utils.unload()</a> will not work properly if the JSM file it is unloading is in a JAR. Also make sure to only unload your own JSM files to avoid accidentally breaking things horribly.</p> + +<p>For tearing down and cleaning up on a per-window basis, there is another route you can take. Instead of directly calling your tear down function, make your <code>unloadFromWindow()</code> something like this:</p> + +<pre class="brush: js">function unloadFromWindow(window) +{ + var event = window.document.createEvent("Event"); + event.initEvent("myAddonName-unload",false,false); + window.dispatchEvent(event); +} +</pre> + +<p>In each window you can then register on startup to listen for your custom "myAddonName-unload" event and just tear down and clean up when that event or a regular "unload" event comes in.</p> + +<h2 id="Step_10_Bypass_cache_when_loading_properties_files">Step 10: Bypass cache when loading properties files</h2> + +<p>The above will get you a working add-on that will install without a Firefox restart. It will even get you a working add-on that will update without a Firefox restart... usually. Some parts work only if you don't look too closely; localization is one of them. As mentioned in the previous section, you'll need to clear the chrome caches on add-on shutdown, namely for chrome images and properties files. Doing this will get an update's new properties file to load, however sometimes this will instead produce an error on the next property access. It just doesn't seem that it can reliably clear the cache correctly, for whatever reason. String changes seem to be fine, however the addition or removal of strings can<em>sometimes</em> produce this error. It's not reliably reproducible, but it does happen.<em>Yes, this is a pain in the ass.</em></p> + +<p>The suggestion that seems to work is to use a <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=719376#c0">hack</a> to bypass the string bundle cache. You should still be caching a reference to your string bundle on add-on startup, preferably using <a href="https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/XPCOMUtils.jsm#defineLazyGetter%28%29">XPCOMUtils.jsm</a> to lazily load the file. For example:</p> + +<pre class="brush: js">Components.utils.import("resource://gre/modules/Services.jsm"); +Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); +XPCOMUtils.defineLazyGetter(this, "strings", function() { + return loadPropertiesFile("chrome://myAddon/locale/mystrings.properties"); +}); +function loadPropertiesFile(path) +{ + /* HACK: The string bundle cache is cleared on addon shutdown, however it doesn't appear to do so reliably. + Errors can erratically happen on next load of the same file in certain instances. (at minimum, when strings are added/removed) + The apparently accepted solution to reliably load new versions is to always create bundles with a unique URL so as to bypass the cache. + This is accomplished by passing a random number in a parameter after a '?'. (this random ID is otherwise ignored) + The loaded string bundle is still cached on startup and should still be cleared out of the cache on addon shutdown. + This just bypasses the built-in cache for repeated loads of the same path so that a newly installed update loads cleanly. */ + return Services.strings.createBundle(path + "?" + Math.random()); +} +</pre> + +<p>Just do <code>strings.GetStringFromName(stringID)</code> as you normally would. The <a href="https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/XPCOMUtils.jsm#defineLazyGetter%28%29">lazy getter magic</a> will cause the file to be automatically loaded the first time it is needed, after which point a reference to the loaded string bundle will be stored in "strings" for future accesses. You still need to clear the cache on add-on shutdown, however it will now also load cleanly on add-on updates. The old file <em>should</em> still be cleared.</p> + +<h2 id="Put_it_all_together">Put it all together</h2> + +<p>That should be all the pieces. Your chrome.manifest will have just chrome and locale (and possibly skin) mappings in it now. No resource mappings or chrome overlays. The new entry point for your add-on is via <code>bootstrap.js:startup()</code> rather than a "load" handler in a XUL overlay.</p> + +<p>Your localization handling should be unaffected by your transition to a restartless/extractionless add-on so long as you properly clear the chrome cache on add-on shutdown and load your properties files using the method listed above. Your property files and DTD files loaded from chrome:// URIs should work just as before. This is all assuming a minimum version of Firefox 17+ (or other Gecko 17+ application) which you should remember to state explicitly in your install.rdf.</p> + +<p><strong>Just remember that whatever you start you also need to have the ability to undo. In order for your add-on to reliably update without a restart it needs to be able to shutdown/disable cleanly.</strong></p> + +<p>Also note that once you do get this all up and running, your users will still have to restart Firefox once to install your first restartless update. While your new add-on may not need a restart to install, if you're updating from an old version that is not restartless then it will need a restart to<em>uninstall</em> that first.</p> + +<div class="note"> +<p>This tutorial was originally written by Dave Garrett from his experience <a href="https://flagfox.wordpress.com/2014/01/19/writing-restartless-addons/">porting the Flagfox extension</a>.</p> +</div> + +<h2 id="Further_reading">Further reading</h2> + +<ul> + <li>Author <a href="https://flagfox.wordpress.com/2014/01/19/writing-restartless-addons/">original article.</a></li> + <li>Another real-world example of porting overlay-based extension into restartless (<a href="https://github.com/oshybystyi/FireX-Pixel-Perfect/compare/v1.4...oshybystyi:issue-5-make-addon-restartless">git diff</a>).</li> + <li>Another <a href="https://github.com/firebug/pixel-perfect/blob/master/lib/pixel-perfect-popup.js#L197">example</a> of using firebug.sdk xul.js to construct ui.</li> +</ul> diff --git a/files/ru/mozilla/add-ons/index.html b/files/ru/mozilla/add-ons/index.html new file mode 100644 index 0000000000..067c5699bd --- /dev/null +++ b/files/ru/mozilla/add-ons/index.html @@ -0,0 +1,240 @@ +--- +title: Дополнения +slug: Mozilla/Add-ons +tags: + - NeedsTranslation + - TopicStub + - Дополнения + - Расширения +translation_of: Mozilla/Add-ons +--- +<p>Дополнения добавляют новые функциональные возможности в <a href="/en-US/docs/Mozilla/Gecko">Gecko</a>-приложения, такие, как Firefox, SeaMonkey и Thunderbird. Есть два основных типа дополнений: <a href="#Extensions">расширения</a>, которые добавляют новые функции в приложение, и <a href="#Themes">темы</a>, изменяющие пользовательский интерфейс приложения.</p> + +<blockquote> +<p>Для расширений и тем в Mozilla работает хранилище на <a href="https://addons.mozilla.org/">addons.mozilla.org</a>, также известное как AMO. Когда вы <a href="/en-US/Add-ons/Submitting_an_add-on_to_AMO">помещаете дополнения на AMO</a>, они рассматриваются, и после этого становятся доступны для пользователей. Вы не обязаны загружать свои дополнения в AMO, но если вы это сделаете, пользователи могут быть уверены в том, что они были предварительно проверены и будут знать, что ваше дополнение действительно полезно.</p> +</blockquote> + +<p>Дополнение может существенно повлиять на поведение приложения, на которое оно устанавливается. Мы разработали <a href="/en-US/docs/Mozilla/Add-ons/Add-on_guidelines">список советов</a>, которые помогут вам удостовериться, что ваше дополнение будет приятным в использовании. Эти правила применяются для всех видов надстроек, независимо от того, размещены они на <a href="https://addons.mozilla.org/">addons.mozilla.org</a> или нет.</p> + +<hr> +<h2 id="Расширения"><a name="Extensions">Расширения</a></h2> + +<p>Расширения добавляют новые функции к приложениям Mozilla, например таким как Firefox и Thunderbird. С их помощью можно изменить стандарное поведение браузера, например реализовать другой способ организации и управления вкладками. Можно даже изменять содержимое отображаемого веб приложения, чтобы улучшить удобство использования или например повысить безопасность определенных сайтов.</p> + +<p>Существует 3 различных способа сборки расширений: restartless-расширения на основе Add-on SDK, restartless-расширения с реализацией этого механизма вручную (manually bootstrapped restartless extensions), и расширения с использованием технологии Overlay.</p> + +<ul class="card-grid"> + <li><span><a href="https://developer.mozilla.org/en-US/Add-ons/SDK">Restartless-расширения на основе Add-on SDK</a></span><br> + Разработка restartless расширений с помощью высокоуровневого JavaScript API.</li> + <li><span><a href="/en-US/Add-ons/Bootstrapped_extensions">Restartless-расширения с реализацией этого механизма вручную</a></span><br> + Разработка расширений с самостоятельной реализацией механизма restartless.</li> + <li><a href="/en-US/Add-ons/Overlay_Extensions"><span>Расширения с использованием технологии Overlay Extensions</span></a><br> + Устаревшей способ разработки расширений, при котором требуется перезапуск браузера. Основан на механизме наложения XUL.</li> +</ul> + +<div class="note"> +<p><strong>Технология WebExtensions</strong></p> + +<p>В данный момент мы разрабатываем систему под названием WebExtensions, которая будет новым способом разработки расширений для браузера Firefox, эта система будет гораздо более совместима с браузерами Chrome и Opera.</p> + +<p>В будущем она станет наиболее предпочтительной при разработке новых проектов для браузера Firefox.</p> +В данный момент она является экспериментальной, но несмотря на это вы можете <a href="https://developer.mozilla.org/en-US/Add-ons/WebExtensions">ознакомиться с документацией</a>, если хотите ее опробовать.</div> + +<p>Где это возможно, рекомендуется выбирать Add-On SDK, который использует механизм расширения без необходимости перезапуска браузера (restartless extensions), а также упрощает разработку и убирает за собой. Если Вам недостаточно возможностей комплекта средств разработки Add-on SDK для реализации ваших идей, механизм restartless Вы можете осуществить самостоятельно. Технология Overlay extensions в целом устарела и не рекомендуется при разработке новых расширений.</p> + +<p>Для получения дополнительной информации о том, какой способ использовать, прочтите это <a href="/en-US/Add-ons/Comparing_Extension_Toolchains">сравнение</a>.</p> + +<div class="column-container"> +<div class="column-half"> +<h3 id="Рекомендуемые_практики">Рекомендуемые практики</h3> + +<p>Вне зависимости от того, каким способом Вы разрабатываете расширение, имеются общие рекомендации, следуя которым вы гарантируете пользователю максимально приятную работу с вашим расширением.</p> + +<dl> + <dt><a href="/en-US/Add-ons/Performance_best_practices_in_extensions">Производительность</a></dt> + <dd>Убедитесь в том, что Ваше расширение обладает хорошей производительностью. Оно должно быть достаточно быстрым, иметь отзывчивый интерфейс и потреблять минимальный объем памяти.</dd> + <dt><a href="/en-US/Add-ons/Security_best_practices_in_extensions">Безопасность</a></dt> + <dd>Убедитесь в том, что Ваше приложение не подвергает пользователя опасности на вредоносных веб сайтах.</dd> + <dt><a href="/en-US/Add-ons/Extension_etiquette">Этикет</a></dt> + <dd>Убедитесь в том, что Ваше расширение не конфликтует с другими расширениями.</dd> +</dl> +</div> + +<div class="column-half"> +<h3 id="Специфика_разработки_для_различных_приложений">Специфика разработки для различных приложений</h3> + +<p>Большая часть документации предполагает, что Вы разрабатываете для десктопной версии Firefox. Если Вы разрабатываете для других основанных на движке Gecko приложений, то существуют некоторые отличия, о которых Вам следует знать.</p> + +<dl> + <dt><a href="/en-US/Add-ons/Thunderbird">Thunderbird</a></dt> + <dd>Разработка расширений для почтового клиента Thunderbird.</dd> + <dt><a href="/en-US/Add-ons/Firefox_for_Android">Firefox для Андроид</a></dt> + <dd>Разработка расширений для Firefox под Андроид.</dd> + <dt><a href="/en-US/Add-ons/SeaMonkey_2">SeaMonkey</a></dt> + <dd>Разработка расширений для <a href="http://www.seamonkey-project.org/">SeaMonkey</a>.</dd> +</dl> +</div> +</div> + +<hr> +<h2 id="Темы"><a id="Themes" name="Themes">Темы</a></h2> + +<p>Темы это дополнения, которые изменяют внешний вид пользовательского интерфейса. Существуют два вида тем: легковесные темы и полные темы.</p> + +<div class="column-container"> +<div class="column-half"> +<p><a href="https://addons.mozilla.org/en-US/developers/docs/themes">Легковесные темы</a> значительно легче создать, чем полные, но их возможности ограничены.</p> +</div> + +<div class="column-half"> +<p>С помощью <a href="/en-US/docs/Themes">полных тем</a> вы можете гораздо глубже менять UI приложения. Документация к полным темам устарела, но приведена здесь в качестве возможной основы для обновленной документации.</p> +</div> +</div> + +<hr> +<h2 id="Другие_типы_дополнений">Другие типы дополнений</h2> + +<p><a href="/en-US/docs/Creating_OpenSearch_plugins_for_Firefox">Поисковые плагины</a> являются простыми и очень специфическими типами дополнений: они добавляют новые поисковые системы для поиска в строке браузера.</p> + +<p><strong><a href="/en-US/docs/Plugins">Плагины</a> </strong>(не путать с расширением и дополнением)<strong> </strong>помогают приложению понять содержание, которое не имеет встроенной поддержки. NPAPI-плагины являются устаревшей технологией и новые сайты не будут ее использовать. Как правило, такие плагины не доступны для использования на большинстве современных мобильных систем, и веб-сайты должны избегать их использования</p> + +<h2 id="Смотрите_также" style="margin-bottom: 20px; line-height: 30px; font-size: 2.14285714285714rem;">Смотрите также</h2> + +<ol> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Bootstrapped_extensions" title="Restartless extensions">Restartless extensions</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Overlay_Extensions" title="Legacy extensions">Legacy extensions</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/SDK">Дополнения на основе SDK</a></li> + <li><a href="https://developer.mozilla.org/ru/Add-ons$edit#">Techniques</a> + <ol> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Techniques/Promises">Promises</a></li> + </ol> + </li> + <li><a href="https://developer.mozilla.org/ru/Add-ons$edit#">Рекомендуемая практика</a> + <ol> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Performance_best_practices_in_extensions" title="Performance">Производительность</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Security_best_practices_in_extensions" title="Security">Безопасность</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Extension_etiquette" title="Etiquette">Этикет</a></li> + </ol> + </li> + <li><a href="https://developer.mozilla.org/ru/Add-ons$edit#">Темы</a> + <ol> + <li><a href="https://developer.mozilla.org/Add-ons/Themes/Background" title="Lightweight themes">Легковесные темы</a></li> + <li><a href="https://developer.mozilla.org/Add-ons/Themes/Background/FAQ" title="Lightweight themes FAQ">Легковесные темы FAQ</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Themes" title="Complete themes">Полные темы</a></li> + </ol> + </li> + <li><a href="https://developer.mozilla.org/ru/Add-ons$edit#">Legacy Plugins </a> + <ol> + <li><a href="https://developer.mozilla.org/en-US/docs/Plugins/Guide/Plug-in_Basics">Plug-in Basics</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Plugins/Guide/Plug-in_Development_Overview">Plug-in Development Overview</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Plugins/Guide/Initialization_and_Destruction">Initialization and Destruction</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Plugins/Guide/Drawing_and_Event_Handling">Drawing and Event Handling</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Plugins/Guide/Streams">Streams</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Plugins/Guide/URLs">URLs</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Plugins/Guide/Memory">Memory</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Plugins/Guide/Version%2C_UI%2C_and_Status_Information">Version, UI, and Status Information</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Plugins/Guide/Plug-in_Side_Plug-in_API">Plug-in side Plug-in API</a> + <ol> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPP_Destroy">NPP_Destroy</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPP_DestroyStream">NPP_DestroyStream</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPP_GetValue">NPP_GetValue</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NP_GetValue">NP_GetValue</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPP_HandleEvent">NPP_HandleEvent</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NP_Initialize">NP_Initialize</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPP_New">NPP_New</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPP_NewStream">NPP_NewStream</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPP_Print">NPP_Print</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPP_SetValue">NPP_SetValue</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPP_SetWindow">NPP_SetWindow</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NP_Shutdown">NP_Shutdown</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPP_StreamAsFile">NPP_StreamAsFile</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPP_URLNotify">NPP_URLNotify</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPP_Write">NPP_Write</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPP_WriteReady">NPP_WriteReady</a></li> + </ol> + </li> + <li><a href="https://developer.mozilla.org/en-US/docs/Plugins/Guide/Browser_Side_Plug-in_API">Browser Side Plug-in API</a> + <ol> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPN_DestroyStream" title="Closes and deletes a stream.">NPN_DestroyStream</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPN_ForceRedraw" title="Asks the plugin host to immediately (synchronously) repaint invalid areas.">NPN_ForceRedraw</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPN_GetAuthenticationInfo" title="The function is called by plugins to get HTTP authentication information from the browser.">NPN_GetAuthenticationInfo</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPN_GetURL" title="Asks the browser to create a stream for the specified URL.">NPN_GetURL</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPN_GetURLNotify" title="Requests creation of a new stream with the contents of the specified URL; gets notification of the result.">NPN_GetURLNotify</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPN_GetValue" title="Allows the plug-in to query the browser for information.">NPN_GetValue</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPN_GetValueForURL" title="Provides information to a plugin which is associated with a given URL, for example the cookies or preferred proxy.">NPN_GetValueForURL</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPN_InvalidateRect" title="Invalidates the specified portion of the plugin's drawing area, adding it to the region that needs to be redrawn when the plugin next repaints its contents.">NPN_InvalidateRect</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPN_InvalidateRegion" title="Invalidates the specified drawing region prior to repainting or refreshing a windowless plug-in.">NPN_InvalidateRegion</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPN_MemAlloc" title="Allocates memory from the browser's memory space.">NPN_MemAlloc</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPN_MemFlush" title="Requests that the browser free a specified amount of memory.">NPN_MemFlush</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPN_MemFree" title="Deallocates a block of allocated memory.">NPN_MemFree</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPN_NewStream" title="Requests the creation of a new data stream produced by the plug-in and consumed by the browser.">NPN_NewStream</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPN_PluginThreadAsyncCall" title="Thread safe way to request that the browser calls a plug-in function on the browser or plugin thread (the thread on which the plug-in was initiated).">NPN_PluginThreadAsyncCall</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPN_PostURL" title="Posts data to a URL.">NPN_PostURL</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference//NPN_PostURLNotify" title="Posts data to a URL, and receives notification of the result.">NPN_PostURLNotify</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPN_ReloadPlugins" title="Reloads all of the installed plugins.">NPN_ReloadPlugins</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPN_RequestRead" title="Requests a range of bytes from a seekable stream. This initiates a read operation; the actual data is received through subsequent calls to NPP_WriteReady() and NPP_Write().">NPN_RequestRead</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPN_SetValue" title="Implemented by browsers. This call is used to inform the browser of variable information controlled by the plugin.">NPN_SetValue</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPN_SetValueForURL" title="Allows a plugin to change the stored information associated with a URL, in particular its cookies. (While the API theoretically allows the preferred proxy for a given URL to be changed, doing so does not have much meaning given how proxies are configured, and is not supported.)">NPN_SetValueForURL</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPN_Status" title="Lets a plug-in display a message on the browser's status line.">NPN_Status</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPN_UserAgent" title="Returns the browser's user agent field. This can be used to handle variations in different browsers (or versions thereof) when implementing your plug-in.">NPN_UserAgent</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/docs/NPN_Version" title="Lets plugins obtain version information, both of the plug-in API and of the browser itself.">NPN_Version</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPN_Write" title="Pushes data into a stream produced by the plug-in and consumed by the browser.">NPN_Write</a></li> + </ol> + </li> + <li><a href="https://developer.mozilla.org/en-US/docs/Plugins/Guide/Scripting_plugins">Scripting plugins</a> + <ol> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPString">NPString</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPVariant">NPVariant</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPN_ReleaseVariantValue">NPN_ReleaseVariantValue</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPN_GetStringIdentifier">NPN_GetStringIdentifier</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPN_GetStringIdentifiers">NPN_GetStringIdentifiers</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPN_GetIntIdentifier">NPN_GetIntIdentifier</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPN_IdentifierIsString">NPN_IdentifierIsString</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPN_UTF8FromIdentifier">NPN_UTF8FromIdentifier</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPN_IntFromIdentifier">NPN_IntFromIdentifier</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPObject">NPObject</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPN_CreateObject">NPN_CreateObject</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPN_RetainObject">NPN_RetainObject</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPN_ReleaseObject">NPN_ReleaseObject</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPN_Invoke">NPN_Invoke</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPN_InvokeDefault">NPN_InvokeDefault</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPN_Evaluate">NPN_Evaluate</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPN_GetProperty">NPN_GetProperty</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPN_SetProperty">NPN_SetProperty</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPN_RemoveProperty">NPN_RemoveProperty</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPN_HasProperty">NPN_HasProperty</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPN_HasMethod">NPN_HasMethod</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPN_SetException">NPN_SetException</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/Reference/NPClass">NPClass</a></li> + </ol> + </li> + <li><a href="https://developer.mozilla.org/en-US/docs/Plugins/Guide/Structures">Structures</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Plugins/Guide/Constants">Constants</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Plugins/External_resources_for_plugin_creation">External Resources</a></li> + </ol> + </li> + <li><a href="https://developer.mozilla.org/ru/Add-ons$edit#">Publishing add-ons</a> + <ol> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Distribution">Signing and distributing your add-on</a></li> + <li><a href="https://addons.mozilla.org/developers/addon/submit/">Submit a new add-on</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/AMO/Policy">Policies</a> + <ol> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/AMO/Policy/Agreement">Developer Agreement</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/AMO/Policy/Reviews">Review Process</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/Add-on_guidelines">Add-on guidelines</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/AMO/Policy/Featured">Featured Add-ons</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/AMO/Policy/Contact">Contacting Us</a></li> + </ol> + </li> + </ol> + </li> + <li><a href="https://developer.mozilla.org/ru/Add-ons$edit#">Community and Support</a> + <ol> + <li><a href="https://blog.mozilla.org/addons">Add-ons Blog</a></li> + <li><a href="https://forums.mozilla.org/addons">Add-on Forums</a></li> + <li><a href="http://stackoverflow.com/questions/tagged/firefox-addon">Stack Overflow</a></li> + <li><a href="https://groups.google.com/forum/#%21forum/mozilla.dev.extensions">Development Newsgroup</a></li> + <li><a href="irc://irc.mozilla.org/extdev">IRC Channel</a></li> + </ol> + </li> +</ol> diff --git a/files/ru/mozilla/add-ons/overlay_extensions/index.html b/files/ru/mozilla/add-ons/overlay_extensions/index.html new file mode 100644 index 0000000000..ceac592b8d --- /dev/null +++ b/files/ru/mozilla/add-ons/overlay_extensions/index.html @@ -0,0 +1,65 @@ +--- +title: Overlay extensions +slug: Mozilla/Add-ons/Overlay_Extensions +tags: + - Add-ons + - Extensions + - Landing + - NeedsTranslation + - TopicStub +translation_of: Archive/Add-ons/Overlay_Extensions +--- +<p>Эта страница содержит ссылки на документы с описанием подхода к разработке расширений для приложений, работающих на движке Gecko, которые используют:</p> + +<ul> + <li>описание интерфейса на основе "XUL overlays"</li> + <li>API-интерфейсы, доступные <a href="/ru/docs/Словарь/privileged_code">привилегированному коду</a>, например модулям <a href="/en-US/docs/XUL/tabbrowser"><code>tabbrowser</code></a> и <a href="/en-US/docs/Mozilla/JavaScript_code_modules">JavaScript</a> для взаимодействия с приложениями и контентом.</li> +</ul> + +<p>До релиза Firefox 4 и до движка Gecko 2.0 это был единственный способ разработки расширений. Эта методология разработки была заменена на следующие две:<a href="/ru/Add-ons/загрузочные_расширения"> расширения, не требующие перезапуска</a>, и расширения на основе <a href="/ru/Add-ons/SDK">Add-on SDK</a>. Они обе построены поверх первой. <a href="/ru/docs/Словарь/privileged_code">Привилегированные интерфейсы</a> JavaScript API, описанные здесь могут быть также использованы в новых техниках разработки дополнений.</p> + +<h2 id="Школа_XUL">Школа XUL</h2> + +<p><a href="/ru/docs/XUL_School">Школа XUL</a> - это комплексный учебник по разработке дополнений, сфокусированный на разработке расширений для Firefox, но также подходящий для других приложений, основанных на движке Gecko.</p> + +<h2 id="Ресурсы">Ресурсы</h2> + +<div class="column-container"> +<div class="column-half"> +<dl> + <dt><a href="/en-US/Mozilla/Add-ons/Setting_up_extension_development_environment">Настройка среды</a></dt> + <dd>Настройка приложений для разработки расширений.</dd> + <dt><a href="/ru/docs/XUL">XUL</a></dt> + <dd>Учебники и справочники по языку программирования, используемому XUL-расширениями.</dd> + <dt><a href="/en-US/Mozilla/Add-ons/Code_snippets">Примеры кода</a></dt> + <dd>Примеры кода, которые пригодятся.</dd> + <dt><a href="/en-US/Mozilla/Add-ons/Installing_extensions">Установка расширений</a></dt> + <dd>Как установить расширение копированием файлов в установочный каталог.</dd> + <dt><a href="/en-US/Add-ons/Overlay_extensions/Firefox_addons_developer_guide">Руководство разработчика дополнений для Firefox</a></dt> + <dd>Руководство по разработка расширений.</dd> + <dt><a href="/en-US/docs/Mozilla/JavaScript_code_modules">JavaScript-модули, доступные разработчику</a></dt> + <dd>JavaScript-модули доступные разработчику расширений.</dd> + <dt><a href="/en-US/Mozilla/Add-ons/Inline_Options">Настройка расширения</a></dt> +</dl> +</div> + +<div class="column-half"> +<dl> + <dd>Как добавить свойства расширения, которые появятся в менеджере дополнений (Add-ons Manager).</dd> + <dt><a href="/ru/docs/FAQ_по_расширениям">FAQ</a></dt> + <dd>Решение некоторых общих проблем.</dd> + <dt><a href="/en-US/Mozilla/Add-ons/Extension_Packaging">Сборка и установка расширения</a></dt> + <dd>Сборка и установка.</dd> + <dt><a href="/en-US/Mozilla/Add-ons/Creating_Custom_Firefox_Extensions_with_the_Mozilla_Build_System">Создание бинарных расширений для Firefox</a></dt> + <dd>Создание бинарных расширений.</dd> + <dt><a href="/ru/docs/Building_an_Extension">Создание расширения</a></dt> + <dd>Ещё один небольшой самоучитель по созданию расширения (только на русском языке)</dd> + <dt><a href="/ru/docs/Динамически_изменяемый_пользовательский_интерфейс_на_XUL">Динамически изменяемый пользовательский интерфейс на XUL</a></dt> + <dd>В этой статье обсуждается управление <a href="https://developer.mozilla.org/ru/XUL" title="ru/XUL">XUL</a> интерфейсами с использованием <a href="https://developer.mozilla.org/ru/DOM" title="ru/DOM">DOM</a> и других API.</dd> + <dt><a href="/ru/docs/Настройка_среды_разработки_расширений">Настройка среды разработки расширений</a></dt> + <dd>В этой статье приводится несколько советов о том, как настроить ваше приложение Mozilla для удобной работы над расширениями.</dd> + <dt><a href="/ru/docs/Руководство_по_XUL">Руководство по XUL</a></dt> + <dd>Руководство по XUL</dd> +</dl> +</div> +</div> diff --git a/files/ru/mozilla/add-ons/sdk/guides/index.html b/files/ru/mozilla/add-ons/sdk/guides/index.html new file mode 100644 index 0000000000..1eacaad55a --- /dev/null +++ b/files/ru/mozilla/add-ons/sdk/guides/index.html @@ -0,0 +1,365 @@ +--- +title: Guides +slug: Mozilla/Add-ons/SDK/Guides +tags: + - Add-on SDK +translation_of: Archive/Add-ons/Add-on_SDK/Guides +--- +<p> </p> + +<div class="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> + +<p>Add-ons using the techniques described in this document are considered a legacy technology in Firefox. Don't use these techniques to develop new add-ons. Use <a href="/en-US/Add-ons/WebExtensions">WebExtensions</a> instead. If you maintain an add-on which uses the techniques described here, consider migrating it to use WebExtensions.</p> + +<p><strong>Starting from <a href="https://wiki.mozilla.org/RapidRelease/Calendar">Firefox 53</a>, no new legacy add-ons will be accepted on addons.mozilla.org (AMO) for desktop Firefox and Firefox for Android.</strong></p> + +<p><strong>Starting from <a href="https://wiki.mozilla.org/RapidRelease/Calendar">Firefox 57</a>, only extensions developed using WebExtensions APIs will be supported on Desktop Firefox and Firefox for Android. </strong></p> + +<p>Even before Firefox 57, changes coming up in the Firefox platform will break many legacy extensions. These changes include multiprocess Firefox (e10s), sandboxing, and multiple content processes. Legacy extensions that are affected by these changes should migrate to use WebExtensions APIs if they can. See the <a href="https://blog.mozilla.org/addons/2017/02/16/the-road-to-firefox-57-compatibility-milestones/">"Compatibility Milestones" document</a> for more information.</p> + +<p>A wiki page containing <a href="https://wiki.mozilla.org/Add-ons/developer/communication">resources, migration paths, office hours, and more</a>, is available to help developers transition to the new technologies.</p> +</div> + +<section class="Quick_links" id="Quick_Links"> +<ol> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions"><strong>Browser extensions</strong></a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions#Getting_started">Getting started</a> + <ol> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/What_are_WebExtensions">What are extensions?</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Your_first_WebExtension">Your first extension</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Your_second_WebExtension">Your second extension</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Anatomy_of_a_WebExtension">Anatomy of an extension</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Examples">Example extensions</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/What_next_">What next?</a></li> + </ol> + </li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions#Concepts">Concepts</a> + <ol> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Using_the_JavaScript_APIs">Using the JavaScript APIs</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Content_scripts">Content scripts</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Match_patterns">Match patterns</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Working_with_files">Working with files</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Internationalization">Internationalization</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Security_best_practices">Security best practices</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Content_Security_Policy">Content Security Policy</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Native_messaging">Native messaging</a></li> + </ol> + </li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions#User_Interface">User interface</a> + <ol> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface">User Interface</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Browser_action">Toolbar button</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Page_actions">Address bar button</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Sidebars">Sidebars</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Context_menu_items">Context menu items</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Options_pages">Options page</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Extension_pages">Extension pages</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Notifications">Notifications</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Omnibox">Address bar suggestions</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/devtools_panels">Developer tools panels</a></li> + </ol> + </li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions#How_to">How to</a> + <ol> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Intercept_HTTP_requests">Intercept HTTP requests</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Modify_a_web_page">Modify a web page</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Safely_inserting_external_content_into_a_page">Insert external content</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Add_a_button_to_the_toolbar">Add a button to the toolbar</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Implement_a_settings_page">Implement a settings page</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Working_with_the_Tabs_API">Work with the Tabs API</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Work_with_the_Bookmarks_API">Work with the Bookmarks API</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Work_with_the_Cookies_API">Work with the Cookies API</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Work_with_contextual_identities">Work with contextual identities</a></li> + </ol> + </li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions#Porting">Porting</a> + <ol> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Porting_a_Google_Chrome_extension">Porting a Google Chrome extension</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Porting_a_legacy_Firefox_add-on">Porting a legacy Firefox extension</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Embedded_WebExtensions">Embedded WebExtensions</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Comparison_with_the_Add-on_SDK">Comparison with the Add-on SDK</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Comparison_with_XUL_XPCOM_extensions">Comparison with XUL/XPCOM extensions</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Chrome_incompatibilities">Chrome incompatibilities</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Differences_between_desktop_and_Android">Differences between desktop and Android</a></li> + </ol> + </li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions#Firefox_workflow">Firefox workflow</a> + <ol> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/User_experience_best_practices">User Experience</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Temporary_Installation_in_Firefox">Temporary Installation in Firefox</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Debugging">Debugging</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Testing_persistent_and_restart_features">Testing persistent and restart features</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Developing_WebExtensions_for_Firefox_for_Android">Developing for Firefox for Android</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Getting_started_with_web-ext">Getting started with web-ext</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/web-ext_command_reference">web-ext command reference</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/WebExtensions_and_the_Add-on_ID">Extensions and the Add-on ID</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Request_the_right_permissions">Request the right permissions</a></li> + </ol> + </li> + <li data-default-state="closed"><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API">JavaScript APIs</a> + <ol> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Browser_support_for_JavaScript_APIs">Browser support for JavaScript APIs</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/alarms">alarms</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/bookmarks">bookmarks</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserAction">browserAction</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserSettings">browserSettings</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browsingData">browsingData</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/clipboard">clipboard</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/commands">commands</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/contentScripts">contentScripts</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/contextualIdentities">contextualIdentities</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/cookies">cookies</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/devtools.inspectedWindow">devtools.inspectedWindow</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/devtools.network">devtools.network</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/devtools.panels">devtools.panels</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/dns">dns</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/downloads">downloads</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/events">events</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/extension">extension</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/extensionTypes">extensionTypes</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/find">find</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/history">history</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/i18n">i18n</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/identity">identity</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/idle">idle</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/management">management</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/menus">menus</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/notifications">notifications</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/omnibox">omnibox</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/pageAction">pageAction</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/permissions">permissions</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/pkcs11">pkcs11</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/privacy">privacy</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/proxy">proxy</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime">runtime</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/search">search</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/sessions">sessions</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/sidebarAction">sidebarAction</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage">storage</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs">tabs</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/theme">theme</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/topSites">topSites</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/types">types</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webNavigation">webNavigation</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest">webRequest</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/windows">windows</a></li> + </ol> + </li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json">Manifest keys</a> + <ol> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/applications">applications</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/author">author</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/background">background</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/browser_action">browser_action</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/chrome_settings_overrides">chrome_settings_overrides</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/chrome_url_overrides">chrome_url_overrides</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/commands">commands</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/content_scripts">content_scripts</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/content_security_policy">content_security_policy</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/default_locale">default_locale</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/description">description</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/developer">developer</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/devtools_page">devtools_page</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/homepage_url">homepage_url</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/icons">icons</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/incognito">incognito</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/manifest_version">manifest_version</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/name">name</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/omnibox">omnibox</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/optional_permissions">optional_permissions</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/options_ui">options_ui</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/page_action">page_action</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions">permissions</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/protocol_handlers">protocol_handlers</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/short_name">short_name</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/sidebar_action">sidebar_action</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/theme">theme</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/version">version</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/version_name">version_name</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/web_accessible_resources">web_accessible_resources</a></li> + </ol> + </li> + <li><a href="/en-US/docs/Mozilla/Add-ons/Themes"><strong>Themes</strong></a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/Themes/Theme_concepts">Browser themes</a> + <ol> + <li><a href="/en-US/docs/Mozilla/Add-ons/Themes/Theme_concepts">Browser theme concepts</a></li> + </ol> + </li> + <li><a href="/en-US/docs/Mozilla/Add-ons/Themes/Lightweight_themes">Lightweight themes</a> + <ol> + <li><a href="/en-US/docs/Mozilla/Add-ons/Themes/Lightweight_themes">Lightweight themes</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/Themes/Lightweight_Themes/FAQ">Lightweight themes FAQ</a></li> + </ol> + </li> + <li><a href="/en-US/docs/Mozilla/Add-ons/Distribution"><strong>Publishing and Distribution</strong></a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/Distribution">Publishing add-ons</a> + <ol> + <li><a href="/en-US/docs/Mozilla/Add-ons/Distribution">Signing and distribution overview</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Package_your_extension_">Package your extension</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/Distribution/Submitting_an_add-on">Submit an add-on</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/Source_Code_Submission">Source code submission</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/Distribution/Resources_for_publishers">Resources for publishers</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/Listing">Creating an appealing listing</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/AMO/Policy/Reviews">Review policies</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/AMO/Policy/Agreement">Developer agreement</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/AMO/Policy/Featured">Featured add-ons</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/Distribution/Retiring_your_extension">Retiring your extension</a></li> + </ol> + </li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Alternative_distribution_options">Distributing add-ons</a> + <ol> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Alternative_distribution_options/Sideloading_add-ons">For sideloading</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Alternative_distribution_options/Add-ons_for_desktop_apps">For desktop apps</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Alternative_distribution_options/Add-ons_in_the_enterprise">For an enterprise</a></li> + </ol> + </li> + <li><a href="https://discourse.mozilla.org/c/add-ons"><strong>Community and Support</strong></a></li> + <li><a href="#">Channels</a> + <ol> + <li><a href="https://blog.mozilla.org/addons">Add-ons blog</a></li> + <li><a href="https://discourse.mozilla.org/c/add-ons">Add-on forums</a></li> + <li><a href="http://stackoverflow.com/questions/tagged/firefox-addon">Stack Overflow</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/#Contact_us">Contact us</a></li> + </ol> + </li> +</ol> +</section> + +<p> </p> + +<p>This page lists more theoretical in-depth articles about the SDK.</p> + +<hr> +<h3 id="Contributor's_guide"><a name="contributors-guide">Contributor's guide</a></h3> + +<div class="column-container"> +<div class="column-half"> +<dl> + <dt><a href="Guides/Getting_Started">Getting Started</a></dt> + <dd>Learn how to contribute to the SDK: getting the code, opening/taking a bug, filing a patch, getting reviews, and getting help.</dd> + <dt><a href="Guides/Modules">Modules</a></dt> + <dd>Learn about the module system used by the SDK (which is based on the CommonJS specification), how sandboxes and compartments can be used to improve security, and about the built-in SDK module loader, known as Cuddlefish.</dd> + <dt><a href="Guides/Classes_and_Inheritance">Classes and Inheritance</a></dt> + <dd>Learn how classes and inheritance can be implemented in JavaScript, using constructors and prototypes, and about the helper functions provided by the SDK to simplify this.</dd> +</dl> +</div> + +<div class="column-half"> +<dl> + <dt><a href="Guides/Private_Properties">Private Properties</a></dt> + <dd>Learn how private properties can be implemented in JavaScript using prefixes, closures, and WeakMaps, and how the SDK supports private properties by using namespaces (which are a generalization of WeakMaps).</dd> + <dt><a href="Guides/Content_Processes">Content Processes</a></dt> + <dd>The SDK was designed to work in an environment where the code to manipulate web content runs in a different process from the main add-on code. This article highlights the main features of that design.</dd> + <dt><a href="Guides/Testing_the_Add-on_SDK">Testing the Add-on SDK</a></dt> + <dd>Learn how to run the Add-on SDK test suites.</dd> +</dl> +</div> +</div> + +<hr> +<h3 id="SDK_infrastructure"><a name="sdk-infrastructure">SDK infrastructure</a></h3> + +<div class="column-container"> +<div class="column-half"> +<dl> + <dt><a href="Guides/Module_structure_of_the_SDK">Module structure of the SDK</a></dt> + <dd>The SDK, and add-ons built using it, are of composed from reusable JavaScript modules. This explains what these modules are, how to load modules, and how the SDK's module tree is structured.</dd> + <dt><a href="Guides/SDK_API_Lifecycle">SDK API lifecycle</a></dt> + <dd>Definition of the lifecycle for the SDK's APIs, including the stability ratings for APIs.</dd> +</dl> +</div> + +<div class="column-half"> +<dl> + <dt><a href="Guides/Program_ID">Program ID</a></dt> + <dd>The Program ID is a unique identifier for your add-on. This guide explains how it's created, what it's used for and how to define your own.</dd> + <dt><a href="Guides/Firefox_Compatibility">Firefox compatibility</a></dt> + <dd>Working out which Firefox releases a given SDK release is compatible with, and dealing with compatibility problems.</dd> +</dl> +</div> +</div> + +<hr> +<h3 id="SDK_idioms"><a name="sdk-idioms">SDK idioms</a></h3> + +<div class="column-container"> +<div class="column-half"> +<dl> + <dt><a href="Guides/Working_with_Events">Working With Events</a></dt> + <dd>Write event-driven code using the the SDK's event emitting framework.</dd> + <dt><a href="Guides/Content_Scripts">Content scripts guide</a></dt> + <dd>An overview of content scripts, including: what they are, what they can do, how to load them, how to communicate with them.</dd> +</dl> +</div> + +<div class="column-half"> +<dl> + <dt><a href="Guides/Two_Types_of_Scripts">Two Types of Scripts</a></dt> + <dd>This article explains the differences between the APIs available to your main add-on code and those available to content scripts.</dd> +</dl> +</div> +</div> + +<hr> +<h3 id="XUL_migration"><a name="xul-migration">XUL migration</a></h3> + +<div class="column-container"> +<div class="column-half"> +<dl> + <dt><a href="Guides/XUL_Migration_Guide">XUL Migration Guide</a></dt> + <dd>Techniques to help port a XUL add-on to the SDK.</dd> + <dt><a href="Guides/XUL_vs_SDK">XUL versus the SDK</a></dt> + <dd>A comparison of the strengths and weaknesses of the SDK, compared to traditional XUL-based add-ons.</dd> +</dl> +</div> + +<div class="column-half"> +<dl> + <dt><a href="Guides/Porting_the_Library_Detector">Porting Example</a></dt> + <dd>A walkthrough of porting a relatively simple XUL-based add-on to the SDK.</dd> +</dl> +</div> +</div> + +<hr> +<h3 id="Multiprocess_Firefox"><a name="multiprocess-firefox">Multiprocess Firefox</a></h3> + +<div class="column-container"> +<div class="column-half"> +<dl> + <dt><a href="Guides/Multiprocess_Firefox_and_the_SDK">Multiprocess Firefox and the SDK</a></dt> + <dd>How to check whether your add-on is compatible with multiprocess Firefox, and fix it if it isn't.</dd> +</dl> +</div> + +<div class="column-half"> </div> +</div> + +<hr> +<div> +<div class="overheadIndicator communitybox" dir="ltr"> +<div class="column-container"> +<h2 id="Join_the_Add-on_SDK_community">Join the Add-on SDK community</h2> + +<div class="column-half"> +<div class="communitysubhead">Choose your preferred method for joining the discussion:</div> + +<ul class="communitymailinglist"> + <li><a href="https://lists.mozilla.org/listinfo/">Mailing list</a></li> + <li><a href="https://twitter.com/mozillajetpack">Twitter</a></li> + <li><a href="http://stackoverflow.com/questions/tagged/firefox-addon-sdk">Stack Overflow</a></li> + <li><a href="http://groups.google.com/group/mozilla-labs-jetpack">Newsgroup</a></li> + <li><a href="http://groups.google.com/group/mozilla-labs-jetpack/feeds">RSS feed</a></li> +</ul> +</div> + +<div class="column-half"> +<ul class="communitycontact"> + <li><strong>IRC: </strong><a href="irc://irc.mozilla.org/jetpack">#jetpack</a> <span class="smaller">(<a href="https://wiki.mozilla.org/IRC">learn more</a>)</span></li> + <li><strong>Team info: </strong><a href="https://wiki.mozilla.org/Jetpack" title="Designs and plans for the SDK tools">Jetpack Wiki</a></li> +</ul> +</div> +</div> +</div> +</div> diff --git a/files/ru/mozilla/add-ons/sdk/guides/скрипты_содержимого/index.html b/files/ru/mozilla/add-ons/sdk/guides/скрипты_содержимого/index.html new file mode 100644 index 0000000000..59832331e8 --- /dev/null +++ b/files/ru/mozilla/add-ons/sdk/guides/скрипты_содержимого/index.html @@ -0,0 +1,519 @@ +--- +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 = "<h1>this page has been eaten</h1>";' + +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 = ' + + ' "<h1>Page matches ruleset</h1>";'; + +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 = "<h1>Page matches ruleset</h1>";</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("<h1>Page matches ruleset</h1>");'; + +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"><!DOCTYPE html"> +<html> + <head> + <script> + window.foo = "hello from page script" + </script> + </head> +</html></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"><html> + <head> + </head> + <body> + <script> + window.onclick = function() { + window.alert("it's my click now!"); + } + </script> + </body> +</html></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 > 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> diff --git a/files/ru/mozilla/add-ons/sdk/high-level_apis/addon-page/index.html b/files/ru/mozilla/add-ons/sdk/high-level_apis/addon-page/index.html new file mode 100644 index 0000000000..069cb199b2 --- /dev/null +++ b/files/ru/mozilla/add-ons/sdk/high-level_apis/addon-page/index.html @@ -0,0 +1,32 @@ +--- +title: Страницы дополнения +slug: Mozilla/Add-ons/SDK/High-Level_APIs/addon-page +translation_of: Archive/Add-ons/Add-on_SDK/High-Level_APIs/addon-page +--- +<p>{{AddonSidebar}}</p> + +<p>{{obsolete_header(35)}}</p> + +<p>Создание простых страниц</p> + +<h2 id="Применеие">Применеие</h2> + +<p>С помошью Add-on SDK Вы можете представлять данные пользователю, такие как руководство по использованию вашего дополнения во вкладке браузера. Вы можете подгружать содержимое из HTML файла в "data" директории дополнения.</p> + +<div class="note"> +<p><strong>Заметка:</strong> Данный модульне влияет на браузер.</p> +</div> + +<p>Для подобных страниц, navigational elements such as the <a href="http://support.mozilla.org/en-US/kb/Location%20bar%20autocomplete">Awesome Bar</a>, <a href="http://support.mozilla.org/en-US/kb/Search%20bar">Search Bar</a>, or <a href="http://support.mozilla.org/en-US/kb/Bookmarks%20Toolbar">Bookmarks Toolbar</a> are not usually relevant and distract from the content you are presenting. The <code>addon-page</code> module provides a simple way to have a page which excludes these elements.</p> + +<p>Чтобы импортировать содержимое, используйте <code>require()</code>. После чего, данные загрузятся из "data/index.html" без элементов навигации:</p> + +<pre class="brush: js">var addontab = require("sdk/addon-page"); +var data = require("sdk/self").data; + +require("sdk/tabs").open(data.url("index.html")); +</pre> + +<p><img alt="" src="https://mdn.mozillademos.org/files/6503/addon-page.png" style="display: block; height: 722px; margin-left: auto; margin-right: auto; width: 666px;"></p> + +<p>Это влияет только на "data/index.html": остальные страницы отображаются нормально.</p> diff --git a/files/ru/mozilla/add-ons/sdk/high-level_apis/context-menu/index.html b/files/ru/mozilla/add-ons/sdk/high-level_apis/context-menu/index.html new file mode 100644 index 0000000000..2d88abc734 --- /dev/null +++ b/files/ru/mozilla/add-ons/sdk/high-level_apis/context-menu/index.html @@ -0,0 +1,578 @@ +--- +title: context-menu +slug: Mozilla/Add-ons/SDK/High-Level_APIs/context-menu +translation_of: Archive/Add-ons/Add-on_SDK/High-Level_APIs/context-menu +--- +<div class="note"> + <p>Stable</p> +</div> +<p><span class="seoSummary">Как добавить элемент меню, подменю и разделитель в контекстное меню страницы.</span></p> +<h2 id="Использование">Использование</h2> +<p>Instead of manually adding items when particular contexts occur and then removing them when those contexts go away, you <em>bind</em> items to contexts, and the adding and removing is automatically handled for you. Items are bound to contexts in much the same way that event listeners are bound to events. When the user invokes the context menu, all of the items bound to the current context are automatically added to the menu. If no items are bound, none are added. Likewise, any items that were previously in the menu but are not bound to the current context are automatically removed from the menu. You never need to manually remove your items from the menu unless you want them to never appear again.</p> +<p>For example, if your add-on needs to add a context menu item whenever the user visits a certain page, don't create the item when that page loads, and don't remove it when the page unloads. Rather, create your item only once and supply a context that matches the target URL.</p> +<p>Context menu items are displayed in the order created or in the case of sub menus the order added to the sub menu. Menu items for each add-on will be grouped together automatically. If the total number of menu items in the main context menu from all add-ons exceeds a certain number (normally 10 but configurable with the <code>extensions.addon-sdk.context-menu.overflowThreshold</code> preference) all of the menu items will instead appear in an overflow menu to avoid making the context menu too large.</p> +<h3 id="Specifying_Contexts">Specifying Contexts</h3> +<p>As its name implies, the context menu should be reserved for the occurrence of specific contexts. Contexts can be related to page content or the page itself, but they should never be external to the page.</p> +<p>For example, a good use of the menu would be to show an "Edit Image" item when the user right-clicks an image in the page. A bad use would be to show a submenu that listed all the user's tabs, since tabs aren't related to the page or the node the user clicked to open the menu.</p> +<h4 id="The_Page_Context">The Page Context</h4> +<p>First of all, you may not need to specify a context at all. When a top-level item does not specify a context, the page context applies. An item that is in a submenu is visible unless you specify a context.</p> +<p>The <em>page context</em> occurs when the user invokes the context menu on a non-interactive portion of the page. Try right-clicking a blank spot in this page, or on text. Make sure that no text is selected. The menu that appears should contain the items "Back", "Forward", "Reload", "Stop", and so on. This is the page context.</p> +<p>The page context is appropriate when your item acts on the page as a whole. It does not occur when the user invokes the context menu on a link, image, or other non-text node, or while a selection exists.</p> +<h4 id="Declarative_Contexts">Declarative Contexts</h4> +<p>You can specify some simple, declarative contexts when you create a menu item by setting the <code>context</code> property of the options object passed to its constructor, like this:</p> +<pre class="brush: js">var cm = require("sdk/context-menu"); +cm.Item({ + label: "My Menu Item", + context: cm.URLContext("*.mozilla.org") +});</pre> +<table class="standard-table"> + <tbody> + <tr> + <th>Constructor</th> + <th>Description</th> + </tr> + <tr> + <td><code>PageContext() </code></td> + <td>The page context.</td> + </tr> + <tr> + <td><code>SelectionContext() </code></td> + <td>This context occurs when the menu is invoked on a page in which the user has made a selection.</td> + </tr> + <tr> + <td><code>SelectorContext(selector) </code></td> + <td>This context occurs when the menu is invoked on a node that either matches <code>selector</code>, a CSS selector, or has an ancestor that matches. <code>selector</code> may include multiple selectors separated by commas, e.g., <code>"a[href], img"</code>.</td> + </tr> + <tr> + <td><code>URLContext(matchPattern) </code></td> + <td>This context occurs when the menu is invoked on pages with particular URLs. <code>matchPattern</code> is a match pattern string or an array of match pattern strings. When <code>matchPattern</code> is an array, the context occurs when the menu is invoked on a page whose URL matches any of the patterns. These are the same match pattern strings that you use with the <a href="/en-US/Add-ons/SDK/High-Level_APIs/page-mod"><code>page-mod</code></a> <code>include</code> property. <a href="/en-US/Add-ons/SDK/Low-Level_APIs/util_match-pattern">Read more about patterns</a>.</td> + </tr> + <tr> + <td><code>PredicateContext(predicateFunction)</code></td> + <td><code>predicateFunction</code> is called when the menu is invoked, and the context occurs when the function returns a true value. The function is passed an object with properties describing the menu invocaton context.</td> + </tr> + <tr> + <td>array</td> + <td>An array of any of the other types. This context occurs when all contexts in the array occur.</td> + </tr> + </tbody> +</table> +<p>Menu items also have a <code>context</code> property that can be used to add and remove declarative contexts after construction. For example:</p> +<pre class="brush: js">var context = require("sdk/context-menu").SelectorContext("img"); +myMenuItem.context.add(context); +myMenuItem.context.remove(context);</pre> +<p>When a menu item is bound to more than one context, it appears in the menu when all of those contexts occur.</p> +<h3 id="In_Content_Scripts">In Content Scripts</h3> +<p>The declarative contexts are handy but not very powerful. For instance, you might want your menu item to appear for any page that has at least one image, but declarative contexts won't help you there.</p> +<p>When you need more control over the context in which your menu items are shown, you can use content scripts. Like other APIs in the SDK, the <code>context-menu</code> API uses <a href="/en-US/Add-ons/SDK/Guides/Content_Scripts">content scripts</a> to let your add-on interact with pages in the browser. Each menu item you create in the top-level context menu can have a content script.</p> +<p>A special event named <code>"context"</code> is emitted in your content scripts whenever the context menu is about to be shown. If you register a listener function for this event and it returns true, the menu item associated with the listener's content script is shown in the menu.</p> +<p>For example, this item appears whenever the context menu is invoked on a page that contains at least one image:</p> +<pre class="brush: js">require("sdk/context-menu").Item({ + label: "This Page Has Images", + contentScript: 'self.on("context", function (node) {' + + ' return !!document.querySelector("img");' + + '});' +});</pre> +<p>Note that the listener function has a parameter called <code>node</code>. This is the node in the page that the user context-clicked to invoke the menu. You can use it to determine whether your item should be shown.</p> +<p>You can both specify declarative contexts and listen for contexts in a content script. In that case, the declarative contexts are evaluated first, and your item is shown only when all declarative contexts are current and your context listener returns true.</p> +<p>If any declarative contexts are not current, then your context listener is never called. This example takes advantage of that fact. The listener can be assured that <code>node</code> will always be an image:</p> +<pre class="brush: js">var cm = require("sdk/context-menu"); +cm.Item({ + label: "A Mozilla Image", + context: cm.SelectorContext("img"), + contentScript: 'self.on("context", function (node) {' + + ' return /mozilla/.test(node.src);' + + '});' +});</pre> +<p>However, if you do combine <code>SelectorContext</code> and the <code>"context"</code> event, be aware that the <code>node</code> argument passed to the <code>"context"</code> event will not always match the type specified in <code>SelectorContext</code>.</p> +<p><code>SelectorContext</code> will match if the menu is invoked on the node specified <em>or any descendant of that node</em>, but the <code>"context"</code> event handler is passed <em>the actual node</em> on which the menu was invoked. The example above works because <code><IMG></code> elements can't contain other elements, but in the example below, <code>node.nodeName</code> is not guaranteed to be "P" - for example, it won't be "P" if the user context-clicked a link inside a paragraph:</p> +<pre class="brush: js">var cm = require("sdk/context-menu"); +cm.Item({ + label: "A Paragraph", + context: cm.SelectorContext("p"), + contentScript: 'self.on("context", function (node) {' + + ' console.log(node.nodeName);' + + ' return true;' + + '});' +});</pre> +<p>The content script is executed for every page that a context menu is shown for. It will be executed the first time it is needed (i.e. when the context menu is first shown and all of the declarative contexts for your item are current) and then remains active until you destroy your context menu item or the page is unloaded.</p> +<h3 id="Handling_Menu_Item_Clicks">Handling Menu Item Clicks</h3> +<p>In addition to using content scripts to listen for the <code>"context"</code> event as described above, you can use content scripts to handle item clicks. When the user clicks your menu item, an event named <code>"click"</code> is emitted in the item's content script.</p> +<p>Therefore, to handle an item click, listen for the <code>"click"</code> event in that item's content script like so:</p> +<pre class="brush: js">require("sdk/context-menu").Item({ + label: "My Item", + contentScript: 'self.on("click", function (node, data) {' + + ' console.log("Item clicked!");' + + '});' +});</pre> +<p>Note that the listener function has parameters called <code>node</code> and <code>data</code>.</p> +<h4 id="The_node_Argument">The "node" Argument</h4> +<p><code>node</code> is the node that the user context-clicked to invoke the menu.</p> +<ul> + <li>If you did not use <code>SelectorContext</code> to decide whether to show the menu item, then this is the actual node clicked.</li> + <li>If you did use <code>SelectorContext</code>, then this is the node that matched your selector.</li> +</ul> +<p>For example, suppose your add-on looks like this:</p> +<pre class="brush: js">var script = "self.on('click', function (node, data) {" + + " console.log('clicked: ' + node.nodeName);" + + "});"; + +var cm = require("sdk/context-menu"); + +cm.Item({ + label: "body context", + context: cm.SelectorContext("body"), + contentScript: script +});</pre> +<p>This add-on creates a context-menu item that uses <code>SelectorContext</code> to display the item whenever the context menu is activated on any descendant of the <code><BODY></code> element. When clicked, the item just logs the <a href="https://developer.mozilla.org/en-US/docs/DOM/Node.nodeName"><code>nodeName</code></a> property for the node passed to the click handler.</p> +<p>If you run this add-on you'll see that it always logs "BODY", even if you click on a paragraph element inside the page:</p> +<pre>info: contextmenu-example: clicked: BODY</pre> +<p>By contrast, this add-on uses the <code>PageContext</code>:</p> +<pre class="brush: js">var script = "self.on('click', function (node, data) {" + + " console.log('clicked: ' + node.nodeName);" + + "});"; + +var cm = require("sdk/context-menu"); + +cm.Item({ + label: "body context", + context: cm.PageContext(), + contentScript: script +});</pre> +<p>It will log the name of the actual node clicked:</p> +<pre>info: contextmenu-example: clicked: P</pre> +<h4 id="The_data_Argument">The "data" Argument</h4> +<p><code>data</code> is the <code>data</code> property of the menu item that was clicked. Note that when you have a hierarchy of menu items the click event will be sent to the content script of the item clicked and all ancestors so be sure to verify that the <code>data</code> value passed matches the item you expect. You can use this to simplify click handling by providing just a single click listener on a <code>Menu</code> that reacts to clicks for any child items.:</p> +<pre class="brush: js">var cm = require("sdk/context-menu"); +cm.Menu({ + label: "My Menu", + contentScript: 'self.on("click", function (node, data) {' + + ' console.log("You clicked " + data);' + + '});', + items: [ + cm.Item({ label: "Item 1", data: "item1" }), + cm.Item({ label: "Item 2", data: "item2" }), + cm.Item({ label: "Item 3", data: "item3" }) + ] +}); +</pre> +<h4 id="Communicating_With_the_Add-on">Communicating With the Add-on</h4> +<p>Often you will need to collect some kind of information in the click listener and perform an action unrelated to content. To communicate to the menu item associated with the content script, the content script can call the <code>postMessage</code> function attached to the global <code>self</code> object, passing it some JSON-able data. The menu item's <code>"message"</code> event listener will be called with that data.</p> +<pre class="brush: js">var cm = require("sdk/context-menu"); +cm.Item({ + label: "Edit Image", + context: cm.SelectorContext("img"), + contentScript: 'self.on("click", function (node, data) {' + + ' self.postMessage(node.src);' + + '});', + onMessage: function (imgSrc) { + openImageEditor(imgSrc); + } +});</pre> +<h3 id="Updating_a_Menu_Item's_Label">Updating a Menu Item's Label</h3> +<p>Each menu item must be created with a label, but you can change its label later using a couple of methods.</p> +<p>The simplest method is to set the menu item's <code>label</code> property. This example updates the item's label based on the number of times it's been clicked:</p> +<pre class="brush: js">var numClicks = 0; +var myItem = require("sdk/context-menu").Item({ + label: "Click Me: " + numClicks, + contentScript: 'self.on("click", self.postMessage);', + onMessage: function () { + numClicks++; + this.label = "Click Me: " + numClicks; + // Setting myItem.label is equivalent. + } +});</pre> +<p>Sometimes you might want to update the label based on the context. For instance, if your item performs a search with the user's selected text, it would be nice to display the text in the item to provide feedback to the user. In these cases you can use the second method. Recall that your content scripts can listen for the <code>"context"</code> event and if your listeners return true, the items associated with the content scripts are shown in the menu. In addition to returning true, your <code>"context"</code> listeners can also return strings. When a <code>"context"</code> listener returns a string, it becomes the item's new label.</p> +<p>This item implements the aforementioned search example:</p> +<pre class="brush: js">var cm = require("sdk/context-menu"); +cm.Item({ + label: "Search Google", + context: cm.SelectionContext(), + contentScript: 'self.on("context", function () {' + + ' var text = window.getSelection().toString();' + + ' if (text.length > 20)' + + ' text = text.substr(0, 20) + "...";' + + ' return "Search Google for " + text;' + + '});' +});</pre> +<p>The <code>"context"</code> listener gets the window's current selection, truncating it if it's too long, and includes it in the returned string. When the item is shown, its label will be "Search Google for <code>text</code>", where <code>text</code> is the truncated selection.</p> +<h3 id="Private_Windows">Private Windows</h3> +<p>If your add-on has not opted into private browsing, then any menus or menu items that you add will not appear in context menus belonging to private browser windows.</p> +<p>To learn more about private windows, how to opt into private browsing, and how to support private browsing, refer to the <a href="/en-US/Add-ons/SDK/High-Level_APIs/private-browsing">documentation for the <code>private-browsing</code> module</a>.</p> +<h3 id="More_Examples">More Examples</h3> +<p>For conciseness, these examples create their content scripts as strings and use the <code>contentScript</code> property. In your own add-on, you will probably want to create your content scripts in separate files and pass their URLs using the <code>contentScriptFile</code> property. See <a href="/en-US/Add-ons/SDK/Guides/Content_Scripts">Working with Content Scripts</a> for more information.</p> +<div class="warning"> + <p>Unless your content script is extremely simple and consists only of a static string, don't use <code>contentScript</code>: if you do, you may have problems getting your add-on approved on AMO.</p> + <p>Instead, keep the script in a separate file and load it using <code>contentScriptFile</code>. This makes your code easier to maintain, secure, debug and review.</p> +</div> +<p>Show an "Edit Page Source" item when the user right-clicks a non-interactive part of the page:</p> +<pre class="brush: js">require("sdk/context-menu").Item({ + label: "Edit Page Source", + contentScript: 'self.on("click", function (node, data) {' + + ' self.postMessage(document.URL);' + + '});', + onMessage: function (pageURL) { + editSource(pageURL); + } +});</pre> +<p>Show an "Edit Image" item when the menu is invoked on an image:</p> +<pre class="brush: js">var cm = require("sdk/context-menu"); +cm.Item({ + label: "Edit Image", + context: cm.SelectorContext("img"), + contentScript: 'self.on("click", function (node, data) {' + + ' self.postMessage(node.src);' + + '});', + onMessage: function (imgSrc) { + openImageEditor(imgSrc); + } +});</pre> +<p>Show an "Edit Mozilla Image" item when the menu is invoked on an image in a mozilla.org or mozilla.com page:</p> +<pre class="brush: js">var cm = require("sdk/context-menu"); +cm.Item({ + label: "Edit Mozilla Image", + context: [ + cm.URLContext(["*.mozilla.org", "*.mozilla.com"]), + cm.SelectorContext("img") + ], + contentScript: 'self.on("click", function (node, data) {' + + ' self.postMessage(node.src);' + + '});', + onMessage: function (imgSrc) { + openImageEditor(imgSrc); + } +});</pre> +<p>Show an "Edit Page Images" item when the page contains at least one image:</p> +<pre class="brush: js">var cm = require("sdk/context-menu"); +cm.Item({ + label: "Edit Page Images", + // This ensures the item only appears during the page context. + context: cm.PageContext(), + contentScript: 'self.on("context", function (node) {' + + ' var pageHasImgs = !!document.querySelector("img");' + + ' return pageHasImgs;' + + '});' + + 'self.on("click", function (node, data) {' + + ' var imgs = document.querySelectorAll("img");' + + ' var imgSrcs = [];' + + ' for (var i = 0 ; i < imgs.length; i++)' + + ' imgSrcs.push(imgs[i].src);' + + ' self.postMessage(imgSrcs);' + + '});', + onMessage: function (imgSrcs) { + openImageEditor(imgSrcs); + } +});</pre> +<p>Show a "Search With" menu when the user right-clicks an anchor that searches Google or Wikipedia with the text contained in the anchor:</p> +<pre class="brush: js">var cm = require("sdk/context-menu"); +var googleItem = cm.Item({ + label: "Google", + data: "http://www.google.com/search?q=" +}); +var wikipediaItem = cm.Item({ + label: "Wikipedia", + data: "http://en.wikipedia.org/wiki/Special:Search?search=" +}); +var searchMenu = cm.Menu({ + label: "Search With", + context: cm.SelectorContext("a[href]"), + contentScript: 'self.on("click", function (node, data) {' + + ' var searchURL = data + node.textContent;' + + ' window.location.href = searchURL;' + + '});', + items: [googleItem, wikipediaItem] +});</pre> +<h2 id="Globals">Globals</h2> +<h3 id="Constructors">Constructors</h3> +<h4 class="addon-sdk-api-name" id="Item(options)"><code>Item(options)</code></h4> +<p>Creates a labeled menu item that can perform an action when clicked.</p> +<h5 id="Parameters">Parameters</h5> +<p><strong>options : object</strong><br> + Required options:</p> +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Name</th> + <th scope="col">Type</th> + <th scope="col"> </th> + </tr> + </thead> + <tbody> + <tr> + <td>label</td> + <td>string</td> + <td> + <p>The item's label. It must either be a string or an object that implements <code>toString()</code>.</p> + </td> + </tr> + </tbody> +</table> +<p>Optional options:</p> +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Name</th> + <th scope="col">Type</th> + <th scope="col"> </th> + </tr> + </thead> + <tbody> + <tr> + <td>image</td> + <td>string</td> + <td> + <p>The item's icon, a string URL. The URL can be remote, a reference to an image in the add-on's <code>data</code> directory, or a data URI.</p> + </td> + </tr> + <tr> + <td>data</td> + <td>string</td> + <td> + <p>An optional arbitrary value to associate with the item. It must be either a string or an object that implements <code>toString()</code>. It will be passed to click listeners.</p> + </td> + </tr> + <tr> + <td>context</td> + <td>value</td> + <td> + <p>If the item is contained in the top-level context menu, this declaratively specifies the context under which the item will appear; see Specifying Contexts above.</p> + </td> + </tr> + <tr> + <td>contentScript</td> + <td>string,array</td> + <td> + <p>If the item is contained in the top-level context menu, this is the content script or an array of content scripts that the item can use to interact with the page.</p> + </td> + </tr> + <tr> + <td>contentScriptFile</td> + <td>string,array</td> + <td> + <p>If the item is contained in the top-level context menu, this is the local file URL of the content script or an array of such URLs that the item can use to interact with the page.</p> + </td> + </tr> + <tr> + <td>onMessage</td> + <td>function</td> + <td> + <p>If the item is contained in the top-level context menu, this function will be called when the content script calls <code>self.postMessage</code>. It will be passed the data that was passed to <code>postMessage</code>.</p> + </td> + </tr> + </tbody> +</table> +<h4 class="addon-sdk-api-name" id="Menu(options)"><code>Menu(options)</code></h4> +<p>Creates a labeled menu item that expands into a submenu.</p> +<h5 id="Parameters_2">Parameters</h5> +<p><strong>options : object</strong><br> + Required options:</p> +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Name</th> + <th scope="col">Type</th> + <th scope="col"> </th> + </tr> + </thead> + <tbody> + <tr> + <td>label</td> + <td>string</td> + <td> + <p>The item's label. It must either be a string or an object that implements <code>toString()</code>.</p> + </td> + </tr> + <tr> + <td>items</td> + <td>array</td> + <td> + <p>An array of menu items that the menu will contain. Each must be an <code>Item</code>, <code>Menu</code>, or <code>Separator</code>.</p> + </td> + </tr> + </tbody> +</table> +<p>Optional options:</p> +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Name</th> + <th scope="col">Type</th> + <th scope="col"> </th> + </tr> + </thead> + <tbody> + <tr> + <td>image</td> + <td>string</td> + <td> + <p>The menu's icon, a string URL. The URL can be remote, a reference to an image in the add-on's <code>data</code> directory, or a data URI.</p> + </td> + </tr> + <tr> + <td>context</td> + <td>value</td> + <td> + <p>If the menu is contained in the top-level context menu, this declaratively specifies the context under which the menu will appear; see Specifying Contexts above.</p> + </td> + </tr> + <tr> + <td>contentScript</td> + <td>string,array</td> + <td> + <p>If the menu is contained in the top-level context menu, this is the content script or an array of content scripts that the menu can use to interact with the page.</p> + </td> + </tr> + <tr> + <td>contentScriptFile</td> + <td>string,array</td> + <td> + <p>If the menu is contained in the top-level context menu, this is the local file URL of the content script or an array of such URLs that the menu can use to interact with the page.</p> + </td> + </tr> + <tr> + <td>onMessage</td> + <td>function</td> + <td> + <p>If the menu is contained in the top-level context menu, this function will be called when the content script calls <code>self.postMessage</code>. It will be passed the data that was passed to <code>postMessage</code>.</p> + </td> + </tr> + </tbody> +</table> +<h4 class="addon-sdk-api-name" id="Separator()"><code>Separator()</code></h4> +<p>Creates a menu separator.</p> +<h4 class="addon-sdk-api-name" id="PageContext()"><code>PageContext()</code></h4> +<p>Creates a page context. See Specifying Contexts above.</p> +<h4 class="addon-sdk-api-name" id="SelectionContext()"><code>SelectionContext()</code></h4> +<p>Creates a context that occurs when a page contains a selection. See Specifying Contexts above.</p> +<h4 class="addon-sdk-api-name" id="SelectorContext(selector)"><code>SelectorContext(selector)</code></h4> +<p>Creates a context that matches a given CSS selector. See Specifying Contexts above.</p> +<h5 id="Parameters_3">Parameters</h5> +<p><strong>selector : string</strong><br> + A CSS selector.</p> +<h4 class="addon-sdk-api-name" id="URLContext(matchPattern)"><code>URLContext(matchPattern)</code></h4> +<p>Creates a context that matches pages with particular URLs. See Specifying Contexts above.</p> +<h5 id="Parameters_4">Parameters</h5> +<p><strong>matchPattern : string,array</strong><br> + A <a href="/en-US/Add-ons/SDK/Low-Level_APIs/util_match-pattern">match pattern</a> string, regexp or an array of match pattern strings or regexps.</p> +<h4 class="addon-sdk-api-name" id="PredicateContext(predicateFunction)"><code>PredicateContext(predicateFunction)</code></h4> +<div class="geckoVersionNote"> + <p>New in Firefox 29</p> +</div> +<p>Creates a context that occurs when predicateFunction returns a true value. See Specifying Contexts above.</p> +<h5 id="Parameters_5">Parameters</h5> +<p><strong>predicateFunction : function(context)</strong><br> + A function which will be called with an object argument that provide information about the invocation context. <code>context</code> object properties:</p> +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Property</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>documentType</code></td> + <td>The MIME type of the document the menu was invoked in. E.g. <code>text/html</code> for HTML pages, <code>application/xhtml+xml</code> for XHTML, or <code>image/jpeg</code> if viewing an image directly.</td> + </tr> + <tr> + <td><code>documentURL</code></td> + <td>The URL of the document the menu was invoked in.</td> + </tr> + <tr> + <td><code>targetName</code></td> + <td>The name of the DOM element that the menu was invoked on, in lower-case.</td> + </tr> + <tr> + <td><code>targetID</code></td> + <td>The <code>id</code> attribute of the element that the menu was invoked on, or <code>null</code> if not set.</td> + </tr> + <tr> + <td><code>isEditable</code></td> + <td><code>true</code> if the menu was invoked in an editable element, and that element isn't disabled or read-only. This includes non-input elements with the <code>contenteditable</code> attribute set to <code>true</code>.</td> + </tr> + <tr> + <td><code>selectionText</code></td> + <td>The current selection as a text string, or <code>null</code>. If the menu was invoked in an input text box or area, this is the selection of that element, otherwise the selection in the contents of the window.</td> + </tr> + <tr> + <td><code>srcURL</code></td> + <td>The <code>src</code> URL of the element that the menu was invoked on, or <code>null</code> if it doesn't have one.</td> + </tr> + <tr> + <td><code>linkURL</code></td> + <td>The <code>href</code> URL of the element that the menu was invoked on, or <code>null</code> if it doesn't have one.</td> + </tr> + <tr> + <td><code>value</code></td> + <td>The current contents of a input text box or area if the menu was invoked in one, <code>null</code> otherwise.</td> + </tr> + </tbody> +</table> +<h2 id="Item">Item</h2> +<p>A labeled menu item that can perform an action when clicked.</p> +<h3 id="Methods">Methods</h3> +<h4 class="addon-sdk-api-name" id="destroy()"><code>destroy()</code></h4> +<p>Permanently removes the item from its parent menu and frees its resources. The item must not be used afterward. If you need to remove the item from its parent menu but use it afterward, call <code>removeItem()</code> on the parent menu instead.</p> +<h3 id="Properties">Properties</h3> +<h4 class="addon-sdk-api-name" id="label"><code>label</code></h4> +<p>The menu item's label. You can set this after creating the item to update its label later.</p> +<h4 class="addon-sdk-api-name" id="image"><code>image</code></h4> +<p>The item's icon, a string URL. The URL can be remote, a reference to an image in the add-on's <code>data</code> directory, or a data URI. You can set this after creating the item to update its image later. To remove the item's image, set it to <code>null</code>.</p> +<h4 class="addon-sdk-api-name" id="data"><code>data</code></h4> +<p>An optional arbitrary value to associate with the item. It must be either a string or an object that implements <code>toString()</code>. It will be passed to click listeners. You can set this after creating the item to update its data later.</p> +<h4 class="addon-sdk-api-name" id="context"><code>context</code></h4> +<p>A list of declarative contexts for which the menu item will appear in the context menu. Contexts can be added by calling <code>context.add()</code> and removed by called <code>context.remove()</code>.</p> +<h4 class="addon-sdk-api-name" id="parentMenu"><code>parentMenu</code></h4> +<p>The item's parent <code>Menu</code>, or <code>null</code> if the item is contained in the top-level context menu. This property is read-only. To add the item to a new menu, call that menu's <code>addItem()</code> method.</p> +<h4 class="addon-sdk-api-name" id="contentScript"><code>contentScript</code></h4> +<p>The content script or the array of content scripts associated with the menu item during creation.</p> +<h4 class="addon-sdk-api-name" id="contentScriptFile"><code>contentScriptFile</code></h4> +<p>The URL of a content script or the array of such URLs associated with the menu item during creation.</p> +<h3 id="Events">Events</h3> +<h4 class="addon-sdk-api-name" id="message"><code>message</code></h4> +<p>If you listen to this event you can receive message events from content scripts associated with this menu item. When a content script posts a message using <code>self.postMessage()</code>, the message is delivered to the add-on code in the menu item's <code>message</code> event.</p> +<h5 id="Arguments">Arguments</h5> +<p><strong>value</strong> : Listeners are passed a single argument which is the message posted from the content script. The message can be any <a href="/en-US/Add-ons/SDK/Guides/Content_Scripts/using_port#JSON-Serializable_Values">JSON-serializable value</a>.</p> +<h2 id="Menu">Menu</h2> +<p>A labeled menu item that expands into a submenu.</p> +<h3 id="Methods_2">Methods</h3> +<h4 class="addon-sdk-api-name" id="addItem(item)"><code>addItem(item)</code></h4> +<p>Appends a menu item to the end of the menu. If the item is already contained in another menu or in the top-level context menu, it's automatically removed first. If the item is already contained in this menu it will just be moved to the end of the menu.</p> +<h5 id="Parameters_6">Parameters</h5> +<p><strong>item : Item,Menu,Separator</strong><br> + The <code>Item</code>, <code>Menu</code>, or <code>Separator</code> to add to the menu.</p> +<h4 class="addon-sdk-api-name" id="removeItem(item)"><code>removeItem(item)</code></h4> +<p>Removes the given menu item from the menu. If the menu does not contain the item, this method does nothing.</p> +<h5 id="Parameters_7">Parameters</h5> +<p><strong>item : Item,Menu,Separator</strong><br> + The menu item to remove from the menu.</p> +<h4 class="addon-sdk-api-name" id="destroy()_2"><code>destroy()</code></h4> +<p>Permanently removes the menu from its parent menu and frees its resources. The menu must not be used afterward. If you need to remove the menu from its parent menu but use it afterward, call <code>removeItem()</code> on the parent menu instead.</p> +<h3 id="Properties_2">Properties</h3> +<h4 class="addon-sdk-api-name" id="label_2"><code>label</code></h4> +<p>The menu's label. You can set this after creating the menu to update its label later.</p> +<h4 class="addon-sdk-api-name" id="items"><code>items</code></h4> +<p>An array containing the items in the menu. The array is read-only, meaning that modifications to it will not affect the menu. However, setting this property to a new array will replace all the items currently in the menu with the items in the new array.</p> +<h4 class="addon-sdk-api-name" id="image_2"><code>image</code></h4> +<p>The menu's icon, a string URL. The URL can be remote, a reference to an image in the add-on's <code>data</code> directory, or a data URI. You can set this after creating the menu to update its image later. To remove the menu's image, set it to <code>null</code>.</p> +<h4 class="addon-sdk-api-name" id="context_2"><code>context</code></h4> +<p>A list of declarative contexts for which the menu will appear in the context menu. Contexts can be added by calling <code>context.add()</code> and removed by called <code>context.remove()</code>.</p> +<h4 class="addon-sdk-api-name" id="parentMenu_2"><code>parentMenu</code></h4> +<p>The menu's parent <code>Menu</code>, or <code>null</code> if the menu is contained in the top-level context menu. This property is read-only. To add the menu to a new menu, call that menu's <code>addItem()</code> method.</p> +<h4 class="addon-sdk-api-name" id="contentScript_2"><code>contentScript</code></h4> +<p>The content script or the array of content scripts associated with the menu during creation.</p> +<h4 class="addon-sdk-api-name" id="contentScriptFile_2"><code>contentScriptFile</code></h4> +<p>The URL of a content script or the array of such URLs associated with the menu during creation.</p> +<h3 id="Events_2">Events</h3> +<h4 class="addon-sdk-api-name" id="message_2"><code>message</code></h4> +<p>If you listen to this event you can receive message events from content scripts associated with this menu item. When a content script posts a message using <code>self.postMessage()</code>, the message is delivered to the add-on code in the menu item's <code>message</code> event.</p> +<h5 id="Arguments_2">Arguments</h5> +<p><strong>value</strong> : Listeners are passed a single argument which is the message posted from the content script. The message can be any <a href="/en-US/Add-ons/SDK/Guides/Content_Scripts/using_port#JSON-Serializable_Values">JSON-serializable value</a>.</p> +<h2 id="Separator">Separator</h2> +<p>A menu separator. Separators can be contained only in <code>Menu</code>s, not in the top-level context menu.</p> +<h3 id="Methods_3">Methods</h3> +<h4 class="addon-sdk-api-name" id="destroy()_3"><code>destroy()</code></h4> +<p>Permanently removes the separator from its parent menu and frees its resources. The separator must not be used afterward. If you need to remove the separator from its parent menu but use it afterward, call <code>removeItem()</code> on the parent menu instead.</p> +<h3 id="Properties_3">Properties</h3> +<h4 class="addon-sdk-api-name" id="parentMenu_3"><code>parentMenu</code></h4> +<p>The separator's parent <code>Menu</code>. This property is read-only. To add the separator to a new menu, call that menu's <code>addItem()</code> method.</p> diff --git a/files/ru/mozilla/add-ons/sdk/high-level_apis/index.html b/files/ru/mozilla/add-ons/sdk/high-level_apis/index.html new file mode 100644 index 0000000000..32b39d045b --- /dev/null +++ b/files/ru/mozilla/add-ons/sdk/high-level_apis/index.html @@ -0,0 +1,10 @@ +--- +title: High-Level APIs +slug: Mozilla/Add-ons/SDK/High-Level_APIs +tags: + - NeedsTranslation + - TopicStub +translation_of: Archive/Add-ons/Add-on_SDK/High-Level_APIs +--- +<p>Modules listed on this page implement high-level APIs for building add-ons: creating user interfaces, interacting with the web, and interacting with the browser.</p> +<p>Unless the documentation explicitly says otherwise, all these modules are "Stable": we'll avoid making incompatible changes to them. {{ LandingPageListSubpages ("/en-US/Add-ons/SDK/High-Level_APIs", 5) }}</p> diff --git a/files/ru/mozilla/add-ons/sdk/high-level_apis/passwords/index.html b/files/ru/mozilla/add-ons/sdk/high-level_apis/passwords/index.html new file mode 100644 index 0000000000..535385e895 --- /dev/null +++ b/files/ru/mozilla/add-ons/sdk/high-level_apis/passwords/index.html @@ -0,0 +1,525 @@ +--- +title: passwords +slug: Mozilla/Add-ons/SDK/High-Level_APIs/passwords +translation_of: Archive/Add-ons/Add-on_SDK/High-Level_APIs/passwords +--- +<div class="note"> + <p>Stable</p> +</div> +<p><span class="seoSummary">Interact with Firefox's <a href="http://support.mozilla.com/en-US/kb/Remembering%20passwords">Password Manager</a> to add, retrieve and remove stored credentials.</span></p> +<h2 id="Usage">Usage</h2> +<p>A <em>credential</em> is the set of information a user supplies to authenticate herself with a service. Typically a credential consists of a username and a password.</p> +<p>Using this module you can:</p> +<ol> + <li> + <p><strong>Search</strong> for credentials which have been stored in the Password Manager. You can then use the credentials to access their related service (for example, by logging into a web site).</p> + </li> + <li> + <p><strong>Store</strong> credentials in the Password Manager. You can store different sorts of credentials, as outlined in the "Credentials" section below.</p> + </li> + <li> + <p><strong>Remove</strong> stored credentials from the Password Manager.</p> + </li> +</ol> +<h3 id="Credentials">Credentials</h3> +<p>In this API, credentials are represented by objects.</p> +<p>You create credential objects to pass into the API, and the API also returns credential objects to you. The sections below explain both the properties you should define on credential objects and the properties you can expect on credential objects returned by the API.</p> +<p>All credential objects include <code>username</code> and <code>password</code> properties. Different sorts of stored credentials include various additional properties, as outlined in this section.</p> +<p>You can use the Passwords API with three sorts of credentials:</p> +<ul> + <li>Add-on credentials</li> + <li>HTML form credentials</li> + <li>HTTP Authentication credentials</li> +</ul> +<h4 id="Add-on_Credential">Add-on Credential</h4> +<p>These are associated with your add-on rather than a particular web site. They contain the following properties:</p> +<table class="standard-table"> + <colgroup> + <col> + </colgroup> + <tbody> + <tr> + <td><code>username</code></td> + <td>The username.</td> + </tr> + <tr> + <td><code>password</code></td> + <td>The password.</td> + </tr> + <tr> + <td><code>url</code></td> + <td> + <p>For an add-on credential, this property is of the form:<br> + <code>addon:<addon-id></code>, where <code><addon-id></code> is the add-on's <a href="/en-US/Add-ons/SDK/Guides/Program_ID"> Program ID</a>.</p> + <p>You don't supply this value when storing an add-on credential: it is automatically generated for you. However, you can use it to work out which stored credentials belong to your add-on by comparing it with the <code>uri</code> property of the <a href="/en-US/Add-ons/SDK/High-Level_APIs/self"><code>self</code></a> module.</p> + </td> + </tr> + <tr> + <td><code>realm</code></td> + <td> + <p>You can use this as a name for the credential, to distinguish it from any other credentials you've stored.</p> + <p>The realm is displayed in Firefox's Password Manager, under "Site", in brackets after the URL. For example, if the realm for a credential is "User Registration", then its "Site" field will look something like:</p> + <code>addon:jid0-01mBBFyu0ZAXCFuB1JYKooSTKIc (User Registration)</code></td> + </tr> + </tbody> +</table> +<h4 id="HTML_Form_Credential">HTML Form Credential</h4> +<p>If a web service uses HTML forms to authenticate its users, then the corresponding credential is an HTML Form credential.</p> +<p>It contains the following properties:</p> +<table class="standard-table"> + <colgroup> + <col> + </colgroup> + <tbody> + <tr> + <td><code>username</code></td> + <td>The username.</td> + </tr> + <tr> + <td><code>password</code></td> + <td>The password.</td> + </tr> + <tr> + <td><code>url</code></td> + <td>The URL for the web service which requires the credential. You should omit anything after the hostname and (optional) port.</td> + </tr> + <tr> + <td><code>formSubmitURL</code></td> + <td>The value of the form's "action" attribute. You should omit anything after the hostname and (optional) port. If the form doesn't contain an "action" attribute, this property should match the <code>url</code> property.</td> + </tr> + <tr> + <td><code>usernameField</code></td> + <td>The value of the "name" attribute for the form's username field.</td> + </tr> + <tr> + <td><code>passwordField</code></td> + <td>The value of the "name" attribute for the form's password field.</td> + </tr> + </tbody> +</table> +<p>So: given a form at <code>http://www.example.com/login</code> with the following HTML:</p> +<pre class="brush: html"><form action="http://login.example.com/foo/authenticate.cgi"> + <div>Please log in.</div> + <label>Username:</label> <input type="text" name="uname"> + <label>Password:</label> <input type="password" name="pword"> +</form></pre> +<p>The corresponding values for the credential (excluding username and password) should be:</p> +<pre> url: "http://www.example.com" + formSubmitURL: "http://login.example.com" + usernameField: "uname" + passwordField: "pword" +</pre> +<p>Note that for both <code>url</code> and <code>formSubmitURL</code>, the portion of the URL after the hostname is omitted.</p> +<h4 id="HTTP_Authentication_Credential">HTTP Authentication Credential</h4> +<p>These are used to authenticate the user to a web site which uses HTTP Authentication, as detailed in <a href="http://tools.ietf.org/html/rfc2617">RFC 2617</a>. They contain the following properties:</p> +<table class="standard-table"> + <colgroup> + <col> + </colgroup> + <tbody> + <tr> + <td><code>username</code></td> + <td>The username.</td> + </tr> + <tr> + <td><code>password</code></td> + <td>The password.</td> + </tr> + <tr> + <td><code>url</code></td> + <td>The URL for the web service which requires the credential. You should omit anything after the hostname and (optional) port.</td> + </tr> + <tr> + <td><code>realm</code></td> + <td> + <p>The WWW-Authenticate response header sent by the server may include a "realm" field as detailed in <a href="http://tools.ietf.org/html/rfc2617">RFC 2617</a>. If it does, this property contains the value for the "realm" field. Otherwise, it is omitted.</p> + <p>The realm is displayed in Firefox's Password Manager, under "Site", in brackets after the URL.</p> + </td> + </tr> + </tbody> +</table> +<p>So: if a web server at <code>http://www.example.com</code> requested authentication with a response code like this:</p> +<pre> HTTP/1.0 401 Authorization Required + Server: Apache/1.3.27 + WWW-Authenticate: Basic realm="ExampleCo Login" +</pre> +<p>The corresponding values for the credential (excluding username and password) should be:</p> +<pre> url: "http://www.example.com" + realm: "ExampleCo Login" +</pre> +<h3 id="onComplete_and_onError">onComplete and onError</h3> +<p>This API is explicitly asynchronous, so all its functions take two callback functions as additional options: <code>onComplete</code> and <code>onError</code>.</p> +<p><code>onComplete</code> is called when the operation has completed successfully and <code>onError</code> is called when the function encounters an error.</p> +<p>Because the <code>search</code> function is expected to return a list of matching credentials, its <code>onComplete</code> option is mandatory. Because the other functions don't return a value in case of success their <code>onComplete</code> options are optional.</p> +<p>For all functions, <code>onError</code> is optional.</p> +<h2 id="Globals">Globals</h2> +<h3 id="Functions">Functions</h3> +<h4 class="addon-sdk-api-name" id="search(options)"><code>search(options)</code></h4> +<p>This function is used to retrieve a credential, or a list of credentials, stored in the Password Manager.</p> +<p>You pass it any subset of the possible properties a credential can contain. Credentials which match all the properties you supplied are returned as an argument to the <code>onComplete</code> callback.</p> +<p>So if you pass in an empty set of properties, all stored credentials are returned:</p> +<pre class="brush: js">function show_all_passwords() { + require("sdk/passwords").search({ + onComplete: function onComplete(credentials) { + credentials.forEach(function(credential) { + console.log(credential.username); + console.log(credential.password); + }); + } + }); + }</pre> +<p>If you pass it a single property, only credentials matching that property are returned:</p> +<pre class="brush: js">function show_passwords_for_joe() { + require("sdk/passwords").search({ + username: "joe", + onComplete: function onComplete(credentials) { + credentials.forEach(function(credential) { + console.log(credential.username); + console.log(credential.password); + }); + } + }); + }</pre> +<p>If you pass more than one property, returned credentials must match all of them:</p> +<pre class="brush: js">function show_google_password_for_joe() { + require("sdk/passwords").search({ + username: "joe", + url: "https://www.google.com", + onComplete: function onComplete(credentials) { + credentials.forEach(function(credential) { + console.log(credential.username); + console.log(credential.password); + }); + } + }); + }</pre> +<p>To retrieve only credentials associated with your add-on, use the <code>url</code> property, initialized from <code>self.uri</code>:</p> +<pre class="brush: js">function show_my_addon_passwords() { + require("sdk/passwords").search({ + url: require("sdk/self").uri, + onComplete: function onComplete(credentials) { + credentials.forEach(function(credential) { + console.log(credential.username); + console.log(credential.password); + }); + } + }); + }</pre> +<h5 id="Parameters">Parameters</h5> +<p><strong>options : object</strong><br> + Required options:</p> +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Name</th> + <th scope="col">Type</th> + <th scope="col"> </th> + </tr> + </thead> + <tbody> + <tr> + <td>onComplete</td> + <td>function</td> + <td> + <p>The callback function that is called once the function completes successfully. It is passed all the matching credentials as a list. This is the only mandatory option.</p> + </td> + </tr> + </tbody> +</table> +<p>Optional options:</p> +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Name</th> + <th scope="col">Type</th> + <th scope="col"> </th> + </tr> + </thead> + <tbody> + <tr> + <td>username</td> + <td>string</td> + <td> + <p>The username for the credential.</p> + </td> + </tr> + <tr> + <td>password</td> + <td>string</td> + <td> + <p>The password for the credential.</p> + </td> + </tr> + <tr> + <td>url</td> + <td>string</td> + <td> + <p>The URL associated with the credential.</p> + </td> + </tr> + <tr> + <td>formSubmitURL</td> + <td>string</td> + <td> + <p>The URL an HTML form credential is submitted to.</p> + </td> + </tr> + <tr> + <td>realm</td> + <td>string</td> + <td> + <p>For HTTP Authentication credentials, the realm for which the credential was requested. For add-on credentials, a name for the credential.</p> + </td> + </tr> + <tr> + <td>usernameField</td> + <td>string</td> + <td> + <p>The value of the <code>name</code> attribute for the user name input field in a form.</p> + </td> + </tr> + <tr> + <td>passwordField</td> + <td>string</td> + <td> + <p>The value of the <code>name</code> attribute for the password input field in a form.</p> + </td> + </tr> + <tr> + <td>onError</td> + <td>function</td> + <td> + <p>The callback function that is called if the function failed. The callback is passed an <code>error</code> containing a reason of a failure: this is an <a href="https://developer.mozilla.org/en/nsIException">nsIException</a> object.</p> + </td> + </tr> + </tbody> +</table> +<h4 class="addon-sdk-api-name" id="store(options)"><code>store(options)</code></h4> +<p>This function is used to store a credential in the Password Manager.</p> +<p>It takes an <code>options</code> object as an argument: this contains all the properties for the new credential.</p> +<p>As different sorts of credentials contain different properties, the appropriate options differ depending on the sort of credential being stored.</p> +<p>To store an add-on credential:</p> +<pre class="brush: js">require("sdk/passwords").store({ + realm: "User Registration", + username: "joe", + password: "SeCrEt123", +});</pre> +<p>To store an HTML form credential:</p> +<pre class="brush: js">require("sdk/passwords").store({ + url: "http://www.example.com", + formSubmitURL: "http://login.example.com", + username: "joe", + usernameField: "uname", + password: "SeCrEt123", + passwordField: "pword" +});</pre> +<p>To store an HTTP Authentication credential:</p> +<pre class="brush: js">require("sdk/passwords").store({ + url: "http://www.example.com", + realm: "ExampleCo Login", + username: "joe", + password: "SeCrEt123", +});</pre> +<p>See "Credentials" above for more details on how to set these properties.</p> +<p>The options parameter may also include <code>onComplete</code> and <code>onError</code> callback functions, which are called when the function has completed successfully and when it encounters an error, respectively. These options are both optional.</p> +<h5 id="Parameters_2">Parameters</h5> +<p><strong>options : object</strong><br> + Required options:</p> +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Name</th> + <th scope="col">Type</th> + <th scope="col"> </th> + </tr> + </thead> + <tbody> + <tr> + <td>username</td> + <td>string</td> + <td> + <p>The username for the credential.</p> + </td> + </tr> + <tr> + <td>password</td> + <td>string</td> + <td> + <p>The password for the credential.</p> + </td> + </tr> + </tbody> +</table> +<p>Optional options:</p> +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Name</th> + <th scope="col">Type</th> + <th scope="col"> </th> + </tr> + </thead> + <tbody> + <tr> + <td>url</td> + <td>string</td> + <td> + <p>The URL to which the credential applies. Omitted for add-on credentials.</p> + </td> + </tr> + <tr> + <td>formSubmitURL</td> + <td>string</td> + <td> + <p>The URL a form-based credential was submitted to. Omitted for add-on credentials and HTTP Authentication credentials.</p> + </td> + </tr> + <tr> + <td>realm</td> + <td>string</td> + <td> + <p>For HTTP Authentication credentials, the realm for which the credential was requested. For add-on credentials, a name for the credential.</p> + </td> + </tr> + <tr> + <td>usernameField</td> + <td>string</td> + <td> + <p>The value of the <code>name</code> attribute for the username input in a form. Omitted for add-on credentials and HTTP Authentication credentials.</p> + </td> + </tr> + <tr> + <td>passwordField</td> + <td>string</td> + <td> + <p>The value of the <code>name</code> attribute for the password input in a form. Omitted for add-on credentials and HTTP Authentication credentials.</p> + </td> + </tr> + <tr> + <td>onComplete</td> + <td>function</td> + <td> + <p>The callback function that is called once the function completes successfully.</p> + </td> + </tr> + <tr> + <td>onError</td> + <td>function</td> + <td> + <p>The callback function that is called if the function failed. The callback is passed an <code>error</code> argument: this is an <a href="https://developer.mozilla.org/en/nsIException">nsIException</a> object.</p> + </td> + </tr> + </tbody> +</table> +<h4 class="addon-sdk-api-name" id="remove(options)"><code>remove(options)</code></h4> +<p>Removes a stored credential. You supply it all the properties of the credential to remove, along with optional <code>onComplete</code> and <code>onError</code> callbacks.</p> +<p>Because you must supply all the credential's properties, it may be convenient to call <code>search</code> first, and use its output as the input to <code>remove</code>. For example, to remove all of joe's stored credentials:</p> +<pre class="brush: js">require("sdk/passwords").search({ + username: "joe", + onComplete: function onComplete(credentials) { + credentials.forEach(require("sdk/passwords").remove); + }) +});</pre> +<p>To change an existing credential just call <code>store</code> after <code>remove</code> succeeds:</p> +<pre class="brush: js">require("sdk/passwords").remove({ + realm: "User Registration", + username: "joe", + password: "SeCrEt123" + onComplete: function onComplete() { + require("sdk/passwords").store({ + realm: "User Registration", + username: "joe", + password: "{new password}" + }) + } +});</pre> +<h5 id="Parameters_3">Parameters</h5> +<p><strong>options : object</strong><br> + Required options:</p> +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Name</th> + <th scope="col">Type</th> + <th scope="col"> </th> + </tr> + </thead> + <tbody> + <tr> + <td>username</td> + <td>string</td> + <td> + <p>The username for the credential.</p> + </td> + </tr> + <tr> + <td>password</td> + <td>string</td> + <td> + <p>The password for the credential.</p> + </td> + </tr> + </tbody> +</table> +<p>Optional options:</p> +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Name</th> + <th scope="col">Type</th> + <th scope="col"> </th> + </tr> + </thead> + <tbody> + <tr> + <td>url</td> + <td>string</td> + <td> + <p>The URL to which the credential applies. Omitted for add-on credentials.</p> + </td> + </tr> + <tr> + <td>formSubmitURL</td> + <td>string</td> + <td> + <p>The URL a form-based credential was submitted to. Omitted for add-on credentials and HTTP Authentication credentials.</p> + </td> + </tr> + <tr> + <td>realm</td> + <td>string</td> + <td> + <p>For HTTP Authentication credentials, the realm for which the credential was requested. For add-on credentials, a name for the credential.</p> + </td> + </tr> + <tr> + <td>usernameField</td> + <td>string</td> + <td> + <p>The value of the <code>name</code> attribute for the username input in a form. Omitted for add-on credentials and HTTP Authentication credentials.</p> + </td> + </tr> + <tr> + <td>passwordField</td> + <td>string</td> + <td> + <p>The value of the <code>name</code> attribute for the password input in a form. Omitted for add-on credentials and HTTP Authentication credentials.</p> + </td> + </tr> + <tr> + <td>onComplete</td> + <td>function</td> + <td> + <p>The callback function that is called once the function has completed successfully.</p> + </td> + </tr> + <tr> + <td>onError</td> + <td>function</td> + <td> + <p>The callback function that is called if the function failed. The callback is passed an <code>error</code> argument: this is an <a href="https://developer.mozilla.org/en/nsIException">nsIException</a> object.</p> + </td> + </tr> + </tbody> +</table> +<p> </p> diff --git a/files/ru/mozilla/add-ons/sdk/index.html b/files/ru/mozilla/add-ons/sdk/index.html new file mode 100644 index 0000000000..6c8217da66 --- /dev/null +++ b/files/ru/mozilla/add-ons/sdk/index.html @@ -0,0 +1,90 @@ +--- +title: Add-on SDK +slug: Mozilla/Add-ons/SDK +tags: + - NeedsTranslation + - TopicStub +translation_of: Archive/Add-ons/Add-on_SDK +--- +<p><span id="result_box" lang="ru"><span class="hps">C помощью </span> <span class="hps">SDK</span> <span class="hps">вы можете создавать дополнения для</span></span><span lang="ru"> <span class="hps">Firefox</span> <span>, используя стандартные</span> <span class="atn hps">веб-</span><span>технологии</span><span>:</span> <span class="hps">JavaScript, HTML</span><span>,</span> <span class="hps">CSS</span>. <span>SDK</span> <span class="hps">включает в себя</span> <span class="hps">API-интерфейсы</span> <span class="hps">JavaScript</span><span>, которые можно использовать</span> <span class="hps">для создания</span> дополнений <span class="hps">и инструменты</span> <span class="hps">для</span> <span class="hps">создания, запуска</span><span>,</span> <span class="hps">тестирования</span> <span class="hps">и</span> <span class="hps">упаковки</span> дополнений<span class="hps">.</span></span></p> + +<hr> +<h3 id="Учебники">Учебники</h3> + +<div class="column-container"> +<div class="column-half"> +<dl> + <dt><a href="/en-US/Add-ons/SDK/Tutorials#getting-started">Начало</a></dt> + <dd>Как <a href="/en-US/Add-ons/SDK/Tutorials/Installation">установить SDK</a> и <a href="/en-US/Add-ons/SDK/Tutorials/Getting_Started_With_cfx">использовать CFX</a> для разработки, тестирования и упаковки дополнений.</dd> + <dt><a href="/en-US/Add-ons/SDK/Tutorials#interact-with-the-browser">Взаимодействие с браузером</a></dt> + <dd><a href="/en-US/Add-ons/SDK/Tutorials/Open_a_Web_Page">Открытие веб-страниц</a>, <a href="/en-US/Add-ons/SDK/Tutorials/Listen_For_Page_Load">прослушивание загрузки страницы</a>, и <a href="/en-US/Add-ons/SDK/Tutorials/List_Open_Tabs">список загруженных страниц</a>.</dd> + <dt><a href="/en-US/Add-ons/SDK/Tutorials#development-techniques">Методы разработки</a></dt> + <dd>Узнайте об распространённых методах разработки, таких как <a href="/en-US/Add-ons/SDK/Tutorials/Unit_testing">модульное тестирование</a>, <a href="/en-US/Add-ons/SDK/Tutorials/Logging">регистрация</a>, <a href="/en-US/Add-ons/SDK/Tutorials/Creating_Reusable_Modules">создание повторных модулей</a>, <a href="/ru/docs/%D0%9B%D0%BE%D0%BA%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F">локализация</a>, и <a href="/en-US/Add-ons/SDK/Tutorials/Mobile_development">мобильная разработка</a>.</dd> +</dl> +</div> + +<div class="column-half"> +<dl> + <dt><a href="/en-US/Add-ons/SDK/Tutorials#create-user-interfaces">Создание компонентов пользовательского интерфейса</a></dt> + <dd>Создание компонентов пользовательского интерфейса, такие как <a href="/en-US/Add-ons/SDK/Tutorials/Adding_a_Button_to_the_Toolbar">кнопки панели инструментов </a>, <a href="/en-US/Add-ons/SDK/Tutorials/Add_a_Context_Menu_Item">контекстные меню</a>, <a href="/en-US/Add-ons/SDK/Tutorials/Add_a_Menu_Item_to_Firefox">пункты меню</a>, и <a href="/en-US/Add-ons/SDK/Tutorials/Display_a_Popup">диалоговые окна</a>.</dd> + <dt><a href="/en-US/Add-ons/SDK/Tutorials#modify-web-pages">Изменение веб-страниц</a></dt> + <dd>Изменение страниц, которые <a href="/en-US/Add-ons/SDK/Tutorials/Modifying_Web_Pages_Based_on_URL">соответствуют заданному URL шаблону</a> или динамически <a href="/en-US/Add-ons/SDK/Tutorials/Modifying_the_Page_Hosted_by_a_Tab">изменить заданную вкладку</a>.</dd> + <dt><a href="/en-US/Add-ons/SDK/Tutorials/Annotator">Соединяем всё вместе</a></dt> + <dd>Обучение на примере расширения Комментатор.</dd> +</dl> +</div> +</div> + +<hr> +<h3 id="Инструкции">Инструкции</h3> + +<div class="column-container"> +<div class="column-half"> +<dl> + <dt><a href="/en-US/Add-ons/SDK/Guides#contributors-guide">Руководство для разработчика НРП</a></dt> + <dd>Learn <a href="/en-US/Add-ons/SDK/Guides/Getting_Started">how to start contributing</a> to the SDK, and about the most important idioms used in the SDK code, such as <a href="/en-US/Add-ons/SDK/Guides/Modules">modules</a>, <a href="/en-US/Add-ons/SDK/Guides/Classes_and_Inheritance">classes and inheritance</a>, <a href="/en-US/Add-ons/SDK/Guides/Private_Properties">private properties</a>, and <a href="/en-US/Add-ons/SDK/Guides/Content_Processes">content processes</a>.</dd> + <dt><a href="/en-US/Add-ons/SDK/Guides#sdk-infrastructure">НРП инфраструктура</a></dt> + <dd>Aspects of the SDK's underlying technology: <a href="/en-US/Add-ons/SDK/Guides/Module_structure_of_the_SDK">modules</a>, the <a href="/en-US/Add-ons/SDK/Guides/Program_ID">Program ID</a>, and the rules defining <a href="/en-US/Add-ons/SDK/Guides/Firefox_Compatibility">Firefox compatibility</a>.</dd> + <dt><a href="/en-US/Add-ons/SDK/Guides/Content_Scripts">Скрипты содержимого</a></dt> + <dd>A detailed guide to working with content scripts.</dd> +</dl> +</div> + +<div class="column-half"> +<dl> + <dt><a href="/en-US/Add-ons/SDK/Guides#sdk-idioms">Особенности НРП</a></dt> + <dd>The SDK's <a href="/en-US/Add-ons/SDK/Guides/Working_with_Events">event framework</a> and the <a href="/en-US/Add-ons/SDK/Guides/Two_Types_of_Scripts">distinction between add-on scripts and content scripts</a>.</dd> + <dt><a href="/en-US/Add-ons/SDK/Guides/XUL_Migration_Guide">XUL перемещение</a></dt> + <dd>A guide to <a href="/en-US/Add-ons/SDK/Guides/XUL_Migration_Guide">porting XUL add-ons to the SDK</a>. This guide includes a <a href="/en-US/Add-ons/SDK/Guides/XUL_vs_SDK">comparison of the two toolsets</a> and a <a href="/en-US/Add-ons/SDK/Guides/Porting_the_Library_Detector">working example</a> of porting a XUL add-on.</dd> +</dl> +</div> +</div> + +<hr> +<h3 id="Справочник">Справочник</h3> + +<div class="column-container"> +<div class="column-half"> +<dl> + <dt><a href="/en-US/Add-ons/SDK/High-Level_APIs">Высокоуровневый ИПП</a></dt> + <dd>Справочная документация для высокоуровневого ИПП в НРП.</dd> + <dt><a href="/en-US/Add-ons/SDK/Tools">Справочник программ</a></dt> + <dd>Справочная документация для <a href="/en-US/Add-ons/SDK/Tools/cfx">cfx программы</a> используемая для разработки, тестирования, и упаковывания расширений, глобальная <a href="/en-US/Add-ons/SDK/Tools/console">console</a> используемая для протоколирования, и файл <a href="/en-US/Add-ons/SDK/Tools/package_json">package.json</a>.</dd> +</dl> +</div> + +<div class="column-half"> +<dl> + <dt><a href="/en-US/Add-ons/SDK/Low-Level_APIs">Низкоуровневый ИПП</a></dt> + <dd>Справочная документация для низкоуровневого ИПП в НРП.</dd> +</dl> +</div> +</div> + +<p> </p> + +<div class="toppageup" id="js-toppageup" style="display: none;"> +<div class="toppageup-link"><span>наверх</span></div> + +<div class="toppageup-add" id="js-toppageup-add"><span>в закладки</span></div> +</div> diff --git a/files/ru/mozilla/add-ons/sdk/low-level_apis/index.html b/files/ru/mozilla/add-ons/sdk/low-level_apis/index.html new file mode 100644 index 0000000000..8cd08458f0 --- /dev/null +++ b/files/ru/mozilla/add-ons/sdk/low-level_apis/index.html @@ -0,0 +1,23 @@ +--- +title: Low-Level APIs +slug: Mozilla/Add-ons/SDK/Low-Level_APIs +tags: + - NeedsTranslation + - TopicStub +translation_of: Archive/Add-ons/Add-on_SDK/Low-Level_APIs +--- +<p>Modules in this section implement low-level APIs. These modules fall roughly into three categories:</p> +<ul> + <li> + <p>fundamental utilities such as <a href="/en-US/Add-ons/SDK/Low-Level_APIs/util_collection">collection</a>. Many add-ons are likely to want to use modules from this category.</p> + </li> + <li> + <p>building blocks for higher level modules, such as <a href="/en-US/Add-ons/SDK/Low-Level_APIs/event_core">events</a> and <a href="/en-US/Add-ons/SDK/Low-Level_APIs/content_worker">worker</a>. You're more likely to use these if you are building your own modules that implement new APIs, thus extending the SDK itself.</p> + </li> + <li> + <p>privileged modules that expose powerful low-level capabilities such as <a href="/en-US/Add-ons/SDK/Low-Level_APIs/window_utils">window/utils</a> and <a href="/en-US/Add-ons/SDK/Low-Level_APIs/net_xhr">net/xhr</a>. You can use these modules in your add-on if you need to, but should be aware that the cost of privileged access is the need to take more elaborate security precautions. In many cases these modules have simpler, more restricted analogs among the "High-Level APIs" (for example, <a href="/en-US/Add-ons/SDK/High-Level_APIs/windows">windows</a> or <a href="/en-US/Add-ons/SDK/High-Level_APIs/request">request</a>).</p> + </li> +</ul> +<p>These modules are still in active development, and we expect to make incompatible changes to them in future releases.</p> +<p>{{ LandingPageListSubpages ("/en-US/Add-ons/SDK/Low-Level_APIs", 5) }}</p> +<p> </p> diff --git a/files/ru/mozilla/add-ons/sdk/low-level_apis/places_bookmarks/index.html b/files/ru/mozilla/add-ons/sdk/low-level_apis/places_bookmarks/index.html new file mode 100644 index 0000000000..299e234fb2 --- /dev/null +++ b/files/ru/mozilla/add-ons/sdk/low-level_apis/places_bookmarks/index.html @@ -0,0 +1,595 @@ +--- +title: places/bookmarks +slug: Mozilla/Add-ons/SDK/Low-Level_APIs/places_bookmarks +translation_of: Archive/Add-ons/Add-on_SDK/Low-Level_APIs/places_bookmarks +--- +<div class="note"> +<p>Unstable</p> +</div> + +<p><span class="seoSummary">Создание, изменение и удаление закладок.</span></p> + +<h2 id="Usage">Usage</h2> + +<p>Этот модуль экспортирует:</p> + +<ul> + <li>три конструктора: <a href="/en-US/Add-ons/SDK/Low-Level_APIs/places_bookmarks#Bookmark(options)">Bookmark</a>, <a href="/en-US/Add-ons/SDK/Low-Level_APIs/places_bookmarks#Group(options)">Group</a>, and <a href="/en-US/Add-ons/SDK/Low-Level_APIs/places_bookmarks#Separator(options)">Separator</a>, corresponding to the types of objects, referred to as <strong>bookmark items</strong>, in the Bookmarks database in Firefox</li> + <li>две дополнительные функции, <a href="/en-US/Add-ons/SDK/Low-Level_APIs/places_bookmarks#save(bookmarkItems.2C_options)"><code>save()</code></a> для создания, обновения и удаления закладок, и <a href="/en-US/Add-ons/SDK/Low-Level_APIs/places_bookmarks#search(queries.2C_options)"><code>search()</code></a> для получения закладок соответствующих параметрам запроса.</li> +</ul> + +<p><code>save()</code> и <code>search()</code> асинхронные функции: they synchronously return a <a href="/en-US/Add-ons/SDK/Low-Level_APIs/places_bookmarks#PlacesEmitter"><code>PlacesEmitter</code></a> object, which then asynchronously emits events as the operation progresses and completes.</p> + +<p>Each retrieved bookmark item represents only a snapshot of state at a specific time. The module does not automatically sync up a <code>Bookmark</code> instance with ongoing changes to that item in the database from the same add-on, other add-ons, or the user.</p> + +<h3 id="Примеры">Примеры</h3> + +<h4 id="Создание_новой_закладки">Создание новой закладки</h4> + +<pre class="brush: js">let { Bookmark, save } = require("sdk/places/bookmarks"); + +// Create a new bookmark instance, unsaved +let bookmark = Bookmark({ title: "Mozilla", url: "http://mozilla.org" }); + +// Attempt to save the bookmark instance to the Bookmarks database +// and store the emitter +let emitter = save(bookmark); + +// Listen for events +emitter.on("data", function (saved, inputItem) { + // on a "data" event, an item has been updated, passing in the + // latest snapshot from the server as `saved` (with properties + // such as `updated` and `id`), as well as the initial input + // item as `inputItem` + console.log(saved.title === inputItem.title); // true + console.log(saved !== inputItem); // true + console.log(inputItem === bookmark); // true +}).on("end", function (savedItems, inputItems) { + // Similar to "data" events, except "end" is an aggregate of + // all progress events, with ordered arrays as `savedItems` + // and `inputItems` +});</pre> + +<h4 id="Создание_нескольких_закладок_в_группе">Создание нескольких закладок в группе</h4> + +<pre class="brush: js">let { Bookmark, Group, save } = require("sdk/places/bookmarks"); + +let group = Group({ title: "Guitars" }); +let bookmarks = [ + Bookmark({ title: "Ran", url: "http://ranguitars.com", group: group }), + Bookmark({ title: "Ibanez", url: "http://ibanez.com", group: group }), + Bookmark({ title: "ESP", url: "http://espguitars.com", group: group }) +]; + +// Save `bookmarks` array -- notice we don't have `group` in the array, +// although it needs to be saved since all bookmarks are children +// of `group`. This will be saved implicitly. + +save(bookmarks).on("data", function (saved, input) { + // A data event is called once for each item saved, as well + // as implicit items, like `group` + console.log(input === group || ~bookmarks.indexOf(input)); // true +}).on("end", function (saves, inputs) { + // like the previous example, the "end" event returns an + // array of all of our updated saves. Only explicitly saved + // items are returned in this array -- the `group` won't be + // present here. + console.log(saves[0].title); // "Ran" + console.log(saves[2].group.title); // "Guitars" +});</pre> + +<h4 id="Поиск_закладок">Поиск закладок</h4> + +<p>Bookmarks can be queried with the <a href="/en-US/Add-ons/SDK/Low-Level_APIs/places_bookmarks#search(queries.2C_options)"><code>search()</code></a> function, which accepts a query object or an array of query objects, as well as a query options object. Query properties are AND'd together within a single query object, but are OR'd together across multiple query objects.</p> + +<pre class="brush: js">let { search, UNSORTED } = require("sdk/places/bookmarks"); + +// Simple query with one object +search( + { query: "firefox" }, + { sort: "title" } +).on(end, function (results) { + // results matching any bookmark that has "firefox" + // in its URL, title or tag, sorted by title +}); + +// Multiple queries are OR'd together +search( + [{ query: "firefox" }, { group: UNSORTED, tags: ["mozilla"] }], + { sort: "title" } +).on("end", function (results) { + // Our first query is the same as the simple query above; + // all of those results are also returned here. Since multiple + // queries are OR'd together, we also get bookmarks that + // match the second query. The second query's properties + // are AND'd together, so results that are in the platform's unsorted + // bookmarks folder, AND are also tagged with 'mozilla', get returned + // as well in this query +});</pre> + +<h2 id="Globals">Globals</h2> + +<h3 id="Constructors">Constructors</h3> + +<h4 class="addon-sdk-api-name" id="Bookmark(options)"><code>Bookmark(options)</code></h4> + +<p>Creates an unsaved bookmark instance.</p> + +<h5 id="Parameters">Parameters</h5> + +<p><strong>options : object</strong><br> + Required options:</p> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Name</th> + <th scope="col">Type</th> + <th scope="col"> </th> + </tr> + </thead> + <tbody> + <tr> + <td>title</td> + <td>string</td> + <td> + <p>The title for the bookmark. Required.</p> + </td> + </tr> + <tr> + <td>url</td> + <td>string</td> + <td> + <p>The URL for the bookmark. Required.</p> + </td> + </tr> + </tbody> +</table> + +<p>Optional options:</p> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Name</th> + <th scope="col">Type</th> + <th scope="col"> </th> + </tr> + </thead> + <tbody> + <tr> + <td>group</td> + <td>Group</td> + <td> + <p>The parent group that the bookmark lives under. Defaults to the <a href="/en-US/Add-ons/SDK/Low-Level_APIs/places_bookmarks#UNSORTED">Bookmarks.UNSORTED</a> group.</p> + </td> + </tr> + <tr> + <td>index</td> + <td>number</td> + <td> + <p>The index of the bookmark within its group. Last item within the group by default.</p> + </td> + </tr> + <tr> + <td>tags</td> + <td>set</td> + <td> + <p>A set of tags to be applied to the bookmark.</p> + </td> + </tr> + </tbody> +</table> + +<h4 class="addon-sdk-api-name" id="Group(options)"><code>Group(options)</code></h4> + +<p>Creates an unsaved bookmark group instance.</p> + +<h5 id="Parameters_2">Parameters</h5> + +<p><strong>options : object</strong><br> + Required options:</p> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Name</th> + <th scope="col">Type</th> + <th scope="col"> </th> + </tr> + </thead> + <tbody> + <tr> + <td>title</td> + <td>string</td> + <td> + <p>The title for the group. Required.</p> + </td> + </tr> + </tbody> +</table> + +<p>Optional options:</p> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Name</th> + <th scope="col">Type</th> + <th scope="col"> </th> + </tr> + </thead> + <tbody> + <tr> + <td>group</td> + <td>Group</td> + <td> + <p>The parent group that the bookmark group lives under. Defaults to the <a href="/en-US/Add-ons/SDK/Low-Level_APIs/places_bookmarks#UNSORTED">Bookmarks.UNSORTED</a> group.</p> + </td> + </tr> + <tr> + <td>index</td> + <td>number</td> + <td> + <p>The index of the bookmark group within its parent group. Last item within the group by default.</p> + </td> + </tr> + </tbody> +</table> + +<h4 class="addon-sdk-api-name" id="Separator(options)"><code>Separator(options)</code></h4> + +<p>Creates an unsaved bookmark separator instance.</p> + +<h5 id="Parameters_3">Parameters</h5> + +<p><strong>options : object</strong><br> + Optional options:</p> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Name</th> + <th scope="col">Type</th> + <th scope="col"> </th> + </tr> + </thead> + <tbody> + <tr> + <td>group</td> + <td>Group</td> + <td> + <p>The parent group that the bookmark group lives under. Defaults to the <a href="/en-US/Add-ons/SDK/Low-Level_APIs/places_bookmarks#UNSORTED">Bookmarks.UNSORTED</a> group.</p> + </td> + </tr> + <tr> + <td>index</td> + <td>number</td> + <td> + <p>The index of the bookmark group within its parent group. Last item within the group by default.</p> + </td> + </tr> + </tbody> +</table> + +<h3 id="Functions">Functions</h3> + +<h4 class="addon-sdk-api-name" id="save(bookmarkItems_options)"><code>save(bookmarkItems, options)</code></h4> + +<p>Creating, saving, and deleting bookmarks are all done with the <code>save()</code> function. This function takes in any of:</p> + +<ul> + <li>a bookmark item (Bookmark, Group, Separator)</li> + <li>a duck-typed object (the relative properties for a bookmark item, in addition to a <code>type</code> property of <code>'bookmark'</code>, <code>'group'</code>, or <code>'separator'</code>)</li> + <li>an array of bookmark items.</li> +</ul> + +<p>All of the items passed in are pushed to the platform and are either created, updated or deleted.</p> + +<ul> + <li>adding items: if passing in freshly instantiated bookmark items or a duck-typed object, the item is created on the platform.</li> + <li>updating items: for an item referenced from a previous <code>save()</code> or from the result of a <code>search()</code> query, changing the properties and calling <code>save()</code> will update the item on the server.</li> + <li>deleting items: to delete a bookmark item, pass in a bookmark item with a property <code>remove</code> set to <code>true</code>.</li> +</ul> + +<p>The function returns a <a href="/en-US/Add-ons/SDK/Low-Level_APIs/places_bookmarks#PlacesEmitter"><code>PlacesEmitter</code></a> that emits a <code>data</code> event for each item as it is saved, and an <code>end</code> event when all items have been saved.</p> + +<pre class="brush: js">let { Bookmark, Group } = require("sdk/places/bookmarks"); + +let myGroup = Group({ title: "My Group" }); +let myBookmark = Bookmark({ + title: "Moz", + url: "http://mozilla.com", + group: myGroup +}); + +save(myBookmark).on("data", function (item, inputItem) { + // The `data` event returns the latest snapshot from the + // host, so this is a new instance of the bookmark item, + // where `item !== myBookmark`. To match it with the input item, + // use the second argument, so `inputItem === myBookmark` + + // All explicitly saved items have data events called, as + // well as implicitly saved items. In this case, + // `myGroup` has to be saved before `myBookmark`, since + // `myBookmark` is a child of `myGroup`. `myGroup` will + // also have a `data` event called for it. +}).on("end", function (items, inputItems) { + // The `end` event returns all items that are explicitly + // saved. So `myGroup` will not be in this array, + // but `myBookmark` will be. + // `inputItems` matches the initial input as an array, + // so `inputItems[0] === myBookmark` +}); + +// Saving multiple bookmarks, as duck-types in this case + +let bookmarks = [ + { title: "mozilla", url: "http://mozilla.org", type: "bookmark" }, + { title: "firefox", url: "http://firefox.com", type: "bookmark" }, + { title: "twitter", url: "http://twitter.com", type: "bookmark" } +]; + +save(bookmarks).on("data", function (item, inputItem) { + // Each item in `bookmarks` has its own `data` event +}).on("end", function (results, inputResults) { + // `results` is an array of items saved in the same order + // as they were passed in. +});</pre> + +<h5 id="Parameters_4">Parameters</h5> + +<p><strong>bookmarkItems : bookmark|group|separator|array</strong><br> + A bookmark item (<a href="/en-US/Add-ons/SDK/Low-Level_APIs/places_bookmarks#Bookmark">Bookmark</a>, <a href="/en-US/Add-ons/SDK/Low-Level_APIs/places_bookmarks#Group">Group</a>, <a href="/en-US/Add-ons/SDK/Low-Level_APIs/places_bookmarks#Separator">Separator</a>), or an array of bookmark items to be saved.</p> + +<p><strong>options : object</strong><br> + Optional options:</p> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Name</th> + <th scope="col">Type</th> + <th scope="col"> </th> + </tr> + </thead> + <tbody> + <tr> + <td>resolve</td> + <td>function</td> + <td> + <p>A resolution function that is invoked during an attempt to save a bookmark item that is not derived from the latest state from the platform. Invoked with two arguments, <code>mine</code> and <code>platform</code>, where <code>mine</code> is the item that is being saved, and <code>platform</code> is the current state of the item on the item. The object returned from this function is what is saved on the platform. By default, all changes on an outdated bookmark item overwrite the platform's bookmark item.</p> + </td> + </tr> + </tbody> +</table> + +<h5 id="Returns">Returns</h5> + +<p><strong>PlacesEmitter</strong> : Returns a <a href="/en-US/Add-ons/SDK/Low-Level_APIs/places_bookmarks#PlacesEmitter">PlacesEmitter</a>.</p> + +<h4 class="addon-sdk-api-name" id="remove(items)"><code>remove(items)</code></h4> + +<p>A helper function that takes in a bookmark item, or an <code>Array</code> of several bookmark items, and sets each item's <code>remove</code> property to true. This does not remove the bookmark item from the database: it must be subsequently saved.</p> + +<pre class="brush: js">let { search, save, remove } = require("sdk/places/bookmarks"); + +search({ tags: ["php"] }).on("end", function (results) { + // The search returns us all bookmark items that are + // tagged with `"php"`. + + // We then pass `results` into the remove function to mark + // all items to be removed, which returns the new modified `Array` + // of items, which is passed into save. + save(remove(results)).on("end", function (results) { + // items tagged with `"php"` are now removed! + }); +})</pre> + +<h5 id="Parameters_5">Parameters</h5> + +<p><strong>items : Bookmark|Group|Separator|array</strong><br> + A bookmark item, or <code>Array</code> of bookmark items to be transformed to set their <code>remove</code> property to <code>true</code>.</p> + +<h5 id="Returns_2">Returns</h5> + +<p><strong>array</strong> : An array of the transformed bookmark items.</p> + +<h4 class="addon-sdk-api-name" id="search(queries_options)"><code>search(queries, options)</code></h4> + +<p>Queries can be performed on bookmark items by passing in one or more query objects, each of which is given one or more properties.</p> + +<p>Within each query object, the properties are AND'd together: so only objects matching all properties are retrieved. Across query objects, the results are OR'd together, meaning that if an item matches any of the query objects, it will be retrieved.</p> + +<p>For example, suppose we called <code>search()</code> with two query objects:</p> + +<pre class="brush: js">[{ url: "mozilla.org", tags: ["mobile"]}, +{ tags: ["firefox-os"]}]</pre> + +<p>This will return:</p> + +<ul> + <li>all bookmark items from mozilla.org that are also tagged "mobile"</li> + <li>all bookmark items that are tagged "firefox-os"</li> +</ul> + +<p>An <code>options</code> object may be used to determine overall settings such as sort order and how many objects should be returned.</p> + +<h5 id="Parameters_6">Parameters</h5> + +<p><strong>queries : object|array</strong><br> + An <code>Object</code> representing a query, or an <code>Array</code> of <code>Objects</code> representing queries. Each query object can take several properties, which are queried against the bookmarks database. Each property is AND'd together, meaning that bookmarks must match each property within a query object. Multiple query objects are then OR'd together.</p> + +<p><strong>options : object</strong><br> + Optional options:</p> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Name</th> + <th scope="col">Type</th> + <th scope="col"> </th> + </tr> + </thead> + <tbody> + <tr> + <td>count</td> + <td>number</td> + <td> + <p>The number of bookmark items to return. If left undefined, no limit is set.</p> + </td> + </tr> + <tr> + <td>sort</td> + <td>string</td> + <td> + <p>A string specifying how the results should be sorted. Possible options are <code>'title'</code>, <code>'date'</code>, <code>'url'</code>, <code>'visitCount'</code>, <code>'dateAdded'</code> and <code>'lastModified'</code>.</p> + </td> + </tr> + <tr> + <td>descending</td> + <td>boolean</td> + <td> + <p>A boolean specifying whether the results should be in descending order. By default, results are in ascending order.</p> + </td> + </tr> + </tbody> +</table> + +<h3 id="Properties">Properties</h3> + +<h4 class="addon-sdk-api-name" id="MENU"><code>MENU</code></h4> + +<p>This is a constant, default <a href="/en-US/Add-ons/SDK/Low-Level_APIs/places_bookmarks#Group"><code>Group</code></a> on the Firefox platform, the <strong>Bookmarks Menu</strong>. It can be used in queries or specifying the parent of a bookmark item, but it cannot be modified.</p> + +<h4 class="addon-sdk-api-name" id="TOOLBAR"><code>TOOLBAR</code></h4> + +<p>This is a constant, default <a href="/en-US/Add-ons/SDK/Low-Level_APIs/places_bookmarks#Group"><code>Group</code></a> on the Firefox platform, the <strong>Bookmarks Toolbar</strong>. It can be used in queries or specifying the parent of a bookmark item, but it cannot be modified.</p> + +<h4 class="addon-sdk-api-name" id="UNSORTED"><code>UNSORTED</code></h4> + +<p>This is a constant, default <a href="/en-US/Add-ons/SDK/Low-Level_APIs/places_bookmarks#Group"><code>Group</code></a> on the Firefox platform, the <strong>Unsorted Bookmarks</strong> group. It can be used in queries or specifying the parent of a bookmark item, but it cannot be modified.</p> + +<h2 id="Bookmark">Bookmark</h2> + +<h3 id="Properties_2">Properties</h3> + +<h4 class="addon-sdk-api-name" id="title"><code>title</code></h4> + +<p>The bookmark's title.</p> + +<h4 class="addon-sdk-api-name" id="url"><code>url</code></h4> + +<p>The bookmark's URL.</p> + +<h4 class="addon-sdk-api-name" id="group"><code>group</code></h4> + +<p>The group instance that the bookmark lives under.</p> + +<h4 class="addon-sdk-api-name" id="index"><code>index</code></h4> + +<p>The index of the bookmark within its group.</p> + +<h4 class="addon-sdk-api-name" id="updated"><code>updated</code></h4> + +<p>A Unix timestamp indicating when the bookmark was last updated on the platform.</p> + +<h4 class="addon-sdk-api-name" id="tags"><code>tags</code></h4> + +<p>A <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set">Set</a> of tags that the bookmark is tagged with.</p> + +<h2 id="Group">Group</h2> + +<h3 id="Properties_3">Properties</h3> + +<h4 class="addon-sdk-api-name" id="title_2"><code>title</code></h4> + +<p>The bookmark group's title.</p> + +<h4 class="addon-sdk-api-name" id="group_2"><code>group</code></h4> + +<p>The group instance that the bookmark group lives under.</p> + +<h4 class="addon-sdk-api-name" id="index_2"><code>index</code></h4> + +<p>The index of the bookmark group within its group.</p> + +<h4 class="addon-sdk-api-name" id="updated_2"><code>updated</code></h4> + +<p>A Unix timestamp indicating when the bookmark was last updated on the platform.</p> + +<h2 id="Separator">Separator</h2> + +<h3 id="Properties_4">Properties</h3> + +<h4 class="addon-sdk-api-name" id="group_3"><code>group</code></h4> + +<p>The group instance that the bookmark group lives under.</p> + +<h4 class="addon-sdk-api-name" id="index_3"><code>index</code></h4> + +<p>The index of the bookmark group within its group.</p> + +<h4 class="addon-sdk-api-name" id="updated_3"><code>updated</code></h4> + +<p>A Unix timestamp indicating when the bookmark was last updated on the platform.</p> + +<h2 id="PlacesEmitter">PlacesEmitter</h2> + +<p>The <code>PlacesEmitter</code> is not exported from the module, but returned from the <code>save</code> and <code>search</code> functions. The <code>PlacesEmitter</code> inherits from <a href="/en-US/Add-ons/SDK/Low-Level_APIs/event_target"><code>event/target</code></a>, and emits <code>data</code>, <code>error</code>, and <code>end</code>.</p> + +<p><code>data</code> events are emitted for every individual operation (such as: each item saved, or each item found by a search query), whereas <code>end</code> events are emitted as the aggregate of an operation, passing an array of objects into the handler.</p> + +<h3 id="Events">Events</h3> + +<h4 class="addon-sdk-api-name" id="data"><code>data</code></h4> + +<p>The <code>data</code> event is emitted when a bookmark item that was passed into the <code>save</code> method has been saved to the platform. This includes implicit saves that are dependencies of the explicit items saved. For example, when creating a new bookmark group with two bookmark items as its children, and explicitly saving the two bookmark children, the unsaved parent group will also emit a <code>data</code> event.</p> + +<pre class="brush: js">let { Bookmark, Group, save } = require("sdk/places/bookmarks"); + +let group = Group({ title: "my group" }); +let bookmarks = [ + Bookmark({ title: "mozilla", url: "http://mozilla.com", group: group }), + Bookmark({ title: "w3", url: "http://w3.org", group: group }) +]; + +save(bookmarks).on("data", function (item) { + // This function will be called three times: + // once for each bookmark saved + // once for the new group specified implicitly + // as the parent of the two items +});</pre> + +<p>The <code>data</code> event is also called for <code>search</code> requests, with each result being passed individually into its own <code>data</code> event.</p> + +<pre class="brush: js">let { search } = require("sdk/places/bookmarks"); + +search({ query: "firefox" }).on("data", function (item) { + // each bookmark item that matches the query will + // be called in this function +});</pre> + +<h5 id="Arguments">Arguments</h5> + +<p><strong>Bookmark|Group|Separator</strong> : For the <code>save</code> function, this is the saved, latest snapshot of the bookmark item. For <code>search</code>, this is a snapshot of a bookmark returned from the search query.</p> + +<p><strong>Bookmark|Group|Separator|object</strong> : Only in <code>save</code> data events. The initial instance of the item that was used for the save request.</p> + +<h4 class="addon-sdk-api-name" id="error"><code>error</code></h4> + +<p>The <code>error</code> event is emitted whenever a bookmark item's save could not be completed.</p> + +<h5 id="Arguments_2">Arguments</h5> + +<p><strong>string</strong> : A string indicating the error that occurred.</p> + +<p><strong>Bookmark|Group|Separator|object</strong> : Only in <code>save</code> error events. The initial instance of the item that was used for the save request.</p> + +<h4 class="addon-sdk-api-name" id="end"><code>end</code></h4> + +<p>The <code>end</code> event is called when all bookmark items and dependencies have been saved, or an aggregate of all items returned from a search query.</p> + +<h5 id="Arguments_3">Arguments</h5> + +<p><strong>array</strong> : The array is an ordered list of the input bookmark items, replaced with their updated, latest snapshot instances (the first argument in the <code>data</code> handler), or in the case of an error, the initial instance of the item that was used for the save request (the second argument in the <code>data</code> or <code>error</code> handler).</p> diff --git a/files/ru/mozilla/add-ons/sdk/tools/console/index.html b/files/ru/mozilla/add-ons/sdk/tools/console/index.html new file mode 100644 index 0000000000..d28b31d127 --- /dev/null +++ b/files/ru/mozilla/add-ons/sdk/tools/console/index.html @@ -0,0 +1,110 @@ +--- +title: console +slug: Mozilla/Add-ons/SDK/Tools/console +translation_of: Archive/Add-ons/Add-on_SDK/Tools/console +--- +<p><span class="seoSummary">Enables your add-on to log error, warning or informational messages.</span> If you have started Firefox for your add-on from the command line with <code>cfx run</code> or <code>cfx test</code> then these messages appear in the command shell you used. If the add-on has been installed in Firefox, then the messages appear in the <a href="/en-US/docs/Tools/Browser_Console">Browser Console</a>.</p> +<p>If you're developing your add-on using the <a href="https://addons.mozilla.org/en-US/firefox/addon/autoinstaller/">Extension Auto-installer</a>, then the add-on is installed in Firefox, meaning that messages will appear in the Browser Console. But see the discussion of <a href="/en-US/Add-ons/SDK/Tools/console#Logging_Levels">logging levels</a>: by default, messages logged using <code>log()</code>, <code>info()</code>, <code>trace()</code>, or <code>warn()</code> won't be logged in these situations.</p> +<h2 id="Console_Methods">Console Methods</h2> +<p>All console methods except <code>exception()</code> and <code>trace()</code> accept one or more JavaScript objects as arguments and log them to the console. Depending on the console's underlying implementation and user interface, you may be able to examine the properties of non-primitive objects that are logged.</p> +<h3 id="console.debug(object_object_...)"><code>console.debug(<em>object</em>[, <em>object</em>, ...])</code></h3> +<p>Logs the arguments to the console, preceded by "debug:" and the name of your add-on:</p> +<pre class="brush: js">console.debug("This is a debug message");</pre> +<pre>debug: my-addon: This is a debug message +</pre> +<h3 id="console.error(object_object_...)"><code>console.error(<em>object</em>[, <em>object</em>, ...])</code></h3> +<p>Logs the arguments to the console, preceded by "error:" and the name of your add-on:<code> </code></p> +<pre class="brush: js">console.error("This is an error message");</pre> +<pre>error: my-addon: This is an error message +</pre> +<h3 id="console.exception(exception)"><code>console.exception(<em>exception</em>)</code></h3> +<p>Logs the given exception instance as an error, outputting information about the exception's stack traceback if one is available.</p> +<pre class="brush: js">try { + doThing(); +} catch (e) { + console.exception(e); +} + +function UserException(message) { + this.message = message; + this.name = "UserException"; +} + +function doThing() { + throw new UserException("Thing could not be done!"); +}</pre> +<pre>error: my-addon: An exception occurred. +UserException: Thing could not be done! +</pre> +<h3 id="console.info(object_object_...)"><code>console.info(<em>object</em>[, <em>object</em>, ...])</code></h3> +<p>A synonym for <code>console.log()</code>.</p> +<h3 id="console.log(object_object_...)"><code>console.log(<em>object</em>[, <em>object</em>, ...])</code></h3> +<p>Logs the arguments to the console, preceded by "info:" and the name of your add-on:</p> +<pre class="brush: js">console.log("This is an informational message");</pre> +<pre>info: my-addon: This is an informational message +</pre> +<h3 id="console.time(name)"><code>console.time(name)</code></h3> +<p>Starts a timer with a name specified as an input parameter. Up to 10,000 simultaneous timers can run on a given page.</p> +<h3 id="console.timeEnd(name)"><code>console.timeEnd(name)</code></h3> +<p>Stops the specified timer and logs the elapsed time in seconds since its start. See <a href="https://developer.mozilla.org/en-US/docs/Web/API/console#Timers">Timers</a>.</p> +<h3 id="console.trace()"><code>console.trace()</code></h3> +<p>Logs a stack trace at the point the function is called.</p> +<h3 id="console.warn(object_object_...)"><code>console.warn(<em>object</em>[, <em>object</em>, ...])</code></h3> +<p>Logs the arguments to the console, preceded by "warn:" and the name of your add-on:<code> </code></p> +<pre class="brush: js"><code>console.warn("This is a warning message");</code></pre> +<pre>warn: my-addon: This is a warning message +</pre> +<h2 id="Logging_Levels">Logging Levels</h2> +<p>Logging's useful, of course, especially during development. But the more logging there is, the more noise you see in the console output. Especially when debug logging shows up in a production environment, the noise can make it harder, not easier, to debug issues.</p> +<p>This is the problem that logging levels are designed to fix. The console defines a number of logging levels, from "more verbose" to "less verbose", and a number of different logging functions that correspond to these levels, which are arranged in order of "severity" from informational messages, through warnings, to errors.</p> +<p>At a given logging level, only calls to the corresponding functions and functions with a higher severity will have any effect.</p> +<p>For example, if the logging level is set to "info", then calls to <code>info()</code>, <code>log()</code>, <code>warn()</code>, and <code>error()</code> will all result in output being written. But if the logging level is "warn" then only calls to <code>warn()</code> and <code>error()</code> have any effect, and calls to <code>info()</code> and <code>log()</code> are simply discarded.</p> +<p>This means that the same code can be more verbose in a development environment than in a production environment - you just need to arrange for the appropriate logging level to be set.</p> +<p>The complete set of logging levels is given in the table below, along with the set of functions that will result in output at each level:</p> +<table class="standard-table"> + <tbody> + <tr> + <th>Level</th> + <th>Will log calls to:</th> + </tr> + <tr> + <td>all</td> + <td>Any console method</td> + </tr> + <tr> + <td>debug</td> + <td><code>debug(), error(), exception(), info(), log(), time(), timeEnd(), trace(), warn()</code></td> + </tr> + <tr> + <td>info</td> + <td><code>error(), exception(), info(), log(), time(), timeEnd(), trace(), warn()</code></td> + </tr> + <tr> + <td>warn</td> + <td><code>error(), exception(), warn()</code></td> + </tr> + <tr> + <td>error</td> + <td><code>error(), exception()</code></td> + </tr> + <tr> + <td>off</td> + <td>Nothing</td> + </tr> + </tbody> +</table> +<h3 id="Setting_the_Logging_Level">Setting the Logging Level</h3> +<p>The logging level defaults to "error".</p> +<p>There are two system preferences that can be used to override this default:</p> +<ul> + <li> + <p><strong>extensions.sdk.console.logLevel</strong>: if set, this determines the logging level for all installed SDK-based add-ons.</p> + </li> + <li> + <p><strong>extensions.</strong><em>extensionID</em><strong>.sdk.console.logLevel</strong>, where <em>extensionID</em> is an add-on's <a href="/en-US/Add-ons/SDK/Guides/Program_ID">Program ID</a>. If set, this determines the logging level for the specified add-on. This overrides the global preference if both preferences are set.</p> + </li> +</ul> +<p>Both these preferences can be set programmatically using the <a href="/en-US/Add-ons/SDK/Low-Level_APIs/preferences_service"><code>preferences/service</code></a> API, or manually using <a href="http://kb.mozillazine.org/About:config">about:config</a>. The value for each preference is the desired logging level, given as a string.</p> +<p>When you run your add-on using <code>cfx run</code> or <code>cfx test</code>, the global <strong>extensions.sdk.console.logLevel</strong> preference is automatically set to "info". This means that calls to <code>console.log()</code> will appear in the console output.</p> +<p>When you install an add-on into Firefox, the logging level will be "error" by default (that is, unless you have set one of the two preferences). This means that messages written using <code>debug()</code>, <code>log()</code>, <code>info()</code>, <code>trace()</code>, and <code>warn()</code> will not appear in the console.</p> +<p>This includes add-ons being developed using the <a href="https://addons.mozilla.org/en-US/firefox/addon/autoinstaller/">Extension Auto-installer</a>.</p> diff --git a/files/ru/mozilla/add-ons/sdk/tools/index.html b/files/ru/mozilla/add-ons/sdk/tools/index.html new file mode 100644 index 0000000000..b55c672f17 --- /dev/null +++ b/files/ru/mozilla/add-ons/sdk/tools/index.html @@ -0,0 +1,10 @@ +--- +title: Tools +slug: Mozilla/Add-ons/SDK/Tools +tags: + - NeedsTranslation + - TopicStub +translation_of: Archive/Add-ons/Add-on_SDK/Tools +--- +<p>Articles listed here provide a reference for the SDK's tools:</p> +<p>{{ LandingPageListSubpages ("/en-US/Add-ons/SDK/Tools", 5) }}</p> diff --git a/files/ru/mozilla/add-ons/sdk/tools/jpm/index.html b/files/ru/mozilla/add-ons/sdk/tools/jpm/index.html new file mode 100644 index 0000000000..dbfacde500 --- /dev/null +++ b/files/ru/mozilla/add-ons/sdk/tools/jpm/index.html @@ -0,0 +1,497 @@ +--- +title: jpm +slug: Mozilla/Add-ons/SDK/Tools/jpm +translation_of: Archive/Add-ons/Add-on_SDK/Tools/jpm +--- +<div class="note"> +<p>Вы можете использовать <code>jpm</code> для Firefox 38 или более поздних версий.</p> + +<p>Данный материал относится только для jpm.</p> +</div> + +<p><span class="seoSummary">Это Node-ориентированная замена устаревшего <a href="/en-US/Add-ons/SDK/Tools/cfx">cfx</a>. Позволяет тестировать, запускать и создавать дополнения для Firefox.</span></p> + +<p>Смотри также <a href="/en-US/Add-ons/SDK/Tutorials/Getting_Started_%28jpm%29">jpm tutorial</a>.</p> + +<p>jpm вызывается через:</p> + +<pre class="brush: bash">jpm [command] [options] +</pre> + +<p>jpm поддерживает следующие глобальные опции:</p> + +<pre class="brush: bash">-h, --help - show a help message and exit +-V, --version - print the jpm version number +</pre> + +<h2 id="Установка">Установка</h2> + +<p>jpm распространяется с помощью менеджера пакетов <a class="external external-icon" href="https://www.npmjs.org/package/jpm">npm</a>, поэтому чтобы установить jpm, вам необходимо предварительно установить менеджер пакетов npm, если вы этого ещё не сделали. npm входит в Node.js, поэтому чтобы установить npm - посетите <a class="external external-icon" href="http://nodejs.org/">nodejs.org</a> и нажмите кнопку INSTALL.</p> + +<p>После этого вы можете установить jpm, как и любой другой npm пакет:</p> + +<pre>npm install jpm -g</pre> + +<p>В зависимости от настроек и операционной системы, вам может потребоваться запустить его с правами администратора (Linux: Debian, Ubuntu, и т.п.):</p> + +<pre class="brush: bash">sudo npm install jpm -g</pre> + +<p>После установки введите в командной строке:</p> + +<pre class="brush: bash">jpm</pre> + +<p>Вы должны увидеть краткое описание доступных команд. Обратите внимание, что в отличие от cfx, jpm доступно из любой запущенной командной строки, в случае, если при установке jpm использовался флаг -g.</p> + +<h3 id="Проблемы">Проблемы?</h3> + +<p>Если у вас возникли проблемы, то обратитесь за помощью. Пользователи SDK и участники проекта готовы обсудить и предложения в <a class="external external-icon" href="http://groups.google.com/group/mozilla-labs-jetpack/topics">project mailing list</a>. Попробуйте поискать там, возможно похожий вопрос уже обсуждался там. Вы также можете обратиться к пользователям SDK в <a class="external external-icon" href="http://mibbit.com/?channel=%23jetpack&server=irc.mozilla.org">#jetpack</a> на <a class="external external-icon" href="http://irc.mozilla.org/">Mozilla's IRC network</a>.</p> + +<h2 id="Справочник_команд">Справочник команд</h2> + +<p>В jpm доступно шесть команд:</p> + +<table class="fullwidth-table standard-table"> + <tbody> + <tr> + <td style="width: 20%;"><a href="/en-US/Add-ons/SDK/Tools/jpm#jpm_init"><code>jpm init</code></a></td> + <td>Создать каркас дополнения в качестве отправной точки для создания вашего дополнения.</td> + </tr> + <tr> + <td><a href="/en-US/Add-ons/SDK/Tools/jpm#jpm_run"><code>jpm run</code></a></td> + <td>Запустить копию Firefox с установленным дополнением.</td> + </tr> + <tr> + <td><a href="/en-US/Add-ons/SDK/Tools/jpm#jpm_test"><code>jpm test</code></a></td> + <td>Запуск тестирования модуля вашего дополнения.</td> + </tr> + <tr> + <td><a href="/en-US/Add-ons/SDK/Tools/jpm#jpm_xpi"><code>jpm xpi</code></a></td> + <td>Упаковать дополнение в <a href="https://developer.mozilla.org/en/XPI">XPI</a> пакет, формат файла установки для дополнений Firefox.</td> + </tr> + <tr> + <td><a href="/en-US/Add-ons/SDK/Tools/jpm#jpm_post"><code>jpm post</code></a></td> + <td>Упаковать дополнение в пакет <a href="https://developer.mozilla.org/en/XPI">XPI</a> и отправить на URL.</td> + </tr> + <tr> + <td><a href="/en-US/Add-ons/SDK/Tools/jpm#jpm_watchpost"><code>jpm watchpost</code></a></td> + <td>Упаковывать дополнение в пакет <a href="https://developer.mozilla.org/en/XPI">XPI</a> и отправлять на URL при каждом изменении файла.</td> + </tr> + </tbody> +</table> + +<h3 id="jpm_init">jpm init</h3> + +<p>Данная команда инициализирует новое дополнение, с нуля.</p> + +<p>Для этого создайте новый каталог, перейдите в него и запустите <code>jpm init</code>.</p> + +<pre class="brush: bash">mkdir my-addon +cd my-addon +jpm init</pre> + +<p>Вам будет предложено указать некоторую информацию о вашем дополнении: данная информация будет использована для создания файла настроек дополнения <a href="https://developer.mozilla.org/en-US/Add-ons/SDK/Tools/package_json">package.json</a>.</p> + +<ul> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/SDK/Tools/package_json#title">title</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/SDK/Tools/package_json#name">name</a>: По умолчанию это имя каталога, в котором была запущена команда jpm init. За исключнием случаев, когда заполненно поле <a href="https://developer.mozilla.org/en-US/Add-ons/SDK/Tools/package_json#id"><code>id</code></a> в файле package.json, тогда jpm добавит указатель "@" перед именем и использует в качестве него значение поля <a href="https://developer.mozilla.org/en-US/Add-ons/Install_Manifests#id"><code>id</code> field in the add-on's install manifest</a>.</li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/SDK/Tools/package_json#version">version</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/SDK/Tools/package_json#description">description</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/SDK/Tools/package_json#main">entry point</a> (which maps to "main" in package.json)</li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/SDK/Tools/package_json#author">author</a></li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/SDK/Tools/package_json#engines">engines</a> (supported applications)</li> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/SDK/Tools/package_json#license">license</a></li> +</ul> + +<p>Большинство из этих полей имеют значения по умолчанию, который указан в скобках после вопроса. Если вы просто нажмите Enter, то в настройках будет указано значение по умолчанию.</p> + +<p>После того как вы укажете значения или выберите значение по умолчанию для этих свойств, вам будет показано полное содержание "package.json" и предложено принять его.</p> + +<p>После jpm создаст каркас дополнения в качестве отправной точки для разрабатываемого вами дополнения, со следующей структурой файлов:</p> + +<ul class="directory-tree"> + <li>my-addon + <ul> + <li>index.js</li> + <li>package.json</li> + <li>test + <ul> + <li>test-index.js</li> + </ul> + </li> + </ul> + </li> +</ul> + +<h3 id="jpm_run">jpm run</h3> + +<p>Эта команда запускает новый экземпляр Firefox с подключенным дополнением:</p> + +<pre class="brush: bash">jpm run</pre> + +<p><code>jpm run</code> принимает следующие значения:</p> + +<table class="fullwidth-table standard-table"> + <tbody> + <tr> + <td style="width: 30%;"><code>-b --binary BINARY</code></td> + <td> + <p>Use the version of Firefox specified in BINARY. BINARY may be specified as a full path or as a path relative to the current directory.</p> + + <pre class="brush: bash"> +jpm run -b /path/to/Firefox/Nightly</pre> + See <a href="/en-US/Add-ons/SDK/Tools/jpm#Selecting_a_browser_version">Selecting a browser version</a>.</td> + </tr> + <tr> + <td><code>--binary-args CMDARGS</code></td> + <td> + <p>Pass <a href="/en-US/docs/Mozilla/Command_Line_Options">extra arguments</a> to Firefox.</p> + + <p>For example, to pass the <code>-jsconsole</code> argument to Firefox, which will launch the <a href="/en-US/docs/Tools/Browser_Console">Browser Console</a>, try the following:</p> + + <pre class="brush: bash"> +jpm run --binary-args -jsconsole</pre> + + <p>To pass multiple arguments, or arguments containing spaces, quote them:</p> + + <pre class="brush: bash"> +jpm run --binary-args '-url mzl.la -jsconsole'</pre> + </td> + </tr> + <tr> + <td><code>--debug</code></td> + <td>Run the <a href="/en-US/Add-ons/Add-on_Debugger">add-on debugger</a> attached to the add-on.</td> + </tr> + <tr> + <td><code>-o --overload PATH</code></td> + <td> + <p>Rather than use the SDK modules built into Firefox, use the modules found at PATH. If <code>-o</code> is specified and PATH is omitted, jpm will look for the JETPACK_ROOT environment variable and use its value as the path.</p> + + <p>See <a href="/en-US/Add-ons/SDK/Tools/jpm#Overloading_the_built-in_modules">Overloading the built-in modules</a> for more information.</p> + </td> + </tr> + <tr> + <td><code>-p --profile=<code> PROFILE</code></code></td> + <td> + <p>By default, jpm uses a clean temporary Firefox <a href="http://support.mozilla.com/en-US/kb/profiles">profile</a> each time you call jpm run. Use the <code>--profile</code> option to instruct jpm to launch Firefox with an existing profile.</p> + + <p>The PROFILE value may be a profile name or the path to the profile.</p> + + <p>See <a href="/en-US/Add-ons/SDK/Tools/jpm#Using_profiles">Using profiles</a> for more information.</p> + </td> + </tr> + <tr> + <td><code>-v --verbose</code></td> + <td>Verbose operation.</td> + </tr> + <tr> + <td><code>--no-copy</code></td> + <td> + <div class="warning">Use with caution because <code>jpm run|test</code> changes many preferences, never use with your main profile.</div> + + <div class="note">This only applies when <code>--profile</code> is used.</div> + Disables the copying of the profile used, which allows one to reuse a profile.</td> + <td> </td> + </tr> + </tbody> +</table> + +<h3 id="jpm_test">jpm test</h3> + +<p>Команда запускает тестирование дополнения. Происходит следующее:</p> + +<ul> + <li>Обзор каталога с именем "test" в корневом каталоге дополнения</li> + <li>Открывается каждый файл, имя которого начинается с "test-" в этом каталоге (обратите внимание на дефис после слова "test" в имени jpm файла - в тест будет включён файл вида "test-myCode.js", но исключены файлы вида "test_myCode.js" или "testMyCode.js"</li> + <li>Вызываются все функции, извлечённые из файла, имя которого начинается с "test"</li> +</ul> + +<pre class="brush: bash">jpm test +</pre> + +<p>See the <a href="https://developer.mozilla.org/en-US/Add-ons/SDK/Tutorials/Unit_testing">tutorial on unit testing</a> and the <a href="https://developer.mozilla.org/en-US/Add-ons/SDK/Low-Level_APIs/test_assert">reference documentation for the <code>assert</code> module</a> for more details on this.</p> + +<p><code>jpm test</code> accepts the following options:</p> + +<table class="fullwidth-table standard-table"> + <tbody> + <tr> + <td><code>-b --binary BINARY</code></td> + <td> + <p>Use the version of Firefox specified in BINARY. BINARY may be specified as a full path or as a path relative to the current directory.</p> + + <pre class="brush: bash"> +jpm test -b /path/to/Firefox/Nightly</pre> + + <p>See <a href="/en-US/Add-ons/SDK/Tools/jpm#Selecting_a_browser_version">Selecting a browser version</a>.</p> + </td> + </tr> + <tr> + <td><code>--binary-args CMDARGS</code></td> + <td> + <p>Pass <a href="http://kb.mozillazine.org/Command_line_arguments">extra arguments</a> to Firefox.</p> + + <p>For example, to pass the <code>-jsconsole</code> argument to Firefox, which will launch the <a href="/en-US/docs/Tools/Browser_Console">Browser Console</a>, try the following:</p> + + <pre class="brush: bash"> +jpm test --binary-args -jsconsole</pre> + + <p>To pass multiple arguments, or arguments containing spaces, quote them:</p> + + <pre class="brush: bash"> +jpm test --binary-args '-url mzl.la -jsconsole'</pre> + </td> + </tr> + <tr> + <td><code>--debug</code></td> + <td>Run the <a href="/en-US/Add-ons/Add-on_Debugger">add-on debugger</a> attached to the add-on.</td> + </tr> + <tr> + <td style="width: 30%;"><code>-f --filter FILE[:TEST]</code></td> + <td> + <p>Only run tests whose filenames match FILE and optionally match TEST, both regexps.</p> + + <pre class="brush: bash"> +jpm test --filter base64:btoa</pre> + + <p>The above command only runs tests in files whose names contain "base64", and in those files only runs tests whose names contain "btoa".</p> + </td> + </tr> + <tr> + <td style="width: 30%;"><code>-o --overload PATH</code></td> + <td> + <p>Rather than use the SDK modules built into Firefox, use the modules found at PATH. If <code>-o</code> is specified and PATH is omitted, jpm will look for the JETPACK_ROOT environment variable and use its value as the path.</p> + + <p>See <a href="/en-US/Add-ons/SDK/Tools/jpm#Overloading_the_built-in_modules">Overloading the built-in modules</a> for more information.</p> + </td> + </tr> + <tr> + <td style="width: 30%;"><code>-p --profile<code> PROFILE</code></code></td> + <td> + <p>By default, jpm uses a clean temporary Firefox <a href="http://support.mozilla.com/en-US/kb/profiles">profile</a> each time you call jpm run. Use the <code>--profile</code> option to instruct jpm to launch Firefox with an existing profile.</p> + + <p>The PROFILE value may be a profile name or the path to the profile.</p> + + <p>See <a href="/en-US/Add-ons/SDK/Tools/jpm#Using_profiles">Using profiles</a> for more information.</p> + </td> + </tr> + <tr> + <td><code>--stop-on-error</code></td> + <td> + <p>By default jpm test keeps running tests even after tests fail. Specify <code>--stop-on-error</code> to stop running tests after the first failure:</p> + + <pre class="brush: bash"> +jpm test --stop-on-error</pre> + </td> + </tr> + <tr> + <td><code>--tbpl</code></td> + <td>Print test output in <a href="https://treeherder.mozilla.org/">Treeherder</a> format</td> + </tr> + <tr> + <td><code>--times NUMBER</code></td> + <td> + <p>Run tests NUMBER of times:</p> + + <pre class="brush: bash"> +jpm test --times 2</pre> + </td> + </tr> + <tr> + <td><code>-v --verbose</code></td> + <td>Verbose operation.</td> + </tr> + <tr> + <td><code>--no-copy</code></td> + <td> + <div class="warning">Use with caution because <code>jpm run|test</code> changes many preferences, never use with your main profile.</div> + + <div class="note">This only applies when <code>--profile</code> is used.</div> + Disables the copying of the profile used, which allows one to reuse a profile.</td> + </tr> + </tbody> +</table> + +<h3 id="jpm_xpi">jpm xpi</h3> + +<p>Эта команда собирает дополнение в пакет XPI. Это формат дополнений, которые можно легко установить Mozilla.</p> + +<pre class="brush: bash">jpm xpi</pre> + +<p>It looks for a file called <code>package.json</code> in the current directory and creates the corresponding XPI file. It ignores any ZIPs or XPIs in the add-on's root, and any test files.</p> + +<p>Once you have built an XPI file you can distribute your add-on by submitting it to <a href="http://addons.mozilla.org">addons.mozilla.org</a>.</p> + +<p><code>jpm xpi</code> accepts the following option:</p> + +<table class="fullwidth-table standard-table"> + <tbody> + <tr> + <td><code>-v --verbose</code></td> + <td> + <p>Verbose operation:</p> + + <pre class="brush: bash"> +jpm xpi -v</pre> + </td> + </tr> + </tbody> +</table> + +<h3 id="jpm_post">jpm post</h3> + +<p>This command packages the add-on as an <a href="https://developer.mozilla.org/en/XPI">XPI</a> file, the posts it to some url.</p> + +<pre class="brush: bash">jpm post</pre> + +<p>It looks for a file called <code>package.json</code> in the current directory and creates a XPI file with which to post to the <code>--post-url</code>.</p> + +<p><code>jpm post</code> accepts the following options:</p> + +<table class="fullwidth-table standard-table"> + <tbody> + <tr> + <td><code>--post-url URL</code></td> + <td> + <p>The url to post the extension to after creating a XPI.</p> + + <pre class="brush: bash"> +jpm post --post-url http://localhost:8888/</pre> + + <p>See <a href="https://www.npmjs.com/package/jpm#using-post-and-watchpost">Using Post and Watchpost</a> for more information.</p> + </td> + </tr> + <tr> + <td><code>-v --verbose</code></td> + <td> + <p>Verbose operation:</p> + + <pre class="brush: bash"> +jpm post --post-url http://localhost:8888/ -v</pre> + </td> + </tr> + </tbody> +</table> + +<h3 id="jpm_watchpost">jpm watchpost</h3> + +<p>This command packages the add-on as an <a href="https://developer.mozilla.org/en/XPI">XPI</a> file, the posts it to some url whenever a file in the current working directory changes.</p> + +<pre class="brush: bash">jpm watchpost</pre> + +<p>Creates a XPI whenever a file in the current working directory changes and posts that to the <code>--post-url</code>.</p> + +<p><code>jpm watchpost</code> accepts the following options:</p> + +<table class="fullwidth-table standard-table"> + <tbody> + <tr> + <td><code>--post-url URL</code></td> + <td> + <p>The url to post the extension to after creating a XPI.</p> + + <pre class="brush: bash"> +jpm watchpost --post-url http://localhost:8888/</pre> + + <p>See <a href="https://www.npmjs.com/package/jpm#using-post-and-watchpost">Using Post and Watchpost</a> for more information.</p> + </td> + </tr> + <tr> + <td><code>-v --verbose</code></td> + <td> + <p>Verbose operation:</p> + + <pre class="brush: bash"> +jpm watchpost --post-url http://localhost:8888/ -v</pre> + </td> + </tr> + </tbody> +</table> + +<h2 id="Techniques">Techniques</h2> + +<h3 id="Selecting_a_browser_version">Selecting a browser version</h3> + +<p>By default, <code>jpm run</code> and <code>jpm test</code> will run the release version of Firefox. You can instruct jpm to use a different version in one of two ways:</p> + +<ul> + <li> + <p>you can use the <code>-b</code> or <code>--binary</code> option to instruct jpm to run a different version of Firefox. You can supply a path to a specific binary:</p> + + <pre class="brush: bash">jpm run -b /path/to/Firefox/Nightly</pre> + + <p>As a shorthand for this, you can pass "nightly", "aurora", "beta", or "firefox" and jpm will look in the default location for these Firefox versions:</p> + + <pre class="brush: bash">jpm run -b nightly</pre> + </li> + <li> + <p>you can set the <code>JPM_FIREFOX_BINARY</code> environment variable with the path to the version of Firefox you want to run. When you invoke <code>jpm run</code> or <code>jpm test</code> without the <code>-b</code> option, jpm will first check <code>JPM_FIREFOX_BINARY</code>, and use this as the path if it is set.</p> + </li> +</ul> + +<h3 id="Using_.jpmignore_to_ignore_files">Using <code>.jpmignore</code> to ignore files</h3> + +<p>Using <code>.jpmignore</code> is similar to using <code>.gitignore</code> with <code>git</code>, <code>.hgignore</code> with Mercurial, or <code>.npmignore</code> with <code>npm</code>. By using this file you can let <code>jpm</code> know which files you would like it to ignore when building a <code>.xpi</code> file with <code>jpm xpi</code>.</p> + +<p>Here is an example:</p> + +<pre class="brush: bash"># Ignore .DS_Store files created by mac +.DS_Store + +# Ignore any zip or xpi files +*.zip +*.xpi +</pre> + +<p>A <code>.jpmignore</code> file with the above contents would ignore all zip files and <code>.DS_Store</code> files from the xpi generated by <code>jpm xpi</code>.</p> + +<h3 id="Using_profiles_2"><a name="Using_profiles">Using profiles</a></h3> + +<p>By default, <code>jpm run</code> uses a new profile each time it is executed. This means that any profile-specific data entered from one run of <code>jpm</code> will not, by default, be available in the next run.</p> + +<p>This includes, for example, any extra add-ons you installed, or your history, or any data stored using the <a href="/en-US/Add-ons/SDK/High-Level_APIs/simple-storage">simple-storage</a> API.</p> + +<p>To make <code>jpm</code> use a specific profile, pass the <code>--profile</code> option, specifying the name of the profile you wish to use, or the path to the profile.</p> + +<pre class="brush: bash">jpm run --profile boogaloo +</pre> + +<pre class="brush: bash">jpm run --profile path/to/boogaloo</pre> + +<p>If you supply <code>--profile</code> but its argument is not the name of or path to an existing profile, jpm will open the <a href="https://support.mozilla.org/en-US/kb/profile-manager-create-and-remove-firefox-profiles">profile manager</a>, enabling you to select and existing profile or create a new one:</p> + +<pre class="brush: bash">jpm run --profile i-dont-exist</pre> + +<h3 id="Developing_without_browser_restarts">Developing without browser restarts</h3> + +<p>Because <code>jpm run</code> restarts the browser each time you invoke it, it can be a little cumbersome if you are making very frequent changes to an add-on. An alternative development model is to use the <a href="https://addons.mozilla.org/en-US/firefox/addon/autoinstaller/" rel="noreferrer">Extension Auto-Installer</a> add-on: this listens for new XPI files on a specified port and installs them automatically. That way you can test new changes without needing to restart the browser:</p> + +<ul> + <li>make a change to your add-on</li> + <li>run <code>jpm post --post-url http://localhost:8888/</code>, to make a xpi and post it.</li> +</ul> + +<p>You could even automate this workflow with a simple script. For example:</p> + +<pre class="brush: bash">jpm watchpost --post-url http://localhost:8888/ +</pre> + +<p>Note that the logging level defined for the console is different when you use this method, compared to the logging level used when an add-on is run using <code>jpm run</code>. This means that if you want to see output from <a href="/en-US/Add-ons/SDK/Tutorials/Logging" rel="noreferrer"><code>console.log()</code></a> messages, you'll have to tweak a setting. See the documentation on <a href="/en-US/Add-ons/SDK/Tools/console#Logging_Levels" rel="noreferrer">logging levels</a> for the details on this.</p> + +<h3 id="Overloading_the_built-in_modules">Overloading the built-in modules</h3> + +<p>The SDK modules you use to implement your add-on are built into Firefox. When you run or package an add-on using <code>jpm run</code> or <code>jpm xpi</code>, the add-on will use the versions of the modules in the version of Firefox that hosts it.</p> + +<p>As an add-on developer, this is usually what you want. But if you're developing the SDK modules themselves, of course, it isn't. In this case you need to:</p> + +<ul> + <li>get a local copy of the SDK modules that you want: this usually means checking out the SDK from its <a href="https://github.com/mozilla/addon-sdk" rel="noreferrer">GitHub repo</a></li> + <li>set the <code>JETPACK_ROOT</code> environment variable to your local copy</li> + <li>pass the <code>-o</code> option to <code>jpm run</code> or <code>jpm xpi</code>:</li> +</ul> + +<pre>jpm run -o +</pre> + +<p>This instructs jpm to use the local copies of the SDK modules, not the ones in Firefox. If you don't want to set the <code>JETPACK_ROOT</code> environment variable, you can pass the location of your copy of the SDK modules along with <code>-o</code>:</p> + +<pre>jpm run -o "/path/to/SDK/"</pre> diff --git a/files/ru/mozilla/add-ons/sdk/tutorials/getting_started_(jpm)/index.html b/files/ru/mozilla/add-ons/sdk/tutorials/getting_started_(jpm)/index.html new file mode 100644 index 0000000000..d9453e9767 --- /dev/null +++ b/files/ru/mozilla/add-ons/sdk/tutorials/getting_started_(jpm)/index.html @@ -0,0 +1,157 @@ +--- +title: Создание простого Add-on (jpm) +slug: Mozilla/Add-ons/SDK/Tutorials/Getting_Started_(jpm) +translation_of: Archive/Add-ons/Add-on_SDK/Tutorials/Getting_Started_(jpm) +--- +<div class="note"> +<p>The Add-on SDK includes a command-line tool that you use to initialize, run, test, and package add-ons. The current tool is called jpm, and is based on <a href="http://nodejs.org/">Node.js</a>. It replaces the old cfx tool.</p> + +<p>You can use jpm from Firefox 38 onwards.</p> + +<p>This article describes how to develop using jpm.</p> +</div> + +<p>This tutorial walks through creating a simple add-on using the SDK.</p> + +<h2 id="Prerequisites">Prerequisites</h2> + +<p>To create add-ons for Firefox using the SDK, you'll need:</p> + +<ul> + <li>Firefox version 38 or later. If you need to work with earlier versions of Firefox, you'll need to use the old cfx tool. See instructions for <a href="/en-US/Add-ons/SDK/Tutorials/Getting_started">getting started with cfx</a>.</li> + <li>the command-line jpm tool. See the instructions for <a href="/en-US/Add-ons/SDK/Tools/jpm#Installation">installing jpm</a>. Once you've done that, you'll be looking at a command prompt.</li> +</ul> + +<h2 id="Initializing_an_empty_add-on">Initializing an empty add-on</h2> + +<p>In the command prompt, create a new directory. Navigate to it, type <code>jpm init</code>, and hit enter:</p> + +<pre>mkdir my-addon +cd my-addon +jpm init +</pre> + +<p>You'll then be asked to supply some information about your add-on: this will be used to create your add-on's <a href="/en-US/Add-ons/SDK/Tools/package_json">package.json</a> file. For now, just press Enter to accept the default for each property. For more information on <code>jpm init</code>, see the <a href="/en-US/Add-ons/SDK/Tools/jpm#Command_reference">jpm command reference</a>.</p> + +<p>Once you've supplied a value or accepted the default for these properties, you'll be shown the complete contents of "package.json" and asked to accept it.</p> + +<h2 id="Implementing_the_add-on">Implementing the add-on</h2> + +<p>Now you can write the add-on's code. Unless you've changed the value of "entry point" ("<a href="/en-US/Add-ons/SDK/Tools/package_json#main">main</a>" in package.json), this goes in "index.js" file in the root of your add-on. This file was created for you in the previous step. Open it and add the following code:</p> + +<pre class="brush: js">var buttons = require('sdk/ui/button/action'); +var tabs = require("sdk/tabs"); + +var button = buttons.ActionButton({ + id: "mozilla-link", + label: "Visit Mozilla", + icon: { + "16": "./icon-16.png", + "32": "./icon-32.png", + "64": "./icon-64.png" + }, + onClick: handleClick +}); + +function handleClick(state) { + tabs.open("http://www.mozilla.org/"); +} +</pre> + +<div class="note"> +<p>Note that "entry point" defaults to "index.js" in jpm, meaning that your main file is "index.js", and it is found directly in your add-on's root.</p> + +<p>In cfx, the entry point defaults to "main.js", and is located in the "lib" directory under the add-on's root.</p> +</div> + +<p>Save the file.</p> + +<p>Next, create a directory called "data" in your add-on's root, and save these three icon files to the "data" directory:</p> + +<table class="standard-table"> + <tbody> + <tr> + <td><img alt="" src="https://mdn.mozillademos.org/files/7635/icon-16.png" style="height: 16px; width: 16px;"></td> + <td>icon-16.png</td> + </tr> + <tr> + <td><img alt="" src="https://mdn.mozillademos.org/files/7637/icon-32.png" style="height: 32px; width: 32px;"></td> + <td>icon-32.png</td> + </tr> + <tr> + <td><img alt="" src="https://mdn.mozillademos.org/files/7639/icon-64.png" style="height: 64px; width: 64px;"></td> + <td>icon-64.png</td> + </tr> + </tbody> +</table> + +<p>Back at the command prompt, type:</p> + +<pre>jpm run</pre> + +<p>This is the jpm command to run a new instance of Firefox with your add-on installed.</p> + +<p>If Firefox can not be located, you may need to provide the path to it (example in Ubuntu):</p> + + +<pre>jpm run -b /usr/bin/firefox</pre> + +<p>When Firefox launches, in the top-right corner of the browser you'll see an icon with the Firefox logo. Click the icon, and a new tab will open with <a href="http://www.mozilla.org/" rel="noreferrer">http://www.mozilla.org/</a> loaded into it.</p> + +<p>That's all this add-on does. It uses two SDK modules: the <a href="/en-US/Add-ons/SDK/Low-Level_APIs/ui_button_action">action button</a> module, which enables you to add buttons to the browser, and the <a href="/en-US/Add-ons/SDK/High-Level_APIs/tabs" rel="noreferrer">tabs</a> module, which enables you to perform basic operations with tabs. In this case, we've created a button whose icon is the Firefox icon, and added a click handler that loads the Mozilla home page in a new tab.</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/7643/mozilla-button.png" style="display: block; height: 221px; margin-left: auto; margin-right: auto; width: 382px;">Try editing this file. For example, we could change the page that gets loaded:</p> + +<pre class="brush: js">var buttons = require('sdk/ui/button/action'); +var tabs = require("sdk/tabs"); + +var button = buttons.ActionButton({ + id: "mozilla-link", + label: "Visit Mozilla", + icon: { + "16": "./icon-16.png", + "32": "./icon-32.png", + "64": "./icon-64.png" + }, + onClick: handleClick +}); + +function handleClick(state) { + tabs.open("https://developer.mozilla.org/"); +}</pre> + +<p>At the command prompt, execute <code>jpm run</code> again. This time clicking it takes you to <a href="https://developer.mozilla.org/">https://developer.mozilla.org/</a>.</p> + +<h2 id="Packaging_the_add-on">Packaging the add-on</h2> + +<p>When you've finished the add-on and are ready to distribute it, you'll need to package it as an XPI file. This is the installable file format for Firefox add-ons. You can distribute XPI files yourself or publish them to <a href="https://addons.mozilla.org" rel="noreferrer">https://addons.mozilla.org</a> so other users can download and install them.</p> + +<p>To build an XPI, just execute the command <code>jpm xpi</code> from the add-on's directory:</p> + +<pre>jpm xpi +</pre> + +<p>You should see a message like:</p> + +<pre>JPM info Successfully created xpi at /path/to/getting-started/@getting-started.xpi +</pre> + +<p>To test that this worked, try installing the XPI file in your own Firefox installation. You can do this by pressing the Ctrl+O key combination (Cmd+O on Mac) from within Firefox, or selecting the "Open" item from Firefox's "File" menu. This will bring up a file selection dialog: navigate to the "@getting-started.xpi" file, open it and follow the prompts to install the add-on.</p> + +<h2 id="Summary">Summary</h2> + +<p>In this tutorial we've built and packaged an add-on using three commands:</p> + +<ul> + <li><code>jpm init</code> to initialize an empty add-on template</li> + <li><code>jpm run</code> to run a new instance of Firefox with the add-on installed, so we can try it out</li> + <li><code>jpm xpi</code> to package the add-on into an XPI file for distribution</li> +</ul> + +<p>These are the three main commands you'll use when developing SDK add-ons. There's comprehensive <a href="/en-US/Add-ons/SDK/Tools/jpm" rel="noreferrer">reference documentation</a> covering all the commands you can use and all the options they take.</p> + +<p>The add-on code itself uses two SDK modules, <a href="/en-US/Add-ons/SDK/Low-Level_APIs/ui_button_action">action button</a> and <a href="/en-US/Add-ons/SDK/High-Level_APIs/tabs" rel="noreferrer">tabs</a>. There's reference documentation for all the <a href="/en-US/Add-ons/SDK/High-Level_APIs" rel="noreferrer">high-level</a> and <a href="/en-US/Add-ons/SDK/Low-Level_APIs" rel="noreferrer">low-level</a> APIs in the SDK.</p> + +<h2 id="What's_next">What's next?</h2> + +<p>To get a feel for some of the things you can do with the SDK APIs, try working through some of the <a href="/en-US/Add-ons/SDK/Tutorials" rel="noreferrer">tutorials</a>.</p> diff --git a/files/ru/mozilla/add-ons/sdk/tutorials/index.html b/files/ru/mozilla/add-ons/sdk/tutorials/index.html new file mode 100644 index 0000000000..277c5573d9 --- /dev/null +++ b/files/ru/mozilla/add-ons/sdk/tutorials/index.html @@ -0,0 +1,145 @@ +--- +title: Tutorials +slug: Mozilla/Add-ons/SDK/Tutorials +tags: + - NeedsTranslation + - TopicStub +translation_of: Archive/Add-ons/Add-on_SDK/Tutorials +--- +<p>Эта страница содержит практические статьи о том как выполнять конкретные задачи используя SDK.</p> + +<hr> +<h3 id="Начало_работы"><a name="getting-started">Начало работы</a></h3> + +<div class="column-container"> +<div class="column-half"> +<dl> + <dt><a href="/en-US/Add-ons/SDK/Tutorials/Installation">Установка </a></dt> + <dd>Скачивание, установка и инициализация <span class="_Tgc">комплекта средств разработки</span> (SDK) для Windows, OS X и Linux.</dd> +</dl> + +<dl> + <dt><a href="/en-US/Add-ons/SDK/Tutorials/Troubleshooting">Исправление проблем </a></dt> + <dd>Несколько указаний для фиксации общих пролбем и получение дополнительной помощи.</dd> +</dl> +</div> + +<div class="column-half"> +<dl> + <dt><a href="/en-US/Add-ons/SDK/Tutorials/Getting_started_with_cfx">Создание простого дополнения (Add-on) </a></dt> + <dd>Пошаговое руководство по созданию простого дополнения при помощи SDK и jpm.</dd> +</dl> +</div> +</div> + +<hr> +<h3 id="Создание_пользовательского_интерфейса"><a name="create-user-interfaces">Создание пользовательского интерфейса</a></h3> + +<div class="column-container"> +<div class="column-half"> +<dl> + <dt><a href="/en-US/Add-ons/SDK/Tutorials/Adding_a_Button_to_the_Toolbar">Добавление кнопи панели инструментов </a></dt> + <dd>Прикрепление кнопки к панели инструментов дополнений Firefox.</dd> + <dt><a href="/en-US/Add-ons/SDK/Tutorials/Add_a_Menu_Item_to_Firefox">Добавление элементов меню Firefox </a></dt> + <dd>Добавление элементов в основные меню Firefox.</dd> +</dl> +</div> + +<div class="column-half"> +<dl> + <dt><a href="/en-US/Add-ons/SDK/Tutorials/Display_a_Popup">Отображение высплывающего окна (popup) </a></dt> + <dd>Отображение всплывающего диалогового окна и его реализация с помощью HTML и JavaScript.</dd> + <dt><a href="/en-US/Add-ons/SDK/Tutorials/Add_a_Context_Menu_Item">Добавление элемента контекстного меню</a></dt> + <dd>Добавление элементов контекстных меню Firefox.</dd> +</dl> +</div> +</div> + +<hr> +<h3 id="Взаимодействие_с_браузером"><a name="interact-with-the-browser">Взаимодействие с браузером</a></h3> + +<div class="column-container"> +<div class="column-half"> +<dl> + <dt><a href="/en-US/Add-ons/SDK/Tutorials/Open_a_Web_Page">Загрузка вебстраниц</a></dt> + <dd>Загрузка вебстраниц в новой вкладке или новом окне с использованием модуля вкладок (tabs module), и доступ к их содержимому.</dd> + <dt><a href="/en-US/Add-ons/SDK/Tutorials/Listen_for_Page_Load">Отслеживание загрузки страниц </a></dt> + <dd>Использование модуля вкладок (tabs module) для получения оповещений о загрузке новых вебстраниц и доступа к их содержимому.</dd> +</dl> +</div> + +<div class="column-half"> +<dl> + <dt><a href="/en-US/Add-ons/SDK/Tutorials/List_Open_Tabs">Получение списка открытых вкладок</a></dt> + <dd>Использование модуля вкладок (tabs module) для перебора открытых вкладок и доступа к их содержимому.</dd> +</dl> +</div> +</div> + +<hr> +<h3 id="Изменение_вебстраниц"><a name="modify-web-pages">Изменение вебстраниц</a></h3> + +<div class="column-container"> +<div class="column-half"> +<dl> + <dt><a href="/en-US/Add-ons/SDK/Tutorials/Modifying_Web_Pages_Based_on_URL">Изменение вебстраниц на основе URL </a></dt> + <dd>Создание фильтров для вебстраниц на основе их URL: всякий раз, когда загрузится вебстраница, чей URL соответствует фильтру, на ней выполнится заданный сценарий.</dd> +</dl> +</div> + +<div class="column-half"> +<dl> + <dt><a href="/en-US/Add-ons/SDK/Tutorials/Modifying_the_Page_Hosted_by_a_Tab">Изменение активной вебстраницы </a></dt> + <dd>Динамическая загрузка сценария на текущую активную вебстраницу.</dd> +</dl> +</div> +</div> + +<hr> +<h3 id="Техники_разработки"><a name="development-techniques">Техники разработки</a></h3> + +<div class="column-container"> +<div class="column-half"> +<dl> + <dt><a href="/en-US/Add-ons/SDK/Tutorials/Logging">Логгирование </a></dt> + <dd>Вывод сообщений в консоль для диагностики.</dd> + <dt><a href="/en-US/Add-ons/SDK/Tutorials/Creating_reusable_modules">Создание повторно используемых модулей </a></dt> + <dd>Структурирование дополнения в отдельные модули, чтобы упростить разработку, отладку и поддержку. Создание повторно используемых пакетов, содержащих ваши модули, чтобы другие разработчики могли их использовать.</dd> + <dt><a href="/en-US/Add-ons/SDK/Tutorials/Unit_testing">Модульное тестирование </a></dt> + <dd>Написание и запуск модульных тестов с использованием тестовой среды SDK.</dd> + <dt><a href="/en-US/Add-ons/SDK/Tutorials/Chrome_authority">Полномочия Chrome </a></dt> + <dd>Получение доступа к объекту Components, позволит вашему дополнению загружать и использовать любой объект XPCOM.</dd> + <dt><a href="/en-US/Add-ons/SDK/Tutorials/Creating_event_targets">Создание целей события </a></dt> + <dd>Включение объектов вашего определения для выпуска собственных событий.</dd> +</dl> +</div> + +<div class="column-half"> +<dl> + <dt><a href="/en-US/Add-ons/SDK/Tutorials/Listening_for_load_and_unload">Отслеживание загрузки и выгрузки </a></dt> + <dd>Получение уведомлений, когда Firefox загрузил или выгрузил ваше дополнение и передача аргументов вашему дополнению из командной строки.</dd> + <dt><a href="/en-US/Add-ons/SDK/Tutorials/Add_a_Menu_Item_to_Firefox">Использование сторонних модулей </a></dt> + <dd>Установка и использование дополнительных модулей не входящих в SDK.</dd> + <dt><a href="/en-US/Add-ons/SDK/Tutorials/l10n">Локализация </a></dt> + <dd>Написание локализуемого кода.</dd> + <dt><a href="/en-US/Add-ons/SDK/Tutorials/Mobile_development">Мобильная разработка </a></dt> + <dd><span class="short_text" id="result_box" lang="ru"><span class="alt-edited">Разработка дополнений для Firefox Mobile на Android.</span></span></dd> + <dt><a href="/en-US/Add-ons/Add-on_Debugger">Отладчик дополнения</a></dt> + <dd>Отладка JavaScript вашего дополнения.</dd> +</dl> +</div> +</div> + +<hr> +<h3 id="Объединение"><a name="putting-it-together">Объединение</a></h3> + +<div class="column-container"> +<div class="column-half"> +<dl> + <dt><a href="/en-US/Add-ons/SDK/Tutorials/Annotator">Аннотация дополнения </a></dt> + <dd><span id="result_box" lang="ru"><span>Пошаговое руководство относительно сложного дополнения.</span></span></dd> +</dl> +</div> +</div> + +<p> </p> diff --git a/files/ru/mozilla/add-ons/sdk/tutorials/installation/index.html b/files/ru/mozilla/add-ons/sdk/tutorials/installation/index.html new file mode 100644 index 0000000000..48b8923923 --- /dev/null +++ b/files/ru/mozilla/add-ons/sdk/tutorials/installation/index.html @@ -0,0 +1,68 @@ +--- +title: Installation +slug: Mozilla/Add-ons/SDK/Tutorials/Installation +translation_of: Mozilla/Add-ons/SDK/Tools/jpm#Installation +--- +<h2 id="Prerequisites">Prerequisites</h2> +<p>To develop with the Add-on SDK, you'll need:</p> +<ul> + <li><a href="http://www.python.org/">Python</a> 2.5, 2.6 or 2.7. Note that versions 3.x of Python are not supported on any platform. Make sure that Python is in your path.</li> + <li>Firefox.</li> + <li>The SDK itself: you can obtain the latest stable version of the SDK as a <a href="https://ftp.mozilla.org/pub/mozilla.org/labs/jetpack/jetpack-sdk-latest.tar.gz">tarball</a> or a <a href="https://ftp.mozilla.org/pub/mozilla.org/labs/jetpack/jetpack-sdk-latest.zip">zip file</a>.</li> +</ul> +<p>Alternatively, if you use Firefox Nightly, you can get the latest development version from its <a href="https://github.com/mozilla/addon-sdk">GitHub repository</a>.</p> +<h2 id="Installation_on_Mac_OS_X_Linux">Installation on Mac OS X / Linux</h2> +<p>Extract the file contents wherever you choose, and navigate to the root directory of the SDK with a shell/command prompt. For example:</p> +<pre>tar -xf addon-sdk.tar.gz +cd addon-sdk +</pre> +<p>Then run if you're a Bash user (most people are):</p> +<pre>source bin/activate +</pre> +<p>And if you're a non-Bash user, you should run:</p> +<pre>bash bin/activate +</pre> +<p>Your command prompt should now have a new prefix containing the name of the SDK's root directory:</p> +<pre>(addon-sdk)~/mozilla/addon-sdk > +</pre> +<h2 id="Installation_on_Mac_using_Homebrew">Installation on Mac using Homebrew</h2> +<p>If you're a Mac user, you can instead choose to use <a href="http://brew.sh/">Homebrew</a> to install the SDK, using the following command:</p> +<pre>brew install mozilla-addon-sdk</pre> +<p>Once this has completed successfully, you can use the <code>cfx</code> program at your command line at any time: you don't need to run bin/activate.</p> +<h2 id="Installation_on_Windows">Installation on Windows</h2> +<p>Extract the file contents wherever you choose, and navigate to the root directory of the SDK with a shell/command prompt. For example:</p> +<pre>7z.exe x addon-sdk.zip +cd addon-sdk +</pre> +<p>Then run:</p> +<pre>bin\activate +</pre> +<p>Your command prompt should now have a new prefix containing the full path to the SDK's root directory:</p> +<pre>(C:\Users\mozilla\sdk\addon-sdk) C:\Users\Work\sdk\addon-sdk> +</pre> +<h2 id="activate">activate</h2> +<p>The activate command sets some environment variables that are needed for the SDK. It sets the variables for the current command prompt only. If you open a new command prompt, the SDK will not be active in the new prompt. until you type <code>activate</code> again.</p> +<p>This means that you can have multiple copies of the SDK in different locations on disk and switch between them, or even have them both activated in different command prompts at the same time.</p> +<h3 id="Making_activate_permanent">Making <code>activate</code> permanent</h3> +<p>By setting these variables permanently in your environment so every new command prompt reads them, you can make activation permanent. Then you don't need to type <code>activate</code> every time you open up a new command prompt.</p> +<p>Because the exact set of variables may change with new releases of the SDK, it's best to refer to the activation scripts to determine which variables need to be set. Activation uses different scripts and sets different variables for bash environments (Linux and Mac OS X) and for Windows environments.</p> +<h4 id="Windows">Windows</h4> +<p>On Windows, <code>bin\activate</code> uses <code>activate.bat</code>, and you can make activation permanent using the command line <code>setx</code> tool or the Control Panel.</p> +<h4 id="LinuxMac_OS_X">Linux/Mac OS X</h4> +<p>On Linux and Mac OS X, <code>source bin/activate</code> uses the <code>activate</code> bash script, and you can make activation permanent using your <code>~/.bashrc</code> (on Linux) or <code>~/.bashprofile</code> (on Mac OS X).</p> +<p>As an alternative to this, you can create a symbolic link to the <code>cfx</code> program in your <code>~/bin</code> directory:</p> +<pre>ln -s PATH_TO_SDK/bin/cfx ~/bin/cfx +</pre> +<p>If you used Homebrew to install the SDK, the environment variables are already set permanently for you.</p> +<h2 id="Sanity_check">Sanity check</h2> +<p>Run this at your shell prompt:</p> +<pre>cfx +</pre> +<p>It should produce output whose first line looks something like this, followed by many lines of usage information:</p> +<pre>Usage: cfx [options] [command] +</pre> +<p>This is the <a href="/en-US/Add-ons/SDK/Tools/cfx"><code>cfx</code> command-line program</a>. It's your primary interface to the Add-on SDK. You use it to launch Firefox and test your add-on, package your add-on for distribution, view documentation, and run unit tests.</p> +<h2 id="Problems">Problems?</h2> +<p>Try the <a href="/en-US/Add-ons/SDK/Tutorials/Troubleshooting">Troubleshooting</a> page.</p> +<h2 id="Next_Steps">Next Steps</h2> +<p>Next, take a look at the <a href="/en-US/Add-ons/SDK/Tutorials/Getting_Started_With_cfx">Getting Started With cfx</a> tutorial, which explains how to create add-ons using the <code>cfx</code> tool.</p> diff --git a/files/ru/mozilla/add-ons/sdk/tutorials/аннотатор/creating_annotations/index.html b/files/ru/mozilla/add-ons/sdk/tutorials/аннотатор/creating_annotations/index.html new file mode 100644 index 0000000000..07cecddaf5 --- /dev/null +++ b/files/ru/mozilla/add-ons/sdk/tutorials/аннотатор/creating_annotations/index.html @@ -0,0 +1,221 @@ +--- +title: Добавление заметок +slug: Mozilla/Add-ons/SDK/Tutorials/Аннотатор/Creating_annotations +translation_of: Archive/Add-ons/Add-on_SDK/Tutorials/Annotator/Creating_annotations +--- +<p>Мы будем использовать два объекта для создания заметок: модификатор страницы - чтобы найти элементы, для которых пользователь может оставить заметку и панель для ввода текста заметки.</p> +<h2 id="Селектор_модификации_страницы">Селектор модификации страницы</h2> +<h3 id="Селектор_контент-скриптов">Селектор контент-скриптов</h3> +<p>Контент-скрипт для селекторамодификации страницы будет ипользовать <a href="http://jquery.com/">jQuery</a> для поиска элементов и манипуляций над ними.</p> +<p>Эго главная задача - обработка "подходящего элемента": это элемент страницы, который подходит для добавления заметки на него. Подходящий элемент будет подсвечен и будет иметь обработчик событий, который будет отправлять сообщения основному коду расширения.</p> +<p>Селектор модификации страницы может быть активирован или деактивирован используя сообщение от основного кода расширения. По-умолчанию он деактивирован:</p> +<pre class="brush: js">var matchedElement = null; +var originalBgColor = null; +var active = false; + +function resetMatchedElement() { + if (matchedElement) { + (matchedElement).css('background-color', originalBgColor); + (matchedElement).unbind('click.annotator'); + } +} + +self.on('message', function onMessage(activation) { + active = activation; + if (!active) { + resetMatchedElement(); + } +});</pre> +<p>Данный селектор ожидает вхождения события <a href="http://api.jquery.com/mouseenter/">jQuery mouseenter</a>.</p> +<p> When a mouseenter event is triggered the selector checks whether the element is eligible for annotation. An element is eligible if it, or one of its ancestors in the DOM tree, has an attribute named <code>"id"</code>. The idea here is to make it more likely that the annotator will be able to identify annotated elements correctly later on.</p> +<p>If the page element is eligible for annotation, then the selector highlights that element and binds a click handler to it. The click handler sends a message called <code>show</code> back to the main add-on code. The <code>show</code> message contains: the URL for the page, the ID attribute value, and the text content of the page element.</p> +<pre class="brush: js">$('*').mouseenter(function() { + if (!active || $(this).hasClass('annotated')) { + return; + } + resetMatchedElement(); + ancestor = $(this).closest("[id]"); + matchedElement = $(this).first(); + originalBgColor = $(matchedElement).css('background-color'); + $(matchedElement).css('background-color', 'yellow'); + $(matchedElement).bind('click.annotator', function(event) { + event.stopPropagation(); + event.preventDefault(); + self.port.emit('show', + [ + document.location.toString(), + $(ancestor).attr("id"), + $(matchedElement).text() + ] + ); + }); +});</pre> +<p>Conversely, the add-on resets the matched element on <a href="http://api.jquery.com/mouseout/">mouseout</a>:</p> +<pre class="brush: js">$('*').mouseout(function() { + resetMatchedElement(); +});</pre> +<p>Save this code in a new file called <code>selector.js</code> in your add-on's <code>data</code> directory.</p> +<p>Because this code uses jQuery, you'll need to <a href="http://docs.jquery.com/Downloading_jQuery">download</a> that as well, and save it in <code>data</code>.</p> +<h3 id="Updating_main.js">Updating main.js</h3> +<p>Go back to <code>main.js</code> and add the code to create the selector into the <code>main</code> function:</p> +<pre class="brush: js">var selector = pageMod.PageMod({ + include: ['*'], + contentScriptWhen: 'ready', + contentScriptFile: [data.url('jquery-1.4.2.min.js'), + data.url('selector.js')], + onAttach: function(worker) { + worker.postMessage(annotatorIsOn); + selectors.push(worker); + worker.port.on('show', function(data) { + console.log(data); + }); + worker.on('detach', function () { + detachWorker(this, selectors); + }); + } +});</pre> +<p>Make sure the name you use to load jQuery matches the name of the jQuery version you downloaded.</p> +<p>The page-mod matches all pages, so each time the user loads a page the page-mod emits the <code>attach</code> event, which will call the listener function we've assigned to <code>onAttach</code>. The handler is passed a <a href="/en-US/Add-ons/SDK/Low-Level_APIs/content_worker">worker</a> object. Each worker represents a channel of communication between the add-on code and any content scripts running in that particular page context. For a more detailed discussion of the way <code>page-mod</code> uses workers, see the <a href="/en-US/Add-ons/SDK/High-Level_APIs/page-mod">page-mod documentation</a>.</p> +<p>In the attach handler we do three things:</p> +<ul> + <li>send the content script a message with the current activation status</li> + <li>add the worker to an array called <code>selectors</code> so we can send it messages later on</li> + <li>assign a message handler for messages from this worker. If the message is <code>show</code> we will just log the content for the time being. If the message is <code>detach</code> we remove the worker from the <code>selectors</code> array.</li> +</ul> +<p>At the top of the file import the <code>page-mod</code> module and declare an array for the workers:</p> +<pre class="brush: js">var pageMod = require('sdk/page-mod'); +var selectors = [];</pre> +<p>Add <code>detachWorker</code>:</p> +<pre class="brush: js">function detachWorker(worker, workerArray) { + var index = workerArray.indexOf(worker); + if(index != -1) { + workerArray.splice(index, 1); + } +}</pre> +<p>Edit <code>toggleActivation</code> to notify the workers of a change in activation state:</p> +<pre class="brush: js">function activateSelectors() { + selectors.forEach( + function (selector) { + selector.postMessage(annotatorIsOn); + }); +} + +function toggleActivation() { + annotatorIsOn = !annotatorIsOn; + activateSelectors(); + return annotatorIsOn; +}</pre> +<p><span class="aside">We'll be using this URL in all our screenshots. Because <code>cfx run</code> doesn't preserve browsing history, if you want to play along it's worth taking a note of the URL.</span></p> +<p>Save the file and execute <code>cfx run</code> again. Activate the annotator by clicking the widget and load a page: the screenshot below uses <a href="http://blog.mozilla.com/addons/2011/02/04/overview-amo-review-process/">http://blog.mozilla.com/addons/2011/02/04/ overview-amo-review-process/</a>. You should see the highlight appearing when you move the mouse over certain elements:</p> +<p><img alt="" src="https://mdn.mozillademos.org/files/6681/highlight.png" style="display: block; margin-left: auto; margin-right: auto;">Click on the highlight and you should see something like this in the console output:</p> +<pre> info: show + info: http://blog.mozilla.com/addons/2011/02/04/overview-amo-review-process/, + post-2249,When you submit a new add-on, you will have to choose between 2 + review tracks: Full Review and Preliminary Review. +</pre> +<h2 id="Annotation_Editor_Panel">Annotation Editor Panel</h2> +<p>So far we have a page-mod that can highlight elements and send information about them to the main add-on code. Next we will create the editor panel, which enables the user to enter an annotation associated with the selected element.</p> +<p>We will supply the panel's content as an HTML file, and will also supply a content script to execute in the panel's context.</p> +<p>So create a subdirectory under <code>data</code> called <code>editor</code>. This will contain two files: the HTML content, and the content script.</p> +<h3 id="Annotation_Editor_HTML">Annotation Editor HTML</h3> +<p>The HTML is very simple:</p> +<pre class="brush: html"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" +"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> +<head> + <title>Annotation</title> + <style type="text/css" media="all"> + body { + font: 100% arial, helvetica, sans-serif; + background-color: #F5F5F5; + } + textarea { + width: 180px; + height: 180px; + margin: 10px; + padding: 0px; + } + </style> + +</head> + +<body> + +<textarea rows='10' cols='20' id='annotation-box'> +</textarea> + +</body> + +</html></pre> +<p>Save this inside <code>data/editor</code> as <code>annotation-editor.html</code>.</p> +<h3 id="Annotation_Editor_Content_Script">Annotation Editor Content Script</h3> +<p>In the corresponding content script we do two things:</p> +<ul> + <li>handle a message from the add-on code by giving the text area focus</li> + <li>listen for the return key and when it is pressed, send the contents of the text area to the add-on.</li> +</ul> +<p>Here's the code:</p> +<pre class="brush: js">var textArea = document.getElementById('annotation-box'); + +textArea.onkeyup = function(event) { + if (event.keyCode == 13) { + self.postMessage(textArea.value); + textArea.value = ''; + } +}; + +self.on('message', function() { + var textArea = document.getElementById('annotation-box'); + textArea.value = ''; + textArea.focus(); +});</pre> +<p>Save this inside <code>data/editor</code> as <code>annotation-editor.js</code>.</p> +<h3 id="Updating_main.js_Again">Updating main.js Again</h3> +<p>Now we'll update <code>main.js</code> again to create the editor and use it.</p> +<p>First, import the <code>panel</code> module:</p> +<pre class="brush: js">var panels = require('sdk/panel');</pre> +<p>Then add the following code to the <code>main</code> function:</p> +<pre class="brush: js">var annotationEditor = panels.Panel({ + width: 220, + height: 220, + contentURL: data.url('editor/annotation-editor.html'), + contentScriptFile: data.url('editor/annotation-editor.js'), + onMessage: function(annotationText) { + if (annotationText) { + console.log(this.annotationAnchor); + console.log(annotationText); + } + annotationEditor.hide(); + }, + onShow: function() { + this.postMessage('focus'); + } +});</pre> +<p>We create the editor panel but don't show it. We will send the editor panel the <code>focus</code> message when it is shown, so it will give the text area focus. When the editor panel sends us its message we log the message and hide the panel.</p> +<p>The only thing left is to link the editor to the selector. So edit the message handler assigned to the selector so that on receiving the <code>show</code> message we assign the content of the message to the panel using a new property "annotationAnchor", and show the panel:</p> +<pre class="brush: js">var selector = pageMod.PageMod({ + include: ['*'], + contentScriptWhen: 'ready', + contentScriptFile: [data.url('jquery-1.4.2.min.js'), + data.url('selector.js')], + onAttach: function(worker) { + worker.postMessage(annotatorIsOn); + selectors.push(worker); + worker.port.on('show', function(data) { + annotationEditor.annotationAnchor = data; + annotationEditor.show(); + }); + worker.on('detach', function () { + detachWorker(this, selectors); + }); + } +});</pre> +<p>Execute <code>cfx run</code> again, activate the annotator, move your mouse over an element and click the element when it is highlighted. You should see a panel with a text area for a note:</p> +<p><img alt="" src="https://mdn.mozillademos.org/files/6683/editor-panel.png" style="display: block; margin-left: auto; margin-right: auto;">Enter the note and press the return key: you should see console output like this:</p> +<pre> info: http://blog.mozilla.com/addons/2011/02/04/overview-amo-review-process/, + post-2249,When you submit a new add-on, you will have to choose between 2 + review tracks: Full Review and Preliminary Review. + info: We should ask for Full Review if possible. +</pre> +<p>That's a complete annotation, and in the next section we'll deal with <a href="/en-US/Add-ons/SDK/Tutorials/Annotator/Storing_annotations">storing it</a>.</p> diff --git a/files/ru/mozilla/add-ons/sdk/tutorials/аннотатор/implementing_the_widget/index.html b/files/ru/mozilla/add-ons/sdk/tutorials/аннотатор/implementing_the_widget/index.html new file mode 100644 index 0000000000..ef43991658 --- /dev/null +++ b/files/ru/mozilla/add-ons/sdk/tutorials/аннотатор/implementing_the_widget/index.html @@ -0,0 +1,68 @@ +--- +title: Реализация Виджета +slug: Mozilla/Add-ons/SDK/Tutorials/Аннотатор/Implementing_the_widget +translation_of: Archive/Add-ons/Add-on_SDK/Tutorials/Annotator/Implementing_the_widget +--- +<p>Мы хотим, чтобы виджет выполнял две вещи:</p> +<ul> + <li>При клике левой кнопкой мыши, Виджет должен активировать или деактивировать Аннотатор;</li> + <li>При клике правой кнопкой, Виджет должен отобразить список всех заметок, созданных пользователем.</li> +</ul> +<p>Так как событие <code>click</code> не различает левую и правую кнопки мыши, мы будем использовать контент-скрипт для захвата событий клика мышью и отправлять соответствующее сообщение назад, нашему расширению.</p> +<p>Виджет должен иметь две иконки: одна для активного состояния, вторая для неактивного.</p> +<p>В итоге нам понадобится создать три файла: контент-скрипт для Виджета и две иконки.</p> +<p>Внутри папки <code>data</code> создайте папку с именем <code>widget</code>. В этой папке мы будем хранить файлы Виджета. (Вам не обязательно создавать отдельную папку, можете просто хранить файлы Виджета в папке <code>data</code>. Но в нашем случае, расширение будет хорошо структурировано.)</p> +<h2 id="Контент-скрипт_Виджета">Контент-скрипт Виджета</h2> +<p>Контент-скрипт Виджета просто следит за нажатиями левой и правой кнопок мыши и отправляет соответствующее сообщение коду расширения:</p> +<pre class="brush: js">this.addEventListener('click', function(event) { + if(event.button == 0 && event.shiftKey == false) + self.port.emit('left-click'); + + if(event.button == 2 || (event.button == 0 && event.shiftKey == true)) + self.port.emit('right-click'); + event.preventDefault(); +}, true);</pre> +<p>Сохраните этот файл в папку <code>data/widget</code> под названием <code>widget.js</code>.</p> +<h2 id="Иконки_Виджета">Иконки Виджета</h2> +<p>Вы можете скопировать эти иконки:</p> +<p><img alt="" src="https://mdn.mozillademos.org/files/6673/pencil-off.png"><img alt="" src="https://mdn.mozillademos.org/files/6675/pencil-on.png" style="width: 32px; height: 32px;"></p> +<p>(Вы также можете создать свои собственные иконки, если чуствуете, что вас поситила муза.) Сохраните их в папку <code>data/widget</code>.</p> +<h2 id="main.js">main.js</h2> +<p>Теперь, в папке <code>lib</code> откройте <code>main.js</code> и добавьте следующий код:</p> +<pre class="brush: js">var widgets = require('sdk/widget'); +var data = require('sdk/self').data; + +var annotatorIsOn = false; + +function toggleActivation() { + annotatorIsOn = !annotatorIsOn; + return annotatorIsOn; +} + +exports.main = function() { + + var widget = widgets.Widget({ + id: 'toggle-switch', + label: 'Annotator', + contentURL: data.url('widget/pencil-off.png'), + contentScriptWhen: 'ready', + contentScriptFile: data.url('widget/widget.js') + }); + + widget.port.on('left-click', function() { + console.log('activate/deactivate'); + widget.contentURL = toggleActivation() ? + data.url('widget/pencil-on.png') : + data.url('widget/pencil-off.png'); + }); + + widget.port.on('right-click', function() { + console.log('show annotation list'); + }); +}</pre> +<p>Аннотатор по-умолчанию отключен. Этот скрипт создает Виджет и реагирует на сообщения контент-скрипта, путем переключения состояния Виджета. Внимание: согласно багу<span class="aside"> <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=626326">bug 626326</a>, контекстное меню панели дополнений будет отображаться вне зависимости от вызова <code>event.preventDefault()</code> в контент-скрипте Виджета.</span> Так как мы пока не имеем кода для отображения заметок, мы просто выведем в консоль событие нажатия правой кнопки.</p> +<p>Теперь, перейдя в папку <code>annotator</code> выполните команду <code>cfx run</code>. Вы должны увидеть Виджет в панели дополнений:</p> +<p><img alt="" src="https://mdn.mozillademos.org/files/6679/widget-icon.png" style="width: 405px; height: 166px; display: block; margin-left: auto; margin-right: auto;"></p> +<p>Левый и правый клики должы выводить соответсвующие сообщения в консоль, и левый клик также должен менять иконку для отображения состояния активности Виджета.</p> +<p> </p> +<p>Далее мы добавим реализацию функции <a href="/en-US/Add-ons/SDK/Tutorials/Annotator/Creating_annotations">создания аннотаций</a>.</p> diff --git a/files/ru/mozilla/add-ons/sdk/tutorials/аннотатор/index.html b/files/ru/mozilla/add-ons/sdk/tutorials/аннотатор/index.html new file mode 100644 index 0000000000..eab37823c0 --- /dev/null +++ b/files/ru/mozilla/add-ons/sdk/tutorials/аннотатор/index.html @@ -0,0 +1,34 @@ +--- +title: Комментатор +slug: Mozilla/Add-ons/SDK/Tutorials/Аннотатор +translation_of: Archive/Add-ons/Add-on_SDK/Tutorials/Annotator +--- +<p>{{AddonSidebar}}</p> + +<div class="warning"> +<p>Запрещено в Firefox 29 и удалено в Firefox 38.</p> + +<p>Предупреждение: это руководство пологается на впоследствии удалённый Widget API и больше не работает с Firefox.</p> + +<p>The widget API is deprecated from Firefox 29 onwards. Please see the <a href="/en-US/Add-ons/SDK/High-Level_APIs/ui">ui module</a> for replacements. In particular, for a simple button, try the <a href="/en-US/Add-ons/SDK/High-Level_APIs/ui#ActionButton">action button</a> or <a href="/en-US/Add-ons/SDK/High-Level_APIs/ui#ToggleButton">toggle button</a> APIs, and for a more complex widget try the <a href="/en-US/Add-ons/SDK/High-Level_APIs/ui#Toolbar">toolbar</a> or <a href="/en-US/Add-ons/SDK/High-Level_APIs/ui#Sidebar">sidebar</a> APIs.</p> +</div> + +<p>В этом уроке мы создадим расширение, которое использует множество различных компонентов <a href="/en-US/Add-ons/SDK/High-Level_APIs">высокоуровнего API</a>.</p> + +<p>Это расширение (Аннотатор) позволит пользователю выделять элементы веб-страниц и добавлять к ним заметки (аннотации). Аннотатор будет сохранять заметки, добавленные пользователем. Когда пользователь посещает веб-страницу, содержащую элементы с прикрепленными к ним заметками - эти элементы подсвечиваются. Если пользователь наведет курсор на такой элемент страницы, то будет отображена заметка, ассоциированная с этим элементом.</p> + +<p>Далее мы кратко рассмотрим архитектуру Аннотатора и поэтапно пройдемся по реализации разных частей расширения.</p> + +<p>Завершенное расширение вы можете найти в <a href="https://github.com/mozilla/addon-sdk/tree/master/examples/annotator">папке <code>examples</code> из SDK</a>.</p> + +<ul> + <li><a href="/ru/docs/Mozilla/Add-ons/SDK/Tutorials/%D0%90%D0%BD%D0%BD%D0%BE%D1%82%D0%B0%D1%82%D0%BE%D1%80/Overview">Краткий обзор архитектуры</a><br> + </li> + <li><a href="/ru/docs/Mozilla/Add-ons/SDK/Tutorials/%D0%90%D0%BD%D0%BD%D0%BE%D1%82%D0%B0%D1%82%D0%BE%D1%80/Implementing_the_widget">Реализация Виджета</a><br> + </li> + <li><a href="/ru/docs/Mozilla/Add-ons/SDK/Tutorials/%D0%90%D0%BD%D0%BD%D0%BE%D1%82%D0%B0%D1%82%D0%BE%D1%80/Creating_annotations">Добавление заметок</a><br> + </li> + <li><a href="/en-US/Add-ons/SDK/Tutorials/Annotator/Storing_annotations">Хранение заметок</a><br> + </li> + <li><a href="/en-US/Add-ons/SDK/Tutorials/Annotator/Displaying_annotations">Отображение заметок</a></li> +</ul> diff --git a/files/ru/mozilla/add-ons/sdk/tutorials/аннотатор/overview/index.html b/files/ru/mozilla/add-ons/sdk/tutorials/аннотатор/overview/index.html new file mode 100644 index 0000000000..08e4713b33 --- /dev/null +++ b/files/ru/mozilla/add-ons/sdk/tutorials/аннотатор/overview/index.html @@ -0,0 +1,34 @@ +--- +title: Краткий обзор +slug: Mozilla/Add-ons/SDK/Tutorials/Аннотатор/Overview +translation_of: Archive/Add-ons/Add-on_SDK/Tutorials/Annotator/Overview +--- +<p>Аннотатор использует контент-скрипты для реализации пользовательских интерфейсов, получения ввода, и для работы со страницами, посещаемыми пользователем.</p> +<p>Модуль <code>main</code> содержит логику приложения и производит операции между различными объектами SDK.</p> +<p>Операции между модулем <code>main</code> и различными контент-скриптами можно изобразить следующим образом:</p> +<p><img alt="" src="https://mdn.mozillademos.org/files/6671/annotator-design.png" style="display: block; margin-left: auto; margin-right: auto;"></p> +<h2 id="Пользовательский_интерфейс">Пользовательский интерфейс</h2> +<p>Основной пользовательский интерфейс состоит из Виджета и трех панелей:</p> +<ul> + <li>Виджет (<code><a href="/en-US/Add-ons/SDK/High-Level_APIs/widget">widget</a></code>) используется для активации Аннотатора и для отображения списка всех сохраненных заметок;</li> + <li>Панель (<code><a href="/en-US/Add-ons/SDK/High-Level_APIs/panel">panel</a></code>) <strong>annotation-editor</strong> позволит пользователю добавить новую заметку;</li> + <li>Панель <strong>annotation-list</strong> будет отображать список всех сохраненных заметок;</li> + <li>Панель <strong>annotation</strong> будет отображать одну заметку.</li> +</ul> +<p>В дополнении, мы будем использовать модуль Оповещений (<a href="/en-US/Add-ons/SDK/High-Level_APIs/notifications"><code>notifications</code></a>), чтобы сообщать пользователю, когда в хранилище закончилось свободное место.</p> +<h2 id="Работаем_с_DOM">Работаем с DOM</h2> +<p>Мы будем использовать два объекта <a href="/en-US/Add-ons/SDK/High-Level_APIs/page-mod"><code>page-mods</code></a> для произведения операций над DOM веб-страниц, которые посещает пользователь:</p> +<ul> + <li> + <p>Объект <strong>selector</strong> позволит пользователю выбрать элемент для добавления заметки к нему. Он идентифицирует элементы страницы, которые подходят для заметок, подсвечивает их при наведении курсора мыши и сообщает основному коду расширения когда пользователь кликает по подсвеченному элементу;</p> + </li> + <li> + <p>Объект <strong>matcher</strong> отвечает за поиск элементов с заметками: он инициализируется со списком заметок и осуществляет поиск веб-сраниц с элементами, ассоциированными с этими заметками. Он также подсвечивает все элементы, ассоциированные с заметками. Когда пользователь наводит курсор мыши на элемент с заметкой, matcher сообщает основному коду расширения, который, в свою очередь, отображает панель с одной заметкой.</p> + </li> +</ul> +<h2 id="Обработка_данных">Обработка данных</h2> +<p>Мы будем использовать модуль <a href="/en-US/Add-ons/SDK/High-Level_APIs/simple-storage"><code>simple-storage</code></a> для хранения заметок.</p> +<p>Поскольку мы сохраняем потенциально секретную информацию, мы хотим оградить пользователя от создания заметок в приватном режиме браузера. Простейший способ решения этой проблемы, это удаление ключа <a href="/en-US/Add-ons/SDK/Tools/package_json#permissions"><code>"private-browsing"</code></a> из файла "package.json" расширения. Если мы удалим этот ключ, то расширение не получит доступ к окнам в режиме приватного просмотра и Виджет Аннотатора не будет отображаться в приватных окнах.</p> +<h2 id="Приступаем_к_работе">Приступаем к работе</h2> +<p>Давайте начнем с создания папки, с именем "annotator". Перейдите в эту папку и введите <code>cfx init</code>.</p> +<p>Далее мы <a href="/en-US/Add-ons/SDK/Tutorials/Annotator/Implementing_the_widget">разработаем Виджет</a>.</p> diff --git a/files/ru/mozilla/add-ons/sdk/tutorials/добавление_кнопки_на_панель_инструментов/index.html b/files/ru/mozilla/add-ons/sdk/tutorials/добавление_кнопки_на_панель_инструментов/index.html new file mode 100644 index 0000000000..7b6e8bf507 --- /dev/null +++ b/files/ru/mozilla/add-ons/sdk/tutorials/добавление_кнопки_на_панель_инструментов/index.html @@ -0,0 +1,94 @@ +--- +title: Добавление кнопки на панель инструментов +slug: Mozilla/Add-ons/SDK/Tutorials/Добавление_кнопки_на_панель_инструментов +tags: + - Add-on SDK + - Дополнение +translation_of: Archive/Add-ons/Add-on_SDK/Tutorials/Adding_a_Button_to_the_Toolbar +--- +<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}}{{AddonSidebar}}</p> + +<div class="note"> +<p><span>Для понимания этого руководства необходимо изучить статью <a href="/en-US/docs/Mozilla/Add-ons/SDK/Tutorials/Getting_Started_%28jpm%29">basics of <code>jpm (основы jpm)</code></a>. </span></p> +</div> + +<p>Для добавления кнопки на панель инструментов (toolbar, тулбар) используются модули <a href="/en-US/Add-ons/SDK/Low-Level_APIs/ui_button_action">action button</a> или <a href="/en-US/Add-ons/SDK/Low-Level_APIs/ui_button_toggle">toggle button</a>.</p> + +<p>Создайте новую папку, перейдите в неё и запустите <code>jpm init</code>, приняв всё по умолчанию.</p> + +<p>Создайте папку <strong>"data"</strong></p> + +<pre>mkdir data</pre> + +<p>и сохраните три файла иконок в этой папке:</p> + +<table class="standard-table"> + <tbody> + <tr> + <td><img alt="" src="https://mdn.mozillademos.org/files/7635/icon-16.png" style="height: 16px; width: 16px;"></td> + <td>icon-16.png</td> + </tr> + <tr> + <td><img alt="" src="https://mdn.mozillademos.org/files/7637/icon-32.png" style="height: 32px; width: 32px;"></td> + <td>icon-32.png</td> + </tr> + <tr> + <td><img alt="" src="https://mdn.mozillademos.org/files/7639/icon-64.png" style="height: 64px; width: 64px;"></td> + <td>icon-64.png</td> + </tr> + </tbody> +</table> + +<p>После, откройте файл "index.js", расположенный в корне каталога дополнения, и допишите этот код:</p> + +<pre class="brush: js">var buttons = require('sdk/ui/button/action'); +var tabs = require("sdk/tabs"); + +var button = buttons.ActionButton({ + id: "mozilla-link", + label: "Visit Mozilla", + icon: { + "16": "./icon-16.png", + "32": "./icon-32.png", + "64": "./icon-64.png" + }, + onClick: handleClick +}); + +function handleClick(state) { + tabs.open("https://www.mozilla.org/"); +}</pre> + +<p>Запустите дополнение через <code>jpm run</code>. Кнопка будет добавлена на тулбар (ищите сверху в окне браузера):</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/7641/mozilla-button.png" style="display: block; height: 221px; margin-left: auto; margin-right: auto; width: 382px;">Вы не сможете установить место первоначального появления кнопки, но пользователь сможет её переместить, используя настройки браузера. Атрибут <code>id</code> является обязательным. Он используется, в частности, для запоминания позиции кнопки на панели, поэтому в следующих версиях своего дополнения вы его не сможете изменить.</p> + +<p>Нажатие кнопки откроет в новой вкладке сайт <a href="https://www.mozilla.org/en-US/">https://www.mozilla.org/</a> .</p> + +<h2 id="Задание_иконки">Задание иконки</h2> + +<p>Свойство icon может содержать одну иконку или набор (различных размеров, как в примере выше). Если указать набор иконок разных размеров, то браузер будет автоматически выбирать размер в зависимости от разрешения экрана и расположения на экране. <a href="/en-US/Add-ons/SDK/Low-Level_APIs/ui_button_action#ActionButton(options)">Более подробная информация о иконках</a>.</p> + +<p>Файл с иконкой должен быть внутри дополнения. Недопустимы ссылки на внешние фалы.</p> + +<p>Вы можете изменить иконку в любое время через установку свойства <code>icon</code> кнопки. Также можно изменить иконку и другие свойства состояния глобально для окна брайзера или только для вкладки. <a href="/en-US/Add-ons/SDK/Low-Level_APIs/ui_button_action#Updating_state">Узнать об этом можно в статье</a>.</p> + +<h2 id="Привязка_панели">Привязка панели</h2> + +<p>Если необходимо привязать к кнопке панель, то используйте <a href="/en-US/Add-ons/SDK/Low-Level_APIs/ui_button_toggle">toggle button</a> API. Этот API такой же как action button API, кроме того, что добавлено булево свтйство <code>checked, </code>которое переключается, когда нажимается конпка. Для связи в панелью нужнопередать кнопку в функцию <a href="https://developer.mozilla.org/en-US/Add-ons/SDK/High-Level_APIs/panel#show(options)"><code>show()</code></a> панели. Для уточнения деталей, изучите документацию <a href="/en-US/Add-ons/SDK/Low-Level_APIs/ui_button_toggle#Attaching_panels_to_buttons">toggle button's documentation</a>.</p> + +<h2 id="Вывод_сложного_контента">Вывод сложного контента</h2> + +<p>Для созлания более сложного пользовательского интерфейса, чем доступен через кнопку, используйте <a href="/en-US/Add-ons/SDK/Low-Level_APIs/ui_toolbar">toolbar</a> API. С этим API вы получите доступ к полным гризонтальным полосам тулбара. Можно добавлять кнопки на панель, и фреймы (<a href="/en-US/Add-ons/SDK/Low-Level_APIs/ui_frame">frames</a>), которые могут содержать HTML, CSS и JavaScript.</p> + +<h2 id="Материал_для_изучения">Материал для изучения</h2> + +<ul> + <li><a href="/en-US/Add-ons/SDK/Low-Level_APIs/ui_button_action">action button reference</a></li> + <li><a href="/en-US/Add-ons/SDK/Low-Level_APIs/ui_button_toggle">toggle button reference</a></li> + <li><a href="/en-US/Add-ons/SDK/Low-Level_APIs/ui_toolbar">toolbar reference</a></li> +</ul> diff --git a/files/ru/mozilla/add-ons/sdk/tutorials/протоколирование/index.html b/files/ru/mozilla/add-ons/sdk/tutorials/протоколирование/index.html new file mode 100644 index 0000000000..d0ab8d6f79 --- /dev/null +++ b/files/ru/mozilla/add-ons/sdk/tutorials/протоколирование/index.html @@ -0,0 +1,61 @@ +--- +title: Протоколирование (Логирование) +slug: Mozilla/Add-ons/SDK/Tutorials/Протоколирование +tags: + - Логирование + - Протоколирование +translation_of: Archive/Add-ons/Add-on_SDK/Tutorials/Logging +--- +<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}}{{AddonSidebar}}</p> + +<div class="note"><span>Перед использованием, вам нужно изучить <a href="/en-US/docs/Mozilla/Add-ons/SDK/Tutorials/Getting_Started_%28jpm%29">основы <code>jpm</code></a>. </span></div> + +<p><a href="https://developer.mozilla.org/en/DOM/console">Консоль для DOM-объекта</a> полезна для отладки JavaScript. Так как DOM-объекты недоступны для главного кода дополнения (add-on), то SDK предоставляет свой собственный глобальный <code>объект</code> <code>"консоль" (console)</code> с большинством таких же методов, как и у DOM-<code>консоли</code>, включая методы для протоколирвоания ошибок (error), предупреждений (warning) или информационных сообщений. Для доступа к консоли не нужно получать что-либо, используя <code>require()</code>. Она уже доступна автоматически.</p> + +<p>Метод <code>console.log()</code> выводит информационное сообщение:</p> + +<pre class="brush: js">console.log("Hello World"); +</pre> + +<p>Попробуйте:</p> + +<ul> + <li>создайте новую папку и перейдите в неё</li> + <li>выполните jpm init со значениями по умолчанию</li> + <li>откройте "index.js" и добавьте строку, указанную в примере выше</li> + <li>выполните <code>jpm run</code></li> +</ul> + +<p>Firefox запустится, и в терминале, где вы ввели <code>jpm run</code>, появится следующая строка:</p> + +<pre>info: Hello World! +</pre> + +<h2 id="Консоль_в_скриптах_Content_Scripts"><code>Консоль</code> в скриптах <code>Content Scripts</code></h2> + +<p>Вы можете использовать консоль в скриптах <code><a href="/en-US/Add-ons/SDK/Guides/Content_Scripts">content scripts</a></code> так же, как и вашем главном коде дополнения. Следующий аддон (add-on) выведет в лог HTML-содержимое каждой закладки, загруженной пользователем, используя <code>console.log()</code> изнутри скрипта <code>content script</code>:</p> + +<pre class="brush: js">require("sdk/tabs").on("ready", function(tab) { + tab.attach({ + contentScript: "console.log(document.body.innerHTML);" + }); +}); +</pre> + +<h2 id="Консоль_Output">Консоль Output</h2> + +<p>Если вы запускаете дополнение из терминала (например, выполня <code>jpm run</code> или <code>jpm test</code>), тогда сообщения консоли появятся в этом же терминале.</p> + +<p>Если вы установили расширение в Firefox тогде сообщения появятся в <a href="/en-US/docs/Tools/Browser_Console">консоли браузера</a> Firefox.</p> + +<p>Но обратите внимание, что <strong>по умолчанию вызовы <code>console.log()</code> не отобразят ничего в Error Console для любых установленных дополнений</strong>. Это правило работает и для дополнений, установленных с использованием Add-on Builder, и для установленных с помощью утилит, таких как <a href="https://addons.mozilla.org/en-US/firefox/addon/autoinstaller/">Extension Auto-installer</a>.</p> + +<p>Смотрите <a href="/en-US/Add-ons/SDK/Tools/console#Logging_Levels">"Уровни логирования"</a> в справочной документации для более подробной информации.</p> + +<h2 id="Дальнейшее_изучение">Дальнейшее изучение</h2> + +<p>Полное <code>API консоли</code> смотри в <a href="/en-US/Add-ons/SDK/Tools/console">API-справочнике</a>.</p> diff --git a/files/ru/mozilla/add-ons/sdk/проба/index.html b/files/ru/mozilla/add-ons/sdk/проба/index.html new file mode 100644 index 0000000000..987a420410 --- /dev/null +++ b/files/ru/mozilla/add-ons/sdk/проба/index.html @@ -0,0 +1,14 @@ +--- +title: Builder +slug: Mozilla/Add-ons/SDK/проба +translation_of: Archive/Add-ons/Add-on_SDK/Builder +--- +<p>The Add-on Builder was a web-based development environment that allowed developers to create add-ons using the SDK APIs, but without needing to use the <code>cfx</code> command line tool. It was retired on April 1, 2014, and the "builder.addons.mozilla.org" domain now redirects to this page.<br> + <br> + If you have only used the SDK through the Builder, you already know most of what you need to know to develop using just the SDK. The <a href="/en-US/Add-ons/SDK/High-Level_APIs">high-level</a> and <a href="/en-US/Add-ons/SDK/Low-Level_APIs">low-level</a> APIs used for Builder add-ons are exactly the same for Builder and SDK. To switch to the SDK:</p> + +<ul> + <li><a href="/en-US/Add-ons/SDK/Tutorials/Installation">install the SDK locally</a></li> + <li>get to know the cfx command line tool, with this <a href="/en-US/Add-ons/SDK/Tutorials/Getting_started">introductory walkthrough</a> and the <a href="/en-US/Add-ons/SDK/Tools/cfx">detailed <code>cfx</code> reference</a></li> + <li>get to know the <a href="/en-US/Add-ons/SDK/Tools/package_json">package.json</a> file used to configure attributes of your add-on</li> +</ul> diff --git a/files/ru/mozilla/add-ons/webextensions/anatomy_of_a_webextension/index.html b/files/ru/mozilla/add-ons/webextensions/anatomy_of_a_webextension/index.html new file mode 100644 index 0000000000..3ca9e8bae6 --- /dev/null +++ b/files/ru/mozilla/add-ons/webextensions/anatomy_of_a_webextension/index.html @@ -0,0 +1,148 @@ +--- +title: Анатомия Расширения +slug: Mozilla/Add-ons/WebExtensions/Anatomy_of_a_WebExtension +tags: + - Расширение + - веб расширение +translation_of: Mozilla/Add-ons/WebExtensions/Anatomy_of_a_WebExtension +--- +<p>{{AddonSidebar}}</p> + +<p><span class="notranslate">Расширение состоит из набора файлов, упакованных для распространения и установки.</span> <span class="notranslate"> В этой статье мы быстро рассмотрим файлы, которые могут присутствовать в расширении.</span></p> + +<h2 id="manifest.json">manifest.json</h2> + +<p><span class="notranslate">Это единственный файл, который должен присутствовать в каждом расширении.</span> <span class="notranslate"> Он содержит основные метаданные, такие как его имя, версию и требуемые разрешения.</span> <span class="notranslate"> Он также предоставляет указатели на другие файлы в расширении.</span></p> + +<p><span class="notranslate">Этот манифест также может содержать указатели на несколько других типов файлов:</span></p> + +<ul> + <li><a href="https://developer.mozilla.org/ru/docs/Mozilla/Add-ons/WebExtensions/Anatomy_of_a_WebExtension#Background_scripts">Background pages</a>: <span class="notranslate">Реализует долгоиграющую логику.</span></li> + <li><span class="notranslate">Иконки для расширения и любых кнопок, которые оно может определить.</span></li> + <li><a href="https://developer.mozilla.org/ru/docs/Mozilla/Add-ons/WebExtensions/Anatomy_of_a_WebExtension#Sidebars_popups_options_pages">Sidebars, popups, and options pages</a>: <span class="notranslate">HTML-документы, которые предоставляют содержимое для различных компонентов пользовательского интерфейса.</span></li> + <li><a href="https://developer.mozilla.org/ru/docs/Mozilla/Add-ons/WebExtensions/Anatomy_of_a_WebExtension#Content_scripts">Content scripts</a>: <span class="notranslate">JavaScript сценарии вашего расширения, которые будут исполняться на веб-страницах.</span></li> + <li><a href="https://developer.mozilla.org/ru/docs/Mozilla/Add-ons/WebExtensions/Anatomy_of_a_WebExtension#Web_accessible_resources">Web-accessible resources</a>: Делает контент вашего расширения видимым для веб-страниц и скриптов.</li> +</ul> + +<p><br> + <img alt="" src="https://mdn.mozillademos.org/files/13669/webextension-anatomy.png" style="display: block; height: 581px; margin-left: auto; margin-right: auto; width: 600px;"></p> + +<p><span class="notranslate">Для получения подробной информации см. справочную страницу </span> <a href="https://developer.mozilla.org/ru/docs/Mozilla/Add-ons/WebExtensions/manifest.json">manifest.json</a></p> + +<p><span class="notranslate">Помимо ссылок, указанных в манифесте, расширение может включать дополнительные</span> <a href="https://developer.mozilla.org/ru/docs/Mozilla/Add-ons/WebExtensions/Anatomy_of_a_WebExtension#Extension_pages">веб-страницы расширения</a><span class="notranslate"> с поддерживающимися файлами.</span></p> + +<h2 id="Фоновые_скрипты">Фоновые скрипты</h2> + +<p><span class="notranslate">Расширения часто должны поддерживать долгосрочное состояние или выполнять долгосрочные операции независимо от срока жизни любой конкретной веб-страницы или окна браузера.</span> <span class="notranslate"> Для этого нужны фоновые сценарии.</span></p> + +<p><span class="notranslate">Фоновые сценарии загружаются сразу после загрузки расширения и остаются загруженными до тех пор, пока расширение не будет отключено или удалено.</span> <span class="notranslate"> Вы можете использовать любой</span> <a href="https://developer.mozilla.org/ru/docs/Mozilla/Add-ons/WebExtensions/API">API расширений</a> <span class="notranslate">в сценарии, если вы запросили необходимые </span><a href="https://developer.mozilla.org/ru/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions">разрешения</a>.</p> + +<h3 id="Спецификации_фоновых_скриптов">Спецификации фоновых скриптов</h3> + +<p><span class="notranslate">Вы можете включить фоновый скрипт, используя <code>background</code> ключ в «manifest.json»:</span></p> + +<pre class="brush: json">// manifest.json + +"background": { + "scripts": ["background-script.js"] +}</pre> + +<p><span class="notranslate">Вы можете указать несколько фоновых сценариев: если вы это сделаете, они выполняются в том же контексте, как и несколько сценариев, загруженных на одной веб-странице.</span></p> + +<p>Вместо указания <span class="notranslate">несколько фоновых сценариев</span> выможете указать фоновую страницу, которая так же преимущества поддержки ES6 модулей:</p> + +<p style="margin-bottom: 0em;"><strong>manifest.json</strong></p> + +<pre class="brush: json line-numbers language-json"><code class="language-json"><span class="comment token">// manifest.json</span> + +<span class="key token">"background":</span> <span class="punctuation token">{</span> + <span class="key token">"page":</span> <span class="string token">"background-page.html"</span> +<span class="punctuation token">}</span></code></pre> + +<p style="margin-bottom: 0em;"><strong>background-page.html</strong></p> + +<pre class="brush: html line-numbers language-html"><code class="language-html"><span class="doctype token"><!DOCTYPE html></span> +<span class="tag token"><span class="tag token"><span class="punctuation token"><</span>html</span> <span class="attr-name token">lang</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>en<span class="punctuation token">"</span></span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>head</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>meta</span> <span class="attr-name token">charset</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>utf-8<span class="punctuation token">"</span></span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>script</span> <span class="attr-name token">type</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>module<span class="punctuation token">"</span></span> <span class="attr-name token">src</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>background-script.js<span class="punctuation token">"</span></span><span class="punctuation token">></span></span><span class="tag token"><span class="tag token"><span class="punctuation token"></</span>script</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>head</span><span class="punctuation token">></span></span> +<span class="tag token"><span class="tag token"><span class="punctuation token"></</span>html</span><span class="punctuation token">></span></span></code></pre> + +<h3 id="Окружение_фоновых_скриптов">Окружение фоновых скриптов</h3> + +<h4 id="DOM_APIs">DOM APIs</h4> + +<p>Фоновые скрипты запускаются в пространстве специальной страницы, называемой фоновой. Это дает им доступ к глобальному <code><a href="/en-US/docs/Web/API/Window">window</a></code> объекту, а так же ко всем его DOM APIs.</p> + +<h4 id="WebExtension_APIs">WebExtension APIs</h4> + +<p>Фоновые скрипты могут использовать любые <a href="https://developer.mozilla.org/ru/docs/Mozilla/Add-ons/WebExtensions/API">API расширений</a>, если расширение имеет необходимые <a href="https://developer.mozilla.org/ru/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions">разрешения</a>.</p> + +<h4 id="Многоцелевой_доступ">Многоцелевой доступ</h4> + +<p>Фоновые скрипты могут осуществлять XHR запросы к любому домену, если расширение имеет <a href="https://developer.mozilla.org/ru/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions">host разрешения</a>.</p> + +<h4 id="Web-содержимое">Web-содержимое</h4> + +<p>Фоновые скрипты не получают прямого доступа к веб-страницам. Однако они могут загружать <a href="https://developer.mozilla.org/ru/docs/Mozilla/Add-ons/WebExtensions/Content_scripts">скрипты содержимого</a> на веб-страницы и <a href="https://developer.mozilla.org/ru/docs/Mozilla/Add-ons/WebExtensions/Content_scripts#Communicating_with_background_scripts">взаимодействовать с этими скриптами с помощью API передачи сообщений</a>.</p> + +<h4 id="Политика_безопастности_содержимого">Политика безопастности содержимого</h4> + +<p>Фоновые скрипты ограничены в выполнении потенциально опасных операций, таких как <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval">eval()</a></code>, через политику безопасности содержимого. Подробнее см. <a href="https://developer.mozilla.org/ru/docs/Mozilla/Add-ons/WebExtensions/Content_Security_Policy">Content Security Policy</a>.</p> + +<h2 id="Боковые_панели_(sidebar)_всплывающие_окна_(popup)_страницы_настроек">Боковые панели (sidebar), всплывающие окна (popup), страницы настроек</h2> + +<p>Ваше расширение может иметь разнообразные компоненты интерфейса, определённые в HTML документах:</p> + +<ul> + <li><font color="#0b0116"><a href="https://developer.mozilla.org/ru/docs/Mozilla/Add-ons/WebExtensions/user_interface/Sidebars">Боковая панель (sidebar</a></font>) - это панель, отображаемая в окне браузера с левой строны, рядом с веб-страницей</li> + <li><a href="https://developer.mozilla.org/ru/docs/Mozilla/Add-ons/WebExtensions/user_interface/Popups">Всплывающие окна (popup</a>) - диалоговое окно, отображаемое по клику на <a href="https://developer.mozilla.org/ru/docs/Mozilla/Add-ons/WebExtensions/user_interface/Browser_action">кнопке</a> на <a href="https://developer.mozilla.org/ru/docs/Mozilla/Add-ons/WebExtensions/user_interface/Browser_action">панели инструментов</a> или в адресной строке</li> + <li><a href="https://developer.mozilla.org/ru/docs/Mozilla/Add-ons/WebExtensions/user_interface/Options_pages">Страница настроек</a> открывается, когда пользователь обращается к настройкам расширения на странице менеджера расширений.</li> +</ul> + +<p>Для каждого из этих компонентов вы создаете HTML файл и помещаете специальную информацию в <a href="https://developer.mozilla.org/ru/docs/Mozilla/Add-ons/WebExtensions/manifest.json">manifest.json</a>. HTML файл может в себя включать CSS и JavaScript файлы, как и любая web-страница.</p> + +<p>Всё это типы <a href="https://developer.mozilla.org/ru/docs/Mozilla/Add-ons/WebExtensions/user_interface/Extension_pages">веб-страниц расширения</a>, и, в отличие от нормальных веб-страниц, ваш JavaScript может использовать все привелегии WebExtension APIs, как и ваши фоновые скрипты. Они даже могут получить доступ к переменным в фоновой странице, используя {{WebExtAPIRef("runtime.getBackgroundPage()")}}.</p> + +<h2 id="Веб-страницы_расширения">Веб-страницы расширения</h2> + +<p>Вы также можете включить HTML документы в ваше расширение, даже если они не будут включены в какой-либо существующий компонент пользовательского интерфейса. В отличие от документов, которые вы можете предоставить для боковых панелей, всплывающих окон или страниц настроек, эти документы не содержатся в manifest.json. Однако, они также имеют такой же доступ к WebExtension APIs, как и фоновые скрипты.</p> + +<p>Вы можете загрузить такую страницу, используя {{WebExtAPIRef("windows.create()")}} или {{WebExtAPIRef("tabs.create()")}}.</p> + +<p>Подробнее см. <a href="https://developer.mozilla.org/ru/docs/Mozilla/Add-ons/WebExtensions/user_interface/Extension_pages">Extension pages</a>.</p> + +<h2 id="Встраиваемые_скрипты">Встраиваемые скрипты</h2> + +<p>Используйте встраиваемые скрипты для доступа и изменения веб-страниц. Встраиваемые скрипты загружаются в веб-страницу и исполняются в контексте данной конкретной страницы.</p> + +<p>Встраиваемые скрипты предоставляются расширением; этим они отличаются от скриптов, загруженных самой веб-страницей, включая тех, что загружены с помощью {{HTMLElement("script")}} элемента веб-страницы.</p> + +<p>Встраиваемые скрипты имеют доступ и могут манипулировать DOM, как и обычные скрипты, загруженные веб-страницей.</p> + +<p>В отличие от обычных скриптов, они могут:</p> + +<ul> + <li>Осуществлять XHR запросы.</li> + <li>Использовать часть <a href="https://developer.mozilla.org/ru/docs/Mozilla/Add-ons/WebExtensions/API">API расширений</a>.</li> + <li>Обмениваться сообщениями с их фоновыми скриптами и таким образом иметь доступ ко всему WebExtension APIs.</li> +</ul> + +<p>Встраиваемые скрипты не могут напрямую взаимодействовать с обычными скриптами на странице, но они могут обмениваться сообщениями с помощью стандартного <code><a href="/en-US/docs/Web/API/Window/postMessage">window.postMessage()</a></code> API.</p> + +<p>Обычно, когда мы говорим о встраиваемых скриптах, мы отсылаемся к JavaScript, но вы так же можете внедрить CSS в веб-страницы, используя этот же механизм.</p> + +<p>Подробнее см. <a href="https://developer.mozilla.org/ru/docs/Mozilla/Add-ons/WebExtensions/Content_scripts">content scripts</a>.</p> + +<h2 id="Веб-доступные_ресурсы"><span class="tlid-translation translation"><span title="">Веб-доступные ресурсы</span></span></h2> + +<p><span class="tlid-translation translation"><span title="">Веб-доступные ресурсы</span></span> - это ресурсы вроде изображений, HTML, CSS и JavaScript, которые вы включаете в расширение и хотите сделать доступными для встраиваемых скриптов и оригинальных скриптов веб-страницы. Такие ресурсы могут быть доступны скриптам через специальную URI схему.</p> + +<p>Например, если встраиваемый скрипт хочет добавить какие-либо изображения в веб-страницу, вы можете включить эти изображения в расширение и сделать их веб-доступными. Тогда встраиваемый скрипт может создать и добавить <code><a href="/en-US/docs/Web/HTML/Element/img">img</a></code> тэги, которые будут ссылаться на эти изображения через <code>src</code> атрибут.</p> + +<p>Подробнее см. <a href="https://developer.mozilla.org/ru/docs/Mozilla/Add-ons/WebExtensions/manifest.json/web_accessible_resources">web_accessible_resources</a> секцию manifest.json.</p> + +<p> </p> + +<p> </p> diff --git a/files/ru/mozilla/add-ons/webextensions/api/cookies/cookie/index.html b/files/ru/mozilla/add-ons/webextensions/api/cookies/cookie/index.html new file mode 100644 index 0000000000..9191b3017a --- /dev/null +++ b/files/ru/mozilla/add-ons/webextensions/api/cookies/cookie/index.html @@ -0,0 +1,107 @@ +--- +title: cookies.Cookie +slug: Mozilla/Add-ons/WebExtensions/API/cookies/Cookie +tags: + - API + - Cookies + - cookie + - Дополнения + - Расширения + - Справка + - данные +translation_of: Mozilla/Add-ons/WebExtensions/API/cookies/Cookie +--- +<div>{{AddonSidebar()}}</div> + +<p>Тип <code>Cookie</code> из {{WebExtAPIRef("cookies")}} API представляет собой информацию о HTTP cookie.</p> + +<h2 id="Тип">Тип</h2> + +<p>Значения этого типа - объекты, которые могут содержать следующие свойства:</p> + +<dl class="reference-values"> + <dt><code>name</code></dt> + <dd><code>string</code> - содержит имя cookie.</dd> + <dt><code>value</code></dt> + <dd><code>string</code> - содержит значение cookie.</dd> + <dt><code>domain</code></dt> + <dd><code>string</code> - содержит домен, которому принадлежит cookie (например, "www.google.com", "example.com").</dd> + <dt><code>hostOnly</code></dt> + <dd><code>boolean</code> - <code>true</code> если cookie является host-only (то есть запрашивающий хост должен в точности совпадать с доменом cookie), в ином случае <code>false</code>.</dd> + <dt><code>path</code></dt> + <dd><code>string</code> - содержит path cookie.</dd> + <dt><code>secure</code></dt> + <dd><code>boolean</code> - <code>true</code>, если cookie помечен как secure (то есть его область действия ограничена безопасными каналами, обычно HTTPS), в ином случае <code>false</code>.</dd> + <dt><code>httpOnly</code></dt> + <dd><code>boolean</code> - <code>true</code> если cookie помечен как HttpOnly (то есть он недоступен для клиентских скриптов), иначе <code>false</code>.</dd> + <dt><code>session</code></dt> + <dd><code>boolean</code> - <code>true</code> если cookie является сессионным, <code>false</code> если cookie является постоянным с указанным временем жизни.</dd> + <dt><code>expirationDate</code>{{optional_inline}}</dt> + <dd><code>number</code> - содержит срок годности cookie, который представляется количеством секунд с начала UNIX-эры. Отсутствует для сессионных cookie.</dd> + <dt><code>storeId</code></dt> + <dd><code>string</code> - представляет собой ID хранилища, в котором хранится данный cookie, как указано в соответствии с {{WebExtAPIRef("cookies.getAllCookieStores()")}}.</dd> +</dl> + +<h2 id="Совместимость_с_браузерами">Совместимость с браузерами</h2> + +<p class="hidden">The compatibility table in this page is generated from structured data. If you'd like to contribute to the data, please check out <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> and send us a pull request.</p> + +<p>{{Compat("webextensions.api.cookies.Cookie")}}</p> + +<h2 id="Примеры">Примеры</h2> + +<p>В большинстве методов из cookies API объекты типа <code>Cookie</code> используются как входные параметры методов, либо же как возвращаемые значения. К примеру, вызов {{WebExtAPIRef("cookies.getAll()")}} возвращает массив объектов типа <code>Cookie</code>.</p> + +<p>В примере ниже мы запрашиваем все cookie, а затем выводим в лог некоторые из полей полученных <code>Cookie</code> объектов:</p> + +<pre class="brush: js">function logCookies(cookies) { + for (cookie of cookies) { + console.log(`Domain: ${cookie.domain}`); + console.log(`Name: ${cookie.name}`); + console.log(`Value: ${cookie.value}`); + console.log(`Persistent: ${!cookie.session}`); + } +} + +var gettingAll = browser.cookies.getAll({}); +gettingAll.then(logCookies);</pre> + +<p>{{WebExtExamples}}</p> + +<div class="note"><strong>Примечание</strong> + +<p>Это API основано на API Chromiumа <code><a href="https://developer.chrome.com/extensions/cookies#type-Cookie">chrome.cookies</a></code>. Эта документация основана на <a href="https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/cookies.json"><code>cookies.json</code></a> из кода Chromium.</p> + +<p>Информация о совместимости Microsoft Edge предоставлена корпорацией Microsoft и включена здесь под лицензией Creative Commons Attribution 3.0 United States License.</p> +</div> + +<div class="hidden"> +<pre>// Copyright 2015 The Chromium Authors. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +</pre> +</div> diff --git a/files/ru/mozilla/add-ons/webextensions/api/cookies/index.html b/files/ru/mozilla/add-ons/webextensions/api/cookies/index.html new file mode 100644 index 0000000000..a31f300edf --- /dev/null +++ b/files/ru/mozilla/add-ons/webextensions/api/cookies/index.html @@ -0,0 +1,156 @@ +--- +title: cookies +slug: Mozilla/Add-ons/WebExtensions/API/cookies +tags: + - API + - Add-ons + - Cookies + - Extensions + - Interface + - NeedsTranslation + - Non-standard + - Reference + - TopicStub + - WebExtensions +translation_of: Mozilla/Add-ons/WebExtensions/API/cookies +--- +<div>{{AddonSidebar}}</div> + +<p>Позволяет WebExtensions получить и установить куки ,а также сообщить об их изменении.</p> + +<p>Для использования этого API,вам нужно предоставить доступ <a href="/en-US/Add-ons/WebExtensions/manifest.json/permissions#API_permissions">API permission</a> в вашем файле <a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json">manifest.json</a>,а также <a href="/en-US/Add-ons/WebExtensions/manifest.json/permissions#Host_permissions">host permissions</a> для тех сайтов чьи куки вам нужны для доступа.Смотрите <a href="/en-US/Add-ons/WebExtensions/API/cookies#Permissions">cookie Permissions</a>.</p> + +<h2 id="Types">Types</h2> + +<dl> + <dt>{{WebExtAPIRef("cookies.Cookie")}}</dt> + <dd>Предоставляет информацию о HTTP cookie</dd> + <dt>{{WebExtAPIRef("cookies.CookieStore")}}</dt> + <dd>Represents a cookie store in the browser.</dd> + <dt>{{WebExtAPIRef("cookies.OnChangedCause")}}</dt> + <dd>Represents the reason a cookie changed.</dd> +</dl> + +<h2 id="Methods">Methods</h2> + +<dl> + <dt>{{WebExtAPIRef("cookies.get()")}}</dt> + <dd>Запрашивает информацию об одном кукис.</dd> + <dt>{{WebExtAPIRef("cookies.getAll()")}}</dt> + <dd>Выдает все кукис которые подходят установленному фильтру.</dd> + <dt>{{WebExtAPIRef("cookies.set()")}}</dt> + <dd>Устанавливает кукис с заданной информацией;в том случае если подобный кукис был информация будет перезаписана.</dd> + <dt>{{WebExtAPIRef("cookies.remove()")}}</dt> + <dd>Удаляет кукис по имени.</dd> + <dt>{{WebExtAPIRef("cookies.getAllCookieStores()")}}</dt> + <dd>Список всех существующих куки</dd> +</dl> + +<h2 id="Event_handlers">Event handlers</h2> + +<dl> + <dt>{{WebExtAPIRef("cookies.onChanged")}}</dt> + <dd>Происходит когда кукис задается или меняется.</dd> +</dl> + +<h2 id="Permissions">Permissions</h2> + +<p>In order to use this API, an add-on must specify the "cookies" <a href="/en-US/Add-ons/WebExtensions/manifest.json/permissions#API_permissions">API permission</a> in its manifest, along with <a href="/en-US/Add-ons/WebExtensions/manifest.json/permissions#Host_permissions">host permissions</a> for any sites for which it wishes to access cookies. The add-on may read or write any cookies which could be read or written by a URL matching the host permissions. For example:</p> + +<dl> + <dt><code>http://*.example.com/</code></dt> + <dd> + <p>An add-on with this host permission may:</p> + + <ul> + <li>Read a non-secure cookie for <code>www.example.com</code>, with any path.</li> + <li>Write a secure or non-secure cookie for <code>www.example.com</code>, with any path.</li> + </ul> + + <p>It may <em>not</em>:</p> + + <ul> + <li>Read a secure cookie for <code>www.example.com</code>.</li> + </ul> + </dd> + <dt><code>http://www.example.com/</code></dt> + <dd> + <p>An add-on with this host permission may:</p> + + <ul> + <li>Read a non-secure cookie for <code>www.example.com</code>, with any path.</li> + <li>Read a non-secure cookie for <code>.example.com</code>, with any path.</li> + <li>Write a secure or non-secure cookie for <code>www.example.com</code> with any path.</li> + <li>Write a secure or non-secure cookie for <code>.example.com</code> with any path.</li> + </ul> + + <p>It may <em>not</em>:</p> + + <ul> + <li>Read or write a cookie for <code>foo.example.com</code>.</li> + <li>Read or write a cookie for <code>foo.www.example.com</code>.</li> + </ul> + </dd> + <dt><code>*://*.example.com/</code></dt> + <dd> + <p>An add-on with this host permission may:</p> + + <ul> + <li>Read or write a secure or non-secure cookie for <code>www.example.com</code> with any path.</li> + </ul> + </dd> +</dl> + +<h2 id="Browser_compatibility">Browser compatibility</h2> + +<p>{{Compat("webextensions.api.cookies")}}</p> + +<div class="hidden note"> +<p>The "Chrome incompatibilities" section is included from <a href="https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Chrome_incompatibilities"> https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Chrome_incompatibilities</a> using the <a href="/en-US/docs/Template:WebExtChromeCompat">WebExtChromeCompat</a> macro.</p> + +<p>If you need to update this content, edit <a href="https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Chrome_incompatibilities">https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Chrome_incompatibilities</a>, then shift-refresh this page to see your changes.</p> +</div> + +<h3 id="Edge_incompatibilities">Edge incompatibilities</h3> + +<p>Promises are not supported in Edge. Use callbacks instead.</p> + +<p>{{WebExtExamples("h2")}}</p> + +<div class="note"><strong>Acknowledgements</strong> + +<p>This API is based on Chromium's <a href="https://developer.chrome.com/extensions/cookies"><code>chrome.cookies</code></a> API. This documentation is derived from <a href="https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/cookies.json"><code>cookies.json</code></a> in the Chromium code.</p> + +<p>Microsoft Edge compatibility data is supplied by Microsoft Corporation and is included here under the Creative Commons Attribution 3.0 United States License.</p> +</div> + +<div class="hidden"> +<pre>// Copyright 2015 The Chromium Authors. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +</pre> +</div> diff --git a/files/ru/mozilla/add-ons/webextensions/api/downloads/index.html b/files/ru/mozilla/add-ons/webextensions/api/downloads/index.html new file mode 100644 index 0000000000..735dab43d5 --- /dev/null +++ b/files/ru/mozilla/add-ons/webextensions/api/downloads/index.html @@ -0,0 +1,123 @@ +--- +title: downloads +slug: Mozilla/Add-ons/WebExtensions/API/downloads +translation_of: Mozilla/Add-ons/WebExtensions/API/downloads +--- +<div>{{AddonSidebar}}</div> + +<p><span class="tlid-translation translation" lang="ru"><span title="">Позволяет расширениям взаимодействовать с менеджером загрузки браузера.</span> <span title="">Этот модуль API можно использовать для загрузки, отмены, приостановки, возобновления загрузки файлов и отображения загруженных файлов в файловом менеджере.</span></span></p> + +<p>Для использования этого API вам необходимо указать "downloads" <a href="/en-US/Add-ons/WebExtensions/manifest.json/permissions#API_permissions">API permission</a> в вашем <a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json">manifest.json</a> файле.</p> + +<h2 id="Types">Types</h2> + +<dl> + <dt>{{WebExtAPIRef("downloads.FilenameConflictAction")}}</dt> + <dd><span class="tlid-translation translation" lang="ru"><span title="">Определяет действия в случае, если имя загружаемого файла конфликтует с именем существующего файла</span></span>.</dd> + <dt>{{WebExtAPIRef("downloads.InterruptReason")}}</dt> + <dd>Defines a set of possible reasons why a download was interrupted.</dd> + <dt>{{WebExtAPIRef("downloads.DangerType")}}</dt> + <dd>Defines a set of common warnings of possible dangers associated with downloadable files.</dd> + <dt>{{WebExtAPIRef("downloads.State")}}</dt> + <dd>Defines different states that a current download can be in.</dd> + <dt>{{WebExtAPIRef("downloads.DownloadItem")}}</dt> + <dd>Represents a downloaded file.</dd> + <dt>{{WebExtAPIRef("downloads.StringDelta")}}</dt> + <dd>Represents the difference between two strings.</dd> + <dt>{{WebExtAPIRef("downloads.DoubleDelta")}}</dt> + <dd>Represents the difference between two doubles.</dd> + <dt>{{WebExtAPIRef("downloads.BooleanDelta")}}</dt> + <dd>Represents the difference between two booleans.</dd> + <dt>{{WebExtAPIRef("downloads.DownloadTime")}}</dt> + <dd>Represents the time a download took to complete.</dd> + <dt>{{WebExtAPIRef("downloads.DownloadQuery")}}</dt> + <dd>Defines a set of parameters that can be used to search the downloads manager for a specific set of downloads.</dd> +</dl> + +<h2 id="Functions">Functions</h2> + +<dl> + <dt>{{WebExtAPIRef("downloads.download()")}}</dt> + <dd>Downloads a file, given its URL and other optional preferences.</dd> + <dt>{{WebExtAPIRef("downloads.search()")}}</dt> + <dd>Queries the {{WebExtAPIRef("downloads.DownloadItem", "DownloadItems")}} available in the browser's downloads manager, and returns those that match the specified search criteria.</dd> + <dt>{{WebExtAPIRef("downloads.pause()")}}</dt> + <dd>Pauses a download.</dd> + <dt>{{WebExtAPIRef("downloads.resume()")}}</dt> + <dd>Resumes a paused download.</dd> + <dt>{{WebExtAPIRef("downloads.cancel()")}}</dt> + <dd>Cancels a download.</dd> + <dt>{{WebExtAPIRef("downloads.getFileIcon()")}}</dt> + <dd>Retrieves an icon for the specified download.</dd> + <dt>{{WebExtAPIRef("downloads.open()")}}</dt> + <dd>Opens the downloaded file with its associated application.</dd> + <dt>{{WebExtAPIRef("downloads.show()")}}</dt> + <dd>Opens the platform's file manager application to show the downloaded file in its containing folder.</dd> + <dt>{{WebExtAPIRef("downloads.showDefaultFolder()")}}</dt> + <dd>Opens the platform's file manager application to show the default downloads folder.</dd> + <dt>{{WebExtAPIRef("downloads.erase()")}}</dt> + <dd>Erases matching {{WebExtAPIRef("downloads.DownloadItem", "DownloadItems")}} from the browser's download history, without deleting the downloaded files from disk.</dd> + <dt>{{WebExtAPIRef("downloads.removeFile()")}}</dt> + <dd>Removes a downloaded file from disk, but not from the browser's download history.</dd> + <dt>{{WebExtAPIRef("downloads.acceptDanger()")}}</dt> + <dd>Prompts the user to accept or cancel a dangerous download.</dd> + <dt>{{WebExtAPIRef("downloads.drag()")}}</dt> + <dd>Initiates dragging the downloaded file to another application.</dd> + <dt>{{WebExtAPIRef("downloads.setShelfEnabled()")}}</dt> + <dd>Enables or disables the gray shelf at the bottom of every window associated with the current browser profile. The shelf will be disabled as long as at least one extension has disabled it.</dd> +</dl> + +<h2 id="Events">Events</h2> + +<dl> + <dt>{{WebExtAPIRef("downloads.onCreated")}}</dt> + <dd>Fires with the {{WebExtAPIRef("downloads.DownloadItem", "DownloadItem")}} object when a download begins.</dd> + <dt>{{WebExtAPIRef("downloads.onErased")}}</dt> + <dd>Fires with the <code>downloadId</code> when a download is erased from history.</dd> + <dt>{{WebExtAPIRef("downloads.onChanged")}}</dt> + <dd>When any of a {{WebExtAPIRef("downloads.DownloadItem", "DownloadItem")}}'s properties except <code>bytesReceived</code> changes, this event fires with the <code>downloadId</code> and an object containing the properties that changed.</dd> +</dl> + +<h2 id="Browser_compatibility">Browser compatibility</h2> + +<p>{{Compat("webextensions.api.downloads")}}</p> + +<p>{{WebExtExamples("h2")}}</p> + +<div class="note"><strong>Acknowledgements</strong> + +<p>This API is based on Chromium's <a href="https://developer.chrome.com/extensions/downloads"><code>chrome.downloads</code></a> API.</p> + +<p>Microsoft Edge compatibility data is supplied by Microsoft Corporation and is included here under the Creative Commons Attribution 3.0 United States License.</p> +</div> + +<div class="hidden"> +<pre class="notranslate">// Copyright 2015 The Chromium Authors. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +</pre> +</div> diff --git a/files/ru/mozilla/add-ons/webextensions/api/index.html b/files/ru/mozilla/add-ons/webextensions/api/index.html new file mode 100644 index 0000000000..6fcf34ce28 --- /dev/null +++ b/files/ru/mozilla/add-ons/webextensions/api/index.html @@ -0,0 +1,53 @@ +--- +title: JavaScript APIs +slug: Mozilla/Add-ons/WebExtensions/API +tags: + - Web-расширение + - Расширение +translation_of: Mozilla/Add-ons/WebExtensions/API +--- +<div>{{AddonSidebar}}</div> + +<div> +<p>WebExtension JavaScript API может быть использован в <a href="/ru/docs/Mozilla/Add-ons/WebExtensions/Anatomy_of_a_WebExtension#%D0%A4%D0%BE%D0%BD%D0%BE%D0%B2%D1%8B%D0%B5_%D1%81%D0%BA%D1%80%D0%B8%D0%BF%D1%82%D1%8B">фоновых скриптах</a> расширения, а так же в любых других документах, поставляемых вместе с расширением, таких как документы во всплывающих окнах после нажатия<a href="/en-US/Add-ons/WebExtensions/User_interface_components#Browser_actions"> </a>кнопок активации расширения <a href="/ru/docs/Mozilla/Add-ons/WebExtensions/user_interface/Browser_action">browser action </a>на панели инструментов<a href="/en-US/Add-ons/WebExtensions/User_interface_components#Browser_actions"> </a>или <a href="/ru/docs/Mozilla/Add-ons/WebExtensions/user_interface/Page_actions">page action</a> в строке адреса, <a href="/ru/docs/Mozilla/Add-ons/WebExtensions/user_interface/Sidebars">боковой панели</a>, <a href="/ru/docs/Mozilla/Add-ons/WebExtensions/user_interface/Options_pages">страницах настроек</a> или <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/chrome_url_overrides">новых открытых вкладках</a>. Некоторые из этих API могут быть доступны на <a href="/ru/docs/Mozilla/Add-ons/WebExtensions/Anatomy_of_a_WebExtension#%D0%92%D1%81%D1%82%D1%80%D0%B0%D0%B8%D0%B2%D0%B0%D0%B5%D0%BC%D1%8B%D0%B5_%D1%81%D0%BA%D1%80%D0%B8%D0%BF%D1%82%D1%8B">встраиваемых в страницу скриптах</a> (см. <a href="/ru/docs/Mozilla/Add-ons/WebExtensions/Content_scripts#WebExtension_APIs">список в руководстве по встраиваемым скриптам</a>).</p> + +<p>Для использования отдельных более продвинутых API, необходимо <a href="/ru/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions">запросить разрешения</a> в manifest.json вашего дополнения.</p> + +<p>Вы можете получить доступ к API, используя пространство имён <code>browser</code>:</p> + +<pre class="brush: js">function logTabs(tabs) { + console.log(tabs); +} + +browser.tabs.query({currentWindow: true}, logTabs);</pre> +</div> + +<div> +<p>Многие API выполняются асинхронно, возвращая <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise">Promise</a></code>:</p> + +<pre class="brush: js">function logCookie(c) { + console.log(c); +} + +function logError(e) { + console.error(e); +} + +var setCookie = browser.cookies.set( + {url: "/"} +); +setCookie.then(logCookie, logError);</pre> +</div> + +<div>Обратите внимание, что это отличается от расширений Google Chrome, которые используют пространство имён <code>chrome</code> вместо <code>browser</code> и колбэки для асинхронных функций вместо промисов. + +<p>Для поддержки портирования, реализация Firefox WebExtensions API так же поддерживает пространство имён <code>chrome</code> и использование колбэков. Это позволяет в большинстве случаев не изменять код, изначально написанный для Chrome.</p> + +<p>Mozilla так же предоставляет полифилл, который позволяет коду, использующему <code>browser</code> и промисы, работать без изменений в Chrome: <a class="external external-icon" href="https://github.com/mozilla/webextension-polyfill">https://github.com/mozilla/webextension-polyfill</a>.</p> + +<p>Microsoft Edge использует пространство имен <code>browser</code>, но ещё не поддерживает, основанный на промисах асинхронный API. В Edge на данный момент асинхронные вызовы API должны использовать колбэки.</p> + +<p>Не все браузеры поддерживают все API: детали см. <a href="/ru/docs/Mozilla/Add-ons/WebExtensions/Browser_support_for_JavaScript_APIs">Browser support for JavaScript APIs</a>.</p> +</div> + +<div>{{SubpagesWithSummaries}}</div> diff --git a/files/ru/mozilla/add-ons/webextensions/api/runtime/getmanifest/index.html b/files/ru/mozilla/add-ons/webextensions/api/runtime/getmanifest/index.html new file mode 100644 index 0000000000..f506e54335 --- /dev/null +++ b/files/ru/mozilla/add-ons/webextensions/api/runtime/getmanifest/index.html @@ -0,0 +1,88 @@ +--- +title: runtime.getManifest() +slug: Mozilla/Add-ons/WebExtensions/API/runtime/getManifest +tags: + - API + - Reference + - WebExtensions + - getManifest + - runtime + - Веб-расширения + - Дополнения + - Нестандартный + - Расширения + - Ссылка + - метод +translation_of: Mozilla/Add-ons/WebExtensions/API/runtime/getManifest +--- +<div>{{AddonSidebar()}}</div> + +<div>Получить весь файл <a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json">manifest.json</a> в виде объекта JavaScript, совместимого с JSON.</div> + +<div></div> + +<h2 id="Синтаксис">Синтаксис</h2> + +<pre class="syntaxbox brush:js">browser.runtime.getManifest() +</pre> + +<h3 id="Параметры">Параметры</h3> + +<p>Нет.</p> + +<h3 id="Возвращаемое_значение">Возвращаемое значение</h3> + +<p><code>object</code> - объект JSON, представляющий манифест.</p> + +<h2 id="Совместимость_с_браузерами">Совместимость с браузерами</h2> + +<p class="hidden">Таблица совместимости на этой странице сгенерирована из структурированных данных. Если Вы хотите дополнить эти данные, пожалуйста, посетите <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> и отправьте нам pull request.</p> + +<p>{{Compat("webextensions.api.runtime.getManifest")}}</p> + +<h2 id="Примеры">Примеры</h2> + +<p>Получить манифест и вывести его свойство "name":</p> + +<pre class="brush: js">var manifest = browser.runtime.getManifest(); +console.log(manifest.name);</pre> + +<p>{{WebExtExamples}}</p> + +<div class="note"><strong>Справка</strong> + +<p>Этот API основан на API Chromium <a href="https://developer.chrome.com/extensions/runtime#method-getManifest"><code>chrome.runtime</code></a>. Настоящая документация унаследована от <a href="https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/runtime.json"><code>runtime.json</code></a> в коде Chromium.</p> + +<p>Данные о совместимости Microsoft Edge предоставлены Корпорацией Microsoft и включены сюда под лицензией Creative Commons Attribution 3.0 United States License.</p> +</div> + +<div class="hidden"> +<pre>// Copyright 2015 The Chromium Authors. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +</pre> +</div> diff --git a/files/ru/mozilla/add-ons/webextensions/api/runtime/index.html b/files/ru/mozilla/add-ons/webextensions/api/runtime/index.html new file mode 100644 index 0000000000..62478e3457 --- /dev/null +++ b/files/ru/mozilla/add-ons/webextensions/api/runtime/index.html @@ -0,0 +1,168 @@ +--- +title: runtime +slug: Mozilla/Add-ons/WebExtensions/API/runtime +tags: + - API + - Add-ons + - Extensions + - Interface + - NeedsTranslation + - Reference + - TopicStub + - WebExtensions + - runtime +translation_of: Mozilla/Add-ons/WebExtensions/API/runtime +--- +<div>{{AddonSidebar}}</div> + +<p><span class="seoSummary">This module provides information about your extension and the environment it's running in.</span></p> + +<p>It also provides messaging APIs enabling you to:</p> + +<ul> + <li>Communicate between different parts of your extension. For advice on choosing between the messaging options, see <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Content_scripts#Choosing_between_one-off_messages_and_connection-based_messaging">Choosing between one-off messages and connection-based messaging</a>.</li> + <li>Communicate with other extensions.</li> + <li>Communicate with native applications.</li> +</ul> + +<h2 id="Types">Types</h2> + +<dl> + <dt>{{WebExtAPIRef("runtime.Port")}}</dt> + <dd>Represents one end of a connection between two specific contexts, which can be used to exchange messages.</dd> + <dt>{{WebExtAPIRef("runtime.MessageSender")}}</dt> + <dd> + <p>Contains information about the sender of a message or connection request.</p> + </dd> + <dt>{{WebExtAPIRef("runtime.PlatformOs")}}</dt> + <dd>Identifies the browser's operating system.</dd> + <dt>{{WebExtAPIRef("runtime.PlatformArch")}}</dt> + <dd>Identifies the browser's processor architecture.</dd> + <dt>{{WebExtAPIRef("runtime.PlatformInfo")}}</dt> + <dd>Contains information about the platform the browser is running on.</dd> + <dt>{{WebExtAPIRef("runtime.RequestUpdateCheckStatus")}}</dt> + <dd>Result of a call to {{WebExtAPIRef("runtime.requestUpdateCheck()")}}.</dd> + <dt>{{WebExtAPIRef("runtime.OnInstalledReason")}}</dt> + <dd>The reason that the {{WebExtAPIRef("runtime.onInstalled")}} event is being dispatched.</dd> + <dt>{{WebExtAPIRef("runtime.OnRestartRequiredReason")}}</dt> + <dd>The reason that the {{WebExtAPIRef("runtime.onRestartRequired")}} event is being dispatched.</dd> +</dl> + +<h2 id="Properties">Properties</h2> + +<dl> + <dt>{{WebExtAPIRef("runtime.lastError")}}</dt> + <dd>This value is set when an asynchronous function has an error condition that it needs to report to its caller.</dd> + <dt>{{WebExtAPIRef("runtime.id")}}</dt> + <dd>The ID of the extension.</dd> +</dl> + +<h2 id="Functions">Functions</h2> + +<dl> + <dt>{{WebExtAPIRef("runtime.getBackgroundPage()")}}</dt> + <dd>Retrieves the <a href="/en-US/docs/Web/API/Window">Window</a> object for the background page running inside the current extension.</dd> + <dt>{{WebExtAPIRef("runtime.openOptionsPage()")}}</dt> + <dd> + <p>Opens your extension's <a href="/en-US/Add-ons/WebExtensions/user_interface/Options_pages">options page</a>.</p> + </dd> + <dt>{{WebExtAPIRef("runtime.getManifest()")}}</dt> + <dd>Gets the complete <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json">manifest.json</a> file, serialized as an object.</dd> + <dt>{{WebExtAPIRef("runtime.getURL()")}}</dt> + <dd>Given a relative path from the <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json">manifest.json</a> to a resource packaged with the extension, returns a fully-qualified URL.</dd> + <dt>{{WebExtAPIRef("runtime.setUninstallURL()")}}</dt> + <dd>Sets a URL to be visited when the extension is uninstalled.</dd> + <dt>{{WebExtAPIRef("runtime.reload()")}}</dt> + <dd>Reloads the extension.</dd> + <dt>{{WebExtAPIRef("runtime.requestUpdateCheck()")}}</dt> + <dd>Checks for updates to this extension.</dd> + <dt>{{WebExtAPIRef("runtime.connect()")}}</dt> + <dd>Establishes a connection from a content script to the main extension process, or from one extension to a different extension.</dd> + <dt>{{WebExtAPIRef("runtime.connectNative()")}}</dt> + <dd> + <div>Connects the extension to a native application on the user's computer.</div> + </dd> + <dt>{{WebExtAPIRef("runtime.sendMessage()")}}</dt> + <dd>Sends a single message to event listeners within your extension or a different extension. Similar to {{WebExtAPIRef('runtime.connect')}} but only sends a single message, with an optional response.</dd> + <dt>{{WebExtAPIRef("runtime.sendNativeMessage()")}}</dt> + <dd>Sends a single message from an extension to a native application.</dd> + <dt>{{WebExtAPIRef("runtime.getPlatformInfo()")}}</dt> + <dd>Returns information about the current platform.</dd> + <dt>{{WebExtAPIRef("runtime.getBrowserInfo()")}}</dt> + <dd>Returns information about the browser in which this extension is installed.</dd> + <dt>{{WebExtAPIRef("runtime.getPackageDirectoryEntry()")}}</dt> + <dd>Returns a DirectoryEntry for the package directory.</dd> +</dl> + +<h2 id="Events">Events</h2> + +<dl> + <dt>{{WebExtAPIRef("runtime.onStartup")}}</dt> + <dd>Fired when a profile that has this extension installed first starts up. This event is not fired when an incognito profile is started.</dd> + <dt>{{WebExtAPIRef("runtime.onInstalled")}}</dt> + <dd>Fired when the extension is first installed, when the extension is updated to a new version, and when the browser is updated to a new version.</dd> + <dt>{{WebExtAPIRef("runtime.onSuspend")}}</dt> + <dd>Sent to the event page just before the extension is unloaded. This gives the extension an opportunity to do some cleanup.</dd> + <dt>{{WebExtAPIRef("runtime.onSuspendCanceled")}}</dt> + <dd>Sent after {{WebExtAPIRef("runtime.onSuspend")}} to indicate that the extension won't be unloaded after all.</dd> + <dt>{{WebExtAPIRef("runtime.onUpdateAvailable")}}</dt> + <dd>Fired when an update is available, but isn't installed immediately because the extension is currently running.</dd> + <dt>{{WebExtAPIRef("runtime.onBrowserUpdateAvailable")}} {{deprecated_inline}}</dt> + <dd>Fired when an update for the browser is available, but isn't installed immediately because a browser restart is required.</dd> + <dt>{{WebExtAPIRef("runtime.onConnect")}}</dt> + <dd>Fired when a connection is made with either an extension process or a content script.</dd> + <dt>{{WebExtAPIRef("runtime.onConnectExternal")}}</dt> + <dd>Fired when a connection is made with another extension.</dd> + <dt>{{WebExtAPIRef("runtime.onMessage")}}</dt> + <dd>Fired when a message is sent from either an extension process or a content script.</dd> + <dt>{{WebExtAPIRef("runtime.onMessageExternal")}}</dt> + <dd>Fired when a message is sent from another extension. Cannot be used in a content script.</dd> + <dt>{{WebExtAPIRef("runtime.onRestartRequired")}}</dt> + <dd>Fired when the device needs to be restarted.</dd> +</dl> + +<h2 id="Browser_compatibility">Browser compatibility</h2> + + + +<p>{{Compat("webextensions.api.runtime")}}</p> + +<div>{{WebExtExamples("h2")}}</div> + +<div class="note"><strong>Acknowledgements</strong> + +<p>This API is based on Chromium's <a href="https://developer.chrome.com/extensions/runtime"><code>chrome.runtime</code></a> API. This documentation is derived from <a href="https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/runtime.json"><code>runtime.json</code></a> in the Chromium code.</p> + +<p>Microsoft Edge compatibility data is supplied by Microsoft Corporation and is included here under the Creative Commons Attribution 3.0 United States License.</p> +</div> + +<div class="hidden"> +<pre>// Copyright 2015 The Chromium Authors. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +</pre> +</div> diff --git a/files/ru/mozilla/add-ons/webextensions/api/tabs/get/index.html b/files/ru/mozilla/add-ons/webextensions/api/tabs/get/index.html new file mode 100644 index 0000000000..25a2126d65 --- /dev/null +++ b/files/ru/mozilla/add-ons/webextensions/api/tabs/get/index.html @@ -0,0 +1,74 @@ +--- +title: tabs.get() +slug: Mozilla/Add-ons/WebExtensions/API/tabs/get +translation_of: Mozilla/Add-ons/WebExtensions/API/tabs/get +--- +<div>{{AddonSidebar()}}</div> + +<p>Получает сведения об указанной вкладке.</p> + +<h2 id="Синтаксис"><span class="short_text" id="result_box" lang="ru"><span>Синтаксис</span></span></h2> + +<pre class="brush: js">browser.tabs.get( + tabId, // integer + function(tab) {...} // function +) +</pre> + +<h3 id="Параметры">Параметры</h3> + +<dl> + <dt><code>tabId</code></dt> + <dd><code>integer</code>.</dd> + <dt><code>callback</code></dt> + <dd><code>function</code>. <span class="short_text" id="result_box" lang="ru"><span>Функция принимает</span> <span>следующие аргументы</span></span>: + <dl class="reference-values"> + <dt><code>tab</code></dt> + <dd>{{WebExtAPIRef('tabs.Tab')}}.</dd> + </dl> + </dd> +</dl> + +<h2 id="Совместимость_с_браузерами">Совместимость с браузерами</h2> + +<p>{{Compat("webextensions.api.tabs.get")}}</p> + +<h2 id="Примеры">Примеры</h2> + +<p>{{WebExtExamples}}</p> + +<div class="note"><strong>Благодарность</strong> + +<p>Этот API основан на Chromium <a href="https://developer.chrome.com/extensions/tabs#method-get"><code>chrome.tabs</code></a> API. Это документация получена из <a href="https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json"><code>tabs.json</code></a> в коде Chromium.</p> +</div> + +<div class="hidden"> +<pre>// Copyright 2015 The Chromium Authors. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +</pre> +</div> diff --git a/files/ru/mozilla/add-ons/webextensions/api/tabs/hide/index.html b/files/ru/mozilla/add-ons/webextensions/api/tabs/hide/index.html new file mode 100644 index 0000000000..a91d67f008 --- /dev/null +++ b/files/ru/mozilla/add-ons/webextensions/api/tabs/hide/index.html @@ -0,0 +1,79 @@ +--- +title: tabs.hide() +slug: Mozilla/Add-ons/WebExtensions/API/tabs/hide +translation_of: Mozilla/Add-ons/WebExtensions/API/tabs/hide +--- +<div>{{AddonSidebar()}}</div> + +<p>Hides one or more tabs.</p> + +<p>Hidden tabs are no longer visible in the browser's tabstrip. Hidden tabs are not automatically <a href="/en-US/Add-ons/WebExtensions/API/tabs/discard">discarded</a>: the code running in them continues to run. You can explicitly discard tabs whenever you hide them: although this is not appropriate in all situations, it will help to reduce the resources used by the browser.</p> + +<p>This is an asynchronous function that returns a <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise">Promise</a></code>.</p> + +<p>Not all tabs are eligible for being hidden:</p> + +<ul> + <li>Tabs that are pinned cannot be hidden.</li> + <li>Tabs that are sharing the screen, microphone or camera cannot be hidden.</li> + <li>The current active tab cannot be hidden.</li> + <li>Tabs that are in the process of being closed cannot be hidden.</li> +</ul> + +<p>The first time an extension hides a tab, the browser will tell the user that the tab is being hidden, show them how they can access the hidden tab, and give them the option of disabling the extension instead.</p> + +<p>To use this API you must have the "tabHide" <a href="/en-US/Add-ons/WebExtensions/manifest.json/permissions">permission</a>.</p> + +<h2 id="Syntax">Syntax</h2> + +<pre class="syntaxbox brush:js">var hiding = browser.tabs.hide( + tabIds // integer or integer array +) +</pre> + +<h3 id="Parameters">Parameters</h3> + +<dl> + <dt><code>tabIds</code></dt> + <dd><code><code>integer</code></code> or <code><code>array</code></code> of <code><code>integer</code></code>. The IDs of the tab or tabs to hide.</dd> + <dd>If any of these tabs are not eligible for being hidden, they will not be hidden, but the call will still succeed and eligible tabs will still be hidden. For example, if you pass <code>[1, 3]</code>, and <code>1</code> identifies the active tab, then only <code>3</code> will be hidden.</dd> + <dd>However, if any of the tab IDs are invalid, the call will fail and no tabs will be hidden.</dd> +</dl> + +<h3 id="Return_value">Return value</h3> + +<p>A <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise">Promise</a></code> that will be fulfilled with an array containing the IDs of the tabs that were hidden. If any error occurs, the promise will be rejected with an error message.</p> + +<h2 id="Browser_compatibility">Browser compatibility</h2> + +<p class="hidden">The compatibility table in this page is generated from structured data. If you'd like to contribute to the data, please check out <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> and send us a pull request.</p> + +<p>{{Compat("webextensions.api.tabs.hide")}}</p> + +<h2 id="Examples">Examples</h2> + +<p>Hide a single tab:</p> + +<pre class="brush: js">function onHidden() { + console.log(`Hidden`); +} + +function onError(error) { + console.log(`Error: ${error}`); +} + +browser.tabs.hide(2).then(onHidden, onError);</pre> + +<p>Hide multiple tabs:</p> + +<pre class="brush: js">function onHidden() { + console.log(`Hidden`); +} + +function onError(error) { + console.log(`Error: ${error}`); +} + +browser.tabs.hide([15, 14, 1]).then(onHidden, onError);</pre> + +<p>{{WebExtExamples}}</p> diff --git a/files/ru/mozilla/add-ons/webextensions/api/tabs/index.html b/files/ru/mozilla/add-ons/webextensions/api/tabs/index.html new file mode 100644 index 0000000000..696329aa4f --- /dev/null +++ b/files/ru/mozilla/add-ons/webextensions/api/tabs/index.html @@ -0,0 +1,179 @@ +--- +title: tabs +slug: Mozilla/Add-ons/WebExtensions/API/tabs +tags: + - API + - Add-ons + - Extensions + - Interface + - NeedsTranslation + - Non-standard + - Reference + - TopicStub + - WebExtensions + - tabs +translation_of: Mozilla/Add-ons/WebExtensions/API/tabs +--- +<div>{{AddonSidebar}}</div> + +<p>Interact with the browser's tab system. You can use this API to get a list of opened tabs and to create, modify, and rearrange tabs in the browser.</p> + +<p>You can use most of this API without any special permission. However, to access <code>Tab.url</code>, <code>Tab.title</code>, and <code>Tab.faviconUrl</code>, you need to have the "tabs" <a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions">permission</a>. In Firefox this also means you need "tabs" to {{WebExtAPIRef("tabs.query", "query")}} by URL.</p> + +<h2 id="Types">Types</h2> + +<dl> + <dt>{{WebExtAPIRef("tabs.MutedInfoReason")}}</dt> + <dd>An event that caused a muted state change.</dd> + <dt>{{WebExtAPIRef("tabs.MutedInfo")}}</dt> + <dd>Tab muted state and the reason for the last state change.</dd> + <dt>{{WebExtAPIRef("tabs.Tab")}}</dt> + <dd>Contains various properties of a single tab.</dd> + <dt>{{WebExtAPIRef("tabs.ZoomSettingsMode")}}</dt> + <dd>Defines how zoom changes are handled, i.e. which entity is responsible for the actual scaling of the page; defaults to <code>automatic</code>.</dd> + <dt>{{WebExtAPIRef("tabs.ZoomSettingsScope")}}</dt> + <dd>Defines whether zoom changes will persist for the page's origin, or only take effect in this tab; defaults to <code>per-origin</code> when in <code>automatic</code> mode, and <code>per-tab</code> otherwise.</dd> + <dt>{{WebExtAPIRef("tabs.ZoomSettings")}}</dt> + <dd>Defines how zoom changes in a tab are handled and at what scope.</dd> + <dt>{{WebExtAPIRef("tabs.TabStatus")}}</dt> + <dd>Whether the tabs have completed loading.</dd> + <dt>{{WebExtAPIRef("tabs.WindowType")}}</dt> + <dd>The type of window.</dd> +</dl> + +<h2 id="Properties">Properties</h2> + +<dl> + <dt>{{WebExtAPIRef("tabs.TAB_ID_NONE")}}</dt> + <dd>An ID which represents the absence of a browser tab.</dd> +</dl> + +<h2 id="Functions">Functions</h2> + +<dl> + <dt>{{WebExtAPIRef("tabs.get()")}}</dt> + <dd>Retrieves details about the specified tab.</dd> + <dt>{{WebExtAPIRef("tabs.getCurrent()")}}</dt> + <dd>Gets the tab that this script call is being made from. May be undefined if called from a non-tab context (for example: a background page or popup view).</dd> + <dt>{{WebExtAPIRef("tabs.connect()")}}</dt> + <dd>Connects to the content script(s) in the specified tab. The {{WebExtAPIRef('runtime.onConnect')}} event is fired in each content script running in the specified tab for the current extension. For more details, see <a href="/en-US/Add-ons/WebExtensions/Content_scripts">content script messaging</a>.</dd> + <dt>{{WebExtAPIRef("tabs.sendRequest()")}}</dt> + <dd>Sends a single request to the content script(s) in the specified tab, with an optional callback to run when a response is sent back. The {{WebExtAPIRef('extension.onRequest')}} event is fired in each content script running in the specified tab for the current extension.</dd> + <dt>{{WebExtAPIRef("tabs.sendMessage()")}}</dt> + <dd>Sends a single message to the content script(s) in the specified tab, with an optional callback to run when a response is sent back. The {{WebExtAPIRef('runtime.onMessage')}} event is fired in each content script running in the specified tab for the current extension.</dd> + <dt>{{WebExtAPIRef("tabs.getSelected()")}}</dt> + <dd>Gets the tab that is selected in the specified window.</dd> + <dt>{{WebExtAPIRef("tabs.getAllInWindow()")}}</dt> + <dd>Gets details about all tabs in the specified window.</dd> + <dt>{{WebExtAPIRef("tabs.create()")}}</dt> + <dd>Creates a new tab.</dd> + <dt>{{WebExtAPIRef("tabs.duplicate()")}}</dt> + <dd>Duplicates a tab.</dd> + <dt>{{WebExtAPIRef("tabs.query()")}}</dt> + <dd>Gets all tabs that have the specified properties, or all tabs if no properties are specified.</dd> + <dt>{{WebExtAPIRef("tabs.highlight()")}}</dt> + <dd>Highlights the given tabs.</dd> + <dt>{{WebExtAPIRef("tabs.update()")}}</dt> + <dd>Modifies the properties of a tab. Properties that are not specified in <var>updateProperties</var> are not modified.</dd> + <dt>{{WebExtAPIRef("tabs.move()")}}</dt> + <dd>Moves one or more tabs to a new position within its window, or to a new window. Note that tabs can only be moved to and from normal (<code>window.type === "normal"</code>) windows.</dd> + <dt>{{WebExtAPIRef("tabs.reload()")}}</dt> + <dd>Reload a tab.</dd> + <dt>{{WebExtAPIRef("tabs.remove()")}}</dt> + <dd>Closes one or more tabs.</dd> + <dt>{{WebExtAPIRef("tabs.detectLanguage()")}}</dt> + <dd>Detects the primary language of the content in a tab.</dd> + <dt>{{WebExtAPIRef("tabs.captureVisibleTab()")}}</dt> + <dd>Captures the visible area of the currently active tab in the specified window. You must have <code><all_urls></code> permission to use this method.</dd> + <dt>{{WebExtAPIRef("tabs.executeScript()")}}</dt> + <dd>Injects JavaScript code into a page. For details, see the programmatic injection section of the <a href="/en-US/Add-ons/WebExtensions/Content_scripts">content scripts</a> doc.</dd> + <dt>{{WebExtAPIRef("tabs.insertCSS()")}}</dt> + <dd>Injects CSS into a page. For details, see the programmatic injection section of the <a href="/en-US/Add-ons/WebExtensions/Content_scripts">content scripts</a> doc.</dd> + <dt>{{WebExtAPIRef("tabs.setZoom()")}}</dt> + <dd>Zooms a specified tab.</dd> + <dt>{{WebExtAPIRef("tabs.getZoom()")}}</dt> + <dd>Gets the current zoom factor of a specified tab.</dd> + <dt>{{WebExtAPIRef("tabs.setZoomSettings()")}}</dt> + <dd>Sets the zoom settings for a specified tab, which define how zoom changes are handled. These settings are reset to defaults upon navigating the tab.</dd> + <dt>{{WebExtAPIRef("tabs.getZoomSettings()")}}</dt> + <dd>Gets the current zoom settings of a specified tab.</dd> +</dl> + +<h2 id="Events">Events</h2> + +<dl> + <dt>{{WebExtAPIRef("tabs.onCreated")}}</dt> + <dd>Fired when a tab is created. Note that the tab's URL may not be set at the time this event fired, but you can listen to onUpdated events to be notified when a URL is set.</dd> + <dt>{{WebExtAPIRef("tabs.onUpdated")}}</dt> + <dd>Fired when a tab is updated.</dd> + <dt>{{WebExtAPIRef("tabs.onMoved")}}</dt> + <dd>Fired when a tab is moved within a window. Only one move event is fired, representing the tab the user directly moved. Move events are not fired for the other tabs that must move in response. This event is not fired when a tab is moved between windows. For that, see {{WebExtAPIRef('tabs.onDetached')}}.</dd> + <dt>{{WebExtAPIRef("tabs.onSelectionChanged")}}</dt> + <dd>Fires when the selected tab in a window changes.</dd> + <dt>{{WebExtAPIRef("tabs.onActiveChanged")}}</dt> + <dd>Fires when the selected tab in a window changes. Note that the tab's URL may not be set at the time this event fired, but you can listen to {{WebExtAPIRef('tabs.onUpdated')}} events to be notified when a URL is set.</dd> + <dt>{{WebExtAPIRef("tabs.onActivated")}}</dt> + <dd>Fires when the active tab in a window changes. Note that the tab's URL may not be set at the time this event fired, but you can listen to onUpdated events to be notified when a URL is set.</dd> + <dt>{{WebExtAPIRef("tabs.onHighlightChanged")}}</dt> + <dd>Fired when the highlighted or selected tabs in a window changes.</dd> + <dt>{{WebExtAPIRef("tabs.onHighlighted")}}</dt> + <dd>Fired when the highlighted or selected tabs in a window changes.</dd> + <dt>{{WebExtAPIRef("tabs.onDetached")}}</dt> + <dd>Fired when a tab is detached from a window, for example because it is being moved between windows.</dd> + <dt>{{WebExtAPIRef("tabs.onAttached")}}</dt> + <dd>Fired when a tab is attached to a window, for example because it was moved between windows.</dd> + <dt>{{WebExtAPIRef("tabs.onRemoved")}}</dt> + <dd>Fired when a tab is closed.</dd> + <dt>{{WebExtAPIRef("tabs.onReplaced")}}</dt> + <dd>Fired when a tab is replaced with another tab due to prerendering or instant.</dd> + <dt>{{WebExtAPIRef("tabs.onZoomChange")}}</dt> + <dd>Fired when a tab is zoomed.</dd> +</dl> + +<h2 id="Browser_compatibility">Browser compatibility</h2> + +<p>{{Compat("webextensions.api.tabs")}}</p> + +<div class="hidden note"> +<p>The "Chrome incompatibilities" section is included from <a href="https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Chrome_incompatibilities"> https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Chrome_incompatibilities</a> using the <a href="/en-US/docs/Template:WebExtChromeCompat">WebExtChromeCompat</a> macro.</p> + +<p>If you need to update this content, edit <a href="https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Chrome_incompatibilities">https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Chrome_incompatibilities</a>, then shift-refresh this page to see your changes.</p> +</div> + +<p>{{WebExtExamples("h2")}}</p> + +<div class="note"><strong>Acknowledgements</strong> + +<p>This API is based on Chromium's <a href="https://developer.chrome.com/extensions/tabs"><code>chrome.tabs</code></a> API. This documentation is derived from <a href="https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/tabs.json"><code>tabs.json</code></a> in the Chromium code.</p> +</div> + +<div class="hidden"> +<pre>// Copyright 2015 The Chromium Authors. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +</pre> +</div> diff --git a/files/ru/mozilla/add-ons/webextensions/api/webrequest/index.html b/files/ru/mozilla/add-ons/webextensions/api/webrequest/index.html new file mode 100644 index 0000000000..3f0da7eada --- /dev/null +++ b/files/ru/mozilla/add-ons/webextensions/api/webrequest/index.html @@ -0,0 +1,188 @@ +--- +title: ВебЗапрос +slug: Mozilla/Add-ons/WebExtensions/API/webRequest +translation_of: Mozilla/Add-ons/WebExtensions/API/webRequest +--- +<div>{{AddonSidebar}}</div> + +<p>Добавляет обработчики событий на различных стадиях HTTP запроса. Обработчик получет детальную информацию о запросе и способен изменить или отменить запрос.</p> + +<p>Каждое событие запущено на определённой стадии запроса. Типичный порядок событий такой:<img alt="" src="https://mdn.mozillademos.org/files/13376/webRequest-flow.png" style="display: block; height: 680px; margin-left: auto; margin-right: auto; width: 624px;"></p> + +<p>{{WebExtAPIRef("webRequest.onErrorOccurred", "onErrorOccurred")}} Может быть запущен в любой момент во время запроса. Чреда событий может отличаться от приведенной выше: например, в Firefox, после <a href="/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security">HSTS</a> обновления, событие <code>onBeforeRedirect</code> будет запущено сразу же после <code>onBeforeRequest</code>.</p> + +<p>Все события, кроме <code>onErrorOccurred</code>, могут принимать три аргумента в <code>addListener()</code>:</p> + +<ul> + <li>сам обработчик</li> + <li>обьект {{WebExtAPIRef("webRequest.RequestFilter", "filter")}} , который позволяет получать оповещения о запросах, сделанных к определённым URL или определённым типам ресурсов.</li> + <li>необязательный обьект <code>extraInfoSpec</code> . Может быть использован для передачи дополнительных срецифических для события инструкций.</li> +</ul> + +<p>Функции - обработчику передается обьект <code>details</code> который содержит информацию о запросе. Она содержит ID запроса, который обеспечен для включения надстройки, которая позволяет соотносить события, ассоциируемые с одним запросом. Это уникально в пределах сессии и контекста надстройки. Информация остается одинаковой везде на протяжении запроса, даже при перенаправлениях и обменах аутентификации.</p> + +<p>Для использования webRequest API для определённого хоста, расширение должно иметь "webRequest" <a href="/en-US/Add-ons/WebExtensions/manifest.json/permissions#API_permissions">API permission</a> и <a href="/en-US/Add-ons/WebExtensions/manifest.json/permissions#Host_permissions">host permission </a>для этого хоста. Для использования возможности "блокирования" расширение должно также иметь "webRequestBlocking" API разрешение.</p> + +<p>Для перехвата ресурсов, загруженных страницей (таких как картинки, скрипты или таблицы стилей), расширение должно иметь разрешение хоста для ресурса также как и для главной страницы, запрашивающей ресурс. К примеру, если страница на "https://developer.mozilla.org" загружает картинку из "https://mdn.mozillademos.org", тогда расширение должно иметь разрешения обоих хостов чтобы перехватить запрос картинки.</p> + +<h2 id="Модифицирование_заголовков">Модифицирование заголовков</h2> + +<p>Используя некоторые из этих событий, вы можете модифицировать запрос. Конкретно, вы можете:</p> + +<ul> + <li>отменить запрос в: + <ul> + <li>{{WebExtAPIRef("webRequest.onBeforeRequest", "onBeforeRequest")}}</li> + <li>{{WebExtAPIRef("webRequest.onBeforeSendHeaders", "onBeforeSendHeaders")}}</li> + <li>{{WebExtAPIRef("webRequest.onAuthRequired", "onAuthRequired")}}</li> + </ul> + </li> + <li>перенаправить запрос в: + <ul> + <li>{{WebExtAPIRef("webRequest.onBeforeRequest", "onBeforeRequest")}}</li> + <li>{{WebExtAPIRef("webRequest.onHeadersReceived", "onHeadersReceived")}}</li> + </ul> + </li> + <li>модифицировать заголовки запроса в: + <ul> + <li>{{WebExtAPIRef("webRequest.onBeforeSendHeaders", "onBeforeSendHeaders")}} + <ul> + </ul> + </li> + </ul> + </li> + <li>модифицировать заголовки ответа в: + <ul> + <li>{{WebExtAPIRef("webRequest.onHeadersReceived", "onHeadersReceived")}}</li> + </ul> + </li> + <li>предоставить учетные данные аутентификации в: + <ul> + <li>{{WebExtAPIRef("webRequest.onAuthRequired", "onAuthRequired")}}</li> + </ul> + </li> +</ul> + +<p>Чтобы сделать это, вам необходимо передать оцпию со значением "blocking" в аргументе <code>extraInfoSpec</code> к <code>addListener()</code>. Это делает обработчик синхронным. В обработчике, вы можете тогда возвратить обьект {{WebExtAPIRef("webRequest.BlockingResponse", "BlockingResponse")}} который индикует модификацию, какую вам нужно сделать: например, модифицированный заголовок запроса который вы хотите отправить.</p> + +<h2 id="Доступ_к_информации_о_безопасности">Доступ к информации о безопасности</h2> + +<p>В обработчике {{WebExtAPIRef("webRequest.onHeadersReceived", "onHeadersReceived")}} вы имеете доступ к <a href="/en-US/docs/Glossary/TLS">TLS</a> свойствам запроса через вызов {{WebExtAPIRef("webRequest.getSecurityInfo()", "getSecurityInfo()")}}. Чтоды сделать это, вы должны также передать "blocking" в <code>extraInfoSpec</code> аргументе к <code>addListener()</code> события.</p> + +<p>Вы можете прочитать детали TLS хэндшейка, но не можете модифицировать их или перезаписать решения доверы браузера.</p> + +<h2 id="Modifying_responses">Modifying responses</h2> + +<p>Для того, чтобы модифицировать тело HTTP ответа на запрос, вызовите {{WebExtAPIRef("webRequest.filterResponseData")}}, и передайте ID запроса. Это возвратит обьект {{WebExtAPIRef("webRequest.StreamFilter")}} который вы сможете использовать чтобы исследовать и изменять данные когда они получены браузером.</p> + +<p>Чтобы сделать это, у вас дожно быть "webRequestBlocking" API разрешение, а также "webRequest" <a href="/en-US/Add-ons/WebExtensions/manifest.json/permissions#API_permissions">API permission</a> и <a href="/en-US/Add-ons/WebExtensions/manifest.json/permissions#Host_permissions">host permission </a>от соответствующего хоста.</p> + +<h2 id="Types">Types</h2> + +<dl> + <dt>{{WebExtAPIRef("webRequest.BlockingResponse")}}</dt> + <dd> + <p>An object of this type is returned by event listeners that have set <code>"blocking"</code> in their <code>extraInfoSpec</code> argument. By setting particular properties in <code>BlockingResponse</code>, the listener can modify network requests.</p> + </dd> + <dt>{{WebExtAPIRef("webRequest.CertificateInfo")}}</dt> + <dd>An object describing a single X.509 certificate.</dd> + <dt>{{WebExtAPIRef("webRequest.HttpHeaders")}}</dt> + <dd>An array of HTTP headers. Each header is represented as an object with two properties: <code>name</code> and either <code>value</code> or <code>binaryValue</code>.</dd> + <dt>{{WebExtAPIRef("webRequest.RequestFilter")}}</dt> + <dd>An object describing filters to apply to webRequest events.</dd> + <dt>{{WebExtAPIRef("webRequest.ResourceType")}}</dt> + <dd>Represents a particular kind of resource fetched in a web request.</dd> + <dt>{{WebExtAPIRef("webRequest.SecurityInfo")}}</dt> + <dd>An object describing the security properties of a particular web request.</dd> + <dt>{{WebExtAPIRef("webRequest.StreamFilter")}}</dt> + <dd>An object that can be used to monitor and modify HTTP responses while they are being received.</dd> + <dt>{{WebExtAPIRef("webRequest.UploadData")}}</dt> + <dd>Contains data uploaded in a URL request.</dd> +</dl> + +<h2 id="Properties">Properties</h2> + +<dl> + <dt>{{WebExtAPIRef("webRequest.MAX_HANDLER_BEHAVIOR_CHANGED_CALLS_PER_10_MINUTES")}}</dt> + <dd>The maximum number of times that <code><a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/WebRequest/handlerBehaviorChanged" title="Suppose an add-on's job is to block web requests against a pattern, and the following scenario happens:"><code>handlerBehaviorChanged()</code></a></code> can be called in a 10 minute period.</dd> +</dl> + +<h2 id="Functions">Functions</h2> + +<dl> + <dt>{{WebExtAPIRef("webRequest.handlerBehaviorChanged()")}}</dt> + <dd>This function can be used to ensure that event listeners are applied correctly when pages are in the browser's in-memory cache.</dd> + <dt>{{WebExtAPIRef("webRequest.filterResponseData()")}}</dt> + <dd>Returns a {{WebExtAPIRef("webRequest.StreamFilter")}} object for a given request.</dd> + <dt>{{WebExtAPIRef("webRequest.getSecurityInfo()")}}</dt> + <dd>Gets detailed information about the <a href="/en-US/docs/Glossary/TLS">TLS</a> connection associated with a given request.</dd> +</dl> + +<h2 id="Events">Events</h2> + +<dl> + <dt>{{WebExtAPIRef("webRequest.onBeforeRequest")}}</dt> + <dd>Fired when a request is about to be made, and before headers are available. This is a good place to listen if you want to cancel or redirect the request.</dd> + <dt>{{WebExtAPIRef("webRequest.onBeforeSendHeaders")}}</dt> + <dd>Fired before sending any HTTP data, but after HTTP headers are available. This is a good place to listen if you want to modify HTTP request headers.</dd> + <dt>{{WebExtAPIRef("webRequest.onSendHeaders")}}</dt> + <dd>Fired just before sending headers. If your add-on or some other add-on modified headers in <code>{{WebExtAPIRef("webRequest.onBeforeSendHeaders", "onBeforeSendHeaders")}}</code>, you'll see the modified version here.</dd> + <dt>{{WebExtAPIRef("webRequest.onHeadersReceived")}}</dt> + <dd>Fired when the HTTP response headers associated with a request have been received. You can use this event to modify HTTP response headers.</dd> + <dt>{{WebExtAPIRef("webRequest.onAuthRequired")}}</dt> + <dd>Fired when the server asks the client to provide authentication credentials. The listener can do nothing, cancel the request, or supply authentication credentials.</dd> + <dt>{{WebExtAPIRef("webRequest.onResponseStarted")}}</dt> + <dd>Fired when the first byte of the response body is received. For HTTP requests, this means that the status line and response headers are available.</dd> + <dt>{{WebExtAPIRef("webRequest.onBeforeRedirect")}}</dt> + <dd>Fired when a server-initiated redirect is about to occur.</dd> + <dt>{{WebExtAPIRef("webRequest.onCompleted")}}</dt> + <dd>Fired when a request is completed.</dd> + <dt>{{WebExtAPIRef("webRequest.onErrorOccurred")}}</dt> + <dd>Fired when an error occurs.</dd> +</dl> + +<h2 id="Browser_compatibility">Browser compatibility</h2> + +<p>{{Compat("webextensions.api.webRequest")}}</p> + +<p><a href="/docs/Mozilla/Add-ons/WebExtensions/Chrome_incompatibilities#webRequest_incompatibilities">Extra notes on Chrome incompatibilities</a>.</p> + +<p>{{WebExtExamples("h2")}}</p> + +<div class="note"><strong>Acknowledgements</strong> + +<p>This API is based on Chromium's <a href="https://developer.chrome.com/extensions/webRequest"><code>chrome.webRequest</code></a> API. This documentation is derived from <a href="https://chromium.googlesource.com/chromium/src/+/master/extensions/common/api/web_request.json"><code>web_request.json</code></a> in the Chromium code.</p> + +<p>Microsoft Edge compatibility data is supplied by Microsoft Corporation and is included here under the Creative Commons Attribution 3.0 United States License.</p> +</div> + +<div class="hidden"> +<pre class="notranslate">// Copyright 2015 The Chromium Authors. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +</pre> +</div> diff --git a/files/ru/mozilla/add-ons/webextensions/api/windows/createtype/index.html b/files/ru/mozilla/add-ons/webextensions/api/windows/createtype/index.html new file mode 100644 index 0000000000..efc9821f8c --- /dev/null +++ b/files/ru/mozilla/add-ons/webextensions/api/windows/createtype/index.html @@ -0,0 +1,65 @@ +--- +title: windows.CreateType +slug: Mozilla/Add-ons/WebExtensions/API/windows/CreateType +translation_of: Mozilla/Add-ons/WebExtensions/API/windows/CreateType +--- +<div>{{AddonSidebar()}}</div> + +<p>Определение типа окна браузера для создания.</p> + +<h2 id="Тип">Тип</h2> + +<p>Значение данного типа <code>strings</code>. Возможные значения:</p> + +<ul> + <li><code>"normal"</code></li> + <li><code>"popup"</code></li> + <li><code>"panel"</code></li> + <li><code>"detached_panel"</code></li> +</ul> + +<h2 id="Совместимость_с_браузерами">Совместимость с браузерами</h2> + + + +<p>{{Compat("webextensions.api.windows.CreateType")}}</p> + +<p>{{WebExtExamples}}</p> + +<div class="note"><strong>Acknowledgements</strong> + +<p>This API is based on Chromium's <a href="https://developer.chrome.com/extensions/windows#type-CreateType"><code>chrome.windows</code></a> API. This documentation is derived from <a href="https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/windows.json"><code>windows.json</code></a> in the Chromium code.</p> + +<p>Microsoft Edge compatibility data is supplied by Microsoft Corporation and is included here under the Creative Commons Attribution 3.0 United States License.</p> +</div> + +<div class="hidden"> +<pre>// Copyright 2015 The Chromium Authors. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +</pre> +</div> diff --git a/files/ru/mozilla/add-ons/webextensions/api/windows/index.html b/files/ru/mozilla/add-ons/webextensions/api/windows/index.html new file mode 100644 index 0000000000..889210561b --- /dev/null +++ b/files/ru/mozilla/add-ons/webextensions/api/windows/index.html @@ -0,0 +1,106 @@ +--- +title: windows +slug: Mozilla/Add-ons/WebExtensions/API/windows +translation_of: Mozilla/Add-ons/WebExtensions/API/windows +--- +<div>{{AddonSidebar}}</div> + +<p><font><font>Взаимодействие с окнами браузера. </font><font>Вы можете использовать этот API, чтобы получить информацию об открытых окнах, а также открывать, изменять и закрывать окна. </font><font>Вы также можете слушать события открытия, закрытия окна, и активировать события.</font></font></p> + +<h2 id="Types">Types</h2> + +<dl> + <dt>{{WebExtAPIRef("windows.WindowType")}}</dt> + <dd>Тип окна браузера.</dd> + <dt>{{WebExtAPIRef("windows.WindowState")}}</dt> + <dd>Состояние окна браузера.</dd> + <dt>{{WebExtAPIRef("windows.Window")}}</dt> + <dd>Информация об окне браузера.</dd> + <dt>{{WebExtAPIRef("windows.CreateType")}}</dt> + <dd>Specifies the type of browser window to create.</dd> +</dl> + +<h2 id="Properties">Properties</h2> + +<dl> + <dt>{{WebExtAPIRef("windows.WINDOW_ID_NONE")}}</dt> + <dd>The <code>windowId</code> value that represents the absence of a browser window.</dd> + <dt>{{WebExtAPIRef("windows.WINDOW_ID_CURRENT")}}</dt> + <dd>The <code>windowId</code> value that represents the current window.</dd> +</dl> + +<h2 id="Functions">Functions</h2> + +<dl> + <dt>{{WebExtAPIRef("windows.get()")}}</dt> + <dd>Gets details about a window, given its ID.</dd> + <dt>{{WebExtAPIRef("windows.getCurrent()")}}</dt> + <dd>Gets the current window.</dd> + <dt>{{WebExtAPIRef("windows.getLastFocused()")}}</dt> + <dd>Gets the window that was most recently focused — typically the window 'on top'.</dd> + <dt>{{WebExtAPIRef("windows.getAll()")}}</dt> + <dd>Gets all windows.</dd> + <dt>{{WebExtAPIRef("windows.create()")}}</dt> + <dd> + <p>Creates a new window.</p> + </dd> + <dt>{{WebExtAPIRef("windows.update()")}}</dt> + <dd>Updates the properties of a window. Use this to move, resize, and (un)focus a window, etc.</dd> + <dt>{{WebExtAPIRef("windows.remove()")}}</dt> + <dd>Closes a window, and all its tabs.</dd> +</dl> + +<h2 id="Events">Events</h2> + +<dl> + <dt>{{WebExtAPIRef("windows.onCreated")}}</dt> + <dd>Fired when a window is created.</dd> + <dt>{{WebExtAPIRef("windows.onRemoved")}}</dt> + <dd>Fired when a window is closed.</dd> + <dt>{{WebExtAPIRef("windows.onFocusChanged")}}</dt> + <dd>Fired when the currently focused window changes.</dd> +</dl> + +<h2 id="Browser_compatibility">Browser compatibility</h2> + +<p>{{Compat("webextensions.api.windows")}}</p> + +<p>{{WebExtExamples("h2")}}</p> + +<div class="note"><strong>Acknowledgements</strong> + +<p>This API is based on Chromium's <a href="https://developer.chrome.com/extensions/windows"><code>chrome.windows</code></a> API. This documentation is derived from <a href="https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/api/windows.json"><code>windows.json</code></a> in the Chromium code.</p> + +<p>Microsoft Edge compatibility data is supplied by Microsoft Corporation and is included here under the Creative Commons Attribution 3.0 United States License.</p> +</div> + +<div class="hidden"> +<pre>// Copyright 2015 The Chromium Authors. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +</pre> +</div> diff --git a/files/ru/mozilla/add-ons/webextensions/chrome_incompatibilities/index.html b/files/ru/mozilla/add-ons/webextensions/chrome_incompatibilities/index.html new file mode 100644 index 0000000000..70e5f2e7e1 --- /dev/null +++ b/files/ru/mozilla/add-ons/webextensions/chrome_incompatibilities/index.html @@ -0,0 +1,331 @@ +--- +title: Chrome incompatibilities +slug: Mozilla/Add-ons/WebExtensions/Chrome_incompatibilities +translation_of: Mozilla/Add-ons/WebExtensions/Chrome_incompatibilities +--- +<div>{{AddonSidebar}}</div> + +<p>Веб расширения разработаны с поддержкой совместимости с расширениями Хрома и Оперы на сколько это возможно. Расширения, написанные для этих браузеров, должны работать в Firefox с минимальными изменениями.</p> + +<p>Все же, Firefox на данный момент имеет поддержку только для ограниченного набора функций и API, поддержуемых в Хроме и Опере. Мы работаем над добавлением большей поддержки, но много функций пока еще не поддерживаются и некоторые из них никогда не будут поддерживаться.</p> + +<p>Эта статья перечисляет все функции и API, которые полностью поддерживаются в <span style="line-height: 1.5;">Firefox Developer Edition (на данный момент Firefox 47). Там где функция поддерживается частично, мы указали на проблемные места.</span></p> + +<div class="note"> +<p>You should assume that features and APIs not listed here at all are not yet supported.</p> +</div> + +<h2 id="manifest.json_функция">manifest.json функция</h2> + +<h3 id="Полностью_поддерживаемые_ключи">Полностью поддерживаемые ключи:</h3> + +<ul> + <li><code><a href="/en-US/Add-ons/WebExtensions/manifest.json/applications">applications</a></code></li> + <li><code><a href="/en-US/Add-ons/WebExtensions/manifest.json/browser_action">browser_action</a></code></li> + <li><code><a href="/en-US/Add-ons/WebExtensions/manifest.json/default_locale">default_locale</a></code></li> + <li><code><a href="/en-US/Add-ons/WebExtensions/manifest.json/description">description</a></code></li> + <li><code><a href="/en-US/Add-ons/WebExtensions/manifest.json/icons">icons</a></code></li> + <li><code><a href="/en-US/Add-ons/WebExtensions/manifest.json/manifest_version">manifest_version</a></code></li> + <li><code><a href="/en-US/Add-ons/WebExtensions/manifest.json/name">name</a></code></li> + <li><code><a href="/en-US/Add-ons/WebExtensions/manifest.json/page_action">page_action</a></code></li> + <li><code><a href="/en-US/Add-ons/WebExtensions/manifest.json/version">version</a></code></li> + <li><code><a href="/en-US/Add-ons/WebExtensions/manifest.json/web_accessible_resources">web_accessible_resources</a></code></li> +</ul> + +<h3 id="Частично_поддерживаемые_ключи">Частично поддерживаемые ключи:</h3> + +<h4 id="background">background</h4> + +<p>Firefox не поддерживает <code>"устойчивое"</code> свойство. Фоновые скрипты остаются загруженными всё время.</p> + +<h4 id="commands">commands</h4> + +<p>Firefox не поддерживает:</p> + +<ul> + <li>Media keys как сокращение</li> + <li><code>global</code></li> + <li>специальную комманду <code>_execute_browser_action</code></li> +</ul> + +<h4 id="content_scripts">content_scripts</h4> + +<p>Firefox не поддерживает:</p> + +<ul> + <li><code>match_about_blank</code></li> +</ul> + +<h4 id="content_security_policy">content_security_policy</h4> + +<p>Firefox не поддерживает:</p> + +<ul> + <li>"http://127.0.0.1" or "http://localhost" as script sources: they must be served over HTTPS.</li> +</ul> + +<h4 id="options_ui">options_ui</h4> + +<p>Firefox не поддерживает:</p> + +<ul> + <li><code>chrome_style</code></li> +</ul> + +<p>Using <code>options_ui</code> requires a valid value for the <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/applications">applications.gecko.id</a> property.</p> + +<h4 id="permissions">permissions</h4> + +<p>Firefox не поддерживает следующие разрешения:</p> + +<ul> + <li><code>background</code></li> + <li><code>clipboardRead</code></li> + <li><code>clipboardWrite</code></li> + <li><code>geolocation</code></li> + <li><code>unlimitedStorage</code></li> +</ul> + +<p>Obviously, it doesn't support permissions for APIs that are themselves not supported.</p> + +<h4 id="incognito">incognito</h4> + +<p>Firefox does not support the following incognito (private browsing) modes:</p> + +<ul> + <li><code>split</code></li> +</ul> + +<h2 id="JavaScript_APIs">JavaScript APIs</h2> + +<h3 id="Fully_supported_APIs">Fully supported APIs</h3> + +<ul> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/alarms">alarms</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserAction">browserAction</a> + <ul> + <li>Relative URLs passed to <code>setPopup()</code> are resolved relative to the caller document, rather than to the extension root</li> + </ul> + </li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/commands">commands</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/contextMenus">contextMenus</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/cookies">cookies</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/i18n">i18n</a></li> + <li><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/pageAction">pageAction</a> + <ul> + <li>Relative URLs passed to <code>setPopup()</code> are resolved relative to the caller document, rather than to the extension root</li> + </ul> + </li> +</ul> + +<h3 id="Partially_supported_APIs">Partially supported APIs</h3> + +<h4 id="bookmarks">bookmarks</h4> + +<ul> + <li>Firefox does not support: + <ul> + <li><code>import()</code></li> + <li><code>export()</code></li> + <li><code>onCreated</code></li> + <li><code>onRemoved</code></li> + <li><code>onChanged</code></li> + <li><code>onMoved</code></li> + <li><code>onChildrenReordered</code></li> + <li><code>onImportBegan</code></li> + <li><code>onImportEnded</code></li> + <li><code>BookmarkTreeNodeUnmodifiable</code></li> + </ul> + </li> + <li>Firefox has special bookmarks like "Recently Bookmarked" or "Recently Visited"</li> +</ul> + +<h4 id="contextMenus">contextMenus</h4> + +<ul> + <li>Firefox does not support: + <ul> + <li>the "browser_action" or "page_action" context types</li> + </ul> + </li> +</ul> + +<h4 id="downloads">downloads</h4> + +<ul> + <li>Firefox does not support: + <ul> + <li><code>drag()</code></li> + <li><code>acceptDanger()</code></li> + <li><code>setShelfEnabled()</code></li> + <li><code>onDeterminingFilename</code></li> + </ul> + </li> + <li>The <code>saveAs</code> option and values other than <code>"GET"</code> for the <code>method</code> option are not supported by <code>download()</code></li> +</ul> + +<h4 id="extension">extension</h4> + +<ul> + <li>Firefox does not support: + <ul> + <li><code>setUpdateUrlData()</code></li> + </ul> + </li> + <li>Additionally, the following deprecated properties will not be supported: + <ul> + <li><code>onRequest</code></li> + <li><code>onRequestExternal</code></li> + <li><code>getExtensionTabs()</code></li> + <li><code>sendRequest()</code></li> + </ul> + </li> +</ul> + +<h4 id="idle">idle</h4> + +<ul> + <li>Firefox does not support: + <ul> + <li><code>onStateChanged</code></li> + <li><code>setDetectionInterval()</code></li> + </ul> + </li> +</ul> + +<p>Additoinally, <code>queryState()</code> always returns <code>"active"</code> in Firefox, regardless of the current system idle state.</p> + +<h4 id="notifications">notifications</h4> + +<ul> + <li>Firefox does not support: + <ul> + <li><code>update()</code></li> + </ul> + </li> + <li>Firefox doesn't provide <code>byUser</code> data.</li> +</ul> + +<h4 id="runtime">runtime</h4> + +<ul> + <li>Firefox does not support: + <ul> + <li><code>getPackageDirectoryEntry()</code></li> + <li><code>reload()</code></li> + <li><code>requestUpdateCheck()</code></li> + <li><code>restart()</code></li> + <li><code>sendNativeMessage()</code></li> + <li><code>onBrowserUpdateAvailable</code></li> + <li><code>onConnectExternal</code></li> + <li><code>onInstalled</code></li> + <li><code>onMessageExternal</code></li> + <li><code>onRestartRequired</code></li> + <li><code>onStartup</code></li> + <li><code>onSuspend</code></li> + <li><code>onSuspendCanceled</code></li> + <li><code>onUpdateAvailable</code></li> + </ul> + </li> +</ul> + +<h4 id="storage">storage</h4> + +<ul> + <li>Firefox does not support: + <ul> + <li><code>managed</code> storage area</li> + <li><code>sync</code> storage area</li> + <li><code>getBytesInUse()</code>.</li> + </ul> + </li> +</ul> + +<h4 id="tabs">tabs</h4> + +<ul> + <li>Firefox treats <code>highlighted</code> and <code>active</code> as the same, since Firefox has no concept of selecting multiple tabs.</li> + <li>In Firefox, you need the <code>tabs</code> <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions">permission</a> if you want to include <code>url</code> in the <code>queryInfo</code> parameter to <code><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/query">tabs.query()</a></code>.</li> + <li> + <p>In Firefox, relative URLs passed into <code>tabs.executeScript()</code> or <code>tabs.insertCSS()</code> are resolved relative to the current page URL. In Chrome, these URLs are resolved relative to the add-on's base URL. To work cross-browser, you can specify the path as an absolute URL, starting at the add-on's root, like this:</p> + + <pre class="line-numbers language-html"><code class="language-html">/path/to/script.js</code></pre> + </li> + <li>In Firefox, you can't open (using {{WebExtAPIRef("tabs.create")}}), or navigate to (using {{WebExtAPIRef("tabs.update")}}) privileged URLs: + <ul> + <li>chrome: URLs</li> + <li>javascript: URLs</li> + <li>data: URLs</li> + <li>privileged about: URLs (for example, about:config, about:addons, about:debugging)</li> + </ul> + </li> + <li>Additionally, the following deprecated properties will not be supported: + <ul> + <li><code>sendRequest()</code></li> + <li><code>getSelected()</code></li> + <li><code>onActiveChanged</code></li> + <li><code>onHighlightChanged</code></li> + <li><code>onSelectionChanged</code></li> + </ul> + </li> +</ul> + +<h4 id="webNavigation">webNavigation</h4> + +<ul> + <li>Firefox does not support: + <ul> + <li><code>onCreatedNavigationTarget</code></li> + <li><code>onTabReplaced</code></li> + </ul> + </li> +</ul> + +<h4 id="webRequest">webRequest</h4> + +<ul> + <li>Firefox does not support: + <ul> + <li><code>onAuthRequired</code></li> + <li>filtering by <code>windowId</code> and <code>tabId</code></li> + <li>the <code>"requestBody"</code> instruction in <code>opt_extraInfoSpec</code></li> + </ul> + </li> + <li>In Firefox requests can be redirected only if their original URL uses the http or https scheme</li> +</ul> + +<h4 id="windows">windows</h4> + +<ul> + <li>Firefox does not support: + <ul> + <li>the <code>focused </code>option in <code>create()</code></li> + </ul> + </li> + <li>In Firefox <code>onFocusChanged</code> will trigger multiple times for a given focus change.</li> +</ul> + +<h3 id="Planned_APIs">Planned APIs</h3> + +<p>We don't support the following APIs, but plan to, soon:</p> + +<ul> + <li><a class="external text" href="https://developer.chrome.com/extensions/devtools" rel="nofollow">Devtools (mostly panels)</a></li> + <li><a href="https://developer.chrome.com/extensions/debugger">debugger</a></li> + <li><a class="external text" href="https://developer.chrome.com/extensions/omnibox" rel="nofollow">omnibox</a></li> + <li><a class="external text" href="https://developer.chrome.com/extensions/permissions" rel="nofollow">permissions</a></li> +</ul> + +<p>This doesn't mean that these are the only additional APIs we will support, but that they are our current priorities.</p> + +<h3 id="Miscellaneous_incompatibilities">Miscellaneous incompatibilities</h3> + +<h4 id="Optional_arguments">Optional arguments</h4> + +<h4 id="URLs_in_CSS">URLs in CSS</h4> + +<p>Firefox resolves URLs in injected CSS files relative to the CSS file itself, rather than to the page it's injected into.</p> + +<h4 id="Additional_incompatibilities">Additional incompatibilities</h4> + +<p>Firefox does not support using <a href="/en-US/docs/Web/API/Window/alert">alert()</a> from background pages. Using <code>alert(message)</code> from a background page will cause the <a href="/en-US/docs/Tools/Browser_Console">Browser Console</a> to be opened and both a line stating "alert() is not supported in background windows; please use console.log instead." and the <code>message</code> will be output to the console.</p> diff --git a/files/ru/mozilla/add-ons/webextensions/content_scripts/index.html b/files/ru/mozilla/add-ons/webextensions/content_scripts/index.html new file mode 100644 index 0000000000..2451aabce6 --- /dev/null +++ b/files/ru/mozilla/add-ons/webextensions/content_scripts/index.html @@ -0,0 +1,495 @@ +--- +title: Встраиваемый скрипт +slug: Mozilla/Add-ons/WebExtensions/Content_scripts +tags: + - Web-расширение + - Расширение +translation_of: Mozilla/Add-ons/WebExtensions/Content_scripts +--- +<div>{{AddonSidebar}}</div> + +<p>Встраиваемый скрипт - это часть расширения, которая выполняется в контексте отдельной веб-страницы (в отличии от фоновых скриптов, выполняющихся в контексте целого браузера).</p> + +<p><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/Anatomy_of_a_WebExtension#%D0%A4%D0%BE%D0%BD%D0%BE%D0%B2%D1%8B%D0%B5_%D1%81%D0%BA%D1%80%D0%B8%D0%BF%D1%82%D1%8B">Фоновые скрипты</a> имеют доступ ко всем методам <a href="/ru/docs/Mozilla/Add-ons/WebExtensions/API">WebExtension JavaScript APIs</a>, но они не имеют доступа к контенту отдельных веб-страниц. Так что если вашему расширению необходимо взаимодействие с контентом веб-страницы, вам нужен встраиваемый скрипт.</p> + +<p>Точно так же, как скрипты загружаемые веб-страницами, встраиваемый скрипт может читать и изменять контент веб-страницы, используя DOM API.</p> + +<p>Встраиваемые скрипты имеют доступ только к <a href="/ru/docs/Mozilla/Add-ons/WebExtensions/Content_scripts#%D0%92%D0%B7%D0%B0%D0%B8%D0%BC%D0%BE%D0%B4%D0%B5%D0%B9%D1%81%D1%82%D0%B2%D0%B8%D0%B5_%D1%81_%D1%84%D0%BE%D0%BD%D0%BE%D0%B2%D1%8B%D0%BC%D0%B8_%D1%81%D0%BA%D1%80%D0%B8%D0%BF%D1%82%D0%B0%D0%BC%D0%B8">небольшому подмножеству методов WebExtension API</a>, но они могут <a href="/ru/docs/Mozilla/Add-ons/WebExtensions/Content_scripts#%D0%92%D0%B7%D0%B0%D0%B8%D0%BC%D0%BE%D0%B4%D0%B5%D0%B9%D1%81%D1%82%D0%B2%D0%B8%D0%B5_%D1%81_%D1%84%D0%BE%D0%BD%D0%BE%D0%B2%D1%8B%D0%BC%D0%B8_%D1%81%D0%BA%D1%80%D0%B8%D0%BF%D1%82%D0%B0%D0%BC%D0%B8">взаимодействовать с фоновыми скриптами</a>, используя систему передачи сообщений, таким образом опосредовано имея доступ ко всему WebExtension API.</p> + +<div class="note"> +<p>Обратите внимание, что встраивание скриптов блокируется на следующих доменах:</p> + +<ul style="display: grid;"> + <li>accounts-static.cdn.mozilla.net</li> + <li>accounts.firefox.com</li> + <li>addons.cdn.mozilla.net</li> + <li>addons.mozilla.org</li> + <li>api.accounts.firefox.com</li> + <li>content.cdn.mozilla.net</li> + <li>content.cdn.mozilla.net</li> + <li>discovery.addons.mozilla.org</li> + <li>input.mozilla.org</li> + <li>install.mozilla.org</li> + <li>oauth.accounts.firefox.com</li> + <li>profile.accounts.firefox.com</li> + <li>support.mozilla.org</li> + <li>sync.services.mozilla.com</li> + <li>testpilot.firefox.com</li> +</ul> + +<p>Если вы попытаетесь встроить скрипт на страницы, находящиеся на вышеперечисленных доменах, у вас ничего не выйдет, и веб-страница сделает запись о <a href="/ru/docs/Web/HTTP/CSP">CSP</a> ошибке.</p> + +<p>По причине того, что список запрещённых доменов включает в себя addons.mozilla.org, пользователи, которые попытаются испытать ваше расширение прямо на странице загрузки, могут посчитать, что расширение не работает! В связи с этим вы могли бы предоставить им соответствующее предупреждение или <a href="/ru/docs/Mozilla/Add-ons/WebExtensions/onboarding_upboarding_offboarding_best_practices">onboarding page</a> чтобы немедленно переадресовать их с addons.mozilla.org.</p> +</div> + +<div class="note"> +<p>Значения, определённые в глобальной области видимости встраиваемого скрипта с помощью <code>var foo</code> или <code>window.foo = "bar"</code> могут исчезать по причине бага <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1408996">1408996</a>.</p> +</div> + +<h2 id="Загрузка_встраиваемого_скрипта">Загрузка встраиваемого скрипта</h2> + +<p>Загрузка встраиваемых скриптов на веб-страницу происходит следующими тремя способами:</p> + +<ol> + <li><strong>Автоматическая загрузка скрипта на страницах с определёнными URL, объявленными при установке:</strong> используя <code><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/manifest.json/content_scripts">content_scripts</a></code> ключ в manifest.json, вы можете запросить браузер загружать встраиваемый скрипт каждый раз, когда браузер загружает веб-страницу, чей URL <a href="/ru/docs/Mozilla/Add-ons/WebExtensions/Match_patterns">совпадает с объявленными шаблонами</a>.</li> + <li><strong>Автоматическая загрузка скрипта на страницах с определёнными URL, объявленными в момент работы расширения:</strong> используя {{WebExtAPIRef("contentScripts")}} API, вы можете запросить браузер загружать встраиваемый скрипт каждый раз, когда браузер загружает веб-страницу, чей URL <a href="/ru/docs/Mozilla/Add-ons/WebExtensions/Match_patterns">совпадает с объявленными шаблонами</a>. Это очень похоже на первый метод, но позволяет добавлять и удалять правила динамически во время работы расширения.</li> + <li><strong>Загрузка скрипта расширением в конкретную вкладку:</strong> используя <code><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/API/Tabs/executeScript">tabs.executeScript()</a></code> API, вы можете загружать встраиваемые скрипты в определённые вкладки когда захотите: например, в ответ на нажатие пользователя на <a href="/ru/docs/Mozilla/Add-ons/WebExtensions/user_interface/Browser_action">browser action</a>.</li> +</ol> + +<p>Существует только одна глобальная область видимости <em>для одного фрейма, для одного расширения</em>. Это означает, что значения из одного встраиваемого скрипта могут быть доступны для другого встраиваемого скрипта, не зависимо от того, как встраиваемый скрипт был загружен на страницу.</p> + +<p>Используя методы (1) и (2), вы можете загружать скрипты на страницы, чьи URL могут быть представлены, используя <a href="/ru/docs/Mozilla/Add-ons/WebExtensions/Match_patterns">шаблон совпадения</a>.</p> + +<p>Используя метод (3), вы к тому же можете загружать скрипты на страницы вашего расширения, но вы не можете загружать скрипты на привилегированные страницы браузеры (например "about:debugging" или "about:addons").</p> + +<h2 id="Условия_работы_встраиваемого_скрипта">Условия работы встраиваемого скрипта</h2> + +<h3 id="Доступ_к_DOM">Доступ к DOM</h3> + +<p>Встраиваемые скрипты имеют доступ и могут изменять DOM на веб-странице, так же как и обычные скрипты. Так же они могут видеть любые изменения сделанные с DOM страничными скриптами.</p> + +<p>При этом, встраиваемые скрипты имеют "чистое DOM представление". Это значит:</p> + +<ul> + <li>Встраиваемые скрипты не могут видеть JavaScript переменных, определённых страничными скриптами.</li> + <li>Если страничный скрипт переназначит встроенное свойство DOM, встраиваемый скрипт всё равно будет видеть его изначальное значение, а не переназначенное.</li> +</ul> + +<p>В Firefox это поведение называется <a href="/ru/docs/Mozilla/Tech/Xray_vision">Xray vision</a>.</p> + +<p>Например, рассмотрите эту веб-страницу:</p> + +<pre class="brush: html"><!DOCTYPE html> +<html> + <head> + <meta http-equiv="content-type" content="text/html; charset=utf-8" /> + </head> + + <body> + <script src="page-scripts/page-script.js"></script> + </body> +</html></pre> + +<p>Скрипт "page-script.js" делает следующее:</p> + +<pre class="brush: js">// page-script.js + +// добавляет новый элемент к DOM +var p = document.createElement("p"); +p.textContent = "Этот параграф был добавлен страничным скриптом."; +p.setAttribute("id", "page-script-para"); +document.body.appendChild(p); + +// определяет новое свойство на объекте window +window.foo = "Эта глобальная переменная была добавлена страничным скриптом"; + +// переопределяет встроенную window.confirm() функцию +window.confirm = function() { + alert("Страничный скрипт так же переопределил 'confirm'"); +}</pre> + +<p>Теперь расширение загружает встраиваемый скрипт на страницу:</p> + +<pre class="brush: js">// content-script.js + +// получает доступ и изменяет DOM +var pageScriptPara = document.getElementById("page-script-para"); +pageScriptPara.style.backgroundColor = "blue"; + +// не может видеть свойств определённых страничным скриптом +console.log(window.foo); // undefined + +// видит изначальное значение свойства, переопределённого страничным скриптом +window.confirm("Вы уверены?"); // вызывает оригинальный window.confirm()</pre> + +<p>Те же самые правила применяются и наоборот: страничный скрипт не может видеть JavaScript свойств, добавленных встраиваемым скриптом.</p> + +<p>Это означает, что встраиваемый скрипт может полагаться на то, что DOM свойства всегда будут вести себя предсказуемо, и не беспокоиться о том, что его переменные будут иметь конфликт с переменными из страничного скрипта.</p> + +<p>Одно из последствий такого поведения состоит в том, что встраиваемый скрипт не будет иметь доступ к JavaScript библиотекам, загруженным страничным скриптом. Например, если веб-страница загружает jQuery, встраиваемый скрипт не сможет увидеть эту библиотеку.</p> + +<p>Если встраиваемому скрипту необходимо использовать какую-либо JavaScript библиотеку, тогда эта библиотека должна быть загружена, тем же способом, как и встраиваемый скрипт вместе с ним:</p> + +<pre class="brush: json">"content_scripts": [ + { + "matches": ["*://*.mozilla.org/*"], + "js": ["jquery.js", "content-script.js"] + } +]</pre> + +<div class="blockIndicator note"> +<p><strong>Примечание:</strong> Firefox предоставляет некоторое API, позволяющее встраиваемому скрипту иметь доступ к JavaScript объектам, созданным страничным скриптом, и предоставлять свои собственные JavaScript объекты страничному скрипту.</p> + +<p>Смотрите <a href="/ru/docs/Mozilla/Add-ons/WebExtensions/Sharing_objects_with_page_scripts">совместное использование объектов со страничным скриптом</a> для получения дополнительной информации.</p> +</div> + +<h3 id="Доступные_WebExtension_API">Доступные WebExtension API</h3> + +<p>В дополнение стандартному DOM API, встраиваемый скрипт может использовать следующие методы WebExtension APIs:</p> + +<p>Из <code><a href="/ru/Add-ons/WebExtensions/API/extension">extension</a></code>:</p> + +<ul> + <li><code><a href="/ru/Add-ons/WebExtensions/API/extension#getURL()">getURL()</a></code></li> + <li><code><a href="/ru/Add-ons/WebExtensions/API/extension#inIncognitoContext">inIncognitoContext</a></code></li> +</ul> + +<p>Из <code><a href="/ru/Add-ons/WebExtensions/API/runtime">runtime</a></code>:</p> + +<ul> + <li><code><a href="/ru/Add-ons/WebExtensions/API/runtime#connect()">connect()</a></code></li> + <li><code><a href="/ru/Add-ons/WebExtensions/API/runtime#getManifest()">getManifest()</a></code></li> + <li><code><a href="/ru/Add-ons/WebExtensions/API/runtime#getURL()">getURL()</a></code></li> + <li><code><a href="/ru/Add-ons/WebExtensions/API/runtime#onConnect">onConnect</a></code></li> + <li><code><a href="/ru/Add-ons/WebExtensions/API/runtime#onMessage">onMessage</a></code></li> + <li><code><a href="/ru/Add-ons/WebExtensions/API/runtime#sendMessage()">sendMessage()</a></code></li> +</ul> + +<p>Из <code><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/API/i18n">i18n</a></code>:</p> + +<ul> + <li><code><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/API/i18n/getMessage">getMessage()</a></code></li> + <li><code><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/API/i18n/getAcceptLanguages">getAcceptLanguages()</a></code></li> + <li><code><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/API/i18n/getUILanguage">getUILanguage()</a></code></li> + <li><code><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/API/i18n/detectLanguage">detectLanguage()</a></code></li> +</ul> + +<p>Из <code><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/API/menus">menus</a></code>:</p> + +<ul> + <li><code><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/API/menus/getTargetElement">getTargetElement</a></code></li> +</ul> + +<p>Ко всему из <code><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/API/storage">storage</a></code>.</p> + +<h3 id="Работа_с_XHR_и_Fetch">Работа с XHR и Fetch</h3> + +<p>Встраиваемые скрипты могут делать запросы используя <code><a href="/ru/docs/Web/API/XMLHttpRequest">window.XMLHttpRequest</a></code> и <code><a href="/ru/docs/Web/API/Fetch_API">window.fetch()</a></code> API.</p> + +<div class="blockIndicator note"> +<p>В Firefox, запросы, совершаемые из встраиваемого скрипта (например, используя <a href="/ru/docs/Web/API/Fetch_API/Using_Fetch">fetch()</a>) происходят в контексте расширения, так что вам необходимо предоставлять полный URL для доступа к контенту страниц. В Chrome, эти запросы совершаются в контексте страницы, так что URL может быть относительным, например <code>/api</code> будет трансформирован в <code>https://[current page URL]/api</code>.</p> +</div> + +<p>Встраиваемый скрипт имеет точно такие же кросс-доменные привилегии, как и всё остальное расширение: так что если расширение запросило кросс-доменный доступ на какой-либо домен используя <code><a href="/ru/Add-ons/WebExtensions/manifest.json/permissions">permissions</a></code> ключ в manifest.json, тогда его встраиваемый скрипт тоже будет иметь доступ к этому домену.</p> + +<p>Это достигается, предоставляя встраиваемому скрипту более привилегированные XHR and fetch объекты. Что имеет побочный эффект, связанный с отсутствием <code><a href="/ru/docs/Web/HTTP/Headers/Origin">Origin</a></code> и <code><a href="/ru/docs/Web/HTTP/Headers/Referer">Referer</a></code> заголовков, которые имел бы запрос, выполняемый из страничного скрипта. Зачастую это предпочитаемо, для того чтобы предотвратить раскрытие кросс-доменной натуры запроса. Начиная с версии 58 и дальше, расширения, которым необходимо выполнять запросы, которые должны выглядеть будто они отправлены встраиваемым скриптом, могут использовать <code>content.XMLHttpRequest</code> и <code>content.fetch()</code>. Кросс-браузерные расширения должны проверять присутствие этих методов.</p> + +<h2 id="Взаимодействие_с_фоновыми_скриптами">Взаимодействие с фоновыми скриптами</h2> + +<p>Хотя встраиваемые скрипты не могут напрямую использовать большинство методов из WebExtension APIs, они могут взаимодействовать с фоновыми скриптами расширения, используя систему сообщений, и таким образом могут опосредованно иметь доступ к тем же самым API, что и фоновые скрипты.</p> + +<p>Существует два способа общения между фоновым и встраиваемым скриптами: вы можете посылать одиночные сообщения, ожидая необязательного ответа, или вы можете установить долгосрочное соединение на двух сторонах и использовать это соединение для обмена сообщениями.</p> + +<h3 id="Одиночные_сообщения">Одиночные сообщения</h3> + +<p>Для отправки одиночного сообщения и ожидания необязательного ответа, вы можете использовать следующее API:</p> + +<table class="fullwidth-table standard-table"> + <thead> + <tr> + <th scope="row"></th> + <th scope="col">Во встраиваемом скрипте</th> + <th scope="col">В фоновом скрипте</th> + </tr> + </thead> + <tbody> + <tr> + <th scope="row">Отправка сообщения</th> + <td><code><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/API/runtime/sendMessage">browser.runtime.sendMessage()</a></code></td> + <td><code><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/API/Tabs/sendMessage">browser.tabs.sendMessage()</a></code></td> + </tr> + <tr> + <th scope="row">Получение сообщения</th> + <td><code><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/API/runtime/onMessage">browser.runtime.onMessage</a></code></td> + <td><code><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/API/runtime/onMessage">browser.runtime.onMessage</a></code></td> + </tr> + </tbody> +</table> + +<p>Например, представьте встраиваемый скрипт, который прослушивает веб-страницу на нажатие левой кнопки мыши.</p> + +<p>Если нажатие было произведено по ссылке, встраиваемый скрипт отправляет сообщение фоновому скрипту со значение URL в ссылке:</p> + +<pre class="brush: js">// content-script.js + +window.addEventListener("click", notifyExtension); + +function notifyExtension(e) { + if (e.target.tagName != "A") { + return; + } + browser.runtime.sendMessage({"url": e.target.href}); +}</pre> + +<p>Фоновый скрипт ожидает эти сообщения и, при их получении, отображает уведомления, используя <code><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/API/notifications">notifications</a></code> API:</p> + +<pre class="brush: js">// background-script.js + +browser.runtime.onMessage.addListener(notify); + +function notify(message) { + browser.notifications.create({ + "type": "basic", + "iconUrl": browser.extension.getURL("link.png"), + "title": "Вы нажали на ссылку!", + "message": message.url + }); +} +</pre> + +<p>(Этот пример кода частично взят из <a href="https://github.com/mdn/webextensions-examples/tree/master/notify-link-clicks-i18n">notify-link-clicks-i18n</a> примера на GitHub.)</p> + +<h3 id="Обмен_сообщениями_через_постоянное_соединение">Обмен сообщениями через постоянное соединение</h3> + +<p>Отправка одиночных сообщений может стать довольно обременительной, если вы пересылаете много сообщений между встраиваемым и фоновым скриптами. Альтернативное решение в этой ситуации будет установить постоянное соединение между двумя скриптами, и использовать его для обмена сообщениями.</p> + +<p>Каждая из сторон имеет <code><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/API/runtime/Port">runtime.Port</a></code> объект, который они могут использовать для обмена сообщениями.</p> + +<p>Для создания постоянного соединения:</p> + +<ul> + <li>Одна из сторон должна ждать соединений, используя <code><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/API/runtime/onConnect">runtime.onConnect</a></code></li> + <li>Другая сторона должна вызвать: + <ul> + <li><code><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/API/tabs/connect">tabs.connect()</a></code> (при соединении со встраиваемым скриптом); или</li> + <li><code><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/API/runtime/connect">runtime.connect()</a></code> (при соединении с фоновым скриптом).</li> + </ul> + </li> +</ul> + +<p>Результатом вызова этих методов будет возвращение <code><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/API/runtime/Port">runtime.Port</a></code> объекта.</p> + +<ul> + <li><code><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/API/runtime/onConnect">runtime.onConnect</a></code> методу передаётся аргумент, являющийся собственным портом этого скрипта, <code><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/Port">runtime.Port</a></code> объект.</li> +</ul> + +<p>Как только обе стороны имеют порт, они могут:</p> + +<ul> + <li>отправлять сообщения, используя <code>runtime.Port.postMessage()</code>, и</li> + <li>получать сообщения используя <code>runtime.Port.onMessage()</code></li> +</ul> + +<p>Например, сразу после загрузки, нижерасположенный встраиваемый скрипт:</p> + +<ul> + <li>Соединяется с фоновым скриптом</li> + <li>Сохраняет <code>Port</code> в переменную <code>myPort</code></li> + <li>Начинает ожидать и записывать сообщения приходящие на <code>myPort</code></li> + <li>Использует <code>myPort</code> для отправки сообщений на фоновый скрипт, когда пользователь нажимает левую кнопку мыши на документе</li> +</ul> + +<pre class="brush: js">// content-script.js + +var myPort = browser.runtime.connect({name:"port-from-cs"}); +myPort.postMessage({greeting: "Привет из встраиваемого скрипта"}); + +myPort.onMessage.addListener(function(m) { + console.log("Во встраиваемом скрипте, получено сообщение из фонового скрипта: "); + console.log(m.greeting); +}); + +document.body.addEventListener("click", function() { + myPort.postMessage({greeting: "Они кликнули по странице!"}); +});</pre> + +<p>Соответствующий фоновый скрипт:</p> + +<ul> + <li>Ожидает попытки соединения от встраиваемого скрипта</li> + <li>Когда он получает эту попытку соединения: + <ul> + <li>сохраняет свой порт в переменную <code>portFromCS</code></li> + <li>отправляет сообщение встраемому скрипту, используя этот порт</li> + <li>начинает ожидать сообщений, приходящих на порт, и записывать их</li> + </ul> + </li> + <li>Отправляет сообщения на встраиваемый скрипт, используя <code>portFromCS</code>, когда пользователь нажимает кнопку расширения в браузере</li> +</ul> + +<pre class="brush: js">// background-script.js + +var portFromCS; + +function connected(p) { + portFromCS = p; + portFromCS.postMessage({greeting: "Привет, встраиваемый скрипт!"}); + portFromCS.onMessage.addListener(function(m) { + console.log("В фоновом скрипте, получено сообщение от встраиваемого скрипта"); + console.log(m.greeting); + }); +} + +browser.runtime.onConnect.addListener(connected); + +browser.browserAction.onClicked.addListener(function() { + portFromCS.postMessage({greeting: "Они нажали кнопку!"}); +}); +</pre> + +<h4 id="Несколько_встраиваемых_скриптов">Несколько встраиваемых скриптов</h4> + +<p>Если вы имеете несколько встраиваемых скриптов, с которыми вы общающаетесь в одно и то же время, вы бы могли сохранять каждое соединение в массиве.</p> + +<ul> +</ul> + +<pre class="brush: js">// background-script.js + +var ports = [] + +function connected(p) { + ports[p.sender.tab.id] = p + //... +} + +browser.runtime.onConnect.addListener(connected) + +browser.browserAction.onClicked.addListener(function() { + ports.forEach(p => { + p.postMessage({greeting: "Они нажали на кнопку!"}) + }) +}); +</pre> + +<ul> +</ul> + +<h2 id="Взаимодействие_с_веб-страницей">Взаимодействие с веб-страницей</h2> + +<p>Хотя по умолчанию встраиваемые скрипты не имеют доступ к объектам, которые созданны страничными скриптами, они могут взаимодействовать со страничными скриптами, используя <code><a href="/ru/docs/Web/API/Window/postMessage">window.postMessage</a></code> и <code><a href="/ru/docs/Web/API/EventTarget/addEventListener">window.addEventListener</a></code> API.</p> + +<p>Например:</p> + +<pre class="brush: js">// page-script.js + +var messenger = document.getElementById("from-page-script"); + +messenger.addEventListener("click", messageContentScript); + +function messageContentScript() { + window.postMessage({ + direction: "from-page-script", + message: "Сообщение со страницы" + }, "*");</pre> + +<pre class="brush: js">// content-script.js + +window.addEventListener("message", function(event) { + if (event.source == window && + event.data && + event.data.direction == "from-page-script") { + alert("Встраиваемый скрипт получил сообщение: \"" + event.data.message + "\""); + } +});</pre> + +<p>Для просмотра законченного и полностью рабочего примера, <a href="https://mdn.github.io/webextensions-examples/content-script-page-script-messaging.html">посетите эту страницу на GitHub</a> и следуйте инструкциям.</p> + +<div class="warning"> +<p>Заметьте, при взаимодействии с непроверенными страницами этим способом, вам нужно быть очень осторожными . Расширения имеют возможность запускать привилегированный код, который может обладать серьёзными возможностями, и вредоносные веб-страницы легко могут обмануть ваше расширение, ради доступа к этим возможностям.</p> + +<p>Как простейший пример, представим встраиваемый скрипт, который получает сообщение от веб-страницы и делает что-то вроде этого:</p> + +<pre class="brush: js">// content-script.js + +window.addEventListener("message", function(event) { + if (event.source == window && + event.data.direction && + event.data.direction == "from-page-script") { + eval(event.data.message); + } +});</pre> + +<p>Теперь страничный скрипт может запускать любой код со всеми привилегиями встраиваемого скрипта.</p> +</div> + +<h2 id="Использование_eval()_во_встраиваемых_скриптах">Использование <code>eval()</code> во встраиваемых скриптах</h2> + +<p>В Chrome, <code><a href="/ru/docs/Web/JavaScript/Reference/Global_Objects/eval">eval()</a></code> всегда выполняет код в контексте встраиваемого скрипта, а не в контексте веб-страницы.</p> + +<p>В Firefox:</p> + +<ul> + <li>Если вы вызываете <code>eval()</code>, код выполняется в контексте <strong>встраиваемого скрипта</strong>.</li> + <li>Если вы вызываете <code>window.eval()</code>, код выполняется в контексте <strong>страничного скрипта</strong>.</li> +</ul> + +<p>Например, рассмотрите этот встраиваемый скрипт:</p> + +<pre class="brush: js">// content-script.js + +window.eval('window.x = 1;'); +eval('window.y = 2'); + +console.log(`Во встраиваемом скрипте, window.x: ${window.x}`); +console.log(`Во встраиваемом скрипте, window.y: ${window.y}`); + +window.postMessage({ + message: "check" +}, "*");</pre> + +<p>Этот код создаёт переменные <code>x</code> and <code>y</code>, используя <code>window.eval()</code> и <code>eval()</code>, затем записывает их значения, и отправляет сообщение на веб-страницу.</p> + +<p>Получая сообщение, страничный скрипт записывает те же самые переменные:</p> + +<pre class="brush: js">window.addEventListener("message", function(event) { + if (event.source === window && event.data && event.data.message === "check") { + console.log(`In page script, window.x: ${window.x}`); + console.log(`In page script, window.y: ${window.y}`); + } +});</pre> + +<p>В Chrome, в консоли будут записаны следующие строки:</p> + +<pre>In content script, window.x: 1 +In content script, window.y: 2 +In page script, window.x: undefined +In page script, window.y: undefined</pre> + +<p>В Firefox, будут записаны следующие строки:</p> + +<pre>In content script, window.x: undefined +In content script, window.y: 2 +In page script, window.x: 1 +In page script, window.y: undefined</pre> + +<p>Те же правила применимы к <code><a href="/ru/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout">setTimeout()</a></code>, <code><a href="/ru/docs/Web/API/WindowOrWorkerGlobalScope/setInterval">setInterval()</a></code>, и <code><a href="/ru/docs/Web/JavaScript/Reference/Global_Objects/Function">Function()</a></code>.</p> + +<div class="blockIndicator warning"> +<p>Будьте очень осторожны, запуская код в контексте страничного скрипта. Окружение страничного скрипта может контролироваться потенциально зловредным веб-страницей, которая может переопределить объекты, с которыми вы взаимодействуете, так что их поведение станет совершенно непредсказуемым:</p> + +<pre class="brush: js">// page.js переопределяет console.log + +var original = console.log; + +console.log = function() { + original(true); +} +</pre> + + +<pre class="brush: js">// content-script.js вызывает переопределённую версию + +window.eval('console.log(false)'); +</pre> +</div> diff --git a/files/ru/mozilla/add-ons/webextensions/content_security_policy/index.html b/files/ru/mozilla/add-ons/webextensions/content_security_policy/index.html new file mode 100644 index 0000000000..2a620b3a39 --- /dev/null +++ b/files/ru/mozilla/add-ons/webextensions/content_security_policy/index.html @@ -0,0 +1,111 @@ +--- +title: Политика защиты содержимого +slug: Mozilla/Add-ons/WebExtensions/Content_Security_Policy +tags: + - Web-расширение + - Безопасность + - Расширение +translation_of: Mozilla/Add-ons/WebExtensions/Content_Security_Policy +--- +<div>{{AddonSidebar}}</div> + +<div class="summary"> +<p>Политика защиты содержимого (англ. Content Security Policy) автоматически применяется ко всем расширениям, разработанным с использованием WebExtension API. Она ограничивает источники, из которых расширение может загружать <a href="/ru/docs/Web/HTML/Element/script"><script></a> и <a href="/ru/docs/Web/HTML/Element/object"><object></a> ресурсы, и препятствует потенциально опасным практикам, например использованию <code><a href="/ru/docs/Web/JavaScript/Reference/Global_Objects/eval">eval()</a></code>.</p> + +<p>Статья в краткой форме объясняет значимость этой политики, каковы её изначальные правила, как они влияют на расширение, и как расширение может изменять эти правила.</p> +</div> + +<p><a href="/ru/docs/Web/HTTP/CSP">Политика защиты содержимого</a> - это механизм, помогающий веб-сайтам предотвращать выполнение умышленно вредного кода. Веб-сайт устанавливает политику защиты, используя HTTP заголовок, посылаемый с сервера. Главным образом эта политика участвует в устанавливании допустимых источников для загрузки различного вида контента, к примеру, скриптов или встроенных плагинов. Например, веб-сайт может использовать политику защиты для инструктирования браузера, чтобы тот выполнял скрипты, загруженные только с самого сайта, а не из каких-либо других источников. Политика защиты содержимого так же может запретить браузеру использовать потенциально опасные практики, например использование <a href="/ru/docs/Web/JavaScript/Reference/Global_Objects/eval">eval()</a>.</p> + +<p>Так же как веб-сайты, расширения могут загружать контент из различных источников. Например, всплывающее окно расширения определяется HTML документом, и может подключать JavaScript и CSS файлы из различных источников, точно так же, как и нормальная веб-страница:</p> + +<pre class="brush: html"><!DOCTYPE html> + +<html> + <head> + <meta charset="utf-8"> + </head> + + <body> + + <!-- Некоторый HTML контент --> + + <!-- + Подключение сторонней библиотеки. + Смотрите так же https://developer.mozilla.org/ru/docs/Web/Security/Subresource_Integrity. + --> + <script> + src="https://code.jquery.com/jquery-2.2.4.js" + integrity="sha256-iT6Q9iMJYuQiMWNd9lDyBUStIq/8PuOW33aOqmvFpqI=" + crossorigin="anonymous"> + </script> + + <!-- Include my popup's own script--> + <script src="popup.js"></script> + </body> + +</html></pre> + +<p>В сравнении с веб-сайтами, расширения имеют доступ к дополнительному привилегированному API, так что вероятность получения к нему доступа сторонним кодом - это очень большой риск. По этой причине:</p> + +<ul> + <li>довольно строгая политика по защите содержимого применяются изначально. Смотрите <a href="/ru/docs/Mozilla/Add-ons/WebExtensions/Content_Security_Policy#%D0%98%D0%B7%D0%BD%D0%B0%D1%87%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5_%D0%BF%D1%80%D0%B0%D0%B2%D0%B8%D0%BB%D0%B0_%D0%BF%D0%BE_%D0%B7%D0%B0%D1%89%D0%B8%D1%82%D0%B5_%D1%81%D0%BE%D0%B4%D0%B5%D1%80%D0%B6%D0%B8%D0%BC%D0%BE%D0%B3%D0%BE">изначальные правила по защите содержимого</a>.</li> + <li>авторы расширений могут изменять изначальную политику, используя <code>content_security_policy</code> ключ в manifest.json, но даже в этом случае существуют ограничения на возможные разрешения. Для дополнительной информации смотрите <code><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/manifest.json/content_security_policy">content_security_policy</a></code>.</li> +</ul> + +<h2 id="Изначальные_правила_по_защите_содержимого">Изначальные правила по защите содержимого</h2> + +<p>Следующие правила по защите содержимого являются изначальными:</p> + +<pre>"script-src 'self'; object-src 'self';"</pre> + +<p>Они применяются к любому расширению, которое самостоятельно не указывает свою политику защиты, используя <code><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/manifest.json/content_security_policy">content_security_policy</a></code> ключ в manifest.json. Это имеет следующие последствия:</p> + +<ul> + <li> + <p><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/Content_Security_Policy#%D0%A0%D0%B0%D1%81%D0%BF%D0%BE%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_script_%D0%B8_object_%D1%80%D0%B5%D1%81%D1%83%D1%80%D1%81%D0%BE%D0%B2">Вы можете загружать только локальные к расширению <script> и <object> ресурсы.</a></p> + </li> + <li> + <p><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/Content_Security_Policy#eval()_%D0%B8_%D1%82%D0%BE%D0%B2%D0%B0%D1%80%D0%B8%D1%89%D0%B8">Расширению не разрешено выполнять код, представленный в виде JavaScript строк.</a></p> + </li> + <li> + <p><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/Content_Security_Policy#%D0%92%D1%81%D1%82%D1%80%D0%B0%D0%B8%D0%B2%D0%B0%D0%B5%D0%BC%D1%8B%D0%B9_(inline)_JavaScript">Встраиваемый (inline) JavaScript код не будет выполняться.</a></p> + </li> +</ul> + +<h3 id="Расположение_script_и_object_ресурсов">Расположение script и object ресурсов</h3> + +<p>Используя изначальную политику защиты содержимого, вы можете загружать только локальные к расширению <a href="/ru/docs/Web/HTML/Element/script"><script></a> и <a href="/ru/docs/Web/HTML/Element/object"><object></a> ресурсы. Например, рассмотрите эту строку из документа расширения:</p> + +<pre class="brush: html"> <script src="https://code.jquery.com/jquery-2.2.4.js"></script></pre> + +<p>Она не будет загружать запрашиваемый ресурс, и вы не сможете найти ни один ожидаемый от ресурса объект. К этой ситуации существует два решения:</p> + +<ul> + <li> + <p>Скачать этот ресурс, упаковать его в ваше расширение и ссылаться к нему локально.</p> + </li> + <li> + <p>Использовать ключ <code><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/manifest.json/content_security_policy">content_security_policy</a></code> в manifest.json, чтобы позволить загрузку контента из вышеупомянутого источника..</p> + </li> +</ul> + +<h3 id="eval()_и_товарищи">eval() и товарищи</h3> + +<p>Изначальная политика защиты содержимого не позволяет выполнять код из JavaScript строк. Это означает, что следующие примеры кода изначально запрещены:</p> + +<pre class="brush: js">eval("console.log('some output');");</pre> + +<pre class="brush: js">window.setTimeout("alert('Hello World!');", 500);</pre> + +<pre class="brush: js">var f = new Function("console.log('foo');");</pre> + +<h3 id="Встраиваемый_(inline)_JavaScript">Встраиваемый (inline) JavaScript</h3> + +<p>Изначальная политика защиты содержимого не позволяет выполнять JavaScript код, встраиваемый в HTML теги. Это запрещает как выполнение JavaScript кода вложенного прямо в <code><script></code> тег, так и выполнение вписанных в атрибут обработчиков событий, означая, что следующий код так же не будет работать:</p> + +<pre class="brush: html"><script>console.log("foo");</script></pre> + +<pre class="brush: html"><div onclick="console.log('click')">Click me!</div></pre> + +<p>Вместо того, чтобы использовать код <code><body onload="main()"></code> для запуска вашего скрипта после загрузки страницы, поставьте обработчики событий на <a href="/ru/docs/Web/Events/DOMContentLoaded">DOMContentLoaded</a> или <a href="/ru/docs/Web/Events/load">load</a>.</p> diff --git a/files/ru/mozilla/add-ons/webextensions/examples/index.html b/files/ru/mozilla/add-ons/webextensions/examples/index.html new file mode 100644 index 0000000000..e59d8c1f7f --- /dev/null +++ b/files/ru/mozilla/add-ons/webextensions/examples/index.html @@ -0,0 +1,34 @@ +--- +title: Примеры расширений +slug: Mozilla/Add-ons/WebExtensions/Examples +tags: + - WebExtensions + - Веб-расширения + - Интерфейс +translation_of: Mozilla/Add-ons/WebExtensions/Examples +--- +<div>{{AddonSidebar}}</div> + +<p>В целях иллюстрации разработки расширений, мы поддерживаем репозиторий простых демонстрационных расширений по адресу <a href="https://github.com/mdn/webextensions-examples">https://github.com/mdn/webextensions-examples</a>. Данная статья описывает, как использовать эти примеры, и перечисляет их вместе с API Веб-расширений (WebExtensions API), которые они демонстрируют.</p> + +<p>Эти примеры работают в Firefox Nightly: большинство из них работает и в более ранних версиях Firefox, но, чтобы удостовериться, проверьте поле <a href="/en-US/Add-ons/WebExtensions/manifest.json/applications">strict_min_version</a> в файле manifest.json.</p> + +<div class="blockIndicator warning"> +<p>Некоторые примеры работают только на специальных доменах или страницах. Подробности о всех ограничениях представлены в файле readme каждого примера. По умолчанию ни один из примеров не работает в приватных окнах браузера, подробности смотрите в <a href="https://support.mozilla.org/en-US/kb/extensions-private-browsing#w_enabling-or-disabling-extensions-in-private-windows">Extensions in Private Browsing</a>.</p> +</div> + +<p>Если Вы хотите попробовать эти примеры, клонируйте репозиторий, а после этого совершите одно из следующих действий:</p> + +<ol> + <li>Загрузите расширение из папки с его исходниками, используя функцию браузера <a href="/en-US/Add-ons/WebExtensions/Temporary_Installation_in_Firefox">Load Temporary Add-on</a>. Расширение останется загруженным до следующего перезапуска Firefox.</li> + <li>Откройте папку с исходниками расширения в командной строке и используйте команду <code><a href="/en-US/Add-ons/WebExtensions/Getting_started_with_web-ext">web-ext</a></code>, чтобы запустить расширение. Расширение останется загруженным до следующего перезапуска Firefox.</li> + <li>В браузере Firefox используйте <strong>Файл</strong> > <strong>Открыть файл</strong> и найдите расширение в папке <code><a href="https://github.com/mdn/webextensions-examples/tree/master/build">build</a></code>. Папка <code>build</code> содержит построенные и подписанные версии всех примеров. В результате пример установится надолго, как обычное расширение.</li> +</ol> + +<div class="warning"> +<p><strong>Важно</strong>: Пожалуйста, не публикуйте эти примеры Веб-расширений на addons.mozilla.org (AMO) - Вам не нужно подписывать примеры Веб-расширений для того, чтобы их запустить. Просто следуйте шагам, описанным выше.</p> +</div> + +<p>Если Вы хотите сделать свой вклад в репозиторий, <a href="https://github.com/mdn/webextensions-examples/blob/master/CONTRIBUTING.md">отправьте нам pull request!</a></p> + +<p>{{WebExtAllExamples}}</p> diff --git a/files/ru/mozilla/add-ons/webextensions/index.html b/files/ru/mozilla/add-ons/webextensions/index.html new file mode 100644 index 0000000000..c25919686b --- /dev/null +++ b/files/ru/mozilla/add-ons/webextensions/index.html @@ -0,0 +1,109 @@ +--- +title: Расширения браузера +slug: Mozilla/Add-ons/WebExtensions +tags: + - Landing + - WebExtensions + - Дополнения + - Расширения +translation_of: Mozilla/Add-ons/WebExtensions +--- +<div style="">{{AddonSidebar}}</div> + +<p style="">WebExtensions - это кросс-браузерная система разработки дополнений (для браузеров). В значительной степени эта система совместима с <a class="external-icon external" href="https://developer.chrome.com/extensions" style="">API-расширений</a>, поддерживаемых Google Chrome и Opera. Расширения, написанные для этих браузеров, в большинстве случаев будут работать с Firefox или <a href="https://developer.microsoft.com/en-us/microsoft-edge/platform/documentation/extensions/" style="">Microsoft Edge</a> <a href="/ru/Add-ons/WebExtensions/Porting_from_Google_Chrome" style="">лишь с минимальными изменениями</a>. Эти API также полностью совместимы с <a href="/ru/Firefox/Multiprocess_Firefox" style="">мультипоточным Firefox</a>.</p> + +<p style="">Также мы намерены расширять API для поддержки нужд разработчиков дополнений, поэтому, если у вас есть идеи, то мы их с удовольствием выслушаем. Вы можете связаться с нами через <a href="https://mail.mozilla.org/listinfo/dev-addons" style="">dev-addons mailing list</a> или <a href="irc://irc.mozilla.org/webextensions" style="">#webextensions</a> на <a href="https://wiki.mozilla.org/IRC" style="">IRC</a>.</p> + +<div class="row topicpage-table" style=""> +<div class="section" style=""> +<h3 id="Приступая_к_работе" style="">Приступая к работе</h3> + +<ul style=""> + <li style=""><a href="/ru/Add-ons/WebExtensions/What_are_WebExtensions" style="">Что такое WebExtensions?</a></li> + <li style=""><a href="/ru/Add-ons/WebExtensions/Your_first_WebExtension" style="">Первое WebExtension</a></li> + <li style=""><a href="/ru/Add-ons/WebExtensions/Your_second_WebExtension" style="">Второе WebExtension</a></li> + <li style=""><a href="/ru/Add-ons/WebExtensions/Anatomy_of_a_WebExtension" style="">Анатомия WebExtension</a></li> + <li style=""><a href="/ru/Add-ons/WebExtensions/Examples" style="">Примеры WebExtensions</a></li> +</ul> + +<h3 id="How_to" style="">How to</h3> + +<ul style=""> + <li style=""><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/Intercept_HTTP_requests" style="">Перехват HTTP-запросов</a></li> + <li style=""><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/Modify_a_web_page" style="">Изменить веб-страницу</a></li> + <li style=""><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/Add_a_button_to_the_toolbar" style="">Добавить кнопку на панель инструментов</a></li> + <li style=""><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/Implement_a_settings_page" style="">Реализация страницы настроек</a></li> + <li style=""><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/Interact_with_the_clipboard" style="">Работа с буфером обмена</a></li> + <li style="">Работа с вкладками браузера</li> + <li style="">Доступ и изменение закладок</li> + <li style="">Доступ и изменение куки (cookies)</li> +</ul> + +<h3 id="Интерфейс_пользователя" style="">Интерфейс пользователя</h3> + +<ul style=""> + <li style=""><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/user_interface" style="">Введение</a></li> + <li style=""><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/user_interface/Browser_action" style="">Кнопка на панели инструментов</a></li> + <li style=""><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/user_interface/Page_actions" style="">Кнопка в адресной строке</a></li> + <li style=""><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/user_interface/Popups" style="">Всплывающие окна</a></li> + <li style=""><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/user_interface/Context_menu_items" style="">Контекстное меню</a></li> + <li style=""><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/user_interface/Sidebars" style="">Боковые панели </a></li> + <li style=""><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/user_interface/Options_page" style="">Страница настройки дополнения</a></li> + <li style=""><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/user_interface/Bundled_web_pages" style="">Дополнительные web-страницы</a></li> + <li style=""><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/user_interface/Notifications" style="">Уведомления</a></li> + <li style=""><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/user_interface/Omnibox" style="">Угадывание адреса по мере ввода</a></li> + <li style=""><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/user_interface/devtools_panels" style="">Панели инструмента разработчика</a></li> +</ul> + +<h3 id="Основные_понятия" style="">Основные понятия</h3> + +<ul style=""> + <li style=""><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/API" style="">Обзор JavaScript API</a></li> + <li style=""><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/User_interface_components" style="">Компоненты пользовательского интерфейса</a></li> + <li style=""><a href="/ru/Add-ons/WebExtensions/Content_scripts" style="">Скрипты Content scripts</a></li> + <li style=""><a href="/ru/Add-ons/WebExtensions/Match_patterns" style="">Match patterns (шаблоны совпадения)</a></li> + <li style=""><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/Internationalization" style="">Internationalization</a></li> + <li style=""><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/Content_Security_Policy" style="">Content Security Policy (политика безопасного контента)</a></li> + <li style=""><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/Native_messaging" style="">Native messaging (нативный обмен сообщениями)</a></li> +</ul> + +<h3 id="Адаптация" style="">Адаптация</h3> + +<ul style=""> + <li style=""><a href="/ru/Add-ons/WebExtensions/Porting_from_Google_Chrome" style="">Портирование расширения из Google Chrome</a></li> + <li style=""><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/Porting_a_legacy_Firefox_add-on" style="">Портирование старых дополнений Firefox</a></li> + <li style=""><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/Embedded_WebExtensions" style="">Embedded WebExtensions</a></li> + <li style=""><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/Comparison_with_the_Add-on_SDK" style="">Сравнение с Add-on SDK</a></li> + <li style=""><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/Comparison_with_XUL_XPCOM_extensions" style="">Сравнение с XUL/XPCOM-расширениями</a></li> + <li style=""><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/Chrome_incompatibilities" style="">Несовместимость с Chrome</a></li> +</ul> + +<h3 id="Рабочий_процесс_workflow_Firefox" style="">Рабочий процесс (workflow) Firefox</h3> + +<ul style=""> + <li style=""><a href="/en-US/Add-ons/WebExtensions/Temporary_Installation_in_Firefox" style="">Установка</a></li> + <li style=""><a href="/ru/Add-ons/WebExtensions/Debugging" style="">Отладка</a></li> + <li style=""><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/Getting_started_with_web-ext" style="">Начало работы с инструментом Web-ext</a></li> + <li style=""><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/web-ext_command_reference" style="">Справочник команд Web-ext</a></li> + <li style=""><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/WebExtensions_and_the_Add-on_ID" style="">WebExtensions и Add-on ID</a></li> + <li style=""><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/Publishing_your_WebExtension" style="">Публикация вашего дополнения WebExtension</a></li> +</ul> +</div> + +<div class="section" style=""> +<h3 id="Справочники" style="">Справочники</h3> + +<ul style=""> + <li style=""><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/API" style="">Обзор JavaScript API</a></li> + <li style=""><a href="/ru/Add-ons/WebExtensions/Browser_support_for_JavaScript_APIs" style="">Таблицы совместимости браузера для JavaScript APIs</a></li> +</ul> + +<h4 id="JavaScript_APIs" style="">JavaScript APIs</h4> + +<div class="twocolumns" style="">{{ ListSubpages ("/ru/Add-ons/WebExtensions/API") }}</div> + +<h4 id="Manifest_keys" style="">Manifest keys</h4> + +<div class="twocolumns" style="">{{ ListSubpages ("/ru/Add-ons/WebExtensions/manifest.json") }}</div> +</div> +</div> diff --git a/files/ru/mozilla/add-ons/webextensions/intercept_http_requests/index.html b/files/ru/mozilla/add-ons/webextensions/intercept_http_requests/index.html new file mode 100644 index 0000000000..91941e4595 --- /dev/null +++ b/files/ru/mozilla/add-ons/webextensions/intercept_http_requests/index.html @@ -0,0 +1,155 @@ +--- +title: Intercept HTTP requests +slug: Mozilla/Add-ons/WebExtensions/Intercept_HTTP_requests +translation_of: Mozilla/Add-ons/WebExtensions/Intercept_HTTP_requests +--- +<div>{{AddonSidebar}}</div> + +<ul> + <li> + <h2 id="Для_перехвата_HTTP_запросов_используйте_WebExtAPIRefwebRequest_API._Этот_API_позволит_вам_добавлять_слушателей_на_различных_этапах_создания_HTTP_запросов._В_слушателях_вы_можете">Для перехвата HTTP запросов используйте {{WebExtAPIRef("webRequest")}} API. Этот API позволит вам добавлять слушателей, на различных этапах создания HTTP запросов. В слушателях вы можете:</h2> + </li> + <li>получить доступ к заголовкам и телам запроса, к заголовкам ответа</li> + <li>отменять и перенаправлять запросы</li> + <li>изменять запрос и заголовки ответа</li> +</ul> + +<p>В этой статье мы рассмотрим три разных способа использования <code>webRequest</code> модуля:</p> + +<ul> + <li>Логирование URL сделанных запросов.</li> + <li>Перенаправление запросов.</li> + <li>Модификация заголовков запроса.</li> +</ul> + +<h2 id="Логирование_URL_запросов">Логирование URL запросов</h2> + +<p>Создайте новый каталог "requests". В нём создайте файл "manifest.json" со следующим содержимым:</p> + +<pre class="brush: json notranslate">{ + "description": "Demonstrating webRequests", + "manifest_version": 2, + "name": "webRequest-demo", + "version": "1.0", + + "permissions": [ + "webRequest", + "<all_urls>" + ], + + "background": { + "scripts": ["background.js"] + } +}</pre> + +<p>Далее, создайте файл "background.js" со следующим содержимым:</p> + +<pre class="brush: js notranslate">function logURL(requestDetails) { + console.log("Loading: " + requestDetails.url); +} + +browser.webRequest.onBeforeRequest.addListener( + logURL, + {urls: ["<all_urls>"]} +); + +</pre> + +<p>Здесь мы используем {{WebExtAPIRef("webRequest.onBeforeRequest", "onBeforeRequest")}} для вызова функции <code>logURL()</code> перед началом запроса. Функция <code>logURL()</code> берёт URL запроса из объекта event и выводит в консоль браузера. <a href="/en-US/Add-ons/WebExtensions/Match_patterns">Шаблон</a> <code>{urls: ["<all_urls>"]}</code> означает, что мы будем перехватывать HTTP запросы ко всем URL.</p> + +<p>Для проверки <a href="/en-US/Add-ons/WebExtensions/Temporary_Installation_in_Firefox">проинсталлируйте WebExtension</a>, <a href="/en-US/docs/Tools/Browser_Console">откройте консоль браузера</a> и откройте какую-нибудь веб-страницу. В консоли вы должны увидеть URL для каждого ресурса, который запрашивает браузер:</p> + +<p>{{EmbedYouTube("X3rMgkRkB1Q")}}</p> + +<h2 id="Перенаправление_запросов">Перенаправление запросов</h2> + +<p>Теперь давайте использовать <code>webRequest</code> для перенаправления HTTP-запросов. Во-первых, замените manifest.json на это:</p> + +<pre class="brush: json notranslate">{ + + "description": "Demonstrating webRequests", + "manifest_version": 2, + "name": "webRequest-demo", + "version": "1.0", + + "permissions": [ + "webRequest", + "webRequestBlocking", + "https://mdn.mozillademos.org" + ], + + "background": { + "scripts": ["background.js"] + } + +}</pre> + +<p class="result">Единственное изменение здесь заключается в добавлении <code>"webRequestBlocking"</code> в <code>permission</code>. Мы должны запрашивать это дополнительное разрешение каждый раз, когда мы изменяем запрос.</p> + +<p>Затем замените «background.js» следующим образом:</p> + +<pre class="brush: js notranslate">var pattern = "https://mdn.mozillademos.org/*"; + +function redirect(requestDetails) { + console.log("Redirecting: " + requestDetails.url); + return { + redirectUrl: "https://38.media.tumblr.com/tumblr_ldbj01lZiP1qe0eclo1_500.gif" + }; +} + +browser.webRequest.onBeforeRequest.addListener( + redirect, + {urls:[pattern], types:["image"]}, + ["blocking"] +);</pre> + +<p class="result">Опять же, мы используем {{WebExtAPIRef("webRequest.onBeforeRequest", "onBeforeRequest")}} прослушиватель событий для запуска функции непосредственно перед каждым запросом. Эта функция заменит целевой URL на <code>redirectUrl</code> указанный в функции.</p> + +<p class="result">На этот раз мы не перехватываем каждый запрос: опция <code>{urls: [pattern], types: ["image"]}</code> указывает, что мы должны перехватывать запросы (1) для URL-адресов, находящихся в разделе «https://mdn.mozillademos.org / "(2) для ресурсов изображения. Подробнее см. {{WebExtAPIRef ("webRequest.RequestFilter")}}.</p> + +<p>Также обратите внимание, что мы передаем опцию <code>"blocking"</code>: нам нужно передать это, когда мы хотим изменить запрос. Это заставляет функцию прослушивателя блокировать сетевой запрос, поэтому браузер ждет, пока слушатель вернется, прежде чем продолжить. Дополнительную информацию о <code>"blocking"</code> смотрите в документации {{WebExtAPIRef ("webRequest.onBeforeRequest")}}.</p> + +<p>Чтобы проверить это, откройте страницу в MDN, которая содержит много изображений (например, https://developer.mozilla.org/en-US/docs/Tools/Network_Monitor), перезагрузите WebExtension и перезагрузите страницу MDN :</p> + +<p>{{EmbedYouTube("ix5RrXGr0wA")}}</p> + +<h2 id="Modifying_request_headers">Modifying request headers</h2> + +<p>Finally we'll use <code>webRequest</code> to modify request headers. In this example we'll modify the "User-Agent" header so the browser identifies itself as Opera 12.16, but only when visiting pages under http://useragentstring.com/".</p> + +<p>The "manifest.json" can stay the same as in the previous example.</p> + +<p>Replace "background.js" with code like this:</p> + +<pre class="brush: js notranslate">var targetPage = "http://useragentstring.com/*"; + +var ua = "Opera/9.80 (X11; Linux i686; Ubuntu/14.10) Presto/2.12.388 Version/12.16"; + +function rewriteUserAgentHeader(e) { + for (var header of e.requestHeaders) { + if (header.name.toLowerCase() == "user-agent") { + header.value = ua; + } + } + return {requestHeaders: e.requestHeaders}; +} + +browser.webRequest.onBeforeSendHeaders.addListener( + rewriteUserAgentHeader, + {urls: [targetPage]}, + ["blocking", "requestHeaders"] +);</pre> + +<p>Here we use the {{WebExtAPIRef("webRequest.onBeforeSendHeaders", "onBeforeSendHeaders")}} event listener to run a function just before the request headers are sent.</p> + +<p>The listener function will be called only for requests to URLs matching the <code>targetPage</code> <a href="/en-US/Add-ons/WebExtensions/Match_patterns">pattern</a>. Also note that we've again passed <code>"blocking"</code> as an option. We've also passed <code>"requestHeaders"</code>, which means that the listener will be passed an array containing the request headers that we expect to send. See {{WebExtAPIRef("webRequest.onBeforeSendHeaders")}} for more information on these options.</p> + +<p>The listener function looks for the "User-Agent" header in the array of request headers, replaces its value with the value of the <code>ua</code> variable, and returns the modified array. This modified array will now be sent to the server.</p> + +<p>To test it out, open <a href="http://useragentstring.com/">useragentstring.com</a> and check that it identifies the browser as Firefox. Then reload the add-on, reload <a href="http://useragentstring.com/">useragentstring.com</a>, and check that Firefox is now identified as Opera:</p> + +<p>{{EmbedYouTube("SrSNS1-FIx0")}}</p> + +<h2 id="Learn_more">Learn more</h2> + +<p>To learn about all the things you can do with the <code>webRequest</code> API, see its <a href="/en-US/Add-ons/WebExtensions/API/WebRequest">reference documentation</a>.</p> diff --git a/files/ru/mozilla/add-ons/webextensions/manifest.json/background/index.html b/files/ru/mozilla/add-ons/webextensions/manifest.json/background/index.html new file mode 100644 index 0000000000..876f151d60 --- /dev/null +++ b/files/ru/mozilla/add-ons/webextensions/manifest.json/background/index.html @@ -0,0 +1,115 @@ +--- +title: ключ background +slug: Mozilla/Add-ons/WebExtensions/manifest.json/background +tags: + - WebExtensions + - Веб-расширения + - Дополнения + - Манифест + - Расширения +translation_of: Mozilla/Add-ons/WebExtensions/manifest.json/background +--- +<div>{{AddonSidebar}}</div> + +<table class="fullwidth-table standard-table"> + <tbody> + <tr> + <th scope="row" style="width: 30%;">Тип</th> + <td><code>Object</code></td> + </tr> + <tr> + <th scope="row">Обязательный</th> + <td>Нет</td> + </tr> + <tr> + <th scope="row">Пример</th> + <td> + <pre class="brush: json no-line-numbers"> +"background": { + "scripts": ["background.js"] +}</pre> + </td> + </tr> + </tbody> +</table> + +<p><span id="result_box" lang="ru"><span>Используйте ключ <code>background</code> для включения одного или нескольких фоновых сценариев </span></span><span lang="ru"><span>и, возможно, фоновой страницы в ваше расширение.</span></span></p> + +<p><span id="result_box" lang="ru"><span>Фоновые сценарии </span></span>—<span lang="ru"><span> это место для размещения кода, который должен поддерживать долгосрочное состояние или выполнять долгосрочные операции, независимо от времени жизни каких-либо конкретных веб-страниц или окон браузера.</span></span></p> + +<p><span id="result_box" lang="ru"><span>Фоновые сценарии загружаются сразу при загрузке расширения и остаются загруженными до тех пор, пока расширение не будет отключено или удалено.</span> <span>Вы можете использовать любой API-интерфейс WebExtension в сценарии, если вы запросили необходимые</span></span> <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions">права (permissions)</a>.</p> + +<p><span id="result_box" lang="ru"><span>Дополнительную информацию см. В разделе «Справочные страницы»</span></span> в статье <a href="/ru/Add-ons/WebExtensions/Anatomy_of_a_WebExtension#Background_pages">Анатомия расширения</a>.</p> + +<p>Ключ <code>background</code> это объект, у которого есть два следующих необязательных свойства:</p> + +<table class="standard-table"> + <tbody> + <tr> + <td><code>scripts</code></td> + <td> + <p>Массив строк, каждая из которых представляет собой путь к файлу JavaScript. Путь к этим файлам указывают относительно папки, в которой находится файл manifest.json. Это скрипты, которые будут выполняться в фоновой странице расширения.</p> + + <p>У этих скриптов общий глобальный контекст объекта <code>window</code>.</p> + + <p>Скрипты загружаются в том порядке, в котором они указаны в массиве.</p> + + <p>Если вы указали значения с помощью свойства <code>scripts</code>, будет создана пустая фоновая страница, в которой будут работать все эти скрипты.</p> + + <div class="note"> + <p><strong>Примечание:</strong> Если вы хотите добавить скрипт из удалённого расположения с помощью тега <code><script></code> (например, <code><script src = "https://code.jquery.com/jquery-1.7.1.min.js"></code>), может также понадобиться изменить значение ключа <code><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/manifest.json/content_security_policy">content_security_policy</a></code> в файле manifest.json вашего расширения.</p> + </div> + + <div class="note"> + <p><strong>Примечание:</strong> В Firefox до версии 50, когда открыт отладчик, скрипты не всегда загружаются в том порядке, в котором они расположены в массиве. Чтобы обойти этот баг, можно использовать свойство <code>page</code> (вместо <code>scripts</code>) и добавить фоновые скрипты с помощью тегов <code><script></code> в странице HTML. Этот баг починен в Firefox 50. Начиная с этой версии, скрипты всегда загружаются в том порядке, в котором они следуют в массиве.</p> + </div> + </td> + </tr> + <tr> + <td><code>page</code></td> + <td> + <p>Если вам нужно какое-нибудь содержимое HTML-страницы, можно определить свою фоновую страницу с помощью свойства <code>page</code>. Это строка, которая представляет собой путь к файлу документа HTML, заданный относительно расположения файла manifest.json. Этот файл HTML должен находиться внутри вашего расширения.</p> + + <p>Если используется это свойство, то уже нельзя добавлять скрипты с помощью свойства <code>scripts</code>. Вместо этого нужно добавлять скрипты в страницу — точно таким же образом, как в обычную веб-страницу.</p> + </td> + </tr> + </tbody> +</table> + +<p>Ключ <code>background</code> также может содержать следующее необязательное свойство:</p> + +<table class="standard-table"> + <tbody> + <tr> + <td><code>persistent</code></td> + <td> + <p>Двоичное значение (<code>Boolean</code>).</p> + + <ul> + <li><code>true</code> определяет, что фоновая страница должна храниться в памяти с момента, когда загрузилось расширение или запустился браузер и до того, как расширение будет удалено или выключено, или браузер будет закрыт (то есть фоновая страница постоянна).</li> + <li><code>false</code> определяет, что фоновая страница может быть выгружена из памяти во время бездействия и создана заново, когда будет нужна. Такие фоновые страницы часто называются «Страницами Событий» (Event Pages) — потому, что они загружаются в память только для того, чтобы обрабатывать события, для которых в фоновых скриптах назначены функции-обработчики. Зарегистрированные события остаются когда фоновая страница выгружена из памяти, но остальные значения сбрасываются. Если нужно хранить постоянные данные при использовании страницы событий, используйте <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage">storage API</a>.</li> + </ul> + </td> + </tr> + </tbody> +</table> + +<h2 id="Примеры">Примеры</h2> + +<pre class="brush: json no-line-numbers"> "background": { + "scripts": ["jquery.js", "my-background.js"] + }</pre> + +<p>Загрузит два фоновых скрипта.</p> + +<pre class="brush: json"> "background": { + "page": "my-background.html" + }</pre> + +<p>Загрузит файл фоновой страницы.</p> + +<h2 id="Совместимость_с_браузерами">Совместимость с браузерами</h2> + +<p class="hidden">Таблица совместимости сгенерирована из структурированных данных. Если вы хотите дополнить эту информацию, пожалуйста, посетите <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> и отправьте нам pull request.</p> + +<p>{{Compat("webextensions.manifest.background", 10)}}</p> diff --git a/files/ru/mozilla/add-ons/webextensions/manifest.json/content_security_policy/index.html b/files/ru/mozilla/add-ons/webextensions/manifest.json/content_security_policy/index.html new file mode 100644 index 0000000000..0efe1fe0d5 --- /dev/null +++ b/files/ru/mozilla/add-ons/webextensions/manifest.json/content_security_policy/index.html @@ -0,0 +1,117 @@ +--- +title: content_security_policy +slug: Mozilla/Add-ons/WebExtensions/manifest.json/content_security_policy +tags: + - Web-расширение + - Безопасность + - Расширение +translation_of: Mozilla/Add-ons/WebExtensions/manifest.json/content_security_policy +--- +<div>{{AddonSidebar}}</div> + +<table class="fullwidth-table standard-table"> + <tbody> + <tr> + <th scope="row" style="width: 30%;">Тип</th> + <td><code>Строка</code></td> + </tr> + <tr> + <th scope="row">Обязателен</th> + <td>Нет</td> + </tr> + <tr> + <th scope="row">Пример</th> + <td> + <pre class="brush: json no-line-numbers"> +"content_security_policy": "default-src 'self'"</pre> + </td> + </tr> + </tbody> +</table> + +<p>Политика защиты содержимого применяется к расширениям автоматически. Изначальная политика защиты содержимого ограничивает источники, из которых расширение может загружать <a href="/ru/docs/Web/HTML/Element/script"><script></a> и <a href="/ru/docs/Web/HTML/Element/object"><object></a> ресурсы, а так же препятствует потенциально опасным практикам, например использованию <code><a href="/ru/docs/Web/JavaScript/Reference/Global_Objects/eval">eval()</a></code>. Смотрите <a href="/ru/docs/Mozilla/Add-ons/WebExtensions/Content_Security_Policy#Изначальные_правила_по_защите_содержимого">изначальные правила защиты содержимого</a>, чтобы узнать о конкретных последствиях применения изначальных правил.</p> + +<p>Ключ <code>"content_security_policy"</code> в manifest.json используется для ослабления или ужесточения политики защиты содержимого. Значения для этого ключа устанавливаются в точно таком же виде, как и для Content-Security-Policy HTTP заголовка. Смотрите <a href="/ru/docs/Web/HTTP/CSP">Использование политики содержимого</a> для получения общего представления о синтаксисе для написания правил политики.</p> + +<p>Примеры использования ключа могут включать в себя:</p> + +<ul> + <li>Разрешение на загрузку не запакованных в расширение скриптов и объектов, предоставляя их URL в {{CSP("script-src")}} и {{CSP("object-src")}} директивах.</li> + <li>Разрешение на выполнение встраиваемых скриптов, <a href="/ru/docs/Web/HTTP/Headers/Content-Security-Policy/script-src#Unsafe_inline_script">предоставляя hash скрипта в <code>"script-src"</code> директиве</a>.</li> + <li>Разрешение на использование <code>eval()</code> и похожих функций, добавляя <code>'unsafe-eval'</code> в {{CSP("script-src")}} директиву.</li> + <li>Ограничение допускаемых источников загрузки для других видов контента, например картинок или файлов стилей, используя соответствующие <a href="/ru/docs/Web/HTTP/Headers/Content-Security-Policy">директивы</a>.</li> +</ul> + +<p>При написании правил по защите содержимого, вы имеете некоторые ограничения:</p> + +<ul> + <li>Правило должно включать в себя {{CSP("script-src")}} и {{CSP("object-src")}} директивы, и {{CSP("script-src")}} директива должна включать ключевое слово <code>'self'</code>.</li> + <li>Удалённые источники должны иметь <code>https:</code> схему.</li> + <li>Удалённые источники не должны определяться через универсальный символ <code>*</code> со следующим за ним <a href="https://publicsuffix.org/list/">доменным публичным суффиксом</a> (например "*.co.uk" и "*.blogspot.com" являются не разрешёнными значениями, но "*.foo.blogspot.com" разрешёно).</li> + <li>У всех источников должен быть определён хост.</li> + <li>Единственные позволенные схемы источников: <code>blob:</code>, <code>filesystem:</code>, <code>moz-extension:</code> и <code>https:</code>.</li> + <li>Единственные позволенные <a href="/ru/docs/Web/HTTP/Headers/Content-Security-Policy/default-src#Sources">ключевые слова</a>: <code>'none'</code>, <code>'self'</code> и <code>'unsafe-eval'</code>.</li> +</ul> + +<h2 id="Примеры">Примеры</h2> + +<h3 id="Работающие_примеры">Работающие примеры</h3> + +<p>Разрешает загрузку скриптов из "https://example.com": <sup>(<em>смотрите примечание</em> <a href="#exampleNote_1">1</a>)</sup></p> + +<pre class="brush: json no-line-numbers">"content_security_policy": "script-src 'self' https://example.com; object-src 'self'"</pre> + +<p>Разрешает загрузку скриптов из любого субдомена "jquery.com":</p> + +<pre class="brush: json no-line-numbers">"content_security_policy": "script-src 'self' https://*.jquery.com; object-src 'self'"</pre> + +<p>Разрешает использование <a href="/ru/docs/Mozilla/Add-ons/WebExtensions/Content_Security_Policy#eval()_и_товарищи"><code>eval()</code> и его товарищей</a>:</p> + +<pre class="brush: json no-line-numbers">"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self';"</pre> + +<p>Разрешает встроить скрипт: <code>"<script>alert('Hello, world.');</script>"</code>:</p> + +<pre class="brush: json no-line-numbers">"content_security_policy": "script-src 'self' 'sha256-qznLcsROx4GACP2dm0UCKCzCG+HiZ1guq6ZZDob/Tng='; object-src 'self'"</pre> + +<p>Оставляет изначальные правила, но так же требует, чтобы могли загружаться только изображения, запакованные вместе с расширением:</p> + +<pre class="brush: json no-line-numbers">"content_security_policy": "script-src 'self'; object-src 'self'; img-src 'self'"</pre> + +<p>Разрешает загрузку только тех ресурсов, которые были запакованы вместе с расширением:</p> + +<pre class="brush: json no-line-numbers">"content_security_policy": "default-src 'self'" +</pre> + +<h3 id="Недопустимые_примеры">Недопустимые примеры</h3> + +<p>Политика, не включающая <code>"object-src"</code> директиву:</p> + +<pre class="brush: json no-line-numbers">"content_security_policy": "script-src 'self' https://*.jquery.com;"</pre> + +<p>Политика, не включающая ключевое слово <code>"self"</code> в <code>"script-src"</code> директиве:</p> + +<pre class="brush: json no-line-numbers">"content_security_policy": "script-src https://*.jquery.com; object-src 'self'"</pre> + +<p>Использование отличной от <code>https</code> схемы для загрузки удалённых ресурсов:</p> + +<pre class="brush: json no-line-numbers">"content_security_policy": "script-src 'self' http://code.jquery.com; object-src 'self'"</pre> + +<p>Использование универсального символа в связке с публичным доменным суффиксом:</p> + +<pre class="brush: json no-line-numbers">"content_security_policy": "script-src 'self' https://*.blogspot.com; object-src 'self'"</pre> + +<p>Указание схемы без хоста:</p> + +<pre class="brush: json no-line-numbers">"content_security_policy": "script-src 'self' https:; object-src 'self'"</pre> + +<p>Использование неподдерживаемого ключевого слова <code>'unsafe-inline'</code>:</p> + +<pre class="brush: json no-line-numbers">"content_security_policy": "script-src 'self' 'unsafe-inline'; object-src 'self'"</pre> + +<p><span id="exampleNote_1">1. <em>Примечание: Работающие примеры демонстрируют правильное написание политики защиты содержимого. Тем не менее, расширения с политикой, включающей ключевые словами 'unsafe-eval', 'unsafe-inline', разрешающей загрузку удалённых скриптов и ресурсов, а так же blob файлов не будут допущены к распространению на addons.mozilla.org из-за значительных проблем с безопасностью.</em></span></p> + +<h2 id="Browser_compatibility">Browser compatibility</h2> + +<p class="hidden">The compatibility table in this page is generated from structured data. If you'd like to contribute to the data, please check out <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> and send us a pull request.</p> + +<p>{{Compat("webextensions.manifest.content_security_policy")}}</p> diff --git a/files/ru/mozilla/add-ons/webextensions/manifest.json/description/index.html b/files/ru/mozilla/add-ons/webextensions/manifest.json/description/index.html new file mode 100644 index 0000000000..46c7310329 --- /dev/null +++ b/files/ru/mozilla/add-ons/webextensions/manifest.json/description/index.html @@ -0,0 +1,44 @@ +--- +title: description +slug: Mozilla/Add-ons/WebExtensions/manifest.json/description +tags: + - Reference + - WebExtensions + - description +translation_of: Mozilla/Add-ons/WebExtensions/manifest.json/description +--- +<div>{{AddonSidebar}}</div> + +<table class="fullwidth-table standard-table"> + <tbody> + <tr> + <th scope="row" style="width: 30%;">Тип</th> + <td><code>String</code></td> + </tr> + <tr> + <th scope="row">Обязательный</th> + <td>Нет</td> + </tr> + <tr> + <th scope="row">Пример</th> + <td> + <pre class="brush: json no-line-numbers"> +"description": "Заменяет картинки на картинки с котиками."</pre> + </td> + </tr> + </tbody> +</table> + +<p>Краткое описание дополнения, предназначенное для показа в интерфейсе браузера.</p> + +<p>Это <a href="/ru/Add-ons/WebExtensions/Internationalization#Internationalizing_manifest.json">локализуемое свойство</a>.</p> + +<h2 id="Пример">Пример</h2> + +<pre class="brush: json no-line-numbers">"description": "Заменяет картинки на картинки с котиками."</pre> + +<h2 id="Совместимость_с_браузерами">Совместимость с браузерами</h2> + +<p class="hidden">The compatibility table in this page is generated from structured data. If you'd like to contribute to the data, please check out <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> and send us a pull request.</p> + +<p>{{Compat("webextensions.manifest.description")}}</p> diff --git a/files/ru/mozilla/add-ons/webextensions/manifest.json/icons/index.html b/files/ru/mozilla/add-ons/webextensions/manifest.json/icons/index.html new file mode 100644 index 0000000000..4352adba81 --- /dev/null +++ b/files/ru/mozilla/add-ons/webextensions/manifest.json/icons/index.html @@ -0,0 +1,80 @@ +--- +title: ключ icons +slug: Mozilla/Add-ons/WebExtensions/manifest.json/icons +tags: + - Icons + - WebExtensions + - Веб-расширение + - Дополнения + - Расширения +translation_of: Mozilla/Add-ons/WebExtensions/manifest.json/icons +--- +<div>{{AddonSidebar}}</div> + +<table class="fullwidth-table standard-table"> + <tbody> + <tr> + <th scope="row" style="width: 30%;">Тип</th> + <td><code>Object</code></td> + </tr> + <tr> + <th scope="row">Обязательный</th> + <td>Нет</td> + </tr> + <tr> + <th scope="row">Пример</th> + <td> + <pre class="brush: json"> +"icons": { + "48": "icon.png", + "96": "icon@2x.png" +}</pre> + </td> + </tr> + </tbody> +</table> + +<p>Ключ <code>icons</code> определяет, какие иконки (значки) будет использовать ваше дополнение. Эти иконки будут использоваться при показе вашего дополнения в менеджерах компонентов, таких как Менеджер Дополнений.</p> + +<p>Он содержит информацию вида ключ-значение со следующими данными: размер изображения в пикселях и путь к соответствующему изображению относительно директории, в которой содержится дополнение.</p> + +<p>Если иконки не предоставлены с помощью этого ключа <code>icons</code>, вместо них будет использоваться стандартная иконка для расширений.</p> + +<p>Вы должны указать по крайней мере одну главную иконку, в идеале размером 48х48 пикселей. Эта иконка будет использоваться по умолчанию в Менеджере Дополнений. Конечно, можно добавить иконки любого размера, и Firefox постарается найти лучшую из них для показа в разных компонентах.</p> + +<p>Firefox учитывает разрешение экрана, когда выбирает иконку. Чтобы получить наилучший результат на мониторах с большим разрешением, использующих технологию Retina display, добавьте для каждой иконки версию с размерами в два раза больше.</p> + +<h2 id="Пример">Пример</h2> + +<p>Ключи в объекте icons определяют размеры иконок в пикселях, значения - относительный путь к файлам с изображениями. Этот пример содержит иконку размером 48х48 пикселей и увеличенную версию для мониторов высокого разрешения.</p> + +<pre class="brush: json">"icons": { + "48": "icon.png", + "96": "icon@2x.png" +}</pre> + +<h2 id="SVG">SVG</h2> + +<p>В качестве иконки можно использовать файл SVG. Тогда браузер будет масштабировать иконку так, чтобы она подходила к компоненту, в котором она используется. Но есть два предостережения:</p> + +<ol> + <li>В файле изображения должен быть определён viewBox. Например: + <pre class="brush: html"><svg viewBox="0 0 48 48" width="48" height="48" ...</pre> + </li> + <li>Даже в том случае, если используется всего один файл, нужно определить его для разных размеров иконки в манифесте. Например: + <pre class="brush: json">"icons": { + "48": "icon.svg", + "96": "icon.svg" +}</pre> + </li> +</ol> + +<div class="note"> +<p>Если вы используете программу Inkscape или подобную ей для создания SVG, сохраняйте изображение как "Простой SVG". Иначе Firefox может запутаться во множестве специальных пространств имён и не отобразить картинку.</p> +</div> + +<h2 id="Совместимость_с_браузерами">Совместимость с браузерами</h2> + +<p class="hidden">Таблица совместимости на этой странице сгенерирована из структурированных данных. Если вы хотите дополнить эти данные, пожалуйста, навестите <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> и отправьте нам pull request.</p> + +<p>{{Compat("webextensions.manifest.icons")}}</p> diff --git a/files/ru/mozilla/add-ons/webextensions/manifest.json/index.html b/files/ru/mozilla/add-ons/webextensions/manifest.json/index.html new file mode 100644 index 0000000000..661cf31e12 --- /dev/null +++ b/files/ru/mozilla/add-ons/webextensions/manifest.json/index.html @@ -0,0 +1,139 @@ +--- +title: manifest.json +slug: Mozilla/Add-ons/WebExtensions/manifest.json +tags: + - WebExtensions + - manifest.json + - Веб-расширения + - Дополнения + - Обзор + - Расширения +translation_of: Mozilla/Add-ons/WebExtensions/manifest.json +--- +<p>{{AddonSidebar}}</p> + +<div class="blockIndicator note"> +<p>В этой статье описан файл manifest.json для веб-расширений. Если Вы ищете информацию о manifest.json для Прогрессивных веб-приложений (PWAs), смотрите статью <a href="/ru/docs/Web/Манифест">Манифест веб-приложения</a>.</p> +</div> + +<p>Файл <code>manifest.json</code> это единственный файл, который обязательно должен быть в каждом расширении, использующем API Веб-расширения (WebExtension APIs).</p> + +<p>Используя manifest.json, Вы определяете базовые метаданные о расширении, такие как имя и версия. Также можно определить некоторые аспекты функционала (такие, как фоновые скрипты, контент скрипты и действия браузера).</p> + +<p>Это файл в формате <a href="ru/docs/Словарь/JSON">JSON</a>, но в нём можно использовать комментарии, каждая строка которых должна начинаться с "<code>//</code>".</p> + +<h2 id="Список_полей_manifest.json">Список полей manifest.json</h2> + +<p>Поддерживаемые <code>manifest.json</code> поля перечислены ниже:</p> + +<div class="twocolumns">{{ListSubpages ("/en-US/Add-ons/WebExtensions/manifest.json") }}</div> + +<h3 class="index" id="Примечания_о_полях_manifest.json">Примечания о полях manifest.json</h3> + +<ul> + <li>Поля <code>"manifest_version"</code>, <code>"version"</code> и <code>"name"</code> являются обязательными.</li> + <li>Поле <code>"default_locale"</code> обязательно, если есть папка <code>"_locales"</code>, иначе его нужно опустить.</li> + <li>Поле <code>"browser_specific_settings"</code> не поддерживается Google Chrome.</li> +</ul> + +<h3 id="Доступ_к_полям_manifest.json_во_время_выполнения">Доступ к полям manifest.json во время выполнения</h3> + +<p>C помощью функции JavaScript {{WebExtAPIRef("runtime.getManifest()")}} можно получить доступ к файлу манифеста расширения:</p> + +<pre class="brush: js; no-line-numbers">browser.runtime.getManifest().version;</pre> + +<h2 id="Пример">Пример</h2> + +<p>В следующем блоке показан основной синтаксис некоторых часто используемых полей манифеста.</p> + +<div class="blockIndicator note"> +<p><strong>Примечание:</strong> Этот пример не рассчитан для того, чтобы его скопировали и вставили в файл реального проекта. Выбор нужных полей зависит от особенностей создаваемого расширения.</p> +</div> + +<p>Если нужны примеры готовых расширений, смотрите <a href="/ru/docs/Mozilla/Add-ons/WebExtensions/Examples">Примеры расширений</a>.</p> + +<pre class="brush: json;">{ + "browser_specific_settings": { + "gecko": { + "id": "addon@example.com", + "strict_min_version": "42.0" + } + }, + + "background": { + "scripts": ["jquery.js", "my-background.js"], + }, + + "browser_action": { + "default_icon": { + "19": "button/geo-19.png", + "38": "button/geo-38.png" + }, + "default_title": "Whereami?", + "default_popup": "popup/geo.html" + }, + + "commands": { + "toggle-feature": { + "suggested_key": { + "default": "Ctrl+Shift+Y", + "linux": "Ctrl+Shift+U" + }, + "description": "Send a 'toggle-feature' event" + } + }, + + "content_security_policy": "script-src 'self' https://example.com; object-src 'self'", + + "content_scripts": [ + { + "exclude_matches": ["*://developer.mozilla.org/*"], + "matches": ["*://*.mozilla.org/*"], + "js": ["borderify.js"] + } + ], + + "default_locale": "en", + + "description": "...", + + "icons": { + "48": "icon.png", + "96": "icon@2x.png" + }, + + "manifest_version": 2, + + "name": "...", + + "page_action": { + "default_icon": { + "19": "button/geo-19.png", + "38": "button/geo-38.png" + }, + "default_title": "Whereami?", + "default_popup": "popup/geo.html" + }, + + "permissions": ["webNavigation"], + + "version": "0.1", + + "user_scripts": { + "api_script": "apiscript.js", + }, + + "web_accessible_resources": ["images/my-image.png"] +}</pre> + +<h2 id="Совместимость_с_браузерами">Совместимость с браузерами</h2> + +<p>Для полного обзора всех полей манифеста и их содержимого, смотрите <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Browser_compatibility_for_manifest.json">полную таблицу совместимости <code>manifest.json</code></a> с браузерами.</p> + +<div class="hidden">Таблица совместимости сгенерирована из структурированных данных. Если Вы хотите дополнить эти данные, пожалуйста, посмотрите <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> и отправьте нам pull request.</div> + +<p>{{Compat("webextensions.manifest")}}</p> + +<h2 id="Смотрите_также">Смотрите также</h2> + +<p>{{WebExtAPIRef("permissions")}} JavaScript API</p> diff --git a/files/ru/mozilla/add-ons/webextensions/manifest.json/manifest_version/index.html b/files/ru/mozilla/add-ons/webextensions/manifest.json/manifest_version/index.html new file mode 100644 index 0000000000..1cf7875003 --- /dev/null +++ b/files/ru/mozilla/add-ons/webextensions/manifest.json/manifest_version/index.html @@ -0,0 +1,45 @@ +--- +title: ключ manifest_version +slug: Mozilla/Add-ons/WebExtensions/manifest.json/manifest_version +tags: + - Reference + - WebExtensions + - manifest_version +translation_of: Mozilla/Add-ons/WebExtensions/manifest.json/manifest_version +--- +<p>{{AddonSidebar}}</p> + +<table class="fullwidth-table standard-table"> + <tbody> + <tr> + <th scope="row" style="width: 30%;">Тип</th> + <td><code>Number</code></td> + </tr> + <tr> + <th scope="row">Обязательный</th> + <td>Да</td> + </tr> + <tr> + <th scope="row">Пример</th> + <td> + <pre class="brush: json"> +"manifest_version": 2</pre> + </td> + </tr> + </tbody> +</table> + +<p>Этот ключ определяет версию файла "manifest.json", использующуюся в этом дополнении.</p> + +<p>В настоящее время всегда должен быть 2</p> + +<h2 id="Пример">Пример</h2> + +<pre class="brush: json">"manifest_version": 2 +</pre> + +<h2 id="Совместимость_с_браузерами">Совместимость с браузерами</h2> + +<p class="hidden">Таблица совместимости на этой странице сгенерирована из структурированных данных. Если вы хотите дополнить эти данные, пожалуйста, посетите <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> и отправьте нам pull request.</p> + +<p>{{Compat("webextensions.manifest.manifest_version")}}</p> diff --git a/files/ru/mozilla/add-ons/webextensions/manifest.json/name/index.html b/files/ru/mozilla/add-ons/webextensions/manifest.json/name/index.html new file mode 100644 index 0000000000..59c50eafdd --- /dev/null +++ b/files/ru/mozilla/add-ons/webextensions/manifest.json/name/index.html @@ -0,0 +1,44 @@ +--- +title: ключ name +slug: Mozilla/Add-ons/WebExtensions/manifest.json/name +tags: + - Reference + - WebExtensions + - name +translation_of: Mozilla/Add-ons/WebExtensions/manifest.json/name +--- +<div>{{AddonSidebar}}</div> + +<table class="fullwidth-table standard-table"> + <tbody> + <tr> + <th scope="row" style="width: 30%;">Тип</th> + <td><code>String</code></td> + </tr> + <tr> + <th scope="row">Обязательный</th> + <td>Да</td> + </tr> + <tr> + <th scope="row">Пример</th> + <td> + <pre class="brush: json"> +"name": "My Extension"</pre> + </td> + </tr> + </tbody> +</table> + +<p>Имя расширения. Используется для идентификации расширения в интерфейсе браузера и на сайтах, подобных addons.mozilla.org.</p> + +<p>Это <a href="/en-US/Add-ons/WebExtensions/Internationalization#Internationalizing_manifest.json">локализуемое свойство</a>.</p> + +<h2 id="Пример">Пример</h2> + +<pre class="brush: json">"name": "My Extension"</pre> + +<h2 id="Совместимость_с_браузерами">Совместимость с браузерами</h2> + +<p class="hidden">Таблица совместимости на этой странице сгенерирована из структурированных данных. Если вы хотите дополнить эти данные, пожалуйста, посетите <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> и отправьте нам pull request.</p> + +<p>{{Compat("webextensions.manifest.name")}}</p> diff --git a/files/ru/mozilla/add-ons/webextensions/manifest.json/permissions/index.html b/files/ru/mozilla/add-ons/webextensions/manifest.json/permissions/index.html new file mode 100644 index 0000000000..bfe2556a86 --- /dev/null +++ b/files/ru/mozilla/add-ons/webextensions/manifest.json/permissions/index.html @@ -0,0 +1,193 @@ +--- +title: permissions +slug: Mozilla/Add-ons/WebExtensions/manifest.json/permissions +tags: + - Web-расширение + - Полномочия + - Расширение +translation_of: Mozilla/Add-ons/WebExtensions/manifest.json/permissions +--- +<p>{{AddonSidebar}}</p> + +<table class="fullwidth-table standard-table"> + <tbody> + <tr> + <th scope="row" style="width: 30%;">Тип</th> + <td><code>Массив</code></td> + </tr> + <tr> + <th scope="row">Обязателен</th> + <td>Нет</td> + </tr> + <tr> + <th scope="row">Пример</th> + <td> + <pre class="brush: json; no-line-numbers"> +"permissions": [ + "*://developer.mozilla.org/*", + "webRequest" +]</pre> + </td> + </tr> + </tbody> +</table> + +<p>Используйте ключ<span style='font-family: "Times New Roman","serif"; font-size: 12.0pt; line-height: 115%;'> </span> <code>permissions</code> для получения дополнительных возможностей для вашего расширения. Значением ключа является массив строк, каждая из которых представляет собой запрос на какие-либо полномочия.</p> + +<p>При объявлении запросов полномочий с помощью этого ключа, браузер проинформирует пользователей, о том какие полномочия необходимы расширению во время его установки, и задаст вопрос, согласны ли они выдать их расширению. Браузер так же даёт пользователям возможность изучить полномочия расширения уже после установки. Так как требование дополнительных полномочий может повлиять на желание пользователя использовать ваше расширение, решение использования конкретного функционала может стоить тщательного рассмотрения. К примеру, есть смысл избегать запрашивания необязательных полномочий, и предоставлять информацию о том, зачем вашему расширению нужны какие-либо полномочия в описании расширения. Более подробная информация о проблемах, которые вам стоит рассмотреть касательно этой темы, предоставлена в статье <a href="/ru/docs/Mozilla/Add-ons/WebExtensions/Request_the_right_permissions">Запрашивание правильных полномочий</a>.</p> + +<p>Значение ключа может содержать три вида запросов полномочий:</p> + +<ul> + <li>Запрос на полномочия для хоста</li> + <li>Запрос на API полномочия</li> + <li>Запрос на activeTab полномочия</li> +</ul> + +<h2 id="Запрос_полномочий_для_хоста">Запрос полномочий для хоста</h2> + +<p>Запрос на полномочия для хоста объявляется через <a href="https://developer.mozilla.org/ru/docs/Mozilla/Add-ons/WebExtensions/Match_patterns">шаблоны совпадения</a>, где каждый шаблон определяет группу URL, при посещении которых расширение будет иметь эти дополнительные полномочия. Например, запрос на полномочия для хоста может быть задан подобной строкой <code>"*://developer.mozilla.org/*"</code>.</p> + +<p>Полномочия для хоста включают:</p> + +<ul> + <li>Возможность выполнять <a href="/ru/docs/Web/API/XMLHttpRequest">XMLHttpRequest</a> и <a href="/ru/docs/Web/API/Fetch_API">fetch</a> запросы на ресурсы, которые имеют заданный origin, не испытывая cross-origin ограничений (даже для запросов, выполняемых из встраиваемого скрипта)</li> + <li>Возможность встраивать скрипты программным путём, используя <a href="/ru/docs/Mozilla/Add-ons/WebExtensions/API/tabs/executeScript">tabs.executeScript</a>, на веб-страницах загруженных с заданного origin</li> + <li>Возможность обрабатывать события из <a href="/ru/docs/Mozilla/Add-ons/WebExtensions/API/webRequest">webRequest</a> API для заданных хостов</li> + <li>Доступ к сookies на заданных хостах, используя <a href="/ru/Add-ons/WebExtensions/API/cookies">cookies</a> API, при условии получения дополнительного "cookies" API полномочия.</li> + <li>Возможность обходить защиту от слежения, при условии полностью указанного хоста, без использования универсального символа <code>*</code>. Не будет работать с <code><all_urls></code>.</li> +</ul> + +<p>В Firefox, начиная с версии 56, расширения автоматически получают полномочия для своего собственного хоста, который имеет вид:</p> + +<pre><code>moz-extension://60a20a9b-1ad4-af49-9b6c-c64c98c37920/</code></pre> + +<p>где <code>60a20a9b-1ad4-af49-9b6c-c64c98c37920</code> - внутреннее ID расширения. Расширение может получить это URL программным путём, через вызов метода <a href="/ru/docs/Mozilla/Add-ons/WebExtensions/API/extension/getURL">extension.getURL()</a>:</p> + +<pre class="brush: js;">browser.extension.getURL(""); +// moz-extension://60a20a9b-1ad4-af49-9b6c-c64c98c37920/ +</pre> + +<h2 id="Запрос_на_API_полномочия">Запрос на API полномочия</h2> + +<p>Запрос на API полномочия объявляется через ключевые слова, каждое из которых представляет собой название <a href="/ru/docs/Mozilla/Add-ons/WebExtensions/API">WebExtension API</a>, доступ к которому необходим расширению.</p> + +<p>Следующие ключевые слова доступны на данный момент:</p> + +<ul> + <li><code>activeTab</code></li> + <li><code>alarms</code></li> + <li><code>background</code></li> + <li><code>bookmarks</code></li> + <li><code>browserSettings</code></li> + <li><code>browsingData</code></li> + <li><code>clipboardRead</code></li> + <li><code>clipboardWrite</code></li> + <li><code>contentSettings</code></li> + <li><code>contextMenus</code></li> + <li><code>contextualIdentities</code></li> + <li><code>cookies</code></li> + <li><code>debugger</code></li> + <li><code>dns</code></li> + <li><code>downloads</code></li> + <li><code>downloads.open</code></li> + <li><code>find</code></li> + <li><code>geolocation</code></li> + <li><code>history</code></li> + <li><code>identity</code></li> + <li><code>idle</code></li> + <li><code>management</code></li> + <li><code>menus</code></li> + <li><code>menus.overrideContext</code></li> + <li><code>nativeMessaging</code></li> + <li><code>notifications</code></li> + <li><code>pageCapture</code></li> + <li><code>pkcs11</code></li> + <li><code>privacy</code></li> + <li><code>proxy</code></li> + <li><code>search</code></li> + <li><code>sessions</code></li> + <li><code>storage</code></li> + <li><code>tabHide</code></li> + <li><code>tabs</code></li> + <li><code>theme</code></li> + <li><code>topSites</code></li> + <li><code>unlimitedStorage</code></li> + <li><code>webNavigation</code></li> + <li><code>webRequest</code></li> + <li><code>webRequestBlocking</code></li> +</ul> + +<p>В большинстве случаев полномочие просто делает возможным доступ к определённому API, за исключением следующих ситуаций:</p> + +<ul> + <li><code>tabs</code> предоставляет доступ к <a href="/ru/Add-ons/WebExtensions/API/tabs">привилегированным частям <code>tabs</code> API</a>: <code>Tab.url</code>, <code>Tab.title</code>, and <code>Tab.faviconUrl</code>. В Firefox, вам так же понадобятся <code>tabs</code> полномочия, если вы собираетесь использовать <code>url</code> ключ в параметре <code>queryInfo</code> для <code><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/API/tabs/query">tabs.query()</a></code> метода. Весь остальной <code>tabs</code> API доступен без запрашивания каких-либо полномочий.</li> + <li><code>webRequestBlocking</code> позволяет вам использовать "blocking" аргумент, для возможности <a href="/ru/Add-ons/WebExtensions/API/WebRequest">изменять и отменять запросы</a>.</li> + <li><code>downloads.open</code> позволяет использовать {{WebExtAPIRef("downloads.open()")}} API.</li> + <li><code>tabHide</code> позволяет использовать {{WebExtAPIRef("tabs.hide()")}} API.</li> +</ul> + +<h2 id="Запрос_на_activeTab_полномочия">Запрос на activeTab полномочия</h2> + +<p>Этот вид запроса объявляется через ключевое слово <code>"activeTab"</code>. <code>activeTab</code> полномочия предоставляются расширению на активной в данный момент вкладке, и вступают в эффект только в момент, когда пользователь взаимодействует с расширением.</p> + +<p>"Взаимодействие пользователя" включает:</p> + +<ul> + <li>Пользователь нажимает на кнопку расширения на панели инструментов или адресной строке</li> + <li>Пользователь взаимодействует с контекстным меню расширения</li> + <li>Пользователь нажимает комбинацию клавиш, ассоциированную с расширением</li> +</ul> + +<p>activeTab полномочия включают:</p> + +<ul> + <li>Возможность программно встраивать JavaScript или CSS на страницу, используя <code><a href="/ru/Add-ons/WebExtensions/API/tabs/executeScript">browser.tabs.executeScript</a></code> и <code><a href="/ru/Add-ons/WebExtensions/API/tabs/insertCSS">browser.tabs.insertCSS</a></code></li> + <li>Получение доступа к привилегированным частям tabs API для активной вкладки: <code>Tab.url</code>, <code>Tab.title</code> и <code>Tab.faviconUrl</code>.</li> +</ul> + +<p>Цель этих полномочий – позволить расширению выполнять наиболее распространенные сценарии работы, без необходимости выдавать ему более серьёзные привилегии, так как большинство расширений задумано для выполнения какой-либо работы на активной вкладке после взаимодействия с пользователем. Например, представьте расширение, которое встраивает скрипт на текущую страницу, после того как пользователь нажимает на кнопку расширения на панели инструментов. Если бы <code>activeTab</code> полномочий не существовало, расширению бы пришлось запрашивать <code><all_urls></code>. Но они бы давали расширению намного больше привилегий, чем ему было бы необходимо: расширение могло бы встраивать скрипты на любую вкладку и в любой момент, когда пожелает.</p> + +<p>Заметьте, что вы сможете иметь доступ к привилегированному tab API, только на момент взаимодействия расширения с пользователем, и пока вкладка не изменила своё состояние. То есть расширение перестанет иметь данные привилегии при изменении адреса страницы или каком-либо другом событии с вкладкой.</p> + +<p>Обычно вкладкой, получающей <code>activeTab</code> полномочия, является активная в данный момент вкладка, за исключением одного случая. <code><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/API/menus">menus</a></code> API позволяет расширению создавать элементы контекстного меню, которые будут появляться непосредственно при нажатии на вкладку (элемент на панели вкладок, при нажатии на который изменяется активная вкладка). Если пользователь вызывает контекстное меню на этом элементе, тогда <code>activeTab</code> полномочия выдадутся для вкладки, по которой было произведено нажатие, несмотря на то, что она могла бы не является активной ({{bug(1446956)}} начиная с Firefox версии 63).</p> + +<h2 id="Доступ_к_буферу_обмена">Доступ к буферу обмена</h2> + +<p>Два полномочия предоставляют расширению привилегии для взаимодействия с буфером обмена:</p> + +<ul> + <li><code>clipboardWrite</code>: для записи в буфер обмена с помощью {{DOMxRef("Clipboard.write()")}}, {{DOMxRef("Clipboard.writeText()")}}, <code>document.execCommand("copy")</code> или <code>document.execCommand("cut")</code></li> + <li><code>clipboardRead</code>: для чтения из буфера обмена с помощью {{DOMxRef("Clipboard.read()")}}, {{DOMxRef("Clipboard.readText()")}} или <code>document.execCommand("paste")</code></li> +</ul> + +<p>Смотрите <a href="/ru/docs/Mozilla/Add-ons/WebExtensions/Interact_with_the_clipboard">Взаимодействие с буфером обмена</a> для более подробной информации.</p> + +<h2 id="Неограниченное_хранилище">Неограниченное хранилище</h2> + +<p>Полномочие <code>unlimitedStorage</code>:</p> + +<ul> + <li>Позволяет расширению превышать любые ограничения размера хранимой информации для {{WebExtAPIRef("storage.local")}} API</li> + <li>В Firefox, позволяет расширению создавать <a href="/ru/docs/Web/API/IndexedDB_API/Browser_storage_limits_and_eviction_criteria#Firefox_specifics">"persistent" базу данных IndexedDB</a>, не запрашивая разрешения у пользователя в момент её создания.</li> +</ul> + +<h2 id="Примеры">Примеры</h2> + +<pre class="brush: json no-line-numbers"> "permissions": ["*://developer.mozilla.org/*"]</pre> + +<p>Запрашивает полномочия для хостов, имеющих developer.mozilla.org в их URL.</p> + +<pre class="brush: json no-line-numbers"> "permissions": ["tabs"]</pre> + +<p>Запрашивает доступ к привилегированным частям <code>tabs</code> API.</p> + +<pre class="brush: json no-line-numbers"> "permissions": ["*://developer.mozilla.org/*", "tabs"]</pre> + +<p>Запрашивает несколько типов полномочий из примеров выше.</p> + +<h2 id="Browser_compatibility">Browser compatibility</h2> + +<p class="hidden">The compatibility table in this page is generated from structured data. If you'd like to contribute to the data, please check out <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> and send us a pull request.</p> + +<p>{{Compat("webextensions.manifest.permissions")}}</p> diff --git a/files/ru/mozilla/add-ons/webextensions/manifest.json/version/index.html b/files/ru/mozilla/add-ons/webextensions/manifest.json/version/index.html new file mode 100644 index 0000000000..42892c82af --- /dev/null +++ b/files/ru/mozilla/add-ons/webextensions/manifest.json/version/index.html @@ -0,0 +1,49 @@ +--- +title: ключ version +slug: Mozilla/Add-ons/WebExtensions/manifest.json/version +tags: + - Reference + - WebExtensions + - version +translation_of: Mozilla/Add-ons/WebExtensions/manifest.json/version +--- +<p>{{AddonSidebar}}</p> + +<table class="fullwidth-table standard-table"> + <tbody> + <tr> + <th scope="row" style="width: 30%;">Тип</th> + <td><code>String</code></td> + </tr> + <tr> + <th scope="row">Обязательный</th> + <td>Да</td> + </tr> + <tr> + <th scope="row">Пример</th> + <td> + <pre class="brush: json no-line-numbers"> +"version": "0.1"</pre> + </td> + </tr> + </tbody> +</table> + +<p>Версия дополнения, отформатированная как числа и символы ASCII, разделенные точками. Подробнее о формате версий смотрите страницу <a href="https://developer.mozilla.org/ru/docs/Toolkit_version_format">Version format</a>.</p> + +<p>Обратите внимание, что <a href="https://developer.chrome.com/extensions/manifest/version">синтаксис ключа <code>version</code> для Chrome</a> более ограниченный, чем у Firefox:</p> + +<ul> + <li>значения <code>version</code> которые действительны для Chrome, всегда будут действительны для Firefox</li> + <li>значения <code>version</code> которые действительны для Firefox, могут быть не действительны для Chrome</li> +</ul> + +<h2 id="Пример">Пример</h2> + +<pre class="brush: json no-line-numbers">"version": "0.1"</pre> + +<h2 id="Совместимость_с_браузерами">Совместимость с браузерами</h2> + +<p class="hidden">The compatibility table in this page is generated from structured data. If you'd like to contribute to the data, please check out <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> and send us a pull request.</p> + +<p>{{Compat("webextensions.manifest.version")}}</p> diff --git a/files/ru/mozilla/add-ons/webextensions/match_patterns/index.html b/files/ru/mozilla/add-ons/webextensions/match_patterns/index.html new file mode 100644 index 0000000000..17ac749843 --- /dev/null +++ b/files/ru/mozilla/add-ons/webextensions/match_patterns/index.html @@ -0,0 +1,426 @@ +--- +title: Шаблоны совпадения в расширении +slug: Mozilla/Add-ons/WebExtensions/Match_patterns +translation_of: Mozilla/Add-ons/WebExtensions/Match_patterns +--- +<div>{{AddonSidebar}}</div> + +<p>Шаблоны совпадения - являются способом обозначения необходимых групп URL. Они используются в нескольких местах в WebExtensions API, главным образом для объявления какие веб-страницы должны загружать <a href="/ru/docs/Mozilla/Add-ons/WebExtensions/Content_scripts">встраиваемые скрипты</a> и по каким URL необходимо ожидать событий из <code><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/API/webRequest">webRequest</a></code> API.</p> + +<p>API, которое использует шаблоны совпадения, обычно принимает их списками, и выполняет соответствующие действия, если URL имеет совпадение с одним из шаблонов. Например, взгляните на <code><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/manifest.json/content_scripts">content_scripts</a></code> ключ в manifest.json.</p> + +<h2 id="Структура_шаблона_совпадения">Структура шаблона совпадения</h2> + +<div class="note"> +<p><strong>Заметьте:</strong> Некоторые браузеры не поддерживают определённые схемы.<br> + Смотрите <a href="#Browser_compatibility">Browser compatibility table</a> для дополнительной информации.</p> +</div> + +<p>Все шаблоны совпадения объявляются в виде строк. За исключением специального <code><a href="/ru/Add-ons/WebExtensions/Match_patterns#%3Call_urls%3E"><all_urls></a></code> шаблона, шаблоны совпадения состоят из трёх компонентов: <em>схема</em>, <em>хост</em> и <em>путь</em>. Схема и хост разделяются с помощью <code>://</code>.</p> + +<pre><схема>://<хост><путь></pre> + +<h3 id="Схема">Схема</h3> + +<p>Компонент<em> схема</em> может принимать один из двух видов:</p> + +<table class="fullwidth-table standard-table"> + <thead> + <tr> + <th scope="col" style="width: 50%;">Вид</th> + <th scope="col">Совпадение</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>*</code></td> + <td>Только "http" and "https", так же <a href="/ru/docs/Web/API/WebSockets_API">"ws" и "wss"</a> в некоторых браузерах.</td> + </tr> + <tr> + <td>Одно из <code>http</code>, <code>https</code>, <code>ws</code>, <code>wss</code>, <code>ftp</code>, <code>ftps</code>, <code>data</code> или <code>file</code>.</td> + <td>Только данная схема.</td> + </tr> + </tbody> +</table> + +<h3 id="Хост">Хост</h3> + +<p>Компонент<em> хост</em> может принимать один из трёх видов:</p> + +<table class="fullwidth-table standard-table"> + <thead> + <tr> + <th scope="col" style="width: 50%;">Form</th> + <th scope="col">Matches</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>*</code></td> + <td>Любой хост.</td> + </tr> + <tr> + <td><code>*.</code> за которыми следует частичное имя хоста.</td> + <td>Данный хост и любые его субдомены.</td> + </tr> + <tr> + <td>Полное название хоста без <code>*</code>.</td> + <td>Только данный хост.</td> + </tr> + </tbody> +</table> + +<p><em>Хост</em> не должен включать в себя значение порта.</p> + +<p><em>Хост</em> не обязателен, если <em>схема </em>задана, как "file".</p> + +<p>Заметьте, что <code>*</code> звёздочка (символ универсального значения) может быть написана только в начале строки.</p> + +<h3 id="Путь">Путь</h3> + +<p>Компонент<em> путь</em> должен начинаться с <code>/</code> символа.</p> + +<p>Вслед за ним он может иметь любую комбинацию символов и <code>*</code> звёздочек, которые позволено использовать для обозначения URL и строки параметров (начинается после <code>?</code>). В отличии от <em>хоста</em>, <em>путь</em> может содержать <code>*</code> звёздочку в середине или в конце строки, и <code>*</code> звёздочка может появляться в строке более одного раза.</p> + +<p>Значение <em>пути</em> сравнивается со строкой, которая представляет из себя URL и <a href="https://en.wikipedia.org/wiki/Query_string">строку параметров</a>. Если строка параметров присутствует в URL, тогда она отделяется от основного URL знаком <code>?</code>. Если вы хотите иметь соответствие с URL на любом домене, где URL путь кончается на <code>foo.bar</code>, не зависимо от присутствия строки параметров, тогда вам нужно иметь массив шаблонов совпадений, например <code>['*://*/*foo.bar', '*://*/*foo.bar?*']</code>. В этой ситуации необходимо использовать <code>?*</code>, а не <code>bar*</code>, для того чтобы обозначить, что <code>*</code> будет применяться к строке параметров, а не к основной части URL пути.</p> + +<p>Ни <a href="https://en.wikipedia.org/wiki/Fragment_identifier">идентификатор якоря</a>, ни предшествующая ему <code>#</code>, не считаются частями<em> пути</em>.</p> + +<h3 id="<all_urls>"><all_urls></h3> + +<p>Специальное значение <code><all_urls></code> совпадает со всеми URL, если они используются со следующими схемами: "http", "https", "ws", "wss", "ftp", "data", and "file".</p> + +<h2 id="Примеры">Примеры</h2> + +<table class="fullwidth-table standard-table"> + <thead> + <tr> + <th scope="col" style="width: 33%;">Шаблон</th> + <th scope="col" style="width: 33%;">Пример совпадения</th> + <th scope="col" style="width: 33%;">Пример несовпадения</th> + </tr> + </thead> + <tbody> + <tr> + <td> + <p><code><all_urls></code></p> + + <p>Совпадение со всеми URL.</p> + </td> + <td> + <p><code>http://example.org/</code></p> + + <p><code>https://a.org/some/path/</code></p> + + <p><code>ws://sockets.somewhere.org/</code></p> + + <p><code>wss://ws.example.com/stuff/</code></p> + + <p><code>ftp://files.somewhere.org/</code></p> + + <p><code>ftps://files.somewhere.org/</code></p> + </td> + <td> + <p><code>resource://a/b/c/</code><br> + (неподдерживаемая схема)</p> + </td> + </tr> + <tr> + <td> + <p><code>*://*/*</code></p> + + <p>Совпадение со всеми HTTP, HTTPS и WebSocket URL.</p> + </td> + <td> + <p><code>http://example.org/</code></p> + + <p><code>https://a.org/some/path/</code></p> + + <p><code>ws://sockets.somewhere.org/</code></p> + + <p><code>wss://ws.example.com/stuff/</code></p> + </td> + <td> + <p><code>ftp://ftp.example.org/</code><br> + (несовпадающая схема)</p> + + <p><code>ftps://ftp.example.org/</code><br> + (несовпадающая схема)</p> + + <p><code>file:///a/</code><br> + (несовпадающая схема)</p> + </td> + </tr> + <tr> + <td> + <p><code>*://*.mozilla.org/*</code></p> + + <p>Совпадение со всеми HTTP, HTTPS и WebSocket URL, которые находятся на "mozilla.org" или одном из её субдоменов.</p> + </td> + <td> + <p><code>http://mozilla.org/</code></p> + + <p><code>https://mozilla.org/</code></p> + + <p><code>http://a.mozilla.org/</code></p> + + <p><code>http://a.b.mozilla.org/</code></p> + + <p><code>https://b.mozilla.org/path/</code></p> + + <p><code>ws://ws.mozilla.org/</code></p> + + <p><code>wss://secure.mozilla.org/something</code></p> + </td> + <td> + <p><code>ftp://mozilla.org/</code><br> + (несовпадающая схема)</p> + + <p><code>http://mozilla.com/</code><br> + (несовпадающий хост)</p> + + <p><code>http://firefox.org/</code><br> + (несовпадающий хост)</p> + </td> + </tr> + <tr> + <td> + <p><code>*://mozilla.org/</code></p> + + <p>Совпадение со всеми HTTP, HTTPS и WebSocket URL, которые находятся исключительно на "mozilla.org/".</p> + </td> + <td> + <p><code>http://mozilla.org/</code></p> + + <p><code>https://mozilla.org/</code></p> + + <p><code>ws://mozilla.org/</code></p> + + <p><code>wss://mozilla.org/</code></p> + </td> + <td> + <p><code>ftp://mozilla.org/</code><br> + (несовпадающая схема)</p> + + <p><code>http://a.mozilla.org/</code><br> + (несовпадающий хост)</p> + + <p><code>http://mozilla.org/a</code><br> + (несовпадающий путь)</p> + </td> + </tr> + <tr> + <td> + <p><code>ftp://mozilla.org/</code></p> + + <p>Совпадение только с "ftp://mozilla.org/".</p> + </td> + <td><code>ftp://mozilla.org</code></td> + <td> + <p><code>http://mozilla.org/</code><br> + (несовпадающая схема)</p> + + <p><code>ftp://sub.mozilla.org/</code><br> + (несовпадающий хост)</p> + + <p><code>ftp://mozilla.org/path</code><br> + (несовпадающий путь)</p> + </td> + </tr> + <tr> + <td> + <p><code>https://*/path</code></p> + + <p>Совпадение со всеми HTTPS URL на любом хосте, чей путь точно соответсвует "path".</p> + </td> + <td> + <p><code>https://mozilla.org/path</code></p> + + <p><code>https://a.mozilla.org/path</code></p> + + <p><code>https://something.com/path</code></p> + </td> + <td> + <p><code>http://mozilla.org/path</code><br> + (несовпадающая схема)</p> + + <p><code>https://mozilla.org/path/</code><br> + (несовпадающий путь)</p> + + <p><code>https://mozilla.org/a</code><br> + (несовпадающий путь)</p> + + <p><code>https://mozilla.org/</code><br> + (несовпадающий путь)</p> + + <p><code>https://mozilla.org/path?foo=1</code><br> + (несовпадающий путь из-за строки параметров)</p> + </td> + </tr> + <tr> + <td> + <p><code>https://*/path/</code></p> + + <p>Совпадение со всеми HTTPS URL на любом хосте, чей путь точно соответсвует "path/" и не имеет строки параметров.</p> + </td> + <td> + <p><code>https://mozilla.org/path/</code></p> + + <p><code>https://a.mozilla.org/path/</code></p> + + <p><code>https://something.com/path</code>/</p> + </td> + <td> + <p><code>http://mozilla.org/path/</code><br> + (несовпадающая схема)</p> + + <p><code>https://mozilla.org/path</code><br> + (несовпадающий путь)</p> + + <p><code>https://mozilla.org/a</code><br> + (несовпадающий путь)</p> + + <p><code>https://mozilla.org/</code><br> + (несовпадающий путь)</p> + + <p><code>https://mozilla.org/path/</code><code>?foo=1</code><br> + (несовпадающий путь из-за строки параметров)</p> + </td> + </tr> + <tr> + <td> + <p><code>https://mozilla.org/*</code></p> + + <p>Совпадение со всеми HTTPS URL только на домене "mozilla.org", с любым URL путём и строкой параметров.</p> + </td> + <td> + <p><code>https://mozilla.org/</code></p> + + <p><code>https://mozilla.org/path</code></p> + + <p><code>https://mozilla.org/another</code></p> + + <p><code>https://mozilla.org/path/to/doc</code></p> + + <p><code>https://mozilla.org/path/to/doc?foo=1</code></p> + </td> + <td> + <p><code>http://mozilla.org/path</code><br> + (несовпадающая схема)</p> + + <p><code>https://mozilla.com/path</code><br> + (несовпадающий хост)</p> + </td> + </tr> + <tr> + <td> + <p><code>https://mozilla.org/a/b/c/</code></p> + + <p>Совпадение только с данным URL, или данным URL, имеющим идентификатор якоря.</p> + </td> + <td> + <p><code>https://mozilla.org/a/b/c/</code></p> + + <p><code>https://mozilla.org/a/b/c/#section1</code></p> + </td> + <td>Всё остальное.</td> + </tr> + <tr> + <td> + <p><code>https://mozilla.org/*/b/*/</code></p> + + <p>Совпадение только с HTTPS URL, которые находятся на "mozilla.org", чей путь имеет сегмент "b" где-то в середине. Совпадёт с URL со строкой параметров, если эта строка параметров заканчивается на <code>/</code>.</p> + </td> + <td> + <p><code>https://mozilla.org/a/b/c/</code></p> + + <p><code>https://mozilla.org/d/b/f/</code></p> + + <p><code>https://mozilla.org/a/b/c/d/</code></p> + + <p><code>https://mozilla.org/a/b/c/d/#section1</code></p> + + <p><code>https://mozilla.org/a/b/c/d/?foo=/</code></p> + + <p><code>https://mozilla.org/a?foo=21314&bar=/b/&extra=c/</code></p> + </td> + <td> + <p><code>https://mozilla.org/b/*/</code><br> + (несовпадающий путь)</p> + + <p><code>https://mozilla.org/a/b/</code><br> + (несовпадающий путь)</p> + + <p><code>https://mozilla.org/a/b/c/d/?foo=bar</code><br> + (несовпадающий путь из-за строки параметров)</p> + </td> + </tr> + <tr> + <td> + <p><code>file:///blah/*</code></p> + + <p>Совпадает с любым FILE URL, чей путь начинается с "blah".</p> + </td> + <td> + <p><code>file:///blah/</code></p> + + <p><code>file:///blah/bleh</code></p> + </td> + <td><code>file:///bleh/</code><br> + (несовпадающий путь)</td> + </tr> + </tbody> +</table> + +<h3 id="Недопустимые_шаблоны_совпадения">Недопустимые шаблоны совпадения</h3> + +<table class="fullwidth-table standard-table"> + <thead> + <tr> + <th scope="col">Недопустимый шаблон</th> + <th scope="col">Причина</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>resource://path/</code></td> + <td>Неподдерживаемая схема.</td> + </tr> + <tr> + <td><code>https://mozilla.org</code></td> + <td>Отсутствие пути.</td> + </tr> + <tr> + <td><code>https://mozilla.*.org/</code></td> + <td>"*" в хосте должна присутствовать только в начале.</td> + </tr> + <tr> + <td><code>https://*zilla.org/</code></td> + <td>"*" в хосте должен быть единственным символом или сопровождаться ".".</td> + </tr> + <tr> + <td><code>http*://mozilla.org/</code></td> + <td>"*" в схеме должен быть единственным символом.</td> + </tr> + <tr> + <td><code>https://mozilla.org:80/</code></td> + <td>Хост не должен включать в себя номер порта.</td> + </tr> + <tr> + <td><code>*://*</code></td> + <td>Пустой путь: должно быть переписано, как "<code>*://*/*</code>".</td> + </tr> + <tr> + <td><code>file://*</code></td> + <td>Пустой путь: должно быть переписано, как "<code>file:///*</code>".</td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility">Browser compatibility</h2> + +<h3 id="scheme">scheme</h3> + + + +<p>{{Compat("webextensions.match_patterns.scheme",10)}}</p> diff --git a/files/ru/mozilla/add-ons/webextensions/prerequisites/index.html b/files/ru/mozilla/add-ons/webextensions/prerequisites/index.html new file mode 100644 index 0000000000..e18158e724 --- /dev/null +++ b/files/ru/mozilla/add-ons/webextensions/prerequisites/index.html @@ -0,0 +1,8 @@ +--- +title: Prerequisites +slug: Mozilla/Add-ons/WebExtensions/Prerequisites +translation_of: Mozilla/Add-ons/WebExtensions/Prerequisites +--- +<div>{{AddonSidebar}}</div> + +<p>Всё что вам нужно - это Firefox 45 или выше. Смотрите <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Your_first_WebExtension">Your first WebExtension</a> для того чтобы начать.</p> diff --git a/files/ru/mozilla/add-ons/webextensions/user_interface/browser_action/index.html b/files/ru/mozilla/add-ons/webextensions/user_interface/browser_action/index.html new file mode 100644 index 0000000000..ba7e259817 --- /dev/null +++ b/files/ru/mozilla/add-ons/webextensions/user_interface/browser_action/index.html @@ -0,0 +1,50 @@ +--- +title: Кнопка в панели инструментов +slug: Mozilla/Add-ons/WebExtensions/user_interface/Browser_action +tags: + - Кнопка панели инструментов +translation_of: Mozilla/Add-ons/WebExtensions/user_interface/Browser_action +--- +<div>{{AddonSidebar}}</div> + +<p>Кнопка на панели инструментов браузера (оригинальное название <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserAction">browser action</a>) - это иконка, которую можно вывести в панель инструментов. Пользователь взаимодействует с расширением нажимая на нее как на кнопку.<br> + <img alt="" src="https://mdn.mozillademos.org/files/12966/browser-action.png" style="display: block; height: 387px; margin-left: auto; margin-right: auto; width: 782px;"></p> + +<p>Кнопка на панели инструментов одинаково отображается для любой открытой вкладки. Это предполагает, что расширение единообразно работает со всеми страницами.</p> + +<p>Например, предустановленная кнопка "обновить" перезагружает любую страницу в активной вкладке, кнопка "добавить в избранное" добавляет любой адрес активной вкладки в список избранного. Кнопка загрузок показывает единый для всего браузера список скачанных файлов, независимо от того что за страница открыта в активной вкладке.</p> + +<p>Применимые лишь к определенным страницам кнопки следует реализовывать с помощью кнопки в адресной строке (<a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Page_actions">page action</a>).</p> + +<h2 id="Объявление_в_manifest.json"><span class="short_text" id="result_box" lang="ru"><span>Объявление в manifest.json</span></span></h2> + +<p>За кнопку на панели инструментов отвечает свойство манифеста <code><a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/browser_action">browser_action</a></code>:</p> + +<pre class="brush: json line-numbers language-json"><code class="language-json"><span class="key token">"browser_action":</span> <span class="punctuation token">{</span> + <span class="key token">"default_icon":</span> <span class="punctuation token">{</span> + <span class="key token">"19":</span> <span class="string token">"button/geo-19.png"</span><span class="punctuation token">,</span> + <span class="key token">"38":</span> <span class="string token">"button/geo-38.png"</span> + <span class="punctuation token">}</span><span class="punctuation token">,</span> + <span class="key token">"default_title":</span> <span class="string token">"Whereami?"</span> +<span class="punctuation token">}</span></code></pre> + +<p>Свойство кнопки <code>default_icon</code> обязательно, оно определяет внешний вид кнопки - иконку, которая окажется на панели инструментов.</p> + +<p>Расширение может иметь только одну кнопку для панели инструментов.</p> + +<p>Возможны два способа реакции на нажатие кнопки: отображение <a href="/en-US/Add-ons/WebExtensions/Popups">всплывающего окна</a> (описано в отдельном разделе) или отправка события в background script расширения. В таком случае реакция на нажатие обеспечивают обработчики событий, подключенные к <a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/BrowserAction/onClicked" title="Fired when a browser action icon is clicked. This event will not fire if the browser action has a popup."><code>browserAction.onClicked</code></a>:</p> + +<pre class="brush: js line-numbers language-js"><code class="language-js">browser<span class="punctuation token">.</span>browserAction<span class="punctuation token">.</span>onClicked<span class="punctuation token">.</span><span class="function token">addListener</span><span class="punctuation token">(</span>handleClick<span class="punctuation token">)</span><span class="punctuation token">;</span></code></pre> + +<p>Если же указать в качестве реакции на нажатие всплывающее окно, то событие передано не будет. Вместо этого около кнопки отобразится всплывающее окно - отдельная маленькая страница, дальнейшее взаимодействие с пользователем берет на себя она. Подробнее этот сценарий описан на отдельной странице, посвященной <a href="/en-US/Add-ons/WebExtensions/Popups">всплывающим окнам</a>.</p> + +<p>Все свойства кнопки на панели инструментов можно изменить программно через API <code><a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserAction">browserAction</a></code>.</p> + +<h2 id="Примеры">Примеры</h2> + +<p><span id="result_box" lang="ru"><span>В GitHub репозитории</span></span> <a href="https://github.com/mdn/webextensions-examples">webextensions-examples</a> представлены <span id="result_box" lang="ru"><span>несколько примеров расширений, которые создают кнопку на панели инструментов:</span></span></p> + +<ul> + <li><a href="https://github.com/mdn/webextensions-examples/blob/master/bookmark-it/">bookmark-it</a> использует событие browserAction.onClicked.</li> + <li><a href="https://github.com/mdn/webextensions-examples/tree/master/beastify">beastify</a> открывает всплывающее окно.</li> +</ul> diff --git a/files/ru/mozilla/add-ons/webextensions/user_interface/context_menu_items/index.html b/files/ru/mozilla/add-ons/webextensions/user_interface/context_menu_items/index.html new file mode 100644 index 0000000000..229d378a2f --- /dev/null +++ b/files/ru/mozilla/add-ons/webextensions/user_interface/context_menu_items/index.html @@ -0,0 +1,54 @@ +--- +title: Контекстное меню +slug: Mozilla/Add-ons/WebExtensions/user_interface/Context_menu_items +translation_of: Mozilla/Add-ons/WebExtensions/user_interface/Context_menu_items +--- +<div> +<div>{{AddonSidebar}}</div> + +<div> +<p>Эта возможность пользовательского интерфейса позволяет добавлять новые элементы в контекстное меню браузера, появляющееся при нажатии правой кнопки мыши. Вкладки браузера также имеют контекстное меню доступное через<a href="/en-US/Add-ons/WebExtensions/API/menus"> browser.menus API</a>.</p> + +<p><img alt="Example of content menu items added by a WebExtension, from the context-menu-demo example" src="https://mdn.mozillademos.org/files/15756/context_menu_example.png" style="display: block; height: 382px; margin-left: auto; margin-right: auto; width: 350px;"></p> + +<p>Возможность добавления элементов в контекстное меню позволяет предоставлять пользователю различные функции в зависимости от его действий на странице или в браузере. Например, можно отобразить элемент, который открывает графический редактор, если пользователь нажимает на изображение, или же предложить функцию для сохранения содержимого страницы, если выбрана некоторая её часть. Элементы могут представлять из себя не только текст, но и, например, кнопку-переключатель или разделитель (см. <a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/menus/ItemType">типы элементов меню</a>). После того, как элемент контекстного меню был добавлен с помощью {{WebExtAPIRef("contextMenus.create")}}, он отображается во всех вкладках браузера, но вы можете удалить его при помощи {{WebExtAPIRef("contextMenus.remove")}}.</p> +</div> +</div> + +<h2 id="Создание_элементов_контекстного_меню">Создание элементов контекстного меню</h2> + +<p>Управление элементами контекстного меню осуществляется с помощью {{WebExtAPIRef("contextMenus")}} API. Однако, вам необходимо указать разрешение <code>contextMenus</code> в manifest.json, чтобы им воспользоваться.</p> + +<pre class="brush: json">"permissions": ["contextMenus"]</pre> + +<p>Затем вы сможете добавлять, обновлять и удалять элементы контекстного меню в <a href="https://developer.mozilla.org/ru/docs/Mozilla/Add-ons/WebExtensions/manifest.json/background">фоновом сценарии</a> вашего расширения. Для создания элемента необходимо указать его id,<em> </em>заголовок и контекст, в котором элемент будет показан. В примере ниже элемент меню появляется, когда выделен текст или какая-либо другая часть страницы:</p> + +<pre class="brush: js">browser.contextMenus.create({ + id: "log-selection", + title: browser.i18n.getMessage("contextMenuItemSelectionLogger"), + contexts: ["selection"] +}, onCreated);</pre> + +<p>Затем вы можете добавить обработчик события нажатия на элемент. Передаваемая обработчику информация о контексте, в котором произошло нажатие, и о вкладке, где контекстное меню было вызвано, может быть использована вами для определения дальнейшего поведения расширения.</p> + +<pre class="brush: js">browser.contextMenus.onClicked.addListener(function(info, tab) { + switch (info.menuItemId) { + case "log-selection": + console.log(info.selectionText); + break; + ... + } +})</pre> + +<h2 id="Иконки">Иконки</h2> + +<p>Чтобы добавить элементам меню икноки, смотрите документацию <a href="https://design.firefox.com/photon/visuals/iconography.html">Iconography</a> в <a class="grey-90 no-underline hover-no-underline" href="https://design.firefox.com/photon/index.html">Photon Design System</a>.</p> + +<h2 id="Примеры">Примеры</h2> + +<p>Репозиторий <a class="external external-icon" href="https://github.com/mdn/webextensions-examples">webextensions-examples</a> на GitHub содержит два примера расширений, в которых реализована работа элементов контекстного меню:</p> + +<ul> + <li><a href="https://github.com/mdn/webextensions-examples/tree/master/menu-demo">menu-demo</a> добавляет несколько элементов в контекстное меню;</li> + <li><a href="https://github.com/mdn/webextensions-examples/tree/master/context-menu-copy-link-with-types">context-menu-copy-link-with-types</a> добавляет элемент контекстного меню, который копирует URL ссылки в буфер в виде текста и форматированного HTML.</li> +</ul> diff --git a/files/ru/mozilla/add-ons/webextensions/user_interface/extension_pages/index.html b/files/ru/mozilla/add-ons/webextensions/user_interface/extension_pages/index.html new file mode 100644 index 0000000000..fdb63f2252 --- /dev/null +++ b/files/ru/mozilla/add-ons/webextensions/user_interface/extension_pages/index.html @@ -0,0 +1,73 @@ +--- +title: Страницы расширения +slug: Mozilla/Add-ons/WebExtensions/user_interface/Extension_pages +tags: + - UI + - WebExtensions + - Веб-расширения + - Для начинающих +translation_of: Mozilla/Add-ons/WebExtensions/user_interface/Extension_pages +--- +<div>{{AddonSidebar()}}</div> + +<p><span class="seoSummary">В расширение можно добавить HTML-страницы, чтобы предоставить пользователю формы, помощь или другое необходимое содержимое.</span></p> + +<p><img alt="Example of a simple bundled page displayed as a detached panel." src="https://mdn.mozillademos.org/files/15752/bundled_page_as_panel_small.png" style="display: block; height: 216px; margin-left: auto; margin-right: auto; width: 350px;"></p> + +<p>Эти страницы получат доступ к привилегированным средствам JavaScript API — таким же как те, что доступны фоновым скриптам расширения. Но каждая из них будет открыта в своей отдельной вкладке — со своей очередью задач JavaScript, своими глобальными переменными и т. д.</p> + +<p>Фоновую страницу можно считать "невидимой страницей расширения".</p> + +<h2 id="Определение_страниц_расширения">Определение страниц расширения</h2> + +<p>К расширению можно подключить файлы HTML и используемые в них файлы CSS и JavaScript. Можно расположить все эти файлы в корне папки расширения, а можно организовать более сложную структуру каталога.</p> + +<pre>/my-extension + /manifest.json + /my-page.html + /my-page.js</pre> + +<h2 id="Отображение_страниц_расширения">Отображение страниц расширения</h2> + +<p>Есть два способа отобразить страницу расширения: {{WebExtAPIRef("windows.create()")}} и {{WebExtAPIRef("tabs.create()")}}.</p> + +<p>Например для того, чтобы создать окно сообщения, можно с помощью функции <code>windows.create()</code> открыть страницу HTML в отсоединённой панели (detached panel) — в окне без строки адреса, полосы закладок и других обычных элементов управления:</p> + +<pre class="brush: js">let createData = { + type: "detached_panel", + url: "panel.html", + width: 250, + height: 100 +}; +let creating = browser.windows.create(createData);</pre> + +<p>Когда окно больше не будет нужно, его можно закрыть программно.</p> + +<p>Например, когда пользователь нажмёт на кнопку, можно вызвать функцию {{WebExtAPIRef("windows.remove()")}} и передать ей идентификатор текущего окна:</p> + +<pre class="brush: js">document.getElementById("closeme").addEventListener("click", function(){ + let winId = browser.windows.WINDOW_ID_CURRENT; + let removing = browser.windows.remove(winId); +}); </pre> + +<h2 id="Страницы_расширения_и_история">Страницы расширения и история</h2> + +<p>По умолчанию страницы, открытые таким образом, будут сохранены в истории браузера — точно так же, как и обычные веб-страницы. Если такое поведение не нужно, используйте {{WebExtAPIRef("history.deleteUrl()")}}, чтобы удалить запись:</p> + +<pre class="brush: js" id="ct-4">function onVisited(historyItem) { + if (historyItem.url == browser.extension.getURL(myPage)) { + browser.history.deleteUrl({url: historyItem.url}); + } +} + +browser.history.onVisited.addListener(onVisited);</pre> + +<p>Для использования API истории браузера нужно добавить разрешение "<code>history</code>" с помощью элемента <a href="https://developer.mozilla.org/ru/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions">permissions</a> в файле <code><a href="https://developer.mozilla.org/ru/docs/Mozilla/Add-ons/WebExtensions/manifest.json">manifest.json</a></code>.</p> + +<h2 id="Дизайн_веб-страницы">Дизайн веб-страницы</h2> + +<p>Подробности о том, как сделать, чтобы дизайн Ваших страниц совпадал со стилем Firefox, смотрите на сайте <a class="grey-90 no-underline hover-no-underline" href="https://design.firefox.com/photon/index.html">Система дизайна Photon</a> (на английском языке) и в документации <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Browser_styles">browser styles</a>.</p> + +<h2 id="Примеры">Примеры</h2> + +<p>В репозитории <a class="external external-icon" href="https://github.com/mdn/webextensions-examples">webextensions-examples</a> на GitHub есть пример <a class="external external-icon" href="https://github.com/mdn/webextensions-examples/tree/master/window-manipulator">window-manipulator</a>, в котором используются некоторые из возможностей для создания окон.</p> diff --git a/files/ru/mozilla/add-ons/webextensions/user_interface/index.html b/files/ru/mozilla/add-ons/webextensions/user_interface/index.html new file mode 100644 index 0000000000..c35b6146c6 --- /dev/null +++ b/files/ru/mozilla/add-ons/webextensions/user_interface/index.html @@ -0,0 +1,107 @@ +--- +title: Пользовательский интерфейс +slug: Mozilla/Add-ons/WebExtensions/user_interface +tags: + - Пользовательский интерфейс +translation_of: Mozilla/Add-ons/WebExtensions/user_interface +--- +<div>{{AddonSidebar}}</div> + +<p>У расширений WebExtensions есть несколько органов взаимодействия с пользователем, с их помощью человек пользуется <em>расширенным</em> функционалом. Все они перечислены ниже, с инструкцией как использовать в своем расширении каждый из них<span id="result_box" lang="ru"><span>.</span></span></p> + +<div class="note"> +<p><span id="result_box" lang="ru"><span>Советы как с помощью этих элементов пользовательского интерфейса (UI)</span></span><span lang="ru"><span> обеспечить отличное взаимодействие человека с программой вы найдёте в статье </span></span><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/User_experience_best_practices">User experience best practices</a>.</p> +</div> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Элемент UI</th> + <th scope="col">Назначение</th> + <th scope="col" style="width: 350px;">Как выглядит?</th> + </tr> + </thead> + <tbody> + <tr> + <td><a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Browser_action">Кнопка на панели инструментов</a></td> + <td> + <p>Кнопка на панели инструментов доступна изо всех вкладок.<br> + Реакцию на нажатие кнопки обеспечивает расширение.</p> + </td> + <td><img alt="Example of a WebExtension toolbar button" src="https://mdn.mozillademos.org/files/12966/browser-action.png" style="height: 99px; width: 350px;"></td> + </tr> + <tr> + <td> + <p><s>Browser toolbar button with a <a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Popups">popup</a></s></p> + </td> + <td> + <p><s>Кнопка со всплывающим окном на панели инструментов браузера, которая открывается при нажатии. Всплывающее окно определяется в документе HTML, который обрабатывает взаимодействие пользователя.</s></p> + </td> + <td> + <p><s><img alt="Example of a WebExtension toolbar button with a popup" src="https://mdn.mozillademos.org/files/14039/popup-shadow.png" style="height: 156px; width: 350px;"></s></p> + </td> + </tr> + <tr> + <td><a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Page_actions">Кнопка в адресной строке</a></td> + <td>В отличие от панели инструментов, в адресной строке кнопка должна появляться только рядом с адресом предназначенной для нее страницы.</td> + <td><img alt="Example showing an address bar button (page action)" src="https://mdn.mozillademos.org/files/15047/address_bar_button.png" style="height: 127px; width: 350px;"></td> + </tr> + <tr> + <td><a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Popups">Всплывающие окна</a></td> + <td>При нажатии на кнопку всплывает (popup) web-страница с органами управления.</td> + <td><img alt="Example of a popup on the address bar button" src="https://mdn.mozillademos.org/files/15053/page_action_popup.png" style="height: 250px; width: 330px;"></td> + </tr> + <tr> + <td><a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Context_menu_items">Контекстное меню</a></td> + <td>Органы управления могут быть упорядочены в ветвящейся структуре контекстных меню браузера.</td> + <td><img alt="" src="https://mdn.mozillademos.org/files/15051/context_menu_example.png" style="height: 359px; width: 350px;"></td> + </tr> + <tr> + <td><a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Sidebars">Боковая панель</a></td> + <td> + <p dir="ltr">В боковой панели рядом с интернет-сайтом открывается web-страница с интерфейсом пользователя. Человек может ее закрыть и открыть когда в ней появится потребность.</p> + </td> + <td><img alt="Example of a WebExtension's sidebar" src="https://mdn.mozillademos.org/files/14825/bookmarks-sidebar.png" style="height: 209px; width: 350px;"></td> + </tr> + <tr> + <td><a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Options_pages">Страница настройки дополнения</a></td> + <td> + <p><span id="result_box" lang="ru"><span>Страница пользовательских настроек доступна из меню управления дополнениями единообразно </span></span>для всех расширений.</p> + </td> + <td><img alt="Example showing the options page content added in the favorite colors example." src="https://mdn.mozillademos.org/files/15055/options_page.png" style="height: 259px; width: 350px;"></td> + </tr> + <tr> + <td><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Bundled_web_pages">Дополнительные веб-страницы</a></td> + <td> + <p>Некоторые варианты содержимого (например, справку или форму обратной связи) удобнее расположить на дополнительной web-странице, которая открывается в собственной вкладке или окне.</p> + </td> + <td><img alt="Example of a simple bundled page displayed as a detached panel." src="https://mdn.mozillademos.org/files/15063/bundled_page_as_panel_small.png" style="height: 180px; width: 350px;"></td> + </tr> + <tr> + <td><a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Notifications">Уведомления</a></td> + <td> + <p>Пользователю можно сообщить что-либо средствами уведомления, предусмотренными в ОС.<br> + Расширение отреагирует когда уведомление будет либо прочитано пользователем, либо скрыто (явным решением человека или логикой программы) так и оставшись непрочтённым.</p> + </td> + <td><img alt="Example notification from a WebExtension" src="https://mdn.mozillademos.org/files/14043/notify-shadowed.png" style="height: 95px; width: 350px;"></td> + </tr> + <tr> + <td><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Omnibox">Угадывание адреса по мере ввода</a></td> + <td><span id="noHighlight_0.4753766294143369">Предлагать настраиваемые варианты адресной строки при вводе пользователем ключевого слова.</span></td> + <td><img alt="Example showing the result of the firefox_code_search WebExtension's customization of the address bar suggestions." src="https://mdn.mozillademos.org/files/15059/omnibox_example_small.png" style="height: 242px; width: 350px;"></td> + </tr> + <tr> + <td><a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/devtools_panels">Панели инструмента разработчика</a></td> + <td><span id="result_box" lang="ru"><span>Вкладка со связанным HTML-документом, который отображается в инструментах разработчика браузера.</span></span></td> + <td><img alt="New panel tab in the Developer Tools tab bar" src="https://mdn.mozillademos.org/files/15049/developer_panel_tab.png" style="height: 180px; width: 350px;"></td> + </tr> + </tbody> +</table> + +<p><span id="noHighlight_0.852967693850544">В следующих руководствах приведены пошаговые инструкции по созданию некоторых из этих параметров пользовательского интерфейса:</span></p> + +<ul> + <li><a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Add_a_button_to_the_toolbar">Add a button to the toolbar</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Implement_a_settings_page">Implement a settings page</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Extending_the_developer_tools">Extending the developer tools</a></li> +</ul> diff --git a/files/ru/mozilla/add-ons/webextensions/user_interface/notifications/index.html b/files/ru/mozilla/add-ons/webextensions/user_interface/notifications/index.html new file mode 100644 index 0000000000..4bb1099110 --- /dev/null +++ b/files/ru/mozilla/add-ons/webextensions/user_interface/notifications/index.html @@ -0,0 +1,51 @@ +--- +title: Уведомления +slug: Mozilla/Add-ons/WebExtensions/user_interface/Notifications +tags: + - Web-расширение + - Расширение +translation_of: Mozilla/Add-ons/WebExtensions/user_interface/Notifications +--- +<div>{{AddonSidebar}}</div> + +<div> +<p><span class="seoSummary">Уведомления позволяют вам передавать информацию пользователям вашего расширения через службу уведомлений в операционной системе.</span></p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/15754/notify-shadowed.png" style="display: block; height: 147px; margin-left: auto; margin-right: auto; width: 390px;"></p> + +<p>Уведомления могут включать в себя призывы к выполнению каких-либо действий, а ваше расширение может обрабатывать события закрытия или нажатия на уведомления.</p> + +<h2 id="Управление_уведомлениями">Управление уведомлениями</h2> + +<p>Управление уведомлениями происходит программным путём с помощью {{WebExtAPIRef("notifications")}} API. Для использования этого API вы должны иметь <code>notifications</code> полномочия в manifest.json:</p> + +<pre class="brush: json"><span class="pl-s"><span class="pl-pds">"</span>permissions<span class="pl-pds">"</span></span>: [<span class="pl-s"><span class="pl-pds">"</span>notifications<span class="pl-pds">"</span></span>]</pre> + +<p>После этого вы можете использовать {{WebExtAPIRef("notifications.create")}} для создания ваших уведомлений, как, например, в нижеприведённом коде, взятом из <a href="https://github.com/mdn/webextensions-examples/tree/master/notify-link-clicks-i18n">notify-link-clicks-i18n:</a></p> + +<pre class="brush: js">var title = browser.i18n.getMessage("notificationTitle"); +var content = browser.i18n.getMessage("notificationContent", message.url); +browser.notifications.create({ + "type": "basic", + "iconUrl": browser.extension.getURL("icons/link-48.png"), + "title": title, + "message": content +});</pre> + +<p>Этот код создаёт уведомление с иконкой, заголовком и сообщением.</p> + +<p>Если уведомление имеет цель призвать пользователя к какому-либо действию, вы можете установить обработчик события на нажатия на уведомления:</p> + +<pre class="brush: js line-numbers language-js"><code class="language-js">browser<span class="punctuation token">.</span>notifications<span class="punctuation token">.</span>onClicked<span class="punctuation token">.</span><span class="function token">addListener</span><span class="punctuation token">(</span>handleClick<span class="punctuation token">)</span><span class="punctuation token">;</span> +</code></pre> + +<p>Если вы собираетесь призывать пользователей к действиям с помощью уведомлений, вам так же будет полезно определять <code>id</code> этих уведомлений, для того чтобы вы в дальнейшем имели возможность различать на какое конкретно уведомление было произведено нажатие.</p> + +<h2 id="Иконки">Иконки</h2> + +<p>Смотрите статью <a href="https://design.firefox.com/photon/visuals/iconography.html">Iconography</a> в документации <a class="grey-90 no-underline hover-no-underline" href="https://design.firefox.com/photon/index.html">Photon Design System</a> для получения информации по созданию иконок для уведомлений.</p> + +<h2 id="Примеры">Примеры</h2> + +<p>Репозиторий образцов расширений <a href="https://github.com/mdn/webextensions-examples">webextensions-examples </a>на GitHub включает в себя расширение <a href="https://github.com/mdn/webextensions-examples/tree/master/notify-link-clicks-i18n">notify-link-clicks-i18n</a>, которое реализует систему уведомлений.</p> +</div> diff --git a/files/ru/mozilla/add-ons/webextensions/user_interface/omnibox/index.html b/files/ru/mozilla/add-ons/webextensions/user_interface/omnibox/index.html new file mode 100644 index 0000000000..cb7285ba92 --- /dev/null +++ b/files/ru/mozilla/add-ons/webextensions/user_interface/omnibox/index.html @@ -0,0 +1,68 @@ +--- +title: Адресная строка +slug: Mozilla/Add-ons/WebExtensions/user_interface/Omnibox +tags: + - Web-расширение + - Расширение +translation_of: Mozilla/Add-ons/WebExtensions/user_interface/Omnibox +--- +<div>{{AddonSidebar()}}</div> + +<p>Используя {{WebExtAPIRef("omnibox")}} API, расширения могут взаимодействовать с адресной строкой и заполнять её выпадающий список предложений своими значениями, после введения пользователем определённого ключевого слова.</p> + +<p><img alt="Example showing the result of the firefox_code_search WebExtension's customization of the address bar suggestions." src="https://mdn.mozillademos.org/files/15749/omnibox_example_small.png" style="display: block; height: 232px; margin-left: auto; margin-right: auto; width: 350px;"></p> + +<p>Это могло бы позволить вам написать расширение, которое, например, искало бы бесплатные книги в электронной библиотеке, или как в примере выше, строки кода из репозитория.</p> + +<h2 id="Настраивание_взаимодействия_с_адресной_строкой">Настраивание взаимодействия с адресной строкой</h2> + +<p>Чтобы получить возможность взаимодействия с адресной строкой, вам необходимо добавить ключ <a href="https://developer.mozilla.org/ru/docs/Mozilla/Add-ons/WebExtensions/manifest.json/omnibox">omnibox</a> в <a href="https://developer.mozilla.org/ru/docs/Mozilla/Add-ons/WebExtensions/manifest.json">manifest.json</a> файл, и присвоить ему значение в виде объекта, определяющего ключевое слово, после введения которого расширение активирует взаимодействие:</p> + +<pre class="brush: json line-numbers language-json"> "omnibox": { "keyword" : "cs" }</pre> + +<p>При желании, используя метод {{WebExtAPIRef("omnibox.setDefaultSuggestion()")}}, вы можете изменить текст изначального предложения, которое всегда будет появляться первым в списке предложений адресной строки. Как вариант, оно может быть использовано для описания предоставляемого расширением функционала:</p> + +<pre class="brush: js line-numbers language-js">browser.omnibox.setDefaultSuggestion({ + description: `Искать в кодовой базе firefox + (пример: "hello world" | "path:omnibox.js onInputChanged")` +});</pre> + +<p>Далее, вы можете зарегистрировать обработчики на событие {{WebExtAPIRef("omnibox.onInputStarted")}}, которое будет распространяться после введения пользователем ключевого слова и нажатия на пробел, и на событие {{WebExtAPIRef("omnibox.onInputChanged")}}, которое будет распространяться при изменении пользователем строки адреса. Так же, с помощью обработчика события {{WebExtAPIRef("omnibox.onInputChanged")}}, вы будете иметь возможность заполнять выпадающий список своими предложениями. К примеру, в случае поиска кода на сайте https://searchfox.org/mozilla-central, используя введённые пользователем слова:</p> + +<pre class="brush: js">browser.omnibox.onInputChanged.addListener((text, addSuggestions) => { + let headers = new Headers({"Accept": "application/json"}); + let init = {method: 'GET', headers}; + let url = buildSearchURL(text); + let request = new Request(url, init); + + fetch(request) + .then(createSuggestionsFromResponse) + .then(addSuggestions); +});</pre> + +<p>Заметьте, что изначальное предложение в любом случае будет оставаться первым в выпадающем списке.</p> + +<p>Чтобы обрабатывать нажатия пользователя на предложения из выпадающего списка, подпишитесь на событие {{WebExtAPIRef("omnibox.onInputEntered")}}. При нажатии на изначальное предложение в функцию обработчика будет передана набранная в данный момент строка адреса, во всех остальных случаях будет передаваться значение из выбранного предложения. Вторым аргументом в функцию обработчика будет передана информация из настроек браузера о том, каким образом пользователь предпочитает открывать новые ссылки. Например, в нижерасположенном коде, нажатие на изначальное предложение запустит поиск, тогда как нажатие на все остальные предложения просто откроет определённые них URL:</p> + +<pre class="brush: js">browser.omnibox.onInputEntered.addListener((text, disposition) => { + let url = text; + if (!text.startsWith(SOURCE_URL)) { + // Обновить url, если пользователь нажал на изначальное предложение. + url = `${SEARCH_URL}?q=${text}`; + } + switch (disposition) { + case "currentTab": + browser.tabs.update({url}); + break; + case "newForegroundTab": + browser.tabs.create({url}); + break; + case "newBackgroundTab": + browser.tabs.create({url, active: false}); + break; + } +});</pre> + +<h2 id="Примеры">Примеры</h2> + +<p>Репозиторий образцов расширений <a href="https://github.com/mdn/webextensions-examples">webextensions-examples</a> на GitHub включает в себя расширение <a class="external external-icon" href="https://github.com/mdn/webextensions-examples/tree/master/firefox-code-search">firefox-code-search</a>, демонстрирующее взаимодействие с адресной строкой.</p> diff --git a/files/ru/mozilla/add-ons/webextensions/user_interface/popups/index.html b/files/ru/mozilla/add-ons/webextensions/user_interface/popups/index.html new file mode 100644 index 0000000000..23541f5a60 --- /dev/null +++ b/files/ru/mozilla/add-ons/webextensions/user_interface/popups/index.html @@ -0,0 +1,50 @@ +--- +title: Всплывающие окна +slug: Mozilla/Add-ons/WebExtensions/user_interface/Popups +translation_of: Mozilla/Add-ons/WebExtensions/user_interface/Popups +--- +<div>{{AddonSidebar}}</div> + +<div> +<p>A popup is a dialog that's associated with a <a href="/en-US/Add-ons/WebExtensions/Browser_action">toolbar button</a> or <a href="/en-US/Add-ons/WebExtensions/Page_actions">address bar button</a>.</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/14039/popup-shadow.png" style="display: block; height: 389px; margin-left: auto; margin-right: auto; width: 500px;"></p> + +<p>When the user clicks the button, the popup is shown. When the user clicks anywhere outside the popup, the popup is closed. The popup can be closed programmatically by calling <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/close">window.close()</a></code> from a script running in the popup. However, you can't open the popup programmatically from an extension's JavaScript: it can only be opened in response to a user action.</p> + +<p>You can define a keyboard shortcut that opens the popup using the <code>"_execute_browser_action"</code> and <code>"_execute_page_action"</code> shortcuts. See the documentation for the manifest.json key <code><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/commands">commands</a></code><span style="display: none;"> </span>.</p> + +<h2 id="Specifying_a_popup">Specifying a popup</h2> + +<p>The popup is specified as an HTML file, which can include CSS and JavaScript files, as a normal web page does. Unlike a normal page, though, the JavaScript can use all the <a href="https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API">WebExtension APIs</a> that the extension has <a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions">permissions</a> for.</p> + +<p>The HTML file is included in the extension and specified as part of the <code><a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/browser_action">browser_action</a></code> or <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/page_action">page_action</a> key by <code>"default_popup"</code> in the manifest.json:</p> + +<pre class="brush: json"> "browser_action": { + "default_icon": "icons/beasts-32.png", + "default_title": "Beastify", + "default_popup": "popup/choose_beast.html" + }</pre> + +<p>You can ask the browser to include a stylesheet in your popup that will make it look consistent with the browser's UI. To do this, include <code>"browser_style": true</code> in the <code><a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/browser_action">browser_action</a></code> or <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/page_action">page_action</a> key.</p> + +<p>Popups have a Content Security Policy that restricts the sources from which they can load resources, and disallows some unsafe practices such as the use of <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval">eval()</a></code>. See <a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Content_Security_Policy">Content Security Policy</a> for more details on this.</p> + +<h2 id="Debugging_popups">Debugging popups</h2> + +<p>You can debug a popup's markup and JavaScript using the Add-on Debugger, but you'll need to turn on the Disable popup auto hide feature to prevent popups from hiding when you click outside them.<a href="https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Debugging#Debugging_popups"> Read about debugging popups</a>.</p> + +<h2 id="Popup_resizing">Popup resizing</h2> + +<p>Popups resize automatically to fit their content. The algorithm for this may differ from one browser to another.</p> + +<p>In Firefox, the size is calculated just before the popup is shown, and at most 10 times per second after DOM mutations. For strict mode documents, the size is calculated based on the layout size of the <code><a href="/en-US/docs/Web/HTML/Element/body"><body></a></code> element. For quirks mode, it's the <code><a href="/en-US/docs/Web/HTML/Element/html"><html></a></code> element. Firefox calculates the preferred width of the contents of that element, reflows it to that width, and then resizes so there's no vertical scrolling. It will grow to a size of <strong>800x600 pixels</strong> at most if that fits on the user's screen. If the user <a href="https://support.mozilla.org/en-US/kb/customize-firefox-controls-buttons-and-toolbars#w_customize-the-menu-or-the-toolbar">moves the extension's button to the menu</a> or it appears in the toolbar overflow, then the popup appears inside the menu's panel and is given a fixed width.</p> + +<h2 id="Examples">Examples</h2> + +<p>The <a href="https://github.com/mdn/webextensions-examples">webextensions-examples</a> repo on GitHub, contains several examples of extensions that use a browser action:</p> + +<ul> + <li><a href="https://github.com/mdn/webextensions-examples/tree/master/beastify">beastify</a> uses a browser action.</li> +</ul> +</div> diff --git a/files/ru/mozilla/add-ons/webextensions/user_interface/sidebars/index.html b/files/ru/mozilla/add-ons/webextensions/user_interface/sidebars/index.html new file mode 100644 index 0000000000..5a4f1e82f1 --- /dev/null +++ b/files/ru/mozilla/add-ons/webextensions/user_interface/sidebars/index.html @@ -0,0 +1,56 @@ +--- +title: Боковые панели (Sidebars) +slug: Mozilla/Add-ons/WebExtensions/user_interface/Sidebars +tags: + - Sidebar + - Боковая панель +translation_of: Mozilla/Add-ons/WebExtensions/user_interface/Sidebars +--- +<div>{{AddonSidebar}}</div> + +<div> +<p>Боковая панель - это панель, которая отображается в левой части окна браузера, рядом с веб-страницей. В браузере предусмотрен пользовательский интерфейс, который позволяет пользователю видеть доступные боковые панели и выбирать боковую панель для отображения. Например, Firefox имеет меню "Вид > Боковая панель". Одновременно может отображаться только одна боковая панель, и эта боковая панель будет отображаться для всех вкладок и всех окон браузера.</p> + +<p>Браузер может включать в себя ряд встроенных боковых панелей. Например, Firefox включает боковую панель для взаимодействия с закладками:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/14825/bookmarks-sidebar.png" style="display: block; height: 761px; margin-left: auto; margin-right: auto; width: 728px;">Используя ключ <code>sidebar_action</code> в manifest.json, расширение может добавить свою боковую панель в браузер. Она будет доступна наравне со встроенными панелями, и пользователь сможет открыть ее, используя тот же механизм, что и для встроенных боковых панелей.</p> + +<p>Как и в случае всплывающих окон (Popups), вы задаете содержимое боковой панели как документ HTML. Когда пользователь открывает боковую панель, этот документ загружается в каждое открытое окно браузера. Каждое окно получает свой экземпляр документа. Когда открываются новые окна, они также получат свои собственные экземпляры документа боковой панели.</p> + +<p>Вы можете задать HTML документ для конкретной вкладки, используя функцию {{WebExtAPIRef("sidebarAction.setPanel()")}}. Боковая панель может определить, к какому окну она принадлежит используя {{WebExtAPIRef("windows.getCurrent()")}} API:</p> + +<pre class="brush: js">// sidebar.js +browser.windows.getCurrent({populate: true}).then((windowInfo) => { + myWindowId = windowInfo.id; +});</pre> + +<p>Это полезно, если боковая панель хочет отображать различный контент для разных окон. Использование такого подхода см. в примере <a href="https://github.com/mdn/webextensions-examples/tree/master/annotate-page">"annotate-page" example</a>.</p> + +<p>HTML документ боковай панели получает доступ к тому же набору привилегированных JavaScript API, что и background и popup сценарии этого расширения. Они могут получить прямой доступ к фоновой странице с помощью {{WebExtAPIRef("runtime.getBackgroundPage()")}}, и могут взаимодействовать с сценариями контента или нативными приложениями, используя API интерфейса обмена сообщениями, такие как {{WebExtAPIRef("tabs.sendMessage()")}} и {{WebExtAPIRef("runtime.sendNativeMessage()")}}.</p> + +<p>Документы боковой панели выгружаются, когда окно браузера закрывается или пользователь закрывает боковую панель. Это означает, что в отличие от background страниц документы боковой панели не остаются загруженными все время, но в отличие от popup окон они остаются загруженными, пока пользователь взаимодействует с веб-страницами.</p> + +<p>После первой установки расширения, использующего боковую панель, его панель будет открыта автоматически. Это сделано для того, чтобы помочь пользователю понять, что расширение использует боковую панель. Обратите внимание, что расширение не может открывать боковые панели программно: боковые панели могут открываться только пользователем.</p> + +<h2 id="Использование_боковых_панелей">Использование боковых панелей</h2> + +<p>Чтобы использовать боковую панель в своем расширении, укажите с помощью ключа <code><a href="/en-US/Add-ons/WebExtensions/manifest.json/sidebar_action">sidebar_action</a></code> в manifest.json key, HTML-документ панели, а также заголовок и значок по умолчанию:</p> + +<pre class="brush: json">"sidebar_action": { + "default_title": "My sidebar", + "default_panel": "sidebar.html", + "default_icon": "sidebar_icon.png" +}</pre> + +<p>Вы можете изменить название и значок панели программно, используя {{WebExtAPIRef("sidebarAction")}} API.</p> + +<p>Заголовок и значок отображаются пользователю в любом UI, предоставляемом браузером, для отображения боковых панелей, например меню "Вид > Боковые панели" в Firefox.</p> + +<h2 id="Примеры">Примеры</h2> + +<p>В репозитории <a href="https://github.com/mdn/webextensions-examples">webextensions-examples</a> на GitHub содержится несколько примеров расширений, которые используют боковую панель:</p> + +<ul> + <li><a href="https://github.com/mdn/webextensions-examples/tree/master/annotate-page">annotate-page</a> использует боковую панель.</li> +</ul> +</div> diff --git a/files/ru/mozilla/add-ons/webextensions/what_are_webextensions/index.html b/files/ru/mozilla/add-ons/webextensions/what_are_webextensions/index.html new file mode 100644 index 0000000000..ff947610ee --- /dev/null +++ b/files/ru/mozilla/add-ons/webextensions/what_are_webextensions/index.html @@ -0,0 +1,95 @@ +--- +title: Что такое WebExtensions? +slug: Mozilla/Add-ons/WebExtensions/What_are_WebExtensions +tags: + - Extensions + - WebExtensions + - Дополнения + - Расширения +translation_of: Mozilla/Add-ons/WebExtensions/What_are_WebExtensions +--- +<div>{{AddonSidebar}}</div> + +<div> +<p>Дополнения расширяют и изменяют функциональность браузера. Они разрабатываются с использованием стандартных Веб-технологий - JavaScript, HTML и CSS, а также некоторых специальных JavaScript API, которые позволяют вам делать намного больше, чем то, на что вы способны на любом из сайтов. Вот некоторые из примеров того, что вы можете делать:</p> +</div> + +<div> +<p><strong>Расширять или дополнять сайты</strong>: Используйте дополнения, чтобы предоставить информацию или дополнительные функции для браузера. Позвольте пользователям собирать информацию с посещённых ими страниц для улучшения предлагаемых вами услуг.</p> +</div> + +<div><img alt="Пример использования Amazon Assistant for Firefox" src="https://media.prod.mdn.mozit.cloud/attachments/2018/02/13/15808/f81a8cc5b196af29cd9d558ee3c5dbdc/Amazon_add_on.png" style="height: 438px; width: 700px;"></div> + +<div> +<p>Примеры: <a href="https://addons.mozilla.org/en-US/firefox/addon/amazon-browser-bar/">Amazon Assistant for Firefox</a>, <a href="https://addons.mozilla.org/en-US/firefox/addon/onenote-clipper/">OneNote Web Clipper</a> и <a href="https://addons.mozilla.org/en-US/firefox/addon/grammarly-1/">Grammarly for Firefox</a>.</p> +</div> + +<div> +<p><strong>Дайте пользователям продемонстрировать себя</strong>: Дополнения могут управлять содержимым сайтов, например, позволять пользователям добавлять их любимые изображения как фоновые картинки для каждого сайта, которые они посещают. Ещё дополнения могут изменять и то, как выглядит сам интерфейс Firefox, делая это тем же способом, что и <a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/Themes/Theme_concepts">обычные темы</a>.</p> +</div> + +<div><img alt="Как расширение может изменить фоновую картинку сайта" src="https://media.prod.mdn.mozit.cloud/attachments/2018/02/13/15809/ce69d140dc91da804ce6eb8f20d03c07/MyWeb_New_Tab_add_on.png" style="height: 398px; width: 540px;"></div> + +<div> +<p>Примеры: <a href="https://addons.mozilla.org/en-US/firefox/addon/myweb-new-tab/">MyWeb New Tab</a>, <a href="https://addons.mozilla.org/en-US/firefox/addon/tabliss/">Tabliss</a> и <a href="https://addons.mozilla.org/en-US/firefox/addon/vivaldifox/">VivaldiFox</a>.</p> +</div> + +<div> +<p><strong>Добавьте или скройте содержимое веб-страниц</strong>: Возможно, вы захотите помочь пользователям заблокировать назойливую рекламу, дать доступ к туристическоим путеводителям, когда на странице упоминается страна или город, или отформатировать содержимое страницы так, чтобы дать незабываемый опыт прочтения. С доступом к HTML и CSS дополнения могут помогать пользователям смотреть на Интернет так, как они хотят.</p> +</div> + +<div><img alt="Как работает uBlock Origin, популярный блокировщик рекламы" src="https://media.prod.mdn.mozit.cloud/attachments/2018/02/13/15807/4e85eb0560fc8d5945e64cf75a1a8e50/ublock_origin_add_on.png" style="height: 480px; width: 640px;"></div> + +<div> +<p>Примеры: <a href="https://addons.mozilla.org/en-US/firefox/addon/ublock-origin/">uBlock Origin</a>, <a href="https://addons.mozilla.org/en-US/firefox/addon/reader/">Reader</a> и <a href="https://addons.mozilla.org/en-US/firefox/addon/toolbox-google-play-store/">Toolbox for Google Play Store™</a>.</p> +</div> + +<div> +<p><strong>Дайте новые инструменты и функции</strong>: Добавляйте новые пункты в список дел или генерируйте QR-коды для текста страницы или различных ссылок. При помощи гибких опций интерфейса и мощью WebExtensions API вы можете с лёгкостью добавлять новые функции в браузер. Причём вы можете расширить таким образом функциональность любого сайта, он не обязательно должен быть вашим.</p> +</div> + +<div><img alt="Как выглядит генератор QR-кодов QRUTILS.com" src="https://media.prod.mdn.mozit.cloud/attachments/2018/02/13/15806/b9070a5f71c40c18d0a4ae722bca2e4a/QR_Code_Image_Generator_add_on.png" style="height: 512px; width: 700px;"></div> + +<div> +<p>Примеры: <a href="https://addons.mozilla.org/en-US/firefox/addon/swimlanes-for-trello/">Swimlanes for Trello</a> и <a href="https://addons.mozilla.org/en-US/firefox/addon/tomato-clock/">Tomato Clock</a>.</p> +</div> + +<div> +<p><strong>Игры</strong>: Давайте геймерам тот же опыт, что и в традиционных компьютерных играх - или же исследуйте новые игровые возможности, например, внедряя геймплей в ежедневный просмотр веб-страниц.</p> +</div> + +<div><img alt="Пример игры Asteroids in Popup" src="https://media.prod.mdn.mozit.cloud/attachments/2018/02/13/15805/259d5d3c0620469521d43a897a7b653b/Asteroids_in_Popup_add_on%20.png" style="height: 438px; width: 700px;"></div> + +<div> +<p>Примеры: <a href="https://addons.mozilla.org/en-US/firefox/addon/asteroids-in-popup/">Asteroids in Popup</a>, <a href="https://addons.mozilla.org/en-US/firefox/addon/solitaire-card-game-new-tab/">Solitaire Card Game New Tab</a> и <a href="https://addons.mozilla.org/en-US/firefox/addon/2048-prime/">2048 Prime</a>.</p> +</div> + +<div> +<p><strong>Добавляйте инструменты для разработки</strong>: Вы можете предлагать инструменты разработки как часть вашего бизнеса, или же как то, что вы нового открыли для веб-разработки и чем хотите поделиться. Например, вы можете добавлять свои инструменты во встроенный набор инструментов разработчика Firefox.</p> +</div> + +<div><img alt="То, как интегрируется aXe в инструменты разработчика Firefox" src="https://media.prod.mdn.mozit.cloud/attachments/2018/02/13/15804/a2f3ed2cd857626d42352dd0de550486/aXe_Developer_Tools_add_on.png" style="height: 261px; width: 700px;"></div> + +<div> +<p>Примеры: <a href="https://addons.mozilla.org/en-US/firefox/addon/web-developer/">Web Developer</a>, <a href="https://addons.mozilla.org/en-US/firefox/addon/react-devtools/">Web React Developer Tools</a> и <a href="https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/">aXe Developer Tools</a>.</p> +</div> + +<div> +<p>WebExtensions - это кросс-браузерная система для разработки дополнений для браузера. В значительной степени ее API совместим с <a class="external external-icon" href="https://developer.chrome.com/extensions">extension API</a>, который поддерживается браузерами Google Chrome и Opera. Расширения, разработанные для этих браузеров, в большинстве случаев будут работать в Firefox или Microsoft Edge с минимальными изменениями. Также API полностью совместим с <a href="/ru/Firefox/Multiprocess_Firefox">мультипроцессным Firefox</a>.</p> +</div> + +<div> +<p>Мы также намерены расширять API для поддержки нужд разработчиков дополнений, и если у вас есть идеи, мы будем рады услышать их. Вы можете связаться с нами через рассылку <a class="external external-icon" href="https://mail.mozilla.org/listinfo/dev-addons">dev-addons mailing list</a> или на <a class="external external-icon" href="https://wiki.mozilla.org/IRC">IRC</a> канале <a href="irc://irc.mozilla.org/webextensions">#webextensions</a>.</p> +</div> + +<div> +<p>До появления WebExtensions разработка дополнения для Firefox осуществлялась одним из трех различных способов: <a href="/en-US/Add-ons/Overlay_Extensions">XUL/XPCOM overlays</a>, <a href="/en-US/docs/Mozilla/Add-ons/Bootstrapped_extensions">bootstrapped extensions</a> или <a href="/en-US/docs/Mozilla/Add-ons/SDK">Add-on SDK</a>. В будущем WebExtensions станет рекомендуемым способом разработки дополнений для Firefox, а остальные способы будут считаться устаревшими.</p> +</div> + +<h2 id="Что_дальше">Что дальше?</h2> + +<ul> + <li>Чтобы посмотреть примеры некоторых дополнений, см. <a href="/en-US/Add-ons/WebExtensions/Examples">Example WebExtensions</a>.</li> + <li>Чтобы узнать больше о структуре дополнений, см. <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Anatomy_of_a_WebExtension">Anatomy of a WebExtension</a>.</li> + <li>Чтобы посмотреть пример разработки простого дополнения, см. <a href="/ru/docs/Mozilla/Add-ons/WebExtensions/Your_first_WebExtension">Ваш первый WebExtension</a>.</li> +</ul> diff --git a/files/ru/mozilla/add-ons/webextensions/your_first_webextension/index.html b/files/ru/mozilla/add-ons/webextensions/your_first_webextension/index.html new file mode 100644 index 0000000000..e9e4e74784 --- /dev/null +++ b/files/ru/mozilla/add-ons/webextensions/your_first_webextension/index.html @@ -0,0 +1,191 @@ +--- +title: Ваш первый WebExtension +slug: Mozilla/Add-ons/WebExtensions/Your_first_WebExtension +tags: + - Beginner + - Extensions + - Guide + - WebExtensions +translation_of: Mozilla/Add-ons/WebExtensions/Your_first_WebExtension +--- +<div>{{AddonSidebar}}</div> + +<p>В этой статье мы пройдем весь путь создания WebExtension для Firefox, от начала и до конца. Это дополнение будет просто добавлять красную рамку ко всем страницам, загруженным с "mozilla.org" или любого из его поддоменов.</p> + +<p>Исходный код этого дополнения доступен на GitHub: <a href="https://github.com/mdn/webextensions-examples/tree/master/borderify">https://github.com/mdn/webextensions-examples/tree/master/borderify</a>.</p> + +<p>Для начала вам нужен Firefox 45 или более поздней версии.</p> + +<h2 id="Написание_WebExtension">Написание WebExtension</h2> + +<p>Создайте новую директорию (папку) и перейдите в нее:</p> + +<pre class="brush: bash">mkdir borderify +cd borderify</pre> + +<h3 id="manifest.json">manifest.json</h3> + +<p>Теперь создайте новый файл, назовите его "manifest.json" в папке "borderify". Вставьте туда следующий код:</p> + +<pre class="brush: json">{ + + "manifest_version": 2, + "name": "Borderify", + "version": "1.0", + + "description": "Adds a solid red border to all webpages matching mozilla.org.", + "icons": { + "48": "icons/border-48.png" + }, + + "applications": { + "gecko": { + "id": "borderify@mozilla.org", + "strict_min_version": "45.0" + } + }, + + "content_scripts": [ + { + "matches": ["*://*.mozilla.org/*"], + "js": ["borderify.js"] + } + ] + +}</pre> + +<ul> + <li>Первые три ключа: <code><a href="/ru/Add-ons/WebExtensions/manifest.json/manifest_version">manifest_version</a></code>, <code><a href="/ru/Add-ons/WebExtensions/manifest.json/name">name</a> и <a href="/ru/Add-ons/WebExtensions/manifest.json/version">version</a></code>, являются обязательными и содержат основные метаданные о дополнении.</li> + <li><code><a href="/ru/Add-ons/WebExtensions/manifest.json/description">description</a></code> не обязателен, но рекомендуется: это описание отображается в Менеджере Дополнений.</li> + <li><code><a href="/ru/Add-ons/WebExtensions/manifest.json/icons">icons</a></code> не обязателен, но рекомендуется: позволяет указать значок для дополнения, который будет виден в Менеджере Дополнений.</li> + <li><code><a href="/ru/Add-ons/WebExtensions/manifest.json/applications">applications</a></code> <span id="result_box" lang="ru"><span>является обязательным для</span> <span>Firefox</span><span>,</span> <span>и</span> <span>определяет</span></span> ID дополнения. Он так же может использоваться для указания минимальной и максимальной версии Firefox, поддерживаемой расширением.</li> +</ul> + +<p>Самый интересный ключ здесь - это <code><a href="/en-US/Add-ons/WebExtensions/manifest.json/content_scripts">content_scripts</a></code>, который говорит Firefox загружать скрипт на Web страницах, чей URL совпадает с заданным шаблоном. В нашем случае, мы просим Firefox загрузить скрипт с названием "borderify.js" на всех HTTP или HTTPS страницах, полученных с "mozilla.org" или любого из его поддоменов.</p> + +<ul> + <li><a href="/ru/Add-ons/WebExtensions/Content_scripts">Узнать больше content scripts.</a></li> + <li><a href="/ru/Add-ons/WebExtensions/Match_patterns">Узнать больше о match patterns</a>.</li> +</ul> + +<div class="warning"> +<p><a href="/ru/Add-ons/WebExtensions/WebExtensions_and_the_Add-on_ID#When_do_you_need_an_Add-on_ID">В некоторых случаях вам нужно указать ID для вашего дополнения</a>. Если вам нужно указать ID дополнения включите ключ <code><a href="/ru/Add-ons/WebExtensions/manifest.json/applications">applications</a></code> в <code>manifest.json</code> и установите его свойство <code>gecko.id</code>:</p> + +<pre class="brush: json">"applications": { + "gecko": { + "id": "borderify@example.com" + } +}</pre> +</div> + +<h3 id="iconsborder-48.png">icons/border-48.png</h3> + +<p>Дополнение должно иметь иконку (значок). Эта иконка будет показана в списке дополнений в Менеджере Дополнений. Наш файл manifest.json сообщает, что иконка будет находиться в файле "icons/border-48.png".</p> + +<p>Создайте директорию (папку) "icons" внутри директории "borderify" . Сохраните в ней иконку под именем "border-48.png". Вы можете использовать <a href="https://github.com/mdn/webextensions-examples/blob/master/borderify/icons/border-48.png">иконку из нашего примера</a>, которая взята из набора иконок Google Material Design, и используется по лицензии <a href="http://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-ShareAlike</a>.</p> + +<p>Вы можете использовать собственную иконку. Её размер должен быть 48x48 пикселей. Вы можете также использовать иконку размером 96x96 пикселей для отображения на мониторах высокого разрешения. В этом случае Вам необходимо указать её в качестве свойства "96" объекта "<code>icons"</code> в файле manifest.json:</p> + +<pre class="brush: json line-numbers language-json"><code class="language-json"><span class="key token">"icons":</span> <span class="punctuation token">{</span> + <span class="key token">"48":</span> <span class="string token">"icons/border-48.png", + "96": "icons/border-96.png"</span> +<span class="punctuation token">}</span></code></pre> + +<p>Также Вы можете создать иконку в формате SVG и она будет корректно масштабироваться.</p> + +<ul> + <li><a href="/ru/Add-ons/WebExtensions/manifest.json/icons">Узнать больше о ключе icons</a></li> +</ul> + +<h3 id="borderify.js">borderify.js</h3> + +<p>Наконец, создайте в директории "borderify" файл с именем "borderify.js" и поместите туда следующий код:</p> + +<pre class="brush: js">document.body.style.border = "5px solid red";</pre> + +<p>Этот скрипт будет встраиваться в страницу, которая совпадает с шаблоном, указанном в ключе <code>content_scripts</code> файла manifest.json. Этот скрипт имеет прямой доступ ко всему документу, как если бы он был загружен самой страницей.</p> + +<ul> + <li><a href="/ru/Add-ons/WebExtensions/Content_scripts">Узнать больше о content scripts</a></li> +</ul> + +<h2 id="Пробуем">Пробуем</h2> + +<p>Сначала внимательно проверьте, что Вы правильно разместили файлы и дали им правильные имена:</p> + +<pre>borderify/ + icons/ + border-48.png + borderify.js + manifest.json</pre> + +<h3 id="Установка">Установка</h3> + +<p>Начиная с версии Firefox 45 Вы можете временно установить WebExtension с локального диска.</p> + +<p>Откройте страницу "about:debugging", кликните "Load Temporary Add-on" и выберите файл manifest.json:</p> + +<p>{{EmbedYouTube("SKb-CNYpl6Q")}}</p> + +<p>Теперь ваше дополнение установлено и останется в браузере до его перезапуска.</p> + +<p>Для проверки, зайдите на страницу "about:addons" чтобы открыть Менеджер Дополнений. Вы должны увидеть своё дополнение с именем и иконкой:</p> + +<p>{{EmbedYouTube("WpUL3-qmenE")}}</p> + +<p>Также, Вы можете запускать WebExtension из командной строки, используя <a href="/ru/docs/Mozilla/Add-ons/WebExtensions/Getting_started_with_web-ext">web-ext</a>.</p> + +<h3 id="Тестирование">Тестирование</h3> + +<p>Теперь зайдите на любую страницу домена "mozilla.org" и вы должны будете увидеть красную границу вокруг страницы:</p> + +<p>{{EmbedYouTube("exUAH0sIyBw")}}</p> + +<p>Поэкспериментируйте немного. Поменяйте цвет границы или сделайте ещё что-нибудь с содержимым на странице. После того, как изменённый скрипт будет сохранён, а страница перезагружена, вы сразу увидите изменения:</p> + +<p>{{EmbedYouTube("t6s_4yF8dRk")}}</p> + +<div class="note"> +<p>Обратите внимание, что после изменения файла manifest.json, вы должны вручную перезагрузить своё дополнение. В настоящий момент это значит, что вам нужно перезагрузить Firefox, а затем снова загрузить своё дополнение на странице "about:debugging". Мы работаем над улучшением этого процесса. </p> +</div> + +<ul> + <li><a href="/ru/Add-ons/WebExtensions/Packaging_and_installation#Loading_from_disk">Узнать больше о временной установке дополнений</a></li> +</ul> + +<h2 id="Упаковка_и_публикация">Упаковка и публикация</h2> + +<div class="hidden"> +<p>Оригинальная статья ссылается на отдельную статью. Убрать параграф туда?</p> +</div> + +<p>Чтобы другие люди могли использовать ваше дополнение, вам необходимо запаковать его. Дополнения Firefox в запакованном виде являются XPI файлами, которые представляют собой обычные ZIP архивы с расширением "xpi".</p> + +<p>При упаковке необходимо учитывать следующее: в ZIP архиве должны быть только файлы, а не содержащая их директория (директория "borderify" не должна попасть в архив). Для того, чтобы создать правильный XPI файл из вашего дополнения, в командной строке перейдите в директорию "borderify" и выполните следующую команду:</p> + +<p><code class="language-bash">zip -r ../borderify.xpi *</code></p> + +<p>Начиная с Firefox 43 все дополнения должны быть подписаны прежде чем они будут установлены в браузер. Вы можете снять это ограничение <em>только</em> в <a class="external external-icon" href="https://www.mozilla.org/en-US/firefox/developer/">Firefox Developer Edition</a> или <a class="text external external-icon" href="https://nightly.mozilla.org/" rel="nofollow">Firefox Nightly</a> при помощи следующих шагов: </p> + +<ul> + <li>перейдите на страницу <code>about:config</code> в Firefox</li> + <li>при помощи строки поиска найдите <code>xpinstall.signatures.required</code></li> + <li>дважды кликнув на этом свойстве или при помощи локального меню (через клик правой кнопкой мыши), выберите "Toggle", чтобы установить значение <code>false</code>.</li> +</ul> + +<p>{{EmbedYouTube("HgtBYDWtH4w")}}</p> + +<ul> + <li><a href="/ru/Add-ons/WebExtensions/Packaging_and_installation">Узнать больше об упаковке и инсталляции</a></li> + <li><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/Publishing_your_WebExtension">Узнать больше о подписи и распространении</a></li> +</ul> + +<h2 id="Что_дальше">Что дальше?</h2> + +<p>Теперь, когда вы имеете представление о разработке дополнений для Firefox, вы можете:</p> + +<ul> + <li><a href="/ru/Add-ons/WebExtensions/Anatomy_of_a_WebExtension">Прочитать больше об анатомии WebExtensions</a></li> + <li><a href="/ru/Add-ons/WebExtensions/Your_second_WebExtension">Создать более сложное WebExtensions</a></li> + <li><a href="/ru/Add-ons/WebExtensions/API">Прочитать больше об API JavaScript, доступном для WebExtensions</a></li> +</ul> diff --git a/files/ru/mozilla/add-ons/webextensions/your_second_webextension/index.html b/files/ru/mozilla/add-ons/webextensions/your_second_webextension/index.html new file mode 100644 index 0000000000..db8eec8f90 --- /dev/null +++ b/files/ru/mozilla/add-ons/webextensions/your_second_webextension/index.html @@ -0,0 +1,363 @@ +--- +title: Ваш второй WebExtension +slug: Mozilla/Add-ons/WebExtensions/Your_second_WebExtension +tags: + - Beginner + - Example + - Guide + - WebExtension +translation_of: Mozilla/Add-ons/WebExtensions/Your_second_WebExtension +--- +<div>{{AddonSidebar}} +<p>Если Вы уже прочитали статью <a dir="ltr" href="/ru/Add-ons/WebExtensions/Your_first_WebExtension" lang="ru-ru">Ваш первый WebExtension</a>, то уже представляете, как создавать WebExtension. В этой статье мы напишем более сложное дополнение, которое демонстрирует еще несколько API.</p> + +<p>Дополнение добавляет новую кнопку на панель инструментов Firefox. Когда пользователь кликает по кнопке, мы показываем ему всплывающую панель с предложением выбрать животное. Когда животное выбрано, мы заменяем содержимое текущей страницы на изображение выбранного животного.</p> + +<p>Чтобы реализовать это, мы:</p> + +<ul> + <li><strong>определим <a href="/ru/docs/Mozilla/Add-ons/WebExtensions/Browser_action">browser action</a> - кнопку, прикрепленную к панели инструментов Firefox.</strong><br> + Для кнопки мы предоставим: + <ul> + <li>иконку с именем "beasts-32.png"</li> + <li>всплывающую панель, если кнопка нажата. Панель состоит из HTML, CSS, и JavaScript.</li> + </ul> + </li> + <li><strong>определим иконку для дополнения</strong> с именем "beasts-48.png". Иконка будет показана в Менеджере дополнений.</li> + <li><strong>напишем сценарий содержимого(content script) "beastify.js", который будет встроен в веб-страницы</strong>.<br> + Это тот код, который и будет изменять страницы.</li> + <li><strong>упакуем несколько изображений животных для замены изображений на веб-странице</strong>.<br> + Мы сделаем изображения "доступными веб-ресурсами"(web accessible resources), чтобы веб-страница могла ссылаться на них.</li> +</ul> + +<p>Вы можете представить общую структуру дополнения вот так:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/13671/Untitled-1.png" style="display: block; height: 1200px; margin-left: auto; margin-right: auto; width: 860px;"></p> + +<p>Это простое дополнение, но показывает множество основных концепций WebExtensions API:</p> + +<ul> + <li>добавление кнопки на панель инструментов</li> + <li>определение всплывающей панели используя HTML, CSS, и JavaScript</li> + <li>встраивание контент-скрипта в веб-страницы</li> + <li>взаимодействие между сценарием содержимого и остальным дополнением</li> + <li>упаковка ресурсов с Вашим дополнением, которые будут использованы веб-страницами</li> +</ul> + +<p>Вы можете найти <a href="https://github.com/mdn/webextensions-examples/tree/master/beastify">полный исходный код дополнения на GitHub</a>.</p> + +<p>Чтобы написать это дополнение, Вам нужен Firefox 45 или новее.</p> + +<h2 id="Написание_WebExtension">Написание WebExtension</h2> + +<p>Создайте новую директорию и перейдите в нее:</p> + +<pre class="brush: bash">mkdir beastify +cd beastify</pre> + +<h3 id="manifest.json">manifest.json</h3> + +<p>Теперь создайте файл "manifest.json" и вставьте в него следующее содержимое:</p> + +<pre class="brush: json">{ + + "manifest_version": 2, + "name": "Beastify", + "version": "1.0", + + "description": "Adds a browser action icon to the toolbar. Click the button to choose a beast. The active tab's body content is then replaced with a picture of the chosen beast. See https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Examples#beastify", + "homepage_url": "https://github.com/mdn/webextensions-examples/tree/master/beastify", + "icons": { + "48": "icons/beasts-48.png" + }, + + "permissions": [ + "activeTab" + ], + + "browser_action": { + "default_icon": "icons/beasts-32.png", + "default_title": "Beastify", + "default_popup": "popup/choose_beast.html" + }, + + "web_accessible_resources": [ + "beasts/frog.jpg", + "beasts/turtle.jpg", + "beasts/snake.jpg" + ] + +} +</pre> + +<ul> + <li>Первые три ключа: <code><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/manifest.json/manifest_version">manifest_version</a></code>, <code><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/manifest.json/name">name</a></code>, <code>и <a href="/ru/docs/Mozilla/Add-ons/WebExtensions/manifest.json/version">version</a></code>, являются обязательными и содержат основные мета-данные для дополнения.</li> + <li><code><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/manifest.json/description">description</a></code> <code>и <a href="/ru/docs/Mozilla/Add-ons/WebExtensions/manifest.json/homepage_url">homepage_url</a></code> необязательны, но рекомендуемы: они предоставляют полезную информацию о дополнении.</li> + <li><code><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/manifest.json/icons">icons</a></code> необязательный, но рекомендуемый: позволяет Вам определять иконку для дополнения, которая будет показана в Менеджере Дополнений.</li> + <li><code><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions">permissions</a></code> перечисляет разрешения для нужд дополнения. Здесь мы просто спрашиваем разрешения для <a href="/ru/Add-ons/WebExtensions/manifest.json/permissions#activeTab_permission"><code>activeTab</code> permission</a>.</li> + <li><code><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/manifest.json/browser_action">browser_action</a></code> задает кнопку на панели инструментов. Здесь мы предоставляем три вида информации: + <ul> + <li><code>default_icon</code> это обязательная иконка для кнопки</li> + <li><code>default_title</code> необязательный заголовок, будет показан в подсказке</li> + <li><code>default_popup</code> используется, если Вы хотите, чтобы всплывающая панель была показана когда пользователь кликает по кнопке. В нашем примере мы использовали этот ключ и он указывает на HTML файл, подключенный к дополнению.</li> + </ul> + </li> + <li><code><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/manifest.json/web_accessible_resources">web_accessible_resources</a></code> перечисляет файлы, которые мы хотим сделать доступными для веб-страниц. Поскольку дополнение заменяет содержимое страницы на изображения, которые мы упаковали вместе с дополнением, нам нужно сделать эти изображения доступными для страницы.</li> +</ul> + +<p>Обратите внимание, что все пути указаны относительно файла manifest.json.</p> + +<h3 id="Иконка">Иконка</h3> + +<p>Дополнение должно иметь иконку. Она будет показана рядом с дополнением в Менеджере Дополнений (Вы можете открыть менеджер перейдя по ссылке "about:addons"). Наш manifest.json обещает, что у нас будет иконка для панели инструментов по адресу "icons/beasts-48.png".</p> + +<p>Создайте папку "icons" и сохраните там иконку с именем "beasts-48.png". Вы можете использовать <a href="https://github.com/mdn/webextensions-examples/blob/master/beastify/icons/beasts-48.png">иконку из нашего примера</a>, которая взята из <a href="https://www.iconfinder.com/iconsets/free-retina-icon-set">набора Aha-Soft’s Free Retina</a> и используется на условиях этой <a href="http://www.aha-soft.com/free-icons/free-retina-icon-set/">лицензии</a>.</p> + +<p>Если Вы выберете свою иконку, она должна быть размером 48x48 пикселей. Вы также можете предоставить иконку размером 96x96 пикселей для дисплеев с высоким разрешением, определив свойство <code>"96"</code> объекта <code>icons</code> в файле manifest.json:</p> + +<pre class="brush: json line-numbers language-json"><code class="language-json"><span class="key token">"icons":</span> <span class="punctuation token">{</span> + <span class="key token">"48":</span> <span class="string token">"icons/beasts-48.png"</span><span class="punctuation token">,</span> + <span class="key token">"96":</span> <span class="string token">"icons/beasts-96.png"</span> +<span class="punctuation token">}</span></code></pre> + +<h3 id="Кнопка_панели_инструментов">Кнопка панели инструментов</h3> + +<p>Кнопка панели инструментов также нуждается в иконке, и наш manifest.json обещает, что у нас будет иконка для панели инструментов по адресу "icons/beasts-32.png".</p> + +<p>Сохраните иконку с именем "beasts-32.png" в папке "icons". Вы можете использовать <a href="https://github.com/mdn/webextensions-examples/blob/master/beastify/icons/beasts-32.png">иконку из нашего примера</a>, которая взята из набора <a href="http://www.iconbeast.com/free">IconBeast Lite </a>и используется на условиях этой <a href="http://www.iconbeast.com/faq/">лицензии</a>.</p> + +<p>Если Вы не предоставите всплывающую панель, то событие click отправляется в Ваше дополнение, когда пользователь кликает кнопку. Если Вы предоставите всплывающую панель, то событие click не отправляется, зато появляется всплывающая панель. Мы хотим панель, давайте создадим ее.</p> + +<h3 id="Всплывающая_панель">Всплывающая панель</h3> + +<p>Функция панели - позволить пользователю выбрать одного из трех зверей.</p> + +<p>Создайте новую папку с именем "popup" в корневой папке дополнения. Здесь мы сохраним код для панели. Панель будет состоять из трех файлов:</p> + +<ul> + <li><strong><code>choose_beast.html</code></strong> определяет содержимое панели</li> + <li><strong><code>choose_beast.css</code></strong> стили для содержимого</li> + <li><strong><code>choose_beast.js</code></strong> обрабатывает выбор пользователя, выполняя content script в активной вкладке</li> +</ul> + +<h4 id="choose_beast.html">choose_beast.html</h4> + +<p>HTML выглядит так:</p> + +<pre class="brush: html"><!DOCTYPE html> + +<html> + <head> + <meta charset="utf-8"> + <link rel="stylesheet" href="choose_beast.css"/> + </head> + + <body> + <div class="button beast">Frog</div> + <div class="button beast">Turtle</div> + <div class="button beast">Snake</div> + <div class="button clear">Reset</div> + + <script src="choose_beast.js"></script> + </body> + +</html></pre> + +<p>У нас есть элемент для каждого животного. Обратите внимание, что мы подключаем CSS и JS файлы из HTML файла, как на обыкновенной веб-странице.</p> + +<h4 id="choose_beast.css">choose_beast.css</h4> + +<p>CSS фиксирует размер всплывающей панели, гарантирует что три варианта заполняют пространство и дает им основной стиль:</p> + +<pre class="brush: css">html, body { + width: 100px; +} + +.button { + margin: 3% auto; + padding: 4px; + text-align: center; + font-size: 1.5em; + cursor: pointer; +} + +.beast:hover { + background-color: #CFF2F2; +} + +.beast { + background-color: #E5F2F2; +} + +.clear { + background-color: #FBFBC9; +} + +.clear:hover { + background-color: #EAEAC9; +} +</pre> + +<h4 id="choose_beast.js">choose_beast.js</h4> + +<p>В JavaScript для всплывающего окна мы слушаем click события. Если click был на одном из трех вариантов наших животных, мы добавляем content script в активную вкладку. После того, как content script загрузится, мы отправляем ему сообщение с выбранным животным:</p> + +<pre class="brush: js">/* +Учитывая имя зверя, получаем URL соответствующего изображения. +*/ +function beastNameToURL(beastName) { + switch (beastName) { + case "Frog": + return browser.extension.getURL("beasts/frog.jpg"); + case "Snake": + return browser.extension.getURL("beasts/snake.jpg"); + case "Turtle": + return browser.extension.getURL("beasts/turtle.jpg"); + } +} + +/* +Слушаем события клика во всплывающей панели. + +Если кликнули одного из зверей: + Добавляем "beastify.js" к активной вкладке. + + Затем получаем активную вкладку и отправляем сценарию "beastify.js" + сообщение, содержащее URL к картинке с выбранным зверем. + +Если кликнули кнопку, класс которой содержит "clear": + Перезагрузить страницу. + Закрыть всплывающую панель. Это необходимо, так как content script + неисправен после перезагрузки страницы. +*/ + +document.addEventListener("click", (e) => { + if (e.target.classList.contains("beast")) { + var chosenBeast = e.target.textContent; + var chosenBeastURL = beastNameToURL(chosenBeast); + + browser.tabs.executeScript(null, { + file: "/content_scripts/beastify.js" + }); + + var gettingActiveTab = browser.tabs.query({active: true, currentWindow: true}); + gettingActiveTab.then((tabs) => { + browser.tabs.sendMessage(tabs[0].id, {beastURL: chosenBeastURL}); + }); + } + else if (e.target.classList.contains("clear")) { + browser.tabs.reload(); + window.close(); + } +}); +</pre> + +<p>Скрипт использует три функции WebExtension API:</p> + +<ul> + <li><code><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/API/tabs/executeScript">browser.tabs.executeScript</a></code> добавляет content script, найденный по адресу content_scripts/beastify.js", к активной вкладке</li> + <li><code><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/API/tabs/query">browser.tabs.query</a></code> запрашивает активную вкладку</li> + <li><code><a href="/ru/docs/Mozilla/Add-ons/WebExtensions/API/tabs/sendMessage">browser.tabs.sendMessage</a></code> отправляет сообщение для content script, который работает в активной вкладке. Сообщение содержит URL изображения выбранного зверя.</li> +</ul> + +<h3 id="Сontent_script">Сontent script</h3> + +<p>Создайте новую папку с именем "content_scripts" в корневой папке дополнения и создайте в ней новый файл с именем "beastify.js", со следующим кодом:</p> + +<pre class="brush: js">/* +beastify(): +* удаляет каждый узел в document.body, +* затем вставляет выбранного зверя +* затем удаляется как слушатель +*/ +function beastify(request, sender, sendResponse) { + removeEverything(); + insertBeast(request.beastURL); + browser.runtime.onMessage.removeListener(beastify); +} + +/* +Удаляет каждый узел в document.body +*/ +function removeEverything() { + while (document.body.firstChild) { + document.body.firstChild.remove(); + } +} + +/* +Учитывая URL изображения зверя, создает и стилизует узел IMG, +указывающий на это изображение, затем вставляет узел в документ. +*/ +function insertBeast(beastURL) { + var beastImage = document.createElement("img"); + beastImage.setAttribute("src", beastURL); + beastImage.setAttribute("style", "width: 100vw"); + beastImage.setAttribute("style", "height: 100vh"); + document.body.appendChild(beastImage); +} + +/* +Назначает beastify() слушателем сообщений расширения. +*/ +browser.runtime.onMessage.addListener(beastify); +</pre> + +<p>Content script добавляет слушателя к сообщениям от дополнения (в частности как в файле "choose_beast.js" выше). В слушателе скрипт:</p> + +<ul> + <li>удаляет каждый элемент из <code>document.body</code></li> + <li>создает <code><img></code> элемент, указывающий на переданный URL, и вставляет элемент в DOM</li> + <li>удаляет слушатель сообщений.</li> +</ul> + +<h3 id="Звери">Звери</h3> + +<p>Наконец, нам нужно подключить изображения животных.</p> + +<p>Создайте новую папку с именем "beasts" и добавьте туда три изображения с соответствующими именами. Вы можете получить изображения из <a href="https://github.com/mdn/webextensions-examples/tree/master/beastify/beasts">GitHub репозитория</a>, или прямо здесь:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/11459/frog.jpg" style="display: inline-block; height: 200px; margin: 20px; width: 200px;"><img alt="" src="https://mdn.mozillademos.org/files/11461/snake.jpg" style="display: inline-block; height: 200px; margin: 20px; width: 200px;"><img alt="" src="https://mdn.mozillademos.org/files/11463/turtle.jpg" style="display: inline-block; height: 200px; margin: 20px; width: 200px;"></p> + +<h2 id="Тестирование">Тестирование</h2> + +<p>Во-первых, дважды проверьте, что у вас все файлы на своих местах:</p> + +<pre>beastify/ + + beasts/ + frog.jpg + snake.jpg + turtle.jpg + + content_scripts/ + beastify.js + + icons/ + beasts-32.png + beasts-48.png + + popup/ + choose_beast.css + choose_beast.html + choose_beast.js + + manifest.json</pre> + +<p>Начиная с Firefox 45 Вы можете временно установить дополнения с жесткого диска.</p> + +<p>Откройте "about:debugging" в Firefox, кликните "Загрузить временное дополнение", и выберете Ваш файл manifest.json. После этого Вы должны увидеть иконку дополнения на панели инструментов Firefox:</p> + +<p>{{EmbedYouTube("sAM78GU4P34")}}</p> + +<p>Откройте веб-страницу, затем щелкните иконку, выберите зверя и посмотрите как страница изменится:</p> + +<p>{{EmbedYouTube("YMQXyAQSiE8")}}</p> + +<h2 id="Разработка_из_командной_строки">Разработка из командной строки</h2> + +<p>Вы можете автоматизировать этап временной установки используя <a href="/ru/Add-ons/WebExtensions/Getting_started_with_web-ext">web-ext</a>. Попробуйте это:</p> + +<pre class="brush: bash">cd beastify +web-ext run</pre> +</div> diff --git a/files/ru/mozilla/add-ons/webextensions/интернационализация/index.html b/files/ru/mozilla/add-ons/webextensions/интернационализация/index.html new file mode 100644 index 0000000000..36a37820d9 --- /dev/null +++ b/files/ru/mozilla/add-ons/webextensions/интернационализация/index.html @@ -0,0 +1,405 @@ +--- +title: Интернационализация +slug: Mozilla/Add-ons/WebExtensions/Интернационализация +translation_of: Mozilla/Add-ons/WebExtensions/Internationalization +--- +<div>{{AddonSidebar}}</div> + +<p>API <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions">WebExtensions</a> предоставляет полезный модуль для интернационализации расширений — <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/i18n">i18n</a>. В этой статье мы рассмотрим его особенности и пример его работы. Система для расширений, построенных с помощью API WebExtension, i18n похожа на библиотеки JavaScript для i18n, такие как <a href="http://i18njs.com/">i18n.js</a>.</p> + +<div class="note"> +<p>Расширение, используемое в этой статье в качестве примера, — <a href="https://github.com/mdn/webextensions-examples/tree/master/notify-link-clicks-i18n">notify-link-clicks-i18n</a> — доступно на GitHub. Читая последующие секции этой статьи, Вы можете исследовать его исходный код.</p> +</div> + +<h2 id="Структура_интернализированного_расширения">Структура интернализированного расширения</h2> + +<p>Интернационализированное расширение может содержать такие же элементы, как и любое другое расширение — <a href="/en-US/Add-ons/WebExtensions/Anatomy_of_a_WebExtension#Background_scripts">фоновые скрипты</a>, <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Content_scripts">встраиваемые скрипты</a>, и т. д. — а также дополнительные инструмены, позволяющие переключаться между разными локализациями. Их можно представить следующим деревом директорий:</p> + +<ul class="directory-tree"> + <li>корневая-директория-расширения/ + <ul> + <li>_locales + <ul> + <li>en + <ul> + <li>messages.json + <ul> + <li>Сообщения на английском (строки)</li> + </ul> + </li> + </ul> + </li> + <li>de + <ul> + <li>messages.json + <ul> + <li>Сообщения на немецком (строки)</li> + </ul> + </li> + </ul> + </li> + <li>и т. д.</li> + </ul> + </li> + <li>manifest.json + <ul> + <li>Метаданные, зависящие от локализации</li> + </ul> + </li> + <li>myJavascript.js + <ul> + <li>Файл JavaScript, получающий локализацию браузера, сообщения, зависящие от локализации, и т. д.</li> + </ul> + </li> + <li>myStyles.css + <ul> + <li>CSS, зависящий от локализации</li> + </ul> + </li> + </ul> + </li> +</ul> + +<p>Давайте отдельно рассмотрим каждый элемент — последующие секции представляют собой шаги, которым стоит следовать во время интернационализации вашего расширения.</p> + +<h2 id="Добавление_локализованных_строк_в__locales">Добавление локализованных строк в _locales</h2> + +<div class="pull-aside"> +<div class="moreinfo">Вы можете определить тэг языка при помощи инструмента <em>Find</em> на <a href="https://r12a.github.io/app-subtags/">странице определения языковых тегов</a>. Обратите внимание на то, что при поиске еужно использовать английское название языка</div> +</div> + +<p>Каждая система i18n требует предоставить строки во всех локализациях, которые Вы хотите поддерживать. В расширениях они хранятся в директории <code>_locales</code>, размещенной внутри корневой директории. Строки каждой локализации (также называемые сообщениями) хранятся в файле <code>messages.json</code>, находящемся в поддиректории <code>_locales</code>, название которой - тег языка локализации.</p> + +<p>Стоит заметить, что если тег включает в себя и базовый язык, и его региональный вариант, то по конвенции эти язык и вариант разделяются дефисом: например, "en-US". Однако в поддиректориях <code>_locales</code>, <strong>вместо дефиса используется нижнее подчеркивание</strong>: "en_US".</p> + +<p>Таким образом, <a href="https://github.com/mdn/webextensions-examples/tree/master/notify-link-clicks-i18n/_locales">в нашем примере</a> существую директории "en" (английский), "de" (немецкий), "nl" (голландский), and "ja" (японский). Внутри каждой из них находится файл <code>messages.json</code> .</p> + +<p>Давайте рассмотрим структуру одного из этих файлов (<a href="https://github.com/mdn/webextensions-examples/blob/master/notify-link-clicks-i18n/_locales/en/messages.json">_locales/en/messages.json</a>):</p> + +<pre class="brush: json notranslate">{ + "extensionName": { + "message": "Notify link clicks i18n", + "description": "Name of the extension." + }, + + "extensionDescription": { + "message": "Shows a notification when the user clicks on links.", + "description": "Description of the extension." + }, + + "notificationTitle": { + "message": "Click notification", + "description": "Title of the click notification." + }, + + "notificationContent": { + "message": "You clicked $URL$.", + "description": "Tells the user which link they clicked.", + "placeholders": { + "url" : { + "content" : "$1", + "example" : "https://developer.mozilla.org" + } + } + } +}</pre> + +<p>Это стандартный файл JSON — каждый из его элементов является объектом с именем, содержащим сообщение (<code>message)</code> и описание (<code>description)</code>. Оба предмета - строки; <code>$URL$</code> — это заполнитель, который заменяется подстрокой, когда элемент <code>notificationContent</code> вызывается расширением. Вы научитесь это делать в секции {{anch("Получение сообщений из JavaScript")}}.</p> + +<div class="note"> +<p><strong>Примечание</strong>: Вы можете найти больше информации о структуре <code>messages.json</code> <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/i18n/Locale-Specific_Message_reference">здесь</a>.</p> +</div> + +<h2 id="Интернационализация_manifest.json">Интернационализация manifest.json</h2> + +<p>Для интернационализации файла manifest.json нужно предпринять несколько шагов.</p> + +<h3 id="Получение_локализованных_строк_в_манифестах">Получение локализованных строк в манифестах</h3> + +<p>Ваш файл <a href="https://github.com/mdn/webextensions-examples/blob/master/notify-link-clicks-i18n/manifest.json">manifest.json</a> содержит строки, отображаемые пользователю, такие как имя и описание расширения. Если Вы интернационализируете эти строки и поместите их переводы в messages.json, то эти переводы будут отображаться пользователю в зависимости от локализации его браузера.</p> + +<p>Чтобы интернационализировать строки, их нужно указывать следующим образом:</p> + +<pre class="brush: json notranslate">"name": "__MSG_extensionName__", +"description": "__MSG_extensionDescription__",</pre> + +<p>Здесь мы получаем сообщения, зависящие от локализации браузера, а не просто статические строки.</p> + +<p>Чтобы получить строку сообщения, ее нужно указать следующим образом:</p> + +<ol> + <li>Два подчеркивания</li> + <li>Строка "MSG"</li> + <li>Одно подчеркивание</li> + <li>Имя сообщения так как оно указано в <code>messages.json</code></li> + <li>Два подчеркивания</li> +</ol> + +<pre class="notranslate"><strong>__MSG_</strong> + <em>messageName</em> + <strong>__</strong></pre> + +<h3 id="Локализация_по_умолчанию">Локализация по умолчанию</h3> + +<p>Еше одно поле. которое нужно указать в manifest.json — это <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/default_locale">default_locale</a>:</p> + +<pre class="brush: json notranslate">"default_locale": "en"</pre> + +<p>Этот параметр устанавливает локализацию по умолчанию, используемую, если расширение не поддерживает локализацию браузера пользователя. Любые сообщения, недоступные в текущей локализации, будут браться из той локализации, которая установлена по умолчанию. There are some more details to be aware of in terms of how the browser selects strings — see {{anch("Выбор локализованной строки")}}.</p> + +<h2 id="CSS_зависящий_от_локализации">CSS, зависящий от локализации</h2> + +<p>Локализованные строки также можно получить из CSS-файлов расширения. Например, Вы можете создать поля CSS, зависящие от локализации, так:</p> + +<pre class="brush: css notranslate">header { + background-image: url(../images/__MSG_extensionName__/header.png); +}</pre> + +<p>Этот функционал может быть полезен, однако, возможно, для этих целей стоит использовать {{anch("Заранее определенные сообщения")}}.</p> + +<h2 id="Получение_сообщений_из_JavaScript">Получение сообщений из JavaScript</h2> + +<p>Допустим, Вы добавили сообщения в Ваш manifest.json. Чтобы Ваше расширение начало использовать правильные языки, соответствующие сообщения следует вызывать при помощи JavaScript. <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/i18n">API i18n</a> достаточно прост и содержит всего 4 основных метода:</p> + +<ul> + <li>Скорее всего, наиболее часто Вы будете использовать {{WebExtAPIRef("i18n.getMessage()")}} — этот сетод используется для получения конкретного сообщения. Примеры его использования можно увидеть ниже.</li> + <li>Методы {{WebExtAPIRef("i18n.getAcceptLanguages()")}} и {{WebExtAPIRef("i18n.getUILanguage()")}} используются, если UI надо менять в зависимости от локализации — например, если Вы хотите, чтобы предпочтения, свойственные носителям какого-либо языка, находились выше в списке, или чтобы формат дат соответствовал локализации браузера.</li> + <li>Метод {{WebExtAPIRef("i18n.detectLanguage()")}} используется для получения языка информации, введенной пользователем, и ее форматирования.</li> +</ul> + +<p>В нашем примере <a href="https://github.com/mdn/webextensions-examples/tree/master/notify-link-clicks-i18n">notify-link-clicks-i18n</a> , <a href="https://github.com/mdn/webextensions-examples/blob/master/notify-link-clicks-i18n/background-script.js">фоновый скрипт</a> содержит следующие строки:</p> + +<pre class="brush: js notranslate">var title = browser.i18n.getMessage("notificationTitle"); +var content = browser.i18n.getMessage("notificationContent", message.url);</pre> + +<p>Первая из них получает поле <code>notificationTitle message</code> из доступного файла <code>messages.json</code>, соответствующее наиболее подходящей локализации . Вторая строка похожа на первую, но в ней метод принимает URL в качестве второго параметра. Зачем? С помощью этого параметра мы указываем, на что нужно заменить заполнитель <code>$URL$</code> в поле <code>notificationContent message</code>:</p> + +<pre class="brush: json notranslate">"notificationContent": { + "message": "You clicked $URL$.", + "description": "Tells the user which link they clicked.", + "placeholders": { + "url" : { + "content" : "$1", + "example" : "https://developer.mozilla.org" + } + } +} +</pre> + +<p>Объект <code>"placeholders"</code> определяет все заполнители и то, откуда их нужно получать. Заполнитель <code>"url"</code> указывает, что информация о нем должна содержаться в $1 — первое значение, заданное внутри второго параметра <code>getMessage()</code>. Поскольку заролнитель называется <code>"url"</code>, <code>$URL$</code> используется для его вызова внутри сообщения (то есть для заполнителя <code>"name"</code> нужно использовать <code>$NAME$</code>, и т. д.). Если Вы хотите задать значения нескольких заполнителей, их можно передавать во второй аргумент {{WebExtAPIRef("i18n.getMessage()")}} в виде массива — массив <code>[a, b, c]</code> передает значения <code>$1</code>, <code>$2</code> и <code>$3</code>, и т. д. внутрь <code>messages.json</code>.</p> + +<p>Давайте посмотрим на пример: изначально сообщение <code>notificationContent</code> в файле <code>en/messages.json</code> такое:</p> + +<pre class="notranslate">You clicked $URL$.</pre> + +<p>Пусть эта ссылка указывает на <code>https://developer.mozilla.org</code>. После вызова {{WebExtAPIRef("i18n.getMessage()")}}, содержание второго параметра становится доступно в messages.json в качестве значения <code>$1</code>, замещающего <code>$URL$</code>, так как это указано в заполнителе <code>"url"</code>. Таким образом, итоговое значение строки:</p> + +<pre class="notranslate">You clicked https://developer.mozilla.org.</pre> + +<h3 id="Прямое_использование_заполнителей">Прямое использование заполнителей</h3> + +<p>Переменные (<code>$1</code>, <code>$2</code>, <code>$3</code>, и т. д.) можно вставлять напрямую в сообщения. Например, можно переписать объект <code>"notificationContent"</code> следующим образом:</p> + +<pre class="brush: json notranslate">"notificationContent": { + "message": "You clicked $1.", + "description": "Tells the user which link they clicked." +}</pre> + +<p>Этот метод может показаться более быстрым и простым, но другой способ (использование <code>"placeholders"</code>) считается лучшей практикой. Это вызвано тем, что имена заполнителей (например <code>"url"</code>) и примеры помогают понять, что означают заполнители — через неделю после написания кода Вы, наверное, забудете, что обозначают заполнители <code>$1</code>–<code>$8</code>, что менее вероятно, если заполнители именованы.</p> + +<h3 id="Заданные_замены">Заданные замены</h3> + +<p>Значения заполнителей можно задавать вручную, если Вы хотите, чтобы каждый раз это значение было одним и тем же, а не определялось переменной в коде. Например:</p> + +<pre class="brush: json notranslate">"mdn_banner": { + "message": "For more information on web technologies, go to $MDN$.", + "description": "Tell the user about MDN", + "placeholders": { + "mdn": { + "content": "https://developer.mozilla.org/" + } + } +}</pre> + +<p>В этом примере мы сами задаем значение заполнителя, а не получаем его из переменной, такой как <code>$1</code>. Это может быть полезно, если сообщение очень сложное, и Вы хотите разделить значения, чтобы сделать строки более читаемыми. К тому же, доступ к этим значениям можно получить внутри программы.</p> + +<p>Вы также можете использовать такие замены для указания частей строки, не нуждающихся в переводе, таких как имена или названия.</p> + +<h2 id="Выбор_локализованной_строки">Выбор локализованной строки</h2> + +<p>Локализации могут быть указаны с помощью кода языка, например <code>fr</code> или <code>en</code>. Они также могут содержать региональный код, например <code>en_US</code> или <code>en_GB</code>, описывающий региональный вариант языка. Когда вы запрашиваете строку у системы i18n, системы возвращает ее используя следующий алгоритм:</p> + +<ol> + <li>Если для текущей локализации существует файл <code>messages.json</code>, содержащий требуемую строку, возвращается она.</li> + <li>Иначе,если текущая локализация — региональный вариант (например <code>en_US</code>) и существует файл <code>messages.json</code> для этого языка, но без указания региона (например <code>en</code>), содержащий строку, возвращается она.</li> + <li>Иначе, если существует файл <code>messages.json</code> для <code>default_locale</code>, указанной в <code>manifest.json</code>, и этот файл содержит нужную строку, возвращается она.</li> + <li>В противном случае возвращается пустая строка.</li> +</ol> + +<p>Рассмотрим следующий пример:</p> + +<ul class="directory-tree"> + <li>корневая-директория-расширения/ + <ul> + <li>_locales + <ul> + <li>en_GB + <ul> + <li>messages.json + <ul> + <li><code>{ "colorLocalised": { "message": "colour", "description": "Color." }, ... }</code></li> + </ul> + </li> + </ul> + en + + <ul> + <li>messages.json + <ul> + <li><code>{ "colorLocalised": { "message": "color", "description": "Color." }, ... }</code></li> + </ul> + </li> + </ul> + </li> + <li>fr + <ul> + <li>messages.json + <ul> + <li><code>{ "colorLocalised": { "message": "<span lang="fr">couleur</span>", "description": "Color." }, ...}</code></li> + </ul> + </li> + </ul> + </li> + </ul> + </li> + </ul> + </li> +</ul> + +<p>Пусть <code>default_locale</code> установлен как <code>fr</code>, а текущая локализация браузера — <code>en_GB</code>:</p> + +<ul> + <li>Вызов <code>getMessage("colorLocalised")</code> вернет "colour".</li> + <li>Если бы в <code>en_GB</code> не было "colorLocalized", то вызов <code>getMessage("colorLocalised")</code>, вернул бы "color", а не "couleur".</li> +</ul> + +<h2 id="Заранее_определенные_сообщения">Заранее определенные сообщения</h2> + +<p>Модуль i18n module предоставляет заранее определенные сообщения, которые можно вызвать таким же образом, как мы это делали в разделе {{anch("Интернационализация manifest.json")}}. Например:</p> + +<pre class="notranslate">__MSG_extensionName__</pre> + +<p>Заранее определенные сообщения используют такой же синтаксис, за исключением <code>@@</code> перед именем сообщения, например:</p> + +<pre class="notranslate">__MSG_@@ui_locale__</pre> + +<p>Следующая таблица содержит различные заранее определенные сообщения:</p> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Message name</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>@@extension_id</code></td> + <td> + <p>Внутренний UUID расширения. Эту строку можно использовать для создания URL ресурсов внутри расширения.Даже нелокализованные расширения могут использовать это сообщения.</p> + + <p>Это сообщения нельзя использовать в manifest.json.</p> + + <p>Также стоит заметить, что этот ID — <em>не</em> ID аддона, которое возвращает {{WebExtAPIRef("runtime.id")}}, и которое может быть установлено с помощью ключа <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/applications">applications</a> в manifest.json. Это сгенерированный UUID, содержащийся в URL аддона. Это означает, что данную величину нельзя использовать в качестве параметра <code>extensionId</code> метода {{WebExtAPIRef("runtime.sendMessage()")}}, или для проверки поля <code>id</code> объекта {{WebExtAPIRef("runtime.MessageSender")}}.</p> + </td> + </tr> + <tr> + <td><code>@@ui_locale</code></td> + <td>Текущая локализация; эту строку можно использовать для создания URL, зависящих от локализации.</td> + </tr> + <tr> + <td><code>@@bidi_dir</code></td> + <td>Направления чтения, либо "ltr" для языков, таких как английский, где текст читается слева направо, либо "rtl" для языков, считающихся справа налево, таких как арабский.</td> + </tr> + <tr> + <td><code>@@bidi_reversed_dir</code></td> + <td>Если <code>@@bidi_dir</code> имеет значение "ltr", то возвращает "rtl"; иначе "ltr".</td> + </tr> + <tr> + <td><code>@@bidi_start_edge</code></td> + <td>Если <code>@@bidi_dir</code> имеет значение "ltr", то возвращает "left"; иначе "right".</td> + </tr> + <tr> + <td><code>@@bidi_end_edge</code></td> + <td>Если <code>@@bidi_dir</code> имеет значение "ltr", то возвращает "right"; иначе "left".</td> + </tr> + </tbody> +</table> + +<p>Возвращаясь к нашему примеру, лучше было бы написать:</p> + +<pre class="brush: css notranslate">header { + background-image: url(../images/__MSG_@@ui_locale__/header.png); +}</pre> + +<p>Теперь мы можем хранить изображения в директориях поддерживаемых локализаций — en, de, и т. д. — что выглядит логичней.</p> + +<p>Давайте рассмотрим пример использования сообщений <code>@@bidi_*</code> в файле CSS:</p> + +<pre class="brush: css notranslate">body { + direction: __MSG_@@bidi_dir__; +} + +div#header { + margin-bottom: 1.05em; + overflow: hidden; + padding-bottom: 1.5em; + padding-__MSG_@@bidi_start_edge__: 0; + padding-__MSG_@@bidi_end_edge__: 1.5em; + position: relative; +}</pre> + +<p>Для языков, в которых текст читается слева направо, таких как английский, правила CSS, использующие заранее определенные сообщения, сверху задают такие значения:</p> + +<pre class="brush: css notranslate">direction: ltr; +padding-left: 0; +padding-right: 1.5em; +</pre> + +<p>Для языков, читающихся справа налево, значения будут следующими:</p> + +<pre class="brush: css notranslate">direction: rtl; +padding-right: 0; +padding-left: 1.5em;</pre> + +<h2 id="Тестирование_расширения">Тестирование расширения</h2> + +<p>Начиная с Firefox 45, расширения могут быть временно установлены с диска — подробнее об этом написано в статье <a href="https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Packaging_and_installation#Loading_from_disk">Loading from disk</a>. Сделайте это и попробуйте протестировать наше расширение <a href="https://github.com/mdn/webextensions-examples/tree/master/notify-link-clicks-i18n">notify-link-clicks-i18n</a>. Перейдите на одну из Ваших любимых страниц и нажмите на ссылку, чтобы проверить, появляется ли сообщения, содержащее URL нажатой ссылки.</p> + +<p>Затем измените локализацию Firefox на какую-либо поддерживающуюся расширением, которое Вы хотите протестировать.</p> + +<ol> + <li>Откройте "about:config" в Firefox, и найдите параметр <code>intl.locale.requested</code> (обратите внимание на версию Firefox: в версиях до Firefox 59 этот параметр называется <code>general.useragent.locale</code>).</li> + <li>Если параметр существует, нажмите на него дважды (или нажмите Return/Enter), чтобы выбрать его, введите языковой код локализации, которую Вы хотите протестировать и нажмите "OK" (или Return/Enter). Например, в нашем примере расширение поддерживает "en" (английский), "de" (немецкий), "nl" (голландский), and "ja" (японский). Вы также можете указать пустую строку (<code>""</code>) в качестве значения. В этом случае браузер выберет язык Вашей ОС по умолчанию.</li> + <li>Если параметр <code>intl.locale.requested</code> не существует, нажмите правой кнопкой мыши на список параметров (или откройте контекстное меню при помощи клавиатуры), и выберите "New", а затем "String". Введите <code>intl.locale.requested</code> как имя настройки и, "de", "nl", и т. д. как значение, как это описано в шаге 2.</li> + <li>Найдите <code>intl.locale.matchOS</code> и, если параметр существует и равен <code>true</code>, дважды нажмите на него и установите на <code>false</code>.</li> + <li>Перезапустите браузер, чтобы изменения вступили в силу.</li> +</ol> + +<div class="note"> +<p><strong>Примечание</strong>: Этот метод работает, даже если у Вас не установлен <a href="https://addons.mozilla.org/en-US/firefox/language-tools/">языковой пакет</a> для выбранного языка. В этом случае UI браузера просто будет использовать Ваш язык по умолчанию.</p> +</div> + +<ol> +</ol> + +<div class="note"> +<p><strong>Примечание:</strong> Чтобы изменить результат <code>getUILanguage</code> требуется языковой пакет, поскольку он отражает язык UI браузера, а не язык сообщений расширения.</p> +</div> + +<p>Еше раз загрузите расширение с диска и протестируйте локализацию:</p> + +<ul> + <li>Еще раз откройте "about:addons" — теперь Вы должны увидеть Ваше расширение, его иконку, имя и описание на выбранном языке.</li> + <li>Еще раз протестируйте расширение. Для нашего примера, Вам следовало бы посетить другую страницу и, нажав на ссылку, проверить, появляется ли сообщение на нужном языке.</li> +</ul> + +<p>{{EmbedYouTube("R7--fp5pPGg")}}</p> diff --git a/files/ru/mozilla/add-ons/webextensions/модификация_веб_страницы/index.html b/files/ru/mozilla/add-ons/webextensions/модификация_веб_страницы/index.html new file mode 100644 index 0000000000..0f58364706 --- /dev/null +++ b/files/ru/mozilla/add-ons/webextensions/модификация_веб_страницы/index.html @@ -0,0 +1,238 @@ +--- +title: Модификация веб страницы +slug: Mozilla/Add-ons/WebExtensions/модификация_веб_страницы +translation_of: Mozilla/Add-ons/WebExtensions/Modify_a_web_page +--- +<p> </p> + +<div>{{AddonSidebar}}</div> + +<p>Одним из наиболее распространённых вариантов использования расширений является внесение изменение в веб-страницу. К примеру, расширение может изменить стиль, применённый к странице, скрыть существующие или вставить на страницу дополнительные DOM-узлы.</p> + +<p>Существует два способа сделать это используя WebExtensions API:</p> + +<ul> + <li><strong>Декларативно</strong>: объявить шаблон, которому соответствует набор URL-адресов, и загрузить набор скриптов на страницы, которые попадают в под этот шаблон.</li> + <li><strong>Программно</strong>: используя JavaScript API, загрузить скрипт на страницу, из определённой вкладки.</li> +</ul> + +<p>В любом случае, эти скрипты называются <em>контентными скриптами</em>, и отличаются от других скриптов, которые составляют расширение:</p> + +<ul> + <li>Они получают доступ к малому подмножеству WebExtension API.</li> + <li>Они получают прямой доступ к странице, на которой были загружены.</li> + <li>Они взаимодействуют с остальными скриптами расширения, используя API сообщений.</li> +</ul> + +<p>В этой статье мы рассмотрим оба способа загрузки скрипта.</p> + +<h2 id="Модификация_страниц_подпадающих_под_URL-шаблон">Модификация страниц, подпадающих под URL-шаблон</h2> + +<p>Прежде всего создадим новую директорию, назовём её "modify-page". В этой директории, создадим файл "manifest.json", со следующим содержимым:</p> + +<pre class="brush: json notranslate">{ + + "manifest_version": 2, + "name": "modify-page", + "version": "1.0", + + "content_scripts": [ + { + "matches": ["https://developer.mozilla.org/*"], + "js": ["page-eater.js"] + } + ] + +}</pre> + +<p>Ключ <code><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/content_scripts">content_scripts</a></code> - это как мы загружаем скрипты на страницы, соответстующие URL-шаблону. В нашем случае, <code>content_scripts</code> говорит браузеру загрузить скрипт "page-eater.js" на все страницы, начинающиеся с <a href="https://developer.mozilla.org/">https://developer.mozilla.org/</a>.</p> + +<div class="note"> +<p>Поскольку свойство <code>"js"</code> ключа <code>content_scripts</code> это массив, вы можете использовать его, для внедрения более одного скрипта. Если вы сделаете это, страницы получат набор, как если бы эти скрипты были загружены самой страницей, они будут загружены в той же очерёдности, в которой они расположены в массиве.</p> +</div> + +<div class="note"> +<p>Ключ <code>content_scripts</code> также имеет свойство <code>"css"</code>, которое вы можете использовать для вставки CSS-таблиц.</p> +</div> + +<p>Далее, создадим файл "page-eater.js", внутри директории "modify-page":</p> + +<pre class="brush: js notranslate">document.body.textContent = ""; + +var header = document.createElement('h1'); +header.textContent = "Эта страница была съедена"; +document.body.appendChild(header);</pre> + +<p>Теперь <a href="https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Temporary_Installation_in_Firefox">установим расширение</a>, и перейдём на страницу <a href="https://developer.mozilla.org/">https://developer.mozilla.org/</a>:</p> + +<p>{{EmbedYouTube("lxf2Tkg6U1M")}}</p> + +<div class="note"> +<p>Обратите внимание, несмотря на то, что в указанном видео, на странице <a href="https://addons.mozilla.org/en-US/firefox/">addons.mozilla.org</a> всё работает нормально, на текущий момент, для этого сайта, контентные скрипты заблокированы.</p> +</div> + +<h2 id="Программная_модификация_страницы">Программная модификация страницы</h2> + +<p>Что, если вы всё еще хотите "съедать" страницы, но лишь в тех случаях, когда пользователь попросил об этом? Давайте обновим этот пример таким образом, чтобы мы внедряли контентный скрипт, когда пользователь выбирает соответствующий пункт контентного меню.</p> + +<p>Для начала обновим "manifest.json":</p> + +<pre class="brush: json notranslate">{ + + "manifest_version": 2, + "name": "modify-page", + "version": "1.0", + + "permissions": [ + "activeTab", + "contextMenus" + ], + + "background": { + "scripts": ["background.js"] + } + +}</pre> + +<p>Мы удалили ключ <code>content_scripts</code> и добавили два новых:</p> + +<ul> + <li><code><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions">permissions (разрешения)</a></code>: для внедрения скрипта, нам нужны разрешения для страниц, которые мы модифицируем. <a href="/en-US/Add-ons/WebExtensions/manifest.json/permissions#activeTab_permission">Разрешение <code>activeTab</code></a> это способ получить доступ к текущей вкладки. Нам также нужно разрешение <code>contextMenus</code>, чтобы добавлять в контектсное меню новые элементы.</li> + <li><code><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/background">background (фоновый)</a></code>: мы используем этот ключ, для загрузки постоянного <a href="/en-US/Add-ons/WebExtensions/Anatomy_of_a_WebExtension#Background_scripts">"фонового скрипта"</a>, с именем "background.js", в котором мы настроим контекстное меню и внедрим контентный скрипт.</li> +</ul> + +<p>Давайте создадим этот файл. Создадим новый файл "background.js" в директории "modify-page" и поместим в него следующий код:</p> + +<pre class="brush: js notranslate">browser.contextMenus.create({ + id: "eat-page", + title: "Съесть эту страницу" +}); + +browser.contextMenus.onClicked.addListener(function(info, tab) { + if (info.menuItemId == "eat-page") { + browser.tabs.executeScript({ + file: "page-eater.js" + }); + } +}); +</pre> + +<p>В этом скрипте мы создаём <a href="/en-US/Add-ons/WebExtensions/API/ContextMenus/create">элемент контекстного меню</a>, передавая ему определённый идентификатор и заголовок (текст будет отображаться в элементе контекстного меню). Затем мы настраиваем обработчик событий таким образом, чтобы когда пользователь выбирает пункт контекстного меню, осуществлялась проверка, наш ли это элемент <code>eat-page</code>. Если это так - внедряем скрипт "page-eater.js" в текущую вкладку, используя <code><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/executeScript">tabs.executeScript()</a></code> API. Это API опционально принимает идентификатор вкладки, в качестве аргумента. Мы опустили его, это означает, что скрипт будет внедряться в текущую активную вкладку.</p> + +<p>На данном этапе расширение должно иметь следующий вид:</p> + +<pre class="line-numbers language-html notranslate"><code class="language-html">modify-page/ + background.js + manifest.json + page-eater.js</code></pre> + +<p>Теперь <a href="https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Temporary_Installation_in_Firefox#Reloading_a_temporary_add-on">перезагрузим расширение</a>, откроем страницу (на этот раз любую) активируем контекстное меню и выберем "Съесть эту страницу":</p> + +<p>{{EmbedYouTube("zX4Bcv8VctA")}}</p> + +<div class="note"> +<p>Обратите внимание, несмотря на то, что в указанном видео, на странице <a href="https://addons.mozilla.org/en-US/firefox/">addons.mozilla.org</a> всё работает нормально, на текущий момент, для этого сайта, контентные скрипты заблокированы.</p> +</div> + +<h2 id="Обмен_сообщениями">Обмен сообщениями</h2> + +<p>Контентные и фоновые скрипты не могут на прямую взаимодействовать друг с другом. Не смотря на это они могут взаимодействовать с помощью обмена сообщениями. Для этого один конец создаёт обработчик сообщений, а другой - может посылать сообщения. В следующей таблице представлены API-интерфейсы, задействованные с каждой стороны:</p> + +<table class=" fullwidth-table standard-table"> + <thead> + <tr> + <th scope="row"></th> + <th scope="col">В контентном скрипте</th> + <th scope="col">В фоновом скрипте</th> + </tr> + <tr> + <th scope="row">Отправка сообщения</th> + <td><code><a href="/en-US/Add-ons/WebExtensions/API/runtime#sendMessage()">browser.runtime.sendMessage()</a></code></td> + <td><code><a href="/en-US/Add-ons/WebExtensions/API/Tabs/sendMessage">browser.tabs.sendMessage()</a></code></td> + </tr> + <tr> + <th scope="row">Получение сообщения</th> + <td><code><a href="/en-US/Add-ons/WebExtensions/API/runtime/onMessage">browser.runtime.onMessage</a></code></td> + <td><code><a href="/en-US/Add-ons/WebExtensions/API/runtime#onMessage">browser.runtime.onMessage</a></code></td> + </tr> + </thead> +</table> + +<p>Давайте обновим наш пример, чтобы посмотреть, как послать сообщение из фонового скрипта.</p> + +<p>Изменим "background.js" :</p> + +<pre class="brush: js notranslate">browser.contextMenus.create({ + id: "eat-page", + title: "Съесть эту страницу" +}); + +function messageTab(tabs) { + browser.tabs.sendMessage(tabs[0].id, { + replacement: "Message from the extension!" + }); +} + +browser.contextMenus.onClicked.addListener(function(info, tab) { + if (info.menuItemId == "eat-page") { + browser.tabs.executeScript({ + file: "page-eater.js" + }); + + var querying = browser.tabs.query({ + active: true, + currentWindow: true + }); + querying.then(messageTab); + } +}); +</pre> + +<p>Теперь, после внедрения "page-eater.js", мы используем <code><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/query">tabs.query()</a></code>, чтобы получить текущую открытую вкладку и используем <code><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/sendMessage">tabs.sendMessage()</a></code>, для отправки сообщения контентному скрипту, загруженному на этой вкладке. Сообщение несёт полезную нагрузку <code>{replacement: "Message from the extension!"}</code>.</p> + +<p>Далее, обновим "page-eater.js":</p> + +<pre class="brush: js notranslate">function eatPage(request, sender, sendResponse) { + document.body.textContent = ""; + + var header = document.createElement('h1'); + header.textContent = request.replacement; + document.body.appendChild(header); +} + +browser.runtime.onMessage.addListener(eatPage); +</pre> + +<p>Теперь, вместо простого "поедания страницы", контентный скрипт ждёт сообщение, используя <code><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/onMessage">runtime.onMessage</a></code>. Когда сообщение получено, контентный скрипт выполняет в точности такой же код, как и а примере ранее, за исключением того, что заменяющий текст берётся из <code>request.replacement</code>.</p> + +<p>Если мы хотим отправить сообщение наоборот, из контентного скрипта в фоновый, настройка будет обратной данному примеру, за исключением того, что мы будем использовать <code><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/sendMessage">runtime.sendMessage()</a></code> в контентном скрипте.</p> + +<div class="note"> +<p>Все эти примеры внедряют JavaScript; вы можете программно внедрять стилевые таблицы CSS используя функцию <code><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/insertCSS">tabs.insertCSS()</a></code>.</p> +</div> + +<h2 id="Узнать_больше">Узнать больше</h2> + +<ul> + <li>Руководство по <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Content_scripts">Content scripts</a></li> + <li>Ключ манифеста<code><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/content_scripts">content_scripts</a></code></li> + <li>Ключ манифеста<code><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions">permissions</a></code></li> + <li><code><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/executeScript">tabs.executeScript()</a></code></li> + <li><code><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/insertCSS">tabs.insertCSS()</a></code></li> + <li><code><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/sendMessage">tabs.sendMessage()</a></code></li> + <li><code><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/sendMessage">runtime.sendMessage()</a></code></li> + <li><code><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/onMessage">runtime.onMessage</a></code></li> + <li>Примеры использования <code>content_scripts</code>: + <ul> + <li><a href="https://github.com/mdn/webextensions-examples/tree/master/borderify">borderify</a></li> + <li><a href="https://github.com/mdn/webextensions-examples/tree/master/notify-link-clicks-i18n">notify-link-clicks-i18n</a></li> + <li><a href="https://github.com/mdn/webextensions-examples/tree/master/page-to-extension-messaging">page-to-extension-messaging</a></li> + </ul> + </li> + <li>Примеры использования <code>tabs.executeScript()</code>: + <ul> + <li><a class="external external-icon" href="https://github.com/mdn/webextensions-examples/tree/master/beastify">beastify</a></li> + <li><a class="external external-icon" href="https://github.com/mdn/webextensions-examples/tree/master/context-menu-demo">context-menu-demo</a></li> + </ul> + </li> +</ul> diff --git a/files/ru/mozilla/add-ons/webextensions/перевод/index.html b/files/ru/mozilla/add-ons/webextensions/перевод/index.html new file mode 100644 index 0000000000..4ceb3eab28 --- /dev/null +++ b/files/ru/mozilla/add-ons/webextensions/перевод/index.html @@ -0,0 +1,218 @@ +--- +title: Отладка +slug: Mozilla/Add-ons/WebExtensions/Перевод +tags: + - Firefox + - Mozilla + - Отладка + - Пособие + - Предоставление Веб-страниц +translation_of: Mozilla/Add-ons/WebExtensions/Debugging +--- +<div>{{AddonSidebar}}</div> + +<div>This article explains how you can use the Firefox developer tools to debug extensions built with WebExtension APIs.</div> + +<p>An extension can consist of various different pieces — background scripts, popups, options pages, content scripts, sidebars — and you'll need to use a slightly different workflow to debug each piece. So each piece gets a top-level section in this article, and the intention is that these sections can be read in isolation. We'll begin by introducing the Add-on Debugger, which you'll use to debug most of the pieces of your extension.</p> + +<ul> +</ul> + +<h2 id="The_Add-on_Debugger">The Add-on Debugger</h2> + +<p>For most of this article we'll use the Add-on Debugger. To open the Add-on Debugger:</p> + +<ul> + <li>open Firefox</li> + <li>enter "about:debugging" in the URL bar</li> + <li>check the box labelled "Enable add-on debugging"</li> + <li>click the "Debug" button next to your extension</li> + <li>click "OK" in the warning dialog.</li> +</ul> + +<p>You'll then see a new window open. The main Firefox window will be switched into the foreground, so you'll have to click on the new window to bring it in front.</p> + +<p>{{EmbedYouTube("G2a65ewjfj0")}}</p> + +<p>This new window is sometimes called a "toolbox" and contains the debugging tools we'll use. It has a tabbed interface: the row of tabs along the top lets you switch between the different tools:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/16309/add-on-debugger.png" style="display: block; height: 472px; margin-left: auto; margin-right: auto; width: 922px;"></p> + +<p>In this article we'll use three debugging tools:</p> + +<ul> + <li><a href="/en-US/docs/Tools/Web_Console">The Console</a>: this displays messages logged by the extension as well as error messages logged by the browser as it runs the extension. It also provides a command line enabling you to execute JavaScript in the extension's context.</li> + <li><a href="/en-US/docs/Tools/Debugger">The Debugger</a>: this enables you to set breakpoints and watchpoints in your extension's JavaScript, and examine and modify its internal state.</li> + <li><a href="/en-US/docs/Tools/Page_Inspector">The Inspector</a>: this enables you to examine and modify the HTML and CSS used to build your extension's pages.</li> +</ul> + +<h2 id="Debugging_background_scripts">Debugging background scripts</h2> + +<div class="note"> +<p>The examples in this section use the "notify-link-clicks-l10n" example extension. If you'd like to play along, you can find this example in the <a href="https://github.com/mdn/webextensions-examples">webextensions-examples</a> repository.</p> +</div> + +<p><a href="/en-US/Add-ons/WebExtensions/Anatomy_of_a_WebExtension#Background_scripts">Background scripts</a> stay loaded for the lifetime of the extension. They're loaded inside an invisible "background page": by default this is an empty HTML document, but you can specify your own HTML content using the <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/background">"background" key in "manifest.json"</a>.</p> + +<p>You can debug background scripts using the <a href="/en-US/Add-ons/WebExtensions/Debugging_(Firefox_50_onwards)#The_Add-on_Debugger">Add-on Debugger</a>.</p> + +<p>In the Add-on Debugger's Console you'll see logged output, including calls to <code><a href="/en-US/docs/Web/API/Console/log">console.log()</a></code> from your own background scripts and any errors the browser raises as it executes them. Note that at the moment, the console shows all errors raised by the browser, not just errors related to your extensions code.</p> + +<p>For example, the <a href="https://github.com/mdn/webextensions-examples/tree/master/notify-link-clicks-i18n">notify-link-clicks-i18n</a> example extension logs a message from its background script when it receives a message from one of its content scripts:</p> + +<p>{{EmbedYouTube("WDQsBU-rpN0")}}</p> + +<p>Using the Console's command line, you can access and modify the objects created by your background scripts.</p> + +<p>For example, here we call the <code>notify()</code> function defined in the extension's background script:</p> + +<p>{{EmbedYouTube("g-Qgf8Mc2wg")}}</p> + +<p>If you switch to the Debugger, you'll see all your extension's background scripts. You can set breakpoints, step through code, and do <a href="https://developer.mozilla.org/en-US/docs/Tools/Debugger">everything else you'd expect to be able to do in a debugger</a>.</p> + +<p>{{EmbedYouTube("MNeaz2jdmzY")}}</p> + +<p>If you press the Escape key while you're in the Debugger, the toolbox will be split, with the bottom half now occupied by the Console. While you're at a breakpoint, you can now modify the program's state using the console. See <a href="/en-US/docs/Tools/Web_Console/Split_console">Split console</a> for more on this.</p> + +<h2 id="Debugging_options_pages">Debugging options pages</h2> + +<p><a href="/en-US/Add-ons/WebExtensions/Anatomy_of_a_WebExtension#Options_pages">Options pages</a> are HTML pages that the extension developer can supply, that contain options for the extension. They are typically displayed in an iframe in the Add-ons Manager (to see the Add-ons Manager, visit the "about:addons" page).</p> + +<p>To debug options pages:</p> + +<ul> + <li>open the <a href="/en-US/Add-ons/WebExtensions/Debugging_(Firefox_50_onwards)#The_Add-on_Debugger">Add-on Debugger</a> for your extension</li> + <li>open your extension's option page.</li> +</ul> + +<p>Any JavaScript sources it includes are then listed in the Debugger:</p> + +<p>{{EmbedYouTube("BUMG-M8tFF4")}}</p> + +<div class="note"> +<p>This video uses the <a href="https://github.com/mdn/webextensions-examples/tree/master/favourite-colourbeastify">favourite-colour</a> example extension.</p> +</div> + +<p>You'll also see any messages logged by your code in the Add-on Debugger's Console.</p> + +<p>You can also use the Add-on Debugger to debug the page's HTML and CSS. First, though, you need to point the tools at the iframe that hosts the options page. To do this: open the options page, click the icon highlighted in the screenshot below, and select the options page from the drop-down list:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/13863/toolbox-iframe.png" style="display: block; height: 417px; margin-left: auto; margin-right: auto; width: 876px;"></p> + +<p>Now switch to the Inspector tab, and you'll be able to examine and edit HTML and CSS for the page:</p> + +<p>{{EmbedYouTube("-2m3ubFAU94")}}</p> + +<h2 id="Debugging_popups">Debugging popups</h2> + +<p><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Popups">Popups</a> are dialogs that are attached to browser actions or page actions. They are specified using an HTML document that can include CSS and JavaScript sources for styling and behavior. Whenever the popup is visible, you can use the <a href="/en-US/Add-ons/WebExtensions/Debugging_(Firefox_50_onwards)#The_Add-on_Debugger">Add-on Debugger</a> to debug its code.</p> + +<p>One problem with popups is that if a popup is open and you click outside the popup, the popup is closed and its code is unloaded. This obviously makes them impossible to debug. To suppress this behavior, select Disable Popup Auto-Hide from the Elipsis menu as shown below:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/16301/add-on-debugger.png" style="display: block; height: 612px; margin-left: auto; margin-right: auto; width: 876px;"></p> + +<p>Now, when you open a popup it will stay open until you press Escape.</p> + +<div class="note"> +<p><strong>Note:</strong> This change applies to built-in browser popups, like the Elipsis menu (<code>...</code>), as well as extension popups.</p> + +<p>The setting does not persist across sessions. When you close the window, the setting reverts to auto-hide popups.</p> +Internally, this button just toggles the <code>ui.popup.disable_autohide</code> preference, which you can toggle manually using about:config.</div> + +<p>When the popup is open, its JavaScript sources will be listed in the Debugger. You can set breakpoints and modify the program's internal state:</p> + +<p>{{EmbedYouTube("hzwnR8qoz2I")}}</p> + +<div class="note"> +<p>This video uses the <a href="https://github.com/mdn/webextensions-examples/tree/master/beastify">beastify</a> example extension.</p> +</div> + +<p>You can also use the Add-on Debugger to debug the popup's HTML and CSS. First, though, you need to point the tools at the popup's document. To do this: open the popup, then click the icon highlighted in the screenshot below and select the popup's page from the drop-down list:<img alt="" src="https://mdn.mozillademos.org/files/13863/toolbox-iframe.png" style="display: block; height: 417px; margin-left: auto; margin-right: auto; width: 876px;"></p> + +<p>Now switch to the Inspector, and you'll be able to examine and edit the popup's HTML and CSS:</p> + +<p>{{EmbedYouTube("6lvdm7jaq7Y")}}</p> + +<h2 id="Debugging_content_scripts">Debugging content scripts</h2> + +<p>You can use the Add-on Debugger to debug background pages, options pages, and popups. However, you can't use it to debug content scripts. This is because, in <a href="/en-US/docs/Mozilla/Firefox/Multiprocess_Firefox">multiprocess Firefox</a>, content scripts run in a different process from the other parts of your extension. The browser console has similar limitations.</p> + +<p>To debug content scripts attached to a web page, use the normal web developer tools for that page:</p> + +<ul> + <li>either select "Toggle Tools" from the Web Developer submenu in the Firefox Menu (or Tools menu if you display the menu bar or are on Mac OS X)</li> + <li>or press the <kbd>Ctrl</kbd><kbd>Shift</kbd><kbd>I</kbd> (<kbd>Command</kbd><kbd>Option</kbd><kbd>I</kbd> on OS X) keyboard shortcut.</li> +</ul> + +<p>{{EmbedYouTube("f46hMLELyaI")}}</p> + +<p>By default, the tools are shown attached to the bottom of browser tab, to reflect the fact that they are attached to this tab. You'll see any output from <code><a href="/en-US/docs/Web/API/Console/log">console.log()</a></code> statements in your content scripts. You will also see your content scripts listed in the Debugger, where you'll be able to set breakpoints, step through the code, and so on.</p> + +<p>{{EmbedYouTube("Hx3GU_fEPeo")}}</p> + +<div class="note"> +<p>This video uses the <a href="https://github.com/mdn/webextensions-examples/tree/master/notify-link-clicks-i18n">notify-link-clicks-i18n</a> example extension.</p> +</div> + +<div class="note"> +<p>If the developer tools tab was not already open when the content script was injected, sometimes the content script is not listed in the debugger panel. If you experience this, reloading the page with the developer tools tab open should fix the problem.</p> +</div> + +<h2 id="Debugging_sidebars">Debugging sidebars</h2> + +<p><a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Sidebars">Sidebars</a> are HTML pages opened as a sidebar in the browser UI that the extension developer can supply.</p> + +<p>To debug sidebars:</p> + +<ul> + <li>open the <a href="/en-US/Add-ons/WebExtensions/Debugging_(Firefox_50_onwards)#The_Add-on_Debugger">Add-on Debugger</a> for your extension</li> + <li>open your extension's sidebar.</li> +</ul> + +<p>Any JavaScript sources it includes are then listed in the Debugger.</p> + +<p>You'll also see any messages logged by your code in the Add-on Debugger's Console.</p> + +<p>You can also use the Add-on Debugger to debug the page's HTML and CSS. First, though, you need to point the tools at the iframe that hosts the options page. To do this: open the sidebar, click the icon highlighted in the screenshot below, and select the sidebar from the drop-down list:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/13863/toolbox-iframe.png" style="display: block; height: 417px; margin-left: auto; margin-right: auto; width: 876px;"></p> + +<h2 id="Debug_runtime_permission_requests">Debug runtime permission requests</h2> + +<p> </p> + +<p>Runtime permissions granted in your extension are persistent. Therefore, if you want to test cases where the permission has not been granted you will need to add a feature to programmatically remove the permission, use the <a class="external external-icon" href="https://github.com/rpl/dev-webext-permissions-manager" rel="noopener">Extensions Permission Manager,</a> or give your extension a new ID. For more information, see <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Test_permission_requests#Retest_runtime_permission_grants">Retest runtime permission grants</a> in <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Test_permission_requests">Test permission requests</a>.</p> + +<p> </p> + +<h2 id="Debugging_developer_tools_pages_panels">Debugging developer tools pages & panels</h2> + +<p><a href="/en-US/Add-ons/WebExtensions/Extending_the_developer_tools">Developer tools</a> are extended by loading a hidden HTML page when devtools are opened and <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/API/devtools.panels/create">developer tools panels</a> are HTML pages displayed as a developer tool in the browser UI that the extension developer can supply.</p> + +<p>To debug the developer tools page:</p> + +<ul> + <li>open the <a href="/en-US/Add-ons/WebExtensions/Debugging_(Firefox_50_onwards)#The_Add-on_Debugger">Add-on Debugger</a> for your extension</li> + <li>open the Web Developer Tools</li> +</ul> + +<p>To debug developer tools panels:</p> + +<ul> + <li>Follow the steps for the developer tools page above</li> + <li>Select your developer tools panel</li> +</ul> + +<p>Any JavaScript sources it includes are then listed in the Debugger.</p> + +<p>You'll also see any messages logged by your code in the Add-on Debugger's Console.</p> + +<p>You can also use the Add-on Debugger to debug the page's HTML and CSS. First, though, you need to point the tools at the iframe that hosts the options page. To do this: open the sidebar, click the icon highlighted in the screenshot below, and select the sidebar from the drop-down list:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/13863/toolbox-iframe.png" style="display: block; height: 417px; margin-left: auto; margin-right: auto; width: 876px;"></p> + +<h2 id="Debugging_Browser_Restarts">Debugging Browser Restarts</h2> + +<p>If your extension is active in ways that might be affected by the browser restarting, such as a session being restored, then you may want to do extra testing to ensure your code works as expected in those conditions.</p> + +<p>See <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions/Testing_persistent_and_restart_features">Testing persistent and restart features</a> for more details.</p> diff --git a/files/ru/mozilla/add-ons/загрузочные_расширения/index.html b/files/ru/mozilla/add-ons/загрузочные_расширения/index.html new file mode 100644 index 0000000000..934e40e904 --- /dev/null +++ b/files/ru/mozilla/add-ons/загрузочные_расширения/index.html @@ -0,0 +1,353 @@ +--- +title: Загружаемые расширения +slug: Mozilla/Add-ons/загрузочные_расширения +tags: + - Bootstrapped + - Extensions + - add-on + - Дополнения +translation_of: Archive/Add-ons/Bootstrapped_extensions +--- +<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}}{{AddonSidebar}}</p> + +<p>{{ gecko_minversion_header("2.0") }}</p> + +<p>К традиционным расширениям относятся оверлеи (<strong>overlays</strong>), в их случае приложение может загрузить XUL из пакета расширения и автоматически применить их на верхнем слое своего UI (интерфейса пользователя). При этом создаются расширения, которые добавляются в пользовательский интерфейс относительно легко, но в этом случае обновление, установка или отмена действия расширения требуют перезагрузку приложения.</p> + +<p>Движок Gecko 2.0 {{ geckoRelease("2.0") }} вводит <strong>загружаемые расширения</strong> (<strong>bootstrapped extensions</strong>). Это специальные расширения, которые вместо использования наложения на интерфейс, сами програмно добавляют себя в приложение. Это делается запуском специального скрипта из файла, который включен в расширение и содержит функции, вызываемые браузером, для того чтобы установить, удалить, загрузить, выгрузить.</p> + +<p>Приложение делает вызовы из из этого файла со скриптом; расширение ответственно за добавление и удаление своего интерфейса пользователя и обработку любых других установок и завершения задач, которые требовались в процессе работы.</p> + +<p>Эта статья поясняет как работают загружаемые расширения. Изучите следующее <a href="/en-US/Add-ons/How_to_convert_an_overlay_extension_to_restartless">руководство по преобразованию приложений-оверлеев (overlay) в приложения, не требующие перезагрузки (restartless, то есть bootstrapped)</a>, для получения пошагового руководства по переходу.</p> + +<h2 id="The_startup_and_shutdown_process">The startup and shutdown process</h2> + +<p>A key feature of bootstrapped extensions is that they must be able to start up and shut down on demand by the application. When the extension's <code>startup()</code> function is called, it must manually inject its user interface and other behavior into the application. Similarly, when its <code>shutdown()</code> function is called, it must remove anything that it has added to the application, as well as all references to any of its objects.</p> + +<p>There are several scenarios in which the <code>startup()</code> function may be called; for example:</p> + +<ul> + <li>When the extension is first installed, assuming that it's both compatible with the application and is enabled.</li> + <li>When the extension becomes enabled using the add-ons manager window.</li> + <li>When the application is started up, if the extension is enabled and compatible with the application.</li> +</ul> + +<p>Some examples of when the <code>shutdown()</code> function may be called:</p> + +<ul> + <li>When the extension is uninstalled, if it's currently enabled.</li> + <li>When the extension becomes disabled.</li> + <li>When the user quits the application, if the extension is enabled.</li> +</ul> + +<h2 id="Notes_on_modifying_the_application_user_interface">Notes on modifying the application user interface</h2> + +<h3 id="chrome.manifest_in_bootstrapped_add-ons">chrome.manifest in bootstrapped add-ons</h3> + +<p>You can use a <a href="/en-US/docs/Chrome_Registration"><code>chrome.manifest</code></a> file in bootstrapped add-ons to:</p> + +<ul> + <li>Make your add-on's content available via a <code>chrome://</code> URL (using the <code>content</code>, <code>locale</code>, and <code>skin</code> instructions in the manifest).</li> + <li>Replace existing <code>chrome://</code> URIs with your content (using the <code>override</code> instruction).</li> +</ul> + +<p>Not all <code>chrome.manifest</code> instructions are supported in bootstrapped add-ons, for example you still cannot register <a href="/en-US/docs/XUL_Overlays">XUL Overlays</a> from a bootstrapped add-on. See the <a href="/en-US/docs/Chrome_Registration"><code>chrome.manifest</code></a> documentation for details.</p> + +<p>In Firefox 10 and later the <code>chrome.manifest</code> file located in the root of the add-on's XPI (i.e. a sibling of the <code>install.rdf</code>) is loaded automatically. In Firefox 8 and 9 you had to load/unload the manifest manually using {{ ifmethod("nsIComponentManager", "addBootstrappedManifestLocation") }} and {{ ifmethod("nsIComponentManager", "removeBootstrappedManifestLocation") }}. This feature was unavailable in Firefox versions before 8.</p> + +<h3 id="Adding_user_interface_manually">Adding user interface manually</h3> + +<p>If you decide to go ahead and try to develop a bootstrapped extension that modifies the application's user interface, here are a few suggestions to get you started.</p> + +<p>You need to look up the relevant application UI elements by their ID by calling {{ domxref("document.getElementById()") }}, then manipulate them to inject your UI. For example, you can get access to the menu bar in Firefox with <code>document.getElementById("main-menubar")</code>.</p> + +<p>Be sure that at shutdown time, you remove any user interface you've added.</p> + +<h2 id="Creating_a_bootstrapped_extension">Creating a bootstrapped extension</h2> + +<p>To mark an extension as bootstrappable, you need to add the following element to its <a href="/en-US/docs/Install_Manifests">install manifest</a>:</p> + +<pre><code><em:bootstrap>true</em:bootstrap></code></pre> + +<p>Then you need to add a <a href="/en-US/docs/Extensions/bootstrap.js"><code><strong>bootstrap.js</strong></code> file</a> that contains the required functions; this should be alongside the <a href="/en-US/docs/Install_Manifests"><code>install.rdf</code> file</a> in the extension's package.</p> + +<h3 id="Backward_compatibility">Backward compatibility</h3> + +<p>Because older versions of Firefox don't know about the <code>bootstrap</code> property or <code>bootstrap.js</code> file, it's not overly difficult to create an XPI that will work on both as a bootstrappable extension and as a traditional extension. Create your extension as a bootstrappable extension, then add the traditional overlays as well. Newer versions of Firefox will use the <code>bootstrap.js</code> script, ignoring the components and overlays, while older versions will use the overlays.</p> + +<h2 id="Bootstrap_entry_points">Bootstrap entry points</h2> + +<p>The <code>bootstrap.js</code> script should contain several specific functions, which are called by the browser to manage the extension. The script gets executed in a privileged sandbox, which is cached until the extension is shut down.</p> + +<h3 id="startup">startup</h3> + +<p>Called when the extension needs to start itself up. This happens at application launch time, when the extension is enabled after being disabled or after it has been shut down in order to install an update. As such, this can be called many times during the lifetime of the application.</p> + +<p>This is when your add-on should inject its UI, start up any tasks it may need running and so forth.</p> + +<pre>void startup( + data, + reason +); +</pre> + +<h6 id="Parameters">Parameters</h6> + +<dl> + <dt><code>data</code></dt> + <dd>A <a href="#Bootstrap_data">bootstrap data structure</a>.</dd> + <dt><code>reason</code></dt> + <dd>One of the <a href="#Reason_constants">reason constants</a>, indicating why the extension is being started up. This will be one of <code>APP_STARTUP</code>, <code>ADDON_ENABLE</code>, <code>ADDON_INSTALL</code>, <code>ADDON_UPGRADE</code>, or <code>ADDON_DOWNGRADE</code>.</dd> +</dl> + +<h3 id="shutdown">shutdown</h3> + +<p>Called when the extension needs to shut itself down, such as when the application is quitting or when the extension is about to be upgraded or disabled. Any user interface that has been injected must be removed, tasks shut down, and objects disposed of.</p> + +<pre>void shutdown( + data, + reason +); +</pre> + +<h6 id="Parameters_2">Parameters</h6> + +<dl> + <dt><code>data</code></dt> + <dd>A <a href="#Bootstrap_data">bootstrap data structure</a>.</dd> + <dt><code>reason</code></dt> + <dd>One of the <a href="#Reason_constants">reason constants</a>, indicating why the extension is being shut down. This will be one of <code>APP_SHUTDOWN</code>, <code>ADDON_DISABLE</code>, <code>ADDON_UNINSTALL</code>, <code>ADDON_UPGRADE</code>, or <code>ADDON_DOWNGRADE</code>.</dd> +</dl> + +<h3 id="install">install</h3> + +<p>Your bootstrap script must include an <code>install()</code> function, which the application calls before the first call to <code>startup()</code> after the extension is installed, upgraded, or downgraded.</p> + +<pre>void install( + data, + reason +); +</pre> + +<h6 id="Parameters_3">Parameters</h6> + +<dl> + <dt><code>data</code></dt> + <dd>A <a href="#Bootstrap_data">bootstrap data structure</a>.</dd> + <dt><code>reason</code></dt> + <dd>One of the <a href="#Reason_constants">reason constants</a>, indicating why the extension is being installed. This will be one of <code>ADDON_INSTALL</code>, <code>ADDON_UPGRADE</code>, or <code>ADDON_DOWNGRADE</code>.</dd> +</dl> + +<h3 id="uninstall">uninstall</h3> + +<p>This function is called after the last call to <code>shutdown()</code> before a particular version of an extension is uninstalled.</p> + +<div class="note"><strong>Note:</strong> If you open the add-on manager and then click "Remove" on an add-on, it will not call uninstall function right away. This is a soft uninstall because of the available "Undo" option. If the add-on manager is closed or another event takes place such that the "Undo" option becomes unavailable, then the hard uninstall takes place and the uninstall function is called.</div> + +<div class="note"><strong>Note:</strong> The uninstall function fires on downgrade and upgrade as well so you should make sure it is an uninstall by doing this:<br> +<code>function uninstall(aData, aReason) {</code><br> +<code>if (aReason == ADDON_UNINSTALL) {</code><br> +<code>console.log('really uninstalling');</code><br> +<code>} else {</code><br> +<code>console.log('not a permanent uninstall, likely an upgrade or downgrade');</code><br> +<code>}</code><br> +<code>}</code></div> + +<pre>void uninstall( + data, + reason +); +</pre> + +<h6 id="Parameters_4">Parameters</h6> + +<dl> + <dt><code>data</code></dt> + <dd>A <a href="#Bootstrap_data">bootstrap data structure</a>.</dd> + <dt><code>reason</code></dt> + <dd>One of the <a href="#Reason_constants">reason constants</a>, indicating why the extension is being uninstalled. This will be one of <code>ADDON_UNINSTALL</code>, <code>ADDON_UPGRADE</code>, or <code>ADDON_DOWNGRADE</code>.</dd> +</dl> + +<h2 id="Reason_constants">Reason constants</h2> + +<p>The bootstrap functions accept a <code>reason</code> parameter, which explains to the extension why it's being called. The reason constants are:</p> + +<table class="standard-table"> + <tbody> + <tr> + <td class="header">Constant</td> + <td class="header">Value</td> + <td class="header">Description</td> + </tr> + <tr> + <td><code>APP_STARTUP</code></td> + <td>1</td> + <td>The application is starting up.</td> + </tr> + <tr> + <td><code>APP_SHUTDOWN</code></td> + <td>2</td> + <td>The application is shutting down.</td> + </tr> + <tr> + <td><code>ADDON_ENABLE</code></td> + <td>3</td> + <td>The add-on is being enabled.</td> + </tr> + <tr> + <td><code>ADDON_DISABLE</code></td> + <td>4</td> + <td>The add-on is being disabled. (Also <a class="link-https" href="https://bugzilla.mozilla.org/show_bug.cgi?id=620541">sent during uninstallation</a>)</td> + </tr> + <tr> + <td><code>ADDON_INSTALL</code></td> + <td>5</td> + <td>The add-on is being installed.</td> + </tr> + <tr> + <td><code>ADDON_UNINSTALL</code></td> + <td>6</td> + <td>The add-on is being uninstalled.</td> + </tr> + <tr> + <td><code>ADDON_UPGRADE</code></td> + <td>7</td> + <td>The add-on is being upgraded.</td> + </tr> + <tr> + <td><code>ADDON_DOWNGRADE</code></td> + <td>8</td> + <td>The add-on is being downgraded.</td> + </tr> + </tbody> +</table> + +<h2 id="Bootstrap_data">Bootstrap data</h2> + +<p>Each of the entry points is passed a simple data structure containing some useful information about the add-on being bootstrapped. More information about the add-on can be obtained by calling <code><a href="/en-US/docs/Addons/Add-on_Manager/AddonManager#getAddonByID()">AddonManager.getAddonByID()</a></code>. The data is a simple JavaScript object with the following properties:</p> + +<table class="standard-table"> + <tbody> + <tr> + <td class="header">Property</td> + <td class="header">Type</td> + <td class="header">Description</td> + </tr> + <tr> + <td><code>id</code></td> + <td><code>string</code></td> + <td>The ID of the add-on being bootstrapped.</td> + </tr> + <tr> + <td><code>version</code></td> + <td><code>string</code></td> + <td>The version of the add-on being bootstrapped.</td> + </tr> + <tr> + <td><code>installPath</code></td> + <td><code>nsIFile</code></td> + <td>The installation location of the add-on being bootstrapped. This may be a directory or an XPI file depending on whether the add-on is installed unpacked or not.</td> + </tr> + <tr> + <td><code>resourceURI</code></td> + <td><code>nsIURI</code></td> + <td>A URI pointing at the root of the add-ons files, this may be a <code>jar:</code> or <code>file:</code> URI depending on whether the add-on is installed unpacked or not. {{ gecko_minversion_inline("7.0") }}</td> + </tr> + <tr> + <td><code>oldVersion</code></td> + <td><code>string</code></td> + <td>The previously installed version, if the reason is <code>ADDON_UPGRADE</code> or <code>ADDON_DOWNGRADE</code>, and the method is <code>install</code> or <code>startup</code>. {{ gecko_minversion_inline("22.0") }}</td> + </tr> + <tr> + <td><code>newVersion</code></td> + <td><code>string</code></td> + <td>The version to be installed, if the reason is <code>ADDON_UPGRADE</code> or <code>ADDON_DOWNGRADE</code>, and the method is <code>shutdown</code> or <code>uninstall</code>. {{ gecko_minversion_inline("22.0") }}</td> + </tr> + </tbody> +</table> + +<div class="note"> +<p><strong>Note:</strong> An add-on may be upgraded/downgraded at application startup, in this case the <code>startup</code> method reason is <code>APP_STARTUP</code>, and the <code>oldVersion</code> property is not set. Also be aware that in some circumstances an add-on upgrade/downgrade may occur without the <code>uninstall</code> method being called.</p> +</div> + +<h2 id="Add-on_debugger">Add-on debugger</h2> + +<p>From Firefox 31 onwards, you can use the <a href="/en-US/Add-ons/Add-on_Debugger">Add-on Debugger</a> to debug bootstrapped add-ons.</p> + +<h2 id="Localization_(L10n)">Localization (L10n)</h2> + +<p>Localizing bootstrapped add-ons is very much the same since Firefox 7, as that is when chrome.manifest compatibility landed.</p> + +<h3 id="JS_and_JSM_Files_-_Using_Property_Files">JS and JSM Files - Using Property Files</h3> + +<p>To localize your .js and .jsm files you have to use <a href="/en-US/docs/XUL/Tutorial/Property_Files">property files</a>.</p> + +<p>The absolute minimum needed here is:</p> + +<ol> + <li>File: install.rdf</li> + <li>File: chrome.manifest</li> + <li>File: bootstrap.js</li> + <li>Folder: locale + <ol> + <li>Folder: VALID_LOCALE_HERE + <ol> + <li>File: ANYTHING.properties</li> + </ol> + </li> + </ol> + </li> +</ol> + +<p>In the locale folder you must have folders for each of the languages you want to provide; each folder must be named a valid locale (ex: en-US). Inside this folder must be a property file. Inside the chrome.manifest file these locale must be defined. For example if you had a subfolder of en-US in locale folder your chrome.manifest file will have to contain: <code>locale NAME_OF_YOUR_ADDON en-US locale/en-US/</code></p> + +<p>Here is an example: <a href="https://github.com/Noitidart/l10n/tree/properties">GitHub :: l10n-properties</a> - on startup of this add-on it will show a prompt saying USA or Great Britain, which ever it deems closest to your locale. You can test different locale by going to about:config and changing preference of general.useragent.locale to en-US and then to en-GB and disabling then re-enabling the add-on.</p> + +<h3 id="XUL_and_HTML_Files_-_Using_Entities_from_DTD_Files">XUL and HTML Files - Using Entities from DTD Files</h3> + +<p>Many times HTML pages are used, however they cannot be localized with DTD files. There are three changes you must make:</p> + +<ol> + <li>You have to change the HTML file's extension to be <code>.xhtml</code></li> + <li>The doctype must be defined point to a DTD file in your locale folder such as: <code><!DOCTYPE html SYSTEM <span class="pl-s1">"chrome://l10n/locale/mozilla.dtd"</span>></code></li> + <li>Must add xmlns attribute to html tag for example: <code><<span class="pl-ent">html</span> <span class="pl-e">xmlns</span>=<span class="pl-s1"><span class="pl-pds">"</span>http://www.w3.org/1999/xhtml<span class="pl-pds">"</span></span>></code></li> + <li>If you have multiple DTD files read on here: <a href="/en-US/docs/Using_multiple_DTDs">Using multiple DTDs</a></li> +</ol> + +<p>The bare minimum needed is:</p> + +<ol> + <li>File: install.rdf</li> + <li>File: chrome.manifest</li> + <li>File: bootstrap.js</li> + <li>Folder: locale + <ol> + <li>Folder: VALID_LOCALE_HERE + <ol> + <li>File: ANYTHING.dtd</li> + </ol> + </li> + </ol> + </li> +</ol> + +<p>The chrome.manifest file must include a definition for content for example: <code>content NAME_OF_YOUR_ADDON ./</code></p> + +<p>The chrome.manifest file must also include a line pointing to the locale, just like in the above property section, if you had a folder named en-US in locale, the chrome.manifest file should contain: <code>locale NAME_OF_YOUR_ADDON en-US locale/en-US/</code></p> + +<p>Here is an example add-on that opens an HTML page and a XUL page on install: <a href="https://github.com/Noitidart/l10n/tree/c456cc82a8a66b6d552cd8c2299cd2babc383af0">GitHub :: l10n-xhtml-xul</a>. Here is an example showing how to use a localized HTML page as an options page: <a href="https://github.com/Noitidart/l10n/tree/html-options">GitHub :: l10n-html-options</a>. You can go to about:config and change the value of the preference <code>general.useragent.locale </code>to <code>en-US</code> and then to <code>en-GB</code> and then reload the open pages to see the localization change.</p> + +<h2 id="Further_reading">Further reading</h2> + +<ul> + <li><a href="https://developer.mozilla.org/en-US/Add-ons/How_to_convert_an_overlay_extension_to_restartless">How to convert an overlay extension to restartless</a> a step by step guide. Some code samples are provided. The page is based on and expanded from Dave Garrett's step-by-step guide to <a class="external" href="https://flagfox.wordpress.com/2014/01/19/writing-restartless-addons/">convert an old overlay based extension into a restartless addon</a>.</li> + <li>Dave Townsend provides a basic code base to <a class="external" href="http://www.oxymoronical.com/blog/2011/01/Playing-with-windows-in-restartless-bootstrapped-extensions">load UI for each opened window</a> in a bootstrapped extension.</li> + <li>Mark Finkle provides some simple example code for <a class="external" href="http://starkravingfinkle.org/blog/2011/01/bootstrap-jones-adventures-in-restartless-add-ons/">restartless add-ons in mobile Firefox</a>, <a class="external" href="http://starkravingfinkle.org/blog/2011/01/restartless-add-ons-more-resources/">adding resources (like the options window)</a> to bootstrapped extensions and <a class="external" href="http://starkravingfinkle.org/blog/2011/01/restartless-add-ons-%e2%80%93-default-preferences/">using default preferences</a> without a <code>default/preferences/prefs.js</code> file.</li> + <li>Kris Maglione writes about <a class="external" href="http://maglione-k.users.sourceforge.net/bootstrapped.xhtml">the requirements for the cleanup procedures</a> in bootstrapped extensions.</li> + <li>Edward Lee shows off some <a class="external" href="http://ed.agadak.net/2011/01/restartless-add-on-example-code">helpful coding patterns and examples</a> you can use in your bootstrapped add-on.</li> + <li>Documentation for <a href="/en-US/docs/Extensions/Inline_Options">Inline Options</a> in Firefox 7 and later.</li> +</ul> diff --git a/files/ru/mozilla/add-ons/рекомендации_по_повышению_производительности_расширений/index.html b/files/ru/mozilla/add-ons/рекомендации_по_повышению_производительности_расширений/index.html new file mode 100644 index 0000000000..4442856118 --- /dev/null +++ b/files/ru/mozilla/add-ons/рекомендации_по_повышению_производительности_расширений/index.html @@ -0,0 +1,102 @@ +--- +title: Рекомендации по повышению производительности расширений +slug: Mozilla/Add-ons/Рекомендации_по_повышению_производительности_расширений +tags: + - Быстродействие + - Лучшие практики + - Плагины + - Производительность + - Расширения + - Руководство +translation_of: Archive/Add-ons/Performance_best_practices_in_extensions +--- +<p>Одно из самых значительных преимуществ браузера Firefox заключается в его чрезвычайной расширяемости. Благодаря дополнениям можно сделать практически что угодно. Есть и обратная сторона медали: плохо написанные расширения могут оказывать серьезное влияние на просмотр сайтов, в том числе и на производительность браузера Firefox в целом. Эта статья предлагает вашему вниманию лучшие практики и рекомендации, которые позволят повысить производительность и быстродействие не только вашего расширения, но также и самого браузера Firefox.</p> + +<h2 id="Увеличиваем_скорость_запуска">Увеличиваем скорость запуска</h2> + +<p>Расширения загружаются и выполняются всякий раз, когда открывается новое окно браузера. Это значит, что при каждом открытии окна ваше расширение может задерживать вывод желаемого контента на экран. Есть несколько способов уменьшения времени задержки вывода пользовательского контента.</p> + +<h3 id="Загружайте_только_то_что_вам_действительно_требуется">Загружайте только то, что вам действительно требуется</h3> + +<p>В момент запуска плагина не следует загружать то, что понадобится только после нажатия пользователем на кнопку, или то, что понадобится только при включенной опции, если сейчас она выключена. Если ваше расширение предоставляет функции, доступные только после авторизации пользователя в сервисе, не следует загружать ресурсы для этих функций до тех пор, пока пользователь фактически не пройдет процедуру авторизации.</p> + +<h3 id="Используйте_модули_JavaScript">Используйте модули JavaScript</h3> + +<p>Вы можете создать собственный <a href="/en-US/docs/Mozilla/JavaScript_code_modules/Using" title="/en-US/docs/Mozilla/JavaScript_code_modules/Using">модуль JavaScript</a>, объединив набор функций, которые нужны только в определенных ситуациях. Это упростит загрузку блоков кода вашего расширения на лету, вместо загрузки всего сразу.</p> + +<p>Несмотря на то, что модули JavaScript могут быть чрезвычайно полезны и давать прирост производительности, они должны применяться разумно. Загрузка модулей все же несет небольшие затраты, поэтому разбивка кода на ненужные уровни может привести к негативным результатам. Код должен быть разбит на модули так, чтобы от этого улучшалась его понятность, а загрузка крупных или требующих больших затрат блоков кода могла быть значительно отсрочена.</p> + +<h3 id="Отсрочивайте_все_что_возможно">Отсрочивайте все, что возможно</h3> + +<p>У большинства расширений есть обработчик события загрузки в главном оверлее, который выполняет функцию при запуске браузера. Выполняйте в этой функции как можно меньше кода. Окно браузера зависает до тех пор, пока обработчик загрузки вашего плагина полностью не выполнится, поэтому чем больше в нем осуществляется действий, тем медленнее Firefox кажется пользователю.</p> + +<p>Если что-то можно сделать пусть даже на долю секунды позже, используйте методы {{ interface("nsITimer") }} или {{ domxref("window.setTimeout()") }} для того, чтобы отложить это действие на потом. Даже короткая отсрочка может иметь большое влияние на быстродействие.</p> + +<h2 id="Общие_вопросы_производительности">Общие вопросы производительности</h2> + +<h3 id="Избегайте_утечек_памяти">Избегайте утечек памяти</h3> + +<p>Утечки памяти вынуждают сборщик мусора и сборщик циклических ссылок (cycle collector) выполнять больший объем работы, а это в значительной мере сказывается на быстродействии.</p> + +<p>Зомби-ячейки (zombie compartments) - это особый вид утечки памяти, который можно легко выявить. Загляните на страницу<a href="/en/Zombie_compartments" title="en/Zombie_compartments"> </a><a href="/en/Zombie_compartments" title="en/Zombie_compartments">Зомби-ячейки</a>, особенно раздел <a href="/en/Zombie_compartments#Proactive_checking_of_add-ons" title="en/Zombie_compartments#Proactive_checking_of_add-ons">Проактивная проверка плагинов</a>.</p> + +<p>Ознакомьтесь с разделом <a href="/en/Extensions/Common_causes_of_memory_leaks_in_extensions" title="en/Extensions/Common_causes_of_zombie_compartments_in_extensions">Распространенные причины утечек памяти в расширениях</a>, чтобы узнать, как избежать возникновения зомби-ячеек и других видов утечек.</p> + +<p>Помимо поиска различных видов утечек памяти, стоит также проверить функционал вашего расширения и содержимое вкладки about:memory на предмет избыточного потребления памяти. Например, <a class="link-https" href="https://bugzilla.mozilla.org/show_bug.cgi?id=719601" title="https://bugzilla.mozilla.org/show_bug.cgi?id=719601">ошибка 719601</a> приводила к тому, что ячейка JavaScript содержала сотни мегабайт памяти, что гораздо больше, чем обычно.</p> + +<h3 id="Избегайте_написания_медленных_таблиц_стилей_CSS">Избегайте написания медленных таблиц стилей CSS</h3> + +<ul> + <li>Прочитайте руководство <a href="/en/CSS/Writing_Efficient_CSS" title="en/CSS/Writing_Efficient_CSS">"Разработка эффективных таблиц стилей CSS"</a>.</li> + <li>Помните, что каждый селектор в вашем правиле, который может совпадать с множеством различных узлов - это источник снижения производительности при поиске совпадения или выполнении динамического обновления элемента. Это особенно плохо, если селектор может динамически запускать и останавливать поиск совпадений. Остерегайтесь использования псевдо-класса ":hover".</li> +</ul> + +<h3 id="Избегайте_использования_технологии_DOM_Mutation_Events">Избегайте использования технологии DOM Mutation Events</h3> + +<p>Технология прослушивания изменений DOM чрезвычайно затратна по ресурсам, ее использование приводит к значительному ухудшению быстродействия. Так как она официально признана нерекомендуемой для применения, при этом имеется <a href="/en-US/Add-ons/Overlay_Extensions/XUL_School/Appendix_F:_Monitoring_DOM_changes">множество аналогов</a>, ее следует всячески избегать.</p> + +<h3 id="Используйте_методы_ленивой_загрузки">Используйте методы ленивой загрузки</h3> + +<p><a href="/en/JavaScript_code_modules/XPCOMUtils.jsm#Methods" title="en/JavaScript_code_modules/XPCOMUtils.jsm#Methods">JavaScript-модуль XPCOMUtils</a> предоставляет два метрода ленивой (отложенной) загрузки:</p> + +<ul> + <li><code>defineLazyGetter()</code> определяет для указанного объекта функцию, которая действует как метод доступа get, возвращающий объект, который будет создан в момент первого обращения к нему. <a class="external" href="http://mxr.mozilla.org/mozilla-central/search?string=defineLazyGetter">Подробнее см. примеры</a>.</li> + <li><code>defineLazyServiceGetter()</code> определяет для указанного объекта функцию, которая действует как метод доступа get для сервиса. Сервис не будет получен до первого его использования. Например, {{ LXRSearch("ident", "string", "defineLazyServiceGetter", "Look through the source") }}.</li> +</ul> + +<p>Множество распространенных сервисов уже закэшированы для вас в модуле <a href="/en-US/JavaScript_code_modules/Services.jsm">Services.jsm</a>.</p> + +<h3 id="Используйте_ассинхронный_вводвывод">Используйте ассинхронный ввод/вывод</h3> + +<p>Это следует подчеркнуть: никогда не выполняйте синхронный ввод/вывод в главном потоке.</p> + +<p>Любой ввод/вывод в главном потоке, будь то активность жесткого диска или сетевая активность, может стать причиной серьезных проблем с временем отклика интерфейса пользователя.</p> + +<ul> + <li>Никогда не используйте синхронные запросы XMLHttpRequests.</li> + <li>Используйте модуль <a href="/en-US/JavaScript_code_modules/NetUtil.jsm">NetUtils.jsm</a>, который предоставляет возможность асинхронного чтения и копирования файлов.</li> + <li>Никогда не работайте с базами данных SQLite синхронно. Вместо этого используйте <a href="/en-US/Storage#Asynchronously">асинхронный API</a>.</li> + <li>Выполняясь одна за другой, асинхронные операции зачастую можно значительно упростить, используя объект <a href="/en-US/Add-ons/Techniques/Promises">Promises</a>.</li> +</ul> + +<h3 id="Избегайте_событий_перемещения_мыши">Избегайте событий перемещения мыши</h3> + +<p>Избегайте использования обработчиков событий мыши, включая такие события, как mouseover, mouseout, mouseenter, mouseexit, и особенно mousemove. Они возникают довольно часто, поэтому их обработчики способны в значительной мере повысить нагрузку на процессор.</p> + +<p>Когда без них обойтись не получается, во время обработки события должен выполняться минимум вычислений, а существенная работа приостановлена. Обработчики должны добавляться к наиболее вероятному элементу, и удаляться, если непосредственно не требуются в данный момент.</p> + +<h3 id="Избегайте_анимированных_изображений">Избегайте анимированных изображений</h3> + +<p>Анимированные изображения значительно более ресурсозатратны, чем считалось ранее, особенно когда используются в элементах {{ XULElem("tree") }}.</p> + +<h3 id="Рассмотрите_возможность_применения_Chrome_Workers">Рассмотрите возможность применения Chrome Workers</h3> + +<p>Вы можете использовать {{ domxref("ChromeWorker") }} для выполнения длительных задач или обработки данных.</p> + +<h2 id="Смотрите_также">Смотрите также</h2> + +<ul> + <li><a href="/en/Performance/Measuring_add-on_startup_performance" title="en/Measuring Add-on Startup Performance">Измерение скорости запуска дополнения</a></li> + <li><a class="external" href="http://blog.mozilla.com/addons/2010/06/14/improve-extension-startup-performance/" title="http://blog.mozilla.com/addons/2010/06/14/improve-extension-startup-performance/">How to Improve Extension Startup Performance</a></li> + <li><a href="/en-US/docs/Performance">Общая информация об измерении и повышении производительности</a></li> +</ul> |