WebCompords рдЪреМрдЦрдЯреЗ, рдШрдЯрдХ рдмрд╛рддрдЪреАрдд рдХреЗ рд░реВрдк рдореЗрдВ

рдЬрдм рд╡реЗрдм рдШрдЯрдХреЛрдВ рдХреА рдмрд╛рдд рдЖрддреА рд╣реИ, рддреЛ рд╡реЗ рдЕрдХреНрд╕рд░ рдХрд╣рддреЗ рд╣реИрдВ: "рдЖрдк рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЗ рдмрд┐рдирд╛ рдХреНрдпрд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ? рд╡рд╣рд╛рдВ рд╕рдм рдХреБрдЫ рддреИрдпрд╛рд░ рд╣реИред тАЭ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рд╡реЗрдм рдШрдЯрдХреЛрдВ рдХреЗ рд╕рдореВрд╣ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рдорд╛рдирдХреЛрдВ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд░реВрдкрд░реЗрдЦрд╛ рддреИрдпрд╛рд░ рдХреА рдЬрд╛рддреА рд╣реИред рдПрдХреНрд╕-рдЯреИрдЧ рдХреА рддрд░рд╣ рдЕрдкреЗрдХреНрд╖рд╛рдХреГрдд рдЕрдЪреНрдЫреЗ рднреА рд╣реИрдВред рд▓реЗрдХрд┐рди рдЖрдЬ, рд╣рдо рдЕрднреА рднреА рд╕рдордЭрддреЗ рд╣реИрдВ рдХрд┐ рдмреНрд░рд╛рдЙрдЬрд╝рд░ API рд░реЛрдЬрдорд░реНрд░рд╛ рдХреЗ рд╡рд┐рдХрд╛рд╕ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рддрдирд╛ рд╕рд░рд▓, рд╕реБрд░реБрдЪрд┐рдкреВрд░реНрдг рдФрд░ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рд╕рдВрджрд░реНрдн рд╕реЗ рдПрдХ рджреВрд╕рд░реЗ рдХреЗ рд╕рд╛рде рдФрд░ рдЕрдиреНрдп рд╡рд╕реНрддреБрдУрдВ рдХреЗ рд╕рд╛рде рдШрдЯрдХреЛрдВ рдХреА рдмрд╛рддрдЪреАрдд рдХрд╛ рдЖрдпреЛрдЬрди рдХрд░рдирд╛ рд╢рд╛рдорд┐рд▓ рд╣реИ, рдФрд░ рдЖрдк рд╣рдореЗрд╢рд╛ рд╡реЗрдм рдШрдЯрдХреЛрдВ рдХреЗ рд╕рд╛рде рднреА рдлреНрд░реЗрдорд╡рд░реНрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдЙрди рдорд╛рдирдХреЛрдВ рдХреЗ рд╕рд╛рде рд╡рд┐рдХрд╕рд┐рдд рдХрд┐рдП рдЧрдП рдереЗ, рдЬрд┐рдирдореЗрдВ рддрдВрддреНрд░ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╢рд╛рдорд┐рд▓ рдереЗ рдЬреЛ рдЖрдЬ рд╣рдо рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░реЗрдВрдЧреЗ, рдХрдо рд╕реЗ рдХрдо рд╕рд╛рдЗрдЯ рдкрд░ рдХрд╣рд╛ рдЧрдпрд╛ рд╣реИ ред

рдПрдХ рдЕрднрд┐рдХрд░реНрдордХ рдЬреИрд╕реЗ рдирд┐рд░реНрдгрдп рд╣рдореЗрдВ рд╕рд┐рдЦрд╛рддреЗ рд╣реИрдВ рдХрд┐ рдПрдХ рдмрдбрд╝рд╛ рдбреЗрдЯрд╛ рдкрдХреНрд╖ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдФрд░ рдЗрд╕рдХреЗ рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЗ рд▓рд┐рдП рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдХрд┐рдП рдЧрдП рдШрдЯрдХ рд╣реЛрдиреЗ рдЪрд╛рд╣рд┐рдП, рдФрд░ рд╡реЗрдм рдШрдЯрдХреЛрдВ рдореЗрдВ рд╡реЗ рдЗрд╕ рддрд░рд╣ рдХреЗ рдПрдХ рдЙрдкрддрдВрддреНрд░ рдХреА рдЕрдиреБрдкрд╕реНрдерд┐рддрд┐ рдХреЛ рд╕рдордЭрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдЕрдирдЬрд╛рдиреЗ рдореЗрдВ рд░рд┐рд╡рд░реНрд╕ рдмрдВрдзрди рднреА рд▓рдЧрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рдпрд╣ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╡реЗрдм рдШрдЯрдХреЛрдВ рдореЗрдВ рдореМрдЬреВрдж рд╣реИред

