Skip to content

Commit 94ceca0

Browse files
authored
Merge branch 'master' into github-actions-css
2 parents b89705f + 32ca9d3 commit 94ceca0

File tree

3 files changed

+181
-4
lines changed

3 files changed

+181
-4
lines changed

examples/coding-template/Example-Template.html

+5-3
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,9 @@ <h1>EXAMPLE_NAME Example</h1>
5757
</ul>
5858

5959
<section>
60-
<h2 id="ex_label">Example</h2>
60+
<div class="example-header">
61+
<h2 id="ex_label">Example</h2>
62+
</div>
6163
<div role="separator" id="ex_start_sep" aria-labelledby="ex_start_sep ex_label" aria-label="Start of"></div>
6264
<!--
6365
Note the ID of the following div that contains the example HTML is used as a parameter for the sourceCode.add() function.
@@ -189,7 +191,7 @@ <h2 id="rps_label">Role, Property, State, and Tabindex Attributes</h2>
189191
<section>
190192
<h2>Javascript and CSS Source Code</h2>
191193
<!-- After the js and css files are named with the name of this example, change the href and text of the following 2 links to refer to the appropriate js and css files. -->
192-
<ul>
194+
<ul id="cssJsFiles">
193195
<li>
194196
CSS:
195197
<a href="css/example_name.css" type="tex/css">example_name.css</a>
@@ -212,7 +214,7 @@ <h2 id="sc1_label">HTML Source Code</h2>
212214
If you change the ID of either the 'ex1' div or the 'sc1' pre, be sure to update the sourceCode.add function parameters.
213215
-->
214216
<script>
215-
sourceCode.add('sc1', 'ex1');
217+
sourceCode.add('sc1', 'ex1', 'ex_label', 'cssJsFiles');
216218
sourceCode.make();
217219
</script>
218220
</section>

examples/css/core.css

+69
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,72 @@ table.data.attributes tbody th,
4040
table.data.attributes tbody td {
4141
border: 1px solid silver;
4242
}
43+
44+
/* CodePen button */
45+
.example-header {
46+
display: flex;
47+
align-items: center;
48+
margin-top: 3rem;
49+
page-break-after: avoid;
50+
page-break-inside: avoid;
51+
font: 100% sans-serif;
52+
font-family: inherit;
53+
line-height: 1.2;
54+
hyphens: manual;
55+
}
56+
57+
.example-header > :first-child {
58+
margin: 0;
59+
}
60+
61+
.example-header > :first-child + * {
62+
margin-left: 1em;
63+
}
64+
65+
.example-header button {
66+
display: inline-block;
67+
position: relative;
68+
padding: 0.4em 0.7em;
69+
border: 1px solid hsl(213, 71%, 49%);
70+
border-radius: 5px;
71+
box-shadow: 0 1px 2px hsl(216, 27%, 55%);
72+
color: #fff;
73+
font-size: inherit;
74+
text-shadow: 0 -1px 1px hsl(216, 27%, 25%);
75+
background-color: hsl(216, 82%, 51%);
76+
background-image: linear-gradient(to bottom, hsl(216, 82%, 53%), hsl(216, 82%, 47%));
77+
}
78+
79+
.example-header button:hover {
80+
border-color: hsl(213, 71%, 29%);
81+
background-color: hsl(216, 82%, 31%);
82+
background-image: linear-gradient(to bottom, hsl(216, 82%, 33%), hsl(216, 82%, 27%));
83+
cursor: default;
84+
}
85+
86+
.example-header button:focus {
87+
outline: none;
88+
}
89+
90+
.example-header button:focus::before {
91+
position: absolute;
92+
z-index: -1;
93+
94+
/* button border width - outline width - offset */
95+
top: calc(-1px - 3px - 3px);
96+
right: calc(-1px - 3px - 3px);
97+
bottom: calc(-1px - 3px - 3px);
98+
left: calc(-1px - 3px - 3px);
99+
border: 3px solid hsl(213, 71%, 49%);
100+
101+
/* button border radius + outline width + offset */
102+
border-radius: calc(5px + 3px + 3px);
103+
content: '';
104+
}
105+
106+
.example-header button:active {
107+
border-color: hsl(213, 71%, 49%);
108+
background-color: hsl(216, 82%, 31%);
109+
background-image: linear-gradient(to bottom, hsl(216, 82%, 53%), hsl(216, 82%, 47%));
110+
box-shadow: inset 0 3px 5px 1px hsl(216, 82%, 30%);
111+
}

examples/js/examples.js

