fie 0.3.0 → 0.3.1

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.
@@ -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