web_components_rails 1.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4616f8671aeb678bfe6d123e1fd8ac02d855e472
4
+ data.tar.gz: 81c4c56577ef7b1cf492872597a69ae0384cfa19
5
+ SHA512:
6
+ metadata.gz: cdec8bfd0dab8414ae902409ac78d13bb4bb0c13265092b11a3f4e5561fbcac97c0fdf2fa5bba46f0f9e908ffbd98c6498e9c5e94f76d904eaf2af13d4ce39f7
7
+ data.tar.gz: 673f4240b5efb0b23fa829022eb6b71a0893744c65c7f2c9ff81f220b7a7136d0d4839781fa57142e168a24751034ee5c823edffc9ee80a920b26773ba0a793c
data/README.md ADDED
@@ -0,0 +1,28 @@
1
+ # web_components_rails
2
+ Ruby gem for using web components in Rails applications.
3
+
4
+ ## Usage
5
+ 1. Include the gem in your Gemfile:
6
+ ```ruby
7
+ gem 'web_components_rails'
8
+ ```
9
+ 2. Add an HTML file to your project (can be just HTML or a Polymer component):
10
+ ```html
11
+ <!-- app/assets/javascripts/my_component.html -->
12
+ <h1>Hello</h1>
13
+ ```
14
+ 3. Include a web component in one of your views:
15
+ ```erb
16
+ <%= html_import_tag 'my_component' %>
17
+ ```
18
+
19
+ ## Building
20
+
21
+ After adding new features or fixes, please update the version in version.rb, and then tag the repo appropriately:
22
+
23
+ ```
24
+ git tag -a -m 'Added foo' 1.1.0
25
+ git push --tags
26
+ ```
27
+
28
+ To release the gem (internally), use `rake build`, and push the gem with stickler.
@@ -0,0 +1,33 @@
1
+ module WebComponentsRails::AssetTagHelper
2
+ # Based on stylesheet_link_tag_with_print in Sprockets
3
+ def html_import_tag(*sources)
4
+ options = sources.extract_options!.stringify_keys
5
+ path_options = options.extract!('protocol').symbolize_keys
6
+ debug_mode = options['debug'] != false && request_debug_assets?
7
+
8
+ sources.map do |source|
9
+ check_errors_for(source, type: :html)
10
+ # In debug mode, include each html asset separately (if we can find the asset)
11
+ if debug_mode
12
+ asset = lookup_asset_for_path(source, type: :html)
13
+ asset.to_a.map do |a|
14
+ _html_import_tag(path_to_asset(a.logical_path, path_options.merge(debug: true)))
15
+ end
16
+ # In production mode, or when we can't find the asset, fall back to a single tag
17
+ else
18
+ _html_import_tag(source, path_options)
19
+ end
20
+ end.flatten.uniq.join("\n").html_safe
21
+ end
22
+
23
+
24
+ private
25
+
26
+ def _html_import_tag(source, path_options = {})
27
+ tag_options = {
28
+ rel: 'import',
29
+ href: path_to_asset(source, path_options.merge(extname: '.html', type: :html))
30
+ }
31
+ tag(:link, tag_options)
32
+ end
33
+ end
@@ -0,0 +1,6 @@
1
+ class WebComponentsRails::HamlTemplate < Tilt::HamlTemplate
2
+ def prepare
3
+ @options = @options.merge(format: :html5)
4
+ super
5
+ end
6
+ end
@@ -0,0 +1,136 @@
1
+ require 'securerandom'
2
+
3
+ # Processes web component HTML files that contains imports
4
+ # See also:
5
+ # https://github.com/rails/sprockets/blob/master/UPGRADING.md
6
+ # https://github.com/rails/sprockets/blob/3.x/lib/sprockets/directive_processor.rb
7
+ class WebComponentsRails::HTMLImportProcessor
8
+
9
+ VERSION = '7'
10
+
11
+ def self.instance
12
+ @instance ||= new
13
+ end
14
+
15
+ def self.call(input)
16
+ instance.call(input)
17
+ end
18
+
19
+ def self.cache_key
20
+ instance.cache_key
21
+ end
22
+
23
+ attr_reader :cache_key
24
+
25
+ def initialize(options = {})
26
+ @cache_key = [self.class.name, VERSION, options].freeze
27
+ end
28
+
29
+ def call(input)
30
+ @context = input[:environment].context_class.new(input)
31
+ @data = input[:data]
32
+ @filename = input[:filename]
33
+ @dirname = File.dirname(@filename)
34
+
35
+ @data, paths = process_imports(@data, @dirname)
36
+ paths.each do |path|
37
+ @context.require_asset(path)
38
+ end
39
+
40
+ @context.metadata.merge(data: @data)
41
+ end
42
+
43
+
44
+ protected
45
+
46
+ def process_imports(html, base_dir)
47
+ doc = Nokogiri::HTML5.fragment(html)
48
+
49
+ # Process HTML and CSS imports
50
+ dependencies = doc.css('link').map do |link|
51
+ href = link.attributes['href'].value
52
+ path = href_to_asset_path(href, base_dir)
53
+ rel = link.attributes['rel'].value
54
+ type_attr = link.attributes['type']
55
+ # The rel determines what type it is by default, but an explicit type will always supercede this
56
+ if type_attr
57
+ type = type_attr.value.downcase
58
+ elsif rel == 'import'
59
+ type = 'html'
60
+ elsif rel == 'stylesheet'
61
+ type = 'css'
62
+ # Unknown link type; ignore
63
+ else
64
+ type = nil
65
+ end
66
+
67
+ case type
68
+ # HTML needs to be required as an external dependency, with the import removed
69
+ when 'html', 'text/html'
70
+ link.remove
71
+ href_to_asset_path(href, base_dir)
72
+ # CSS needs to be inlined
73
+ when 'css', 'text/css'
74
+ asset = ::Rails.application.assets.find_asset(path, accept: 'text/css')
75
+ # Replace it inline with a style node containing the referenced CSS
76
+ style = Nokogiri::XML::Element.new('style', doc)
77
+ style.inner_html = asset.source
78
+ link.replace(style)
79
+ nil
80
+ # Ignore unknown types
81
+ else
82
+ nil
83
+ end
84
+ end.compact
85
+
86
+ # Script/JS imports should just have their src rewritten to work with sprockets
87
+ # (because they could repeat a lot, and we can't mark non-HTML files as dependencies)
88
+ doc.css('script[src]').map do |script|
89
+ puts "SCRIPT"
90
+ src = script.attributes['src'].value
91
+ if src.present?
92
+ # Some references may try to be relative to the bower_components root,
93
+ # which is already in the asset pipeline search path; fix those
94
+ # (eg. from 'web_components/lib-a/foo.html', <script src='../lib-b/bar.js'> -> 'lib-b/bar.js')
95
+ src = src.sub(/^..\//, '')
96
+ new_script = Nokogiri::XML::Element.new('script', doc)
97
+ new_script['src'] = @context.asset_path(src)
98
+ script.replace(new_script)
99
+ end
100
+ end
101
+
102
+ # Nokogiri/Nokogumbo are hard-coded to URI-escape certain attributes (src, href, action, and a[name]),
103
+ # so we have to put in placeholders, and fix the values in the HTML string output afterwards
104
+ # This doesn't work so well with framework-specific syntax (eg. <foo src="{{bar}}">)
105
+ placeholder_mapping = {}
106
+ %w(src href action).each do |name|
107
+ doc.css("[#{name}]").each do |node|
108
+ # The placeholders are just random strings
109
+ placeholder = SecureRandom.hex(40)
110
+ attr = node.attributes[name]
111
+ placeholder_mapping[placeholder] = attr.value
112
+ attr.value = placeholder
113
+ end
114
+ end
115
+ new_html = doc.to_html
116
+ placeholder_mapping.each do |placeholder, value|
117
+ new_html.sub!(placeholder, value)
118
+ end
119
+
120
+ [new_html, dependencies]
121
+ end
122
+
123
+ def href_to_asset_path(href, base_dir)
124
+ abs_path = File.expand_path(File.join(base_dir, href))
125
+ # If it is relative to the current dir, we should be able to find it easily
126
+ if File.exist?(abs_path)
127
+ abs_path
128
+ # Otherwise, just return it as a relative path, and hope sprockets can find it in an asset dir
129
+ else
130
+ # Sometimes we prefix with /assets/ to make the HTML work in the browser without asset-pipeline.
131
+ # We don't need this when using require with sprockets.
132
+ href.sub(%r{^/assets/}, '')
133
+ end
134
+ end
135
+
136
+ end
@@ -0,0 +1,25 @@
1
+ require 'haml'
2
+ class WebComponentsRails::Railtie < Rails::Railtie
3
+ # Register our asset tag helpers
4
+ initializer 'web_components.asset_tag_helper' do
5
+ ActionView::Base.module_eval do
6
+ include WebComponentsRails::AssetTagHelper
7
+ end
8
+ # Certain run modes in Rails (like rails g migration), won't have assets loaded
9
+ if Rails.application.assets.present?
10
+ Rails.application.assets.context_class.class_eval do
11
+ include WebComponentsRails::AssetTagHelper
12
+ end
13
+ end
14
+ end
15
+
16
+ # Allows HAML templates to be used with asset pipeline
17
+ initializer 'web_components.sprockets', after: 'sprockets.environment', group: :all do |app|
18
+ app.assets.register_mime_type 'text/html', extensions: ['.html', '.haml']
19
+ app.assets.register_preprocessor 'text/html', Sprockets::DirectiveProcessor
20
+ app.assets.register_preprocessor 'text/html', WebComponentsRails::HTMLImportProcessor
21
+ app.assets.register_engine '.haml', WebComponentsRails::HamlTemplate
22
+ app.assets.register_bundle_processor 'text/html', ::Sprockets::Bundle
23
+ end
24
+ end
25
+
@@ -0,0 +1,3 @@
1
+ module WebComponentsRails
2
+ VERSION = '1.1.0'
3
+ end
@@ -0,0 +1,10 @@
1
+ require 'nokogumbo'
2
+
3
+ module WebComponentsRails
4
+ end
5
+
6
+ require 'web_components_rails/asset_tag_helper'
7
+ require 'web_components_rails/haml_template'
8
+ require 'web_components_rails/html_import_processor'
9
+ require 'web_components_rails/railtie'
10
+ require 'web_components_rails/version'
metadata ADDED
@@ -0,0 +1,92 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: web_components_rails
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Jon Botelho
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-03-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: nokogumbo
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 1.4.5
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 1.4.5
27
+ - !ruby/object:Gem::Dependency
28
+ name: railties
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 4.0.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 4.0.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: sprockets
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: 3.0.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: 3.0.0
55
+ description: Web components utils for rails
56
+ email:
57
+ - jon@jbotelho.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - README.md
63
+ - lib/web_components_rails.rb
64
+ - lib/web_components_rails/asset_tag_helper.rb
65
+ - lib/web_components_rails/haml_template.rb
66
+ - lib/web_components_rails/html_import_processor.rb
67
+ - lib/web_components_rails/railtie.rb
68
+ - lib/web_components_rails/version.rb
69
+ homepage:
70
+ licenses: []
71
+ metadata: {}
72
+ post_install_message:
73
+ rdoc_options: []
74
+ require_paths:
75
+ - lib
76
+ required_ruby_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ required_rubygems_version: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ requirements: []
87
+ rubyforge_project:
88
+ rubygems_version: 2.5.1
89
+ signing_key:
90
+ specification_version: 4
91
+ summary: Web components utils for rails
92
+ test_files: []