fie 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,24 +0,0 @@
1
- require 'opal/base'
2
- require 'opal/mini'
3
-
4
- require 'corelib/io'
5
- require 'corelib/dir'
6
- require 'corelib/file'
7
-
8
- require 'corelib/unsupported'
9
-
10
- module Fie
11
- require_tree './fie'
12
-
13
- include Fie::Native
14
-
15
- DiffSetup.run
16
-
17
- Element.document.add_event_listener('DOMContentLoaded') do
18
- cable = Cable.new
19
-
20
- ExposeMethods.run
21
-
22
- Listeners.new(cable)
23
- end
24
- end
@@ -1,63 +0,0 @@
1
- require 'securerandom'
2
- require 'fie/native'
3
- require 'json'
4
-
5
- module Fie
6
- class Cable
7
- include Fie::Native
8
-
9
- def initialize
10
- connection_uuid = SecureRandom.uuid
11
- commander_name = "#{ camelize(controller_name) }Commander"
12
-
13
- @commander = Commander.new(channel_name: commander_name, identifier: connection_uuid, cable: self)
14
- @pools = {}
15
- end
16
-
17
- def call_remote_function(element:, event_name:, function_name:, parameters:)
18
- log_event(element: element, event_name: event_name, function_name: function_name, parameters: parameters)
19
-
20
- function_parameters = {
21
- caller: {
22
- id: element.id,
23
- class: element.class_name,
24
- value: element.value
25
- },
26
- controller_name: controller_name,
27
- action_name: action_name
28
- }.merge(parameters)
29
-
30
- @commander.perform(function_name, function_parameters)
31
- end
32
-
33
- def subscribe_to_pool(subject)
34
- @pools[subject] = Pool.new(channel_name: 'Fie::Pools', identifier: subject, cable: self)
35
- end
36
-
37
- def commander
38
- @commander
39
- end
40
-
41
- private
42
- def log_event(element:, event_name:, function_name:, parameters:)
43
- parameters = parameters.to_json
44
- puts "Event #{ event_name } triggered by element #{ element.descriptor } is calling function #{ function_name } with parameters #{ parameters }"
45
- end
46
-
47
- def action_name
48
- view_name_element['fie-action']
49
- end
50
-
51
- def controller_name
52
- view_name_element['fie-controller']
53
- end
54
-
55
- def view_name_element
56
- Element.body.query_selector('[fie-controller]:not([fie-controller=""])');
57
- end
58
-
59
- def camelize(string)
60
- string.split('_').collect(&:capitalize).join
61
- end
62
- end
63
- end
@@ -1,50 +0,0 @@
1
- require 'fie/native'
2
- require 'diffhtml/dist/diffhtml.min'
3
-
4
- module Fie
5
- class Commander < Fie::Native::ActionCableChannel
6
- include Fie::Native
7
-
8
- def connected
9
- super
10
-
11
- @cable.call_remote_function \
12
- element: Element.body,
13
- function_name: 'initialize_state',
14
- event_name: 'Upload State',
15
- parameters: { view_variables: Util.view_variables }
16
- end
17
-
18
- def received(data)
19
- process_command(data['command'], data['parameters'])
20
- end
21
-
22
- def process_command(command, parameters = {})
23
- case command
24
- when 'refresh_view'
25
- $$.diff.innerHTML Element.fie_body.unwrapped_element, parameters['html']
26
- @event.dispatch
27
- when 'subscribe_to_pools'
28
- parameters['subjects'].each do |subject|
29
- @cable.subscribe_to_pool(subject)
30
- end
31
- when 'publish_to_pool'
32
- subject = parameters['subject']
33
- object = parameters['object']
34
- sender_uuid = parameters['sender_uuid']
35
-
36
- perform("pool_#{ subject }_callback", { object: object, sender_uuid: sender_uuid })
37
- when 'publish_to_pool_lazy'
38
- subject = parameters['subject']
39
- object = parameters['object']
40
- sender_uuid = parameters['sender_uuid']
41
-
42
- perform("pool_#{ subject }_callback", { object: object, sender_uuid: sender_uuid, lazy: true })
43
- when 'execute_function'
44
- Util.exec_js(parameters['name'], parameters['arguments'])
45
- else
46
- puts "Command: #{ command }, Parameters: #{ parameters }"
47
- end
48
- end
49
- end
50
- end
@@ -1,31 +0,0 @@
1
- require 'es6-object-assign/dist/object-assign.min'
2
-
3
- class DiffSetup
4
- class << self
5
- include Fie::Native
6
-
7
- def run
8
- $$.ObjectAssign.polyfill()
9
-
10
- Native \
11
- `diff.use(
12
- Object.assign(_ => {}, {
13
- syncTreeHook: (oldTree, newTree) => {
14
- if (newTree.nodeName === 'input') {
15
- let oldElement = document.querySelector('[name="' + newTree.attributes.name + '"]');
16
-
17
- if (oldElement != undefined && oldElement.attributes['fie-ignore'] != undefined) {
18
- newTree.nodeValue = oldElement.value;
19
- newTree.attributes.value = oldElement.value;
20
- newTree.attributes.autofocus = '';
21
- newTree.attributes['fie-ignore'] = oldElement.attributes['fie-ignore'];
22
- }
23
-
24
- return newTree;
25
- }
26
- }
27
- })
28
- )`
29
- end
30
- end
31
- end
@@ -1,27 +0,0 @@
1
- class ExposeMethods
2
- class << self
3
- def run
4
- Native(`window.Fie = {}`)
5
-
6
- Native \
7
- `window.Fie.executeCommanderMethod =
8
- #{
9
- -> (function_name, parameters = {}) do
10
- cable.call_remote_function \
11
- element: Element.body,
12
- event_name: 'calling remote function',
13
- function_name: function_name,
14
- parameters: Hash.new(parameters)
15
- end
16
- }`
17
-
18
- Native \
19
- `window.Fie.addEventListener =
20
- #{
21
- -> (event_name, selector, block) do
22
- Element.fie_body.add_event_listener(event_name, selector, &block)
23
- end
24
- }`
25
- end
26
- end
27
- end
@@ -1,129 +0,0 @@
1
- require 'fie/native'
2
- require 'securerandom'
3
-
4
- module Fie
5
- class Listeners
6
- include Fie::Native
7
-
8
- def initialize(cable)
9
- @cable = cable
10
- @timer = Timeout.new(0) { 'hello' }
11
-
12
- initialize_input_elements
13
- initialize_fie_events [:click, :submit, :scroll, :keyup, :keydown, :enter]
14
- end
15
-
16
- private
17
- def initialize_fie_events(event_names)
18
- event_names.each do |fie_event_name|
19
- selector = "[fie-#{ fie_event_name }]:not([fie-#{ fie_event_name }=''])"
20
-
21
- event_name = fie_event_name
22
- event_name = :keydown if event_name == :enter
23
-
24
- Element.fie_body.add_event_listener(event_name, selector) do |event|
25
- handle_fie_event(fie_event_name, event_name, event)
26
- end
27
- end
28
- end
29
-
30
- def handle_fie_event(fie_event_name, event_name, event)
31
- event_is_valid = (fie_event_name == :enter && event.keyCode == 13) || fie_event_name != :enter
32
-
33
- if event_is_valid
34
- element = Element.new(element: event.target)
35
- remote_function_name = element["fie-#{ fie_event_name }"]
36
- function_parameters = JSON.parse(element['fie-parameters'] || {})
37
-
38
- @timer.fast_forward
39
-
40
- @cable.call_remote_function \
41
- element: element,
42
- function_name: remote_function_name,
43
- event_name: event_name,
44
- parameters: function_parameters
45
- end
46
- end
47
-
48
- def initialize_input_elements
49
- typing_input_types = ['text', 'password', 'search', 'tel', 'url']
50
-
51
- typing_input_selector = (['textarea'] + typing_input_types).reduce do |selector, input_type|
52
- selector += ", input[type=#{ input_type }]"
53
- end
54
-
55
- non_typing_input_selector = (['input'] + typing_input_types).reduce do |selector, input_type|
56
- selector += ":not([type=#{ input_type }])"
57
- end
58
-
59
- Element.fie_body.add_event_listener('keydown', typing_input_selector) do |event|
60
- if event.keyCode == 13
61
- event.target.blur
62
- else
63
- @timer.clear
64
-
65
- input_element = Element.new(element: event.target)
66
-
67
- @timer = Timeout.new(300) do
68
- update_state_using_changelog(input_element)
69
- end
70
- end
71
- end
72
-
73
- Element.fie_body.add_event_listener('focusin', typing_input_selector) do |event|
74
- event.target.setAttribute('fie-ignore', SecureRandom.uuid)
75
- end
76
-
77
- Element.fie_body.add_event_listener('focusout', typing_input_selector) do |event|
78
- event.target.removeAttribute('fie-ignore')
79
- end
80
-
81
- Element.fie_body.add_event_listener('change', non_typing_input_selector) do |event|
82
- input_element = Element.new(element: event.target)
83
- update_state_using_changelog(input_element)
84
- end
85
- end
86
-
87
- def update_state_using_changelog(input_element)
88
- objects_changelog = {}
89
-
90
- changed_object_name = input_element.name.split('[')[0]
91
- changed_object_key_chain = input_element.name.scan(Regexp.new '\[(.*?)\]').flatten
92
-
93
- is_form_object = !changed_object_key_chain.empty? && !changed_object_name.nil?
94
- is_fie_nested_object = Util.view_variables.include? changed_object_name
95
- is_fie_form_object = is_form_object && is_fie_nested_object
96
-
97
- is_fie_non_nested_object = Util.view_variables.include? input_element.name
98
-
99
- if is_fie_form_object
100
- build_changelog(changed_object_key_chain, changed_object_name, objects_changelog, input_element)
101
- elsif is_fie_non_nested_object
102
- objects_changelog[input_element.name] = input_element.value;
103
- end
104
-
105
- @cable.call_remote_function \
106
- element: input_element,
107
- function_name: 'modify_state_using_changelog',
108
- event_name: 'Input Element Change',
109
- parameters: { objects_changelog: objects_changelog }
110
- end
111
-
112
- def build_changelog(object_key_chain, object_name, changelog, input_element)
113
- is_final_key = -> (key) { key == object_key_chain[-1] }
114
- object_final_key_value = input_element.value
115
-
116
- changelog[object_name] = {}
117
- changelog = changelog[object_name]
118
-
119
- object_key_chain.each do |key|
120
- if is_final_key.call(key)
121
- changelog[key] = object_final_key_value
122
- else
123
- changelog[key] = {}
124
- changelog = changelog[key]
125
- end
126
- end
127
- end
128
- end
129
- end
@@ -1,5 +0,0 @@
1
- module Fie
2
- module Native
3
- require_tree './native'
4
- end
5
- end
@@ -1,35 +0,0 @@
1
- require 'fie/native'
2
-
3
- module Fie
4
- module Native
5
- class ActionCableChannel
6
- def initialize(channel_name:, identifier:, cable:)
7
- @channel_name = channel_name
8
- @identifier = identifier
9
- @cable = cable
10
- @event = Event.new('fieChanged')
11
-
12
- @subscription = $$.App.cable.subscriptions.create(
13
- { channel: @channel_name, identifier: @identifier },
14
- {
15
- connected: -> { connected },
16
- received: -> (data) { received Native(`#{data}`) }
17
- }
18
- )
19
- end
20
-
21
- def responds_to?(t)
22
- true
23
- end
24
-
25
- def connected
26
- perform('initialize_pools')
27
- puts "Connected to #{ @channel_name } with identifier #{ @identifier }"
28
- end
29
-
30
- def perform(function_name, parameters = {})
31
- @subscription.perform(function_name, parameters);
32
- end
33
- end
34
- end
35
- end
@@ -1,116 +0,0 @@
1
- require 'native'
2
-
3
- module Fie
4
- module Native
5
- class Element
6
- include Native
7
-
8
- def initialize(element: nil, selector: nil)
9
- if selector.nil?
10
- @element = element
11
- elsif element.nil?
12
- if selector == 'document'
13
- @element = $$.document
14
- else
15
- @element = $$.document.querySelector(selector)
16
- end
17
- end
18
- end
19
-
20
- def [](name)
21
- @element.getAttribute(name)
22
- end
23
-
24
- def []=(name, value)
25
- @element.setAttribute(name, value)
26
- end
27
-
28
- def add_event_listener(event_name, selector = nil, &block)
29
- @element.addEventListener(event_name) do |event|
30
- event = Native(`#{ event }`)
31
-
32
- if selector.nil?
33
- yield event
34
- else
35
- if event.target.matches(selector)
36
- yield event
37
- end
38
- end
39
- end
40
- end
41
-
42
- def innerHTML
43
- @element.innerHTML
44
- end
45
-
46
- def query_selector(selector)
47
- Element.new(element: @element.querySelector(selector))
48
- end
49
-
50
- def query_selector_all(selector)
51
- entries = Native(`Array.prototype.slice.call(document.querySelectorAll(#{ selector }))`)
52
-
53
- entries.map do |element|
54
- Element.new(element: element)
55
- end
56
- end
57
-
58
- def name
59
- @element.name
60
- end
61
-
62
- def id
63
- @element.id
64
- end
65
-
66
- def class_name
67
- @element.className
68
- end
69
-
70
- def descriptor
71
- descriptor = @element.tagName
72
-
73
- id_is_blank =
74
- id.nil? || id == ''
75
-
76
- class_name_is_blank =
77
- class_name.nil? || class_name == ''
78
-
79
- if !id_is_blank
80
- descriptor + "##{ id }"
81
- elsif !class_name_is_blank
82
- descriptor + ".#{ class_name }"
83
- else
84
- descriptor
85
- end
86
- end
87
-
88
- def value
89
- @element.value
90
- end
91
-
92
- def unwrapped_element
93
- @element
94
- end
95
-
96
- private
97
- def node_list_to_array(node_list)
98
- $$.Array.prototype.slice.call(node_list)
99
- end
100
-
101
- class << self
102
- def document
103
- Element.new(selector: 'document')
104
- end
105
-
106
- def body
107
- Element.new(selector: 'body')
108
- end
109
-
110
- def fie_body
111
- Element.new(selector: '[fie-body=true]')
112
- end
113
- end
114
- end
115
- end
116
- end