рдкреНрд░рддреНрдпреЗрдХ рддрддреНрд╡ рдХреЗ рдореВрд▓реНрдп рдХреЗ рдЧреБрдг рд╣реИрдВ, рдЬрд┐рдиреНрд╣реЗрдВ рд╣рдо рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВред рдФрд░ рдпрджрд┐ рдЖрдк рдЖрдмреНрдЬрд░реНрд╡реЗрдЯ рдХрд┐рдП рдЧрдП рд╣реБрдХ рдореЗрдВ рдирд╛рдореЛрдВ рдХреЛ рд╕реВрдЪреАрдмрджреНрдз рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЬрдм рд╡реЗ рдмрджрд▓рддреЗ рд╣реИрдВ, рддреЛ рд╡рд┐рд╢реЗрд╖рддрд╛рдЪреИрд▓реНрдХреЙрд▓рдмреИрдХ () рдХреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдХреЙрд▓ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдЬрд┐рд╕рдореЗрдВ рд╣рдо рдШрдЯрдХ рдХреЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬрдм рд╡рд┐рд╢реЗрд╖рддрд╛ рдмрджрд▓ рдЬрд╛рддреА рд╣реИред рдЧреЗрдЯреНрдЯрд░ рдореИрдЬрд┐рдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛, рдПрдХ рд╕рдорд╛рди рддрд░реАрдХреЗ рд╕реЗ рд░рд┐рд╡рд░реНрд╕ рдмрд╛рдЗрдВрдбрд┐рдВрдЧ рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реИред

рд╣рдордиреЗ рдкрд╣рд▓реЗ рднрд╛рдЧ рдореЗрдВ рдХреБрдЫ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЛ рдкрд╣рд▓реЗ рд╣реА рд╕реНрдХреЗрдЪ рдХрд░ рд▓рд┐рдпрд╛ рдерд╛ рдФрд░ рдЖрдЬ рд╣рдо рдЗрд╕реЗ рдЖрдЧреЗ рднреА рдЬрд╛рд░реА рд░рдЦреЗрдВрдЧреЗред

рдпрд╣ рдПрдХ рд╕реАрдорд╛ рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдХрд░рддреЗ рд╣реБрдП, рдХрдо рд╕реЗ рдХрдо рд╡рд░реНрддрдорд╛рди рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ, рдпрд╣ рд╣реИ рдХрд┐ рд╡рд┐рд╢реЗрд╖рддрд╛ рдорд╛рди рдХреЗрд╡рд▓ рдПрдХ рдЖрджрд┐рдо рдореВрд▓реНрдп рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдЬреЛ рдПрдХ рд╢рд╛рдмреНрджрд┐рдХ рдФрд░ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЗ рд▓рд┐рдП reducible рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░ "objecs" рдХреЛ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдЯреНрд░рд╛рдВрд╕рдлрд░ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИ рдХрд┐ рдмрд╛рд╣рд░ рд╕реЗ рдПрдХрд▓ рдХреЛрдЯреНрд╕ рдФрд░ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдбрдмрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдПред рдорд╛рди рдФрд░ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рдХреНрд╖реЗрддреНрд░ред

<my-component my='{"foo": "bar"}'></my-component> 

рдХреЛрдб рдореЗрдВ рдЗрд╕ рдореВрд▓реНрдп рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдк рдПрдХ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдореИрдЬрд┐рдХ рдЧреЗрдЯреНрдЯрд░ рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рдЙрд╕ рдкрд░ JSON.parse () рдХреЛ рдХреЙрд▓ рдХрд░реЗрдЧрд╛ред

рд▓реЗрдХрд┐рди рдЕрднреА рдХреЗ рд▓рд┐рдП, рдХрд╛рдЙрдВрдЯрд░ рдХрд╛ рд╕рдВрдЦреНрдпрд╛рддреНрдордХ рдорд╛рди рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реИред

рд╣рдо рдЕрдкрдиреЗ рддрддреНрд╡ рдореЗрдВ рдПрдХ рдирдИ рд╡рд┐рд╢реЗрд╖рддрд╛ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ, рдЗрд╕реЗ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХреЗ рд░реВрдк рдореЗрдВ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддреЗ рд╣реИрдВ, рдЗрд╕ рдХрд╛рдЙрдВрдЯрд░ рдХреЛ рдмрдврд╝рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХреНрд▓рд┐рдХ рд╣реИрдВрдбрд▓рд░ рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░реЗрдВ, рдФрд░ рдкрд░рд┐рд╡рд░реНрддрди рд╣реБрдХ рд╕реЗ рд╕реАрдзреЗ рд▓рд┐рдВрдХ рджреНрд╡рд╛рд░рд╛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдореВрд▓реНрдп рдХрд╛ рдЕрджреНрдпрддрди рдЬреЛрдбрд╝реЗрдВ, рдЬреЛ рддрд░реНрдХ рдПрдХ рдЕрд▓рдЧ рдкреБрди: рдкреНрд░рдпреЛрдЬреНрдп рдЕрджреНрдпрддрди () рд╡рд┐рдзрд┐ рдореЗрдВ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред

 export class MyWebComp extends HTMLElement { constructor() { super(); } connectedCallback() { let html = document.importNode(myWebCompTemplate.content, true); this.attachShadow({mode: 'open'}); this.shadowRoot.appendChild(html); this.updateLabel(); } updateLabel() { this.shadowRoot.querySelector('#helloLabel').textContent = 'Hello ' + this.getAttribute('greet-name') + ' ' + this.getAttribute('count'); } static get observedAttributes() { return ['count']; } attributeChangedCallback(name, oldValue, newValue) { if (name === 'count') { this.updateLabel(); } } showMessage(event) { this.setAttribute('count', this.getAttribute('count') + 1); } } 



