tao_on_rails 0.8.2 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5ad64fc49a4b54a73034e05b813147c99693707b
4
- data.tar.gz: 3f75f7753cf05b4a38bdfdeb20c2a5c17cf1bdc2
3
+ metadata.gz: 593f883fe5535ca2c421021fa06c51df7ae7651f
4
+ data.tar.gz: d5b2ddb46cec54946270deaa71214a449ac83c00
5
5
  SHA512:
6
- metadata.gz: d8ee03b857f25f4751dfec541ebab23c4293650f2383e9d1c9d49a4422ddefa43e4c91c3985946067e204f04ba528bec067a9f8f081f7d641686edce43cb7a37
7
- data.tar.gz: 467aaa7e5a3c6693e333df8415974551accf53b653946a4ec45a44c205ebc5baa151e3a1e5514ae34c11214f4688bc1c7f6c18935fabd7e88fe7471f90f026c0
6
+ metadata.gz: 83ab490a10967d6bbd5f5e6a7fa16ae99773fc02e9e2520bb4f3ca984c1e4cd18ab7e244a9e20e2d27bbb12096a049b38f4462e30cee7f908c50f0a6d8b66d02
7
+ data.tar.gz: 58e2422623a70bdba6c7ed854c02d51f2addbf2244e5b4bb9d6c08d9fd5de67cf4318c8ae8dacbd903d99b9b94be786f6c76ad6cdf5805c3c39fa8e25a7adf30
data/Rakefile CHANGED
@@ -1,3 +1,4 @@
1
+ require 'bundler/setup'
1
2
  require "bundler/gem_tasks"
2
3
  require "rake/testtask"
3
4
 
@@ -0,0 +1,94 @@
1
+ #= require ./module
2
+
3
+ manager = null
4
+
5
+ class TaoAttributeManager extends TaoModule
6
+
7
+ @defaultOptions =
8
+ type: 'string'
9
+
10
+ @getManager: ->
11
+ manager ||= new TaoAttributeManager()
12
+
13
+ @getAttribute: (element, name, options) ->
14
+ manager = @getManager()
15
+ options = _.extend {}, @defaultOptions, options
16
+ manager._attributes[_.camelCase(options.type)]?.get element, name, options
17
+
18
+ @setAttribute: (element, name, val, options) ->
19
+ manager = @getManager()
20
+ options = _.extend {}, @defaultOptions, options
21
+ manager._attributes[_.camelCase(options.type)]?.set element, name, val, options
22
+
23
+ _attributes: {}
24
+
25
+ @registerAttribute: (type, config) ->
26
+ if _.isString config
27
+ @::_attributes[type] = @::_attributes[config]
28
+ else
29
+ @::_attributes[type] = config
30
+
31
+ @registerAttribute 'string',
32
+ get: (element, name, options) ->
33
+ element.getAttribute(name) || options.default || ''
34
+ set: (element, name, val, options) ->
35
+ element.setAttribute(name, val.toString())
36
+
37
+ @registerAttribute 'number',
38
+ get: (element, name, options) ->
39
+ value = parseFloat element.getAttribute(name)
40
+ if _.isNaN value
41
+ options.default || null
42
+ else
43
+ value
44
+ set: (element, name, val, options) ->
45
+ element.setAttribute(name, val.toString())
46
+
47
+ @registerAttribute 'boolean',
48
+ get: (element, name, options) ->
49
+ element.hasAttribute(name)
50
+ set: (element, name, val, options) ->
51
+ if val
52
+ element.setAttribute name, ''
53
+ else
54
+ element.removeAttribute name
55
+
56
+ @registerAttribute 'bool', 'boolean'
57
+
58
+ @registerAttribute 'hash',
59
+ get: (element, name, options) ->
60
+ value = element.getAttribute name
61
+ if _.isString value
62
+ try
63
+ JSON.parse value
64
+ catch e
65
+ options.default || null
66
+ else
67
+ options.default || null
68
+ set: (element, name, val, options) ->
69
+ val = try
70
+ JSON.stringify val
71
+ catch e
72
+ '{}'
73
+ element.setAttribute name, val
74
+
75
+ @registerAttribute 'object', 'hash'
76
+
77
+ @registerAttribute 'array',
78
+ get: (element, name, options) ->
79
+ value = element.getAttribute name
80
+ if _.isString value
81
+ try
82
+ JSON.parse value
83
+ catch e
84
+ options.default || null
85
+ else
86
+ options.default || null
87
+ set: (element, name, val, options) ->
88
+ val = try
89
+ JSON.stringify val
90
+ catch e
91
+ '[]'
92
+ element.setAttribute name, val
93
+
94
+ Tao.AttributeManager = window.TaoAttributeManager = TaoAttributeManager
@@ -1,4 +1,4 @@
1
- #= require ./attribute_parser
1
+ #= require ./attribute_manager
2
2
 
3
3
  components = {}
4
4
 
@@ -26,8 +26,8 @@ TaoComponentBasedOn = (superClassName = 'HTMLElement') ->
26
26
  count = 0
27
27
 
28
28
  @extend: (obj) ->
29
- unless obj and typeof obj == 'object'
30
- throw new Error('TaoComponent.extend: param should be an object')
29
+ obj = obj.call(@) if _.isFunction obj
30
+ return unless obj and typeof obj == 'object'
31
31
 
32
32
  for key, val of obj when key not in ['included', 'extended']
33
33
  @[key] = val
@@ -36,8 +36,8 @@ TaoComponentBasedOn = (superClassName = 'HTMLElement') ->
36
36
  @
37
37
 
38
38
  @include: (obj) ->
39
- unless obj and typeof obj == 'object'
40
- throw new Error('TaoComponent.include: param should be an object')
39
+ obj = obj.call(@) if _.isFunction obj
40
+ return unless obj and typeof obj == 'object'
41
41
 
