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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7d8c38354230edc446e8203ee3896a31ac7f98fd
4
- data.tar.gz: 356f626ad8188570d0dd3dd8184d15639b095d6f
3
+ metadata.gz: 9a846e18a8992b019b87619c1bdafb965f975400
4
+ data.tar.gz: bc56889e6594d08b74da58eab1a29f58ff4f0c5f
5
5
  SHA512:
6
- metadata.gz: 6db2cca637b146893fd3ac1bb5c40bbd7ca47572a51d0482699b5723bc418fd654d3cd8e079dcdda4c6aa8d806c1cd4af623935751f7ee1075854fde430467e5
7
- data.tar.gz: 5cb1deab188b5a8cb12d1039622ab5ededa534661caedb19081a569ebe8b6af23fbec114d56ddb77dcec0b34587addb18c355bcb072d2a40898ec2825ccffc11
6
+ metadata.gz: 5d5cb8d2303030c60a2cf97b3fa7f8a838e9213b3c533b9ee0502319ce06a5457710843acb7ebca9fac3c30c59f1c967bf2b4b3c2acaba1dd0e6bcc8dc993cd6
7
+ data.tar.gz: cf6d819951e9062584dc879c9f864bf6798acd19deafe23f043ec9b02a54e1fd1397d3cecb6f0f2f450b5cd5d2cd6c5b84898078bf5e5263bd7b45fe1660eb4a
@@ -0,0 +1,3 @@
1
+ doc
2
+ tmp
3
+ .yardoc
data/.reek ADDED
@@ -0,0 +1,11 @@
1
+ ---
2
+ ControlParameter:
3
+ enabled: false
4
+ BooleanParameter:
5
+ enabled: false
6
+ NilCheck:
7
+ enabled: false
8
+ FeatureEnvy:
9
+ enabled: false
10
+ PrimaDonnaMethod:
11
+ enabled: false
@@ -0,0 +1,54 @@
1
+ AllCops:
2
+ Exclude:
3
+ - vendor/**/*
4
+
5
+ VariableName:
6
+ EnforcedStyle: snake_case
7
+
8
+ MethodName:
9
+ EnforcedStyle: snake_case
10
+
11
+ HandleExceptions:
12
+ Enabled: false
13
+
14
+ Blocks:
15
+ Enabled: true
16
+
17
+ SingleSpaceBeforeFirstArg:
18
+ Enabled: false
19
+
20
+ LineLength:
21
+ Enabled: false
22
+
23
+ MethodLength:
24
+ Enabled: false
25
+
26
+ Blocks:
27
+ Enabled: false
28
+
29
+ TrivialAccessors:
30
+ Enabled: false
31
+
32
+ ClassLength:
33
+ Enabled: false
34
+
35
+ UnneededPercentX:
36
+ Enabled: false
37
+
38
+ CyclomaticComplexity:
39
+ Enabled: false
40
+
41
+ RegexpLiteral:
42
+ Enabled: false
43
+
44
+ AbcSize:
45
+ Enabled: false
46
+
47
+ PerceivedComplexity:
48
+ Enabled: false
49
+
50
+ EmptyElse:
51
+ Enabled: false
52
+
53
+ PredicateName:
54
+ Enabled: false
@@ -0,0 +1,11 @@
1
+ language: ruby
2
+ script: bundle exec rake ci
3
+ rvm:
4
+ - 2.0
5
+ notifications:
6
+ webhooks:
7
+ urls:
8
+ - https://webhooks.gitter.im/e/8375add4f4ffbc5b7434
9
+ on_success: change
10
+ on_failure: always
11
+ on_start: false
@@ -0,0 +1,4 @@
1
+ --private
2
+ --protected
3
+ --title Fron
4
+ opal/**/*.rb
@@ -0,0 +1,7 @@
1
+ #### 0.1.* -> 0.2.*
2
+ -------------------
3
+ * Removed **delegate** DSL from **Component** in favor of `def_delegators` method in the **Forwardable** module.
4
+ * Removed **model** relation from **Component**
5
+ * Removed **options** argument from **Component**
6
+ * Refactored **component** and **on** DSLs in **Component** into **Behaviours**
7
+ * Removed **Controller**, **Router**, **Model** and **Application** because we are moving away from an MVC style framework
data/Gemfile CHANGED
@@ -1,4 +1,6 @@
1
- source "https://rubygems.org"
1
+ source 'https://rubygems.org'
2
2
  gemspec
3
3
 
4
4
  gem 'rake'