рдкреНрд░рддреНрдпреЗрдХ рдЖрдЗрдЯрдо рдХреЛ рдПрдХ рд╕реНрд╡рддрдВрддреНрд░, рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдЕрджреНрдпрддрди рдХрд╛рдЙрдВрдЯрд░ рдкреНрд░рд╛рдкреНрдд рд╣реБрдЖред

рд╣реЛрдорд╡рд░реНрдХ: рдПрдХ рдирдВрдмрд░ рдкрд░ рдХрд╛рдЙрдВрдЯрд░ рдХреЗ рд░реВрдкрд╛рдВрддрд░рдг рдХреЛ рд▓рд╛рдЧреВ рдХрд░реЗрдВ рдФрд░ рдСрдЯреЛ-рдЧреЗрдЯрд░ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ;)

рдмреЗрд╢рдХ, рдЕрдзрд┐рдХ рдЙрдиреНрдирдд рд╡рд┐рдХрд▓реНрдк рд╕рдВрднрд╡ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ рдЖрдк рд╕рд░рд▓ рдХреЙрд▓рдмреИрдХ рдФрд░ рдШрдЯрдирд╛рдУрдВ рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рдирд╣реАрдВ рд░рдЦрддреЗ рд╣реИрдВ, рддреЛ рджреЗрд╢реА рдкреНрд░реЙрдХреНрд╕реА рдФрд░ рд╕рдорд╛рди рдЧреЗрдЯрд░реНрд╕ рдФрд░ рд╕реЗрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ, рдЖрдк рд░рд┐рд╡рд░реНрд╕ рдмрд╛рдЗрдВрдбрд┐рдВрдЧ рдХреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдЗрд╕ рддрд░рд╣ рдХреЗ рдПрдХ рд╡рд░реНрдЧ рдХреЗ рд╕рд╛рде my-counter.js рдлрд╝рд╛рдЗрд▓ рдЬреЛрдбрд╝реЗрдВ

 export class MyCounter extends EventTarget { constructor() { super(); this.count = 0; } increment() { this.count++; this.dispatchEvent(new CustomEvent('countChanged', { detail: { count: this.count } })); } } 

рд╣рдореЗрдВ EventTarget рд╕реЗ рдПрдХ рд╡рд░реНрдЧ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓рд╛ рд╣реИ рддрд╛рдХрд┐ рдЕрдиреНрдп рд╡рд░реНрдЧ рдЗрд╕ рд╡рд░реНрдЧ рдХреА рд╡рд╕реНрддреБрдУрдВ рджреНрд╡рд╛рд░рд╛ рдлреЗрдВрдХреА рдЧрдИ рдШрдЯрдирд╛рдУрдВ рдХреА рд╕рджрд╕реНрдпрддрд╛ рд▓реЗ рд╕рдХреЗрдВ рдФрд░ рдПрдХ рдХрд╛рдЙрдВрдЯрд░ рдкреНрд░реЙрдкрд░реНрдЯреА рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░ рд╕рдХреЗрдВ рдЬреЛ рдХрд╛рдЙрдВрдЯрд░ рд╡реИрд▓реНрдпреВ рдХреЛ рд╕реНрдЯреЛрд░ рдХрд░реЗрдЧрд╛ред

рдЕрдм рдШрдЯрдХ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕реНрдерд┐рд░ рд╕рдВрдкрддреНрддрд┐ рдХреЗ рд░реВрдк рдореЗрдВ рдЗрд╕ рд╡рд░реНрдЧ рдХрд╛ рдЙрджрд╛рд╣рд░рдг рдЬреЛрдбрд╝реЗрдВред

 <script type="module"> import { MyWebComp } from "./my-webcomp.js"; import { MyCounter } from "./my-counter.js"; let counter = new MyCounter(); Object.defineProperty(MyWebComp.prototype, 'counter', { value: counter }); customElements.define('my-webcomp', MyWebComp); </script> 

