fron 0.1.0

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.
@@ -0,0 +1,41 @@
1
+ module Fron
2
+ class Controller
3
+ class << self
4
+ attr_accessor :baseComponent, :routes, :beforeFilters, :events
5
+
6
+ def base(component)
7
+ @baseComponent = component
8
+ end
9
+
10
+ def route(*args)
11
+ @routes ||= []
12
+ @routes << Router.map(*args)
13
+ end
14
+
15
+ def on(name,action)
16
+ @events ||= []
17
+ @events << {name: name, action: action}
18
+ end
19
+
20
+ def beforeFilter(method,actions)
21
+ @beforeFilters ||= []
22
+ @beforeFilters << {method: method, actions: actions}
23
+ end
24
+ end
25
+
26
+ attr_reader :base
27
+
28
+ def initialize
29
+ if self.class.baseComponent
30
+ @base = self.class.baseComponent.new
31
+ else
32
+ @base = DOM::Element.new 'div'
33
+ end
34
+
35
+ return unless self.class.events
36
+ self.class.events.each do |event|
37
+ Eventable.on event[:name] do self.send(event[:action]) end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,31 @@
1
+ module Fron
2
+ module Eventable
3
+ extend self
4
+
5
+ def on(event, &block)
6
+ @events ||= {}
7
+ @events[event] ||= []
8
+ @events[event] << block
9
+ end
10
+
11
+ def trigger(event, triggerGlobal = true)
12
+ Eventable.trigger event, false if triggerGlobal
13
+ return unless @events
14
+ return unless @events[event]
15
+ @events[event].each do |block|
16
+ block.call
17
+ end
18
+ end
19
+
20
+ def off(event = nil, &block)
21
+ return unless @events
22
+ if block_given?
23
+ @events[event].delete block
24
+ elsif event
25
+ @events[event] = []
26
+ else
27
+ @events = {}
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,8 @@
1
+ module Fron
2
+ class Logger
3
+ def info(message)
4
+ return if ENV == 'test'
5
+ puts Time.now.strftime("[%H:%M] ") + message
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,68 @@
1
+ module Fron
2
+ class Model
3
+ include Eventable
4
+ attr_reader :errors
5
+
6
+ class << self
7
+ attr_accessor :fields
8
+ attr_accessor :adapter
9
+
10
+ def adapter(adapter, options = {})
11
+ options.merge! fields: @fields
12
+ @adapter = adapter.new options
13
+ end
14
+
15
+ def field(name)
16
+ @fields ||= []
17
+ @fields << name
18
+ define_method(name) do
19
+ @data[name]
20
+ end
21
+ define_method(name+"=") do |value|
22
+ @data[name] = value
23
+ trigger 'change'
24
+ end
25
+ end
26
+
27
+ def all(&block)
28
+ @adapter.all do |items|
29
+ block.call items.map{ |item| self.new item }
30
+ end
31
+ end
32
+
33
+ def find(id, &block)
34
+ user = self.new
35
+ @adapter.get id do |data|
36
+ user.merge data
37
+ block.call user
38
+ end
39
+ user
40
+ end
41
+ end
42
+
43
+ def initialize(data = {})
44
+ @data = data
45
+ end
46
+
47
+ def update(attributes, &block)
48
+ data = @data.dup.merge! attributes
49
+ self.class.instance_variable_get("@adapter").set id, data do |errors|
50
+ @errors = errors
51
+ merge data
52
+ block.call if block_given?
53
+ end
54
+ end
55
+
56
+ def dirty?
57
+ !self.id
58
+ end
59
+
60
+ private
61
+
62
+ def merge(data)
63
+ data.each_pair do |key,value|
64
+ self.send(key+"=", value) if self.respond_to?(key+"=")
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,81 @@
1
+ module Fron
2
+ class Router
3
+ def initialize(routes,config)
4
+ @config = config
5
+ @routes = routes
6
+
7
+ DOM::Window.on 'load' do
8
+ route
9
+ end
10
+ DOM::Window.on 'hashchange' do
11
+ route
12
+ end
13
+ end
14
+
15
+ def self.map(*args)
16
+ data = case args.length
17
+ when 1
18
+ action = args[0]
19
+ {path: "*"}
20
+ when 2
21
+ action = args[1]
22
+ {path: Router.pathToRegexp(args[0]) }
23
+ end
24
+ if action.is_a? Class
25
+ data[:controller] = action.new
26
+ else
27
+ data[:action] = action.to_s
28
+ end
29
+ data
30
+ end
31
+
32
+ def self.pathToRegexp(path)
33
+ return path if path == "*"
34
+ {regexp: Regexp.new('^'+path.gsub(/:(.+)/, '(.+)')), map: path.match(/:(.+)/).to_a[1..-1] }
35
+ end
36
+
37
+ def route(hash = DOM::Window.hash, controller = nil)
38
+ routes = controller ? controller.class.routes : @routes
39
+ routes.each do |r|
40
+ if r[:path] == '*'
41
+ if r[:controller]
42
+ break route(hash,r[:controller])
43
+ else
44
+ break applyRoute(controller,r)
45
+ end
46
+ else
47
+ matches = hash.match(r[:path][:regexp]).to_a[1..-1]
48
+ if matches
49
+ params = {}
50
+ if r[:path][:map]
51
+ r[:path][:map].each_with_index do |key, index|
52
+ params[key.to_sym] = matches[index]
53
+ end
54
+ end
55
+ if r[:action]
56
+ break applyRoute(controller,r,params)
57
+ else
58
+ break route hash.gsub(r[:path][:regexp],''), r[:controller]
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+
65
+ private
66
+
67
+ def applyRoute(controller,route, params = {})
68
+ if controller.class.beforeFilters
69
+ controller.class.beforeFilters.each do |filter|
70
+ if filter[:actions].include?(route[:action])
71
+ controller.send(filter[:method], params)
72
+ end
73
+ end
74
+ end
75
+ controller.send(route[:action], params)
76
+ @config.logger.info "Navigate >> #{controller.class}##{route[:action]} with params #{params}"
77
+ @config.main.empty
78
+ @config.main << controller.base
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,11 @@
1
+ require './dom/modules/events'
2
+ require './dom/modules/classlist'
3
+ require './dom/modules/dimensions'
4
+ require './dom/style'
5
+ require './dom/node'
6
+ require './dom/text'
7
+ require './dom/element'
8
+ require './dom/fragment'
9
+ require './dom/document'
10
+ require './dom/window'
11
+ require './dom/event'
@@ -0,0 +1,20 @@
1
+ module DOM
2
+ module Document
3
+ def self.head
4
+ find 'head'
5
+ end
6
+
7
+ def self.body
8
+ find 'body'
9
+ end
10
+
11
+ def self.title=(value)
12
+ `document.title = #{value}`
13
+ end
14
+
15
+ def self.find(selector)
16
+ value = `document.querySelector(#{selector}) || false`
17
+ value ? DOM::Element.new(value) : nil
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,102 @@
1
+ module DOM
2
+ class Element
3
+ include Node
4
+ include ClassList
5
+ include Dimensions
6
+
7
+ attr_reader :style
8
+
9
+ ATTRIBUTE_REGEXP = /\[(.*?)=(.*?)\]/
10
+ TAG_REGEXP = /(^[A-Za-z_\-0-9]+)(.*)/
11
+ MODIFIER_REGEXP = /(#|\.)(.+?)(?=#|\.| |$)/
12
+
13
+ def initialize(data)
14
+ if `typeof #{data} === 'string'`
15
+ match, tag, rest = data.match(TAG_REGEXP).to_a
16
+ @el = `document.createElement(#{tag})`
17
+ rest = rest.gsub ATTRIBUTE_REGEXP do |match|
18
+ m,key,value = match.match(ATTRIBUTE_REGEXP).to_a
19
+ self[key] = value
20
+ ''
21
+ end
22
+ rest = rest.gsub MODIFIER_REGEXP do |match|
23
+ m,type,value = match.match(MODIFIER_REGEXP).to_a
24
+ case type
25
+ when "#"
26
+ self['id'] = value
27
+ when "."
28
+ addClass value
29
+ end
30
+ ''
31
+ end
32
+ if (m = rest.match /\s(.+)$/)
33
+ self.text = m[0].strip
34
+ end
35
+ else
36
+ @el = data
37
+ end
38
+ @style = Style.new @el
39
+ end
40
+
41
+ # Visiblity
42
+ # --------------------------------
43
+ def hide
44
+ @style.display = 'none'
45
+ end
46
+
47
+ def show
48
+ @style.display = 'block'
49
+ end
50
+
51
+ # Attribute access
52
+ # --------------------------------
53
+ def [](name)
54
+ `#{@el}.getAttribute(#{name})`
55
+ end
56
+
57
+ def []=(name,value)
58
+ `#{@el}.setAttribute(#{name},#{value})`
59
+ end
60
+
61
+ # Traversing
62
+ # --------------------------------
63
+ def find(selector)
64
+ value = `#{@el}.querySelector(#{selector}) || false`
65
+ value ? DOM::Element.new(value) : nil
66
+ end
67
+
68
+ # HTML Modification
69
+ # --------------------------------
70
+ def html
71
+ `#{@el}.innerHTML`
72
+ end
73
+
74
+ def html=(value)
75
+ `#{@el}.innerHTML = #{value}`
76
+ end
77
+
78
+ def empty
79
+ self.html = ''
80
+ end
81
+
82
+ def value
83
+ `#{@el}.value`
84
+ end
85
+
86
+ def value=(value)
87
+ `#{@el}.value = #{value}`
88
+ end
89
+
90
+ def checked
91
+ `!!#{@el}.checked`
92
+ end
93
+
94
+ def checked=(value)
95
+ `#{@el}.checked = #{value}`
96
+ end
97
+
98
+ def tag
99
+ `#{@el}.tagName`.downcase
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,70 @@
1
+ class Event
2
+ def initialize(e)
3
+ @e = e
4
+ end
5
+
6
+ def target
7
+ `#{@e}.target`
8
+ end
9
+
10
+ def charCode
11
+ `#{@e}.charCode`
12
+ end
13
+
14
+ def keyCode
15
+ `#{@e}.keyCode`
16
+ end
17
+
18
+ def stop
19
+ preventDefault
20
+ stopPropagation
21
+ end
22
+
23
+ def preventDefault
24
+ `#{@e}.preventDefault()`
25
+ end
26
+
27
+ def stopPropagation
28
+ `#{@e}.stopPropagation()`
29
+ end
30
+
31
+ def pageX
32
+ `#{@e}.pageX`
33
+ end
34
+
35
+ def pageY
36
+ `#{@e}.pageY`
37
+ end
38
+
39
+ def screenX
40
+ `#{@e}.screenX`
41
+ end
42
+
43
+ def screenY
44
+ `#{@e}.screenY`
45
+ end
46
+
47
+ def clientX
48
+ `#{@e}.clientX`
49
+ end
50
+
51
+ def clientY
52
+ `#{@e}.clientY`
53
+ end
54
+
55
+ def alt?
56
+ `#{@e}.altkey`
57
+ end
58
+
59
+ def shift?
60
+ `#{@e}.shiftkey`
61
+ end
62
+
63
+ def ctrl?
64
+ `#{@e}.ctrlkey`
65
+ end
66
+
67
+ def meta?
68
+ `#{@e}.metakey`
69
+ end
70
+ end
@@ -0,0 +1,9 @@
1
+ module DOM
2
+ class Fragment
3
+ include Node
4
+
5
+ def initialize
6
+ @el = `document.createDocumentFragment()`
7
+ end
8
+ end
9
+ end