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:
Andrew Bone 2019-01-17 20:44:01 +00:00 committed by Ben Halpern
parent 7d98a79b6f
commit b56865915c
4 changed files with 122 additions and 0 deletions

View 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)

View file

@ -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>

View 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

View file

@ -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>