UNPKG

joicomponents

Version:

Design patterns to build native web components

78 lines (70 loc) 2.44 kB
<script> const innerTemplate = ` <script src="https://unpkg.com/joievents@1.0.16/src/link-click-es6.js"></scrip` + `t> <script src="https://unpkg.com/joievents@1.0.16/src/browse.js"></scrip` + `t> <script>(function(){ window.addEventListener("browse", function(e){ e.preventDefault(); let event = {type: e.type, timeStamp: e.timeStamp, href: e.getHref()}; parent.postMessage(JSON.stringify({event}), "*"); }, true); })();</scrip` + `t>`; const outerTemplate = document.createElement("template"); outerTemplate.innerHTML = ` <style> :host, iframe { border: none; margin: 0; padding: 0; } :host{ overflow: visible; display: inline-block; } iframe { overflow: hidden; height: 100%; /*initial value only, will be overwritten later*/ width: 100%; /*initial value only, will be overwritten later*/ } </style> <iframe sandbox="allow-scripts" scrolling="no" frameborder="0"></iframe>`; class OverflowIframe extends HTMLElement { constructor() { super(); this.attachShadow({mode: "open"}); this.shadowRoot.appendChild(outerTemplate.content.cloneNode(true)); this._iframe = this.shadowRoot.children[1]; window.addEventListener("message", this.onMessage.bind(this)) } static get observedAttributes() { return ["srcdoc"]; } attributeChangedCallback(name, oldValue, newValue) { if (name === "srcdoc") { const src = (newValue || "") + innerTemplate; let blob = new Blob([src], {type: "text/html"}); this._iframe.setAttribute("src", URL.createObjectURL(blob)); } } onMessage(e) { if (e.source !== this._iframe.contentWindow) return; const res = JSON.parse(e.data); if (res.event) this.dispatchEvent(new CustomEvent(res.event.type, {bubbles: true, composed: true, detail: {href: res.event.href}})); } } customElements.define("overflow-iframe", OverflowIframe); </script> <h1>Hello world!</h1> <hr> <overflow-iframe srcdoc="<a href='//bbc.com'>bbc.com</a><hr><a href='//google.com'>google.com</a>"></overflow-iframe> <script> window.addEventListener("browse", function(e){ console.log("browsing to: ", e); }); </script> <!-- This code is untested. I have only done superficial tests from within devtools in Chrome. The code should only work in Chrome, Safari, Firefox as template does not work in IE and Edge. -->