fron 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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