Jsfiddle LiquidTag (#1509)
* Create jsfiddle_tag.rb Add liquid tag for jsfiddle * Create jsfiddle_tag-spec.rb Add liquid tag for jsfiddle * Update _editor_guide_text.html.erb Add liquid tag for jsfiddle * Updates for rubocop * Edit boilerplate Change some of the boiler plate code. * rubocop compliance * Fixed name Fixed file name * Fixed boiler plate Changed codepen to jsfiddle * Update guide text Change the Guide Text to be jsfiddle specific. Co-Authored-By: Link2Twenty <AndrewB05@gmail.com> * Fixed typo in spec Co-Authored-By: Link2Twenty <AndrewB05@gmail.com> * Update Valid Link * Update jsfiddle_tag.rb * Add Approved html * Remove double slash * Revert change * Fix XSS error * Remove extra line * Remove extra slash * Remove extra slash * Make DRY * rubocop compliance * Change test logic * Revert test to Approvals * Fix HTML approved
This commit is contained in:
parent
7d98a79b6f
commit
b56865915c
4 changed files with 122 additions and 0 deletions
55
app/liquid_tags/jsfiddle_tag.rb
Normal file
55
app/liquid_tags/jsfiddle_tag.rb
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
class JSFiddleTag < LiquidTagBase
|
||||
def initialize(tag_name, link, tokens)
|
||||
super
|
||||
@link = parse_link(link)
|
||||
@build_options = parse_options(link)
|
||||
@height = 600
|
||||
end
|
||||
|
||||
def render(_context)
|
||||
html = <<-HTML
|
||||
<iframe
|
||||
src="#{@link}/embedded/#{@build_options}/dark"
|
||||
width="100%"
|
||||
height="#{@height}"
|
||||
scrolling="no"
|
||||
frameborder="no"
|
||||
allowfullscreen
|
||||
allowtransparency="true">
|
||||
</iframe>
|
||||
HTML
|
||||
finalize_html(html)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def valid_option(option)
|
||||
option.match(/^(js|html|css|result|,)*\z/)
|
||||
end
|
||||
|
||||
def parse_options(input)
|
||||
stripped_link = ActionController::Base.helpers.strip_tags(input)
|
||||
_, *options = stripped_link.split(" ")
|
||||
|
||||
# Validation
|
||||
validated_options = options.map { |o| valid_option(o) }.reject { |e| e == nil }
|
||||
raise StandardError, "Invalid Options" unless options.empty? || !validated_options.empty?
|
||||
|
||||
validated_options.length.zero? ? "" : validated_options.join(",").concat("/")
|
||||
end
|
||||
|
||||
def parse_link(link)
|
||||
stripped_link = ActionController::Base.helpers.strip_tags(link)
|
||||
the_link = stripped_link.split(" ").first
|
||||
raise StandardError, "Invalid JSFiddle URL" unless valid_link?(the_link)
|
||||
|
||||
the_link
|
||||
end
|
||||
|
||||
def valid_link?(link)
|
||||
link_no_space = link.delete(" ")
|
||||
(link_no_space =~ /^(http|https):\/\/(jsfiddle\.net)\/[a-zA-Z0-9\-\/]*\z/).zero?
|
||||
end
|
||||
end
|
||||
|
||||
Liquid::Template.register_tag("jsfiddle", JSFiddleTag)
|
||||
|
|
@ -148,6 +148,17 @@
|
|||
<h3><strong>CodeSandbox Embed</strong></h3>
|
||||
<p>All you need is the ID of the Sandbox:</p>
|
||||
<code>{% codesandbox ppxnl191zx %}</code>
|
||||
|
||||
<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>
|
||||
<code>{% jsfiddle https://jsfiddle.net/link2twenty/v2kx9jcd %}</code>
|
||||
|
||||
<dl>
|
||||
<dt><code>Custom tabs</code></dt>
|
||||
<dd>
|
||||
You can add a custom tab order to you JSFiddle embed tag. Defaults to <i>js,html,css,result</i><br/>
|
||||
<code>{% jsfiddle https://jsfiddle.net/webdevem/Q8KVC result,html,css %}</code>
|
||||
</dd>
|
||||
|
||||
<h3><strong>repl.it Embed</strong></h3>
|
||||
<p>All you need is the URL after the domain name:</p>
|
||||
|
|
|
|||
50
spec/liquid_tags/jsfiddle_tag_spec.rb
Normal file
50
spec/liquid_tags/jsfiddle_tag_spec.rb
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
require "rails_helper"
|
||||
|
||||
RSpec.describe JSFiddleTag, type: :liquid_template do
|
||||
describe "#link" do
|
||||
let(:jsfiddle_link) { "http://jsfiddle.net/link2twenty/v2kx9jcd" }
|
||||
let(:jsfiddle_link_with_custom_tabs) { "http://jsfiddle.net/link2twenty/v2kx9jcd result,html,css" }
|
||||
|
||||
xss_links = %w(
|
||||
//evil.com/?jsfiddle.net
|
||||
https://jsfiddle.net.evil.com
|
||||
https://jsfiddle.net/some_username/pen/" onload='alert("xss")'
|
||||
)
|
||||
|
||||
def generate_new_liquid(link)
|
||||
Liquid::Template.register_tag("jsfiddle", JSFiddleTag)
|
||||
Liquid::Template.parse("{% jsfiddle #{link} %}")
|
||||
end
|
||||
|
||||
it "accepts jsfiddle link" do
|
||||
liquid = generate_new_liquid(jsfiddle_link)
|
||||
rendered_jsfiddle_iframe = liquid.render
|
||||
Approvals.verify(rendered_jsfiddle_iframe, name: "jsfiddle_liquid_tag", format: :html)
|
||||
end
|
||||
|
||||
it "accepts jsfiddle link with a / at the end" do
|
||||
jsfiddle_link = "http://jsfiddle.net/link2twenty/v2kx9jcd/"
|
||||
expect do
|
||||
generate_new_liquid(jsfiddle_link)
|
||||
end.not_to raise_error
|
||||
end
|
||||
|
||||
it "rejects invalid jsfiddle link" do
|
||||
expect do
|
||||
generate_new_liquid("invalid_jsfiddle_link")
|
||||
end.to raise_error(StandardError)
|
||||
end
|
||||
|
||||
it "accepts jsfiddle link with a custom-tab parameter" do
|
||||
expect do
|
||||
generate_new_liquid(jsfiddle_link_with_custom_tabs)
|
||||
end.not_to raise_error
|
||||
end
|
||||
|
||||
it "rejects XSS attempts" do
|
||||
xss_links.each do |link|
|
||||
expect { generate_new_liquid(link) }.to raise_error(StandardError)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<body>
|
||||
<iframe src="http://jsfiddle.net/link2twenty/v2kx9jcd/embedded//dark" width="100%" height="600" scrolling="no" frameborder="no" allowfullscreen="" allowtransparency="true"> </iframe>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Add table
Reference in a new issue