fron 0.1.4 → 0.2.0rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.reek +11 -0
  4. data/.rubocop.yml +54 -0
  5. data/.travis.yml +11 -0
  6. data/.yardopts +4 -0
  7. data/Changelog.md +7 -0
  8. data/Gemfile +3 -1
  9. data/Gemfile.lock +106 -15
  10. data/Rakefile +19 -15
  11. data/Readme.md +23 -0
  12. data/fron.gemspec +2 -2
  13. data/lib/fron/version.rb +2 -1
  14. data/opal/fron.rb +5 -5
  15. data/opal/fron/core.rb +3 -10
  16. data/opal/fron/core/behaviors/components.rb +42 -0
  17. data/opal/fron/core/behaviors/events.rb +27 -0
  18. data/opal/fron/core/behaviors/routes.rb +59 -0
  19. data/opal/fron/core/component.rb +64 -90
  20. data/opal/fron/core/eventable.rb +18 -0
  21. data/opal/fron/core/logger.rb +10 -1
  22. data/opal/fron/core_ext.rb +9 -0
  23. data/opal/fron/core_ext/array.rb +12 -0
  24. data/opal/fron/core_ext/date.rb +57 -0
  25. data/opal/fron/core_ext/hash.rb +52 -0
  26. data/opal/fron/core_ext/kernel.rb +57 -0
  27. data/opal/fron/core_ext/nil.rb +7 -0
  28. data/opal/fron/core_ext/numeric.rb +19 -0
  29. data/opal/fron/core_ext/object.rb +11 -0
  30. data/opal/fron/core_ext/proc.rb +19 -0
  31. data/opal/fron/{core-ext → core_ext}/string.rb +4 -0
  32. data/opal/fron/dom.rb +15 -13
  33. data/opal/fron/dom/document.rb +22 -6
  34. data/opal/fron/dom/element.rb +105 -67
  35. data/opal/fron/dom/event.rb +110 -40
  36. data/opal/fron/dom/{file-reader.rb → file_reader.rb} +6 -1
  37. data/opal/fron/dom/fragment.rb +2 -0
  38. data/opal/fron/dom/modules/attributes.rb +43 -0
  39. data/opal/fron/dom/modules/classlist.rb +26 -13
  40. data/opal/fron/dom/modules/dimensions.rb +79 -9
  41. data/opal/fron/dom/modules/element_accessor.rb +35 -0
  42. data/opal/fron/dom/modules/events.rb +67 -20
  43. data/opal/fron/dom/node.rb +98 -39
  44. data/opal/fron/dom/nodelist.rb +9 -2
  45. data/opal/fron/dom/style.rb +23 -2
  46. data/opal/fron/dom/text.rb +4 -0
  47. data/opal/fron/dom/window.rb +31 -2
  48. data/opal/fron/event_mock.rb +54 -0
  49. data/opal/fron/js/syntetic_event.js +16 -0
  50. data/opal/fron/request.rb +2 -2
  51. data/opal/fron/request/request.rb +77 -14
  52. data/opal/fron/request/response.rb +33 -6
  53. data/opal/fron/storage.rb +1 -1
  54. data/opal/fron/storage/local_storage.rb +54 -0
  55. data/opal/fron/utils/drag.rb +135 -0
  56. data/opal/fron/utils/keyboard.rb +70 -0
  57. data/opal/fron/utils/point.rb +78 -0
  58. data/opal/fron/utils/render_proc.rb +27 -0
  59. data/spec/core-ext/array_spec.rb +15 -0
  60. data/spec/core-ext/date_spec.rb +54 -0
  61. data/spec/core-ext/hash_spec.rb +18 -2
  62. data/spec/core-ext/kernel_spec.rb +57 -0
  63. data/spec/core-ext/nil_spec.rb +9 -0
  64. data/spec/core-ext/numeric_spec.rb +25 -0
  65. data/spec/core-ext/proc_spec.rb +15 -0
  66. data/spec/core-ext/string_spec.rb +11 -0
  67. data/spec/core/behaviors/events_spec.rb +25 -0
  68. data/spec/core/behaviors/routes_spec.rb +59 -0
  69. data/spec/core/component_inheritance_spec.rb +26 -16
  70. data/spec/core/component_spec.rb +25 -29
  71. data/spec/core/eventable_spec.rb +19 -19
  72. data/spec/core/logger_spec.rb +5 -6
  73. data/spec/dom/document_spec.rb +4 -5
  74. data/spec/dom/element_spec.rb +106 -15
  75. data/spec/dom/event_spec.rb +101 -61
  76. data/spec/dom/file_reader_spec.rb +11 -0
  77. data/spec/dom/fragment_spec.rb +3 -4
  78. data/spec/dom/instance_retaining_spec.rb +58 -0
  79. data/spec/dom/modules/classlist_spec.rb +18 -19
  80. data/spec/dom/modules/dimensions_spec.rb +87 -22
  81. data/spec/dom/modules/events_spec.rb +22 -8
  82. data/spec/dom/node_spec.rb +25 -17
  83. data/spec/dom/nodelist_spec.rb +2 -3
  84. data/spec/dom/style_spec.rb +6 -5
  85. data/spec/dom/text_spec.rb +4 -3
  86. data/spec/dom/window_spec.rb +24 -9
  87. data/spec/js/mocks.js +14 -0
  88. data/spec/request/request_spec.rb +34 -15
  89. data/spec/request/response_spec.rb +9 -10
  90. data/spec/spec_helper.rb +11 -0
  91. data/spec/storage/{local-storage_spec.rb → local_storage_spec.rb} +6 -7
  92. data/spec/utils/drag_spec.rb +136 -0
  93. data/spec/utils/keyboard_spec.rb +75 -0
  94. data/spec/utils/point_spec.rb +55 -0
  95. data/spec/utils/render_proc_spec.rb +18 -0
  96. metadata +58 -36
  97. data/docs/application.md +0 -7
  98. data/docs/configuration.md +0 -29
  99. data/docs/controllers.md +0 -35
  100. data/docs/routing.md +0 -63
  101. data/opal/fron/core-ext.rb +0 -5
  102. data/opal/fron/core-ext/hash.rb +0 -31
  103. data/opal/fron/core-ext/kernel.rb +0 -10
  104. data/opal/fron/core-ext/numeric.rb +0 -9
  105. data/opal/fron/core-ext/proc.rb +0 -9
  106. data/opal/fron/core/adapters/local.rb +0 -43
  107. data/opal/fron/core/adapters/rails.rb +0 -65
  108. data/opal/fron/core/application.rb +0 -42
  109. data/opal/fron/core/configuration.rb +0 -29
  110. data/opal/fron/core/controller.rb +0 -41
  111. data/opal/fron/core/model.rb +0 -90
  112. data/opal/fron/core/router.rb +0 -86
  113. data/opal/fron/storage/local-storage.rb +0 -34
  114. data/spec/core/adapter/local_spec.rb +0 -65
  115. data/spec/core/adapter/rails_spec.rb +0 -77
  116. data/spec/core/application_spec.rb +0 -35
  117. data/spec/core/configuration_spec.rb +0 -20
  118. data/spec/core/controlller_spec.rb +0 -68
  119. data/spec/core/model_spec.rb +0 -125
  120. data/spec/core/router_spec.rb +0 -124
