fron 0.1.4 → 0.2.0rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.reek +11 -0
  4. data/.rubocop.yml +54 -0
  5. data/.travis.yml +11 -0
  6. data/.yardopts +4 -0
  7. data/Changelog.md +7 -0
  8. data/Gemfile +3 -1
  9. data/Gemfile.lock +106 -15
  10. data/Rakefile +19 -15
  11. data/Readme.md +23 -0
  12. data/fron.gemspec +2 -2
  13. data/lib/fron/version.rb +2 -1
  14. data/opal/fron.rb +5 -5
  15. data/opal/fron/core.rb +3 -10
  16. data/opal/fron/core/behaviors/components.rb +42 -0
  17. data/opal/fron/core/behaviors/events.rb +27 -0
  18. data/opal/fron/core/behaviors/routes.rb +59 -0
  19. data/opal/fron/core/component.rb +64 -90
  20. data/opal/fron/core/eventable.rb +18 -0
  21. data/opal/fron/core/logger.rb +10 -1
  22. data/opal/fron/core_ext.rb +9 -0
  23. data/opal/fron/core_ext/array.rb +12 -0
  24. data/opal/fron/core_ext/date.rb +57 -0
  25. data/opal/fron/core_ext/hash.rb +52 -0
  26. data/opal/fron/core_ext/kernel.rb +57 -0
  27. data/opal/fron/core_ext/nil.rb +7 -0
  28. data/opal/fron/core_ext/numeric.rb +19 -0
  29. data/opal/fron/core_ext/object.rb +11 -0
  30. data/opal/fron/core_ext/proc.rb +19 -0
  31. data/opal/fron/{core-ext → core_ext}/string.rb +4 -0
  32. data/opal/fron/dom.rb +15 -13
  33. data/opal/fron/dom/document.rb +22 -6
  34. data/opal/fron/dom/element.rb +105 -67
  35. data/opal/fron/dom/event.rb +110 -40
  36. data/opal/fron/dom/{file-reader.rb → file_reader.rb} +6 -1
  37. data/opal/fron/dom/fragment.rb +2 -0
  38. data/opal/fron/dom/modules/attributes.rb +43 -0
  39. data/opal/fron/dom/modules/classlist.rb +26 -13
  40. data/opal/fron/dom/modules/dimensions.rb +79 -9
  41. data/opal/fron/dom/modules/element_accessor.rb +35 -0
  42. data/opal/fron/dom/modules/events.rb +67 -20
  43. data/opal/fron/dom/node.rb +98 -39
  44. data/opal/fron/dom/nodelist.rb +9 -2
  45. data/opal/fron/dom/style.rb +23 -2
  46. data/opal/fron/dom/text.rb +4 -0
  47. data/opal/fron/dom/window.rb +31 -2
  48. data/opal/fron/event_mock.rb +54 -0
  49. data/opal/fron/js/syntetic_event.js +16 -0
  50. data/opal/fron/request.rb +2 -2
  51. data/opal/fron/request/request.rb +77 -14
  52. data/opal/fron/request/response.rb +33 -6
  53. data/opal/fron/storage.rb +1 -1
  54. data/opal/fron/storage/local_storage.rb +54 -0
  55. data/opal/fron/utils/drag.rb +135 -0
  56. data/opal/fron/utils/keyboard.rb +70 -0
  57. data/opal/fron/utils/point.rb +78 -0
  58. data/opal/fron/utils/render_proc.rb +27 -0
  59. data/spec/core-ext/array_spec.rb +15 -0
  60. data/spec/core-ext/date_spec.rb +54 -0
  61. data/spec/core-ext/hash_spec.rb +18 -2
  62. data/spec/core-ext/kernel_spec.rb +57 -0
  63. data/spec/core-ext/nil_spec.rb +9 -0
  64. data/spec/core-ext/numeric_spec.rb +25 -0
  65. data/spec/core-ext/proc_spec.rb +15 -0
  66. data/spec/core-ext/string_spec.rb +11 -0
  67. data/spec/core/behaviors/events_spec.rb +25 -0
  68. data/spec/core/behaviors/routes_spec.rb +59 -0
  69. data/spec/core/component_inheritance_spec.rb +26 -16
  70. data/spec/core/component_spec.rb +25 -29
  71. data/spec/core/eventable_spec.rb +19 -19
  72. data/spec/core/logger_spec.rb +5 -6
  73. data/spec/dom/document_spec.rb +4 -5
  74. data/spec/dom/element_spec.rb +106 -15
  75. data/spec/dom/event_spec.rb +101 -61
  76. data/spec/dom/file_reader_spec.rb +11 -0
  77. data/spec/dom/fragment_spec.rb +3 -4
  78. data/spec/dom/instance_retaining_spec.rb +58 -0
  79. data/spec/dom/modules/classlist_spec.rb +18 -19
  80. data/spec/dom/modules/dimensions_spec.rb +87 -22
  81. data/spec/dom/modules/events_spec.rb +22 -8
  82. data/spec/dom/node_spec.rb +25 -17
  83. data/spec/dom/nodelist_spec.rb +2 -3
  84. data/spec/dom/style_spec.rb +6 -5
  85. data/spec/dom/text_spec.rb +4 -3
  86. data/spec/dom/window_spec.rb +24 -9
  87. data/spec/js/mocks.js +14 -0
  88. data/spec/request/request_spec.rb +34 -15
  89. data/spec/request/response_spec.rb +9 -10
  90. data/spec/spec_helper.rb +11 -0
  91. data/spec/storage/{local-storage_spec.rb → local_storage_spec.rb} +6 -7
  92. data/spec/utils/drag_spec.rb +136 -0
  93. data/spec/utils/keyboard_spec.rb +75 -0
  94. data/spec/utils/point_spec.rb +55 -0
  95. data/spec/utils/render_proc_spec.rb +18 -0
  96. metadata +58 -36
  97. data/docs/application.md +0 -7
  98. data/docs/configuration.md +0 -29
  99. data/docs/controllers.md +0 -35
  100. data/docs/routing.md +0 -63
  101. data/opal/fron/core-ext.rb +0 -5
  102. data/opal/fron/core-ext/hash.rb +0 -31
  103. data/opal/fron/core-ext/kernel.rb +0 -10
  104. data/opal/fron/core-ext/numeric.rb +0 -9
  105. data/opal/fron/core-ext/proc.rb +0 -9
  106. data/opal/fron/core/adapters/local.rb +0 -43
  107. data/opal/fron/core/adapters/rails.rb +0 -65
  108. data/opal/fron/core/application.rb +0 -42
  109. data/opal/fron/core/configuration.rb +0 -29
  110. data/opal/fron/core/controller.rb +0 -41
  111. data/opal/fron/core/model.rb +0 -90
  112. data/opal/fron/core/router.rb +0 -86
  113. data/opal/fron/storage/local-storage.rb +0 -34
  114. data/spec/core/adapter/local_spec.rb +0 -65
  115. data/spec/core/adapter/rails_spec.rb +0 -77
  116. data/spec/core/application_spec.rb +0 -35
  117. data/spec/core/configuration_spec.rb +0 -20
  118. data/spec/core/controlller_spec.rb +0 -68
  119. data/spec/core/model_spec.rb +0 -125
  120. data/spec/core/router_spec.rb +0 -124