42
42
  for key, val of obj when key not in ['included', 'extended']
43
43
  @::[key] = val
@@ -64,18 +64,11 @@ TaoComponentBasedOn = (superClassName = 'HTMLElement') ->
64
64
  attrName = _.kebabCase(name)
65
65
 
66
66
  @get name, ->
67
- val = if @hasAttribute attrName
68
- @getAttribute(attrName)
69
- else
70
- null
71
- TaoAttributeParser.parse val, options
67
+ Tao.AttributeManager.getAttribute @, attrName, options
72
68
 
73
69
  @set name, (val) ->
74
- val = TaoAttributeParser.stringify val, options
75
- if _.isString val
76
- @setAttribute attrName, val
77
- else
78
- @removeAttribute attrName
70
+ return if @_beforeAttributeChanged(attrName, val) == false
71
+ Tao.AttributeManager.setAttribute @, attrName, val, options
79
72
 
80
73
  @observedAttributes.push(attrName) if options.observe
81
74
 
@@ -136,6 +129,9 @@ TaoComponentBasedOn = (superClassName = 'HTMLElement') ->
136
129
  _disconnected: ->
137
130
  # called when the element was disconnected from dom
138
131
 
132
+ _beforeAttributeChanged: (name, val) ->
133
+ @["_before#{_.upperFirst _.camelCase name}Changed"]?(val)
134
+
139
135
  _attributeChanged: (name) ->
140
136
  @["_#{_.camelCase name}Changed"]?()
141
137
 
@@ -149,17 +145,20 @@ TaoComponentBasedOn = (superClassName = 'HTMLElement') ->
149
145
  findComponent: (selector, readyCallback) ->
150
146
  component = @jq.find(selector).get(0)
151
147
  if component.connected
152
- readyCallback? component
148
+ # make sure element is returned before callback
149
+ setTimeout -> readyCallback? component
153
150
  else
154
151
  @one 'connected', selector, ->
155
152
  readyCallback? component
156
153
  component
157
154
 
158
- on: (args...) ->
159
- @jq.on args...
155
+ on: (name, args...) ->
156
+ name = "#{name}.#{@constructor._tag}-#{@taoId}" if name && name.indexOf('.') < 0
157
+ @jq.on name, args...
160
158
 
161
- off: (args...) ->
162
- @jq.off args...
159
+ off: (name = '', args...) ->
160
+ name = "#{name}.#{@constructor._tag}-#{@taoId}" if name.indexOf('.') < 0
161
+ @jq.off name, args...
163
162
 
164
163
  trigger: (args...) ->
165
164
  @jq.trigger(args...)
@@ -1,4 +1,4 @@
1
- #= require polyfills/polyfills
1
+ #= require polyfills
2
2
  #= require turbolinks
3
3
  #= require jquery3
4
4
  #= require jquery_ujs
@@ -3,8 +3,8 @@ class TaoModule
3
3
  id = 0
4
4
 
5
5
  @extend: (obj) ->
6
- unless obj and typeof obj == 'object'
7
- throw new Error('TaoModule.extend: param should be an object')
6
+ obj = obj.call(@) if _.isFunction obj
7
+ return unless obj and typeof obj == 'object'
8
8
 
9
9
  for key, val of obj when key not in ['included', 'extended']
10
10
  @[key] = val
@@ -13,8 +13,8 @@ class TaoModule
13
13
  @
14
14
 
15
15
  @include: (obj) ->
16
- unless obj and typeof obj == 'object'
17
- throw new Error('TaoModule.include: param should be an object')
16
+ obj = obj.call(@) if _.isFunction obj
17
+ return unless obj and typeof obj == 'object'
18
18
 
19
19
  for key, val of obj when key not in ['included', 'extended']
20
20
  @::[key] = val
@@ -1,6 +1,6 @@
1
1
  class <%= page_id.underscore.camelize %>Page extends TaoPage
2
2
 
3
- @tag: "<%= page_id %>-page"
3
+ @tag "<%= page_id %>-page"
4
4
 
5
5
  _init: ->
6
6
  # called when the page connected to dom for the first time
@@ -3,7 +3,7 @@ module TaoOnRails
3
3
  module Helpers
4
4
 
5
5
  def page_id
6
- return @page_id if @page_id.present?
6
+ return @page_id if defined?(@page_id)
7
7
  controller_names = controller_path.split('/')
8
8
  [controller_names, action_name].compact.flatten.join('_').dasherize
9
9
  end
@@ -2,37 +2,51 @@ module TaoOnRails
2
2
  module Components
3
3
  class Base
4
4
 
5
- attr_reader :options, :template_name, :template_paths, :view
5
+ attr_reader :options, :view
6
+
7
+ delegate :tag_name, :component_name, :tag_prefix, :template_paths, :template_name, to: :class
6
8
 
7
9
  def initialize view, options = {}
8
10
  @view = view
9
- @options = options
10
- @template_name = self.class.template_name.dup
11
- @template_paths = self.class.template_paths.dup
12
- @template_paths.unshift(@options.delete(:template_path)) if @options[:template_path].present?
11
+ @options = merge_options default_options, options
12
+ template_paths.unshift(@options.delete(:template_path)) if @options[:template_path].present?
13
13
  end
14
14
 
15
15
  def render &block
16
16
  if template = find_template
17
+ render_template template, &block
18
+ else
19
+ view.content_tag tag_name, nil, html_options, &block
20
+ end
21
+ end
22
+
23
+ def render_template(template, &block)
24
+ if template.is_a?(String) || template.is_a?(Symbol)
25
+ template = find_template(template)
26
+ end
27
+
28
+ if template
17
29
  if block_given?