@@ -1,110 +1,84 @@
1
+ require 'fron/core/behaviors/components'
2
+ require 'fron/core/behaviors/events'
3
+ require 'fron/core/behaviors/routes'
4
+
1
5
  module Fron
6
+ # Component
2
7
  class Component < DOM::Element
3
- attr_reader :model
4
-
5
8
  class << self
6
- attr_reader :events
9
+ # @return [String] The tagname of the component
7
10
  attr_reader :tagname
8
- attr_reader :components
9
- attr_reader :delegates
10
11
 
11
- def inherited(subclass)
12
- [:components,:events,:delegates].each do |type|
13
- if (var = instance_variable_get("@#{type}"))
14
- inst_var = subclass.instance_variable_get('@#{type}')
15
- subclass.instance_variable_set("@#{type}", []) unless inst_var
16
- subclass.send(type).concat var
17
- end
18
- end
19
- end
20
-
21
- def tag(tag)
22
- @tagname = tag
12
+ # @return [Hash] The hash of behaviors
13
+ attr_reader :behaviors
14
+
15
+ # Creates a new class with the specific tag
16
+ #
17
+ # @param tag [String] The tag
18
+ #
19
+ # @return [Fron::Component] The new component
20
+ def create(tag)
21
+ klass = Class.new self
22
+ klass.tag tag
23
+ klass
23
24
  end