5
+ gem 'quality_control', github: 'gdotdesign/quality-control', ref: 'next'
6
+ gem 'execjs'
@@ -1,35 +1,126 @@
1
+ GIT
2
+ remote: git://github.com/gdotdesign/quality-control.git
3
+ revision: 1035bd82c6df8882d831060a2c7a4f89416b18ed
4
+ ref: next
5
+ specs:
6
+ quality_control (0.1.2)
7
+ colorize (~> 0.7.3)
8
+ opal-rspec
9
+ rake
10
+ rubocop
11
+ rubycritic
12
+ scss-lint
13
+ yard
14
+
1
15
  PATH
2
16
  remote: .
3
17
  specs:
4
- fron (0.1.4)
5
- opal (~> 0.6.2)
18
+ fron (0.2.0rc1)
19
+ opal (~> 0.7.0)
6
20
 
7
21
  GEM
8
22
  remote: https://rubygems.org/
9
23
  specs:
24
+ abstract_type (0.0.7)
25
+ adamantium (0.2.0)
26
+ ice_nine (~> 0.11.0)
27
+ memoizable (~> 0.4.0)
28
+ ast (2.0.0)
29
+ astrolabe (1.3.0)
30
+ parser (>= 2.2.0.pre.3, < 3.0)
31
+ axiom-types (0.1.1)
32
+ descendants_tracker (~> 0.0.4)
33
+ ice_nine (~> 0.11.0)
34
+ thread_safe (~> 0.3, >= 0.3.1)
35
+ coercible (1.0.0)
36
+ descendants_tracker (~> 0.0.1)
37
+ colorize (0.7.5)
38
+ concord (0.1.5)
39
+ adamantium (~> 0.2.0)
40
+ equalizer (~> 0.0.9)
41
+ descendants_tracker (0.0.4)
42
+ thread_safe (~> 0.3, >= 0.3.1)
43
+ diff-lcs (1.2.5)
44
+ equalizer (0.0.10)
45
+ execjs (2.4.0)
46
+ flay (2.4.0)
47
+ ruby_parser (~> 3.0)
48
+ sexp_processor (~> 4.0)
49
+ flog (4.2.1)
50
+ ruby_parser (~> 3.1, > 3.1.0)
51
+ sexp_processor (~> 4.4)
10
52
  hike (1.2.3)
11
- json (1.8.1)
12
- multi_json (1.10.0)
13
- opal (0.6.2)
14
- source_map
15
- sprockets
16
- opal-rspec (0.3.0.beta3)
17
- opal (>= 0.6.0, < 1.0.0)
18
- rack (1.5.2)
19
- rake (10.3.1)
20
- source_map (3.0.1)
21
- json
22
- sprockets (2.12.1)
53
+ ice_nine (0.11.1)
54
+ memoizable (0.4.2)
55
+ thread_safe (~> 0.3, >= 0.3.1)
56
+ multi_json (1.11.0)
57
+ opal (0.7.1)
58
+ hike (~> 1.2)
59
+ sourcemap (~> 0.1.0)
60
+ sprockets (>= 2.2.3, < 4.0.0)
61
+ tilt (~> 1.4)
62
+ opal-rspec (0.4.1)
63
+ opal (~> 0.7.0)
64
+ parser (2.2.0.3)
65
+ ast (>= 1.1, < 3.0)
66
+ powerpack (0.1.0)
67
+ procto (0.0.2)
68
+ rack (1.6.0)
69
+ rainbow (2.0.0)
70
+ rake (10.4.2)
71
+ reek (1.6.5)
72
+ parser (~> 2.2.0.pre.7)
73
+ rainbow (>= 1.99, < 3.0)
74
+ unparser (~> 0.2.2)
75
+ rubocop (0.29.1)
76
+ astrolabe (~> 1.3)
77
+ parser (>= 2.2.0.1, < 3.0)
78
+ powerpack (~> 0.1)
79
+ rainbow (>= 1.99.1, < 3.0)
80
+ ruby-progressbar (~> 1.4)
81
+ ruby-progressbar (1.7.1)
82
+ ruby_parser (3.6.5)
83
+ sexp_processor (~> 4.1)
84
+ rubycritic (1.4.0)
85
+ flay (= 2.4.0)
86
+ flog (= 4.2.1)
87
+ parser (>= 2.2.0, < 3.0)
88
+ reek (= 1.6.5)
89
+ virtus (~> 1.0)
90
+ sass (3.4.13)
91
+ scss-lint (0.35.0)
92
+ rainbow (~> 2.0)
93
+ sass (~> 3.4.1)
94
+ sexp_processor (4.5.0)
95
+ sourcemap (0.1.1)
96
+ sprockets (2.12.3)
23
97
  hike (~> 1.2)
24
98
  multi_json (~> 1.0)