+107-1
Original file line numberDiff line numberDiff line change
@@ -35,17 +35,26 @@ var VOID_ELEMENTS = ['area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input',
3535
aria.widget.SourceCode = function () {
3636
this.location = new Array();
3737
this.code = new Array();
38+
this.exampleHeader = new Array();
39+
this.resources = new Array();
3840
};
3941

4042
/**
4143
* Adds source code
4244
*
45+
* @param {string} locationId - ID of `code` element that will display the example html
46+
* @param {string} codeID - ID of element containing only and all of the html used to render the example widget
47+
* @param {string} exampleHeaderId - ID of header element under which the "Open in Codepen" button belongs
48+
* @param {string} cssJsFilesId - ID of element containing links to all the relevent js and css files used for the example widget
49+
*
4350
* @method add
4451
* @memberof aria.widget.SourceCode
4552
*/
46-
aria.widget.SourceCode.prototype.add = function (locationId, codeId) {
53+
aria.widget.SourceCode.prototype.add = function (locationId, codeId, exampleHeaderId, cssJsFilesId) {
4754
this.location[this.location.length] = locationId;
4855
this.code[this.code.length] = codeId;
56+
this.exampleHeader[this.exampleHeader.length] = exampleHeaderId;
57+
this.resources[this.resources.length] = cssJsFilesId;
4958
};
5059

5160
/**
@@ -66,6 +75,11 @@ aria.widget.SourceCode.prototype.make = function () {
6675
if (sourceCodeNode.innerHTML.startsWith('<br>')) {
6776
sourceCodeNode.innerHTML = sourceCodeNode.innerHTML.replace('<br>', '');
6877
}
78+
79+
// Adds the "Open In CodePen" button by the example header
80+
if (this.exampleHeader[i]) {
81+
addOpenInCodePenForm(i, this.exampleHeader[i], this.code[i], this.resources[i]);
82+
}
6983
}
7084
};
7185

@@ -300,4 +314,96 @@ function indentLines (input, indentation) {
300314
return lines.join('\n');
301315
}
302316

317+
/**
318+
* Creates and adds an "Open in CodePen" button
319+
*
320+
* @param {String} exampleIndex - the example number, if there are multiple examples
321+
* @param {String} exampleHeaderId - the example header to place the button next to
322+
* @param {String} exampleCodeId - the example html code
323+
* @param {String} exampleFilesId - the element containing all relevent CSS and JS file
324+
*/
325+
function addOpenInCodePenForm (exampleIndex, exampleHeaderId, exampleCodeId, exampleFilesId) {
326+
var jsonInputId = 'codepen-data-ex-' + exampleIndex;
327+
var buttonId = exampleCodeId + '-codepenbutton'
328+
329+
var form = document.createElement('form');
330+
form.setAttribute('action', 'https://codepen.io/pen/define');
331+
form.setAttribute('method', 'POST');
332+
form.setAttribute('target', '_blank');
333+
334+
var input = document.createElement('input');
335+
input.setAttribute('id', jsonInputId);
336+
input.setAttribute('type', 'hidden');
337+
input.setAttribute('name', 'data');
338+
339+
var button = document.createElement('button');
340+
button.innerText = 'Open In CodePen';
341+
342+
form.appendChild(input);
343+
form.appendChild(button);
344+
345+
var exampleHeader = document.getElementById(exampleHeaderId);
346+
exampleHeader.parentNode.insertBefore(form, exampleHeader.nextSibling);
347+
348+
// Correct the indentation for the example html
349+
var indentedExampleHtml = document.getElementById(exampleCodeId).innerHTML;
350+
indentedExampleHtml = indentedExampleHtml.replace(/^\n+/, '');
351+
var indentation = indentedExampleHtml.match(/^\s+/)[0];
352+
var exampleHtml = indentedExampleHtml.replace(new RegExp('^' + indentation, 'gm'), '');
353+
354+
var postJson = {
355+
html: exampleHtml,
356+
css: '',
357+
js: '',
358+
head: '<base href="' + location.href + '">'
359+
};
360+
361+
var totalFetchedFiles = 0;
362+
var fileLinks = document.querySelectorAll('#' + exampleFilesId + ' a');
363+
364+
for (let fileLink of fileLinks) {
365+
366+
var request = new XMLHttpRequest();
367+
368+
request.open('GET', fileLink.href, true);
369+
request.onload = function() {
370+
var href = this.responseURL;
371+
if (this.status >= 200 && this.status < 400) {
372+
if (href.indexOf('css') !== -1) {
373+
postJson.css = postJson.css.concat(this.response);
374+
}
375+
if (href.indexOf('js') !== -1) {
376+
postJson.js = postJson.js.concat(this.response);
377+
}
378+
totalFetchedFiles++;
379+
}
380+
else {
381+
hideButton(buttonId, "Could not load resource: " + href);
382+
}
383+
};
384+
request.onerror = function() {
385+
hideButton(buttonId, "Could not load resource: " + fileLink.href);
386+
};
387+
request.send();
388+
}
389+
390+
var timerId = setInterval(() => {
391+
console.log(totalFetchedFiles);
392+
if (totalFetchedFiles === fileLinks.length) {
393+
document.getElementById(jsonInputId).value = JSON.stringify(postJson);
394+
clearInterval(timerId);
395+
}
396+
}, 500);
397+
398+
setTimeout(() => {
399+
clearInterval(timerId);
400+
}, 10000);
401+
}
402+
403+
function hideButton(buttonId, errorMsg) {
404+
let button = document.querySelector(buttonId);
405+
button.style.display = "none";
406+
console.log("Removing 'Open in Codepen button'. " + errorMsg);
407+
}
408+
303409
var sourceCode = new aria.widget.SourceCode();

0 commit comments

Comments
 (0)