From 4a2a003a98ad86f4294a02ed4944eade5c800038 Mon Sep 17 00:00:00 2001 From: Josh Cheek Date: Mon, 20 Aug 2018 13:26:18 -0500 Subject: [PATCH] Feature/vimeo tag (#409) * Add liquid tag for vimeo * VimeoTag works when Markdown makes its input HTML * VimeoTag documentation --- app/liquid_tags/vimeo_tag.rb | 35 +++++++++++++++++++ app/views/pages/markdown_basics.html.erb | 7 ++-- spec/liquid_tags/vimeo_tag_spec.rb | 44 ++++++++++++++++++++++++ 3 files changed, 83 insertions(+), 3 deletions(-) create mode 100644 app/liquid_tags/vimeo_tag.rb create mode 100644 spec/liquid_tags/vimeo_tag_spec.rb diff --git a/app/liquid_tags/vimeo_tag.rb b/app/liquid_tags/vimeo_tag.rb new file mode 100644 index 000000000..01c2ccb09 --- /dev/null +++ b/app/liquid_tags/vimeo_tag.rb @@ -0,0 +1,35 @@ +class VimeoTag < LiquidTagBase + def initialize(tag_name, token, tokens) + super + @id = id_for token + @width = 710 + @height = 399 + end + + def render(_context) + finalize_html <<~HTML + + HTML + end + + private + + def id_for(input) + # This was the original plan: + # require "uri" + # File.basename URI(input).path + # But the markdown turns the link into html. This is simple enough, + # works for all the use cases and isn't exploitable. + input.to_s.scan(/\d+/).max_by(&:length) + end +end + +Liquid::Template.register_tag("vimeo", VimeoTag) diff --git a/app/views/pages/markdown_basics.html.erb b/app/views/pages/markdown_basics.html.erb index 553709ff4..96a647a1a 100644 --- a/app/views/pages/markdown_basics.html.erb +++ b/app/views/pages/markdown_basics.html.erb @@ -55,9 +55,10 @@

All you need is the gist link

{% gist https://gist.github.com/QuincyLarson/4bb1682ce590dc42402b2edddbca7aaa %} -

YouTube Embed

-

All you need is the YouTube id from the URL.

- {% youtube 9z-Pdfxxdyo %} +

Video Embed

+

All you need is the id from the URL.

+ {% youtube 9z-Pdfxxdyo %}
+ {% vimeo 193110695 %}

Instagram Embed

All you need is the Instagram post id from the URL.

diff --git a/spec/liquid_tags/vimeo_tag_spec.rb b/spec/liquid_tags/vimeo_tag_spec.rb new file mode 100644 index 000000000..cf4fc68c7 --- /dev/null +++ b/spec/liquid_tags/vimeo_tag_spec.rb @@ -0,0 +1,44 @@ +require "rails_helper" +require "nokogiri" + +RSpec.describe VimeoTag, type: :liquid_template do + let(:id) { "205930710" } + + def assert_parses(vimeo_id, token) + liquid = Liquid::Template.parse("{% vimeo #{token} %}") + html = Nokogiri.parse(liquid.render).root + expect(html.name).to eq "iframe" + expect(html[:src]).to eq "https://player.vimeo.com/video/#{vimeo_id}" + expect(html[:width]).to eq "710" + expect(html[:height]).to eq "399" + end + + it "accepts vimeo video id" do + assert_parses id, id + end + + it "accepts vimeo video id with wonky whitespace" do + assert_parses id, " #{id} \t" + end + + it "accepts a vimeo video url" do + assert_parses id, "https://vimeo.com/#{id}" + assert_parses id, "vimeo.com/#{id}" + end + + it "accepts a vimeo player url" do + assert_parses id, "https://player.vimeo.com/video/#{id}" + assert_parses id, "ps://player.vimeo.com/video/#{id}" + end + + # NOTE: This is kinda dumb. It seems like the right answer is that + # either it should run liquid before markdown, or markdown shouldn't + # mess with the liquid tags (there is a fn to escape them, but it doesn't + # seem to escape the url here) + # https://github.com/thepracticaldev/dev.to/blob/master/app/labor/markdown_parser.rb#L73-L92 + # My test suite isn't entirely passing, and I've spent longer on this than I + # wanted to, io Instead of looking into those, I'm going to just make this work ¯\_(ツ)_/¯ + it "accepts urls that were over-eagerly turned into links by markdown" do + assert_parses id, "https://vimeo.com/192819855 " + end +end