18
30
  block_content = view.capture(&block)
19
- template.render(view, {component: self, block_given: true}) do
20
- block_content
31
+ template.render(view, {component: self, block_given: true}) do |*name|
32
+ view._layout_for(*name) {block_content}
21
33
  end
22
34
  else
23
35
  template.render(view, {component: self})
24
36
  end
25
- else
26
- view.content_tag self.class.tag_name, nil, options, &block
27
37
  end
28
38
  end
29
39
 
30
- def translate key
40
+ def translate key, options = {}
31
41
  i18n_scope = self.class.name.underscore.split('/').join('.').gsub(/(.+)_component$/, '\1')
32
- I18n.t(key, scope: i18n_scope).presence
42
+ I18n.t(key, options.merge!(scope: i18n_scope)).presence
33
43
  end
34
44
  alias_method :t, :translate
35
45
 
46
+ def html_options
47
+ @html_options ||= transform_html_options options
48
+ end
49
+
36
50
  def self.tag_name
37
51
  @tag_name ||= "#{self.tag_prefix}-#{self.component_name.to_s.dasherize}"
38
52
  end
@@ -60,8 +74,45 @@ module TaoOnRails
60
74
 
61
75
  private
62
76
 
63
- def find_template
64
- view.lookup_context.find_all(template_name, template_paths, true, template_keys).first
77
+ def default_options
78
+ {}
79
+ end
80
+
81
+ def merge_options options, other_options
82
+ options.merge(other_options) { |key, old_val, new_val|
83
+ if key.to_s == 'class'
84
+ old_val = old_val.split(' ') if old_val.is_a? String
85
+ new_val = new_val.split(' ') if new_val.is_a? String
86
+ Array(old_val) + Array(new_val)
87
+ elsif old_val.is_a?(Hash) && old_val.is_a?(Hash)
88
+ old_val.merge! new_val
89
+ else
90
+ new_val
91
+ end
92
+ }
93
+ end
94
+
95
+ def transform_html_options options, other_options = nil
96
+ if other_options
97
+ options = merge_options options, other_options
98
+ end
99
+
100
+ options.transform_keys { |key|
101
+ key.to_s.dasherize.to_sym
102
+ }.transform_values { |value|
103
+ case value
104
+ when true
105
+ ''
106
+ when false
107
+ nil
108
+ else
109
+ value
110
+ end
111
+ }
112
+ end
113
+
114
+ def find_template(name = template_name)
115
+ view.lookup_context.find_all(name, template_paths, true, template_keys).first
65
116
  end
66
117
 
67
118
  def template_keys
@@ -3,17 +3,11 @@ require 'tao_on_rails/components/base'
3
3
  module TaoOnRails
4
4
  module Components
5
5
  class PageComponent < Base
6
+ attr_reader :page_id
6
7
 
7
8
  def initialize view, options = {}
8
- super
9
-
10
9
  @page_id = view.page_id
11
-
12
- if @options[:class].present?
13
- @options[:class] += " tao-page #{@page_id}-page"
14
- else
15
- @options[:class] = "tao-page #{@page_id}-page"
16
- end
10
+ super
17
11
  end
18
12
 
19
13
  def render &block
@@ -24,6 +18,12 @@ module TaoOnRails
24
18
  :page
25
19
  end
26
20
 
21
+ private
22
+
23
+ def default_options
24
+ {class: ['tao-page', "#{@page_id}-page"]}
25
+ end
26
+
27
27
  end
28
28
  end
29
29
  end
@@ -1,3 +1,3 @@
1
1
  module TaoOnRails
2
- VERSION = "0.8.2"
2
+ VERSION = "0.9.0"
3
3
  end
