{"id":346315,"date":"2023-03-06T09:01:28","date_gmt":"2023-03-06T09:01:28","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=346315"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=346315","title":{"rendered":"<span>\u0420\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043d\u043e\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 \u043b\u0435\u0433\u043a\u0438\u043c \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0435\u043c \u0440\u0443\u043a\u0438<\/span>"},"content":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-1\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/mk\/0e\/mf\/mk0emfkez9es5uyh-ahvqmucgdw.png\" data-src=\"https:\/\/habrastorage.org\/webt\/mk\/0e\/mf\/mk0emfkez9es5uyh-ahvqmucgdw.png\"\/>  <\/p>\n<p>  Hello, world!<\/p>\n<p>  <\/p>\n<p>\u0412 \u044d\u0442\u043e\u043c \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u043c \u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b\u0435 \u043c\u044b \u0441 \u0432\u0430\u043c\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u043e\u0435, \u043d\u043e \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <a href=\"https:\/\/www.plasmo.com\/\">Plasmo<\/a>.<\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u0448\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u043e\u0431\u043e\u0439 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0439 \u0441\u043e\u0447\u0435\u0442\u0430\u043d\u0438\u0435\u043c \u043a\u043b\u0430\u0432\u0438\u0448 \u043f\u043e\u043f\u0430\u043f \u0441 \u0438\u043d\u043f\u0443\u0442\u043e\u043c \u0434\u043b\u044f \u043f\u043e\u0438\u0441\u043a\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043d\u0430 <a href=\"https:\/\/developer.mozilla.org\/en-US\/\">MDN<\/a> \u0441 \u0432\u044b\u0432\u043e\u0434\u043e\u043c 5 \u043b\u0443\u0447\u0448\u0438\u0445 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u0432 \u0432\u0438\u0434\u0435 \u0441\u043f\u0438\u0441\u043a\u0430. \u041a\u0440\u043e\u043c\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430, \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u0434\u043b\u044f \u043a\u0430\u0441\u0442\u043e\u043c\u0438\u0437\u0430\u0446\u0438\u0438 \u0446\u0432\u0435\u0442\u043e\u0432 \u0438 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0445\u043b\u0435\u0431\u043d\u044b\u0445 \u043a\u0440\u043e\u0448\u0435\u043a. \u041c\u044b \u0431\u0443\u0434\u0435\u043c \u0440\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f \u0434\u043b\u044f Chrome, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0442\u0430\u043a\u0436\u0435 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0432 Firefox.<\/p>\n<p>  <\/p>\n<p>\u0412\u043e\u0442 \u043a\u0430\u043a \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/2b\/22\/wn\/2b22wndyxvqm1_axjfttw0c-hlg.png\" data-src=\"https:\/\/habrastorage.org\/webt\/2b\/22\/wn\/2b22wndyxvqm1_axjfttw0c-hlg.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0442\u0435\u0445, \u043a\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u043e\u0434, \u0432\u043e\u0442 <a href=\"https:\/\/github.com\/harryheman\/Blog-Posts\/tree\/master\/mdn-finder\">\u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439<\/a>.<\/p>\n<p>  <\/p>\n<p>\u0418\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e? \u0422\u043e\u0433\u0434\u0430 \u043f\u0440\u043e\u0448\u0443 \u043f\u043e\u0434 \u043a\u0430\u0442.<\/p>\n<p><a name=\"habracut\"><\/a>  <\/p>\n<h2 id=\"osnovnoy-funkcional---popap-s-poiskom\">\u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u2014 \u043f\u043e\u043f\u0430\u043f \u0441 \u043f\u043e\u0438\u0441\u043a\u043e\u043c<\/h2>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044f\u043c\u0438 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f <a href=\"https:\/\/yarnpkg.com\/\">Yarn<\/a>.<\/p>\n<p>  <\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0448\u0430\u0431\u043b\u043e\u043d \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f:<\/p>\n<p>  <\/p>\n<pre><code class=\"bash\"># mdn-finder - \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\/\u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f yarn create plasmo mdn-finder<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u0443\u044e \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e \u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438:<\/p>\n<p>  <\/p>\n<pre><code class=\"bash\">cd mdn-finder  yarn<\/code><\/pre>\n<p>  <\/p>\n<p>\u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u043e\u0438\u0441\u043a\u0430:<\/p>\n<p>  <\/p>\n<pre><code class=\"bash\">yarn add @plasmohq\/storage downshift flexsearch fzf swr<\/code><\/pre>\n<p>  <\/p>\n<ul>\n<li><a href=\"https:\/\/github.com\/PlasmoHQ\/storage\">@plasmohq\/storage<\/a> \u2014 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u044f \u043d\u0430\u0434 <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Storage_API\">Storage API<\/a>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f\u043c\u0438 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430 \u0434\u043b\u044f \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445;<\/li>\n<li><a href=\"https:\/\/www.downshift-js.com\/\">downshift<\/a> \u2014 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0430\u044f \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u044b \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043f\u0440\u043e\u0441\u0442\u044b\u0445, \u0433\u0438\u0431\u043a\u0438\u0445, \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0449\u0438\u0445 \u0432\u0441\u0435\u043c \u043a\u0440\u0438\u0442\u0435\u0440\u0438\u044f\u043c WAI-ARIA React-\u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 autocomplete\/combobox \u0438\u043b\u0438 select\/dropdown;<\/li>\n<li><a href=\"https:\/\/github.com\/nextapps-de\/flexsearch\">flexsearch<\/a> \u2014 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u043e\u043b\u043d\u043e\u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u0438\u0441\u043a\u0430;<\/li>\n<li><a href=\"https:\/\/github.com\/ajitid\/fzf-for-js\">fzf<\/a> \u2014 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043d\u0435\u0442\u043e\u0447\u043d\u043e\u0433\u043e (fuzzy) \u043f\u043e\u0438\u0441\u043a\u0430;<\/li>\n<li><a href=\"https:\/\/swr.vercel.app\/ru\">swr<\/a> \u2014 \u0445\u0443\u043a\u0438 React \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f, \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u043c\u0443\u0442\u0430\u0446\u0438\u0438 \u0434\u0430\u043d\u043d\u044b\u0445.<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0431\u0443\u0434\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">- assets   - icon.png   - search-index.json   - search.png - src   - components     - Search.tsx   - search     - fuzzy-search.ts     - search-utils.ts     - search.tsx   - background.ts   - options.tsx   - popup.tsx   - storage.ts   - style.css   - ...<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0430 \u0444\u0430\u0439\u043b\u043e\u0432 \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e <code>src<\/code>, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043e\u0442\u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0444\u0430\u0439\u043b <code>tsconfig.json<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"json\">{   \/\/ ...   \"compilerOptions\": {     \"baseUrl\": \".\",     \"paths\": {       \"~*\": [         \".\/src\/*\"       ]     }   } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041e \u0441\u0430\u043c\u043e\u043c \u043f\u043e\u0438\u0441\u043a\u0435 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u043b \u0432 <a href=\"https:\/\/habr.com\/ru\/company\/timeweb\/blog\/585910\/\">\u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435<\/a>, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b\u0435 \u043c\u044b \u0441\u043e\u0441\u0440\u0435\u0434\u043e\u0442\u043e\u0447\u0438\u043c\u0441\u044f \u043d\u0430 Plasmo. \u0421\u043a\u043e\u043f\u0438\u0440\u0443\u0439\u0442\u0435 \u0444\u0430\u0439\u043b\u044b \u0438\u0437 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0439 <code>components<\/code>, <code>search<\/code> \u0438 <code>assets<\/code>, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0444\u0430\u0439\u043b <code>style.css<\/code> \u0438\u0437 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430. \u041f\u043e\u0438\u0441\u043a\u043e\u0432\u044b\u0439 \u0438\u043d\u0434\u0435\u043a\u0441 (<code>search-index.json<\/code>), \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441 <a href=\"https:\/\/developer.mozilla.org\/en-US\/search-index.json\">MDN<\/a>. \u0417\u0430\u043f\u0440\u043e\u0441\u044b \u043a MDN \u0438\u0437 \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430 \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u044e\u0442\u0441\u044f <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTTP\/CORS\">CORS<\/a>, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u043e\u0438\u0441\u043a\u043e\u0432\u044b\u0439 \u0438\u043d\u0434\u0435\u043a\u0441 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e.<\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0438\u043c\u0435\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u043f\u043e\u0438\u0441\u043a\u043e\u0432\u044b\u043c \u0438\u043d\u0434\u0435\u043a\u0441\u043e\u043c, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043e\u0442\u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0444\u0430\u0439\u043b <code>package.json<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"json\">{   \/\/ ...   \"manifest\": {     \"web_accessible_resources\": [       {         \"resources\": [           \"assets\/search-index.json\"         ],         \"matches\": [           \"https:\/\/*\/*\"         ]       }     ],     \"host_permissions\": [       \"https:\/\/*\/*\"     ]   } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0422\u043e\u0447\u043a\u043e\u0439 \u0432\u0445\u043e\u0434\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f Plasmo \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0444\u0430\u0439\u043b <code>popup.tsx<\/code>. \u041a\u0430\u043a \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0438\u0437 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f, \u044d\u0442\u043e\u0442 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u043f\u043e\u043f\u0430\u043f\u0430, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0431\u0443\u0434\u0435\u0442 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0438\u043d\u043f\u0443\u0442 \u0434\u043b\u044f \u043f\u043e\u0438\u0441\u043a\u0430. \u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0443\u0435\u043c \u044d\u0442\u043e\u0442 \u0444\u0430\u0439\u043b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">import Search from '.\/components\/Search' import '.\/style.css'  function IndexPopup() {   return &lt;Search preload={true} \/> }  export default IndexPopup<\/code><\/pre>\n<p>  <\/p>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0441\u0435\u0440\u0432\u0435\u0440 \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u043c\u0430\u043d\u0434\u044b <code>yarn dev<\/code>. \u0412\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u044d\u0442\u043e\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 <code>build\/chrome-mv3-dev<\/code> \u0441 \u0444\u0430\u0439\u043b\u0430\u043c\u0438 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<p>\u041f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043f\u043e \u0430\u0434\u0440\u0435\u0441\u0443 <code>chrome:\/\/extensions\/<\/code> \u0438 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440 (\u043a\u043d\u043e\u043f\u043a\u0430 &#171;\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435&#187;\/&#187;Load unpacked extension&#187;):<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/rk\/dj\/61\/rkdj61shaakmqltsfl_xnd09_2i.png\" data-src=\"https:\/\/habrastorage.org\/webt\/rk\/dj\/61\/rkdj61shaakmqltsfl_xnd09_2i.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<p>\u0412 \u0440\u0435\u0436\u0438\u043c\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435, \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u043e\u0435 \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440, \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u0444\u0430\u0439\u043b\u043e\u0432.<\/p>\n<p>  <\/p>\n<p>\u0421\u043e\u0447\u0435\u0442\u0430\u043d\u0438\u0435 \u043a\u043b\u0430\u0432\u0438\u0448 \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u043d\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 <code>chrome:\/\/extensions\/shortcuts<\/code>:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/nu\/m9\/r4\/num9r47zvohex0x5po872p3kf-q.png\" data-src=\"https:\/\/habrastorage.org\/webt\/nu\/m9\/r4\/num9r47zvohex0x5po872p3kf-q.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u0441\u0431\u043e\u0440\u043a\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u0443 <code>yarn build<\/code>. \u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u0441\u0431\u043e\u0440\u043a\u0430 \u0434\u043b\u044f Chrome. \u0412 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u0435 \u0432\u0440\u0435\u043c\u044f Plasmo \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u0431\u043e\u0440\u043e\u043a \u0434\u043b\u044f Firefox. \u041a\u043e\u043c\u0430\u043d\u0434\u0430 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0442\u0430\u043a\u043e\u0439 \u0441\u0431\u043e\u0440\u043a\u0438: <code>yarn build --target=firefox-mv2<\/code>. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043f\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u043e\u0431 \u044d\u0442\u043e\u043c \u043c\u043e\u0436\u043d\u043e <a href=\"https:\/\/docs.plasmo.com\/framework\/workflows\/build\">\u0437\u0434\u0435\u0441\u044c<\/a>.<\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f \u0432 Firefox \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c 2 \u0432\u0435\u0449\u0438:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 <code>src<\/code> \u0444\u0430\u0439\u043b <code>background.ts<\/code> \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u044f:<\/li>\n<\/ul>\n<p>  <\/p>\n<pre><code class=\"javascript\">export {}<\/code><\/pre>\n<p>  <\/p>\n<p>\u042d\u0442\u043e\u0442 \u0444\u0430\u0439\u043b \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432, \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0449\u0438\u0445 \u0437\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0444\u043e\u043d\u043e\u0432\u044b\u0445 \u0437\u0430\u0434\u0430\u0447. \u041a \u0442\u0430\u043a\u0438\u043c \u0441\u043a\u0440\u0438\u043f\u0442\u0430\u043c \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0441\u044f, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043b\u043e\u0433\u0438\u043a\u0430 <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Service_Worker_API\">\u0441\u0435\u0440\u0432\u0438\u0441-\u0432\u043e\u0440\u043a\u0435\u0440\u0430<\/a>. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043f\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u043e\u0431 \u044d\u0442\u043e\u043c \u043c\u043e\u0436\u043d\u043e <a href=\"https:\/\/docs.plasmo.com\/framework\/background-service-worker\">\u0437\u0434\u0435\u0441\u044c<\/a>. \u041f\u043e\u0447\u0435\u043c\u0443-\u0442\u043e \u0431\u0435\u0437 \u044d\u0442\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 \u0432 Firefox \u043d\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f.<\/p>\n<p>  <\/p>\n<ul>\n<li>\u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u0443\u044e \u0441\u0431\u043e\u0440\u043a\u0443 \u0432 \u0432\u0438\u0434\u0435 \u0430\u0440\u0445\u0438\u0432\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u043c\u0430\u043d\u0434\u044b <code>yarn build --target=firefox-mv2 --zip<\/code>.<\/li>\n<\/ul>\n<p>  <\/p>\n<h2 id=\"dopolnitelnyy-funkcional---stranica-nastroek\">\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u2014 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a<\/h2>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0444\u0430\u0439\u043b <code>options.tsx<\/code> \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 <code>src<\/code>.<\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0438\u043c \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c \u043e\u0431\u043c\u0435\u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u043c\u0435\u0436\u0434\u0443 \u043f\u043e\u043f\u0430\u043f\u043e\u043c \u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a (\u0430 \u0442\u0430\u043a\u0436\u0435 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u0441\u043a\u0440\u0438\u043f\u0442\u0430\u043c\u0438) \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c\u043e\u0433\u043e Plasmo <a href=\"https:\/\/docs.plasmo.com\/framework\/storage\">\u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430<\/a>.<\/p>\n<p>  <\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 <code>src<\/code> \u0444\u0430\u0439\u043b <code>storage.ts<\/code> \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u044f:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">import { Storage } from '@plasmohq\/storage'  \/\/ \u043a\u043b\u044e\u0447 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a export const OPTIONS_KEY = 'mdn_finder_options'  \/\/ \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u044b\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 export const defaultOptions = {   \/\/ \u0446\u0432\u0435\u0442 \u0444\u043e\u043d\u0430   backgroundColor: '#282c34',   \/\/ \u0446\u0432\u0435\u0442 \u0442\u0435\u043a\u0441\u0442\u0430   textColor: '#f7f7f7',   \/\/ \u0444\u043e\u043d \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u044f   selectionBackground: '#5cb85c',   \/\/ \u0446\u0432\u0435\u0442 \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u044f   selectionColor: '#282c34',   \/\/ \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0445\u043b\u0435\u0431\u043d\u044b\u0445 \u043a\u0440\u043e\u0448\u0435\u043a \u0432 \u0441\u043f\u0438\u0441\u043a\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u043f\u043e\u0438\u0441\u043a\u0430   showUrl: true }  \/\/ \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 const storage = new Storage()  \/\/ \u0438 \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0435\u0433\u043e export default storage<\/code><\/pre>\n<p>  <\/p>\n<p>\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0443\u0435\u043c \u0444\u0430\u0439\u043b <code>options.tsx<\/code> \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">import { useRef } from 'react' import storage, { defaultOptions, OPTIONS_KEY } from '~storage' import '.\/style.css'  export default function IndexOptions() {   \/\/ \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0444\u043e\u0440\u043c\u044b   const btnRef = useRef&lt;HTMLButtonElement | null>(null)    \/\/ \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0444\u043e\u0440\u043c\u044b   const onSubmit: React.FormEventHandler = async (e) => {     e.preventDefault()      \/\/ \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u0444\u043e\u0440\u043c\u044b \u0432 \u0432\u0438\u0434\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0430     const formData = Object.fromEntries(       new FormData(e.target as HTMLFormElement).entries(),     )      try {       \/\/ \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0432 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435       await storage.set(OPTIONS_KEY, formData)        \/\/ \u043c\u0435\u043d\u044f\u0435\u043c \u0442\u0435\u043a\u0441\u0442 \u043a\u043d\u043e\u043f\u043a\u0438       if (btnRef.current) {         btnRef.current.textContent = 'Saved'          const id = setTimeout(() => {           btnRef.current.textContent = 'Save'           clearTimeout(id)         }, 1000)       }     } catch (e) {       console.log(e)     }   }    return (     &lt;form className='options' onSubmit={onSubmit}>       &lt;label>         Background color:{' '}         &lt;input           type='color'           name='backgroundColor'           defaultValue={defaultOptions.backgroundColor}         \/>       &lt;\/label>       &lt;label>         Result item color:{' '}         &lt;input           type='color'           name='textColor'           defaultValue={defaultOptions.textColor}         \/>       &lt;\/label>       &lt;label>         Selection background:{' '}         &lt;input           type='color'           name='selectionBackground'           defaultValue={defaultOptions.selectionBackground}         \/>       &lt;\/label>       &lt;label>         Selection color:{' '}         &lt;input           type='color'           name='selectionColor'           defaultValue={defaultOptions.selectionColor}         \/>       &lt;\/label>       &lt;label>         Show URL:{' '}         &lt;input           type='checkbox'           name='showUrl'           defaultChecked={defaultOptions.showUrl}         \/>       &lt;\/label>       &lt;button ref={btnRef}>Save&lt;\/button>     &lt;\/form>   ) }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043f\u0430\u0441\u0442\u044c \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043a\u043b\u0438\u043a\u043d\u0443\u0442\u044c \u043f\u043e \u0438\u043a\u043e\u043d\u043a\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f \u0438 \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u043f\u0443\u043d\u043a\u0442 &#171;\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b&#187;\/&#187;Options&#187;:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/y0\/jd\/x3\/y0jdx3c7reh2pb5epfzefwbuhrm.png\" data-src=\"https:\/\/habrastorage.org\/webt\/y0\/jd\/x3\/y0jdx3c7reh2pb5epfzefwbuhrm.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/t9\/lc\/ol\/t9lcolgtrtfxdfgglyy0i6eq6py.png\" data-src=\"https:\/\/habrastorage.org\/webt\/t9\/lc\/ol\/t9lcolgtrtfxdfgglyy0i6eq6py.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<p>\u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u0441\u044f \u043a \u043f\u043e\u043f\u0430\u043f\u0443. \u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0443\u0435\u043c \u0444\u0430\u0439\u043b <code>search\/search.tsx<\/code>. \u0418\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u0438 \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u043c \u0438\u0437 \u043d\u0435\u0433\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">import storage, { defaultOptions, OPTIONS_KEY } from '~storage'  \/\/ ...  function InnerSearchNavigateWidget(props: InnerSearchNavigateWidgetProps) {   \/\/ ...   const [options, setOptions] = useState(defaultOptions)    \/\/ ...   useEffect(() => {     storage.get&lt;typeof options>(OPTIONS_KEY).then((opts) => {       if (opts) {         setOptions(opts)       }     })   }, [])    \/\/ \u0434\u0430\u043b\u0435\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u0441 \u044d\u0442\u0438\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u043c }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0418\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0445\u043b\u0435\u0431\u043d\u044b\u0445 \u043a\u0440\u043e\u0448\u0435\u043a (<code>options.showUrl<\/code>) \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 \u0441\u043f\u0438\u0441\u043a\u0430 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u043f\u043e\u0438\u0441\u043a\u0430:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">resultItems.map((item, i) => (   &lt;div     {...getItemProps({       key: item.url,       className:         'result-item ' + (i === highlightedIndex ? 'highlight' : ''),       item,       index: i,     })}   >     &lt;HighlightMatch title={item.title} q={inputValue} \/>     {\/* ! *\/}     {Boolean(options.showUrl) ? (       &lt;>         &lt;br \/>         &lt;BreadcrumbURI uri={item.url} positions={item.positions} \/>       &lt;\/>     ) : null}   &lt;\/div> ))<\/code><\/pre>\n<p>  <\/p>\n<p>\u0426\u0432\u0435\u0442 \u0444\u043e\u043d\u0430 (<code>options.backgroundColor<\/code>) \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0443 \u0444\u043e\u0440\u043c\u044b:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">&lt;form   \/\/ ...   style={     {       '--background-color': options.backgroundColor,     } as React.CSSProperties   } >   {\/* ... *\/} &lt;\/form><\/code><\/pre>\n<p>  <\/p>\n<p>\u0412 \u0444\u0430\u0439\u043b\u0435 <code>style.css<\/code> \u0443 \u043d\u0430\u0441 \u0438\u043c\u0435\u044e\u0442\u0441\u044f \u0442\u0430\u043a\u0438\u0435 \u0441\u0442\u0440\u043e\u043a\u0438:<\/p>\n<p>  <\/p>\n<pre><code class=\"css\">.search-form {   --background-color: var(--dark);    \/* ... *\/   background-color: var(--background-color); }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u0446\u0432\u0435\u0442\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0443 \u0441 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430\u043c\u0438 \u043f\u043e\u0438\u0441\u043a\u0430:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">&lt;div   className='search-results'   style={     {       '--text-color': options.textColor,       '--selection-background': options.selectionBackground,       '--selection-color': options.selectionColor,     } as React.CSSProperties   } >   {searchResults} &lt;\/div><\/code><\/pre>\n<p>  <\/p>\n<p>\u0412 <code>style.css<\/code> \u0443 \u043d\u0430\u0441 \u0438\u043c\u0435\u044e\u0442\u0441\u044f \u0442\u0430\u043a\u0438\u0435 \u0441\u0442\u0440\u043e\u043a\u0438:<\/p>\n<p>  <\/p>\n<pre><code class=\"css\">.search-results {   --text-color: var(--light);   --selection-background: var(--success);   --selection-color: var(--dark); }  .result-item span, .result-item small {   color: var(--text-color); }  .result-item mark {   background-color: var(--selection-background);   color: var(--selection-color); }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0421\u043f\u0430\u0441\u0438\u0431\u043e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u043c CSS \u0437\u0430 \u0438\u0445 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u043d\u043e\u0441\u0442\u044c \ud83d\ude42<\/p>\n<p>  <\/p>\n<p>\u041c\u0435\u043d\u044f\u0435\u043c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/kp\/qy\/cx\/kpqycx4aarajdpf7yy5dlxvuphk.png\" data-src=\"https:\/\/habrastorage.org\/webt\/kp\/qy\/cx\/kpqycx4aarajdpf7yy5dlxvuphk.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/aa\/qc\/lz\/aaqclzqzkyswknzlde70pav7h5u.png\" data-src=\"https:\/\/habrastorage.org\/webt\/aa\/qc\/lz\/aaqclzqzkyswknzlde70pav7h5u.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<p>\u0412\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0431\u043b\u0430\u0433\u043e\u043f\u043e\u043b\u0443\u0447\u043d\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f \u043a \u043f\u043e\u043f\u0430\u043f\u0443.<\/p>\n<p>  <\/p>\n<p>\u0421\u043b\u0435\u0434\u0443\u0435\u0442 \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u043f\u0440\u043e\u0435\u043a\u0442, \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0439 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Plasmo CLI, \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0432 \u0441\u0435\u0431\u044f GitHub Action <a href=\"https:\/\/github.com\/marketplace\/actions\/browser-platform-publisher\">Browser Platform Publisher<\/a> \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f \u0432\u043e \u0432\u0441\u0435\u0445 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u044b\u0445 \u0441\u0442\u043e\u0440\u0430\u0445. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043f\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u043e\u0431 \u044d\u0442\u043e\u043c \u043c\u043e\u0436\u043d\u043e <a href=\"https:\/\/docs.plasmo.com\/framework\/workflows\/submit\">\u0437\u0434\u0435\u0441\u044c<\/a>. \u0421\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u0444\u0430\u0439\u043b \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 <code>.github\/workflows<\/code>.<\/p>\n<p>  <\/p>\n<p>\u041a \u0441\u043b\u043e\u0432\u0443, \u043f\u043e\u0438\u0441\u043a\u043e\u0432\u044b\u0439 \u0438\u043d\u0434\u0435\u043a\u0441 \u0441\u043e \u0441\u0442\u0430\u0442\u044c\u044f\u043c\u0438 \u043d\u0430 \u0440\u0443\u0441\u0441\u043a\u043e\u043c \u044f\u0437\u044b\u043a\u0435 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 <a href=\"https:\/\/developer.mozilla.org\/ru\/search-index.json\">\u0437\u0434\u0435\u0441\u044c<\/a>.<\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u0434\u0435\u044e\u0441\u044c, \u0432\u044b \u0443\u0437\u043d\u0430\u043b\u0438 \u0447\u0442\u043e-\u0442\u043e \u043d\u043e\u0432\u043e\u0435 \u0438 \u043d\u0435 \u0437\u0440\u044f \u043f\u043e\u0442\u0440\u0430\u0442\u0438\u043b\u0438 \u0432\u0440\u0435\u043c\u044f.<\/p>\n<p>  <\/p>\n<p>Happy coding!<\/p>\n<p>  <\/p>\n<hr\/>\n<\/div>\n<\/div>\n<\/div>\n<p> <!----> <!----><\/div>\n<p> <!----> <!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/company\/timeweb\/blog\/720646\/\"> https:\/\/habr.com\/ru\/company\/timeweb\/blog\/720646\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-1\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/mk\/0e\/mf\/mk0emfkez9es5uyh-ahvqmucgdw.png\" data-src=\"https:\/\/habrastorage.org\/webt\/mk\/0e\/mf\/mk0emfkez9es5uyh-ahvqmucgdw.png\"\/>  <\/p>\n<p>  Hello, world!<\/p>\n<p>  <\/p>\n<p>\u0412 \u044d\u0442\u043e\u043c \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u043c \u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b\u0435 \u043c\u044b \u0441 \u0432\u0430\u043c\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u043e\u0435, \u043d\u043e \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <a href=\"https:\/\/www.plasmo.com\/\">Plasmo<\/a>.<\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u0448\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u043e\u0431\u043e\u0439 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0439 \u0441\u043e\u0447\u0435\u0442\u0430\u043d\u0438\u0435\u043c \u043a\u043b\u0430\u0432\u0438\u0448 \u043f\u043e\u043f\u0430\u043f \u0441 \u0438\u043d\u043f\u0443\u0442\u043e\u043c \u0434\u043b\u044f \u043f\u043e\u0438\u0441\u043a\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043d\u0430 <a href=\"https:\/\/developer.mozilla.org\/en-US\/\">MDN<\/a> \u0441 \u0432\u044b\u0432\u043e\u0434\u043e\u043c 5 \u043b\u0443\u0447\u0448\u0438\u0445 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u0432 \u0432\u0438\u0434\u0435 \u0441\u043f\u0438\u0441\u043a\u0430. \u041a\u0440\u043e\u043c\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430, \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u0434\u043b\u044f \u043a\u0430\u0441\u0442\u043e\u043c\u0438\u0437\u0430\u0446\u0438\u0438 \u0446\u0432\u0435\u0442\u043e\u0432 \u0438 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0445\u043b\u0435\u0431\u043d\u044b\u0445 \u043a\u0440\u043e\u0448\u0435\u043a. \u041c\u044b \u0431\u0443\u0434\u0435\u043c \u0440\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f \u0434\u043b\u044f Chrome, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0442\u0430\u043a\u0436\u0435 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0432 Firefox.<\/p>\n<p>  <\/p>\n<p>\u0412\u043e\u0442 \u043a\u0430\u043a \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/2b\/22\/wn\/2b22wndyxvqm1_axjfttw0c-hlg.png\" data-src=\"https:\/\/habrastorage.org\/webt\/2b\/22\/wn\/2b22wndyxvqm1_axjfttw0c-hlg.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0442\u0435\u0445, \u043a\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u043e\u0434, \u0432\u043e\u0442 <a href=\"https:\/\/github.com\/harryheman\/Blog-Posts\/tree\/master\/mdn-finder\">\u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439<\/a>.<\/p>\n<p>  <\/p>\n<p>\u0418\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e? \u0422\u043e\u0433\u0434\u0430 \u043f\u0440\u043e\u0448\u0443 \u043f\u043e\u0434 \u043a\u0430\u0442.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-346315","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/346315","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=346315"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/346315\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=346315"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=346315"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=346315"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}