24
25
 
25
- def on(*args)
26
- @events ||= []
27
- @events << args
28
- end
29
-
30
- def component(*args,&block)
31
- attr_reader args[0]
32
- @components ||= []
33
- @components << ( args << block )
34
- end
35
-
36
- def delegate(*args)
37
- @delegates ||= []
38
- @delegates << args
39
- end
40
- end
41
-
42
- def initialize(*args)
43
- case args.length
44
- when 1
45
- @model = args[0]
46
- when 2
47
- tag, @model = args
48
- when 3
49
- tag, options, @model = args
26
+ # Register a behavior
27
+ #
28
+ # @param behavior [Module] The behavior
29
+ # @param methods [Array] The methods to register
30
+ def register(behavior, methods)
31
+ @behaviors ||= {}
32
+ @behaviors[behavior] = methods
33
+
34
+ methods.each do |name|
35
+ instance_variable_set "@#{name}", []
36
+ meta_def name do |*args, &block|
37
+ args << block if block_given?
38
+ instance_variable_get("@#{name}") << args
39
+ end
40
+ end
50
41
  end
51
42
 
52
- super tag || self.class.tagname || self.class.name.split("::").last
53
-
54
- applyEvents
55
- createComponents
56
- applyDelegates
57
-
58
- if options
59
- options.each do |method,value|
60
- self.send(method+"=",value) if self.respond_to?(method+"=")
43
+ # Handles inheritance
44
+ #
45
+ # @param subclass [Class] The subclass
46
+ def inherited(subclass)
47
+ # Copy behaviours
48
+ subclass.instance_variable_set '@behaviors', @behaviors.dup
49
+
50
+ # Copy registries
51
+ @behaviors.values.reduce(&:+).each do |type|
52
+ next unless (var = instance_variable_get("@#{type}"))
53
+ inst_var = subclass.instance_variable_get("@#{type}") || []
54
+ subclass.instance_variable_set("@#{type}", inst_var.concat(var))
61
55
  end
62
56
  end
63
57
 
64
- return if !respond_to?(:render) || !@model
65
- @model.on 'change' do render end
66
- render
67
- end
68
-
69
- def component(name,comp,options,&block)
70
- c = comp.is_a?(Class) ? comp.new(nil,options,@model) : Component.new(comp, options, @model)
71
- c.instance_eval(&block) if block
72
- self << c
73
- self.instance_variable_set "@#{name}", c
74
- end
75
-
76
- private
77
-
78
- def createComponents
79
- return unless self.class.components
80
- self.class.components.each do |args|
81
- arguments = args.dup
82
- block = arguments.last.is_a?(Proc) ? arguments.pop : nil
83
- component *arguments, &block
58
+ # Sets the tag name of the component
59
+ #
60
+ # @param tag [String] The tag name
61
+ def tag(tag)
62
+ @tagname = tag
84
63
  end
85
64
  end
86
65
 
87
- def applyDelegates
88
- return unless self.class.delegates
89
- self.class.delegates.each do |args|
90
- method, target = args
91
- self.class.define_method(method) do
92
- instance_variable_get("@#{target}").send(method)
93
- end
66
+ include Behaviors::Components
67
+ include Behaviors::Events
94
68
 
95
- self.class.define_method(method+"=") do |value|
96
- instance_variable_get("@#{target}").send(method+"=",value)
97
- end
98
- end
99
- end
69
+ # Initalizs the component
70
+ #
71
+ # @param tag [String] The tagname
72
+ def initialize(tag = nil)
73
+ klass = self.class
74
+
75
+ super tag || klass.tagname || klass.name.split('::').last
100
76
 
101
- def applyEvents
102
- return unless self.class.events
103
- self.class.events.each do |args|
104
- if args.length == 3
105
- delegate(args[0], args[1]) { |e| self.method(args[2]).call e }
106
- else
107
- on(args[0]) { |e| self.method(args[1]).call e }
77
+ klass.behaviors.each do |mod, methods|
78
+ methods.each do |name|
79
+ next unless mod.respond_to?(name)
80
+ registry = self.class.instance_variable_get("@#{name}")
81
+ instance_exec registry, &mod.method(name)
108
82
  end