рдФрд░ рдШрдЯрдХ рдХреЛрдб рдореЗрдВ, рд╣рдо рд╡реИрд▓реНрдпреВ рдЪреЗрдВрдЬ рдЕрдкрдбреЗрдЯрд▓реЗрдмреЗрд▓ () рд▓реЗрдмрд▓ рдЕрдкрдбреЗрдЯ рд╡рд┐рдзрд┐ рдХреА рд╕рджрд╕реНрдпрддрд╛ рд▓реЗрдВрдЧреЗ, рдЬрд┐рд╕рдореЗрдВ рд╣рдо рд╡реИрд╢реНрд╡рд┐рдХ рд╕рд╛рдЭрд╛ рдХрд╛рдЙрдВрдЯрд░ рд╕реЗ рдореВрд▓реНрдп рдкреНрд░рджрд░реНрд╢рди рдЬреЛрдбрд╝рддреЗ рд╣реИрдВред рдФрд░ рдХреНрд▓рд┐рдХ рд╣реИрдВрдбрд▓рд░ рдореЗрдВ, рд╡реГрджреНрдзрд┐рд╢реАрд▓ рд╡рд┐рдзрд┐ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕реАрдзрд╛ рдХреЙрд▓ред

 export class MyWebComp extends HTMLElement { constructor() { super(); } connectedCallback() { let html = document.importNode(myWebCompTemplate.content, true); this.attachShadow({mode: 'open'}); this.shadowRoot.appendChild(html); this.updateLabel(); this.counter.addEventListener('countChanged', this.updateLabel.bind(this)); } updateLabel() { this.shadowRoot.querySelector('#helloLabel').textContent = 'Hello ' + this.getAttribute('greet-name') + ' ' + this.getAttribute('count') + ' ' + this.counter.count; } static get observedAttributes() { return ['count']; } attributeChangedCallback(name, oldValue, newValue) { if (name === 'count') { if (this.shadowRoot) { this.updateLabel(); } } } showMessage(event) { this.setAttribute('count', parseInt(this.getAttribute('count')) + 1); this.counter.increment(); } } 

рдЗрд╕ рддрдереНрдп рдХреЗ рдмрд╛рд╡рдЬреВрдж рдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рддрддреНрд╡ рдХреЛ рджреЛ рдХрд╛рдЙрдВрдЯрд░ рдкреНрд░рд╛рдкреНрдд рд╣реБрдП, рдЗрд╕рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рдореВрд▓реНрдпреЛрдВ рдХреЛ рд╕реНрд╡рддрдВрддреНрд░ рд░реВрдк рд╕реЗ рдмрдврд╝рд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛, рд▓реЗрдХрд┐рди рд╕рд╛рдЭрд╛ рдХрд╛рдЙрдВрдЯрд░ рдХрд╛ рдореВрд▓реНрдп рджреЛрдиреЛрдВ рддрддреНрд╡реЛрдВ рдХреЗ рд▓рд┐рдП рд╕рдорд╛рди рд╣реЛрдЧрд╛, рдФрд░ рд╡реНрдпрдХреНрддрд┐рдЧрдд рдорд╛рди рдХреЗрд╡рд▓ рдЙрди рдкрд░ рдХреНрд▓рд┐рдХ рдХреА рд╕рдВрдЦреНрдпрд╛ рд╕реЗ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рд╣реЛрдВрдЧреЗред



рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╣рдореЗрдВ рдкреНрд░рддреНрдпрдХреНрд╖ рдмрдВрдзрди рдореЗрдВ рдкреНрд░рддреНрдпрдХреНрд╖ рдмрдВрдзрди рдорд┐рд▓рд╛, рдФрд░ рдШрдЯрдирд╛рдУрдВ рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЗ рдХрд╛рд░рдг, рдпрд╣ рдореВрд▓реНрдп рдЕрджреНрдпрддрди рдХрд░рдиреЗ рдореЗрдВ рдХрдордЬреЛрд░ рд╣реИред рдмреЗрд╢рдХ, рдХреБрдЫ рднреА рд╡реГрджреНрдзрд┐ рдХреЛ рдШрдЯрдирд╛рдУрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рд╣реЛрдиреЗ рд╕реЗ рдирд╣реАрдВ рд░реЛрдХрддрд╛ рд╣реИ, рд╡реГрджреНрдзрд┐ () рд╡рд┐рдзрд┐ рдХреЛ рдШрдЯрдирд╛ рдХреЗ рд▓реАрдЬрд╝рд░ рд╕реЗ рдмрд╛рдВрдзрдХрд░:

 export class MyCounter extends EventTarget { constructor() { super(); this.count = 0; this.addEventListener('increment', this.increment.bind(this)); } increment() { this.count++; this.dispatchEvent(new CustomEvent('countChanged', { detail: { count: this.count } })); } } 

рдФрд░ рдЗрд╡реЗрдВрдЯ рдереНрд░реЛ рдХреЗ рд╕рд╛рде рдореЗрдердб рдХреЙрд▓ рдХреЛ рдмрджрд▓рдирд╛:

 export class MyWebComp extends HTMLElement { ... showMessage(event) { this.setAttribute('count', parseInt(this.getAttribute('count')) + 1); this.counter.dispatchEvent(new CustomEvent('increment')); } } 

