Merge pull request #2 from Heydon/standalone

Standalone windows
This commit is contained in:
Heydon Pickering 2017-08-06 10:54:02 +01:00 committed by GitHub
commit faf62f0940
7 changed files with 135 additions and 27 deletions

View File

@ -74,6 +74,13 @@ toggle.addEventListener('click', (e) => {
</script> </script>
{{</demo>}} {{</demo>}}
## Launch in a separate window
The "Launch in separate window" takes the demo code and pushes it to a new browser window. This serves two purposes:
* It provides a fallback for browsers that do not support Shadow DOM encapsulation (a warning message will replace the inline demo).
* It creates an isolated test case for the demo, allowing you to run browser extensions and bookmarklets on the the demo code and _just_ the demo code.
## Captioned demos ## Captioned demos
It's possible to give your demo a caption using an accessible `<figure>` and `<figcaption>` structure. All _you_ need to do is supply a `caption` attribute. For example: It's possible to give your demo a caption using an accessible `<figure>` and `<figcaption>` structure. All _you_ need to do is supply a `caption` attribute. For example:

View File

@ -162,12 +162,16 @@ main ul ul {
button { button {
font-size: 1.25rem; font-size: 1.25rem;
font-family: inherit; font-family: inherit;
font-weight: inherit;
background: #111; background: #111;
color: #fff; color: #fff;
padding: 0.75rem; padding: 0.75rem;
border: 0; border: 0;
} }
[data-launch] {
font-size: 0.75rem;
margin-top: 0.75rem;
padding: 0.5rem;
}
/* Tables */ /* Tables */
table { table {
@ -683,6 +687,13 @@ h1 svg {
} }
/* inline demos */ /* inline demos */
.demo-container {
border-top: 1px solid;
border-bottom: 1px solid;
padding: 1.5rem 0 0;
text-align: right;
}
[id^="js-demo-"] { [id^="js-demo-"] {
all: initial; all: initial;
display: block; display: block;

View File

@ -357,6 +357,25 @@
<nav class="toc" aria-labelledby="toc-heading">
<h2 id="toc-heading">Table of contents</h2>
<ol>
<li>
<a href="#launch-in-a-separate-window">
Launch in a separate window
</a>
</li>
<li>
<a href="#captioned-demos">
Captioned demos
</a>
</li>
</ol>
</nav>
@ -406,7 +425,7 @@ toggle.addEventListener('click', (e) => {
<div class="demo-container"> <div class="demo-container">
<div class="demo" id="demo-414e06a48e755bf9e43e5e2596f9ea7a"></div> <div class="demo" id="js-demo-414e06a48e755bf9e43e5e2596f9ea7a"></div>
<template id="template-414e06a48e755bf9e43e5e2596f9ea7a"> <template id="template-414e06a48e755bf9e43e5e2596f9ea7a">
@ -440,25 +459,48 @@ toggle.addEventListener('click', (e) => {
</script> </script>
</template> </template>
<button data-launch="js-demo-414e06a48e755bf9e43e5e2596f9ea7a">Launch in separate window</button>
<script> <script>
(function() { (function() {
var root = document.getElementById('demo-414e06a48e755bf9e43e5e2596f9ea7a'); var root = document.getElementById('js-demo-414e06a48e755bf9e43e5e2596f9ea7a');
if (document.head.attachShadow) {
root.attachShadow({mode: 'open'});
var template = document.getElementById('template-414e06a48e755bf9e43e5e2596f9ea7a'); var template = document.getElementById('template-414e06a48e755bf9e43e5e2596f9ea7a');
var script = template.content.querySelector('script'); var script = template.content.querySelector('script');
if (script) { if (script) {
script.textContent = `(function() { var demo = document.getElementById(\'demo-414e06a48e755bf9e43e5e2596f9ea7a\').shadowRoot; ${script.textContent} })()` var standaloneScript = '(function() { document.getElementsByTagName(\'html\')[0].setAttribute(\'lang\', \'en\'); var demo = document; ' + script.textContent + ' })()';
var wrappedScript = '(function() { var demo = document.getElementById(\'js-demo-414e06a48e755bf9e43e5e2596f9ea7a\').shadowRoot;' + script.textContent + '})()';
script.textContent = wrappedScript;
} }
if (document.head.attachShadow) {
root.attachShadow({mode: 'open'});
root.shadowRoot.appendChild(document.importNode(template.content, true)); root.shadowRoot.appendChild(document.importNode(template.content, true));
} else { } else {
root.innerHTML = '<p class="site-error"><strong style="font-weight:bold">Site error:</strong> A browser supporting Shadow DOM is needed to run encapsulated demos. The browser does not have an issue with the demo code itself.</p>'; root.innerHTML = '<p class="site-error"><strong style="font-weight:bold">Site error:</strong> A browser supporting Shadow DOM is needed to run encapsulated demos. You can launch the demo in a separate window ↓</p>';
} }
var launchButton = document.querySelector('[data-launch="js-demo-414e06a48e755bf9e43e5e2596f9ea7a"]');
launchButton.addEventListener('click', function () {
var demoContent = template.content;
var standalone = window.open();
script.textContent = standaloneScript;
standalone.document.body.appendChild(document.importNode(template.content, true));
standalone.document.title = 'demo ' + "414e06a48e755bf9e43e5e2596f9ea7a"
});
})(); })();
</script> </script>
</div> </div>
<h2 id="launch-in-a-separate-window">Launch in a separate window</h2>
<p>The &ldquo;Launch in separate window&rdquo; takes the demo code and pushes it to a new browser window. This serves two purposes:</p>
<ul>
<li>It provides a fallback for browsers that do not support Shadow DOM encapsulation (a warning message will replace the inline demo).</li>
<li>It creates an isolated test case for the demo, allowing you to run browser extensions and bookmarklets on the the demo code and <em>just</em> the demo code.</li>
</ul>
<h2 id="captioned-demos">Captioned demos</h2> <h2 id="captioned-demos">Captioned demos</h2>
<p>It&rsquo;s possible to give your demo a caption using an accessible <code>&lt;figure&gt;</code> and <code>&lt;figcaption&gt;</code> structure. All <em>you</em> need to do is supply a <code>caption</code> attribute. For example:</p> <p>It&rsquo;s possible to give your demo a caption using an accessible <code>&lt;figure&gt;</code> and <code>&lt;figcaption&gt;</code> structure. All <em>you</em> need to do is supply a <code>caption</code> attribute. For example:</p>

View File

@ -1665,7 +1665,7 @@ toggle.addEventListener('click', (e) => {
<div class="demo-container"> <div class="demo-container">
<div class="demo" id="demo-414e06a48e755bf9e43e5e2596f9ea7a"></div> <div class="demo" id="js-demo-414e06a48e755bf9e43e5e2596f9ea7a"></div>
<template id="template-414e06a48e755bf9e43e5e2596f9ea7a"> <template id="template-414e06a48e755bf9e43e5e2596f9ea7a">
@ -1699,25 +1699,48 @@ toggle.addEventListener('click', (e) => {
</script> </script>
</template> </template>
<button data-launch="js-demo-414e06a48e755bf9e43e5e2596f9ea7a">Launch in separate window</button>
<script> <script>
(function() { (function() {
var root = document.getElementById('demo-414e06a48e755bf9e43e5e2596f9ea7a'); var root = document.getElementById('js-demo-414e06a48e755bf9e43e5e2596f9ea7a');
if (document.head.attachShadow) {
root.attachShadow({mode: 'open'});
var template = document.getElementById('template-414e06a48e755bf9e43e5e2596f9ea7a'); var template = document.getElementById('template-414e06a48e755bf9e43e5e2596f9ea7a');
var script = template.content.querySelector('script'); var script = template.content.querySelector('script');
if (script) { if (script) {
script.textContent = `(function() { var demo = document.getElementById(\'demo-414e06a48e755bf9e43e5e2596f9ea7a\').shadowRoot; ${script.textContent} })()` var standaloneScript = '(function() { document.getElementsByTagName(\'html\')[0].setAttribute(\'lang\', \'en\'); var demo = document; ' + script.textContent + ' })()';
var wrappedScript = '(function() { var demo = document.getElementById(\'js-demo-414e06a48e755bf9e43e5e2596f9ea7a\').shadowRoot;' + script.textContent + '})()';
script.textContent = wrappedScript;
} }
if (document.head.attachShadow) {
root.attachShadow({mode: 'open'});
root.shadowRoot.appendChild(document.importNode(template.content, true)); root.shadowRoot.appendChild(document.importNode(template.content, true));
} else { } else {
root.innerHTML = '<p class="site-error"><strong style="font-weight:bold">Site error:</strong> A browser supporting Shadow DOM is needed to run encapsulated demos. The browser does not have an issue with the demo code itself.</p>'; root.innerHTML = '<p class="site-error"><strong style="font-weight:bold">Site error:</strong> A browser supporting Shadow DOM is needed to run encapsulated demos. You can launch the demo in a separate window ↓</p>';
} }
var launchButton = document.querySelector('[data-launch="js-demo-414e06a48e755bf9e43e5e2596f9ea7a"]');
launchButton.addEventListener('click', function () {
var demoContent = template.content;
var standalone = window.open();
script.textContent = standaloneScript;
standalone.document.body.appendChild(document.importNode(template.content, true));
standalone.document.title = 'demo ' + "414e06a48e755bf9e43e5e2596f9ea7a"
});
})(); })();
</script> </script>
</div> </div>
<h2 id="launch-in-a-separate-window">Launch in a separate window</h2>
<p>The &ldquo;Launch in separate window&rdquo; takes the demo code and pushes it to a new browser window. This serves two purposes:</p>
<ul>
<li>It provides a fallback for browsers that do not support Shadow DOM encapsulation (a warning message will replace the inline demo).</li>
<li>It creates an isolated test case for the demo, allowing you to run browser extensions and bookmarklets on the the demo code and <em>just</em> the demo code.</li>
</ul>
<h2 id="captioned-demos">Captioned demos</h2> <h2 id="captioned-demos">Captioned demos</h2>
<p>It&rsquo;s possible to give your demo a caption using an accessible <code>&lt;figure&gt;</code> and <code>&lt;figcaption&gt;</code> structure. All <em>you</em> need to do is supply a <code>caption</code> attribute. For example:</p> <p>It&rsquo;s possible to give your demo a caption using an accessible <code>&lt;figure&gt;</code> and <code>&lt;figcaption&gt;</code> structure. All <em>you</em> need to do is supply a <code>caption</code> attribute. For example:</p>

File diff suppressed because one or more lines are too long

View File

@ -3,7 +3,7 @@
{{ if .Get "caption" }} {{ if .Get "caption" }}
<figure role="group" aria-labelledby="caption-{{ $uniq }}"> <figure role="group" aria-labelledby="caption-{{ $uniq }}">
{{ end }} {{ end }}
<div class="demo" id="demo-{{ $uniq }}"></div> <div class="demo" id="js-demo-{{ $uniq }}"></div>
{{ if .Get "caption" }} {{ if .Get "caption" }}
<figcaption id="caption-{{ $uniq }}">{{ .Get "caption" | markdownify }}</figcaption> <figcaption id="caption-{{ $uniq }}">{{ .Get "caption" | markdownify }}</figcaption>
{{ end }} {{ end }}
@ -13,20 +13,34 @@
<template id="template-{{ $uniq }}"> <template id="template-{{ $uniq }}">
{{ .Inner }} {{ .Inner }}
</template> </template>
<button data-launch="js-demo-{{ $uniq }}">Launch in separate window</button>
<script> <script>
(function() { (function() {
var root = document.getElementById('demo-{{ $uniq }}'); var root = document.getElementById('js-demo-{{ $uniq }}');
if (document.head.attachShadow) {
root.attachShadow({mode: 'open'});
var template = document.getElementById('template-{{ $uniq }}'); var template = document.getElementById('template-{{ $uniq }}');
var script = template.content.querySelector('script'); var script = template.content.querySelector('script');
if (script) { if (script) {
script.textContent = `(function() { var demo = document.getElementById(\'demo-{{ $uniq }}\').shadowRoot; ${script.textContent} })()` var standaloneScript = '(function() { document.getElementsByTagName(\'html\')[0].setAttribute(\'lang\', \'en\'); var demo = document; ' + script.textContent + ' })()';
var wrappedScript = '(function() { var demo = document.getElementById(\'js-demo-{{ $uniq }}\').shadowRoot;' + script.textContent + '})()';
script.textContent = wrappedScript;
} }
if (document.head.attachShadow) {
root.attachShadow({mode: 'open'});
root.shadowRoot.appendChild(document.importNode(template.content, true)); root.shadowRoot.appendChild(document.importNode(template.content, true));
} else { } else {
root.innerHTML = '<p class="site-error"><strong style="font-weight:bold">Site error:</strong> A browser supporting Shadow DOM is needed to run encapsulated demos. The browser does not have an issue with the demo code itself.</p>'; root.innerHTML = '<p class="site-error"><strong style="font-weight:bold">Site error:</strong> A browser supporting Shadow DOM is needed to run encapsulated demos. You can launch the demo in a separate window ↓</p>';
} }
var launchButton = document.querySelector('[data-launch="js-demo-{{ $uniq }}"]');
launchButton.addEventListener('click', function () {
var demoContent = template.content;
var standalone = window.open();
script.textContent = standaloneScript;
standalone.document.body.appendChild(document.importNode(template.content, true));
standalone.document.title = 'demo ' + {{ $uniq }}
});
})(); })();
</script> </script>
</div> </div>

View File

@ -162,12 +162,16 @@ main ul ul {
button { button {
font-size: 1.25rem; font-size: 1.25rem;
font-family: inherit; font-family: inherit;
font-weight: inherit;
background: #111; background: #111;
color: #fff; color: #fff;
padding: 0.75rem; padding: 0.75rem;
border: 0; border: 0;
} }
[data-launch] {
font-size: 0.75rem;
margin-top: 0.75rem;
padding: 0.5rem;
}
/* Tables */ /* Tables */
table { table {
@ -683,6 +687,13 @@ h1 svg {
} }
/* inline demos */ /* inline demos */
.demo-container {
border-top: 1px solid;
border-bottom: 1px solid;
padding: 1.5rem 0 0;
text-align: right;
}
[id^="js-demo-"] { [id^="js-demo-"] {
all: initial; all: initial;
display: block; display: block;