Added the 'initalpath' and 'module' options to the codesandbox embed (#1545)

* Added the 'initalpath' and 'module' options to the codesandbox embed and updated the help page.

* Fixed spelling errors.

* Rework from previous PR: Improved exception text. Improved regex for detecting invalid options. Changed logic to raise an exception if any invalid options are found by moving the exception raising to be inside the valid_option() method.

* Added unit tests for codesandbox_tag.rb.
This commit is contained in:
Dave Follett 2019-01-21 17:39:09 -05:00 committed by Mac Siri
parent 77dc803998
commit 03bdf63ce4
3 changed files with 105 additions and 8 deletions

View file

@ -2,30 +2,53 @@ class CodesandboxTag < LiquidTagBase
def initialize(tag_name, id, tokens)
super
@id = parse_id(id)
@query = parse_options(id)
end
def render(_context)
'<iframe src="https://codesandbox.io/embed/' + @id + '"
'<iframe src="https://codesandbox.io/embed/' + @id + @query + '"
style="width:100%; height:calc(300px + 8vw); border:0; border-radius: 4px; overflow:hidden;"
sandbox="allow-same-origin allow-scripts allow-forms allow-top-navigation-by-user-activation"
sandbox="allow-same-origin allow-scripts allow-forms allow-top-navigation-by-user-activation>"
</iframe>'
end
private
def parse_id(input)
input_no_space = input.delete(" ")
if valid_id?(input_no_space)
input_no_space
else
raise StandardError, "Invalid codesandbox Id"
id = input.split(" ").first
raise StandardError, "CodeSandbox Error: Invalid ID" unless valid_id?(id)
end
id
end
def valid_id?(id)
id =~ /\A[a-zA-Z0-9\-]{0,60}\Z/
end
def parse_options(input)
_, *options = input.split(" ")
options.map { |o| valid_option(o) }.reject { |e| e == nil }
query = options.join("&")
if query.blank?
query
else
"?#{query}"
end
end
# Valid options must start with 'initialpath=' or 'module=' and a string of at least 1 length
# composed of letters, numbers, dashes, underscores, forward slashes, @ signs, periods/dots,
# and % symbols. Invalid options will raise an exception
def valid_option(option)
if (option =~ /\A(initialpath=([a-zA-Z0-9\-\_\/\.\@\%])+)\Z|\A(module=([a-zA-Z0-9\-\_\/\.\@\%])+)\Z/)&.zero?
option
else
raise StandardError, "CodeSandbox Error: Invalid options"
end
end
end
Liquid::Template.register_tag("codesandbox", CodesandboxTag)

View file

@ -148,6 +148,18 @@
<h3><strong>CodeSandbox Embed</strong></h3>
<p>All you need is the ID of the Sandbox:</p>
<code>{% codesandbox ppxnl191zx %}</code>
<p>Of CodeSandbox's many <a href="https://codesandbox.io/docs/embedding#embed-options">optional attributes</a>, the following are supported by using them in your tag, just add them after the id, separated by spaces.</p>
<dl>
<dt><code>initialpath</code></dt>
<dd>
Which url to initially load in address bar.<br/>
<code>{% codesandbox ppxnl191zx initialpath=/initial/load/path %}</code>
</dd>
<dt><code>module</code></dt>
<dd>
Which module to open by default.<br/>
<code>{% codesandbox ppxnl191zx module=/path/to/module %}</code>
</dd>
<h3><strong>JSFiddle Embed</strong></h3>
<p>All you need is the full JSFiddle <code>link</code>, ending in the fiddle ID code, as follows:</p>

View file

@ -0,0 +1,62 @@
require "rails_helper"
RSpec.describe CodesandboxTag, type: :liquid_template do
describe "#id" do
let(:valid_id) { "22qaa1wcxr" }
let(:valid_id_with_initialpath) { "68jkdlsaie initialpath=/initial/path/file.js" }
let(:valid_id_with_module) { "28qvv1wvxr module=/path/to/module.html" }
let(:valid_id_with_initialpath_and_module) { "43lkjfdauf initialpath=/initial-path/file.js module=/path/to/module.html" }
let(:valid_id_with_special_characters) { "68jkfdsasa initialpath=/.@%_- module=-/%@._" }
let(:bad_ids) do
[
"28qvv1wvxr initialpath=((",
"22qaa1wcxr module=",
"68jkdlsaie initialpath=uses-a-(",
"68jkfdsasa initialpath=/uses-a-semi-colon-;",
"43lkjfdauf module= initialpath=",
"89fadksjhe random=/stuff",
"initialpath=/initial/path/file.js",
"54jfadslkj module=stuff \"onmouseover='alert(\"XSS\")'",
"42fadfdaf;",
"%&*($#@$&=",
]
end
def generate_tag(id)
Liquid::Template.register_tag("codesandbox", CodesandboxTag)
Liquid::Template.parse("{% codesandbox #{id} %}")
end
it "accepts a vaild id" do
liquid = generate_tag(valid_id)
expect(liquid.render).to include("<iframe")
end
it "accepts a vaild id with initialpath" do
liquid = generate_tag(valid_id_with_initialpath)
expect(liquid.render).to include("<iframe")
end
it "accepts a vaild id with module" do
liquid = generate_tag(valid_id_with_module)
expect(liquid.render).to include("<iframe")
end
it "accepts a vaild id with initialpath and module" do
liquid = generate_tag(valid_id_with_initialpath_and_module)
expect(liquid.render).to include("<iframe")
end
it "accepts a vaild id with special_characters of / . @ % _ " do
liquid = generate_tag(valid_id_with_special_characters)
expect(liquid.render).to include("<iframe")
end
it "rejects bad ids" do
bad_ids.each do |id|
expect { generate_tag(id) } .to raise_error(StandardError)
end
end
end
end