рд╡рд╣ рдХреНрдпрд╛ рдмрджрд▓рддрд╛ рд╣реИ? рдЕрдм, рдЕрдЧрд░ рд╡рд┐рдХрд╛рд╕ рдХреЗ рджреМрд░рд╛рди рд╡реЗрддрди рд╡реГрджреНрдзрд┐ () рд╡рд┐рдзрд┐ рдХреЛ рд╣рдЯрд╛ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдпрд╛ рдмрджрд▓ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рд╣рдорд╛рд░реЗ рдХреЛрдб рдХреА рд╢реБрджреНрдзрддрд╛ рдХрд╛ рдЙрд▓реНрд▓рдВрдШрди рд╣реЛрдЧрд╛, рд▓реЗрдХрд┐рди рдХреЛрдИ рджреБрднрд╛рд╖рд┐рдпрд╛ рддреНрд░реБрдЯрд┐рдпрд╛рдВ рдирд╣реАрдВ рд╣реЛрдВрдЧреА, рдЕрд░реНрдерд╛рддреНред рд╕рдВрдЪрд╛рд▓рди рдХреНрд╖рдорддрд╛ рдмрдиреА рд░рд╣реЗрдЧреАред рдЗрд╕ рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЛ рдХрдордЬреЛрд░ рдХрдиреЗрдХреНрдЯрд┐рд╡рд┐рдЯреА рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред

рд╡рд┐рдХрд╛рд╕ рдореЗрдВ, рдкреНрд░рддреНрдпрдХреНрд╖ рдФрд░ рдХрдордЬреЛрд░ рджреЛрдиреЛрдВ рдкреНрд░рдХрд╛рд░ рдХреЗ рдмрдВрдзрди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдЖрдорддреМрд░ рдкрд░ рдпрд╣ рдПрдХ рдШрдЯрдХ рдореЙрдбреНрдпреВрд▓ рдХреЗ рддрд░реНрдХ рдХреЗ рдЕрдВрджрд░ рдкреНрд░рддреНрдпрдХреНрд╖ рдмрдВрдзрди рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рдерд╛рдЧрдд рд╣реЛрддрд╛ рд╣реИ, рдФрд░ рдкреВрд░реЗ рд╕рд┐рд╕реНрдЯрдо рдХреЗ рд▓рдЪреАрд▓реЗрдкрди рдФрд░ рд╡реНрдпрд╛рдкрдХрддрд╛ рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рднрд┐рдиреНрди рдореЙрдбреНрдпреВрд▓ рдФрд░ рдШрдЯрдХреЛрдВ рдХреЗ рдмреАрдЪ рдХрдордЬреЛрд░ рдпреБрдЧреНрдорди рд╣реЛрддрд╛ рд╣реИред HTML рд╢рдмреНрджрд╛рд░реНрде рдХрд╛ рдЕрд░реНрде рд╣реИ рдЗрд╕ рддрд░рд╣ рдХреЗ рд▓рдЪреАрд▓реЗрдкрди рдХрд╛ рдПрдХ рдЙрдЪреНрдЪ рд╕реНрддрд░, рдЕрд░реНрдерд╛рдд рдХрдордЬреЛрд░ рдХрдиреЗрдХреНрдЯрд┐рд╡рд┐рдЯреА рдХреЗ рд▓рд┐рдП рд╡рд░реАрдпрддрд╛, рд▓реЗрдХрд┐рди рдЖрд╡реЗрджрди рдЕрдзрд┐рдХ рдордЬрд╝рдмреВрддреА рд╕реЗ рдХрд╛рдо рдХрд░реЗрдЧрд╛ рдпрджрд┐ рдШрдЯрдХреЛрдВ рдХреЗ рдЕрдВрджрд░ рдХрдиреЗрдХреНрд╢рди рдкреНрд░рддреНрдпрдХреНрд╖ рд╣реИрдВред

рд╣рдо рдкреБрд░рд╛рдиреЗ рдлрд╝реИрд╢рди рдореЗрдВ рд╣реИрдВрдбрд▓рд░ рд▓рдЯрдХрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рд╡реИрд╢реНрд╡рд┐рдХ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдСрдмреНрдЬреЗрдХреНрдЯ рдкрд░ рдХреЙрд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

 export class MyWebComp extends HTMLElement { constructor() { super(); } connectedCallback() { let html = document.importNode(myWebCompTemplate.content, true); this.attachShadow({mode: 'open'}); this.shadowRoot.appendChild(html); this.updateLabel(); this.counter.addEventListener('countChanged', this.updateLabel.bind(this)); document.addEventListener('countChanged', this.updateLabel.bind(this)); } disconnectedCallback() { document.removeEventListener(new CustomEvent('increment')); document.removeEventListener(new CustomEvent('countChanged')); } ... showMessage(event) { this.setAttribute('count', parseInt(this.getAttribute('count')) + 1); this.counter.dispatchEvent(new CustomEvent('increment')); document.dispatchEvent(new CustomEvent('increment')); } } 

 export class MyCounter extends EventTarget { constructor() { super(); this.count = 0; this.addEventListener('increment', this.increment.bind(this)); document.addEventListener('increment', this.increment.bind(this)); } increment() { this.count++; this.dispatchEvent(new CustomEvent('countChanged', { detail: { count: this.count } })); document.dispatchEvent(new CustomEvent('countChanged', { detail: { count: this.count } })); } } 

рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛрдИ рднрд┐рдиреНрди рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдЕрдм рд╣рдореЗрдВ рд╡реИрд╢реНрд╡рд┐рдХ рд╡рд╕реНрддреБ рд╕реЗ рдИрд╡реЗрдВрдЯ рд╣реИрдВрдбрд▓рд░ рдХреЛ рд╣рдЯрд╛рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдпрджрд┐ рддрддреНрд╡ рд╕реНрд╡рдпрдВ рдкреЗрдбрд╝ рд╕реЗ рд╣рдЯрд╛ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд╕реМрднрд╛рдЧреНрдп рд╕реЗ, рд╡реЗрдм рдШрдЯрдХ рд╣рдореЗрдВ рди рдХреЗрд╡рд▓ рдбрд┐рдЬрд╛рдЗрди рд╣реБрдХ рдкреНрд░рджрд╛рди рдХрд░рддреЗ рд╣реИрдВ, рдмрд▓реНрдХрд┐ рд╕реНрдореГрддрд┐ рд▓реАрдХ рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рдирд╛рд╢ рднреА рдХрд░рддреЗ рд╣реИрдВред

рдПрдХ рдФрд░ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд┐рдВрджреБ рднреА рд╣реИ: "рдмреБрджрдмреБрджрд╛рд╣рдЯ" рдирд╛рдордХ рдПрдХ рддрдВрддреНрд░ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкреЗрдбрд╝ рдХреЗ рддрддреНрд╡реЛрдВ рдХреА рдШрдЯрдирд╛рдУрдВ рдХреЛ рдПрдХ рджреВрд╕рд░реЗ рдХреЗ рд╕рд╛рде рдмрд╛рддрдЪреАрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдЬрдм рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╣рдорд╛рд░реЗ рддрддреНрд╡ рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░рддрд╛ рд╣реИ, рддреЛ рдШрдЯрдирд╛, рддрддреНрд╡ рдкрд░ рд╣реА рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реИ, рдорд╛рддрд╛-рдкрд┐рддрд╛ рдХреЛ рдкрд╛рдиреА рдкрд░ рдордВрдбрд▓рд┐рдпреЛрдВ рдХреА рддрд░рд╣ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рдиреЗ рд▓рдЧрддрд╛ рд╣реИ, рдлрд┐рд░ рдЗрд╕ рдорд╛рддрд╛-рдкрд┐рддрд╛ рдХреЗ рдорд╛рддрд╛-рдкрд┐рддрд╛ рдХреЛ рдФрд░ рдореВрд▓ рддрддреНрд╡ рдкрд░ред

рдЗрд╕ рдХреЙрд▓ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХреЗ рдХрд┐рд╕реА рднреА рдмрд┐рдВрджреБ рдкрд░, рдШрдЯрдирд╛ рдХреЛ рд░реЛрдХрд╛ рдФрд░ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рдпрд╣, рдЬрд╝рд╛рд╣рд┐рд░ рд╣реИ, рдпрд╣ рдПрдХ рд╣реА рдШрдЯрдирд╛ рдирд╣реАрдВ рд╣реИ, рдФрд░ рдЗрд╕рдХреЗ рдбреЗрд░рд┐рд╡реЗрдЯрд┐рд╡ рдФрд░ рд╕рдВрджрд░реНрдн рд╣реИрдВ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рд╡реЗ рдПрдХ рджреВрд╕рд░реЗ рд╕реЗ рд▓рд┐рдВрдХ рдХрд░реЗрдВрдЧреЗ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП event.path рдореЗрдВ , рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдореЗрд▓ рдирд╣реАрдВ рдЦрд╛рдПрдВрдЧреЗ ред

рд╣рд╛рд▓рд╛рдВрдХрд┐, рдпрд╣ рддрдВрддреНрд░ рдЖрдкрдХреЛ рдЕрдкрдиреЗ рдорд╛рддрд╛-рдкрд┐рддрд╛ рдХреЗ рд╕рд╛рде рдмрд╛рд▓ рддрддреНрд╡реЛрдВ рдХреЛ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдЬреЛрдбрд╝рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рд▓рд┐рдВрдХ рдЗрдВрдЬреАрдирд┐рдпрд░рд┐рдВрдЧ рдкреИрдЯрд░реНрди рдХрд╛ рдЙрд▓реНрд▓рдВрдШрди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдЕрд░реНрдерд╛рддред рд╕реАрдзреЗ рд▓рд┐рдВрдХ рдХреЗ рдмрд┐рдирд╛, рд▓реЗрдХрд┐рди рдХреЗрд╡рд▓ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЗ рдХрд╛рд░рдгред