@@ -1,12 +1,17 @@
1
1
  module DOM
2
+ # File Reader
2
3
  class FileReader
3
4
  include Events
4
5
 
6
+ # Initialzies the fire reader
5
7
  def initialize
6
8
  @el = `new FileReader()`
7
9
  end
8
10
 
9
- def readAsDataURL(file)
11
+ # Read the given file as data url
12
+ #
13
+ # @param file [Native] The file
14
+ def read_as_data_url(file)
10
15
  return unless file
11
16
  `#{@el}.readAsDataURL(file.native)`
12
17
  end
@@ -1,5 +1,7 @@
1
1
  module DOM
2
+ # Fragment
2
3
  class Fragment < NODE
4
+ # Initializes the document fragment
3
5
  def initialize
4
6
  @el = `document.createDocumentFragment()`
5
7
  end
@@ -0,0 +1,43 @@
1
+ module DOM
2
+ # Attributes
3
+ module Attributes
4
+ # Returns the value of the attribute with the given name
5
+ #
6
+ # @param name [String] The name of the attribute
7
+ #
8
+ # @return [String] The value
9
+ def [](name)
10
+ `#{@el}.getAttribute(#{name}) || Opal.nil`
11
+ end
12
+
13
+ # Sets the value of the attribute with the given name with the given value
14
+ #
15
+ # @param name [String] The name
16
+ # @param value [String] The value
17
+ #
18
+ # @return [type] [description]
19
+ def []=(name, value)
20
+ if value
21
+ `#{@el}.setAttribute(#{name},#{value})`
22
+ else
23
+ remove_attribute name
24
+ end
25
+ end
26
+
27
+ # Returns if the element has the given attribute
28
+ #
29
+ # @param name [String] The attribute
30
+ #
31
+ # @return [Boolean] True / False
32
+ def attribute?(name)
33
+ `#{@el}.hasAttribute(#{name})`
34
+ end
35
+
36
+ # Removes the given attribute
37
+ #
38
+ # @param name [String] The attributes name
39
+ def remove_attribute(name)
40
+ `#{@el}.removeAttribute(#{name})`
41
+ end
42
+ end
43
+ end
@@ -1,26 +1,39 @@
1
1
  module DOM
