web_components_rails 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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: []