25
99
  rack (~> 1.0)
26
100
  tilt (~> 1.1, != 1.3.0)
101
+ thread_safe (0.3.5)
27
102
  tilt (1.4.1)
103
+ unparser (0.2.2)
104
+ abstract_type (~> 0.0.7)
105
+ adamantium (~> 0.2.0)
106
+ concord (~> 0.1.5)
107
+ diff-lcs (~> 1.2.5)
108
+ equalizer (~> 0.0.9)
109
+ parser (~> 2.2.0.2)
110
+ procto (~> 0.0.2)
111
+ virtus (1.0.5)
112
+ axiom-types (~> 0.1)
113
+ coercible (~> 1.0)
114
+ descendants_tracker (~> 0.0, >= 0.0.3)
115
+ equalizer (~> 0.0, >= 0.0.9)
116
+ yard (0.8.7.6)
28
117
 
29
118
  PLATFORMS
30
119
  ruby
31
120
 
32
121
  DEPENDENCIES
122
+ execjs
33
123
  fron!
34
- opal-rspec (~> 0.3.0.beta3)
124
+ opal-rspec (~> 0.4.0)
125
+ quality_control!
35
126
  rake
data/Rakefile CHANGED
@@ -1,18 +1,22 @@
1
- require 'bundler'
2
- Bundler.require
3
- Bundler::GemHelper.install_tasks
4
- require 'opal/rspec/rake_task'
5
- require 'rack'
6
-
7
- Opal::RSpec::RakeTask.new(:default)
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'quality_control'
4
+ require 'quality_control/rubycritic'
5
+ require 'quality_control/rubocop'
6
+ require 'quality_control/yard'
7
+ require 'quality_control/opal_rspec'
8
+ require 'fron'
8
9
 
9
- task :test do
10
+ Bundler::GemHelper.install_tasks
10
11
 
11
- app = Opal::Server.new { |s|
12
- s.main = 'opal/rspec/sprockets_runner'
13
- s.append_path 'spec'
14
- s.debug = false
15
- }
12
+ QualityControl::Rubycritic.directories += %w(opal)
13
+ QualityControl::Yard.threshold = 95
14
+ QualityControl::OpalRspec.files = /^opal\/fron\/.*\.rb/
15
+ QualityControl::OpalRspec.threshold = 98
16
16
 