2
+ # ClassList management for DOM::Element
2
3
  module ClassList
3
- def addClass(*classes)
4
- classes.each do |cls|
5
- `#{@el}.classList.add(#{cls})`
6
- end
4
+ # Adds classes to the class list
5
+ #
6
+ # @param classes [Array] The classes
7
+ def add_class(*classes)
8
+ classes.each { |cls| `#{@el}.classList.add(#{cls})` }
7
9
  end
8
10
 
9
- def removeClass(*classes)
10
- classes.each do |cls|
11
- `#{@el}.classList.remove(#{cls})`
12
- end
11
+ # Removes classes from the class list
12
+ #
13
+ # @param classes [Array] The classes
14
+ def remove_class(*classes)
15
+ classes.each { |cls| `#{@el}.classList.remove(#{cls})` }
13
16
  end
14
17
 
15
- def hasClass(cls)
18
+ # Returns whether the class list has the given class or not
19
+ #
20
+ # @param cls [String] The class
21
+ #
22
+ # @return [Boolean] True if it has false if not
23
+ def has_class(cls)
16
24
  `#{@el}.classList.contains(#{cls})`
17
25
  end
18
26
 
19
- def toggleClass(cls,value = nil)
20
- if value || (value == nil && !hasClass(cls))
21
- addClass cls
27
+ # Toggles the given class based on the second argument,
28
+ # or if omitted then toggles the class.
29
+ #
30
+ # @param cls [String] The class
31
+ # @param value [Boolean] The value
32
+ def toggle_class(cls, value = nil)
33
+ if value || (value.nil? && !has_class(cls))
34
+ add_class cls
22
35
  else
23
- removeClass cls
36
+ remove_class cls
24
37
  end
25
38
  end
26
39
  end
@@ -1,35 +1,105 @@
1
1
  require 'native'
2
-
3
2
  module DOM
3
+ # Dimensions module for returning node like elements position on the screen.
4
+ #
5
+ # Features:
6
+ # * Accessors for *top*, *left*, *right*, *bottom*, width and height
7
+ # * Positions are compensated with *scroll* *position*
4
8
  module Dimensions
5
-
9
+ # Returns the top position of the element
10
+ #
11
+ # @return [Number] The top position
6
12
  def top
7
- `#{clientRect}.top` + Window.scrollY
13
+ `#{client_rect}.top` + Window.scroll_y
8
14
  end
9
15
 
16
+ # Returns the left position of the element
17
+ #
18
+ # @return [Number] The left position
10
19
  def left