@@ -1,14 +1,14 @@
1
1
  (function(){
2
- 'use strict';var g={scope:{}};g.defineProperty="function"==typeof Object.defineProperties?Object.defineProperty:function(a,b,f){if(f.get||f.set)throw new TypeError("ES3 does not support getters and setters.");a!=Array.prototype&&a!=Object.prototype&&(a[b]=f.value)};g.getGlobal=function(a){return"undefined"!=typeof window&&window===a?a:"undefined"!=typeof global&&null!=global?global:a};g.global=g.getGlobal(this);g.SYMBOL_PREFIX="jscomp_symbol_";
2
+ 'use strict';var g=g||{};g.scope={};g.defineProperty="function"==typeof Object.defineProperties?Object.defineProperty:function(a,b,f){if(f.get||f.set)throw new TypeError("ES3 does not support getters and setters.");a!=Array.prototype&&a!=Object.prototype&&(a[b]=f.value)};g.getGlobal=function(a){return"undefined"!=typeof window&&window===a?a:"undefined"!=typeof global&&null!=global?global:a};g.global=g.getGlobal(this);g.SYMBOL_PREFIX="jscomp_symbol_";
3
3
  g.initSymbol=function(){g.initSymbol=function(){};g.global.Symbol||(g.global.Symbol=g.Symbol)};g.symbolCounter_=0;g.Symbol=function(a){return g.SYMBOL_PREFIX+(a||"")+g.symbolCounter_++};g.initSymbolIterator=function(){g.initSymbol();var a=g.global.Symbol.iterator;a||(a=g.global.Symbol.iterator=g.global.Symbol("iterator"));"function"!=typeof Array.prototype[a]&&g.defineProperty(Array.prototype,a,{configurable:!0,writable:!0,value:function(){return g.arrayIterator(this)}});g.initSymbolIterator=function(){}};
4
4
  g.arrayIterator=function(a){var b=0;return g.iteratorPrototype(function(){return b<a.length?{done:!1,value:a[b++]}:{done:!0}})};g.iteratorPrototype=function(a){g.initSymbolIterator();a={next:a};a[g.global.Symbol.iterator]=function(){return this};return a};g.makeIterator=function(a){g.initSymbolIterator();var b=a[Symbol.iterator];return b?b.call(a):g.arrayIterator(a)};g.owns=function(a,b){return Object.prototype.hasOwnProperty.call(a,b)};
5
5
  g.polyfill=function(a,b){if(b){var f=g.global;a=a.split(".");for(var e=0;e<a.length-1;e++){var c=a[e];c in f||(f[c]={});f=f[c]}a=a[a.length-1];e=f[a];b=b(e);b!=e&&null!=b&&g.defineProperty(f,a,{configurable:!0,writable:!0,value:b})}};
6
6
  g.polyfill("WeakMap",function(a){function b(a){this.id_=(d+=Math.random()+1).toString();if(a){g.initSymbol();g.initSymbolIterator();a=g.makeIterator(a);for(var b;!(b=a.next()).done;)b=b.value,this.set(b[0],b[1])}}function f(a){g.owns(a,c)||g.defineProperty(a,c,{value:{}})}function e(a){var b=Object[a];b&&(Object[a]=function(a){f(a);return b(a)})}if(function(){if(!a||!Object.seal)return!1;try{var b=Object.seal({}),d=Object.seal({}),c=new a([[b,2],[d,3]]);if(2!=c.get(b)||3!=c.get(d))return!1;c.delete(b);
7
7
  c.set(d,4);return!c.has(b)&&4==c.get(d)}catch(v){return!1}}())return a;var c="$jscomp_hidden_"+Math.random().toString().substring(2);e("freeze");e("preventExtensions");e("seal");var d=0;b.prototype.set=function(a,b){f(a);if(!g.owns(a,c))throw Error("WeakMap key fail: "+a);a[c][this.id_]=b;return this};b.prototype.get=function(a){return g.owns(a,c)?a[c][this.id_]:void 0};b.prototype.has=function(a){return g.owns(a,c)&&g.owns(a[c],this.id_)};b.prototype.delete=function(a){return g.owns(a,c)&&g.owns(a[c],
8
- this.id_)?delete a[c][this.id_]:!1};return b},"es6-impl","es3");g.ASSUME_NO_NATIVE_MAP=!1;
8
+ this.id_)?delete a[c][this.id_]:!1};return b},"es6-impl","es3");g.MapEntry=function(){};g.ASSUME_NO_NATIVE_MAP=!1;
9
9
  g.polyfill("Map",function(a){function b(){var a={};return a.previous=a.next=a.head=a}function f(a,b){var d=a.head_;return g.iteratorPrototype(function(){if(d){for(;d.head!=a.head_;)d=d.previous;for(;d.next!=d.head;)return d=d.next,{done:!1,value:b(d)};d=null}return{done:!0,value:void 0}})}function e(a,b){var c;c=b&&typeof b;"object"==c||"function"==c?d.has(b)?c=d.get(b):(c=""+ ++m,d.set(b,c)):c="p_"+b;var f=a.data_[c];if(f&&g.owns(a.data_,c))for(a=0;a<f.length;a++){var e=f[a];if(b!==b&&e.key!==e.key||
10
10
  b===e.key)return{id:c,list:f,index:a,entry:e}}return{id:c,list:f,index:-1,entry:void 0}}function c(a){this.data_={};this.head_=b();this.size=0;if(a){a=g.makeIterator(a);for(var d;!(d=a.next()).done;)d=d.value,this.set(d[0],d[1])}}if(!g.ASSUME_NO_NATIVE_MAP&&function(){if(!a||!a.prototype.entries||"function"!=typeof Object.seal)return!1;try{var b=Object.seal({x:4}),d=new a(g.makeIterator([[b,"s"]]));if("s"!=d.get(b)||1!=d.size||d.get({x:4})||d.set({x:4},"t")!=d||2!=d.size)return!1;var c=d.entries(),
11
- f=c.next();if(f.done||f.value[0]!=b||"s"!=f.value[1])return!1;f=c.next();return f.done||4!=f.value[0].x||"t"!=f.value[1]||!c.next().done?!1:!0}catch(R){return!1}}())return a;g.initSymbol();g.initSymbolIterator();var d=new WeakMap;c.prototype.set=function(a,b){var d=e(this,a);d.list||(d.list=this.data_[d.id]=[]);d.entry?d.entry.value=b:(d.entry={next:this.head_,previous:this.head_.previous,head:this.head_,key:a,value:b},d.list.push(d.entry),this.head_.previous.next=d.entry,this.head_.previous=d.entry,
11
+ f=c.next();if(f.done||f.value[0]!=b||"s"!=f.value[1])return!1;f=c.next();return f.done||4!=f.value[0].x||"t"!=f.value[1]||!c.next().done?!1:!0}catch(Q){return!1}}())return a;g.initSymbol();g.initSymbolIterator();var d=new WeakMap;c.prototype.set=function(a,b){var d=e(this,a);d.list||(d.list=this.data_[d.id]=[]);d.entry?d.entry.value=b:(d.entry={next:this.head_,previous:this.head_.previous,head:this.head_,key:a,value:b},d.list.push(d.entry),this.head_.previous.next=d.entry,this.head_.previous=d.entry,
12
12
  this.size++);return this};c.prototype.delete=function(a){a=e(this,a);return a.entry&&a.list?(a.list.splice(a.index,1),a.list.length||delete this.data_[a.id],a.entry.previous.next=a.entry.next,a.entry.next.previous=a.entry.previous,a.entry.head=null,this.size--,!0):!1};c.prototype.clear=function(){this.data_={};this.head_=this.head_.previous=b();this.size=0};c.prototype.has=function(a){return!!e(this,a).entry};c.prototype.get=function(a){return(a=e(this,a).entry)&&a.value};c.prototype.entries=function(){return f(this,
13
13
  function(a){return[a.key,a.value]})};c.prototype.keys=function(){return f(this,function(a){return a.key})};c.prototype.values=function(){return f(this,function(a){return a.value})};c.prototype.forEach=function(a,b){for(var d=this.entries(),c;!(c=d.next()).done;)c=c.value,a.call(b,c[1],c[0],this)};c.prototype[Symbol.iterator]=c.prototype.entries;var m=0;return c},"es6-impl","es3");g.ASSUME_NO_NATIVE_SET=!1;
