Skip to content

Commit 218d9c2

Browse files
authored
Merge pull request #14 from bit-docs/prismjs-run-button
Run code PrismJS button registration
2 parents 6e7d111 + 7a18b43 commit 218d9c2

File tree

3 files changed

+122
-26
lines changed

3 files changed

+122
-26
lines changed

index.js

Lines changed: 59 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,28 @@ function findSelector(start, selector) {
9090
}
9191
}
9292

93+
function findDemoWrapper(el) {
94+
while(el && el.parentNode) {
95+
if(matches.call(el.parentNode, '.demo_wrapper')) {
96+
return el.parentNode;
97+
}
98+
el = el.parentNode;
99+
}
100+
}
101+
102+
function findPreForToolbarBtn(el) {
103+
while(el) {
104+
if (el.nodeName === "PRE") {
105+
return el;
106+
}
107+
if (matches.call(el, '.toolbar')) {
108+
el = findSelector(el, 'pre');
109+
} else {
110+
el = el.parentNode;
111+
}
112+
}
113+
}
114+
93115
function getStylesFromIframe(iframe) {
94116
var styles = iframe.contentDocument.documentElement.querySelectorAll("style");
95117
var cssText = "";
@@ -100,13 +122,36 @@ function getStylesFromIframe(iframe) {
100122
}
101123

102124
module.exports = function() {
125+
var codepens = document.querySelectorAll('div.codepen');
126+
//remove the old codepen links
127+
codepens.forEach(function(codepen, i){
128+
var wrapper = findSelector(codepen, "pre, .demo_wrapper");
129+
//the CodePen iframe wrapper has ".codepen" class too
130+
if (wrapper) {
131+
wrapper.setAttribute('data-has-run', true);
132+
codepen.parentNode.removeChild(codepen);
133+
}
134+
});
103135

104-
document.body.addEventListener("click", function(ev){
105-
if(matches.call(ev.target, ".codepen")){
106-
107-
var el = findSelector(ev.target, "pre, .demo_wrapper");
108-
if(el && matches.call(el, "pre")) {
109-
var preElement = el;
136+
//Register PrismJS "Run" custom button
137+
Prism.plugins.toolbar.registerButton("run-code", function(env) {
138+
var demoWrapper = findDemoWrapper(env.element);
139+
var pre = env.element.parentElement;
140+
var hasRunBtn = demoWrapper ? demoWrapper.getAttribute("data-has-run") : pre.getAttribute("data-has-run");
141+
//prevent other demos without codepen link to register Run button
142+
if (hasRunBtn) {
143+
var btn = document.createElement("button");
144+
btn.innerHTML = "Run";
145+
btn.setAttribute("data-run", "");
146+
return btn;
147+
}
148+
});
149+
document.body.addEventListener('click', function (ev) {
150+
if (ev.target.getAttribute('data-run') != null) {
151+
var btn = ev.target;
152+
var demoWrapper = findDemoWrapper(btn);
153+
if (!demoWrapper) {
154+
var preElement = findPreForToolbarBtn(btn);
110155
var codeElement = preElement.querySelector("code");
111156
var language = codeElement.className.match(languageHTML)[1];
112157
var text = codeElement.textContent;
@@ -131,31 +176,26 @@ module.exports = function() {
131176
console.warn("Unable to create a codepen for this demo");
132177
}
133178
}
134-
if(el && matches.call(el, ".demo_wrapper")) {
135-
var htmlCode = el.querySelector("[data-for=html] code");
136-
var htmlText = htmlCode ? htmlCode.textContent.trim() : "";
137-
138-
var jsCode = el.querySelector("[data-for=js] code");
139-
var jsText = jsCode ? jsCode.textContent.trim() : "";
140-
141-
var cssText = getStylesFromIframe( el.querySelector("iframe") );
142-
179+
if (demoWrapper && matches.call(demoWrapper, '.demo_wrapper')) {
180+
var htmlCode = demoWrapper.querySelector('[data-for=html] code');
181+
var htmlText = htmlCode ? htmlCode.textContent.trim() : '';
182+
var jsCode = demoWrapper.querySelector('[data-for=js] code');
183+
var jsText = jsCode ? jsCode.textContent.trim() : '';
184+
var cssText = getStylesFromIframe(demoWrapper.querySelector('iframe'));
143185
var codePen = {
144186
html: htmlText,
145187
js: jsText,
146188
js_module: true,
147-
editors: "1011",
189+
editors: '1011',
148190
css: cssText.trim()
149191
};
150192
cleanCodePenData(codePen);
151-
if(window.CREATE_CODE_PEN) {
193+
if (window.CREATE_CODE_PEN) {
152194
CREATE_CODE_PEN(codePen);
153195
} else {
154196
createCodePen(codePen);
155197
}
156-
157198
}
158-
159199
}
160200
});
161201
};

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,9 @@
2727
"dependencies": {},
2828
"devDependencies": {
2929
"bit-docs-generate-html": "^0.1.0",
30+
"bit-docs-prettify": "^0.4.1",
3031
"connect": "^2.14.4",
3132
"mocha": "^6.0.2",
32-
"zombie": "^4.3.0"
33+
"zombie": "^6.1.0"
3334
}
3435
}

test.js

Lines changed: 61 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ describe("bit-docs-html-codepen-link", function() {
4040
html: {
4141
dependencies: {
4242
"bit-docs-html-codepen-link": __dirname,
43+
"bit-docs-prettify": "^0.4.0",
4344
"bit-docs-tag-demo": "^0.5.3"
4445
}
4546
},
@@ -54,10 +55,10 @@ describe("bit-docs-html-codepen-link", function() {
5455
browser.window.CREATE_CODE_PEN = function(data) {
5556
createCallData.push(data);
5657
};
57-
var codePens = doc.querySelectorAll('.codepen');
58-
59-
Array.from(codePens).forEach(function(codePen) {
60-
codePen.click();
58+
var toolbars = doc.querySelectorAll('.toolbar');
59+
toolbars.forEach(function(toolbar) {
60+
var btn = toolbar.children[toolbar.children.length - 1].querySelector('button');
61+
btn.click();
6162
});
6263
assert.deepEqual(createCallData, [{
6364
html: '<my-app></my-app>',
@@ -70,8 +71,21 @@ describe("bit-docs-html-codepen-link", function() {
7071
js: 'import {DefineMap} from "//unpkg.com/can@^5.0.0-pre.1/core.mjs";\nconsole.log( myCounter.count ) //-> 1',
7172
js_module: true,
7273
editors: '0011'
73-
}
74-
]);
74+
},
75+
{
76+
css: 'h1 {color: red;}',
77+
editors: '1011',
78+
html: '<h1>Hi There!</h1>',
79+
js: 'var code = "code";',
80+
js_module: true
81+
},
82+
{
83+
css: 'h1 {color: red;}',
84+
editors: '1011',
85+
html: '<h1>Hi There!</h1>',
86+
js: 'var code = "code";',
87+
js_module: true
88+
}]);
7589

7690
close();
7791
done();
@@ -223,4 +237,45 @@ describe("bit-docs-html-codepen-link", function() {
223237
it("supports ts files", function() {
224238
assert.ok(codepenData.ts, "there is a ts");
225239
});
240+
241+
it("Registers run code button", function(done) {
242+
this.timeout(60000);
243+
244+
var docMap = Promise.resolve({
245+
index: {
246+
name: "index",
247+
demo: "path/to/demo.html",
248+
body: fs.readFileSync(__dirname + "/test-demo.md", "utf8"),
249+
codepen: [
250+
["can", "//unpkg.com/can@^5.0.0-pre.1/core.mjs"]
251+
]
252+
}
253+
});
254+
255+
generate(docMap, {
256+
html: {
257+
dependencies: {
258+
"bit-docs-html-codepen-link": __dirname,
259+
"bit-docs-prettify": "^0.4.0",
260+
"bit-docs-tag-demo": "^0.5.3"
261+
}
262+
},
263+
dest: path.join(__dirname, "temp"),
264+
parent: "index",
265+
forceBuild: true,
266+
minifyBuild: false
267+
}).then(function() {
268+
open("temp/index.html", function(browser, close) {
269+
var doc = browser.window.document;
270+
var toolbars = doc.querySelectorAll(".code-toolbar");
271+
toolbars.forEach(function(toolbar) {
272+
var children = toolbar.children;
273+
assert.equal(toolbar.children.length, 2);
274+
assert.equal(children[children.length - 1].innerHTML, '<div class="toolbar-item"><button>Copy</button></div><div class="toolbar-item"><button data-run="">Run</button></div>');
275+
});
276+
close();
277+
done();
278+
}, done);
279+
}, done);
280+
});
226281
});

0 commit comments

Comments
 (0)