109
83
  end
110
84
  end
@@ -1,7 +1,16 @@
1
+ # rubocop:disable ModuleFunction
2
+
1
3
  module Fron
4
+ # Eventable
2
5
  module Eventable
3
6
  extend self
4
7
 
8
+ # Add an event listener
9
+ #
10
+ # @param event [String] The type of the event
11
+ # @param block [Proc] The listener body
12
+ #
13
+ # @return [Proc] The block
5
14
  def on(event, &block)
6
15
  @events ||= {}
7
16
  @events[event] ||= []
@@ -9,6 +18,11 @@ module Fron
9
18
  block
10
19
  end
11
20
 
21
+ # Triggers an event
22
+ #
23
+ # @param event [String] The type of the event
24
+ # @param data = {} [type] The data
25
+ # @param triggerGlobal [Boolean] Whether or not to trigger a global event
12
26
  def trigger(event, data = {}, triggerGlobal = true)
13
27
  return unless @events
14
28
  return unless @events[event]
@@ -18,6 +32,10 @@ module Fron
18
32
  end
19
33
  end
20
34
 
35
+ # Removes event listeners
36
+ #
37
+ # @param event [String] The type of the event
38
+ # @param block [Proc] The listener body
21
39
  def off(event = nil, &block)
22
40
  return unless @events
23
41
  if block_given?
@@ -1,15 +1,24 @@
1
1
  module Fron
2
+ # Logger
2
3
  class Logger
4
+ # Sets / gets the log level
5
+ #
6
+ # @param value [Symbol] The level
7
+ # @return [Symbol] The level
3
8
  attr_accessor :level
4
9
 
10
+ # Initailizes the logger
5
11
  def initialize
6
12
  @level = :info
7
13
  end
8
14
 
15
+ # Logs the given message
16
+ #
17
+ # @param message [String] The message
9
18
  def info(message)
10
19
  return if ENV == 'test'
11
20
  return if @level == :error
12
- puts Time.now.strftime("[%H:%M] ") + message
21
+ puts Time.now.strftime('[%H:%M] ') + message
13
22
  end
14
23
  end
15
24
  end