14
14
  g.polyfill("Set",function(a){function b(a){this.map_=new Map;if(a){a=g.makeIterator(a);for(var b;!(b=a.next()).done;)this.add(b.value)}this.size=this.map_.size}if(!g.ASSUME_NO_NATIVE_SET&&function(){if(!a||!a.prototype.entries||"function"!=typeof Object.seal)return!1;try{var b=Object.seal({x:4}),e=new a(g.makeIterator([b]));if(!e.has(b)||1!=e.size||e.add(b)!=e||1!=e.size||e.add({x:4})!=e||2!=e.size)return!1;var c=e.entries(),d=c.next();if(d.done||d.value[0]!=b||d.value[1]!=b)return!1;d=c.next();return d.done||
@@ -33,7 +33,7 @@ null!==c&&this.attributeChangedCallback(a,e,null,c,null)}n.isConnected(a)&&this.
33
33
  x.prototype.attributeChangedCallback=function(a,b,f,e,c){var d=a.__CE_definition;d.attributeChangedCallback&&-1<d.observedAttributes.indexOf(b)&&d.attributeChangedCallback.call(a,b,f,e,c)};w.default=x;var y={};function z(a,b){this._internals=a;this._document=b;this._observer=void 0;this._internals.patchAndUpgradeTree(this._document);"loading"===this._document.readyState&&(this._observer=new MutationObserver(this._handleMutations.bind(this)),this._observer.observe(this._document,{childList:!0,subtree:!0}))}z.prototype.disconnect=function(){this._observer&&this._observer.disconnect()};
34
34
  z.prototype._handleMutations=function(a){var b=this._document.readyState;"interactive"!==b&&"complete"!==b||this.disconnect();for(b=0;b<a.length;b++)for(var f=a[b].addedNodes,e=0;e<f.length;e++)this._internals.patchAndUpgradeTree(f[e])};y.default=z;var A={};function B(){var a=this;this._resolve=this._value=void 0;this._promise=new Promise(function(b){a._resolve=b;a._value&&b(a._value)})}B.prototype.resolve=function(a){if(this._value)throw Error("Already resolved.");this._value=a;this._resolve&&this._resolve(a)};B.prototype.toPromise=function(){return this._promise};A.default=B;var C={};function D(a){this._elementDefinitionIsRunning=!1;this._internals=a;this._whenDefinedDeferred=new Map;this._flushCallback=function(a){return a()};this._flushPending=!1;this._unflushedLocalNames=[];this._documentConstructionObserver=new y.default(a,document)}
35
35
  D.prototype.define=function(a,b){var f=this;if(!(b instanceof Function))throw new TypeError("Custom element constructors must be functions.");if(!n.isValidCustomElementName(a))throw new SyntaxError("The element name '"+a+"' is not valid.");if(this._internals.localNameToDefinition(a))throw Error("A custom element with name '"+a+"' has already been defined.");if(this._elementDefinitionIsRunning)throw Error("A custom element is already being defined.");this._elementDefinitionIsRunning=!0;var e,c,d,m,
36
- l;try{var q=function(a){var b=v[a];if(void 0!==b&&!(b instanceof Function))throw Error("The '"+a+"' callback must be a function.");return b},v=b.prototype;if(!(v instanceof Object))throw new TypeError("The custom element constructor's prototype is not an object.");e=q("connectedCallback");c=q("disconnectedCallback");d=q("adoptedCallback");m=q("attributeChangedCallback");l=b.observedAttributes||[]}catch(Q){return}finally{this._elementDefinitionIsRunning=!1}this._internals.setDefinition(a,{localName:a,
36
+ l;try{var q=function(a){var b=v[a];if(void 0!==b&&!(b instanceof Function))throw Error("The '"+a+"' callback must be a function.");return b},v=b.prototype;if(!(v instanceof Object))throw new TypeError("The custom element constructor's prototype is not an object.");e=q("connectedCallback");c=q("disconnectedCallback");d=q("adoptedCallback");m=q("attributeChangedCallback");l=b.observedAttributes||[]}catch(P){return}finally{this._elementDefinitionIsRunning=!1}this._internals.setDefinition(a,{localName:a,
37
37
  constructor:b,connectedCallback:e,disconnectedCallback:c,adoptedCallback:d,attributeChangedCallback:m,observedAttributes:l,constructionStack:[]});this._unflushedLocalNames.push(a);this._flushPending||(this._flushPending=!0,this._flushCallback(function(){return f._flush()}))};
38
38
  D.prototype._flush=function(){if(!1!==this._flushPending)for(this._flushPending=!1,this._internals.patchAndUpgradeTree(document);0<this._unflushedLocalNames.length;){var a=this._unflushedLocalNames.shift();(a=this._whenDefinedDeferred.get(a))&&a.resolve(void 0)}};D.prototype.get=function(a){if(a=this._internals.localNameToDefinition(a))return a.constructor};
39
39
  D.prototype.whenDefined=function(a){if(!n.isValidCustomElementName(a))return Promise.reject(new SyntaxError("'"+a+"' is not a valid custom element name."));var b=this._whenDefinedDeferred.get(a);if(b)return b.toPromise();b=new A.default;this._whenDefinedDeferred.set(a,b);this._internals.localNameToDefinition(a)&&-1===this._unflushedLocalNames.indexOf(a)&&b.resolve(void 0);return b.toPromise()};
@@ -52,8 +52,8 @@ c);for(var e=0;e<d.length;e++)a.disconnectTree(d[e]);if(n.isConnected(this))for(
52
52
  b.remove=function(){var b=n.isConnected(this);f.remove.call(this);b&&a.disconnectTree(this)}}};var M={default:function(a){function b(b,d){Object.defineProperty(b,"innerHTML",{enumerable:d.enumerable,configurable:!0,get:d.get,set:function(b){var c=this,e=void 0;n.isConnected(this)&&(e=[],n.walkDeepDescendantElements(this,function(a){a!==c&&e.push(a)}));d.set.call(this,b);if(e)for(var f=0;f<e.length;f++){var m=e[f];m.__CE_state===u.default.custom&&a.disconnectedCallback(m)}this.ownerDocument.__CE_hasRegistry?a.patchAndUpgradeTree(this):a.patchTree(this);return b}})}function f(b,d){n.setPropertyUnchecked(b,
53
53
  "insertAdjacentElement",function(b,c){var e=n.isConnected(c);b=d.call(this,b,c);e&&a.disconnectTree(c);n.isConnected(b)&&a.connectTree(c);return b})}E.default.Element_attachShadow?n.setPropertyUnchecked(Element.prototype,"attachShadow",function(a){return this.__CE_shadowRoot=a=E.default.Element_attachShadow.call(this,a)}):console.warn("Custom Elements: `Element#attachShadow` was not patched.");if(E.default.Element_innerHTML&&E.default.Element_innerHTML.get)b(Element.prototype,E.default.Element_innerHTML);
54
54
  else if(E.default.HTMLElement_innerHTML&&E.default.HTMLElement_innerHTML.get)b(HTMLElement.prototype,E.default.HTMLElement_innerHTML);else{var e=E.default.Document_createElement.call(document,"div");a.addPatch(function(a){b(a,{enumerable:!0,configurable:!0,get:function(){return E.default.Node_cloneNode.call(this,!0).innerHTML},set:function(a){var b="template"===this.localName?this.content:this;for(e.innerHTML=a;0<b.childNodes.length;)E.default.Node_removeChild.call(b,b.childNodes[0]);for(;0<e.childNodes.length;)E.default.Node_appendChild.call(b,
55
- e.childNodes[0])}})})}n.setPropertyUnchecked(Element.prototype,"setAttribute",function(b,d){if(this.__CE_state!==u.default.custom)return E.default.Element_setAttribute.call(this,b,d);var c=E.default.Element_getAttribute.call(this,b);E.default.Element_setAttribute.call(this,b,d);d=E.default.Element_getAttribute.call(this,b);c!==d&&a.attributeChangedCallback(this,b,c,d,null)});n.setPropertyUnchecked(Element.prototype,"setAttributeNS",function(b,d,e){if(this.__CE_state!==u.default.custom)return E.default.Element_setAttributeNS.call(this,
56
- b,d,e);var c=E.default.Element_getAttributeNS.call(this,b,d);E.default.Element_setAttributeNS.call(this,b,d,e);e=E.default.Element_getAttributeNS.call(this,b,d);c!==e&&a.attributeChangedCallback(this,d,c,e,b)});n.setPropertyUnchecked(Element.prototype,"removeAttribute",function(b){if(this.__CE_state!==u.default.custom)return E.default.Element_removeAttribute.call(this,b);var c=E.default.Element_getAttribute.call(this,b);E.default.Element_removeAttribute.call(this,b);null!==c&&a.attributeChangedCallback(this,
55
+ e.childNodes[0])}})})}n.setPropertyUnchecked(Element.prototype,"setAttribute",function(b,d){if(this.__CE_state!==u.default.custom)return E.default.Element_setAttribute.call(this,b,d);var c=E.default.Element_getAttribute.call(this,b);E.default.Element_setAttribute.call(this,b,d);d=E.default.Element_getAttribute.call(this,b);a.attributeChangedCallback(this,b,c,d,null)});n.setPropertyUnchecked(Element.prototype,"setAttributeNS",function(b,d,e){if(this.__CE_state!==u.default.custom)return E.default.Element_setAttributeNS.call(this,
56
+ b,d,e);var c=E.default.Element_getAttributeNS.call(this,b,d);E.default.Element_setAttributeNS.call(this,b,d,e);e=E.default.Element_getAttributeNS.call(this,b,d);a.attributeChangedCallback(this,d,c,e,b)});n.setPropertyUnchecked(Element.prototype,"removeAttribute",function(b){if(this.__CE_state!==u.default.custom)return E.default.Element_removeAttribute.call(this,b);var c=E.default.Element_getAttribute.call(this,b);E.default.Element_removeAttribute.call(this,b);null!==c&&a.attributeChangedCallback(this,
57
57
  b,c,null,null)});n.setPropertyUnchecked(Element.prototype,"removeAttributeNS",function(b,d){if(this.__CE_state!==u.default.custom)return E.default.Element_removeAttributeNS.call(this,b,d);var c=E.default.Element_getAttributeNS.call(this,b,d);E.default.Element_removeAttributeNS.call(this,b,d);var e=E.default.Element_getAttributeNS.call(this,b,d);c!==e&&a.attributeChangedCallback(this,d,c,e,b)});E.default.HTMLElement_insertAdjacentElement?f(HTMLElement.prototype,E.default.HTMLElement_insertAdjacentElement):
58
58
  E.default.Element_insertAdjacentElement?f(Element.prototype,E.default.Element_insertAdjacentElement):console.warn("Custom Elements: `Element#insertAdjacentElement` was not patched.");I.default(a,Element.prototype,{prepend:E.default.Element_prepend,append:E.default.Element_append});L.default(a,Element.prototype,{before:E.default.Element_before,after:E.default.Element_after,replaceWith:E.default.Element_replaceWith,remove:E.default.Element_remove})}};/*
59
59
 
@@ -64,5 +64,5 @@ E.default.Element_insertAdjacentElement?f(Element.prototype,E.default.Element_in
64
64
  Code distributed by Google as part of the polymer project is also
65
65
  subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
66
66
  */
