fron 0.1.4 → 0.2.0rc1

Sign up to get free protection for your applications and to get access to all the features.
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)