@@ -0,0 +1,9 @@
1
+ require 'fron/core_ext/hash'
2
+ require 'fron/core_ext/kernel'
3
+ require 'fron/core_ext/numeric'
4
+ require 'fron/core_ext/proc'
5
+ require 'fron/core_ext/string'
6
+ require 'fron/core_ext/object'
7
+ require 'fron/core_ext/nil'
8
+ require 'fron/core_ext/date'
9
+ require 'fron/core_ext/array'
@@ -0,0 +1,12 @@
1
+ # Array extensions
2
+ class Array
3
+ # Runs through the elements
4
+ # form the back with index
5
+ #
6
+ # @yieldreturn [*] The item and index
7
+ def reverse_each_with_index
8
+ (0...length).reverse_each do |i|
9
+ yield self[i], i
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,57 @@
1
+ require 'date'
2
+
3
+ # Methods for date class
4
+ class Date
5
+ class << self
6
+ # Returns a range for this week
7
+ #
8
+ # @return [Range] The days as range
9
+ def this_week
10
+ Date.week(Date.today)
11
+ end
12
+
13
+ # Returns a range for last week
14
+ #
15
+ # @return [Range] The days as range
16
+ def last_week
17
+ Date.week(Date.today - 7)
18
+ end
19
+
20
+ # Returns the monday of the current week
21
+ #
22
+ # @return [Date] The date
23
+ def monday(date = Date.today)
24
+ today = date
25
+ day = today.wday
26
+ diff = case day
27
+ when 0
28
+ 6
29
+ when 1..6
30
+ day - 1
31
+ end
32
+ today - diff
33
+ end
34
+
35
+ # Returns the week days in the current week
36
+ #
37
+ # @return [Range] The days as range
38
+ def week(date = Date.today)
39
+ day = monday(date)
40
+ (day..day + 6)
41
+ end
42
+ end
43
+
44
+ # Returns the begging of the month
45
+ #
46
+ # @return [Date] The date
47
+ def beginning_of_month
48
+ self.class.new year, month, 1
49
+ end
50
+
51
+ # Returns the end of the month
52
+ #
53
+ # @return [Date] The date
54
+ def end_of_month
55
+ self.class.new year, month + 1, 0
56
+ end
57
+ end
@@ -0,0 +1,52 @@
1
+ # Hash
2
+ class Hash
3
+ # Returns the difference from the other object
4
+ #
5
+ # @param other [Hash] The other hash
6
+ #
7
+ # @return [Hash] The difference
8
+ def difference(other)
9
+ Hash[to_a - other.to_a]
10
+ end
11
+
12
+ alias_method :-, :difference
13
+
14
+ # Converts the hash into an url encoded query string
15
+ #
16
+ # @return [String] the query string
17
+ def to_query_string
18
+ map do |key, value|
19
+ `encodeURIComponent(#{key})+"="+encodeURIComponent(#{value})`
20
+ end.join '&'
21
+ end
22
+
23
+ # Converts the hash into a form data object
24
+ #
25
+ # @return [FormData] The native form data object
26
+ def to_form_data
27
+ form_data = `new FormData()`
28
+ each do |key, value|
29
+ `#{form_data}.append(#{key},#{value})`
30
+ end
31
+ form_data
32
+ end
33
+
34
+ # Produces a diff hash from self and the other hash
35
+ #
36
+ # @param other [Hash] The other hash
37
+ #
38
+ # @return [Hash] The difference from the other hash
39
+ def deep_diff(other)
40
+ (keys + other.keys).uniq.each_with_object({}) do |key, diff|
41
+ self_key = self[key]
42
+ other_key = other[key]
43
+ next if self_key == other_key
44
+ if self_key.respond_to?(:deep_diff) && other_key.respond_to?(:deep_diff)
45
+ diff[key] = self_key.deep_diff(other_key)
46
+ else
47
+ diff[key] = [self_key, other_key]
48
+ end
49
+ diff
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,57 @@
1
+ # Kernel
2
+ module Kernel
3
+ # Requests an animation frame from the browser
4
+ # and runs the givel block if given.
5
+ def request_animation_frame
6
+ return unless block_given?
7
+ return unless `!!window.requestAnimationFrame`
8
+ `window.requestAnimationFrame(function(){ #{yield} })`
9
+ end
10
+
11
+ # Runs the given block after the given number of milliseconds.
12
+ #
13
+ # @param ms [Integer] The milliseconds
14
+ def timeout(ms = 0)
15
+ `setTimeout(function(){#{yield}},#{ms})`
16
+ end
17
+
18
+ # Shows a prompt window with text and value
19
+ #
20
+ # @param text [String] The text
21
+ # @param value [String] The value
22
+ #
23
+ # @return [String] The user input
24
+ def prompt(text, value)
25
+ `prompt(#{text}, #{value})`
26
+ end
27
+
28
+ # Shows an alert window with the given text
29
+ #
30
+ # @param text [String] the text
31
+ def alert(text)
32
+ `alert(#{text})`
33
+ end
34
+
35
+ # Shows an confirm window with the given text
36
+ #
37
+ # @param text [String] the text
38
+ #
39
+ # @return [Boolean] True of false depending on user input
40
+ def confirm(text)
41
+ `confirm(#{text})`
42
+ end
43
+
44
+ # Clears the timeout with the given ID
45
+ #
46
+ # @param id [Numeric] The ID
47
+ def clear_timeout(id)
48
+ `clearTimeout(#{id})`
49
+ end
50
+
51
+ # Returns the logger for the application
52
+ #
53
+ # @return [Fron::Logger] The logger
54
+ def logger
55
+ @logger ||= Fron::Logger.new
56
+ end
57
+ end
@@ -0,0 +1,7 @@
1
+ # Nil
2
+ class NilClass
3
+ # Returns true for empty?
4
+ def empty?
5
+ true
6
+ end
7
+ end
@@ -0,0 +1,19 @@
1
+ # Numeric
2
+ class Numeric
3
+ # Clamps itself between two values
4
+ #
5
+ # @param min [Numeric] The minimum value
6
+ # @param max [Numeric] The maximum value
7
+ #
8
+ # @return [Numeric] The clamped value
9
+ def clamp(min, max)
10
+ [[self, max].min, min].max
11
+ end
12
+
13
+ # Returns the px representation
14
+ #
15
+ # @return [String] The px
16
+ def px
17
+ "#{round}px"
18
+ end
19
+ end