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:
parent
77dc803998
commit
03bdf63ce4
3 changed files with 105 additions and 8 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
62
spec/liquid_tags/codesandbox_tag_spec.rb
Normal file
62
spec/liquid_tags/codesandbox_tag_spec.rb
Normal 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
|
||||
Loading…
Add table
Reference in a new issue