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 %}
+
+ - YouTube:
{% youtube dQw4w9WgXcQ %}
+ - Vimeo:
{% 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