From da87fe2e0d4ba9f5ac0f71010437687cc961883c Mon Sep 17 00:00:00 2001 From: Andy Zhao Date: Thu, 13 Sep 2018 14:21:10 -0400 Subject: [PATCH] Fix YouTube tag (#649) * Fix YouTube tag * Remove solargraph from VS Code recommendations * Update editor guide for more clarity --- .vscode/extensions.json | 1 - app/liquid_tags/youtube_tag.rb | 28 ++++------ app/views/pages/_editor_guide_text.html.erb | 10 +++- spec/liquid_tags/youtube_tag_spec.rb | 61 +++++++++++++++++---- 4 files changed, 68 insertions(+), 32 deletions(-) diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 5af2af1354d30..d2f44ed5c5bd1 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -5,7 +5,6 @@ "donjayamanne.git-extension-pack", "msjsdiag.debugger-for-chrome", "rebornix.ruby", - "castwide.solargraph", "MS-vsliveshare.vsliveshare-pack" ] } diff --git a/app/liquid_tags/youtube_tag.rb b/app/liquid_tags/youtube_tag.rb index 94aa503d72e38..fb6626adca298 100644 --- a/app/liquid_tags/youtube_tag.rb +++ b/app/liquid_tags/youtube_tag.rb @@ -21,31 +21,25 @@ def render(_context) private def parse_id(input) - input = translate_url(input) if input.include?("watch?v=") - input = translate_start_time(input) if input.include?("?t=") input_no_space = input.delete(" ") - if valid_id?(input_no_space) - input_no_space - else - raise StandardError, "Invalid Youtube Id" - end - end - - def translate_url(input) - input.split("watch?v=")[1].split("\"")[0] + raise StandardError, "Invalid YouTube ID" unless valid_id?(input_no_space) + return translate_start_time(input_no_space) if input_no_space.include?("?t=") + input_no_space end def translate_start_time(id) time = id.split("?t=")[-1] - if /(\d+)m(\d+)s/.match?(time) - time = time.scan(/(\d+)m(\d+)s/)[0].map(&:to_i) - seconds = time[1] + (time[0] * 60) - "#{id.split('?t=')[0]}?start=#{seconds}" - end + time_hash = { + h: time.scan(/\d+h/)[0]&.delete("h").to_i, + m: time.scan(/\d+m/)[0]&.delete("m").to_i, + s: time.scan(/\d+s/)[0]&.delete("s").to_i + } + time_in_seconds = (time_hash[:h] * 3600) + (time_hash[:m] * 60) + time_hash[:s] + "#{id.split('?t=')[0]}?start=#{time_in_seconds}" end def valid_id?(id) - id =~ /[a-zA-Z0-9_-]{11}(\?start\=\d*)?/ + id =~ /\A[a-zA-Z0-9_-]{11}((\?t\=)?(\d{1}h)?(\d{1,2}m)?(\d{1,2}s)?){5,11}?\Z/ end end diff --git a/app/views/pages/_editor_guide_text.html.erb b/app/views/pages/_editor_guide_text.html.erb index aa9f5e8090016..387b6fdf6187c 100644 --- a/app/views/pages/_editor_guide_text.html.erb +++ b/app/views/pages/_editor_guide_text.html.erb @@ -87,12 +87,16 @@

GitHub Gist Embed

All you need is the gist link:

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

Video Embed

All you need is the id from the URL. - {% youtube dQw4w9WgXcQ %} - {% vimeo 193110695 %}
+

CodePen Embed

All you need is the full CodePen link, ending in the pen ID code, as follows:

diff --git a/spec/liquid_tags/youtube_tag_spec.rb b/spec/liquid_tags/youtube_tag_spec.rb index ac2e0dbb36199..7de0970b24974 100644 --- a/spec/liquid_tags/youtube_tag_spec.rb +++ b/spec/liquid_tags/youtube_tag_spec.rb @@ -2,7 +2,33 @@ RSpec.describe YoutubeTag, type: :liquid_template do describe "#id" do - let(:youtube_id) { "dQw4w9WgXcQ" } + let(:valid_id_no_time) { "dQw4w9WgXcQ" } + + let(:valid_ids_with_time) do + %w( + QASbw8_0meM?t=8h12m26s + QASbw8_0meM?t=6h34m + QASbw8_0meM?t=7h + QASbw8_0meM?t=1h57s + dQw4w9WgXcQ?t=4m45s + dQw4w9WgXcQ?t=5m + dQw4w9WgXcQ?t=8s + ) + end + + let(:invalid_id) { Faker::Lorem.characters(rand(12..100)) } + + def parsed_id(id) + return id unless id.include?("?t=") + id_array = id.split("?t=") + time_hash = { + h: id_array[1].scan(/\d+h/)[0]&.delete("h").to_i, + m: id_array[1].scan(/\d+m/)[0]&.delete("m").to_i, + s: id_array[1].scan(/\d+s/)[0]&.delete("s").to_i + } + time_string = ((time_hash[:h] * 3600) + (time_hash[:m] * 60) + time_hash[:s]).to_s + "#{id_array[0]}?start=#{time_string}" + end def generate_new_liquid(id) Liquid::Template.register_tag("youtube", YoutubeTag) @@ -13,24 +39,37 @@ def generate_iframe(id) "" end - it "accepts youtube video id" do - liquid = generate_new_liquid(youtube_id) - expect(liquid.render).to eq(generate_iframe(youtube_id)) + it "accepts a valid YouTube ID with no starting time" do + liquid = generate_new_liquid(valid_id_no_time) + expect(liquid.render).to eq(generate_iframe(valid_id_no_time)) + end + + it "accepts valid YouTube IDs with starting times" do + valid_ids_with_time.each do |id| + generated_liquid = generate_new_liquid(id) + expect(generated_liquid.render).to eq generate_iframe(id) + end + end + + it "accepts YouTube ID with no start time and an empty space" do + liquid = generate_new_liquid(valid_id_no_time + " ") + expect(liquid.render).to eq(generate_iframe(valid_id_no_time)) end - it "accepts youtube video id with empty space" do - liquid = generate_new_liquid(youtube_id + " ") - expect(liquid.render).to eq(generate_iframe(youtube_id)) + it "accepts YouTube IDs with start times and one empty space" do + valid_ids_with_time.each do |id| + generated_liquid = generate_new_liquid(id + " ") + expect(generated_liquid.render).to eq generate_iframe(id) + end end - it "accepts youtube video id with start time" do - liquid = generate_new_liquid(youtube_id + "?t=1m7s") - expect(liquid.render).to eq(generate_iframe(youtube_id + "?start=67")) + it "raises an error for invalid IDs" do + expect { generate_new_liquid(invalid_id).render }.to raise_error("Invalid YouTube ID") end end end