├── .bowerrc ├── lib ├── generators │ └── polymer │ │ ├── component │ │ ├── templates │ │ │ ├── component.css.erb │ │ │ ├── component.js.erb │ │ │ └── component.html.erb │ │ └── component_generator.rb │ │ └── install │ │ ├── templates │ │ ├── bowerrc.json │ │ └── application.html.erb │ │ └── install_generator.rb ├── polymer-rails │ ├── version.rb │ ├── engine.rb │ ├── processors │ │ ├── directive.rb │ │ ├── sprockets_processor.rb │ │ └── component.rb │ ├── xml_adapters │ │ ├── base.rb │ │ ├── jsoup.rb │ │ └── nokogiri.rb │ ├── helpers │ │ └── asset_tag_helper.rb │ ├── railtie.rb │ └── component.rb └── polymer-rails.rb ├── Gemfile ├── bower.json ├── spec ├── spec_helper.rb ├── asset_tag_helper_spec.rb └── component_spec.rb ├── Rakefile ├── app └── assets │ └── javascripts │ ├── shadycss │ ├── apply-shim.html │ ├── custom-style-interface.html │ ├── custom-style-interface.min.js │ └── apply-shim.min.js │ ├── polymer │ ├── lib │ │ ├── utils │ │ │ ├── unresolved.html │ │ │ ├── flush.html │ │ │ ├── case-map.html │ │ │ ├── boot.html │ │ │ ├── mixin.html │ │ │ ├── resolve-url.html │ │ │ ├── import-href.html │ │ │ ├── debounce.html │ │ │ ├── render-status.html │ │ │ ├── style-gather.html │ │ │ ├── async.html │ │ │ ├── path.html │ │ │ ├── flattened-nodes-observer.html │ │ │ └── array-splice.html │ │ ├── legacy │ │ │ ├── polymer-fn.html │ │ │ ├── templatizer-behavior.html │ │ │ ├── mutable-data-behavior.html │ │ │ ├── polymer.dom.html │ │ │ └── class.html │ │ ├── mixins │ │ │ ├── gesture-event-listeners.html │ │ │ └── mutable-data.html │ │ └── elements │ │ │ ├── custom-style.html │ │ │ ├── dom-bind.html │ │ │ ├── dom-module.html │ │ │ ├── dom-if.html │ │ │ └── array-selector.html │ ├── polymer.html │ └── polymer-element.html │ └── webcomponentsjs │ ├── custom-elements-es5-adapter.js │ ├── webcomponents-loader.js │ └── webcomponents-hi.js ├── .gitignore ├── LICENSE.txt ├── polymer-rails.gemspec └── README.md /.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "app/assets/javascripts" 3 | } 4 | -------------------------------------------------------------------------------- /lib/generators/polymer/component/templates/component.css.erb: -------------------------------------------------------------------------------- 1 | :host { 2 | display: block; 3 | } 4 | -------------------------------------------------------------------------------- /lib/polymer-rails/version.rb: -------------------------------------------------------------------------------- 1 | module Polymer 2 | module Rails 3 | VERSION = "2.0" 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /lib/generators/polymer/install/templates/bowerrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "vendor/assets/components" 3 | } 4 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # Specify your gem's dependencies in polymer-rails.gemspec 4 | gemspec 5 | -------------------------------------------------------------------------------- /lib/polymer-rails/engine.rb: -------------------------------------------------------------------------------- 1 | module Polymer 2 | module Rails 3 | class Engine < ::Rails::Engine 4 | end 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "polymer-rails", 3 | "private": true, 4 | "dependencies": { 5 | "polymer": "Polymer/polymer#2.0.1" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /lib/polymer-rails/processors/directive.rb: -------------------------------------------------------------------------------- 1 | module Polymer 2 | module Rails 3 | module Processors 4 | class Directive < Sprockets::DirectiveProcessor 5 | end 6 | end 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /lib/generators/polymer/component/templates/component.js.erb: -------------------------------------------------------------------------------- 1 | class <%= class_name %> extends Polymer.Element { 2 | static get is() { return '<%= component_name %>'; } 3 | } 4 | 5 | window.customElements.define(<%= class_name %>.is, <%= class_name %>) 6 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib')) 2 | $:.unshift(File.dirname(__FILE__)) 3 | 4 | require 'rspec' 5 | require 'pry' 6 | 7 | RSpec.configure do |config| 8 | 9 | config.color = true 10 | 11 | end 12 | -------------------------------------------------------------------------------- /lib/generators/polymer/component/templates/component.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /lib/generators/polymer/install/templates/application.html.erb: -------------------------------------------------------------------------------- 1 | // This is a manifest file that'll be compiled into application.html, which will include all the files 2 | // listed below. 3 | // 4 | // Any web component HTML file within this directory or vendor/assets/components, if any, 5 | // can be referenced here using a relative path. 6 | // 7 | //= require polymer/polymer 8 | -------------------------------------------------------------------------------- /lib/polymer-rails.rb: -------------------------------------------------------------------------------- 1 | require "sprockets" 2 | require "polymer-rails/version" 3 | require "polymer-rails/xml_adapters/base" 4 | require "polymer-rails/processors/directive" 5 | require "polymer-rails/processors/component" 6 | require "polymer-rails/helpers/asset_tag_helper" 7 | require "polymer-rails/engine" if defined?(::Rails) 8 | require "polymer-rails/railtie" if defined?(::Rails) 9 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require "bundler/gem_tasks" 2 | 3 | task :default 4 | 5 | if RUBY_PLATFORM =~ /java/ 6 | require 'maven/ruby/maven' 7 | require 'jar_installer' 8 | 9 | desc 'setup jar dependencies to be used for "testing" and generates lib/example_jars.rb' 10 | task :setup do 11 | Jars::JarInstaller.install_jars 12 | end 13 | 14 | desc 'compile src/main/java/** into lib/example.jar' 15 | task :jar do 16 | Maven::Ruby::Maven.new.exec 'prepare-package' 17 | end 18 | 19 | end 20 | -------------------------------------------------------------------------------- /lib/polymer-rails/xml_adapters/base.rb: -------------------------------------------------------------------------------- 1 | module Polymer 2 | module Rails 3 | module XmlAdapters 4 | class Base 5 | 6 | # HTML Encoding 7 | ENCODING = 'UTF-8' 8 | 9 | def self.factory 10 | klass = "#{module_parent}::#{RUBY_PLATFORM =~ /java/ ? 'Jsoup' : 'Nokogiri'}" 11 | klass.constantize.new 12 | end 13 | 14 | end 15 | end 16 | end 17 | end 18 | 19 | if RUBY_PLATFORM =~ /java/ 20 | require "polymer-rails/xml_adapters/jsoup" 21 | else 22 | require "polymer-rails/xml_adapters/nokogiri" 23 | end 24 | -------------------------------------------------------------------------------- /lib/polymer-rails/helpers/asset_tag_helper.rb: -------------------------------------------------------------------------------- 1 | module Polymer 2 | module Rails 3 | module AssetTagHelper 4 | def html_import_tag(*sources) 5 | options = sources.extract_options! 6 | path_options = options.extract!('protocol').symbolize_keys 7 | sources.uniq.map do |source| 8 | tag_options = { rel: "import", href: path_to_asset(source, {type: :html, extname: '.html'}.merge!(path_options)) } 9 | tag(:link, tag_options.merge!(options).stringify_keys) 10 | end.join("\n").html_safe 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /app/assets/javascripts/shadycss/apply-shim.html: -------------------------------------------------------------------------------- 1 | 10 | 11 | -------------------------------------------------------------------------------- /app/assets/javascripts/shadycss/custom-style-interface.html: -------------------------------------------------------------------------------- 1 | 10 | 11 | -------------------------------------------------------------------------------- /spec/asset_tag_helper_spec.rb: -------------------------------------------------------------------------------- 1 | require "spec_helper" 2 | require 'action_view' 3 | require 'polymer-rails/helpers/asset_tag_helper' 4 | 5 | class AssetTagHelperTest 6 | end 7 | 8 | describe Polymer::Rails::AssetTagHelper do 9 | 10 | before do 11 | @dummy_class = AssetTagHelperTest.new 12 | @dummy_class.extend(ActionView::Helpers::TagHelper) 13 | @dummy_class.extend(ActionView::Helpers::AssetTagHelper) 14 | @dummy_class.extend(Polymer::Rails::AssetTagHelper) 15 | end 16 | 17 | it 'generates html import tag' do 18 | expect(@dummy_class.html_import_tag('application')).to eq("") 19 | end 20 | 21 | end 22 | -------------------------------------------------------------------------------- /lib/polymer-rails/processors/sprockets_processor.rb: -------------------------------------------------------------------------------- 1 | module Polymer 2 | module Rails 3 | class SprocketsProcessor 4 | 5 | def self.instance 6 | @instance ||= new 7 | end 8 | 9 | def self.call(input) 10 | @@sprockets_env = input[:environment] 11 | instance.call(input) 12 | end 13 | 14 | def call(input) 15 | prepare(input) 16 | data = process 17 | 18 | @context.metadata.merge(data: data) 19 | end 20 | 21 | private 22 | 23 | def prepare(input) 24 | @context = input[:environment].context_class.new(input) 25 | @component = Component.new(input[:data]) 26 | end 27 | 28 | end 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | *.rbc 3 | .bundle 4 | .config 5 | .yardoc 6 | Gemfile.lock 7 | InstalledFiles 8 | _yardoc 9 | coverage 10 | doc/ 11 | lib/bundler/man 12 | pkg 13 | rdoc 14 | spec/reports 15 | test/tmp 16 | test/version_tmp 17 | tmp 18 | bower_components 19 | .ruby-version 20 | app/assets/javascripts/polymer/*.json 21 | app/assets/javascripts/polymer/*.log 22 | app/assets/javascripts/polymer/*.txt 23 | app/assets/javascripts/webcomponentsjs/*.json 24 | app/assets/javascripts/webcomponentsjs/*.log 25 | app/assets/javascripts/webcomponentsjs/*.md 26 | app/assets/javascripts/webcomponentsjs/*.js 27 | !app/assets/javascripts/webcomponentsjs/webcomponents.js 28 | !app/assets/javascripts/webcomponentsjs/webcomponents-lite.js 29 | -------------------------------------------------------------------------------- /lib/generators/polymer/install/install_generator.rb: -------------------------------------------------------------------------------- 1 | module Polymer 2 | module Generators 3 | class InstallGenerator < ::Rails::Generators::Base 4 | source_root File.expand_path('../templates', __FILE__) 5 | 6 | desc "Adds app/assets/components and vendor/assets/components directories and adds webcomponents to js manifest" 7 | 8 | def create_manifest 9 | template "application.html.erb", "app/assets/components/application.html.erb" 10 | end 11 | 12 | def inject_js 13 | insert_into_file "app/assets/javascripts/application.js", before: "//= require jquery\n" do 14 | out = "" 15 | out << "//= require webcomponentsjs/webcomponents-loader" 16 | out << "\n" 17 | end 18 | end 19 | 20 | def copy_bowerrc 21 | template "bowerrc.json", ".bowerrc" 22 | end 23 | 24 | def create_vendor_dir 25 | create_file "vendor/assets/components/.keep" 26 | end 27 | 28 | end 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /lib/generators/polymer/component/component_generator.rb: -------------------------------------------------------------------------------- 1 | module Polymer 2 | module Generators 3 | class ComponentGenerator < ::Rails::Generators::NamedBase 4 | source_root File.expand_path('../templates', __FILE__) 5 | 6 | def create_component_dir 7 | empty_directory "app/assets/components/#{component_name}" 8 | end 9 | 10 | def copy_component_template 11 | template "component.html.erb", "app/assets/components/#{component_name}/#{component_base_name}.html" 12 | template "component.js.erb", "app/assets/components/#{component_name}/#{component_base_name}.js" 13 | template "component.css.erb", "app/assets/components/#{component_name}/#{component_base_name}.css" 14 | end 15 | 16 | private 17 | 18 | def component_name 19 | name.gsub('_', '-').downcase 20 | end 21 | 22 | def class_name 23 | name.gsub!('-','_') 24 | name.split('_').map(&:capitalize).join('') 25 | end 26 | 27 | def component_base_name 28 | component_name.split('/')[-1] 29 | end 30 | end 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /app/assets/javascripts/polymer/lib/utils/unresolved.html: -------------------------------------------------------------------------------- 1 | 10 | 32 | -------------------------------------------------------------------------------- /lib/polymer-rails/railtie.rb: -------------------------------------------------------------------------------- 1 | module Polymer 2 | module Rails 3 | class Railtie < ::Rails::Railtie 4 | 5 | initializer :polymer_html_import do 6 | ::ActionView::Base.module_eval('include AssetTagHelper') 7 | end 8 | 9 | initializer :precompile_polymer do |app| 10 | if app.config.respond_to?(:assets) 11 | app.config.assets.precompile += %w( polymer/polymer.js ) 12 | end 13 | end 14 | 15 | initializer :add_preprocessors do |app| 16 | add_preprocessors(app) 17 | end 18 | 19 | private 20 | 21 | def add_preprocessors(app) 22 | app.config.assets.configure do |env| 23 | env.context_class.class_eval("include Polymer::Rails::AssetTagHelper") 24 | env.register_preprocessor 'text/html', Polymer::Rails::Processors::Directive 25 | env.register_mime_type 'text/html', extensions: ['.html'] 26 | env.register_bundle_processor 'text/html', ::Sprockets::Bundle 27 | env.register_postprocessor 'text/html', Polymer::Rails::Processors::Component 28 | end 29 | end 30 | end 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 Alex Chaplinsky 2 | 3 | MIT License 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /lib/polymer-rails/xml_adapters/jsoup.rb: -------------------------------------------------------------------------------- 1 | require 'ostruct' 2 | require 'jar_dependencies' 3 | require_jar 'org.jsoup', 'jsoup', '1.8.3' 4 | 5 | module Polymer 6 | module Rails 7 | module XmlAdapters 8 | class Jsoup < Base 9 | 10 | def parse_document data 11 | doc = org.jsoup.Jsoup.parse_body_fragment(data) 12 | doc.output_settings.charset(ENCODING) 13 | doc 14 | end 15 | 16 | def create_node doc, name, content 17 | node = doc.create_element(name) 18 | datanode = org.jsoup.nodes.DataNode.new(content, doc.base_uri) 19 | node.append_child datanode 20 | node 21 | end 22 | 23 | def stringify doc 24 | doc.select('body').html 25 | end 26 | 27 | def replace_node old_node, new_node 28 | old_node.replace_with new_node 29 | end 30 | 31 | def css_select doc, selector 32 | doc.select selector.gsub('\'', '') 33 | end 34 | 35 | end 36 | end 37 | end 38 | end 39 | 40 | Java::OrgJsoupNodes::Attributes.class_eval do 41 | def [] name 42 | OpenStruct.new value: get(name) 43 | end 44 | end 45 | 46 | Java::OrgJsoupNodes::Element.class_eval do 47 | alias name nodeName 48 | end 49 | -------------------------------------------------------------------------------- /app/assets/javascripts/polymer/polymer.html: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 26 | -------------------------------------------------------------------------------- /lib/polymer-rails/component.rb: -------------------------------------------------------------------------------- 1 | require 'uri' 2 | 3 | module Polymer 4 | module Rails 5 | class Component 6 | 7 | # Selectors for component resources 8 | SELECTORS = { 9 | html: "link[rel='import']:not([type='css'])", 10 | stylesheet: "link[rel='stylesheet'], link[rel='import'][type='css']", 11 | javascript: "script[src]" 12 | } 13 | 14 | def initialize(data) 15 | @adapter = XmlAdapters::Base.factory 16 | @doc = @adapter.parse_document(data) 17 | end 18 | 19 | def stringify 20 | @adapter.stringify(@doc) 21 | end 22 | 23 | def replace_node(node, name, content) 24 | @adapter.replace_node node, @adapter.create_node(@doc, name, content) 25 | end 26 | 27 | def stylesheets 28 | @adapter.css_select(@doc, SELECTORS[:stylesheet]).reject{|tag| is_external? tag.attributes['href'].value} 29 | end 30 | 31 | def javascripts 32 | @adapter.css_select(@doc, SELECTORS[:javascript]).reject do |tag| 33 | is_external? tag.attributes['src'].value 34 | end 35 | end 36 | 37 | def html_imports 38 | @adapter.css_select(@doc, SELECTORS[:html]) 39 | end 40 | 41 | private 42 | 43 | def is_external?(source) 44 | !URI(source).host.nil? 45 | end 46 | end 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /app/assets/javascripts/polymer/polymer-element.html: -------------------------------------------------------------------------------- 1 | 10 | 11 | -------------------------------------------------------------------------------- /polymer-rails.gemspec: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | lib = File.expand_path('../lib', __FILE__) 3 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 4 | require 'polymer-rails/version' 5 | 6 | Gem::Specification.new do |spec| 7 | spec.name = "polymer-rails" 8 | spec.version = Polymer::Rails::VERSION 9 | spec.authors = ["Alex Chaplinsky"] 10 | spec.email = ["alchaplinsky@gmail.com"] 11 | spec.summary = %q{Use of web components with polymer with rails} 12 | spec.description = %q{Use of web components and polymer-project in Ruby on Rails projects} 13 | spec.homepage = "http://github.com/alchapone/polymer-rails" 14 | spec.license = "MIT" 15 | 16 | spec.files = Dir["{app,config,db,lib}/**/*", "Rakefile", "README.md"] 17 | 18 | if RUBY_PLATFORM =~ /java/ 19 | spec.platform = 'java' 20 | spec.add_runtime_dependency 'jar-dependencies', ">= 0.1.1" 21 | spec.requirements << "jar org.jsoup:jsoup, 1.8.3" 22 | spec.add_development_dependency 'ruby-maven', '>= 3.1.1.0' 23 | else 24 | spec.add_runtime_dependency "nokogiri", "~> 1.6" 25 | # lock nokogumbo to 1.4.2, looks like nokogumbo 1.4.3 deletes template tags from custom components 26 | spec.add_runtime_dependency "nokogumbo", "1.4.2" 27 | end 28 | 29 | spec.add_runtime_dependency "rails", ">= 3.1.0" 30 | spec.add_runtime_dependency "sprockets", "~> 3.0" 31 | spec.add_development_dependency "bundler", "~> 1.5" 32 | spec.add_development_dependency "rake", "~> 0" 33 | spec.add_development_dependency "rspec", "~> 3.0" 34 | spec.add_development_dependency "pry" 35 | end 36 | -------------------------------------------------------------------------------- /lib/polymer-rails/xml_adapters/nokogiri.rb: -------------------------------------------------------------------------------- 1 | require 'nokogiri' 2 | require 'nokogumbo' 3 | 4 | module Polymer 5 | module Rails 6 | module XmlAdapters 7 | class Nokogiri < Base 8 | 9 | # XML options for to_xml method 10 | XML_OPTIONS = { save_with: ::Nokogiri::XML::Node::SaveOptions::NO_EMPTY_TAGS } 11 | 12 | # Nodes that should be parsed as XML nodes 13 | XML_NODES = ['*[selected]', '*[checked]', '*[src]:not(script)'] 14 | 15 | def parse_document data 16 | ::Nokogiri::HTML5 data 17 | end 18 | 19 | def create_node doc, name, content 20 | node = ::Nokogiri::XML::Node.new(name, doc) 21 | node.content = content 22 | node 23 | end 24 | 25 | def replace_node old_node, new_node 26 | old_node.replace new_node 27 | end 28 | 29 | def stringify doc 30 | xml_nodes(doc).reduce(to_html(doc)) do |output, node| 31 | pattern = node.to_html 32 | replacement = node.to_xml(XML_OPTIONS) 33 | replacement.gsub!( /src="%5B%5B(.+?)%5D%5D"/i, 'src="[[\1]]"' ) 34 | replacement.gsub!( /src="%7B%7B(.+?)%7D%7D"/i, 'src="{{\1}}"' ) 35 | output.gsub(pattern, replacement).encode(ENCODING) 36 | end 37 | end 38 | 39 | def css_select doc, selector 40 | doc.css selector 41 | end 42 | 43 | private 44 | def xml_nodes doc 45 | doc.css(XML_NODES.join(',')) 46 | end 47 | def to_html doc 48 | doc.css("head,body").children.to_html(encoding: ENCODING).lstrip 49 | end 50 | end 51 | end 52 | end 53 | end 54 | -------------------------------------------------------------------------------- /app/assets/javascripts/webcomponentsjs/custom-elements-es5-adapter.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | 4 | (()=>{'use strict';if(!window.customElements)return;const a=window.HTMLElement,b=window.customElements.define,c=window.customElements.get,d=new Map,e=new Map;let f=!1,g=!1;window.HTMLElement=function(){if(!f){const j=d.get(this.constructor),k=c.call(window.customElements,j);g=!0;const l=new k;return l}f=!1;},window.HTMLElement.prototype=a.prototype;Object.defineProperty(window,'customElements',{value:window.customElements,configurable:!0,writable:!0}),Object.defineProperty(window.customElements,'define',{value:(j,k)=>{const l=k.prototype,m=class extends a{constructor(){super(),Object.setPrototypeOf(this,l),g||(f=!0,k.call(this)),g=!1;}},n=m.prototype;m.observedAttributes=k.observedAttributes,n.connectedCallback=l.connectedCallback,n.disconnectedCallback=l.disconnectedCallback,n.attributeChangedCallback=l.attributeChangedCallback,n.adoptedCallback=l.adoptedCallback,d.set(k,j),e.set(j,k),b.call(window.customElements,j,m);},configurable:!0,writable:!0}),Object.defineProperty(window.customElements,'get',{value:(j)=>e.get(j),configurable:!0,writable:!0});})(); 5 | 6 | /** 7 | @license 8 | Copyright (c) 2017 The Polymer Project Authors. All rights reserved. 9 | This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt 10 | The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt 11 | The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt 12 | Code distributed by Google as part of the polymer project is also 13 | subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt 14 | */ 15 | 16 | }()); 17 | -------------------------------------------------------------------------------- /app/assets/javascripts/polymer/lib/legacy/polymer-fn.html: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 49 | -------------------------------------------------------------------------------- /app/assets/javascripts/polymer/lib/utils/flush.html: -------------------------------------------------------------------------------- 1 | 10 | 11 | 61 | -------------------------------------------------------------------------------- /lib/polymer-rails/processors/component.rb: -------------------------------------------------------------------------------- 1 | require 'polymer-rails/component' 2 | require "polymer-rails/processors/sprockets_processor" 3 | 4 | module Polymer 5 | module Rails 6 | module Processors 7 | class Component < Polymer::Rails::SprocketsProcessor 8 | 9 | def process 10 | inline_styles 11 | inline_javascripts 12 | require_imports 13 | @component.stringify 14 | end 15 | 16 | private 17 | 18 | def require_imports 19 | @component.html_imports.each do |import| 20 | @context.require_asset absolute_asset_path(import.attributes['href'].value) 21 | import.remove 22 | end 23 | end 24 | 25 | def inline_javascripts 26 | @component.javascripts.each do |script| 27 | @component.replace_node(script, 'script', asset_content(script.attributes['src'].value)) 28 | end 29 | end 30 | 31 | def inline_styles 32 | @component.stylesheets.each do |link| 33 | @component.replace_node(link, 'style', asset_content(link.attributes['href'].value)) 34 | end 35 | end 36 | 37 | def asset_content(file) 38 | asset_path = absolute_asset_path(file) 39 | asset = find_asset(asset_path) 40 | unless asset.blank? 41 | @context.depend_on_asset asset_path 42 | asset.to_s 43 | else 44 | nil 45 | end 46 | end 47 | 48 | def absolute_asset_path(file) 49 | search_file = file.sub(/^(\.\.\/)+/, '/').sub(/^\/*/, '') 50 | @@sprockets_env.paths.each do |path| 51 | file_list = Dir.glob( "#{File.absolute_path search_file, path }*") 52 | return file_list.first unless file_list.blank? 53 | end 54 | components = Dir.glob("#{File.absolute_path file, File.dirname(@context.pathname)}*") 55 | return components.blank? ? nil : components.first 56 | end 57 | 58 | def find_asset(asset_path) 59 | @@sprockets_env.find_asset(asset_path) 60 | end 61 | 62 | end 63 | end 64 | end 65 | end 66 | -------------------------------------------------------------------------------- /app/assets/javascripts/polymer/lib/utils/case-map.html: -------------------------------------------------------------------------------- 1 | 10 | 11 | 65 | -------------------------------------------------------------------------------- /app/assets/javascripts/polymer/lib/mixins/gesture-event-listeners.html: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 62 | -------------------------------------------------------------------------------- /app/assets/javascripts/polymer/lib/utils/boot.html: -------------------------------------------------------------------------------- 1 | 10 | 61 | -------------------------------------------------------------------------------- /app/assets/javascripts/polymer/lib/utils/mixin.html: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 77 | -------------------------------------------------------------------------------- /app/assets/javascripts/shadycss/custom-style-interface.min.js: -------------------------------------------------------------------------------- 1 | (function(){/* 2 | 3 | Copyright (c) 2017 The Polymer Project Authors. All rights reserved. 4 | This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt 5 | The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt 6 | The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt 7 | Code distributed by Google as part of the polymer project is also 8 | subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt 9 | */ 10 | 'use strict';var c=!(window.ShadyDOM&&window.ShadyDOM.inUse),f;function g(a){f=a&&a.shimcssproperties?!1:c||!(navigator.userAgent.match("AppleWebKit/601")||!window.CSS||!CSS.supports||!CSS.supports("box-shadow","0 0 0 var(--foo)"))}window.ShadyCSS&&void 0!==window.ShadyCSS.nativeCss?f=window.ShadyCSS.nativeCss:window.ShadyCSS?(g(window.ShadyCSS),window.ShadyCSS=void 0):g(window.WebComponents&&window.WebComponents.flags);var h=f;function k(a,b){for(var d in b)null===d?a.style.removeProperty(d):a.style.setProperty(d,b[d])};var l=null,m=window.HTMLImports&&window.HTMLImports.whenReady||null,q;function r(){var a=t;requestAnimationFrame(function(){m?m(a):(l||(l=new Promise(function(a){q=a}),"complete"===document.readyState?q():document.addEventListener("readystatechange",function(){"complete"===document.readyState&&q()})),l.then(function(){a&&a()}))})};var u=null,t=null;function v(){this.customStyles=[];this.enqueued=!1}function x(a){!a.enqueued&&t&&(a.enqueued=!0,r())}v.prototype.c=function(a){a.__seenByShadyCSS||(a.__seenByShadyCSS=!0,this.customStyles.push(a),x(this))};v.prototype.b=function(a){if(a.__shadyCSSCachedStyle)return a.__shadyCSSCachedStyle;var b;a.getStyle?b=a.getStyle():b=a;return b}; 11 | v.prototype.a=function(){for(var a=this.customStyles,b=0;b 10 | 11 | 12 | 74 | -------------------------------------------------------------------------------- /spec/component_spec.rb: -------------------------------------------------------------------------------- 1 | require "spec_helper" 2 | require "polymer-rails/xml_adapters/base" 3 | require "polymer-rails/component" 4 | 5 | describe Polymer::Rails::Component do 6 | 7 | if RUBY_PLATFORM =~ /java/ 8 | XML_ELEMENT = org.jsoup.nodes.Element 9 | else 10 | XML_ELEMENT = Nokogiri::XML::Element 11 | end 12 | 13 | let(:data){ ' 14 | 15 | 16 | 17 | 18 | ' 19 | } 20 | 21 | let(:img_tag){' 22 | ' 23 | } 24 | 25 | context '#replace_node' do 26 | subject do 27 | doc = described_class.new(data) 28 | node = doc.stylesheets[0] 29 | doc.replace_node node, "style", "body{color: red;}" 30 | doc 31 | end 32 | 33 | it 'replaces stylesheet link with inline styles' do 34 | expect(subject.stringify).to include('') 35 | expect(subject.stringify).not_to include(' 57 | 58 | var fire = function() { 59 | requestAnimationFrame(function() { 60 | window.WebComponents.ready = true; 61 | document.dispatchEvent(new CustomEvent('WebComponentsReady', {bubbles: true})); 62 | }); 63 | }; 64 | 65 | if (document.readyState !== 'loading') { 66 | fire(); 67 | } else { 68 | document.addEventListener('readystatechange', function wait() { 69 | fire(); 70 | document.removeEventListener('readystatechange', wait); 71 | }); 72 | } 73 | } 74 | })(); 75 | -------------------------------------------------------------------------------- /app/assets/javascripts/polymer/lib/utils/resolve-url.html: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 109 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Polymer-Rails 2 | Want to get started with [web components](http://www.w3.org/wiki/WebComponents/)? Want to bring them into your Rails app? Easily build your own and use web components that are built by community in your Ruby on Rails Application. Polymer-rails helps you to do this: 3 | 4 | 1. Adds [polymer](http://polymer-project.org/) library to assets of your rails project. 5 | 6 | 2. Allows you to easily import web component with `<%= html_import_tag "my-component" %>` helper. 7 | 8 | 3. Allows you to import and package web components into assets pipeline, exactly as you would Javascript or CSS 9 | 10 | #### Prefer using SASS or CoffeeSript? 11 | 12 | Polymer-rails works well with compiling assets, such as CoffeeScript and Sass. 13 | You can easily use external stylesheet or script tag references in your web component `` for stylesheets and ` 108 | -------------------------------------------------------------------------------- /app/assets/javascripts/polymer/lib/utils/debounce.html: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 14 | 116 | -------------------------------------------------------------------------------- /app/assets/javascripts/polymer/lib/utils/render-status.html: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 131 | -------------------------------------------------------------------------------- /app/assets/javascripts/polymer/lib/elements/dom-bind.html: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 122 | -------------------------------------------------------------------------------- /app/assets/javascripts/polymer/lib/elements/dom-module.html: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 135 | -------------------------------------------------------------------------------- /app/assets/javascripts/polymer/lib/utils/style-gather.html: -------------------------------------------------------------------------------- 1 | 10 | 11 | 147 | -------------------------------------------------------------------------------- /app/assets/javascripts/polymer/lib/legacy/templatizer-behavior.html: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 137 | -------------------------------------------------------------------------------- /app/assets/javascripts/polymer/lib/legacy/mutable-data-behavior.html: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 151 | -------------------------------------------------------------------------------- /app/assets/javascripts/polymer/lib/utils/async.html: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 205 | -------------------------------------------------------------------------------- /app/assets/javascripts/shadycss/apply-shim.min.js: -------------------------------------------------------------------------------- 1 | (function(){/* 2 | 3 | Copyright (c) 2017 The Polymer Project Authors. All rights reserved. 4 | This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt 5 | The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt 6 | The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt 7 | Code distributed by Google as part of the polymer project is also 8 | subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt 9 | */ 10 | 'use strict';var k={};function n(){this.end=this.start=0;this.rules=this.parent=this.previous=null;this.cssText=this.parsedCssText="";this.atRule=!1;this.type=0;this.parsedSelector=this.selector=this.keyframesName=""} 11 | function p(a){a=a.replace(aa,"").replace(ba,"");var b=q,c=a,d=new n;d.start=0;d.end=c.length;for(var e=d,f=0,h=c.length;f *")}; 18 | function oa(a,b){b=b.replace(A,function(b,d,e,f){return pa(a,b,d,e,f)});return O(a,b)}function O(a,b){for(var c;c=B.exec(b);){var d=c[0],e=c[1];c=c.index;var f=b.slice(0,c+d.indexOf("@apply"));b=b.slice(c+d.length);var h=P(a,f),d=void 0;var g=a;var e=e.replace(ma,""),m=[];var l=g.a.get(e);l||(g.a.set(e,{}),l=g.a.get(e));if(l)for(d in g.c&&(l.i[g.c]=!0),l.h)g=h&&h[d],l=[d,": var(",e,"_-_",d],g&&l.push(",",g),l.push(")"),m.push(l.join(""));d=m.join("; ");b=""+f+d+b;B.lastIndex=c+d.length}return b} 19 | function P(a,b){b=b.split(";");for(var c,d,e={},f=0,h;f 10 | 11 | 12 | 13 | 195 | -------------------------------------------------------------------------------- /app/assets/javascripts/polymer/lib/utils/path.html: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 275 | -------------------------------------------------------------------------------- /app/assets/javascripts/polymer/lib/utils/flattened-nodes-observer.html: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 243 | -------------------------------------------------------------------------------- /app/assets/javascripts/webcomponentsjs/webcomponents-hi.js: -------------------------------------------------------------------------------- 1 | (function(){ 2 | /* 3 | 4 | Copyright (c) 2016 The Polymer Project Authors. All rights reserved. 5 | This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt 6 | The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt 7 | The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt 8 | Code distributed by Google as part of the polymer project is also 9 | subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt 10 | 11 | Copyright (c) 2014 The Polymer Project Authors. All rights reserved. 12 | This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt 13 | The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt 14 | The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt 15 | Code distributed by Google as part of the polymer project is also 16 | subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt 17 | 18 | Copyright (c) 2017 The Polymer Project Authors. All rights reserved. 19 | This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt 20 | The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt 21 | The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt 22 | Code distributed by Google as part of the polymer project is also 23 | subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt 24 | */ 25 | 'use strict';(function(m){function n(a,b){if("function"===typeof window.CustomEvent)return new CustomEvent(a,b);var c=document.createEvent("CustomEvent");c.initCustomEvent(a,!!b.bubbles,!!b.cancelable,b.detail);return c}function k(a){if(z)return a.ownerDocument!==document?a.ownerDocument:null;var b=a.__importDoc;if(!b&&a.parentNode){b=a.parentNode;if("function"===typeof b.closest)b=b.closest("link[rel=import]");else for(;!u(b)&&(b=b.parentNode););a.__importDoc=b}return b}function v(a){var b=document.querySelectorAll("link[rel=import]:not(import-dependency)"), 26 | c=b.length;if(c)for(var d=0,e=b.length,h;d]*)(rel=['|"]?stylesheet['|"]?[^>]*>)/g,f={A:function(a,b){a.href&&a.setAttribute("href",f.i(a.getAttribute("href"),b));a.src&&a.setAttribute("src",f.i(a.getAttribute("src"),b));if("style"===a.localName){var c=f.u(a.textContent,b,H);a.textContent=f.u(c,b,I)}},u:function(a,b,c){return a.replace(c, 29 | function(a,c,h,g){a=h.replace(/["']/g,"");b&&(a=f.v(a,b));return c+"'"+a+"'"+g})},i:function(a,b){return a&&G.test(a)?a:f.v(a,b)},v:function(a,b){if(void 0===f.g){f.g=!1;try{var c=new URL("b","http://a");c.pathname="c%20d";f.g="http://a/c%20d"===c.href}catch(d){}}if(f.g)return(new URL(a,b)).href;c=f.w;c||(c=document.implementation.createHTMLDocument("temp"),f.w=c,c.l=c.createElement("base"),c.head.appendChild(c.l),c.j=c.createElement("a"));c.l.href=b;c.j.href=a;return c.j.href||a}},D={async:!0,load:function(a, 30 | b,c){if(a)if(a.match(/^data:/)){a=a.split(",");var d=a[1],d=-1e.status?b(d,a):c(d)};e.send()}else c("error: href must be specified")}},A=/Trident/.test(navigator.userAgent)|| 31 | /Edge\/\d./i.test(navigator.userAgent);l.prototype.f=function(a){a=a.querySelectorAll("link[rel=import]");for(var b=0,c=a.length;b 10 | 11 | 12 | 13 | 14 | 15 | 16 | 266 | -------------------------------------------------------------------------------- /app/assets/javascripts/polymer/lib/legacy/polymer.dom.html: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 337 | -------------------------------------------------------------------------------- /app/assets/javascripts/polymer/lib/utils/array-splice.html: -------------------------------------------------------------------------------- 1 | 10 | 11 | -------------------------------------------------------------------------------- /app/assets/javascripts/polymer/lib/legacy/class.html: -------------------------------------------------------------------------------- 1 | 10 | 11 | 335 | -------------------------------------------------------------------------------- /app/assets/javascripts/polymer/lib/elements/array-selector.html: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 14 | 15 | 411 | --------------------------------------------------------------------------------