11
- `#{clientRect}.left` + Window.scrollX
20
+ `#{client_rect}.left` + Window.scroll_x
12
21
  end
13
22
 
23
+ # Returns the right position of the element
24
+ #
25
+ # @return [Number] The right position
14
26
  def right
15
- `#{clientRect}.right` + Window.scrollX
27
+ `#{client_rect}.right` + Window.scroll_x
16
28
  end
17
29
 
30
+ # Returns the bottom position of the element
31
+ #
32
+ # @return [Number] The bottom position
18
33
  def bottom
19
- `#{clientRect}.bottom` + Window.scrollY
34
+ `#{client_rect}.bottom` + Window.scroll_y
20
35
  end
21
36
 
37
+ # Returns the width of the element
38
+ #
39
+ # @return [Number] The width
22
40
  def width
23
- `#{clientRect}.width`
41
+ `#{client_rect}.width`
24
42
  end
25
43
 
44
+ # Returns the height of the element
45
+ #
46
+ # @return [Number] The height
26
47
  def height
27
- `#{clientRect}.height`
48
+ `#{client_rect}.height`
49
+ end
50
+
51
+ # Returns the top scroll position of the element
52
+ #
53
+ # @return [Number] The height
54
+ def scroll_top
55
+ `#{@el}.scrollTop`
56
+ end
57
+
58
+ # Returns the left scroll position of the element
59
+ #
60
+ # @return [Number] The height
61
+ def scroll_left
62
+ `#{@el}.scrollLeft`
63
+ end
64
+
65
+ # Returns whether or not the element covers the given position
66
+ #
67
+ # @param pos [Point] The point
68
+ #
69
+ # @return [Boolean] True if covers false if not
70
+ def cover?(pos)
71
+ (left...(left + width)).cover?(pos.x) && (top...(top + height)).cover?(pos.y)
72
+ end
73
+
74
+ # Returns if the element is visible or not.
75
+ #
76
+ # The element is visible if:
77
+ # * The size is 0
78
+ # * display: none
79
+ # * Element not in the dom
80
+ # * Width & Height set to 0
81
+ # * It is outside of the viewport
82
+ #
83
+ # The following is not checked because the element is still visible in a sense
84
+ # because it has a width & height but it is transparent.
85
+ # * opacity: 0
86
+ # * visibility: hidden
87
+ #
88
+ # @return [Boolean] True if visible, false if not
89
+ def visible?
90
+ size_visible = width > 0 && height > 0
91
+ vert_visible = ((`#{client_rect}.top` + height) > 0) && `#{client_rect}.top` < `window.innerHeight`
92
+ horiz_visible = ((`#{client_rect}.left` + width) > 0) && `#{client_rect}.left` < `window.innerWidth`
93
+
94
+ size_visible && vert_visible && horiz_visible
28
95
  end
29
96
 
30
97
  private
31
98
 
32
- def clientRect
99
+ # Gets the bounding client rect of element.
100
+ #
101
+ # @return [Hash] The rect
102
+ def client_rect
33
103
  `#{@el}.getBoundingClientRect()`
34
104
  end
35
105
  end
@@ -0,0 +1,35 @@
1
+ module DOM
2
+ # Element accessor methods
3
+ module ElementAccessor
4
+ # Defines a method that is delegated to the
5
+ # underlying element.
6
+ #
7
+ # @param method [Symbol] The name of the method
8
+ def element_method(method)
9
+ define_method method do
10
+ `#{@el}[#{method}]()`
11
+ end
12
+ end
13
+
14
+ # Defines a property accessor that is delegated to the
15
+ # underlying element.
16
+ #
17
+ # Options:
18
+ # * **as** - Use this instead of the property as identifier
19
+ # * **default** - Return this value if the property is null or undefined
20
+ #
21
+ # @param property [Symbol] The property
22
+ # @param options [Hash] The options
23
+ def element_accessor(property, options = {})
24
+ options = { as: property, default: nil }.merge!(options)
25
+
26
+ define_method options[:as] do
27
+ `#{@el}[#{property}] || #{options[:default]}`
28
+ end
29
+
30
+ define_method "#{options[:as]}=" do |value|
31
+ `#{@el}[#{property}] = #{value}`
32
+ end
33
+ end
34
+ end
35
+ end
@@ -1,36 +1,71 @@
1
1
  module DOM
2
+ # Events module for managing events for elements and element like nodes (SVG Element for example).
3
+ #
4
+ # Features:
5
+ # * Store event listeners for listing and removal
6
+ # * Shorthand *on* and *on!* for non capture / capture
7
+ # * Triggering event dynamically
2
8
  module Events
9
+ # @return [Hash] The listeners in a hash
3
10
  attr_reader :listeners
4
11
 
12
+ # Triggers an event with the given type and data
13
+ #
14
+ # @param type [String] The type
15
+ # @param data [Hash] The data
5
16
  def trigger(type, data = {})
17
+ data = if data.is_a?(Event)
18
+ data.instance_variable_get('@event')
19
+ elsif data.respond_to?(:to_json)
20
+ `JSON.parse(#{data.to_json})`
21
+ end
6
22
  %x{
7
23
  var event = document.createEvent("HTMLEvents");
8
24
  event.initEvent(#{type}, true, true);
9
- for (key in #{data}) {
10
- value = #{data}[key];
25
+ dat = #{data};
26
+ for (key in dat) {
27
+ value = dat[key];
11
28
  event[key] = value;
12
29
  }
13
30
  #{@el}.dispatchEvent(event);
14
31
  }
15
32
  end
16
33
 
34
+ # Listens on the given type of event with capture
35
+ #
36
+ # @param type [String] The type
37
+ #
38
+ # @yieldparam event [Event] The event
17
39
  def on!(type, &listener)
18
- _on type, true, &listener
40
+ add_listener type, true, &listener
19
41
  end
20
42
 
43
+ # Listens on the given type of event without capture
44
+ #
45
+ # @param type [String] The type
46
+ #
47
+ # @yieldparam event [Event] The event
21
48
  def on(type, &listener)
22
- _on type, &listener
49
+ add_listener type, &listener
23
50
  end
24
51
 
52
+ # Removes events
53
+ #
54
+ # * If type and method given removes the exact event
55
+ # * If only type is given removes events with that type
56
+ # * If no arguments are passed removes all attached events
57
+ #
58
+ # @param type [String] The type
59
+ # @param method [Function] The listener returned from *on*
25
60
  def off(type = nil, method = nil)
26
61
  return unless @listeners
27
62
 
28
- if type == nil
63
+ if type.nil?
29
64
  @listeners.keys.each do |ltype|
30
- removeListeners ltype
65
+ remove_listeners ltype
31
66
  end
32
- elsif method == nil
33
- removeListeners type
67
+ elsif method.nil?
68
+ remove_listeners type
34
69
  else
35
70
  return unless @listeners[type].index(method)
36
71
  @listeners[type].delete method
@@ -39,23 +74,32 @@ module DOM
39
74
  end
40
75
  end
41
76
 
42
- def delegate(type,selector, &listener)
77
+ # Delegates the events with the given type
78
+ # if they match the given selector
79
+ #
80
+ # @param type [String] The type
81
+ # @param selector [type] The selector
82
+ #
83
+ # @yieldparam event [Event] The event
84
+ def delegate(type, selector)
43
85
  on type do |event|
44
- if event.target.matches selector
45
- listener.call event
46
- end
86
+ break unless event.target.matches selector
87
+ yield event
47
88
  end
48
89
  end
49
90
 
50
91
  private
51
92
 
52
- def _on(type, capture = false, &listener)
53
- klass = if defined? self.class::EVENT_TARGET_CLASS
54
- self.class::EVENT_TARGET_CLASS
55
- else
56
- Hash
57
- end
58
- method = `function(e){#{ listener.call Event.new(`e`,klass)}}`
93
+ # Adds an event listener for the given type.
94
+ #
95
+ # @param type [String] The type
96
+ # @param capture [Boolean] To use capture or not
97
+ #
98
+ # @return [Function] The native function for later removal
99
+ #
100
+ # @yieldparam event [Event] The event
101
+ def add_listener(type, capture = false)
102
+ method = `function(e){#{ yield Event.new(`e`)}}`
59
103
 
60
104
  @listeners ||= {}
61
105
  @listeners[type] ||= []
@@ -65,7 +109,10 @@ module DOM
65
109
  method
66
110
  end
67
111
 
68
- def removeListeners(type)
112
+ # Removes all events with the given type
113
+ #
114
+ # @param type [String] The type
115
+ def remove_listeners(type)
69
116
  @listeners[type].each do |method|
70
117
  @listeners[type].delete method
71
118
  `#{@el}.removeEventListener(#{type},#{method})`
@@ -1,111 +1,170 @@
1
1
  require 'native'
2
2
 
3
3
  module DOM
4
+ # Node
4
5
  class NODE
5
- EVENT_TARGET_CLASS = self
6
-
7
6
  include Events
8
7
  include Comparable
9
8
 
9
+ # Returns the ruby instance associated to the node,
10
+ # or creates a new instance if there is none.
11
+ #
12
+ # @param node [Native] The node
13
+ #
14
+ # @return [DOM::NODE] The ruby node
15
+ def self.from_node(node)
16
+ return nil unless node
17
+ instance = `#{node}._instance || Opal.nil`
18
+ return instance if instance && instance.is_a?(DOM::NODE)
19
+ new node
20
+ end
21
+
22
+ # Initializes the node with the given native node
23
+ #
24
+ # @param node [Native] The native node
10
25
  def initialize(node = nil)
11
- raise "A node must be provided!" unless node
12
- raise "Not a HTML Node given!" unless `#{node} instanceof Node`
26
+ fail 'A node must be provided!' unless node
27
+ fail 'Not a HTML Node given!' unless `#{node} instanceof Node`
13
28
  @el = node
29
+ `#{@el}._instance = #{self}`
14
30
  end
15
31
 
16
- # Cloning
17
- # ---------------------------------------
32
+ # Clones the node without child nodes
33
+ #
34
+ # @return [DOM::NODE] The new node
18
35
  def dup
19
36
  self.class.new `#{@el}.cloneNode()`
20
37
  end
21
38
 
39
+ # Clones the node with child nodes
40
+ #
41
+ # @return [DOM::NODE] The new node
22
42
  def dup!
23
43
  self.class.new `#{@el}.cloneNode(true)`
24
44
  end
25
45
 
26
- # Hierarchy
27
- # ---------------------------------------
28
- def parentNode
29
- el = `#{@el}.parentNode || false`
30
- el ? DOM::NODE.new(el) : nil
46
+ # Returns the parent node
47
+ #
48
+ # @return [DOM::NODE] The parent node
49
+ def parent_node
50
+ DOM::Element.from_node `#{@el}.parentNode || Opal.nil`
31
51
  end
32
52
 
53
+ # Returns the parent element
54
+ #
55
+ # @return [DOM::NODE] The parent element
33
56
  def parent
34
- el = `#{@el}.parentElement || false`
35
- el ? DOM::NODE.new(el) : nil
57
+ DOM::Element.from_node `#{@el}.parentElement || Opal.nil`
36
58
  end
37
59
 
60
+ # Removes all the child nodes
38
61
  def empty
39
- children.each { |node| node.remove! }
62
+ children.each(&:remove!)
40
63
  end
41
64
 
65
+ # Returns if the node is empty or not
66
+ #
67
+ # @return [Boolean] True if empty false if not
42
68
  def empty?
43
69
  `#{@el}.childNodes.length === 0`
44
70
  end
45
71
 
72
+ # Returns the child nodes as a NodeList
73
+ #
74
+ # @return [DOM::NodeList] The node list
46
75
  def children
47
76
  NodeList.new `Array.prototype.slice.call(#{@el}.childNodes)`
48
77
  end
49
78
 
50
- # Remove
51
- # ---------------------------------------
79
+ # Removes the given elment from the node
80
+ #
81
+ # @param el [DOM::NODE] The element
52
82
  def remove(el)
53
- `#{@el}.removeChild(#{NODE.getElement el})`
83
+ `#{@el}.removeChild(#{NODE.get_element el})`
54
84
  end
55
85
 
86
+ # Removes self from parent node
56
87
  def remove!
57
88
  return unless parent
58
89
  parent.remove self
59
90
  end
60
91
 
61
- # Hierarchy Manipulation
62
- # ---------------------------------------
63
- def << el
64
- `#{@el}.appendChild(#{NODE.getElement el})`
92
+ # Inserts other node into self
93
+ #
94
+ # @param other [DOM::NODE] The other node
95
+ def <<(other)
96
+ `#{@el}.appendChild(#{NODE.get_element other})`
65
97
  end
66
98
 
67
- def >> el
68
- `#{NODE.getElement el}.appendChild(#{@el})`
99
+ # Inserts self into other node
100
+ #
101
+ # @param other [DOM::NODE] The other node
102
+ def >>(other)
103
+ `#{NODE.get_element other}.appendChild(#{@el})`
69
104
  end
70
105
 
71
- def insertBefore(what,where)
106
+ # Inserts the given node before the other given node
107
+ #
108
+ # @param what [DOM::NODE] The node to insert
109
+ # @param where [DOM::NODE] The other node
110
+ def insert_before(what, where)
72
111
  return what >> self unless where # Fir for firefox...
73
- `#{@el}.insertBefore(#{NODE.getElement what},#{NODE.getElement where})`
112
+ `#{@el}.insertBefore(#{NODE.get_element what},#{NODE.get_element where})`
74
113
  end
75
114
 
76
- # Text manipulation
77
- # ---------------------------------------
115
+ # Returns the text content of the node
116
+ #
117
+ # @return [String] The text content
78
118
  def text
79
119
  `#{@el}.textContent`
80
120
  end
81
121
 
122
+ # Sets the text content of the node with the given value
123
+ #
124
+ # @param text [String] The new value
82
125
  def text=(text)
83
126
  `#{@el}.textContent = #{text}`
84
127
  end
85
128
 
129
+ # Normalizes the node removing extra text nodes
86
130
  def normalize!
87
131
  `#{@el}.normalize()`
88
132
  end
89
133
 
90
- # Comparabe methods
91
- # ---------------------------------------
92
- def ==(obj)
93
- `#{NODE.getElement(obj)} === #{@el}`
134
+ # Compars self with other node
135
+ #
136
+ # @param other [DOM::NODE] Other node
137
+ #
138
+ # @return [Boolean] True if the same false if not
139
+ def ==(other)
140
+ `#{NODE.get_element(other)} === #{@el}`
94
141
  end
95
142
 
96
- def <=>(obj)
97
- if obj == self then return 0 end
98
- if obj.parent != parent then raise 'Nodes not Comparable!' end
99
- obj.index <=> index
143
+ # Compars self position with other node
144
+ #
145
+ # @param other [DOM::NODE] Other node
146
+ #
147
+ # @return [Boolean] The compareable with the other node
148
+ def <=>(other)
149
+ return 0 if other == self
150
+ fail 'Nodes not Comparable!' if other.parent != parent
151
+ other.index <=> index
100
152
  end
101
153
 
154
+ # Returns the index of the node
155
+ #
156
+ # @return [Integer] Zero based index
102
157
  def index
103
- parent.children.index self
158
+ return nil unless parent
159
+ NodeList.new(`Array.prototype.slice.call(#{@el}.parentNode.children)`).index self
104
160
  end
105
161
 
106
- private
107
-
108
- def self.getElement(obj)
162
+ # Gets the native node from the given object
163
+ #
164
+ # @param obj [Object] The object
165
+ #
166
+ # @return [Native] The native node
167
+ def self.get_element(obj)
109
168
  if `#{obj} instanceof Node`
110
169
  obj
111
170
  elsif obj.is_a?(NODE)