media_embed 0.1.2 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 271bd0b19f56cf30b54ac2bef3507bb358caf4ad
4
- data.tar.gz: a5a1ead1fe236e53e069f56a471848fb05d55beb
3
+ metadata.gz: a9096ec35334ef0c2f550288504a4a9dc29d5530
4
+ data.tar.gz: 2cf136dbe551deb08e635c0d7b6f71407e3d2f4c
5
5
  SHA512:
6
- metadata.gz: 9d56273b015b3b3c35eafcb1b0d8b7226e7feca49f98b18ce230c4ded1e349515b835263b69772817e3acab487ff063d8a93c1d5e2eca18f294a03d80c691493
7
- data.tar.gz: 8607ec0867624b583b30c32730a0951dae572184b6cd2ccbd556440a1c73026fb4c16ca87fc3ccb9271b143c6a545a82196de81b15c6de630e788708c9992cad
6
+ metadata.gz: bbf742c4d9efbbb0a291fb99b63589e18eae1bb13560c6f0b2c644c46501ddf15227e4829db30c536cb716e66a4f490c45e0da2d1e8511b4eb668b3dd70a0f42
7
+ data.tar.gz: 858b36547f11e620bc91f3afd6a274a9264519dd71ab92d76a56e95dc78211042c911ef678338c3cbf1c3bd455f9038008769fc3f8c2affec406680f8de6fd12
@@ -1,6 +1,8 @@
1
1
  require "media_embed/version"
2
2
  require "media_embed/railtie" if defined? Rails
3
3
 
4
+ require "media_embed/iframe_builder"
5
+ require "media_embed/options_handler"
4
6
  require "media_embed/handler"
5
7
  require "media_embed/video"
6
8
  require "media_embed/podcast"
