fron 0.1.4 → 0.2.0rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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