Finishes adding all the codepen embed options available (#16102)
Co-authored-by: JaneOri <7545075+James0x57@users.noreply.github.com> Co-authored-by: Michael Kohl <me@citizen428.net>
This commit is contained in:
parent
b4b12a993a
commit
d5348995c1
4 changed files with 193 additions and 5 deletions
|
|
@ -1,12 +1,15 @@
|
|||
class CodepenTag < LiquidTagBase
|
||||
PARTIAL = "liquids/codepen".freeze
|
||||
REGISTRY_REGEXP =
|
||||
%r{\A(http|https)://(codepen\.io|codepen\.io/team)/[a-zA-Z0-9_\-]{1,30}/pen/([a-zA-Z0-9]{5,32})/{0,1}\z}
|
||||
%r{\A(http|https)://(codepen\.io|codepen\.io/team)/[a-zA-Z0-9_\-]{1,30}/(pen|embed)(/preview)?/([a-zA-Z0-9]{5,32})/{0,1}\z}
|
||||
|
||||
def initialize(_tag_name, link, _parse_context)
|
||||
super
|
||||
link = CGI.unescape_html(link)
|
||||
@link = parse_link(link)
|
||||
@build_options = parse_options(link)
|
||||
valid_options = parse_options(link)
|
||||
@build_options = valid_options.gsub(/height=\d{3,4}&(amp;)?/, '')
|
||||
@height = (valid_options[/height=(\d{3,4})/, 1] || '600').to_i
|
||||
end
|
||||
|
||||
def render(_context)
|
||||
|
|
@ -14,7 +17,7 @@ class CodepenTag < LiquidTagBase
|
|||
partial: PARTIAL,
|
||||
locals: {
|
||||
link: @link,
|
||||
height: 600,
|
||||
height: @height,
|
||||
build_options: @build_options
|
||||
},
|
||||
)
|
||||
|
|
@ -23,7 +26,10 @@ class CodepenTag < LiquidTagBase
|
|||
private
|
||||
|
||||
def valid_option(option)
|
||||
option.match(/(default-tab=\w+(,\w+)?)/)
|
||||
option.match(/(default-tab=\w+(,\w+)?)/) ||
|
||||
option.match(/(theme-id=\d{1,7})/) ||
|
||||
option.match(/(editable=true)/) ||
|
||||
option.match(/(height=\d{3,4})/)
|
||||
end
|
||||
|
||||
def parse_options(input)
|
||||
|
|
@ -60,4 +66,4 @@ end
|
|||
|
||||
Liquid::Template.register_tag("codepen", CodepenTag)
|
||||
|
||||
UnifiedEmbed.register(CodepenTag, regexp: CodepenTag::REGISTRY_REGEXP)
|
||||
UnifiedEmbed.register(CodepenTag, regexp: CodepenTag::REGISTRY_REGEXP)
|
||||
|
|
@ -283,6 +283,36 @@
|
|||
<p>Add default-tab parameter to your CodePen embed tag. Defaults to <i>result</i>.</p>
|
||||
<pre>{% codepen https://codepen.io/twhite96/pen/XKqrJX default-tab=js,result %}</pre>
|
||||
</dd>
|
||||
|
||||
<dt><strong>preview</strong></dt>
|
||||
<dd>
|
||||
<p>Change the codepen URL path from /pen/ to /pen/preview/ (or to /embed/preview/) to use codepen's Click-to-Load preview embed feature in the resulting iframe.</p>
|
||||
<pre>{% codepen https://codepen.io/propjockey/pen/preview/dyVMgBg %}</pre>
|
||||
</dd>
|
||||
|
||||
<dt><strong>height</strong></dt>
|
||||
<dd>
|
||||
<p>Add height parameter to your CodePen embed tag and to the resulting iframe itself. Defaults to <i>600</i></p>
|
||||
<pre>{% codepen https://codepen.io/propjockey/pen/dyVMgBg height=300 %}</pre>
|
||||
</dd>
|
||||
|
||||
<dt><strong>theme-id</strong></dt>
|
||||
<dd>
|
||||
<p>Add theme-id parameter to your CodePen embed tag. The pen and theme-id must be from a codepen pro user to have an effect.</p>
|
||||
<pre>{% codepen https://codepen.io/propjockey/pen/dyVMgBg theme-id=40148 %}</pre>
|
||||
</dd>
|
||||
|
||||
<dt><strong>editable=true</strong></dt>
|
||||
<dd>
|
||||
<p>Add editable=true parameter to your CodePen embed tag. Editable Embeds require more resources than non-editable Embeds. The pen must be from a codepen pro user to have an effect.</p>
|
||||
<pre>{% codepen https://codepen.io/propjockey/pen/dyVMgBg editable=true %}</pre>
|
||||
</dd>
|
||||
|
||||
<dt><strong>multiple-params</strong></dt>
|
||||
<dd>
|
||||
<p>Add multiple parameters to your CodePen embed tag.</p>
|
||||
<pre>{% codepen https://codepen.io/propjockey/pen/dyVMgBg height=300 default-tab=css,result editable=true %}</pre>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<%= render partial: "editor_guide_h3", locals: { id: "kotlin-playground", title: "Kotlin Playground" } %>
|
||||
|
|
|
|||
|
|
@ -145,6 +145,36 @@
|
|||
Add default-tab parameter to your CodePen embed tag. Default to <i>result</i><br>
|
||||
<code>{% codepen https://codepen.io/twhite96/pen/XKqrJX default-tab=js,result %}</code>
|
||||
</dd>
|
||||
|
||||
<dt><code>preview</code></dt>
|
||||
<dd>
|
||||
<p>Change the codepen URL path from /pen/ to /pen/preview/ (or to /embed/preview/) to use codepen's Click-to-Load preview embed feature in the resulting iframe.</p>
|
||||
<pre>{% codepen https://codepen.io/propjockey/pen/preview/dyVMgBg %}</pre>
|
||||
</dd>
|
||||
|
||||
<dt><code>height</code></dt>
|
||||
<dd>
|
||||
<p>Add height parameter to your CodePen embed tag and to the resulting iframe itself. Defaults to <i>600</i></p>
|
||||
<pre>{% codepen https://codepen.io/propjockey/pen/dyVMgBg height=300 %}</pre>
|
||||
</dd>
|
||||
|
||||
<dt><code>theme-id</code></dt>
|
||||
<dd>
|
||||
<p>Add theme-id parameter to your CodePen embed tag. The pen and theme-id must be from a codepen pro user to have an effect.</p>
|
||||
<pre>{% codepen https://codepen.io/propjockey/pen/dyVMgBg theme-id=40148 %}</pre>
|
||||
</dd>
|
||||
|
||||
<dt><code>editable=true</code></dt>
|
||||
<dd>
|
||||
<p>Add editable=true parameter to your CodePen embed tag. Editable Embeds require more resources than non-editable Embeds. The pen must be from a codepen pro user to have an effect.</p>
|
||||
<pre>{% codepen https://codepen.io/propjockey/pen/dyVMgBg editable=true %}</pre>
|
||||
</dd>
|
||||
|
||||
<dt><code>multiple-params</code></dt>
|
||||
<dd>
|
||||
<p>Add multiple parameters to your CodePen embed tag.</p>
|
||||
<pre>{% codepen https://codepen.io/propjockey/pen/dyVMgBg height=300 default-tab=css,result editable=true %}</pre>
|
||||
</dd>
|
||||
</dl>
|
||||
<h3>Kotlin Playground</h3>
|
||||
<p>To create a runnable kotlin snippet, create a Kotlin Snippet at <a href="https://play.kotlinlang.org">https://play.kotlinlang.org</a></p>
|
||||
|
|
|
|||
|
|
@ -7,6 +7,21 @@ RSpec.describe CodepenTag, type: :liquid_tag do
|
|||
let(:codepen_team_private_link) { "https://codepen.io/team/codepen/pen/fb02c34281cb08966ec44b4e1ae22bc3" }
|
||||
let(:codepen_team_link) { "https://codepen.io/team/keyframers/pen/ZMRMEw" }
|
||||
let(:codepen_link_with_default_tab) { "https://codepen.io/twhite96/pen/XKqrJX default-tab=js,result" }
|
||||
let(:codepen_link_with_theme_id) { "https://codepen.io/propjockey/pen/dyVMgBg theme-id=40148" }
|
||||
let(:codepen_link_with_preview_indicator) { "https://codepen.io/propjockey/pen/preview/dyVMgBg" }
|
||||
let(:codepen_link_with_embed_path) { "https://codepen.io/propjockey/embed/dyVMgBg" }
|
||||
let(:codepen_link_with_embed_preview_path) { "https://codepen.io/propjockey/embed/preview/dyVMgBg" }
|
||||
let(:codepen_link_with_height_param) { "https://codepen.io/propjockey/pen/dyVMgBg height=300" }
|
||||
let(:codepen_link_with_editable_true) { "https://codepen.io/propjockey/pen/dyVMgBg editable=true" }
|
||||
let(:codepen_link_with_multiple_params) do
|
||||
"https://codepen.io/propjockey/pen/dyVMgBg theme-id=40148 default-tab=js,result height=250 editable=true"
|
||||
end
|
||||
let(:codepen_link_with_preview_and_params) do
|
||||
"https://codepen.io/propjockey/pen/preview/dyVMgBg theme-id=40148 default-tab=js,result"
|
||||
end
|
||||
let(:codepen_link_with_embed_path_and_params) do
|
||||
"https://codepen.io/propjockey/embed/dyVMgBg theme-id=40148 default-tab=js,result"
|
||||
end
|
||||
|
||||
xss_links = %w(
|
||||
//evil.com/?codepen.io
|
||||
|
|
@ -84,6 +99,113 @@ RSpec.describe CodepenTag, type: :liquid_tag do
|
|||
end.not_to raise_error
|
||||
end
|
||||
|
||||
it "accepts codepen link with a theme-id parameter" do
|
||||
expect do
|
||||
generate_new_liquid(codepen_link_with_theme_id)
|
||||
end.not_to raise_error
|
||||
|
||||
liquid = generate_new_liquid(codepen_link_with_theme_id)
|
||||
|
||||
expect(liquid.render).to include("<iframe")
|
||||
.and include('src="https://codepen.io/propjockey/embed/dyVMgBg?height=600&theme-id=40148')
|
||||
end
|
||||
|
||||
it "accepts codepen link with pen/preview in the url" do
|
||||
expect do
|
||||
generate_new_liquid(codepen_link_with_preview_indicator)
|
||||
end.not_to raise_error
|
||||
|
||||
liquid = generate_new_liquid(codepen_link_with_preview_indicator)
|
||||
|
||||
expect(liquid.render).to include("<iframe")
|
||||
.and include('src="https://codepen.io/propjockey/embed/preview/dyVMgBg')
|
||||
end
|
||||
|
||||
it "accepts codepen link with embed path in the url" do
|
||||
expect do
|
||||
generate_new_liquid(codepen_link_with_embed_path)
|
||||
end.not_to raise_error
|
||||
|
||||
liquid = generate_new_liquid(codepen_link_with_embed_path)
|
||||
|
||||
expect(liquid.render).to include("<iframe")
|
||||
.and include('src="https://codepen.io/propjockey/embed/dyVMgBg')
|
||||
end
|
||||
|
||||
it "accepts codepen link with embed/preview in the url" do
|
||||
expect do
|
||||
generate_new_liquid(codepen_link_with_embed_preview_path)
|
||||
end.not_to raise_error
|
||||
|
||||
liquid = generate_new_liquid(codepen_link_with_embed_preview_path)
|
||||
|
||||
expect(liquid.render).to include("<iframe")
|
||||
.and include('src="https://codepen.io/propjockey/embed/preview/dyVMgBg')
|
||||
end
|
||||
|
||||
it "accepts codepen link with a height parameter" do
|
||||
expect do
|
||||
generate_new_liquid(codepen_link_with_height_param)
|
||||
end.not_to raise_error
|
||||
|
||||
liquid = generate_new_liquid(codepen_link_with_height_param)
|
||||
|
||||
expect(liquid.render).to include("<iframe")
|
||||
.and include('height="300"')
|
||||
.and include('src="https://codepen.io/propjockey/embed/dyVMgBg?height=300')
|
||||
end
|
||||
|
||||
it "accepts codepen link with a editable=true parameter" do
|
||||
expect do
|
||||
generate_new_liquid(codepen_link_with_editable_true)
|
||||
end.not_to raise_error
|
||||
|
||||
liquid = generate_new_liquid(codepen_link_with_editable_true)
|
||||
|
||||
expect(liquid.render).to include("<iframe")
|
||||
.and include('src="https://codepen.io/propjockey/embed/dyVMgBg?height=600&editable=true')
|
||||
end
|
||||
|
||||
it "accepts codepen link with multiple params" do
|
||||
expect do
|
||||
generate_new_liquid(codepen_link_with_multiple_params)
|
||||
end.not_to raise_error
|
||||
|
||||
liquid = generate_new_liquid(codepen_link_with_multiple_params)
|
||||
|
||||
expect(liquid.render).to include("<iframe")
|
||||
.and include('height="250"')
|
||||
.and include(
|
||||
'src="https://codepen.io/propjockey/embed/dyVMgBg?height=250&theme-id=40148&default-tab=js,result&editable=true',
|
||||
)
|
||||
end
|
||||
|
||||
it "accepts codepen link with preview and params" do
|
||||
expect do
|
||||
generate_new_liquid(codepen_link_with_preview_and_params)
|
||||
end.not_to raise_error
|
||||
|
||||
liquid = generate_new_liquid(codepen_link_with_preview_and_params)
|
||||
|
||||
expect(liquid.render).to include("<iframe")
|
||||
.and include(
|
||||
'src="https://codepen.io/propjockey/embed/preview/dyVMgBg?height=600&theme-id=40148&default-tab=js,result',
|
||||
)
|
||||
end
|
||||
|
||||
it "accepts codepen link with embed and params" do
|
||||
expect do
|
||||
generate_new_liquid(codepen_link_with_embed_path_and_params)
|
||||
end.not_to raise_error
|
||||
|
||||
liquid = generate_new_liquid(codepen_link_with_embed_path_and_params)
|
||||
|
||||
expect(liquid.render).to include("<iframe")
|
||||
.and include(
|
||||
'src="https://codepen.io/propjockey/embed/dyVMgBg?height=600&theme-id=40148&default-tab=js,result',
|
||||
)
|
||||
end
|
||||
|
||||
it "rejects XSS attempts" do
|
||||
xss_links.each do |link|
|
||||
expect { generate_new_liquid(link) }.to raise_error(StandardError)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue