Class: Atome

Inherits:
Object show all
Includes:
Essentials, Molecule
Defined in:
lib/atome/atome.rb,
lib/atome/version.rb,
lib/molecules/init.rb,
lib/renderers/renderer.rb,
lib/atome/presets/atome.rb,
lib/atome/extensions/sha.rb,
lib/atome/extensions/ping.rb,
lib/atome/utilities/security.rb,
lib/atome/utilities/sanitizer.rb,
lib/atome/utilities/utilities.rb,
lib/molecules/intuition/tools.rb,
lib/renderers/html/atome_html.rb,
lib/renderers/headless/headless.rb,
lib/atome/extensions/geolocation.rb,
lib/atome/extensions/mathematics.rb,
lib/atome/genesis/particles/event.rb,
lib/molecules/intuition/utilities.rb,
lib/platform_specific/opal/extensions/ping.rb,
lib/platform_specific/opal/extensions/color.rb,
lib/platform_specific/opal/extensions/geolocation.rb

Overview

rgb utility

Constant Summary collapse

VERSION =
'0.5.7.6.0'

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Essentials

#add_essential_drm, default_params, new_default_params, #validation

Constructor Details

#initialize(new_atome = {}, &atomes_proc) ⇒ Atome

dummy method to catch a method get all instance variable and try to call a method but initialized is only an instance variable not a method FIXME : replace all



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/atome/atome.rb', line 19

def initialize(new_atome = {}, &atomes_proc)
  # TODO: atome format should always be as followed : {value: 0.44, unit: :px, opt1: 554}
  # the keys :renderers, :type and :id should be placed in the first position in the hash
  @history = {}
  @tag = {}
  @tick = {}
  @storage = {}
  @behavior = {}
  @selected = false
  @unit = {}
  @apply = []
  @collect = {}
  @int8 = {}
  @css = {}
  @code = {}
  @aid = new_atome[:aid] || identity_generator
  @controller_proc = []
  @id = new_atome[:id] || @aid
  Universe.atomes.each_value do |atome_f|
    # we affect the already existing atome to target
    next unless atome_f.id == @id

    new_atome[:affect].each do |affected|
      grab(affected).apply(@id)
    end if new_atome[:affect]
    return false
  end
  Universe.add_to_atomes(@aid, self)
  Universe.id_to_aid(@id, @aid)
  @type = new_atome[:type] || :element
  @fasten = []
  @affect = []
  @category = []
  @html = HTML.new(@id, self)
  @headless = Headless.new(@id, self)
  @initialized = {}
  @creator = Universe.current_user
  # now we store the proc in a an atome's property called :bloc
  new_atome[:code] = atomes_proc if atomes_proc
  # we reorder the hash
  reordered_atome = reorder_particles(new_atome)
  # FIXME : try to remove the condition below (it crash in the method :  def generator ... in genesis.rb)
  collapse(reordered_atome)
end

Class Attribute Details

.initializedObject

Returns the value of attribute initialized.



10
11
12
# File 'lib/atome/utilities/utilities.rb', line 10

def initialized
  @initialized
end

Instance Attribute Details

#controller_procObject

controller_proc is used to stack multiple procs from native controller



9
10
11
# File 'lib/atome/atome.rb', line 9

def controller_proc
  @controller_proc
end

Class Method Details

.activate_click_analysisObject



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/molecules/intuition/tools.rb', line 49

def activate_click_analysis
  # the condition below avoid touchdown analysis accumulation
  unless @click_analysis_active
    # this method analyse all object under the touchdown to find the first user object and return it's id
    @click_analysis = lambda { |native_event|
      # the instance variable below check if we can apply tool (cf:  if the atome we don't want to apply tool)
      if Universe.allow_tool_operations
        event = Native(native_event)
        x = event[:clientX]
        y = event[:clientY]
        elements = JS.global[:document].elementsFromPoint(x, y)
        elements.to_a.each do |atome_touched|
          id_found = atome_touched[:id]
          id_found = id_found.to_s.to_sym # keep .to_s to because ruby wasm try may to_sym on on symbol
          atome_found = grab(id_found)

          is_descendant_of_intuition = atome_found.descendant_of?(:intuition).to_s if atome_found
          # the condition below is use to exclude the treatment any object in the intuition layer
          unless is_descendant_of_intuition == 'true'

            Universe.active_tools.each do |tool|
              apply_tool(tool, atome_found, event)
            end
          end
          break
        end
      else
        Universe.allow_tool_operations = true
      end
    }
    @click_analysis_active = true
  end

end

.alteration(current_tool, tool_actions, atome_touched, a_event) ⇒ Object



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/molecules/intuition/tools.rb', line 128

def alteration(current_tool, tool_actions, atome_touched, a_event)
  if atome_touched
    storage_allowed = Universe.allow_localstorage
    action_found = tool_actions[:action]
    post = tool_actions[:post]
    params = { current_tool: current_tool, atome_touched: atome_touched, event: a_event }
    action_found.each do |part, val|
      Universe.allow_localstorage = false
      Universe.allow_localstorage = storage_allowed
      if current_tool.data[:allow_alteration]
        if val.instance_of?(Proc)
          atome_touched.instance_exec(&val)
        else
          atome_touched.send(part, val)
        end
        current_tool.data[:treated] << atome_touched if current_tool.data[:treated]
      end
      current_tool.instance_exec(params, &post) if post.is_a? Proc
    end

  end
end

.apply_tool(tool, atome_touched, a_event) ⇒ Object



183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
# File 'lib/molecules/intuition/tools.rb', line 183

def apply_tool(tool, atome_touched, a_event)
  current_tool = grab(tool)
  tool_actions = current_tool.data
  method_found = tool_actions[:method]
  unless method_found
    method_found = :alteration
    tool_actions[:action] = { noop: true }
    current_tool.data = tool_actions
  end
  tool_name = tool.to_s.sub('_tool', '')
  tools_scheme = Universe.tools[tool_name.to_sym]

  target = if tools_scheme[:target]
             grab(atome_touched.send(tools_scheme[:target]).last)
           else
             atome_touched
           end
  if target && method_found == :alteration && target.tag[:system]
    # in this case (on target touch )we are targeting a system object non alterable so we create an a new atome
    # Ex: if we are on a system color we create a new color that can be altered
    tools_scheme[:particles]&.each do |particle_f, value_f|
      type_to_create = target.type
      if type_to_create
        target = atome_touched.send(type_to_create, { particle_f => value_f })
        tools_scheme[:particles]&.each do |particle_f, value_f|
          target.send(particle_f, value_f)
        end
      end
    end
  else

    # below code trigger when activating the current tool :
    tools_scheme[:particles]&.each do |particle_f, value_f|
      is_descendant_of_intuition = target.descendant_of?(:intuition).to_s
      atome_descendant_of_intuition = atome_touched.descendant_of?(:intuition).to_s
      # the condition below is use to exclude the treatment any object in the intuition layer
      unless is_descendant_of_intuition == 'true' || atome_descendant_of_intuition == 'true'
        target.send(particle_f, value_f)
      end
    end
    send(method_found, current_tool, tool_actions, target, a_event)
  end

end

.controller_listenerObject



97
98
99
100
# File 'lib/atome/utilities/utilities.rb', line 97

def controller_listener
  return if $host == :html
  atome_js.JS.controller_listener() # js folder atome/helipers/atome/communication
end

.controller_sender(message) ⇒ Object



34
35
36
37
38
39
40
41
# File 'lib/atome/utilities/utilities.rb', line 34

def controller_sender(message)
  return if $host == :html

  json_msg = message.to_json
  js_json_msg = json_msg.inspect
  js_command = "atomeJS.controller_sender(#{js_json_msg})"
  JS.eval(js_command)
end

.creation(current_tool, tool_actions, atome_touched, a_event) ⇒ Object



151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
# File 'lib/molecules/intuition/tools.rb', line 151

def creation(current_tool, tool_actions, atome_touched, a_event)
  @creation_mode = true
  storage_allowed = Universe.allow_localstorage
  Universe.allow_localstorage = false
  action_found = tool_actions[:action]
  pre = tool_actions[:pre]
  post = tool_actions[:post]
  params = { current_tool: current_tool, atome_touched: atome_touched, event: a_event }

  action_found.each do |atome, particle|
    current_tool.instance_exec(params, &pre) if pre.is_a? Proc
    temp_val = particle.merge({ resize: true, drag: true, top: a_event[:pageY].to_i, left: a_event[:pageX].to_i })
    if current_tool.data[:allow_creation]
      # uncomment the line below if you want to attach to current atome
      new_atome = if atome_touched
                    atome_touched.send(atome, temp_val)
                  else
                    grab(:view).send(atome, temp_val)
                  end
      current_tool.data[:created] << new_atome
      params.delete(:atome_touched)
      params[new_atome: new_atome]
      Universe.allow_localstorage = [atome]
      Universe.historicize(new_atome.aid, :write, atome, particle)
    end

  end
  current_tool.instance_exec(params, &post) if post.is_a? Proc
  # we restore prev_local_storage to allow logs of drag and resize ...
  Universe.allow_localstorage = storage_allowed
end

.de_activate_click_analysisObject



84
85
86
87
# File 'lib/molecules/intuition/tools.rb', line 84

def de_activate_click_analysis
  @click_analysis = nil
  @click_analysis_active = false
end

.file_handler(parent, content, bloc) ⇒ Object



30
31
32
# File 'lib/atome/utilities/utilities.rb', line 30

def file_handler(parent, content, bloc)
  grab(parent).instance_exec(content, &bloc)
end

.handleSVGContent(svg_content, target) ⇒ Object



102
103
104
105
106
107
# File 'lib/atome/utilities/utilities.rb', line 102

def handleSVGContent(svg_content, target)
  puts svg_content
  atome_content = A.vectorizer(svg_content)
  target_vector = grab(target)
  target_vector.data(atome_content)
end

.init_intuitionObject



36
37
38
39
40
41
42
43
# File 'lib/molecules/intuition/tools.rb', line 36

def init_intuition
  Atome.start_click_analysis
  toolbox_root = Universe.tools_root
  toolbox_root[:tools].each_with_index do |root_tool, index|
    tools_scheme = Universe.tools[root_tool]
    A.build_tool({ name: root_tool, scheme: tools_scheme, index: index, toolbox: toolbox_root[:toolbox] })
  end
end

.monitoring(atomes_to_monitor, particles_to_monitor, &bloc) ⇒ Object

monitoring system



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/atome/utilities/utilities.rb', line 64

def monitoring(atomes_to_monitor, particles_to_monitor, &bloc)
  atomes_to_monitor.each do |atome_to_monitor|
    particles_to_monitor.each do |monitored_particle|
      # Store original method
      original_method = atome_to_monitor.method(monitored_particle)

      # redefine method
      atome_to_monitor.define_singleton_method(monitored_particle) do |*args, &proc|

        # Monitor before calling original method
        value_before = atome_to_monitor.instance_variable_get("@#{monitored_particle}")
        if args.empty?
          args = nil
        else
          if monitored_particle == :touch
            instance_variable_set("@#{monitored_particle}", { tap: args[0] })
            instance_variable_set("@#{monitored_particle}_code", { touch: proc })

            args = { tap: args[0] }
          else
            instance_variable_set("@#{monitored_particle}", args[0])
          end
          args = args[0]
        end
        if bloc.is_a?(Proc)
          instance_exec({ original: value_before, altered: args, particle: monitored_particle }, &bloc)
        end
        original_method.call(*args)
      end
    end
  end
end

.preset_builder(preset_name, &bloc) ⇒ Object

atome builder



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/atome/utilities/utilities.rb', line 44

def preset_builder(preset_name, &bloc)
  # Important : previously def box , def circle
  Universe.atome_preset << preset_name
  Object.define_method preset_name do |params = {}, &proc|
    grab(:view).send(preset_name, params, &proc)
  end
  define_method preset_name do |params|
    preset_to_add = instance_exec(params, &bloc) if bloc.is_a? Proc
    if Essentials.default_params[preset_name]
      Essentials.default_params[preset_name].merge(preset_to_add) if preset_to_add
    else
      Essentials.default_params[preset_name] = preset_to_add if preset_to_add
    end
    params = atome_common(preset_name, params)
    preset_common(params, &bloc)
  end

end

.sanitize_data_for_json(data) ⇒ Object



12
13
14
# File 'lib/atome/utilities/utilities.rb', line 12

def sanitize_data_for_json(data)
  data.gsub('"', '\\"')
end

.selectionObject



45
46
47
# File 'lib/molecules/intuition/tools.rb', line 45

def selection
  grab(Universe.current_user).selection.collect
end

.send_localstorage_contentObject



16
17
18
19
20
21
22
23
# File 'lib/atome/utilities/utilities.rb', line 16

def send_localstorage_content
  storage = JS.global[:localStorage]
  storage_array = storage.to_a
  storage_array.each_with_index do |_i, index|
    key = JS.global[:localStorage].key(index)
    sanitize_data_for_json(storage.getItem(key))
  end
end

.server_receiver(params) ⇒ Object



25
26
27
28
# File 'lib/atome/utilities/utilities.rb', line 25

def server_receiver(params)
  callback_found = Universe.messages[params[:message_id]]
  callback_found.call(params) if callback_found.is_a? Proc
end

.start_click_analysisObject



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/molecules/intuition/tools.rb', line 89

def start_click_analysis
  # here we capture any touch when using tool
  @click_analysis_active = false

  click_timeout = nil
  double_click_delay = 222

  JS.global[:document].addEventListener('click') do |native_event|
    if @click_analysis
      if click_timeout
        wait(:kill, click_timeout)
        click_timeout = nil
        selected_items = grab(Universe.current_user).selection.collect
        if  selected_items.length >  0
          dup_selected_items = selected_items.dup
          dup_selected_items.each do |atome_id_selected|
            atome_selected = grab(atome_id_selected)
            atome_selected.selected(false)
          end
        else
          atomes_in_view= grab(:view).fasten
          atomes_in_view.each do |atome_id_found|
            grab(atome_id_found).selected(true)
          end
          end


      else
        click_timeout = wait(double_click_delay / 1000.0) do
          click_timeout = nil # important do not remove !
          Atome.instance_exec(native_event, &@click_analysis) if @click_analysis.is_a?(Proc)
        end
      end
    end

  end

end

Instance Method Details

#*(other) ⇒ Object



9
10
11
# File 'lib/atome/extensions/mathematics.rb', line 9

def *(other)
  value * other
end

#+(other) ⇒ Object



17
18
19
# File 'lib/atome/extensions/mathematics.rb', line 17

def +(other)
  value + other
end

#-(other) ⇒ Object



13
14
15
# File 'lib/atome/extensions/mathematics.rb', line 13

def -(other)
  value - other
end

#/(other) ⇒ Object



5
6
7
# File 'lib/atome/extensions/mathematics.rb', line 5

def /(other)
  value / other
end

#<<(item) ⇒ Object



589
590
591
# File 'lib/atome/utilities/utilities.rb', line 589

def <<(item)
  collect << item
end

#activate_toolObject



242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
# File 'lib/molecules/intuition/tools.rb', line 242

def activate_tool
  tool_name = id
  tool_scheme = @tool_scheme
  tool = self

  alterations = tool_scheme[:alteration] ? tool_scheme[:alteration].keys : []
  creations = tool_scheme[:creation] ? tool_scheme[:creation].keys : []
  prev_auth = Universe.allow_localstorage ||= []
  events_allow = %i[top left right bottom width height]
  storage_allowed = events_allow.concat(alterations).concat(creations).concat(prev_auth).uniq

  Universe.allow_localstorage = storage_allowed
  # we set edit mode to true (this allow to prevent user atome to respond from click)

  Universe.edit_mode = true
  # init the tool
  tool.data[:treated] = []
  tool.data[:created] = []
  tool.data[:prev_states] = {}
  # generic behavior
  grab("#{tool_name}_icon").color(:white)
  grab("#{tool_name}_label").color(:white)
  Universe.active_tools << tool_name
  # activation code
  activation_code = tool_scheme[:activation]
  tool.instance_exec(&activation_code) if activation_code.is_a? Proc
  # below we the particles of selected atomes to feed tools values
  # possibility 1 (pipette like):
  # now we get the values from selected atomes
  Atome.selection.each do |atome_id_to_treat|
    tool.data[:action]&.each_key do |particle_req|
      unless Universe.atome_preset
        value_found = grab(atome_id_to_treat).send(particle_req)
        if value_found
          tool.data[:action][particle_req] = value_found
        else
        end
      end
    end
  end
  # possibility 2  (immediate apply):
  allow_creation = tool.data[:allow_creation]
  allow_alteration = tool.data[:allow_alteration]
  unless tool_name.to_sym == :select_tool || !allow_creation || !allow_alteration
    Atome.selection.each do |atome_id_to_treat|
      atome_found = grab(atome_id_to_treat)
      event = { pageX: 0, pageY: 0, clientX: 0, clientY: 0 }
      Atome.apply_tool(tool_name, atome_found, event)
    end
  end
  # activate tool analysis test
  Atome.activate_click_analysis
  tool.active(true)
end

#add_button(params) ⇒ Object



108
109
110
111
112
113
114
115
116
# File 'lib/molecules/intuition/utilities.rb', line 108

def add_button(params)
  params.each do |button_id, params|
    label = params[:text]
    code = params[:code]
    index = fasten.length
    create_new_button(button_id, index, label, code)
  end
  false
end

#add_text_visual(params) ⇒ Object



295
296
297
# File 'lib/atome/utilities/utilities.rb', line 295

def add_text_visual(params)
  html.add_font_to_css(params)
end

#aid(_v = nil) ⇒ Object



11
12
13
# File 'lib/atome/atome.rb', line 11

def aid(_v = nil)
  @aid
end

#alternate(*states) ⇒ Object



694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
# File 'lib/atome/utilities/utilities.rb', line 694

def alternate(*states)
  @alternate ||= { state: 0 }
  @alternate[:data] = states
  if @alternate[:state] < states.length - 1
    @alternate[:state] += 1
  else
    @alternate[:state] = 0
  end

  current_state = @alternate[:data][@alternate[:state] - 1]
  if current_state.instance_of?(Hash)
    current_state.each do |state, value|
      send(state, value)
    end
  end
  current_state
end

#animation_callback(proc_sub_category, value = nil) ⇒ Object



3
4
5
6
# File 'lib/atome/genesis/particles/event.rb', line 3

def animation_callback(proc_sub_category, value = nil)
  proc_found = @animate_code[proc_sub_category]
  instance_exec(value, &proc_found) if proc_found.is_a?(Proc)
end

#atomeObject



514
515
516
517
518
519
# File 'lib/atome/utilities/utilities.rb', line 514

def atome
  # allow to get all atomes instance variables available as a Hash
  instance_variables.each_with_object({}) do |var, hash|
    hash[var[1..-1].to_sym] = instance_variable_get(var) # var[1..-1] enlève le '@' au début
  end
end

#atome_common(atome_preset, params) ⇒ Object



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/atome/presets/atome.rb', line 10

def atome_common(atome_preset, params)

  basic_params = { renderers: [] }
  # TODO : remove Essentials.default_params[atome_preset] || {} as it is
  # applied twice because preset is now a particle
  preset_params = Essentials.default_params[atome_preset] || {}
  basic_params[:type] = preset_params[:type] || :element
  basic_params[:id] = params[:id] || identity_generator
  basic_params[:renderers] = @renderers || preset_params[:renderers]
  essential_params = basic_params.merge(preset_params)
  reordered_params = essential_params.reject { |key, _| params.has_key?(key) }
  params = reordered_params.merge(params)
  params[:id] = params[:id].to_sym
  # condition to handle color/shadow/paint atomes that shouldn't be attach to view
  if Universe.applicable_atomes.include?(atome_preset)
    unless params[:affect]
      params[:affect] = if @id == :view
                          [:black_matter]
                        else
                          [@id]
                        end
    end
  else
    params[:attach] = params[:attach] || @id || :view
  end
  # we reorder the hash
  reorder_particles(params)
end

#atome_post_process(element, params, new_atome, &user_proc) ⇒ Object



359
360
361
362
363
364
365
# File 'lib/atome/utilities/utilities.rb', line 359

def atome_post_process(element, params, new_atome, &user_proc)

  return unless Atome.instance_variable_get("@post_#{element}").is_a?(Proc)

  new_atome.instance_exec(params, user_proc, &Atome.instance_variable_get("@post_#{element}"))

end

#atome_pre_process(element, params, &user_proc) ⇒ Object



347
348
349
350
351
352
# File 'lib/atome/utilities/utilities.rb', line 347

def atome_pre_process(element, params, &user_proc)
  if Atome.instance_variable_get("@pre_#{element}").is_a?(Proc)
    params = instance_exec(params, self, user_proc, &Atome.instance_variable_get("@pre_#{element}"))
  end
  params
end

#atome_processor(element, params, &user_proc) ⇒ Object



367
368
369
370
371
372
373
374
375
376
377
378
379
# File 'lib/atome/utilities/utilities.rb', line 367

def atome_processor(element, params, &user_proc)
  # TODO: replace with the line below but need extensive testing as it crash some demos ex: animation
  params = atome_common(element, params)

  atome_pre_process(element, params, &user_proc)

  new_atome = send("set_#{element}", params, &user_proc) # it call  Atome.define_method "set_#{element}" in  new_atome method
  # TODO : check if we don't have a security issue allowing atome modification after creation
  # if we have one find another solution the keep this facility
  atome_post_process(element, params, new_atome, &user_proc)

  new_atome
end

#atome_sanitizer(element, params, &user_proc) ⇒ Object



354
355
356
357
# File 'lib/atome/utilities/utilities.rb', line 354

def atome_sanitizer(element, params, &user_proc)
  # Attention: the method is the same as the one used for the particle
  particle_sanitizer(element, params)
end

#authorise(autorisations) ⇒ Object



5
6
7
8
9
10
11
12
13
14
# File 'lib/atome/utilities/security.rb', line 5

def authorise(autorisations)
  autorisations[:read]&.each do |k, v|
    autorisations[:read][k] = Black_matter.encode(v)
  end
  autorisations[:write]&.each do |k, v|
    autorisations[:write][k] = Black_matter.encode(v)
  end

  @authorisations = autorisations
end

#b64_to_tag(params) ⇒ Object



797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
# File 'lib/atome/utilities/utilities.rb', line 797

def b64_to_tag(params)
  unless params[:target]
    new_img = image({ left: 0, top: 0 })
    params[:target] = new_img.id
  end
  new_tag = <<STRR
var serializer = new XMLSerializer();
var svg_string = serializer.serializeToString(document.getElementById('#{params[:id]}'));
var encoded_svg = btoa(unescape(encodeURIComponent(svg_string)));
var img = document.getElementById('#{params[:target]}');
img.src = "data:image/svg+xml;base64," + encoded_svg;
var parent = document.getElementById('#{id}');
parent.appendChild(img);
STRR
  JS.eval(new_tag)
  new_atome = grab(params[:target])
  html_obj = new_atome.html.object
  obj_src = html_obj[:src]
  new_atome.path(obj_src)
  new_atome
end

#block(params) ⇒ Object



176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
# File 'lib/atome/utilities/utilities.rb', line 176

def block(params)
  direction = params.delete(:direction) || :vertical
  spacing = params.delete(:spacing) || 3
  width_found = params.delete(:width) || '100%'
  height_found = params.delete(:height) || '100%'
  bloc_params = params.delete(:data) || {}

  last_id_found = grip(:block).last

  if last_id_found
    last_found = grab(last_id_found)
    case direction
    when :vertical
      box({ top: below(last_found, spacing), role: :block, width: width_found }.merge(params).merge(bloc_params))
    when :horizontal
      width_found = to_px(:width)
      block_left = after(last_found, spacing)
      left_in_percent = (block_left / width_found) * 100
      box({ left: "#{left_in_percent}%", role: :block, height: height_found }.merge(params).merge(bloc_params))
    else
      #
    end
  else
    case direction
    when :vertical
      box({ top: spacing, role: :block, width: width_found }.merge(params).merge(bloc_params))
    when :horizontal
      box({ left: spacing, role: :block, height: height_found }.merge(params).merge(bloc_params))
    else
      #
    end
  end

end

#blocks(params) ⇒ Object



211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
# File 'lib/atome/utilities/utilities.rb', line 211

def blocks(params)
  # alert 'blocks case'

  blocks = params.delete(:blocks)
  distribute = params.delete(:distribute)
  if distribute && params[:direction] == :horizontal
    width_found = to_px(:width)
    params[:spacing] = "#{found_spacing_in_percent(width_found, params[:width], blocks.length)}%"
  elsif distribute
    height_found = to_px(:height)
    params[:spacing] = found_spacing_in_percent(height_found, params[:height], blocks.length)
  end
  blocks.each do |bloc_id, block_to_create|
    sanitized_bloc_data = params.merge(block_to_create)
    block({ data: sanitized_bloc_data }.merge({ id: bloc_id }).merge(params))
  end
end

#build_tool(params) ⇒ Object



330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
# File 'lib/molecules/intuition/tools.rb', line 330

def build_tool(params)
  # here is the main entry for tool creation
  language ||= grab(:view).language

  label = params.dig(:scheme, :int8, language) || params[:name]
  tool_name = "#{params[:name]}_tool"
  index = params[:index]
  tool_scheme = params[:scheme]
  toolbox = params[:toolbox] || {}
  orientation_wanted = tool_scheme[:orientation] || :sn

  grab(:intuition).storage[:tool_open] ||= []
  grab(:intuition).storage[:tool_open] << tool_name
  size = grab(:toolbox_style).data[:size]
  margin = grab(:toolbox_style).data[:margin]
  smooth = grab(:toolbox_style).data[:smooth]
  text_color = grab(:toolbox_style).data[:text_color]
  case orientation_wanted
  when :sn
    top = :auto
    bottom_offset = toolbox[:bottom] || 3
    spacing = toolbox[:spacing] || 3
    bottom = index * (size + spacing) + bottom_offset
    left = toolbox[:left] || 3
    right = :auto
  when :ns
  when :ew
  when :we
  else
    #
  end

  # tool creation
  if tool_scheme[:creation]
    action = tool_scheme[:creation]
    method = :creation
  end
  if tool_scheme[:alteration]
    action = tool_scheme[:alteration]
    method = :alteration
  end

  tool = grab(:intuition).box({ id: tool_name,
                                tag: { system: true },
                                # orientation: orientation_wanted,
                                top: top,
                                bottom: bottom,
                                depth: 0,
                                left: left,
                                right: right,
                                width: size,
                                height: size,
                                smooth: smooth,
                                apply: %i[inactive_tool_col tool_box_border tool_shade],
                                state: :closed,
                                data: { method: method,
                                        action: action,
                                        allow_alteration: true,
                                        allow_creation: true,
                                        post: tool_scheme[:post],
                                        pre: tool_scheme[:pre],
                                }

                              })

  tool.instance_variable_set('@tool_scheme', tool_scheme)
  edition = 'M257.7 752c2 0 4-0.2 6-0.5L431.9 722c2-0.4 3.9-1.3 5.3-2.8l423.9-423.9c3.9-3.9 3.9-10.2 0-14.1L694.9 114.9c-1.9-1.9-4.4-2.9-7.1-2.9s-5.2 1-7.1 2.9L256.8 538.8c-1.5 1.5-2.4 3.3-2.8 5.3l-29.5 168.2c-1.9 11.1 1.5 21.9 9.4 29.8 6.6 6.4 14.9 9.9 23.8 9.9z m67.4-174.4L687.8 215l73.3 73.3-362.7 362.6-88.9 15.7 15.6-89zM880 836H144c-17.7 0-32 14.3-32 32v36c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-36c0-17.7-14.3-32-32-32z'
  icon = tool.vector({ tag: { system: true }, left: 9, top: :auto, bottom: 9, width: 18, height: 18, id: "#{tool_name}_icon",
                       data: { path: { d: edition, id: "p1_#{tool_name}_icon", stroke: :black, 'stroke-width' => 37, fill: :white } } })

  icon.color(text_color)

  tool.text({ tag: { system: true }, data: truncate_string(label, 5), component: { size: 9 }, center: { x: 0 }, top: :auto, bottom: 0,
              color: text_color, id: "#{tool_name}_label", width: size, position: :absolute })

  code_for_zone = tool_scheme[:zone]
  tool.instance_exec(tool, &code_for_zone) if code_for_zone.is_a? Proc
  tool.active(false)
  tool.touch(:long) do
    tool.instance_variable_set('@prevent_action', true)
    if tool.instance_variable_get('@tool_open') == true
      tool.instance_variable_set('@tool_open', false)
      tool_scheme[:particles]&.each_key do |particle|
          grab("tool_particle_#{particle}").delete({ force: true })
        end
      tool.width(size)
    else
      tool.instance_variable_set('@tool_open', true)

      tool_scheme[:particles]&.each_with_index do |(particle_name, _value_), ind|
        particle = tool.box({ id: "tool_particle_#{particle_name}", tag: { system: true }, depth: 1, smooth: smooth,
                              apply: %i[inactive_tool_col tool_box_border tool_shade],
                              width: size, height: size, left: ind * (size + margin) + size })
        particle_label = particle.text({
                                         id: "tool_particle_name_#{particle_name}",
                                         tag: { system: true },
                                         data: truncate_string(particle_name, 5),
                                         center: { x: 0 },
                                         position: :absolute,
                                         component: { size: 9 },
                                         color: text_color,
                                         top: :auto,
                                       }

        )
        label_value = particle.text({
                                      id: "tool_particle_value_#{particle_name}",
                                      data: 0.00,
                                      tag: { system: true },
                                      center: { x: 0 },
                                      position: :absolute,
                                      component: { size: 9 },
                                      color: text_color,
                                      top: margin,

                                    })
        particle_label.center({ x: 0 })
        particle_label.top(:auto)
        particle_label.bottom(0)
        particle.touch(true) do
          tool.instance_variable_set('@prevent_action', true)
          slider_id = "particle_slider_#{particle_name}"
          if particle.instance_variable_get('@active')
            grab(slider_id).delete({ force: true })
            particle.instance_variable_set('@active', false)
            particle.height(size)
            particle.top(0)
          else
            particle.height(139 + size / 2)
            particle.top(-139 + size)
            slider_id = "particle_slider_#{particle_name}"
            slider_f = particle.slider({ orientation: :vertical,
                                         id: slider_id,
                                         range: { color: { alpha: 0 } },
                                         value: 55,
                                         depth: 2,
                                         center: { x: 0 },
                                         width: 18, height: 123, smooth: 1,
                                         left: 0,
                                         top: size / 2,
                                         color: { alpha: 0 },
                                         cursor:
                                           { color: { alpha: 1, red: 0.9, green: 0.9, blue: 0.0 },
                                             width: 18, height: 12, smooth: 3 } }) do |value|
              # Slider actions below:
              if grab(slider_id).instance_variable_get('@initialised')
                Atome.selection.each do |atome_id_to_treat|


                  tool_scheme[:particles][particle_name] = value.to_f / 100
                  atome_found = grab(atome_id_to_treat)
                  target = grab(atome_found.color.last)
                  target.send(particle_name, value.to_f / 100) if tool.active

                end

                label_value.data(value.to_f / 100)
                tool_scheme[:particles][particle_name]=value.to_f / 100
              end
            end

            Atome.selection.each do |atome_id_to_treat|
              atome_found = grab(atome_id_to_treat)
              target = if tool_scheme[:target]
                         grab(atome_found.send(tool_scheme[:target]).last)
                       else
                         atome_found
                       end
              value_found = target.send(particle_name)
              slider_f.value(value_found * 100)
            end
            slider_f.instance_variable_set('@initialised', true)
            particle.instance_variable_set('@active', true)
          end

        end
      end
    end

  end
  tool.touch(:down) do
    tool.depth(999)
  end
  tool.touch(:double) do
    tool_to_deactivate = Universe.active_tools.dup
    tool_to_deactivate.each do |atome_id_found|
      atome_found = grab(atome_id_found)
      atome_found.deactivate_tool
    end
    tool.activate_tool
  end
  tool.touch(true) do
    unless tool.instance_variable_get('@prevent_action')
      # we add all specific tool actions to @tools_actions_to_exec hash
      # we set allow_tool_operations to false to ignore tool operation when clicking on a tool
      Universe.allow_tool_operations = false
      # we create the creation_layer if not already exist
      if tool.active == false # first click
        tool.activate_tool
      else
        tool.deactivate_tool
        tick[tool_name] = 0
      end
    end
    tool.instance_variable_set('@prevent_action', false)
  end
end

#calculate_sha(string) ⇒ Object



5
6
7
# File 'lib/atome/extensions/sha.rb', line 5

def calculate_sha(string)
  Digest::SHA256.hexdigest(string)
end

#callback(element, return_params = nil) ⇒ Object

this method generate the method accessible for end developers it’s the send the method define in “particle_callback”



490
491
492
# File 'lib/atome/utilities/utilities.rb', line 490

def callback(element, return_params = nil)
  send("#{element}_callback", return_params)
end

#check_password_destruction(operation, element) ⇒ Object



16
17
18
19
20
# File 'lib/atome/utilities/security.rb', line 16

def check_password_destruction(operation, element)
  return unless @authorisations[:destroy]

  @authorisations[operation].delete(element)
end

#collapse(new_atome) ⇒ Object



278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
# File 'lib/atome/utilities/utilities.rb', line 278

def collapse(new_atome)
  initialized_procs = []
  initialized = Atome.initialized
  new_atome.each do |element, value|
    send(element, value)
    initialized_proc = initialized[element]
    initialized_procs << { value => initialized_proc } if initialized_proc.is_a?(Proc)
  end

  initialized_procs.each do |value|
    value.each do |val, proc|
      instance_exec(val, &proc)
    end
  end

end

#create_new_button(button_id, position_in_menu, label, code) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/molecules/intuition/utilities.rb', line 41

def create_new_button(button_id, position_in_menu, label, code)
  essential_keys = [:inactive, :active]
  buttons_style = data.select { |key, _value| essential_keys.include?(key) }
  menu_item = box({ id: button_id })
  actor({ button_id => :button })
  menu_item.role(:button)
  menu_item.text({ data: label, id: "#{button_id}_label" })
  menu_item.code({ button_code: code })

  inactive_style = buttons_style[:inactive]
  active_style = buttons_style[:active]
  if active_style
    active_state_text = active_style[:text]
    keys_to_exclude = [:margin, :spacing, :disposition, :text]

    active_style = active_style.reject { |key, _| keys_to_exclude.include?(key) }
  end

  if inactive_style
    inactive_state_text = inactive_style[:text]
    margin = inactive_style[:margin]
    spacing = inactive_style[:spacing]
    disposition = inactive_style[:disposition]
    keys_to_exclude = [:margin, :spacing, :disposition, :text]
    inactive_style = inactive_style.reject { |key, _| keys_to_exclude.include?(key) }
    menu_item.set(inactive_style)

    # reorder_menu
    if disposition == :horizontal
      menu_item.left = margin[:left] + (inactive_style[:width] + spacing) * position_in_menu
      menu_item.top = margin[:top]
    else
      menu_item.top = margin[:top] + (inactive_style[:height] + spacing) * position_in_menu
      menu_item.left = margin[:left]
    end
    menu_item.text.each do |text_f|
      item_found = grab(text_f)
      item_found.set(inactive_state_text)
    end

  end

  menu_item.touch(:down) do
    unless @active_item == menu_item.id

      menu_item.text.each do |text_f|
        # below we unset any active style
        fasten.each do |item_id|
          unless button_id == item_id
            grab(item_id).remove({ all: :shadow })
            grab(item_id).set(inactive_style)
            grab("#{item_id}_label").remove({ all: :shadow })
            grab("#{item_id}_label").set(inactive_state_text)
          end
          grab(text_f).set(active_state_text)
        end

      end
      menu_item.set(active_style)
      code&.call
      @active_item = menu_item.id
    end

  end

end

#deactivate_toolObject



297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
# File 'lib/molecules/intuition/tools.rb', line 297

def deactivate_tool
  tool_name = id
  tool_scheme = @tool_scheme
  tool = self
  tool.active(false)
  tool.instance_variable_get('@toolbox')&.each do |sub_tool_id|
    toolbox_tool = grab("#{sub_tool_id}_tool")
    toolbox_tool.deactivate_tool
    # we delete the fasten toolbox if it exist
    toolbox_tool.delete({ force: true })
  end
  grab("#{tool_name}_icon").color(grab(:toolbox_style).data[:text_color])
  grab("#{tool_name}_label").color(grab(:toolbox_style).data[:text_color])
  # when closing delete tools action from tool_actions_to_exec
  Universe.active_tools.delete(tool_name)
  # we check if all tools are inactive if so we set edit_mode to false
  if Universe.active_tools.length == 0
    Atome.de_activate_click_analysis
    Universe.edit_mode = false
    Universe.allow_localstorage = false
  end

  inactivation_code = tool_scheme[:inactivation]
  tool.instance_exec(tool.data, &inactivation_code) if inactivation_code.is_a? Proc
  # generic behavior
  # we remove touch and resize binding on newly created atomes
  tool.apply(:inactive_tool_col)
  tool.data[:created]&.each do |new_atome|
    new_atome.drag(false)
    new_atome.resize(:remove)
  end
end

#debug(msg) ⇒ Object

def detach_atome(atome_id_to_detach)

alert :uuu
atome_to_detach = grab(atome_id_to_detach)
# TODO: remove the condition below and find why it try to detach an atome that doesn't exist
nil unless atome_to_detach

end



610
611
612
# File 'lib/atome/utilities/utilities.rb', line 610

def debug(msg)
  puts msg
end

#descendant_of?(ancestor) ⇒ Boolean

Returns:

  • (Boolean)


12
13
14
# File 'lib/renderers/html/atome_html.rb', line 12

def descendant_of?(ancestor)
  HTML.is_descendant(ancestor, id)
end


153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/molecules/intuition/utilities.rb', line 153

def drop_down(params, &code)


  data_f = params.delete(:data)
  text_f = params.delete(:text) || {component: {size: 12}, color: :lightgray}
  margin = params.delete(:margin) || 6
  default_params = { width: 150,
                     height: 25,
                     smooth:3,
                     shadow: { blur: 12, alpha: 0.3,left: 0, top: 0 }
  }
  params=default_params.merge(params)

  b=grab(:view).box(params.merge({depth: 33333, left: to_px(:left), top: to_px(:top)}))
  item_height=(params[:height]+margin)
  item_height = text_f[:component][:size]+margin*2 if text_f[:component][:size] > item_height
  b.height(data_f.length*item_height)
  temp_width=0
  data_f.each_with_index  do |label, index|
    item_f= b.text(text_f.merge({ left: margin, data: label, position: :absolute, top: item_height * index + margin }))
    temp_width=item_f.to_px(:width) if item_f.to_px(:width) > temp_width
    item_f.touch(:down) do
      code.call(label)
      b.delete(true)
    end
  end
  b.width(temp_width+margin*2)
end

#encrypt(string) ⇒ Object



649
650
651
652
653
654
655
656
657
# File 'lib/atome/utilities/utilities.rb', line 649

def encrypt(string)
  # if RUBY_ENGINE.downcase == 'opal' || 'wasm32-wasi'
  # `sha256(#{string})`
  js_code = "sha256('#{string}')"
  JS.eval(js_code)
  # else
  # Digest::SHA256.hexdigest(string)
  # end
end

#example(particle, &example) ⇒ Object



258
259
260
261
262
263
264
265
# File 'lib/atome/utilities/utilities.rb', line 258

def example(particle, &example)
  if example
    Universe.set_example(particle, &example)
  else
    example_found = Universe.get_example(particle)
    instance_exec(&example_found) if example_found.is_a?(Proc)
  end
end

#fetch_svg(params) ⇒ Object



819
820
821
822
823
824
825
# File 'lib/atome/utilities/utilities.rb', line 819

def fetch_svg(params)
  source = params[:source]
  img_element = JS.global[:document].getElementById(source.to_s)
  svg_path = img_element.getAttribute("src")
  target = params[:target]
  JS.eval("fetchSVGContent('#{svg_path}', '#{target}')")
end

#file_for_opal(parent, bloc) ⇒ Object

local server messaging



268
269
270
# File 'lib/atome/utilities/utilities.rb', line 268

def file_for_opal(parent, bloc)
  JS.eval("fileForOpal('#{parent}', #{bloc})")
end

#found_spacing_in_percent(parent_width, child_width, nb_of_children) ⇒ Object



168
169
170
171
172
173
174
# File 'lib/atome/utilities/utilities.rb', line 168

def found_spacing_in_percent(parent_width, child_width, nb_of_children)
  total_child_width = child_width * nb_of_children
  remaining_width = parent_width - total_child_width
  spacing = remaining_width.to_f / (nb_of_children + 1)
  spacing_percentage = (spacing / parent_width) * 100
  spacing_percentage.round(2)
end

#geolocationObject



7
8
9
10
11
12
# File 'lib/atome/extensions/geolocation.rb', line 7

def geolocation
  # native version
  public_ip = `curl https://api.ipify.org`
  results = Geocoder.search(public_ip)
  results.first.coordinates
end

#get_localstorage_contentObject



659
660
661
662
663
664
665
666
667
668
669
# File 'lib/atome/utilities/utilities.rb', line 659

def get_localstorage_content
  storage = JS.global[:localStorage]
  storage_array = storage.to_a
  storage_items = {}
  storage_array.each_with_index do |_i, index|
    key = JS.global[:localStorage].key(index)
    value = JS.global[:localStorage].getItem(key)
    storage_items[key] = value
  end
  storage_items
end

#grip(role_wanted) ⇒ Object



113
114
115
116
117
118
119
120
121
# File 'lib/atome/utilities/utilities.rb', line 113

def grip(role_wanted)
  gripped_atome = []

  fasten.each do |child_id|
    child_found = grab(child_id)
    gripped_atome << child_id if child_found.role && child_found.role.include?(role_wanted)
  end
  gripped_atome
end

#headless(_val = nil) ⇒ Object



6
# File 'lib/renderers/headless/headless.rb', line 6

def headless(_val = nil); end

#help(particle, &doc) ⇒ Object



249
250
251
252
253
254
255
256
# File 'lib/atome/utilities/utilities.rb', line 249

def help(particle, &doc)
  if doc
    Universe.set_help(particle, &doc)
  else
    doc_found = Universe.get_help(particle)
    instance_exec(&doc_found) if doc_found.is_a?(Proc)
  end
end

#historyObject

def history(filter = {})

filter[:id] = @id
Universe.story(filter)

end



395
396
397
# File 'lib/atome/utilities/utilities.rb', line 395

def history
  Universe.story
end

#html(obj = nil) ⇒ Object



4
5
6
7
8
9
10
# File 'lib/renderers/html/atome_html.rb', line 4

def html(obj = nil)
  if obj
    @html = obj
  else
    @html
  end
end

#include?(value) ⇒ Boolean

Returns:

  • (Boolean)


593
594
595
# File 'lib/atome/utilities/utilities.rb', line 593

def include?(value)
  include?(value)
end

#init_websocketObject



645
646
647
# File 'lib/atome/utilities/utilities.rb', line 645

def init_websocket
  connection(@current_server)
end

#inspectObject



86
87
88
89
90
91
92
93
# File 'lib/atome/atome.rb', line 86

def inspect
  filtered_vars = instance_variables.reject { |var| var == :@html_object || var == :@history }
  content = filtered_vars.map do |var|
    "#{var}=#{instance_variable_get(var).inspect}"
  end.join(", ")

  "#<#{self.class}: #{content}>"
end

#jsObject



64
65
66
# File 'lib/atome/atome.rb', line 64

def js
  html.object
end

#js_callback(id, particle, value, sub = nil) ⇒ Object



494
495
496
497
498
# File 'lib/atome/utilities/utilities.rb', line 494

def js_callback(id, particle, value, sub = nil)
  current_atome = grab(id)
  proc_found = current_atome.instance_variable_get("@#{particle}_code")[particle.to_sym]
  instance_exec(value, &proc_found) if proc_found.is_a?(Proc)
end

#noop(_p) ⇒ Object



230
231
232
# File 'lib/molecules/intuition/tools.rb', line 230

def noop(_p)
  # this method is used by tools when no treatment is needed
end

#particle_after(element, params, &user_proc) ⇒ Object



340
341
342
343
344
345
# File 'lib/atome/utilities/utilities.rb', line 340

def particle_after(element, params, &user_proc)
  if Atome.instance_variable_get("@after_#{element}").is_a?(Proc) # after is post saving
    params = instance_exec(params, user_proc, self, &Atome.instance_variable_get("@after_#{element}"))
  end
  params
end

#particle_callback(element) ⇒ Object

This method is used to automatically create a callback method suffixed by ‘_callback’. For example: shell => shell_callback. it can be override if you create a method like: new(:shell) do |params, bloc| # write what you want … end



450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
# File 'lib/atome/utilities/utilities.rb', line 450

def particle_callback(element)
  Atome.define_method("#{element}_callback") do |return_params|
    # we test if instance_variable_get("@#{element}_code") is a hash for the can se the particle value is a hash
    proc_found = if instance_variable_get("@#{element}_code").instance_of? Hash
                   # Then we get the first item of the hash because the proc is fasten to it
                   instance_variable_get("@#{element}_code").values.first
                   # instance_exec(@callback[element], proc_found)if proc_found.is_a? Proc
                 else
                   instance_variable_get("@#{element}_code")[element]
                   # instance_exec(@callback[element], proc_found)if proc_found.is_a? Proc
                 end
    # array_of_proc_found.each do |proc_found|
    proc_found.call(return_params) if proc_found.is_a? Proc
    # end if array_of_proc_found

    # if array_of_proc_found
    #   proc_found= array_of_proc_found.shift
    #   proc_found.call(return_params) if proc_found.is_a? Proc
    # end

  end
end

#particle_creation(element, params, store, rendering, &user_proc) ⇒ Object



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/atome/atome.rb', line 68

def particle_creation(element, params, store, rendering, &user_proc)

  params = particle_main(element, params, &user_proc)
  # Params is now an instance variable so it should be passed thru different methods
  instance_variable_set("@#{element}", params) if store
  # pre rendering processor
  params = particle_pre(element, params, &user_proc)
  # we create a proc holder of any new particle if user pass a bloc
  particle_callback(element)
  store_proc(element, params, &user_proc) if user_proc
  render(element, params, &user_proc) if rendering
  # post rendering processor
  params = particle_post(element, params, &user_proc)
  instance_variable_set("@#{element}", params) if store
  Universe.historicize(@aid, :write, element, params)
  particle_after(element, params, &user_proc)
end

#particle_main(element, params, &user_proc) ⇒ Object



299
300
301
302
303
304
305
306
# File 'lib/atome/utilities/utilities.rb', line 299

def particle_main(element, params, &user_proc)
  # TODO : optimise below removing all conditions if possible
  if Atome.instance_variable_get("@main_#{element}").is_a?(Proc) # post is before rendering and broadcasting
    result = instance_exec(params, user_proc, self, &Atome.instance_variable_get("@main_#{element}"))
    params = result if result && !result.instance_of?(Atome)
  end
  params
end

#particle_post(element, params, &user_proc) ⇒ Object



333
334
335
336
337
338
# File 'lib/atome/utilities/utilities.rb', line 333

def particle_post(element, params, &user_proc)
  if Atome.instance_variable_get("@post_#{element}").is_a?(Proc) # post is after rendering and broadcasting
    params = instance_exec(params, user_proc, self, &Atome.instance_variable_get("@post_#{element}"))
  end
  params
end

#particle_pre(element, params, &user_proc) ⇒ Object



326
327
328
329
330
331
# File 'lib/atome/utilities/utilities.rb', line 326

def particle_pre(element, params, &user_proc)
  if Atome.instance_variable_get("@pre_#{element}").is_a?(Proc) # post is before rendering and broadcasting
    params = instance_exec(params, user_proc, self, &Atome.instance_variable_get("@pre_#{element}"))
  end
  params
end

#particle_read(element, params, &user_proc) ⇒ Object



308
309
310
311
312
313
# File 'lib/atome/utilities/utilities.rb', line 308

def particle_read(element, params, &user_proc)
  if Atome.instance_variable_get("@read_#{element}").is_a?(Proc) # post is before rendering and broadcasting
    params = instance_exec(params, user_proc, self, &Atome.instance_variable_get("@read_#{element}"))
  end
  params
end

#particle_sanitizer(element, params, &user_proc) ⇒ Object



315
316
317
318
319
320
321
322
323
324
# File 'lib/atome/utilities/utilities.rb', line 315

def particle_sanitizer(element, params, &user_proc)

  bloc_found = Universe.get_sanitizer_method(element)
  # sanitizer occurs before any treatment
  # it's call at the very start when a new atome is created : in genesis.rb /new_atome
  # it's also call when creating a new particle in genesis/ new_particle befre creating the particle
  # and also before creating additional method  in genesis/ additional_particle_methods
  params = instance_exec(params, user_proc, &bloc_found) if bloc_found.is_a?(Proc)
  params
end

#particles(particles_found = nil) ⇒ Object

def callback(data)

@callback[data.keys[0]] = data[data.keys[0]]

end



504
505
506
507
508
509
510
511
512
# File 'lib/atome/utilities/utilities.rb', line 504

def particles(particles_found = nil)
  if particles_found
    particles_found.each do |particle_found, value_found|
      atome[particle_found] = value_found
    end
  else
    atome
  end
end

#particles_to_hashObject



521
522
523
524
525
526
527
528
# File 'lib/atome/utilities/utilities.rb', line 521

def particles_to_hash
  hash = {}
  instance_variables.each do |var|
    next if %i[@selection_style @html_object @history @initialized @tick @controller_proc].include?(var)
    hash[var.to_s.delete('@').to_sym] = instance_variable_get(var)
  end
  hash
end

#ping(my_proc = false) ⇒ Object



11
12
13
# File 'lib/atome/extensions/ping.rb', line 11

def ping(address, my_proc: false)
  up(address, my_proc) # prints "true" if ping replies
end

#preset_common(params, &bloc) ⇒ Object



39
40
41
# File 'lib/atome/presets/atome.rb', line 39

def preset_common(params, &bloc)
  Atome.new(params, &bloc)
end

#read_auth(element) ⇒ Object



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/atome/utilities/security.rb', line 47

def read_auth(element)

  if (@password && @password[:read]) && @authorisations && @authorisations[:read]
    if !@authorisations[:read][element]
      return false
    elsif @password[:read][element] == @authorisations[:read][element]
      check_password_destruction(:read, element)
      # we check if we a specific password to read the particle
      return true
    elsif @authorisations[:read][:atome] == @password[:read][:atome]
      check_password_destruction(:read, element)
      # we check if we a a password that allow to read the whole atome so all the particles
      return true
    else
      check_password_destruction(:read, element)

      return false
    end

    check_password_destruction(:read, element)
  else
    true
  end
end

#read_ruby_callback(element) ⇒ Object



480
481
482
483
484
485
486
# File 'lib/atome/utilities/utilities.rb', line 480

def read_ruby_callback(element)
  puts "dunno what this method is about ?? method call :#{element}"
  # alert id
  # puts "2 ===> #{element} !!!"
  # alert  send("terminal_callback").inspect
  # alert  send("#{element}_callback")
end

#recursive(_val) ⇒ Object



123
124
125
# File 'lib/atome/utilities/utilities.rb', line 123

def recursive(_val)
  # dummy method
end

#refresh(&bloc) ⇒ Object



583
584
585
586
587
# File 'lib/atome/utilities/utilities.rb', line 583

def refresh(&bloc)
  retrieve({ self: true }) do |child|
    child.refresh_atome
  end
end

#refresh_atomeObject

def refresh

# we get the current color because they will be removed
particles_found = particles_to_hash.dup
# id_found=id
data_found=particles_found.delete(:data)
attach_found=particles_found.delete(:attach)
apply_found=particles_found.delete(:apply)
particles_found.each do |particle_found, value_found|
  send(particle_found, value_found)
end
# Universe.applicable_atomes.each do |atome_type|
#
#   send(atome_type).each do |col|
#     apply(col)
#   end
# end
# alert id_found
# grab(attach_found).fasten(id_found)
data(data_found)

apply_found.delete(:text_color) #TODO : patch here :  the array is not correctly ordered so default color are apply over the next
apply_found.delete(:box_color) ##TODO : patch here :  the array is not correctly ordered so default color are apply over the next
apply(apply_found)
# attach(attach_found)

end



557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
# File 'lib/atome/utilities/utilities.rb', line 557

def refresh_atome
  id_found = id.dup
  id(:temporary)
  fasten_atomes = []
  fasten_found = fasten.dup
  fasten_found.each do |child_id_found|
    child_found = grab(child_id_found)
    if child_found
      new_child = child_found.duplicate({})
      fasten_atomes << new_child.id
    end
  end

  infos_found = infos.dup
  data_found = infos_found.delete(:data)
  keys_to_delete = %i[history callback duplicate copy paste touch_code html fasten aid]
  keys_to_delete.each { |key| infos_found.delete(key) }
  new_atome_id = id_found
  infos_found[:id] = new_atome_id
  new_atome = Atome.new(infos_found)
  @duplicate ||= {}
  @duplicate[new_atome_id] = new_atome
  new_atome.data(data_found) # needed because if atome type is a text we need add type at the end
  new_atome
end

#remove_get_atome_on_touchObject



238
239
240
# File 'lib/molecules/intuition/tools.rb', line 238

def remove_get_atome_on_touch
  @touch_action = nil
end

#remove_layoutObject



622
623
624
625
626
627
628
629
630
631
632
633
634
635
# File 'lib/atome/utilities/utilities.rb', line 622

def remove_layout
  display(:default)
  # we get the current parent (the previous layout)
  parent_found = grab(attach)
  # we get the parent of the parent
  grand_parent = parent_found.attach
  # and attach the item to the grand parent
  # we remove the parent category and restore atome category
  remove({ category: attach })
  category(:atome)
  attach(grand_parent)
  #  we delete the parent (the layout) if it no more children fasten
  parent_found.delete(true) if parent_found.fasten.length == 0
end

#remove_menu_item(item_to_remove) ⇒ Object



36
37
38
39
# File 'lib/molecules/intuition/utilities.rb', line 36

def remove_menu_item(item_to_remove)
  grab(item_to_remove).delete(recursive: true)
  reorder_menu
end

#render(element, params, &user_proc) ⇒ Object

private



6
7
8
9
10
11
12
13
14
# File 'lib/renderers/renderer.rb', line 6

def render(element, params, &user_proc)

  render_engines = @renderers || []
  render_engines.each do |render_engine|
    # in case we found an exception the method call will have the form, example for color top  : html_color_top
    exception_found = "#{Universe.get_atomes_specificities[type][element]}"
    send("#{render_engine}_#{exception_found}#{element}", params, &user_proc)
  end
end

#reorder_blocsObject



24
25
26
27
28
29
30
31
32
33
34
# File 'lib/molecules/intuition/utilities.rb', line 24

def reorder_blocs
  @prev_bloc_height = 0
  fasten.each do |bloc_f|
    potential_bloc = grab(bloc_f)
    spacing = potential_bloc.spacing
    if potential_bloc.role && potential_bloc.role.include?(:block)
      potential_bloc.top(spacing + @prev_bloc_height)
      @prev_bloc_height = @prev_bloc_height + potential_bloc.height + spacing
    end
  end
end

#reorder_menuObject



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# File 'lib/molecules/intuition/utilities.rb', line 4

def reorder_menu
  # disposition = data
  disposition = data[:inactive][:disposition]
  margin = data[:inactive][:margin]
  spacing = data[:inactive][:spacing]
  inactive_style = data[:inactive]
  keys_to_exclude = [:margin, :spacing, :disposition, :text]
  inactive_style = inactive_style.reject { |key, _| keys_to_exclude.include?(key) }
  fasten.each_with_index do |atome_f, index|
    menu_item = grab(atome_f)
    if disposition == :horizontal
      menu_item.left = margin[:left] + (inactive_style[:width] + spacing) * index
      menu_item.top = margin[:top]
    else
      menu_item.top = margin[:top] + (inactive_style[:height] + spacing) * index
      menu_item.left = margin[:left]
    end
  end
end

#resize_matrix(params) ⇒ Object



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/molecules/intuition/utilities.rb', line 118

def resize_matrix(params)
  width(params[:width])
  height(params[:height])
  current_matrix = self
  real_width = current_matrix.to_px(:width)
  real_height = current_matrix.to_px(:height)
  spacing = current_matrix.data[:spacing]
  matrix_cells = current_matrix.data[:matrix]

  total_spacing_x = spacing * (matrix_cells.collect.length ** (0.5) + 1)
  total_spacing_y = spacing * (matrix_cells.collect.length ** (0.5) + 1)

  if real_width > real_height
    full_size = real_width
    available_width = full_size - total_spacing_x
    available_height = full_size - total_spacing_y
  else
    full_size = real_width
    available_width = full_size - total_spacing_x
    available_height = full_size - total_spacing_y
  end

  box_width = available_width / matrix_cells.collect.length ** (0.5)
  box_height = available_height / matrix_cells.collect.length ** (0.5)

  matrix_cells.collect.each_with_index do |box_id, index|
    box = grab(box_id)
    box.width(box_width)
    box.height(box_height)
    box.left((box_width + spacing) * (index % matrix_cells.collect.length ** (0.5)) + spacing)
    box.top((box_height + spacing) * (index / matrix_cells.collect.length ** (0.5)).floor + spacing)
  end

end

#response_listener(hashed_msg) ⇒ Object



272
273
274
275
276
# File 'lib/atome/utilities/utilities.rb', line 272

def response_listener(hashed_msg)
  js_action = hashed_msg.JS[:action]
  js_body = hashed_msg.JS[:body]
  send(js_action, js_body)
end

#retrieve(params = {}, &block) ⇒ Object



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/atome/utilities/utilities.rb', line 127

def retrieve(params = {}, &block)
  closest_first = true, include_self = false
  if params[:ascending] == false
    closest_first = :inverted
  end
  if params[:self] == true
    include_self = true
  end

  # this method allow to retrieve all children of an atome recursively, beginning from the closet child or inverted

  all_children = []
  fetch_children_recursively = lambda do |parent, depth|
    children_ids = parent.fasten
    if children_ids.any?
      children_ids.each do |child_id|
        child = grab(child_id)
        fetch_children_recursively.call(child, depth + 1)
      end
    end
    if include_self
      all_children << { depth: depth, child: parent }
    else
      all_children << { depth: depth, child: parent } unless parent == self
    end

  end

  fetch_children_recursively.call(self, 0)

  sorted_children = if closest_first != :inverted
                      all_children.sort_by { |entry| entry[:depth] }
                    else
                      all_children.sort_by { |entry| -entry[:depth] }
                    end

  sorted_children.each do |entry|
    block.call(entry[:child])
  end
end

#rgb_html(string) ⇒ Object



5
6
7
8
9
10
11
12
13
# File 'lib/platform_specific/opal/extensions/color.rb', line 5

def rgb_html(string)
  js_code = <<-JS
var col = w3color('#{string}');
var rgb_col = col.toRgb();
return rgb_col;
  JS

  JS.eval(js_code)
end

#server(server_params = nil) ⇒ Object



637
638
639
640
641
642
643
# File 'lib/atome/utilities/utilities.rb', line 637

def server(server_params = nil)
  if server_params
    @current_server = server_params
  else
    @current_server
  end
end

#set(params) ⇒ Object



597
598
599
600
601
# File 'lib/atome/utilities/utilities.rb', line 597

def set(params)
  params.each do |particle, value|
    send(particle, value)
  end
end

#set_action_on_touch(&action) ⇒ Object



234
235
236
# File 'lib/molecules/intuition/tools.rb', line 234

def set_action_on_touch(&action)
  @touch_action = action
end

#set_current_user(user_id) ⇒ Object



614
615
616
617
618
619
620
# File 'lib/atome/utilities/utilities.rb', line 614

def set_current_user(user_id)
  if Universe.users[user_id]
    Universe.current_user = user_id
  else
    debug "#{user_id} not found"
  end
end

#store_proc(element, params = true, &user_proc) ⇒ Object

def broadcasting(element)

params = instance_variable_get("@#{element}")
@broadcast.each_value do |particle_monitored|
  if particle_monitored[:particles].include?(element)
    code_found = particle_monitored[:code]
    instance_exec(self, element, params, &code_found) if code_found.is_a?(Proc)
  end
end

end



409
410
411
412
413
414
415
416
417
418
419
420
421
# File 'lib/atome/utilities/utilities.rb', line 409

def store_proc(element, params = true, &user_proc)
  instance_variable_set("@#{element}_code", {}) unless instance_variable_get("@#{element}_code")
  # TODO : we may have to change this code if we need multiple proc for an particle
  # FIXME : find a better algorithm can be found to avoid test if option is a Hash
  Object.attr_accessor "#{element}_code"
  elem_code = "@#{element}_code"
  # if params.instance_of? Hash
  #   option_found = params.values[0]
  #   instance_variable_get(elem_code)["#{option_found}_code"] = user_proc
  # else
  instance_variable_get(elem_code)[element] = user_proc
  # end
end

#store_ruby_callback(params) ⇒ Object



473
474
475
476
477
478
# File 'lib/atome/utilities/utilities.rb', line 473

def store_ruby_callback(params)

  params.each do |element, value_v|
    send("#{element}_code")[element].call(value_v)
  end
end

#sub_block(sub_params, spacing_found = 3) ⇒ Object



229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
# File 'lib/atome/utilities/utilities.rb', line 229

def sub_block(sub_params, spacing_found = 3)
  num_blocks = sub_params.size
  parent_width = to_px(:width)
  total_ratios = sub_params.values.sum { |sub_content| sub_content[:width] }
  total_spacing = (num_blocks + 1) * spacing_found
  available_width = parent_width - total_spacing
  left_offset = spacing_found
  sub_params.each do |sub_id, sub_content|
    ratio = sub_content[:width]
    block_width = (available_width * ratio) / total_ratios
    sub_created = box({ id: sub_id, height: '100%', left: left_offset, role: :sub })
    sub_content["width"] = block_width
    sub_created.set(sub_content)
    sub_created.width(block_width)
    left_offset += block_width + spacing_found
    sub_created.width(sub_created.to_percent(:width))
    sub_created.left(sub_created.to_percent(:left))
  end
end

#sync(params, &bloc) ⇒ Object

def to_sym

puts "sanitizer temp patch when an atome is passed instead of an id"
@id

end def transform_to_string_keys_and_values(hash)

hash.transform_keys(&:to_s).transform_values do |value|
  if value.is_a?(Hash)
    transform_to_string_keys_and_values(value)
  else
    value.to_s
  end
end

end



685
686
687
688
689
690
691
692
# File 'lib/atome/utilities/utilities.rb', line 685

def sync(params, &bloc)
  params = { data: params } unless params.instance_of? Hash
  message_id = "msg_#{Universe.messages.length}"
  params[:message_id] = message_id
  Universe.store_messages({ msg_nb: message_id, proc: bloc })
  # params = transform_to_string_keys_and_values(params)
  html.send_message(params)
end

#to_percent(property) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/renderers/html/atome_html.rb', line 27

def to_percent(property)
  parent = grab(attach)
  parent_width = parent.to_px(:width)
  parent_height = parent.to_px(:height)
  property_needed_px = to_px(property)
  case property
  when :width, :left
    "#{(property_needed_px / parent_width.to_f) * 100}%"
  when :height, :top
    "#{(property_needed_px / parent_height.to_f) * 100}%"
  else
    raise ArgumentError # unsupported property use left , top, width an height
  end
end

#to_px(particle) ⇒ Object



16
17
18
19
20
21
22
23
24
25
# File 'lib/renderers/html/atome_html.rb', line 16

def to_px(particle)
  ruby_wasm_code = <<-JS
var div = document.getElementById("#{@id}");
var style = window.getComputedStyle(div);
var original_value = style.getPropertyValue("#{particle}");
var parsed_value = parseInt(original_value);
return parsed_value;
  JS
  JS.eval(ruby_wasm_code).to_f
end

#to_rgb(string) ⇒ Object



15
16
17
18
19
20
21
22
23
24
# File 'lib/platform_specific/opal/extensions/color.rb', line 15

def to_rgb(string)
  rgb_color = rgb_html(string)

  {
    red: rgb_color[:r] / 255,
    green: rgb_color[:g] / 255,
    blue: rgb_color[:b] / 255,
    alpha: 1
  }
end

#toolbox(tool_list) ⇒ Object



27
28
29
30
31
32
33
# File 'lib/molecules/intuition/tools.rb', line 27

def toolbox(tool_list)
  @toolbox = tool_list[:tools]
  tool_list[:tools].each_with_index do |root_tool, index|
    tools_scheme = Universe.tools[root_tool]
    build_tool({ name: root_tool, scheme: tools_scheme, index: index, toolbox: tool_list[:toolbox] })
  end
end

#up?(host, _my_proc) ⇒ Boolean

Returns:

  • (Boolean)


5
6
7
8
9
# File 'lib/atome/extensions/ping.rb', line 5

def up?(host, _my_proc)
  check = Net::Ping::External.new(host)
  return unless check.ping?
  'ping respond!!'
end

#vectorizer(svg_content) ⇒ Object



712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
# File 'lib/atome/utilities/utilities.rb', line 712

def vectorizer(svg_content)
  atome_content = []

  # circle_regex = /<circle\s+.*?id\s*=\s*"(.*?)"\s+(?:stroke\s*=\s*"(.*?)"\s+)?(?:stroke-width\s*=\s*"(.*?)"\s+)?fill\s*=\s*"(.*?)"\s+cx\s*=\s*"(\d+)"\s+cy\s*=\s*"(\d+)"\s+r\s*=\s*"(\d+)".*?\/>/
  circle_regex = /<circle\s+.*?id\s*=\s*"(.*?)"\s+(?:stroke\s*=\s*"(.*?)"\s+)?(?:stroke-width\s*=\s*"(.*?)"\s+)?fill\s*=\s*"(.*?)"\s+cx\s*=\s*"(\d+(?:\.\d+)?)"\s+cy\s*=\s*"(\d+(?:\.\d+)?)"\s+r\s*=\s*"(\d+(?:\.\d+)?)"\s*.*?\/>/

  svg_content.scan(circle_regex) do |id, stroke, stroke_width, fill, cx, cy, r|
    stroke = stroke || 'none'
    stroke_width = stroke_width || '0'
    fill = fill || 'none'
    circle_def = { circle: { cx: cx, cy: cy, r: r, id: id, stroke: stroke, "stroke-width" => stroke_width, fill: fill } }
    atome_content << circle_def
  end

  # path_regex = /<path\s+.*?d\s*=\s*"([^"]+)"\s+(?:id\s*=\s*"(.*?)"\s+)?(?:stroke\s*=\s*"(.*?)"\s+)?(?:stroke-width\s*=\s*"(.*?)"\s+)?fill\s*=\s*"(.*?)".*?\/>/
  path_regex = /<path\s+.*?d\s*=\s*"([^"]+)"\s+(?:id\s*=\s*"(.*?)"\s+)?(?:stroke\s*=\s*"(.*?)"\s+)?(?:stroke-width\s*=\s*"(.*?)"\s+)?fill\s*=\s*"(.*?)".*?\/>/

  svg_content.scan(path_regex) do |d, id, stroke, stroke_width, fill|
    id = id || 'path_id'
    stroke = stroke || 'none'
    stroke_width = stroke_width || '0'
    fill = fill || 'none'
    path_def = { path: { d: d, id: id, stroke: stroke, 'stroke-width' => stroke_width, fill: fill } }
    atome_content << path_def
  end

  # rect_regex = /<rect\s+.*?id\s*=\s*"(.*?)"\s+(?:stroke\s*=\s*"(.*?)"\s+)?(?:stroke-width\s*=\s*"(.*?)"\s+)?fill\s*=\s*"(.*?)"\s+x\s*=\s*"(\d+)"\s+y\s*=\s*"(\d+)"\s+width\s*=\s*"(\d+)"\s+height\s*=\s*"(\d+)".*?\/>/
  rect_regex = /<rect\s+.*?id\s*=\s*"(.*?)"\s+(?:stroke\s*=\s*"(.*?)"\s+)?(?:stroke-width\s*=\s*"(.*?)"\s+)?fill\s*=\s*"(.*?)"\s+x\s*=\s*"(\d+(?:\.\d+)?)"\s+y\s*=\s*"(\d+(?:\.\d+)?)"\s+width\s*=\s*"(\d+(?:\.\d+)?)"\s+height\s*=\s*"(\d+(?:\.\d+)?)"\s*.*?\/>/

  svg_content.scan(rect_regex) do |id, stroke, stroke_width, fill, x, y, width, height|
    id = id || 'rect_id'
    stroke = stroke || 'none'
    stroke_width = stroke_width || '0'
    fill = fill || 'none'
    rect_def = { rect: { x: x, y: y, width: width, height: height, id: id, stroke: stroke, 'stroke-width' => stroke_width, fill: fill } }
    atome_content << rect_def
  end

  # line_regex = /<line\s+.*?id\s*=\s*"(.*?)"\s+(?:stroke\s*=\s*"(.*?)"\s+)?(?:stroke-width\s*=\s*"(.*?)"\s+)?x1\s*=\s*"(\d+)"\s+y1\s*=\s*"(\d+)"\s+x2\s*=\s*"(\d+)"\s+y2\s*=\s*"(\d+)".*?\/>/
  line_regex = /<line\s+.*?id\s*=\s*"(.*?)"\s+(?:stroke\s*=\s*"(.*?)"\s+)?(?:stroke-width\s*=\s*"(.*?)"\s+)?x1\s*=\s*"(\d+(?:\.\d+)?)"\s+y1\s*=\s*"(\d+(?:\.\d+)?)"\s+x2\s*=\s*"(\d+(?:\.\d+)?)"\s+y2\s*=\s*"(\d+(?:\.\d+)?)"\s*.*?\/>/

  svg_content.scan(line_regex) do |id, stroke, stroke_width, x1, y1, x2, y2|
    id = id || 'line_id'
    stroke = stroke || 'none'
    stroke_width = stroke_width || '0'
    line_def = { line: { x1: x1, y1: y1, x2: x2, y2: y2, id: id, stroke: stroke, 'stroke-width' => stroke_width } }
    atome_content << line_def
  end

  # ellipse_regex = /<ellipse\s+.*?id\s*=\s*"(.*?)"\s+(?:stroke\s*=\s*"(.*?)"\s+)?(?:stroke-width\s*=\s*"(.*?)"\s+)?fill\s*=\s*"(.*?)"\s+cx\s*=\s*"(\d+)"\s+cy\s*=\s*"(\d+)"\s+rx\s*=\s*"(\d+)"\s+ry\s*=\s*"(\d+)".*?\/>/
  ellipse_regex = /<ellipse\s+.*?id\s*=\s*"(.*?)"\s+(?:stroke\s*=\s*"(.*?)"\s+)?(?:stroke-width\s*=\s*"(.*?)"\s+)?fill\s*=\s*"(.*?)"\s+cx\s*=\s*"(\d+(?:\.\d+)?)"\s+cy\s*=\s*"(\d+(?:\.\d+)?)"\s+rx\s*=\s*"(\d+(?:\.\d+)?)"\s+ry\s*=\s*"(\d+(?:\.\d+)?)"\s*.*?\/>/

  svg_content.scan(ellipse_regex) do |id, stroke, stroke_width, fill, cx, cy, rx, ry|
    id = id || 'ellipse_id'
    stroke = stroke || 'none'
    stroke_width = stroke_width || '0'
    fill = fill || 'none'
    ellipse_def = { ellipse: { cx: cx, cy: cy, rx: rx, ry: ry, id: id, stroke: stroke, 'stroke-width' => stroke_width, fill: fill } }
    atome_content << ellipse_def
  end

  # polygon_regex = /<polygon\s+(?:id\s*=\s*"(.*?)"\s+)?(?:stroke\s*=\s*"(.*?)"\s+)?(?:stroke-width\s*=\s*"(.*?)"\s+)?(?:fill\s*=\s*"(.*?)"\s+)?points\s*=\s*"([^"]+)".*?\/>/
  polygon_regex = /<polygon\s+(?:id\s*=\s*"(.*?)"\s+)?(?:stroke\s*=\s*"(.*?)"\s+)?(?:stroke-width\s*=\s*"(.*?)"\s+)?(?:fill\s*=\s*"(.*?)"\s+)?points\s*=\s*"([^"]+)".*?\/>/
  svg_content.scan(polygon_regex) do |id, stroke, stroke_width, fill, points|
    id ||= 'polygon_id'
    stroke ||= 'none'
    stroke_width ||= '0'
    fill ||= 'none'
    polygon_def = { polygon: { points: points, id: id, stroke: stroke, 'stroke-width' => stroke_width, fill: fill } }
    atome_content << polygon_def
  end

  polyline_regex = /<polyline\s+.*?points\s*=\s*"([^"]+)"\s+(?:id\s*=\s*"(.*?)"\s+)?(?:stroke\s*=\s*"(.*?)"\s+)?(?:stroke-width\s*=\s*"(.*?)"\s+)?(?:fill\s*=\s*"(.*?)")?.*?\/>/
  svg_content.scan(polyline_regex) do |points, id, stroke, stroke_width, fill|
    id ||= 'polyline_id'
    stroke ||= 'none'
    stroke_width ||= '0'
    fill ||= 'none'
    polyline_def = { polyline: { points: points, id: id, stroke: stroke, 'stroke-width' => stroke_width, fill: fill } }
    atome_content << polyline_def
  end

  atome_content
end

#write_auth(element) ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/atome/utilities/security.rb', line 22

def write_auth(element)
  if (@password && @password[:write]) && @authorisations && @authorisations[:write]
    if !@authorisations[:write][element]
      return false
    elsif @password[:write][element] == @authorisations[:write][element]
      # we check if we a specific password to read the particle
      check_password_destruction(:write, element)
      return true
    elsif @authorisations[:write][:atome] == @password[:write][:atome]

      puts "#{@authorisations[:write][:atome]} == #{@password[:write][:atome]}"
      check_password_destruction(:write, element)
      # we check if we a a password that allow to read the whole atome so all the particles
      return true
    else
      check_password_destruction(:write, element)
      return false
    end

    check_password_destruction(:write, element)
  else
    true
  end
end