@@ -0,0 +1,53 @@
1
+ module MediaEmbed
2
+ class IframeBuilder
3
+ IFRAME_ATTRS_WHITELIST = [ :align, :frameborder, :height,
4
+ :marginheight, :marginwidth, :name, :width, :allowfullscreen,
5
+ :webkitallowfullscreen, :mozallowfullscreen ]
6
+
7
+ NO_VALUE_OPTIONS = [
8
+ :allowfullscreen,
9
+ :webkitallowfullscreen,
10
+ :mozallowfullscreen
11
+ ]
12
+
13
+ attr_accessor :url_options, :iframe_options
14
+
15
+ def initialize(source, options = {}, url_params_whitelist = [])
16
+ @source = source
17
+ @options = Hash[options.map { |key, val| [key.to_sym, val] }]
18
+ @url_params_whitelist = url_params_whitelist
19
+
20
+ split_options
21
+ end
22
+
23
+ def build
24
+ %(<iframe src="#{@source}#{url_params_string}"#{iframe_options_string}></iframe>)
25
+ end
26
+
27
+ # private
28
+
29
+ def url_params_string
30
+ "?#{url_options.map { |name, value| "#{name}=#{value}" }.join('&')}" if url_options.any?
31
+ end
32
+
33
+ def iframe_options_string
34
+ return unless iframe_options.any?
35
+
36
+ key_value_options = iframe_options.reject { |opt_name, _| NO_VALUE_OPTIONS.include?(opt_name) }
37
+
38
+ options_string = " #{key_value_options.map { |name, value| "#{name}=\"#{value}\"" }.join(' ')}"
39
+
40
+ if NO_VALUE_OPTIONS.any? { |opt| iframe_options.keys.include? opt }
41
+ options_string = "#{options_string}#{NO_VALUE_OPTIONS.map { |opt| iframe_options[opt] ? opt.to_s : nil }.compact.join(' ')}"
42
+ end
43
+
44
+ options_string
45
+ end
46
+
47
+ def split_options
48
+ self.iframe_options = @options.select { |key, _| IFRAME_ATTRS_WHITELIST.include?(key) }
49
+ self.url_options = @options.select { |key, _| @url_params_whitelist.include?(key) }
50
+ end
51
+
52
+ end
53
+ end
@@ -0,0 +1,43 @@
1
+ module MediaEmbed
2
+ class OptionsHandler
3
+
4
+ attr_accessor :prioritized_options, :remaining_options
5
+
6
+ def initialize(prioritized_options_name, options_hash)
7
+ @prioritized_options_name = prioritized_options_name
8
+ @options_hash = transform_synonymous_keys(options_hash)
9
+
10
+ split_options
11
+ override_duplicate_remaining_options
12
+ end
13
+
14
+ def consolidate_options
15
+ prioritized_options.merge(remaining_options)
16
+ end
17
+
18
+ private
19
+
20
+ def split_options
21
+ self.remaining_options = @options_hash.dup
22
+ self.prioritized_options = remaining_options.delete(@prioritized_options_name) || {}
23
+ end
24
+
25
+ def override_duplicate_remaining_options
26
+ remaining_options.reject! do |option_name, _|
27
+ prioritized_options.keys.include?(option_name)
28
+ end
29
+ end
30
+
31
+ def transform_synonymous_keys(options)
32
+ Hash[ options.map do |key, value|
33
+ [ keys_synonym(key), value.is_a?(Hash) ? transform_synonymous_keys(value) : value ]
34
+ end
35
+ ]
36
+ end
37
+
38
+ def keys_synonym(key)
39
+ key == :auto_play ? :autoplay : key
40
+ end
41
+
42
+ end
43
+ end
@@ -1,7 +1,32 @@
1
1
  module MediaEmbed
2
2
  class Podcast
3
+
4
+ SOUNDCLOUD_SRC_WHITELIST = [ :auto_play, :buying, :color, :default_height, :default_width,
5
+ :download, :enable_api, :font, :sharing, :show_artwork, :show_bpm, :show_comments,
6
+ :show_playcount, :show_user, :single_active, :start_track, :text_buy_set, :text_buy_track,
7
+ :text_download_track, :theme_color ]
8
+
3
9
  def self.soundcloud_template(code, options = {})
4
- %Q(<iframe width="100%" height="450" scrolling="no" frameborder="no" src="https://w.soundcloud.com/player/?url=https%3A//soundcloud.com/#{code}&amp;auto_play=false&amp;hide_related=false&amp;show_comments=true&amp;show_user=true&amp;show_reposts=false&amp;visual=true"></iframe>)
10
+ source = "https://w.soundcloud.com/player?url=https%3A//soundcloud.com/#{code}"
11
+
12
+ builder = IframeBuilder.new(
13
+ source,
14
+ consolidated_options(:soundcloud, options),
15
+ SOUNDCLOUD_SRC_WHITELIST
16
+ )
17
+
18
+ builder.build
5
19
  end
20
+
21
+ def self.consolidated_options(service, options)
22
+ handler = OptionsHandler.new(service, options)
23
+
24
+ return transform_synonymous_keys(handler.consolidate_options)
25
+ end
26
+
27
+ def self.transform_synonymous_keys(options)
28
+ Hash[options.map { |k,v| [k == :autoplay ? :auto_play : k, v] }]
29
+ end
30
+
6
31
  end
7
32
  end
@@ -1,3 +1,3 @@
1
1
  module MediaEmbed
2
- VERSION = "0.1.2"
2
+ VERSION = "1.0.0"
3
3
  end
@@ -1,18 +1,42 @@
1
1
  module MediaEmbed
2
2
  class Video
3
+
4
+ YOUTUBE_SRC_WHITELIST = [ :autoplay, :cc_load_policy, :color,
5
+ :controls, :disablekb, :enablejsapi, :end, :fs, :h1, :iv_load_policy,
6
+ :list, :listType, :loop, :modestbranding, :origin, :playlist,
7
+ :playsinline, :rel, :showinfo, :start ]
8
+
9
+ VIMEO_SRC_WHITELIST = [ :autopause, :autoplay, :badge, :byline,
10
+ :color, :loop, :player_id, :portrait, :title ]
11
+
3
12
  def self.youtube_template(code, options = {})
4
- iframe("//www.youtube.com/embed/#{code}/enablejsapi=1", options)
13
+ source = "//www.youtube.com/embed/#{code}"
14
+
15
+ builder = IframeBuilder.new(
16
+ source,
17
+ consolidated_options(:youtube, options),
18
+ YOUTUBE_SRC_WHITELIST
19
+ )
20
+
21
+ builder.build
5
22
  end
6
23
 
7
24
  def self.vimeo_template(code, options = {})
8
- iframe("//player.vimeo.com/video/#{code}", options)
9
- end
25
+ source = "//player.vimeo.com/video/#{code}"
26
+
27
+ builder = IframeBuilder.new(
28
+ source,
29
+ consolidated_options(:vimeo, options),
30
+ VIMEO_SRC_WHITELIST
31
+ )
10
32
 
11
- private
33
+ builder.build
34
+ end
12
35
 
13
- def self.iframe(source, options = {})
14
- %(<iframe src='#{source}' #{options.map { |key, value| "#{key}='#{value}'" }.join(' ')}></iframe>)
36
+ def self.consolidated_options(service, options)
37
+ OptionsHandler.new(service, options).consolidate_options
15
38
  end
39
+
16
40
  end
17
41
  end
18
42
 
@@ -2,6 +2,7 @@ require 'test_helper'
2
2
  require 'media_embed/handler'
3
3
 
4
4
  class HandlerTest < Minitest::Test
5
+
5
6
  CODE = MediaEmbed::Handler::CODE
6
7
 
7
8
  YOUTUBE_URLS = %w(youtube.com/watch?v=CODE
@@ -40,4 +41,5 @@ class HandlerTest < Minitest::Test
40
41
  match = @klass.soundcloud?("irrelevantinfo#{SOUNDCLOUD_URL}")[CODE]
41
42
  assert_equal match, 'username/code-for-podcast'
42
43
  end
44
+
43
45
  end
@@ -0,0 +1,80 @@
1
+ require 'test_helper'
2
+ require 'media_embed/iframe_builder'
3
+
4
+ class IframeBuilderTest < Minitest::Test
5
+
6
+ def setup
7
+ @source = '//youtube.com/embed/1234'
8
+ end
9
+
10
+ test 'it should return an iframe with the appropriate source, given no options' do
11
+ builder = MediaEmbed::IframeBuilder.new(@source)
12
+
13
+ iframe = %(<iframe src="#{@source}"></iframe>)
14
+
15
+ assert_equal iframe, builder.build
16
+ end
17
+
18
+ test 'it should return an iframe with attributes, given valid iframe attributes' do
19
+ options = { :width => '500px' }
20
+
21
+ builder = MediaEmbed::IframeBuilder.new(@source, options)
22
+
23
+ iframe = %(<iframe src="#{@source}" width="500px"></iframe>)
24
+
25
+ assert_equal iframe, builder.build
26
+ end
27
+
28
+ test 'it should return an iframe with no attributes, given invalid iframe attributes' do
29
+ options = { :notanattr => 'fake' }
30
+
31
+ builder = MediaEmbed::IframeBuilder.new(@source, options)
32
+
33
+ iframe = %(<iframe src="#{@source}"></iframe>)
34
+
35
+ assert_equal iframe, builder.build
36
+ end
37
+
38
+ test 'it should return an iframe with a src that has parameters, given a parameters src_whitelist' do
39
+ options = { :autoplay => '0', :loop => 1 }
40
+ src_whitelist = [:autoplay, :loop]
41
+
42
+ builder = MediaEmbed::IframeBuilder.new(@source, options, src_whitelist)
43
+
44
+ iframe = %(<iframe src="#{@source}?autoplay=0&loop=1"></iframe>)
45
+
46
+ assert_equal iframe, builder.build
47
+ end
48
+
49
+ test 'it should return an iframe with a src with *only* src_whitelisted parameters' do
50
+ options = { :autoplay => '0', :loop => 1, :notanattr => 'fake' }
51
+ src_whitelist = [:autoplay, :loop]
52
+
53
+ builder = MediaEmbed::IframeBuilder.new(@source, options, src_whitelist)
54
+
55
+ refute builder.build.match('notanattr=fake')
56
+ end
57
+
58
+ test 'it should combine iframe attrs and src parameters' do
59
+ options = { :autoplay => '0', :loop => 1, :notanattr => 'fake', :width => '500px' }
60
+ src_whitelist = [:autoplay, :loop]
61
+
62
+ builder = MediaEmbed::IframeBuilder.new(@source, options, src_whitelist)
63
+
64
+ iframe = %(<iframe src="#{@source}?autoplay=0&loop=1" width="500px"></iframe>)
65
+
66
+ assert_equal iframe, builder.build
67
+ end
68
+
69
+ test 'it should deal with the allowfullscreen options correctly' do
70
+ options = { allowfullscreen: true, webkitallowfullscreen: true, mozallowfullscreen: true }
71
+ src_whitelist = []
72
+
73
+ builder = MediaEmbed::IframeBuilder.new(@source, options, src_whitelist)
74
+
75
+ iframe = %(<iframe src="#{@source}" allowfullscreen webkitallowfullscreen mozallowfullscreen></iframe>)
76
+
77
+ assert_equal iframe, builder.build
78
+ end
79
+
80
+ end
@@ -0,0 +1,54 @@
1
+ require 'test_helper'
2
+ require 'media_embed/options_handler'
3
+
4
+ class OptionsHandlerTest < Minitest::Test
5
+
6
+ test 'it should set the prioritized options' do
7
+ options = { youtube: { key: "value" }, not_youtube: "not youtube" }
8
+
9
+ handler = MediaEmbed::OptionsHandler.new(:youtube, options)
10
+
11
+ expected_options = { key: "value" }
12
+
13
+ assert_equal expected_options, handler.prioritized_options
14
+ end
15
+
16
+ test 'it should return remaining options that do not override prioritized options' do
17
+ options = { youtube: { autoplay: true }, autoplay: false, width: '500px' }
18
+
19
+ handler = MediaEmbed::OptionsHandler.new(:youtube, options)
20
+
21
+ expected_options = { width: '500px' }
22
+
23
+ assert_equal expected_options, handler.remaining_options
24
+ end
25
+
26
+ test 'it should return prioritized and remaining options, merged' do
27
+ options = { youtube: { autoplay: true }, autoplay: false, width: '500px' }
28
+
29
+ handler = MediaEmbed::OptionsHandler.new(:youtube, options)
30
+
31
+ expected_options = { autoplay: true, width: '500px' }
32
+
33
+ assert_equal expected_options, handler.consolidate_options
34
+ end
35
+
36
+ test 'it should return an empty hash for an empty hash' do
37
+ options = {}
38
+
39
+ handler = MediaEmbed::OptionsHandler.new(:youtube, options)
40
+
41
+ assert_equal options, handler.consolidate_options
42
+ end
43
+
44
+ test 'it should interpret :autoplay and :auto_play the same' do
45
+ options = { soundcloud: { auto_play: true }, autoplay: false }
46
+
47
+ handler = MediaEmbed::OptionsHandler.new(:soundcloud, options)
48
+
49
+ expected_options = { autoplay: true }
50
+
51
+ assert_equal expected_options, handler.consolidate_options
52
+ end
53
+
54
+ end
@@ -3,12 +3,41 @@ require 'media_embed/podcast'
3
3
 
4
4
  class PodcastTest < Minitest::Test
5
5
 
6
- test 'should wrap a given code in the soundcloud embed iframe' do
7
- code = '1234'
6
+ # SOUNDCLOUD
8
7
 
9
- iframe = %Q(<iframe width="100%" height="450" scrolling="no" frameborder="no" src="https://w.soundcloud.com/player/?url=https%3A//soundcloud.com/#{code}&amp;auto_play=false&amp;hide_related=false&amp;show_comments=true&amp;show_user=true&amp;show_reposts=false&amp;visual=true"></iframe>)
8
+ test 'it should call to the IframeBuilder with soundcloud source, consolidated options, and soundcloud src whitelist' do
9
+ source = 'https://w.soundcloud.com/player?url=https%3A//soundcloud.com/1234'
10
+ options = {}
11
+ consolidated_options = { consolidated: 'options' }
12
+ whitelist = MediaEmbed::Podcast::SOUNDCLOUD_SRC_WHITELIST
10
13
 
11
- assert_equal iframe, MediaEmbed::Podcast.soundcloud_template(code)
14
+ builder = MediaEmbed::IframeBuilder.new(source, options, whitelist)
15
+
16
+ MediaEmbed::Podcast.expects(:consolidated_options).with(:soundcloud, {}).returns(consolidated_options)
17
+ MediaEmbed::IframeBuilder.expects(:new).with(source, consolidated_options, whitelist).returns(builder)
18
+
19
+ MediaEmbed::Podcast.soundcloud_template('1234')
20
+ end
21
+
22
+ test 'it should call to OptionsHandler with options' do
23
+ handler = MediaEmbed::OptionsHandler.new(:soundcloud, {})
24
+
25
+ MediaEmbed::OptionsHandler.expects(:new).with(:soundcloud, {}).returns(handler)
26
+ MediaEmbed::OptionsHandler.any_instance.expects(:consolidate_options).returns({})
27
+
28
+ MediaEmbed::Podcast.consolidated_options(:soundcloud, {})
29
+ end
30
+
31
+ test 'it should interpret :autoplay as :auto_play' do
32
+ handler = MediaEmbed::OptionsHandler.new(:soundcloud, {})
33
+ options = { autoplay: true }
34
+
35
+ MediaEmbed::OptionsHandler.expects(:new).with(:soundcloud, {}).returns(handler)
36
+ MediaEmbed::OptionsHandler.any_instance.expects(:consolidate_options).returns(options)
37
+
38
+ expected_options = { auto_play: true }
39
+
40
+ assert_equal expected_options, MediaEmbed::Podcast.consolidated_options(:soundcloud, {})
12
41
  end
13
42
 
14
43
  end
@@ -3,23 +3,54 @@ require 'media_embed/video'
3
3
 
4
4
  class VideoTest < Minitest::Test
5
5
 
6
- test 'it should wrap a youtube code without options in an iframe tag' do
7
- source = '//www.youtube.com/embed/1234/enablejsapi=1'
6
+ # YOUTUBE
8
7
 
9
- assert_equal %(<iframe src='#{source}' ></iframe>), MediaEmbed::Video.youtube_template('1234')
8
+ test 'it should call to the IframeBuilder with youtube source and youtube src whitelist' do
9
+ source = '//www.youtube.com/embed/1234'
10
+ options = {}
11
+ consolidated_options = { consolidated: 'options' }
12
+ whitelist = MediaEmbed::Video::YOUTUBE_SRC_WHITELIST
13
+
14
+ builder = MediaEmbed::IframeBuilder.new(source, options, whitelist)
15
+
16
+ MediaEmbed::Video.expects(:consolidated_options).with(:youtube, {}).returns(consolidated_options)
17
+ MediaEmbed::IframeBuilder.expects(:new).with(source, consolidated_options, whitelist).returns(builder)
18
+
19
+ MediaEmbed::Video.youtube_template('1234')
10
20
  end
11
21
 
12
- test 'it should wrap a vimeo code without options in an iframe tag' do
22
+ test 'it should call to OptionsHandler with Youtube Options' do
23
+ handler = MediaEmbed::OptionsHandler.new(:youtube, {})
24
+
25
+ MediaEmbed::OptionsHandler.expects(:new).with(:youtube, {}).returns(handler)
26
+ MediaEmbed::OptionsHandler.any_instance.expects(:consolidate_options).returns({})
27
+
28
+ MediaEmbed::Video.consolidated_options(:youtube, {})
29
+ end
30
+
31
+ # VIMEO
32
+
33
+ test 'it should call the IframeBuilder with vimeo source and vimeo src whitelist' do
13
34
  source = '//player.vimeo.com/video/1234'
35
+ options = {}
36
+ consolidated_options = { consolidated: 'options' }
37
+ whitelist = MediaEmbed::Video::VIMEO_SRC_WHITELIST
38
+
39
+ builder = MediaEmbed::IframeBuilder.new(source, options, whitelist)
14
40
 
15
- assert_equal %(<iframe src='#{source}' ></iframe>), MediaEmbed::Video.vimeo_template('1234')
41
+ MediaEmbed::Video.expects(:consolidated_options).with(:vimeo, {}).returns(consolidated_options)
42
+ MediaEmbed::IframeBuilder.expects(:new).with(source, consolidated_options, whitelist).returns(builder)
43
+
44
+ MediaEmbed::Video.vimeo_template('1234')
16
45
  end
17
46
 
18
- test 'it should wrap a source with options' do
19
- source = '//www.youtube.com/embed/1234/enablejsapi=1'
20
- iframe_with_options = %(<iframe src='#{source}' width='50px' height='50px'></iframe>)
47
+ test 'it should call to OptionsHandler with Vimeo Options' do
48
+ handler = MediaEmbed::OptionsHandler.new(:vimeo, {})
49
+
50
+ MediaEmbed::OptionsHandler.expects(:new).with(:vimeo, {}).returns(handler)
51
+ MediaEmbed::OptionsHandler.any_instance.expects(:consolidate_options).returns({})
21
52
 
22
- assert_equal iframe_with_options, MediaEmbed::Video.youtube_template('1234', width: '50px', height: '50px')
53
+ MediaEmbed::Video.consolidated_options(:vimeo, {})
23
54
  end
24
55
 
25
56
  end
@@ -1,6 +1,9 @@
1
1
  require 'bundler'
2
2
  Bundler.require :default, :test
3
3
  require 'minitest/autorun'
4
+ require 'minitest/unit'
5
+
6
+ require 'mocha/mini_test'
4
7
 
5
8
  # Filter out Minitest backtrace while allowing backtrace from other libraries
6
9
  # to be shown.
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: media_embed
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - WendyBeth
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-01-06 00:00:00.000000000 Z
11
+ date: 2017-01-23 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: mocha
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: pry
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -64,12 +78,16 @@ files:
64
78
  - Rakefile
65
79
  - lib/media_embed.rb
66
80
  - lib/media_embed/handler.rb
81
+ - lib/media_embed/iframe_builder.rb
82
+ - lib/media_embed/options_handler.rb
67
83
  - lib/media_embed/podcast.rb
68
84
  - lib/media_embed/railtie.rb
69
85
  - lib/media_embed/version.rb
70
86
  - lib/media_embed/video.rb
71
87
  - lib/tasks/media_embed_tasks.rake
72
88
  - test/media_embed/handler_test.rb
89
+ - test/media_embed/iframe_builder_test.rb
90
+ - test/media_embed/options_handler_test.rb
73
91
  - test/media_embed/podcast_test.rb
74
92
  - test/media_embed/video_test.rb
75
93
  - test/test_helper.rb
@@ -99,6 +117,8 @@ specification_version: 4
99
117
  summary: Easy media embedding
100
118
  test_files:
101
119
  - test/media_embed/handler_test.rb
120
+ - test/media_embed/iframe_builder_test.rb
121
+ - test/media_embed/options_handler_test.rb
102
122
  - test/media_embed/podcast_test.rb
103
123
  - test/media_embed/video_test.rb
104
124
  - test/test_helper.rb