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 +7 -0
- data/README.md +28 -0
- data/lib/web_components_rails/asset_tag_helper.rb +33 -0
- data/lib/web_components_rails/haml_template.rb +6 -0
- data/lib/web_components_rails/html_import_processor.rb +136 -0
- data/lib/web_components_rails/railtie.rb +25 -0
- data/lib/web_components_rails/version.rb +3 -0
- data/lib/web_components_rails.rb +10 -0
- metadata +92 -0
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,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,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: []
|