fron 0.2.0rc1 → 1.0.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.
- checksums.yaml +4 -4
- data/.codeclimate.yml +20 -0
- data/.reek +2 -0
- data/.rubocop.yml +14 -11
- data/Gemfile +6 -3
- data/Gemfile.lock +73 -86
- data/Rakefile +11 -15
- data/Readme.md +1 -1
- data/fron.gemspec +2 -2
- data/lib/fron/version.rb +1 -1
- data/opal/fron.rb +2 -0
- data/opal/fron/core.rb +1 -0
- data/opal/fron/core/behaviors/components.rb +18 -10
- data/opal/fron/core/behaviors/events.rb +9 -10
- data/opal/fron/core/behaviors/routes.rb +6 -10
- data/opal/fron/core/behaviors/style.rb +30 -0
- data/opal/fron/core/component.rb +44 -23
- data/opal/fron/core/eventable.rb +3 -3
- data/opal/fron/core/logger.rb +1 -1
- data/opal/fron/core/sheet.rb +140 -0
- data/opal/fron/core_ext.rb +1 -0
- data/opal/fron/core_ext/array.rb +23 -0
- data/opal/fron/core_ext/hash.rb +6 -6
- data/opal/fron/core_ext/kernel.rb +10 -1
- data/opal/fron/core_ext/numeric.rb +7 -0
- data/opal/fron/core_ext/time.rb +6 -0
- data/opal/fron/dom/document.rb +6 -3
- data/opal/fron/dom/element.rb +79 -19
- data/opal/fron/dom/event.rb +5 -1
- data/opal/fron/dom/modules/dimensions.rb +0 -14
- data/opal/fron/dom/modules/element_accessor.rb +25 -0
- data/opal/fron/dom/modules/events.rb +1 -1
- data/opal/fron/dom/node.rb +7 -5
- data/opal/fron/dom/style.rb +0 -2
- data/opal/fron/dom/window.rb +14 -0
- data/opal/fron/event_mock.rb +24 -6
- data/opal/fron/js/scroll_into_view_if_needed.js +27 -0
- data/opal/fron/js/syntetic_event.js +20 -13
- data/opal/fron/request/request.rb +21 -19
- data/opal/fron/request/response.rb +1 -1
- data/opal/fron/storage.rb +2 -0
- data/opal/fron/storage/local_storage.rb +3 -45
- data/opal/fron/storage/session_storage.rb +12 -0
- data/opal/fron/storage/store.rb +54 -0
- data/opal/fron/utils/drag.rb +21 -18
- data/opal/fron/utils/keyboard.rb +14 -12
- data/opal/fron/utils/point.rb +12 -4
- data/opal/fron/utils/render_proc.rb +6 -2
- data/spec/core-ext/array_spec.rb +10 -2
- data/spec/core-ext/numeric_spec.rb +6 -0
- data/spec/core/behaviors/style_spec.rb +51 -0
- data/spec/core/component_inheritance_spec.rb +10 -15
- data/spec/core/component_spec.rb +10 -15
- data/spec/dom/element_spec.rb +12 -1
- data/spec/dom/modules/classlist_spec.rb +8 -9
- data/spec/dom/modules/dimensions_spec.rb +2 -1
- data/spec/dom/modules/events_spec.rb +42 -31
- data/spec/dom/style_spec.rb +1 -1
- data/spec/spec_helper.rb +0 -1
- data/spec/utils/drag_spec.rb +2 -2
- data/spec/utils/keyboard_spec.rb +4 -1
- data/website/application.rb +4 -0
- data/website/config.ru +30 -0
- data/website/examples/content_editable.rb +29 -0
- data/website/examples/converter.rb +49 -0
- data/website/examples/icon_button.rb +20 -0
- data/website/examples/image_paragraph.rb +33 -0
- data/website/examples/my_blue_box.rb +9 -0
- data/website/examples/my_box.rb +9 -0
- data/website/examples/my_button.rb +27 -0
- data/website/examples/my_green_box.rb +14 -0
- data/website/examples/source_reader.rb +32 -0
- data/website/examples/text_area.rb +42 -0
- data/website/pages/components.md.erb +16 -0
- data/website/pages/components/composition.md.erb +9 -0
- data/website/pages/components/events.md.erb +20 -0
- data/website/pages/components/inheritance.md.erb +19 -0
- data/website/pages/components/routes.md.erb +49 -0
- data/website/pages/components/styles.md.erb +38 -0
- data/website/pages/getting-started.md +8 -0
- data/website/pages/home.md +4 -0
- data/website/pages/intro.md +30 -0
- data/website/pages/utilities.md +10 -0
- data/website/pages/utilities/local-storage.md.erb +16 -0
- data/website/pages/utilities/request.md.erb +12 -0
- data/website/setup.rb +162 -0
- data/website/vendor/highlight.js +2 -0
- data/website/vendor/highlight.ruby.js +1 -0
- data/website/vendor/marked.min.js +6 -0
- metadata +43 -7
data/opal/fron/storage.rb
CHANGED
@@ -2,52 +2,10 @@ module Fron
|
|
2
2
|
module Storage
|
3
3
|
# Local Storage wrapper and adapter
|
4
4
|
module LocalStorage
|
5
|
-
|
6
|
-
#
|
7
|
-
# @param key [String] The key
|
8
|
-
#
|
9
|
-
# @return [Object] The value
|
10
|
-
def self.get(key)
|
11
|
-
value = `window.localStorage.getItem(#{key}) || false`
|
12
|
-
value ? JSON.parse(value) : nil
|
13
|
-
end
|
14
|
-
|
15
|
-
# Sets a value to local storage with the given key
|
16
|
-
#
|
17
|
-
# @param key [String] The key
|
18
|
-
# @param data [Object] The value
|
19
|
-
def self.set(key, data)
|
20
|
-
`window.localStorage.setItem(#{key},#{data.to_json})`
|
21
|
-
end
|
22
|
-
|
23
|
-
# Removes a value from local storage with the given key
|
24
|
-
#
|
25
|
-
# @param key [String] The key
|
26
|
-
def self.remove(key)
|
27
|
-
`window.localStorage.removeItem(#{key})`
|
28
|
-
end
|
29
|
-
|
30
|
-
# Returns the all keys present in local storage
|
31
|
-
#
|
32
|
-
# @return [Array] Array of keys
|
33
|
-
def self.keys
|
34
|
-
%x{
|
35
|
-
ret = []
|
36
|
-
for (var key in localStorage){ ret.push(key) }
|
37
|
-
return ret
|
38
|
-
}
|
39
|
-
end
|
40
|
-
|
41
|
-
# Returns all values from local storage
|
42
|
-
#
|
43
|
-
# @return [Array] Array of values
|
44
|
-
def self.all
|
45
|
-
keys.map { |key| get key }
|
46
|
-
end
|
5
|
+
extend Store
|
47
6
|
|
48
|
-
|
49
|
-
|
50
|
-
`window.localStorage.clear()`
|
7
|
+
def self.store
|
8
|
+
`window.localStorage`
|
51
9
|
end
|
52
10
|
end
|
53
11
|
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Fron
|
2
|
+
module Storage
|
3
|
+
# Abstract wrapper and adapter for the Storage API
|
4
|
+
module Store
|
5
|
+
# Gets a value from the store with the given key
|
6
|
+
#
|
7
|
+
# @param key [String] The key
|
8
|
+
#
|
9
|
+
# @return [Object] The value
|
10
|
+
def get(key)
|
11
|
+
value = `#{store}.getItem(#{key}) || false`
|
12
|
+
value ? JSON.parse(value) : nil
|
13
|
+
end
|
14
|
+
|
15
|
+
# Sets a value to the store with the given key
|
16
|
+
#
|
17
|
+
# @param key [String] The key
|
18
|
+
# @param data [Object] The value
|
19
|
+
def set(key, data)
|
20
|
+
`#{store}.setItem(#{key},#{data.to_json})`
|
21
|
+
end
|
22
|
+
|
23
|
+
# Removes a value from the store with the given key
|
24
|
+
#
|
25
|
+
# @param key [String] The key
|
26
|
+
def remove(key)
|
27
|
+
`#{store}.removeItem(#{key})`
|
28
|
+
end
|
29
|
+
|
30
|
+
# Returns the all keys present in store
|
31
|
+
#
|
32
|
+
# @return [Array] Array of keys
|
33
|
+
def keys
|
34
|
+
%x{
|
35
|
+
ret = []
|
36
|
+
for (var key in #{store}){ ret.push(key) }
|
37
|
+
return ret
|
38
|
+
}
|
39
|
+
end
|
40
|
+
|
41
|
+
# Returns all values from the store
|
42
|
+
#
|
43
|
+
# @return [Array] Array of values
|
44
|
+
def all
|
45
|
+
keys.map { |key| get key }
|
46
|
+
end
|
47
|
+
|
48
|
+
# Clears the store, removeing all values
|
49
|
+
def clear
|
50
|
+
`#{store}.clear()`
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
data/opal/fron/utils/drag.rb
CHANGED
@@ -12,29 +12,30 @@ module Fron
|
|
12
12
|
# @return [DOM::Element] The documents body
|
13
13
|
attr_reader :body
|
14
14
|
|
15
|
-
IS_TOUCH =
|
16
|
-
|
17
|
-
if IS_TOUCH
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
15
|
+
IS_TOUCH = false
|
16
|
+
|
17
|
+
EVENTS = if IS_TOUCH
|
18
|
+
{
|
19
|
+
down: 'touchstart',
|
20
|
+
move: 'touchmove',
|
21
|
+
up: 'touchend'
|
22
|
+
}
|
23
|
+
else
|
24
|
+
{
|
25
|
+
down: 'mousedown',
|
26
|
+
move: 'mousemove',
|
27
|
+
up: 'mouseup'
|
28
|
+
}
|
29
|
+
end
|
30
30
|
|
31
31
|
# Creates a new drag instance.
|
32
32
|
#
|
33
33
|
# @param base [DOM::Element] The element to monitor
|
34
|
-
def initialize(base)
|
34
|
+
def initialize(base, start_distance = 7)
|
35
35
|
reset
|
36
36
|
@base = base
|
37
37
|
@body = DOM::Document.body
|
38
|
+
@start_distance = start_distance
|
38
39
|
|
39
40
|
@base.on EVENTS[:down] do |event| start(event) end
|
40
41
|
end
|
@@ -66,6 +67,8 @@ module Fron
|
|
66
67
|
@up_method = @body.on! EVENTS[:up] do |evt| up(evt) end
|
67
68
|
|
68
69
|
request_animation_frame do move end
|
70
|
+
|
71
|
+
pos(event) if @start_distance == 0
|
69
72
|
end
|
70
73
|
|
71
74
|
# Runs when the pointer moves starts.
|
@@ -73,7 +76,7 @@ module Fron
|
|
73
76
|
# @param event [Event] The event
|
74
77
|
def pos(event)
|
75
78
|
@position = position(event)
|
76
|
-
if diff.distance
|
79
|
+
if diff.distance >= @start_distance.to_i && !@started
|
77
80
|
@started = true
|
78
81
|
trigger 'start', @target
|
79
82
|
end
|
@@ -128,7 +131,7 @@ module Fron
|
|
128
131
|
if IS_TOUCH && event.touches
|
129
132
|
Point.new `#{event.touches}[0].pageX`, `#{event.touches}[0].pageY`
|
130
133
|
else
|
131
|
-
Point.new event.
|
134
|
+
Point.new event.page_x, event.page_y
|
132
135
|
end
|
133
136
|
end
|
134
137
|
end
|
data/opal/fron/utils/keyboard.rb
CHANGED
@@ -39,11 +39,8 @@ module Fron
|
|
39
39
|
# @param event [DOM::Event] The event
|
40
40
|
def keydown(event)
|
41
41
|
return if DOM::Document.active_element
|
42
|
-
|
43
|
-
combo
|
44
|
-
combo << 'shift' if event.shift?
|
45
|
-
combo << 'alt' if event.alt?
|
46
|
-
combo.uniq!
|
42
|
+
|
43
|
+
combo = Keyboard.calculate_shortcut event
|
47
44
|
|
48
45
|
self.class.shortcuts.each do |shortcut|
|
49
46
|
next unless shortcut[:parts].sort == combo.sort
|
@@ -53,18 +50,23 @@ module Fron
|
|
53
50
|
end
|
54
51
|
end
|
55
52
|
|
53
|
+
def self.calculate_shortcut(event)
|
54
|
+
combo = [event.key]
|
55
|
+
combo << 'ctrl' if event.ctrl?
|
56
|
+
combo << 'shift' if event.shift?
|
57
|
+
combo << 'alt' if event.alt?
|
58
|
+
combo << 'meta' if event.meta?
|
59
|
+
combo.uniq
|
60
|
+
end
|
61
|
+
|
56
62
|
# Handles the shortcut.
|
57
63
|
#
|
58
64
|
# @param shortcut [Hash] The shortcut
|
59
65
|
def handle_shortcut(shortcut)
|
60
66
|
action = shortcut[:action]
|
61
|
-
if shortcut[:block]
|
62
|
-
|
63
|
-
|
64
|
-
send action
|
65
|
-
else
|
66
|
-
warn self.class.name + " - shortcut #{shortcut[:parts].join('+')}:#{action} is not implemented!"
|
67
|
-
end
|
67
|
+
return instance_exec(&shortcut[:block]) if shortcut[:block]
|
68
|
+
return send(action) if respond_to? action
|
69
|
+
warn self.class.name + " - shortcut #{shortcut[:parts].join('+')}:#{action} is not implemented!"
|
68
70
|
end
|
69
71
|
end
|
70
72
|
end
|
data/opal/fron/utils/point.rb
CHANGED
@@ -1,6 +1,3 @@
|
|
1
|
-
# rubocop:disable VariableName
|
2
|
-
require 'math'
|
3
|
-
|
4
1
|
module Fron
|
5
2
|
# Simple class for point with x and y coordinates.
|
6
3
|
class Point
|
@@ -21,7 +18,8 @@ module Fron
|
|
21
18
|
# @param x [Float] The x coordiante
|
22
19
|
# @param y [Float] The y coordiante
|
23
20
|
def initialize(x = 0, y = 0)
|
24
|
-
@x
|
21
|
+
@x = x
|
22
|
+
@y = y
|
25
23
|
end
|
26
24
|
|
27
25
|
# Returns the difference from an other point.
|
@@ -74,5 +72,15 @@ module Fron
|
|
74
72
|
def to_s
|
75
73
|
"[#{x}, #{y}]"
|
76
74
|
end
|
75
|
+
|
76
|
+
def clamp(width, height)
|
77
|
+
@x = @x.clamp(0, width)
|
78
|
+
@y = @y.clamp(0, height)
|
79
|
+
self
|
80
|
+
end
|
81
|
+
|
82
|
+
def to_h
|
83
|
+
{ x: x, y: y }
|
84
|
+
end
|
77
85
|
end
|
78
86
|
end
|
@@ -6,10 +6,11 @@ module Fron
|
|
6
6
|
#
|
7
7
|
# @param method [Method] The method
|
8
8
|
# @param verbose [Boolean] Whether or not to log render time
|
9
|
-
def initialize(method, verbose)
|
9
|
+
def initialize(method, verbose, message)
|
10
10
|
@running = false
|
11
11
|
@method = method
|
12
12
|
@verbose = verbose
|
13
|
+
@message = message
|
13
14
|
end
|
14
15
|
|
15
16
|
# Runs the proc
|
@@ -19,7 +20,10 @@ module Fron
|
|
19
20
|
request_animation_frame do
|
20
21
|
time = Time.now
|
21
22
|
@method.call
|
22
|
-
|
23
|
+
if @verbose
|
24
|
+
message = @message || "Rendered #{@method.owner}"
|
25
|
+
logger.info "[#{(Time.now - time) * 1000}ms] #{message}"
|
26
|
+
end
|
23
27
|
@running = false
|
24
28
|
end
|
25
29
|
end
|
data/spec/core-ext/array_spec.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Array do
|
4
|
-
subject { %w(a b) }
|
4
|
+
subject { %w(a b a) }
|
5
5
|
|
6
6
|
describe '#reverse_each_with_index' do
|
7
7
|
it 'should run in reverse' do
|
@@ -9,7 +9,15 @@ describe Array do
|
|
9
9
|
subject.reverse_each_with_index do |item, index|
|
10
10
|
array << [item, index]
|
11
11
|
end
|
12
|
-
array.should eq [['b', 1], ['a', 0]]
|
12
|
+
array.should eq [['a', 2], ['b', 1], ['a', 0]]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '#sort_by!' do
|
17
|
+
it 'should sort the array in place' do
|
18
|
+
result = subject.sort_by! { |item| item }
|
19
|
+
result.should eq subject
|
20
|
+
subject.should eq %w(a a b)
|
13
21
|
end
|
14
22
|
end
|
15
23
|
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
# Test Component
|
4
|
+
class StyleTest < Fron::Component
|
5
|
+
tag 'style-test'
|
6
|
+
|
7
|
+
stylesheet 'http://test.com/index.css'
|
8
|
+
|
9
|
+
keyframes 'test', from: { color: :red },
|
10
|
+
to: { color: :blue }
|
11
|
+
|
12
|
+
style background: :red,
|
13
|
+
img: {
|
14
|
+
width: 200.px
|
15
|
+
},
|
16
|
+
'&:hover' => {
|
17
|
+
color: :blue
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
describe StyleTest do
|
22
|
+
let(:style) { Fron::Sheet.render }
|
23
|
+
|
24
|
+
before do
|
25
|
+
subject
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should create style tag' do
|
29
|
+
style.should_not be_nil
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should set css for component' do
|
33
|
+
style.should match('style-test')
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should set css for sub rulest' do
|
37
|
+
style.should match('style-test img')
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should set css for hover' do
|
41
|
+
style.should match('style-test:hover')
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should create keyframes rule' do
|
45
|
+
style.should match('@keyframes test')
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should create styleheet link tag' do
|
49
|
+
style.should match('test.com')
|
50
|
+
end
|
51
|
+
end
|
@@ -26,28 +26,23 @@ end
|
|
26
26
|
describe SuperComponent do
|
27
27
|
subject { described_class }
|
28
28
|
|
29
|
-
let(:
|
29
|
+
let(:registry) { subject.instance_variable_get('@registry') }
|
30
30
|
|
31
|
-
it 'should inherit
|
32
|
-
|
33
|
-
|
34
|
-
|
31
|
+
it 'should inherit registry in order' do
|
32
|
+
registry.should_not be nil
|
33
|
+
registry[0][:args].should eq [:text, 'text']
|
34
|
+
registry[2][:args].should eq [:title, 'title']
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
38
|
describe InheritedComponent do
|
39
39
|
subject { described_class }
|
40
40
|
|
41
|
-
let(:
|
42
|
-
let(:events) { subject.instance_variable_get('@on') }
|
41
|
+
let(:registry) { subject.instance_variable_get('@registry') }
|
43
42
|
|
44
|
-
it 'should inherit
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
it 'should inherit events' do
|
50
|
-
events.should_not be nil
|
51
|
-
events[0].should eq [:click, :render]
|
43
|
+
it 'should inherit registry' do
|
44
|
+
registry.should_not be nil
|
45
|
+
registry[0][:args].should eq [:text, 'text']
|
46
|
+
registry[1][:args].should eq [:click, :render]
|
52
47
|
end
|
53
48
|
end
|
data/spec/core/component_spec.rb
CHANGED
@@ -10,11 +10,10 @@ class TestComponent < Fron::Component
|
|
10
10
|
end
|
11
11
|
|
12
12
|
describe Fron::Component do
|
13
|
-
subject
|
13
|
+
subject { TestComponent.new }
|
14
14
|
|
15
15
|
let(:listeners) { subject.instance_variable_get '@listeners' }
|
16
|
-
let(:
|
17
|
-
let(:events) { subject.instance_variable_get('@on') }
|
16
|
+
let(:registry) { subject.instance_variable_get('@registry') }
|
18
17
|
|
19
18
|
describe 'DSL' do
|
20
19
|
subject { TestComponent }
|
@@ -34,22 +33,18 @@ describe Fron::Component do
|
|
34
33
|
end
|
35
34
|
|
36
35
|
describe '#on' do
|
37
|
-
it 'should
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
it 'should push event into the events array' do
|
43
|
-
subject.on :click, :test
|
44
|
-
events.length.should be 2
|
36
|
+
it 'should add to registry' do
|
37
|
+
expect {
|
38
|
+
subject.on :click, :test
|
39
|
+
}.to change { registry.count }.by 1
|
45
40
|
end
|
46
41
|
end
|
47
42
|
|
48
43
|
describe '#component' do
|
49
44
|
it 'should create components array' do
|
50
|
-
|
51
|
-
|
52
|
-
|
45
|
+
expect {
|
46
|
+
subject.component :test, 'test'
|
47
|
+
}.to change { registry.count }.by 1
|
53
48
|
end
|
54
49
|
|
55
50
|
it 'should create attr_reader for component' do
|
@@ -65,7 +60,7 @@ describe Fron::Component do
|
|
65
60
|
end
|
66
61
|
|
67
62
|
it 'should apply events' do
|
68
|
-
listeners[:click].length.should eq
|
63
|
+
listeners[:click].length.should eq 1
|
69
64
|
end
|
70
65
|
|
71
66
|
it 'should create components' do
|