рдкреНрд░рд╛рдЪреАрди рд╕рдордп рдореЗрдВ, рдЗрд╕рдиреЗ рдмрд╣реБрдд рдкрд░реЗрд╢рд╛рдиреА рдХреЛ рдЬрдиреНрдо рджрд┐рдпрд╛, рдЬрдм рдХреБрдЫ рддрддреНрд╡реЛрдВ рдХреА рдШрдЯрдирд╛рдУрдВ рдиреЗ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдХреЗ рдХреБрдЫ рдЦрдВрдбреЛрдВ рдореЗрдВ "рдордВрдбрд▓рд┐рдпреЛрдВ" рдпрд╛ рдЧреВрдБрдЬ рдХрд╛ рдХрд╛рд░рдг рдмрдирд╛ рдЬреЛ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдЕрд╡рд╛рдВрдЫрдиреАрдп рдереЗред

рд╡рд░реНрд╖реЛрдВ рддрдХ, рд╡реЗрдм рдбреЗрд╡рд▓рдкрд░реНрд╕ рдШрдЯрдирд╛рдУрдВ рдХреЗ "рдкреНрд░рдЪрд╛рд░" (рдкреНрд░рд╕рд╛рд░ рдпрд╛ рд╕рд░рдлреЗрд╕рд┐рдВрдЧ) рд╕реЗ рдЬреВрдЭрддреЗ рд░рд╣реЗ рдФрд░ рдЙрдиреНрд╣реЗрдВ рд░реЛрдХ рджрд┐рдпрд╛ рдФрд░ рдЙрдиреНрд╣реЗрдВ рд╡реИрд╕реЗ рд╣реА рдШреБрдорд╛рдпрд╛, рдЬреИрд╕реЗ рдЙрдирдХреЗ рдЖрд░рд╛рдорджрд╛рдпрдХ рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП, рдЬреИрд╕рд╛ рдХрд┐ рдЖрдИрдбреА рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдХреЗрд╡рд▓ рдЫрд╛рдпрд╛ рд╡реГрдХреНрд╖ рдХреЗ рдЕрд▓рдЧрд╛рд╡ рдХреА рдХрдореА рдереАред

рдпрд╣рд╛рдВ рдЬрд╛рджреВ рдпрд╣ рд╣реИ рдХрд┐ рд╢реИрдбреЛ рдЯреНрд░реА рдХреЗ рдмрд╛рд╣рд░ рдШрдЯрдирд╛рдПрдВ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИрдВред рд▓реЗрдХрд┐рди рдлрд┐рд░ рднреА, рдЖрдк рдореЗрдЬрдмрд╛рди рдШрдЯрдХ рдореЗрдВ рдЕрдкрдиреЗ рдмрдЪреНрдЪреЛрдВ рджреНрд╡рд╛рд░рд╛ рдлреЗрдВрдХреА рдЧрдИ рдШрдЯрдирд╛ рдХреЛ рдкрдХрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдкреЗрдбрд╝ рдХреЛ рдХрд┐рд╕реА рдЕрдиреНрдп рдШрдЯрдирд╛ рдХреЗ рдЕрд░реНрде рдХреЗ рд░реВрдк рдореЗрдВ рд░реЛрд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ, рдпрд╛ рдмрд╕ рдЗрд╕реЗ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдпрд╣ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдпрд╣ рд╕рдм рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рд╣рдо рдЕрдкрдиреЗ webcomp рддрддреНрд╡реЛрдВ рдХреЛ рдЗрд╕ рддрд░рд╣ рдХрдВрдЯреЗрдирд░ рдореЗрдВ рд▓рдкреЗрдЯрддреЗ рд╣реИрдВ:

 <my-webcont count=0> <my-webcomp id="myWebComp" greet-name="John" count=0 onclick="this.showMessage(event)"></my-webcomp> <my-webcomp id="myWebComp2" greet-name="Josh" count=0 onclick="this.showMessage(event)"></my-webcomp> </my-webcont> 

рдХрдВрдЯреЗрдирд░ рдореЗрдВ рдпрд╣ рдХреЛрдб рд╣реЛрдЧрд╛:

 export class MyWebCont extends HTMLElement { constructor() { super(); } connectedCallback() { this.addEventListener('increment', this.updateCount.bind(this)); } updateCount(event) { this.setAttribute('count', parseInt(this.getAttribute('count')) + 1); } static get observedAttributes() { return ['count']; } attributeChangedCallback(name, oldValue, newValue) { if (name === 'count') { this.querySelectorAll('my-webcomp').forEach((el) => { el.setAttribute('count', newValue); }); } } } 