17
- Rack::Server.start(:app => app, :Port => 9292)
18
- end
17
+ QualityControl.tasks += %w(
18
+ syntax:ruby
19
+ opal:rspec:coverage
20
+ documentation:coverage
21
+ rubycritic:coverage
22
+ )
@@ -0,0 +1,23 @@
1
+ # Fron
2
+ [![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/digitalnatives/fron?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
3
+ [![Build Status](https://travis-ci.org/digitalnatives/fron.svg?branch=master)](https://travis-ci.org/digitalnatives/fron)
4
+ [![Code Climate](https://codeclimate.com/github/digitalnatives/fron/badges/gpa.svg)](https://codeclimate.com/github/digitalnatives/fron)
5
+ [![Inline docs](http://inch-ci.org/github/digitalnatives/fron.svg?branch=master)](http://inch-ci.org/github/digitalnatives/fron)
6
+
7
+ Fron is a general UI framework written in Ruby.
8
+
9
+ * Documentation: [http://www.rubydoc.info/github/digitalnatives/fron/master](http://www.rubydoc.info/github/digitalnatives/fron/master)
10
+ * Wiki: [https://github.com/digitalnatives/fron/wiki](https://github.com/digitalnatives/fron/wiki)
11
+
12
+ # Rake Tasks
13
+ ```
14
+ rake ci # Run continous integation tasks
15
+ rake documentation:coverage # Check documentation coverage
16
+ rake documentation:generate # Generate documentation
17
+ rake opal:rspec # Run opal specs in phantomjs
18
+ rake opal:rspec:coverage # Check opal specs coverage
19
+ rake opal:rspec:coverage:runner # Run opal specs in phantomjs
20
+ rake rubycritic:coverage # Check Rubycritic coverage
21
+ rake rubycritic:generate # Generates Rubycritic report
22
+ rake syntax:ruby # Run a Ruby syntax check
23
+ ```
@@ -15,6 +15,6 @@ Gem::Specification.new do |s|
15
15
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
16
  s.require_paths = ['lib']
17
17
 
18
- s.add_runtime_dependency 'opal', ['~> 0.6.2']
19
- s.add_development_dependency 'opal-rspec', '~> 0.3.0.beta3'
18
+ s.add_runtime_dependency 'opal', ['~> 0.7.0']
19
+ s.add_development_dependency 'opal-rspec', '~> 0.4.0'
20
20
  end
@@ -1,3 +1,4 @@
1
+ # Fron
1
2
  module Fron
2
- VERSION = '0.1.4'
3
+ VERSION = '0.2.0rc1'
3
4
  end
@@ -1,6 +1,6 @@
1
1
  require 'opal'
2
- require './fron/core-ext'
3
- require './fron/dom'
4
- require './fron/request'
5
- require './fron/storage'
6
- require './fron/core'
2
+ require 'fron/core_ext'
3
+ require 'fron/dom'
4
+ require 'fron/core'
5
+ require 'fron/request'
6
+ require 'fron/storage'
@@ -1,10 +1,3 @@
1
- require './core/logger'
2
- require './core/component'
3
- require './core/adapters/rails'
4
- require './core/adapters/local'
5
- require './core/configuration'
6
- require './core/eventable'
7
- require './core/model'
8
- require './core/router'
9
- require './core/controller'
10
- require './core/application'
1
+ require 'fron/core/logger'
2
+ require 'fron/core/component'
3
+ require 'fron/core/eventable'
@@ -0,0 +1,42 @@
1
+ module Fron
2
+ # Bevahviors
3
+ module Behaviors
4
+ # Components
5
+ module Components
6
+ # Runs for included classes
7
+ #
8
+ # @param base [Class] The class
9
+ def self.included(base)
10
+ base.register self, [:component]
11
+ end
12
+
13
+ # Creates components from the registry
14
+ #
15
+ # @param registry [Array] Registry of components
16
+ def self.component(registry)
17
+ registry.each do |args|
18
+ arguments = args.dup
19
+ block = arguments.last.is_a?(Proc) ? arguments.pop : nil
20
+ component(*arguments, &block)
21
+ end
22
+ end
23
+
24
+ # Creates a child component
25
+ #
26
+ # @param name [String] The name of the component
27
+ # @param comp [Class] The component
28
+ # @param block [Proc] The block to eval on the new component
29
+ def component(name, comp, &block)
30
+ component = comp.is_a?(Class) ? comp.new(nil) : Component.new(comp)
31
+ component.instance_eval(&block) if block
32
+ self << component
33
+ instance_variable_set "@#{name}", component
34
+
35
+ return if respond_to?(name)
36
+ define_singleton_method name do
37
+ instance_variable_get("@#{name}")
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,27 @@
1
+ module Fron
2
+ # Bevahviors
3
+ module Behaviors
4
+ # Events
5
+ module Events
6
+ # Runs for included classes
7
+ #
8
+ # @param base [Class] The class
9
+ def self.included(base)
10
+ base.register self, [:on]
11
+ end
12
+
13
+ # Applies events from the registry
14
+ #
15
+ # @param registry [Array] Registry of events
16
+ def self.on(registry)
17
+ registry.each do |args|
18
+ if args.length == 3
19
+ delegate(args[0], args[1]) { |event| send args[2], event }
20
+ else
21
+ on(args[0]) { |event| send args[1], event }
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,59 @@
1
+ module Fron
2
+ # Bevahviors
3
+ module Behaviors
4
+ # Components
5
+ module Routes
6
+ # Register a route
7
+ #
8
+ # @param path [String] The path
9
+ # @param action [String] The action to take
10
+ # @param component [Fron::Component] The component
11
+ def self.register(path, action, component)
12
+ @routes << {
13
+ path: Regexp.new(path),
14
+ action: action,
15
+ component: component
16
+ }
17
+ end
18
+
19
+ # Handles hash change event
20
+ #
21
+ # @param hash [String] The hash
22
+ def self.handle_hash_change(hash)
23
+ routes = @routes.select { |route_| route_[:path] =~ hash }
24
+ routes.each do |route|
25
+ matches = hash.match route[:path]
26
+ route[:component].send route[:action], *matches[1..-1]
27
+ end
28
+ end
29
+
30
+ # Runs for included classes
31
+ #
32
+ # @param base [Class] The class
33
+ def self.included(base)
34
+ base.register self, [:route]
35
+
36
+ return if @initialized
37
+ @initialized = true
38
+ @routes = []
39
+ listen
40
+ end
41
+
42
+ # Listen on events (maily for tests)
43
+ def self.listen
44
+ DOM::Window.on('popstate') { handle_hash_change DOM::Window.state }
45
+ end
46
+
47
+ # Registers routes from the registry
48
+ #
49
+ # @param registry [Array] The routes
50
+ def self.route(registry)
51
+ registry.each do |item|
52
+ path, action = item
53
+ fail "There is no method #{action} on #{self}" unless respond_to? action
54
+ Routes.register path, action, self
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end