67
- var N=window.customElements;if(window.MutationObserver&&(!N||N.forcePolyfill||"function"!=typeof N.define||"function"!=typeof N.get)){var O=new w.default;H.default(O);J.default(O);K.default(O);M.default(O);document.__CE_hasRegistry=!0;var P=new C.default(O);Object.defineProperty(window,"customElements",{configurable:!0,enumerable:!0,value:P})};
67
+ var N=window.customElements;if(!N||N.forcePolyfill||"function"!=typeof N.define||"function"!=typeof N.get){var O=new w.default;H.default(O);J.default(O);K.default(O);M.default(O);document.__CE_hasRegistry=!0;var customElements=new C.default(O);Object.defineProperty(window,"customElements",{configurable:!0,enumerable:!0,value:customElements})};
68
68
  }).call(self);
@@ -68,7 +68,7 @@ if window.customElements
68
68
  // ptototype chain of built-in elements.
69
69
  window.HTMLElement.prototype = NativeHTMLElement.prototype;
70
70
 
71
- window.customElements.define = (tagname, elementClass) => {
71
+ const define = (tagname, elementClass) => {
72
72
  const elementProto = elementClass.prototype;
73
73
  const StandInElement = class extends NativeHTMLElement {
74
74
  constructor() {
@@ -102,7 +102,16 @@ if window.customElements
102
102
  nativeDefine.call(window.customElements, tagname, StandInElement);
103
103
  };
104
104
 
105
- window.customElements.get = (tagname) => constructorByTagname.get(tagname);
105
+ const get = (tagname) => constructorByTagname.get(tagname);
106
+
107
+ // Workaround for Safari bug where patching customElements can be lost, likely
108
+ // due to native wrapper garbage collection issue
109
+ Object.defineProperty(window, 'customElements',
110
+ {value: window.customElements, configurable: true, writable: true});
111
+ Object.defineProperty(window.customElements, 'define',
112
+ {value: define, configurable: true, writable: true});
113
+ Object.defineProperty(window.customElements, 'get',
114
+ {value: get, configurable: true, writable: true});
106
115
 
107
116
  })();
108
- '''
117
+ '''
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tao_on_rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.2
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Siyuan Liu
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2017-05-21 00:00:00.000000000 Z
12
+ date: 2017-06-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: turbolinks
@@ -17,70 +17,70 @@ dependencies:
17
17
  requirements:
18
18
  - - "~>"
19
19
  - !ruby/object:Gem::Version
20
- version: '5.0'
20
+ version: 5.0.1
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
25
  - - "~>"
26
26
  - !ruby/object:Gem::Version
27
- version: '5.0'
27
+ version: 5.0.1
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: jquery-rails
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
32
  - - "~>"
33
33
  - !ruby/object:Gem::Version
34
- version: '4.2'
34
+ version: 4.3.1
35
35
  type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
39
  - - "~>"
40
40
  - !ruby/object:Gem::Version
41
- version: '4.2'
41
+ version: 4.3.1
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: lodash-rails
44
44
  requirement: !ruby/object:Gem::Requirement
45
45
  requirements:
46
46
  - - "~>"
47
47
  - !ruby/object:Gem::Version
48
- version: '4.16'
48
+ version: 4.17.4
49
49
  type: :runtime
50
50
  prerelease: false
51
51
  version_requirements: !ruby/object:Gem::Requirement
52
52
  requirements:
53
53
  - - "~>"
54
54
  - !ruby/object:Gem::Version
55
- version: '4.16'
55
+ version: 4.17.4
56
56
  - !ruby/object:Gem::Dependency
57
57
  name: rails
58
58
  requirement: !ruby/object:Gem::Requirement
59
59
  requirements:
60
60
  - - "~>"
61
61
  - !ruby/object:Gem::Version
62
- version: 5.0.3
62
+ version: 5.1.1
63
63
  type: :runtime
64
64
  prerelease: false
65
65
  version_requirements: !ruby/object:Gem::Requirement
66
66
  requirements:
67
67
  - - "~>"
68
68
  - !ruby/object:Gem::Version
69
- version: 5.0.3
69
+ version: 5.1.1
70
70
  - !ruby/object:Gem::Dependency
71
71
  name: sqlite3
72
72
  requirement: !ruby/object:Gem::Requirement
73
73
  requirements:
74
- - - "~>"
74
+ - - ">="
75
75
  - !ruby/object:Gem::Version
76
- version: '1.3'
76
+ version: '0'
77
77
  type: :development
78
78
  prerelease: false
79
79
  version_requirements: !ruby/object:Gem::Requirement
80
80
  requirements:
81
- - - "~>"
81
+ - - ">="
82
82
  - !ruby/object:Gem::Version
83
- version: '1.3'
83
+ version: '0'
84
84
  - !ruby/object:Gem::Dependency
85
85
  name: blade
86
86
  requirement: !ruby/object:Gem::Requirement
@@ -101,28 +101,28 @@ dependencies:
101
101
  requirements:
102
102
  - - "~>"
103
103
  - !ruby/object:Gem::Version
104
- version: 0.6.2
104
+ version: 0.7.0
105
105
  type: :development
106
106
  prerelease: false
107
107
  version_requirements: !ruby/object:Gem::Requirement
108
108
  requirements:
109
109
  - - "~>"
110
110
  - !ruby/object:Gem::Version
111
- version: 0.6.2
111
+ version: 0.7.0
112
112
  - !ruby/object:Gem::Dependency
113
- name: nokogiri
113
+ name: mocha
114
114
  requirement: !ruby/object:Gem::Requirement
115
115
  requirements:
116
116
  - - "~>"
117
117
  - !ruby/object:Gem::Version
118
- version: '1.7'
118
+ version: 1.2.1
119
119
  type: :development
120
120
  prerelease: false
121
121
  version_requirements: !ruby/object:Gem::Requirement
122
122
  requirements:
123
123
  - - "~>"
124
124
  - !ruby/object:Gem::Version
125
- version: '1.7'
125
+ version: 1.2.1
126
126
  description: Ruby on Rails lacks a recommended way to structure your frontend code
127
127
  for many years. Tao on Rails is the framework to fill the gap which will modularize
128
128
  your page with the new Custom Elements v1 API.
@@ -137,7 +137,7 @@ files:
137
137
  - README.md
138
138
  - Rakefile
139
139
  - lib/assets/javascripts/tao/application.coffee
140
- - lib/assets/javascripts/tao/attribute_parser.coffee
140
+ - lib/assets/javascripts/tao/attribute_manager.coffee
141
141
  - lib/assets/javascripts/tao/component.coffee
142
142
  - lib/assets/javascripts/tao/helpers.coffee
143
143
  - lib/assets/javascripts/tao/index.coffee
@@ -186,8 +186,8 @@ files:
186
186
  - lib/tao_on_rails/engine.rb
187
187
  - lib/tao_on_rails/version.rb
188
188
  - vendor/assets/javascripts/polyfills/custom-elements.js
189
+ - vendor/assets/javascripts/polyfills/index.coffee
189
190
  - vendor/assets/javascripts/polyfills/native-shim.coffee
190
- - vendor/assets/javascripts/polyfills/polyfills.coffee
191
191
  homepage: https://github.com/mycolorway/tao_on_rails
192
192
  licenses:
193
193
  - MIT
@@ -200,7 +200,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
200
200
  requirements:
201
201
  - - ">="
202
202
  - !ruby/object:Gem::Version
203
- version: '0'
203
+ version: 2.3.1
204
204
  required_rubygems_version: !ruby/object:Gem::Requirement
205
205
  requirements:
206
206
  - - ">="
@@ -208,7 +208,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
208
208
  version: '0'
209
209
  requirements: []
210
210
  rubyforge_project:
211
- rubygems_version: 2.5.1
211
+ rubygems_version: 2.6.11
212
212
  signing_key:
213
213
  specification_version: 4
214
214
  summary: The missing frontend solution for Rails project
@@ -1,110 +0,0 @@
1
- #= require ./module
2
-
3
- parser = null
4
-
5
- class TaoAttributeParser extends TaoModule
6
-
7
- @defaultOptions =
8
- type: 'string'
9
-
10
- @getParser: ->
11
- parser ||= new TaoAttributeParser()
12
-
13
- @parse: (value, options = {}) ->
14
- parser = @getParser()
15
- options = _.extend {}, @defaultOptions, options
16
- if parse = parser["_#{_.camelCase "parse_#{options.type}"}"]
17
- parse.call parser, value, options
18
- else
19
- value
20
-
21
- @stringify: (value, options = {}) ->
22
- parser = @getParser()
23
- options = _.extend {}, @defaultOptions, options
24
- if stringify = parser["_#{_.camelCase "stringify_#{options.type}"}"]
25
- stringify.call parser, value, options
26
- else
27
- value
28
-
29
- _parseString: (value, options) ->
30
- value || options.default || ''
31
-
32
- _parseNumber: (value, options) ->
33
- value = parseFloat value
34
- if _.isNaN value
35
- options.default || 0
36
- else
37
- value
38
-
39
- _parseBoolean: (value, options) ->
40
- if _.isNil value
41
- options.default || false
42
- else if value == 'true'
43
- true
44
- else if value == 'false'
45
- false
46
- else
47
- !!value
48
-
49
- @aliasMethod '_parseBool', '_parseBoolean'
50
-
51
- _parseHash: (value, options) ->
52
- if _.isString value
53
- try
54
- JSON.parse value
55
- catch e
56
- options.default || null
57
- else
58
- options.default || null
59
-
60
- @aliasMethod '_parseObject', '_parseHash'
61
-
62
- _parseArray: (value, options) ->
63
- if _.isString value
64
- try
65
- JSON.parse value
66
- catch e
67
- options.default || null
68
- else
69
- options.default || null
70
-
71
- _stringifyString: (value, options) ->
72
- value.toString()
73
-
74
- _stringifyNumber: (value, options) ->
75
- value.toString()
76
-
77
- _stringifyBoolean: (value, options) ->
78
- unless _.isBoolean value
79
- value = options.default || false
80
-
81
- if value == true
82
- 'true'
83
- else if value == false
84
- 'false'
85
- else
86
- null
87
-
88
- @aliasMethod '_stringifyBool', '_stringifyBoolean'
89
-
90
- _stringifyHash: (value, options) ->
91
- unless _.isObject value
92
- value = options.default || {}
93
-
94
- try
95
- JSON.stringify value
96
- catch e
97
- '{}'
98
-
99
- @aliasMethod '_stringifyObject', '_stringifyHash'
100
-
101
- _stringifyArray: (value, options) ->
102
- unless _.isObject value
103
- value = options.default || []
104
-
105
- try
106
- JSON.stringify value
107
- catch e
108
- '[]'
109
-
110
- Tao.AttributeParser = window.TaoAttributeParser = TaoAttributeParser