рдХрдиреЗрдХреНрдЯрдХреЙрд▓рдмреИрдХ () рдореЗрдВ, рд╣рдо рд╣реИрдВрдбрд▓рд░ рдХреЛ рд╡реГрджреНрдзрд┐ рдХреА рдШрдЯрдирд╛ рдкрд░ рд▓рдЯрдХрд╛рдПрдВрдЧреЗ, рдЬреЛ рдмрдЪреНрдЪреЛрдВ рдХреЛ рдлреЗрдВрдХ рджреЗрдЧрд╛ред рд╣реИрдВрдбрд▓рд░ рддрддреНрд╡ рдХреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдХрд╛рдЙрдВрдЯрд░ рдХреЛ рдмрдврд╝рд╛рдПрдЧрд╛, рдФрд░ рдЗрд╕рдХреЗ рдореВрд▓реНрдп рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдХреЙрд▓рдмреИрдХ рд╕рднреА рдмрд╛рд▓ рддрддреНрд╡реЛрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЬрд╛рдПрдЧрд╛ рдФрд░ рдЙрдирдХреЗ рдХрд╛рдЙрдВрдЯрд░реЛрдВ рдХреЛ рдмрдврд╝рд╛рдПрдЧрд╛, рдЬрд┐рд╕ рдкрд░ рдкрд╣рд▓реЗ рд╣рдорд╛рд░реЗ рджреНрд╡рд╛рд░рд╛ рд╡рд┐рдХрд╕рд┐рдд рд╣реИрдВрдбрд▓рд░ рд▓рдЯрдХрд╛рдП рдЧрдП рдереЗред

рдмрд╛рд▓ рддрддреНрд╡реЛрдВ рдХрд╛ рдХреЛрдб рдереЛрдбрд╝рд╛ рдмрджрд▓ рдЬрд╛рдПрдЧрд╛, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рд╣рдо рд╕рднреА рдХреА рдЬрд░реВрд░рдд рд╣реИ рдХрд┐ рд╡реГрджреНрдзрд┐рд╢реАрд▓ рдШрдЯрдирд╛ рдХреЗ рд▓рд┐рдП рддрддреНрд╡ рдХреЛ рд╕реНрд╡рдпрдВ рдмрд╛рд╣рд░ рдлреЗрдВрдХрдирд╛ рд╣реИ рдФрд░ рдЗрд╕рдХреЗ рд╕рдореБрдЪреНрдЪрдп рдирд╣реАрдВ рд╣реИрдВ, рдФрд░ рдЗрд╕реЗ рдмреБрд▓рдмреБрд▓реЗ рдХреЗ рд╕рд╛рде рдХрд░реЗрдВ : рд╕рдЪреНрдЪреА рд╡рд┐рд╢реЗрд╖рддрд╛ред

 export class MyWebComp extends HTMLElement { ... showMessage(event) { this.setAttribute('count', parseInt(this.getAttribute('count')) + 1); this.counter.dispatchEvent(new CustomEvent('increment')); this.dispatchEvent(new CustomEvent('increment', { bubbles: true })); document.dispatchEvent(new CustomEvent('increment')); } } 



рдЕрдм, рдХреБрдЫ рд╕рд╛рдорд╛рдиреНрдп рдпрд╛рджреГрдЪреНрдЫрд┐рдХрддрд╛ рдХреЗ рдмрд╛рд╡рдЬреВрдж, рдкрд╣рд▓рд╛ рддрддреНрд╡ рдХрд╛рдЙрдВрдЯрд░ рд╣рдореЗрд╢рд╛ рдорд╛рддрд╛-рдкрд┐рддрд╛ рдХреЗ рдореВрд▓реНрдп рдХреЛ рджрд┐рдЦрд╛рдПрдЧрд╛ред рдПрдХ рд╕рд╛рде, рдЖрдЬ рд╣рдордиреЗ рдЬреЛ рдХреБрдЫ рднреА рдХрд┐рдпрд╛ рд╣реИ, рд╡рд╣ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдкрд╛рд▓рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЙрджрд╛рд╣рд░рдг рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдХреЗрд╡рд▓ рд╕рдВрднрд╛рд╡рдирд╛рдУрдВ рдФрд░ рддрдХрдиреАрдХреЛрдВ рдХрд╛ рдПрдХ рд╕рд┐рдВрд╣рд╛рд╡рд▓реЛрдХрди рд╣реИ рдЬрд┐рд╕рдХреЗ рджреНрд╡рд╛рд░рд╛ рдЖрдк рдШрдЯрдХреЛрдВ рдХреЗ рдмреАрдЪ рд╕рд╣реА рдорд╛рдпрдиреЗ рдореЗрдВ рдореЙрдбреНрдпреВрд▓рд░ рдмрд╛рддрдЪреАрдд рдХреЛ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдиреНрдпреВрдирддрдо рд╕рд╛рдзрдиреЛрдВ рд╕реЗ рдмрдЪрддреЗ рд╣реБрдПред

рдЖрдк рдПрдХ рд╣реА рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ рд╕рдВрджрд░реНрдн рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рдХреЛрдб рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдШрдЯрдирд╛рдУрдВ рдХреЗ рдмреНрд░рдВрдЪ рдореЗрдВ ред

Source: https://habr.com/ru/post/hi461153/


All Articles