Support RunKit preamble (#696)
* feat(runkit-tag): support preamble * chore(runkit-tag): remove unnecessary length check * docs(editor guide text): add preamble to runkit snippet * fix(spec/runkit-tag): add preamble code to spec * fix(runkit-tag): prevent xss attacks * fix(runkit-tag): prevent race condition
This commit is contained in:
parent
160056a19d
commit
4d673e9601
3 changed files with 37 additions and 28 deletions
|
|
@ -1,7 +1,7 @@
|
|||
class RunkitTag < Liquid::Block
|
||||
def initialize(tag_name, markup, tokens)
|
||||
super
|
||||
@markup = markup
|
||||
@preamble = ActionView::Base.full_sanitizer.sanitize(markup, tags: [])
|
||||
end
|
||||
|
||||
def render(context)
|
||||
|
|
@ -9,7 +9,8 @@ class RunkitTag < Liquid::Block
|
|||
parsed_content = content.xpath("//html/body").text
|
||||
html = <<~HTML
|
||||
<div class="runkit-element">
|
||||
#{parsed_content}
|
||||
<code style="display: none">#{@preamble}</code>
|
||||
<code>#{parsed_content}</code>
|
||||
</div>
|
||||
HTML
|
||||
html
|
||||
|
|
@ -18,15 +19,15 @@ class RunkitTag < Liquid::Block
|
|||
def self.special_script
|
||||
<<~JAVASCRIPT
|
||||
var targets = document.getElementsByClassName("runkit-element");
|
||||
if (targets.length > 0) {
|
||||
for (var i = 0; i < targets.length; i++) {
|
||||
var content = targets[i].textContent;
|
||||
targets[i].innerHTML = "";
|
||||
var notebook = RunKit.createNotebook({
|
||||
element: targets[i],
|
||||
source: content,
|
||||
});
|
||||
}
|
||||
for (var i = 0; i < targets.length; i++) {
|
||||
var preamble = targets[i].children[0].textContent;
|
||||
var content = targets[i].children[1].textContent;
|
||||
targets[i].innerHTML = "";
|
||||
var notebook = RunKit.createNotebook({
|
||||
element: targets[i],
|
||||
source: content,
|
||||
preamble: preamble
|
||||
});
|
||||
}
|
||||
JAVASCRIPT
|
||||
end
|
||||
|
|
@ -36,16 +37,17 @@ class RunkitTag < Liquid::Block
|
|||
var checkRunkit = setInterval(function() {
|
||||
if(typeof(RunKit) !== 'undefined') {
|
||||
var targets = document.getElementsByClassName("runkit-element");
|
||||
if (targets.length > 0) {
|
||||
for (var i = 0; i < targets.length; i++) {
|
||||
var content = targets[i].textContent;
|
||||
if(/^(\<iframe src)/.test(content) === false) {
|
||||
targets[i].innerHTML = "";
|
||||
var notebook = RunKit.createNotebook({
|
||||
element: targets[i],
|
||||
source: content,
|
||||
});
|
||||
}
|
||||
for (var i = 0; i < targets.length; i++) {
|
||||
var wrapperContent = targets[i].textContent;
|
||||
if(/^(\<iframe src)/.test(wrapperContent) === false) {
|
||||
var preamble = targets[i].children[0].textContent;
|
||||
var content = targets[i].children[1].textContent;
|
||||
targets[i].innerHTML = "";
|
||||
var notebook = RunKit.createNotebook({
|
||||
element: targets[i],
|
||||
source: content,
|
||||
preamble: preamble
|
||||
});
|
||||
}
|
||||
}
|
||||
clearInterval(checkRunkit);
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@
|
|||
|
||||
<h3><strong>RunKit Embed</strong></h3>
|
||||
<p>Put executable code within a runkit liquid block, as follows:</p>
|
||||
<pre>{% runkit %}<br>console.log("Place javascript here!"); <br>{% endrunkit %} <br></pre>
|
||||
<pre>{% runkit<br>// hidden setup JavaScript code goes in this preamble area<br>const hiddenVar = 42<br>%}<br>// visible, reader-editable JavaScript code goes here<br>console.log(hiddenVar)<br>{% endrunkit %} <br></pre>
|
||||
|
||||
<h3><strong>repl.it Embed</strong></h3>
|
||||
<p>All you need is the URL after the domain name:</p>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,12 @@ require "rails_helper"
|
|||
|
||||
RSpec.describe RunkitTag, type: :liquid_template do
|
||||
describe "#render" do
|
||||
let(:preamble) do
|
||||
<<~CODE
|
||||
const myVar = 9001
|
||||
CODE
|
||||
end
|
||||
|
||||
let(:content) do
|
||||
<<~CODE
|
||||
// GeoJSON!
|
||||
|
|
@ -11,22 +17,23 @@ RSpec.describe RunkitTag, type: :liquid_template do
|
|||
CODE
|
||||
end
|
||||
|
||||
def generate_new_liquid(block)
|
||||
def generate_new_liquid(preamble_str, block)
|
||||
Liquid::Template.register_tag("runkit", described_class)
|
||||
Liquid::Template.parse("{% runkit %}#{block}{% endrunkit %}")
|
||||
Liquid::Template.parse("{% runkit #{preamble_str}%}#{block}{% endrunkit %}")
|
||||
end
|
||||
|
||||
def generate_script(block)
|
||||
def generate_script(preamble_str, block)
|
||||
<<~HTML
|
||||
<div class="runkit-element">
|
||||
#{block}
|
||||
<code style="display: none">#{preamble_str}</code>
|
||||
<code>#{block}</code>
|
||||
</div>
|
||||
HTML
|
||||
end
|
||||
|
||||
it "generates proper div with content" do
|
||||
liquid = generate_new_liquid(content)
|
||||
expect(liquid.render).to eq(generate_script(content))
|
||||
liquid = generate_new_liquid(preamble, content)
|
||||
expect(liquid.render).to eq(generate_script(preamble, content))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue