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 +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: []
|