uki 1.0.0

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 (235) hide show
  1. data/.gitignore +7 -0
  2. data/.gitmodules +3 -0
  3. data/LICENSE +20 -0
  4. data/Rakefile +23 -0
  5. data/Readme.rdoc +9 -0
  6. data/VERSION +1 -0
  7. data/bin/uki +102 -0
  8. data/frameworks/jspec/lib/images/bg.png +0 -0
  9. data/frameworks/jspec/lib/images/hr.png +0 -0
  10. data/frameworks/jspec/lib/images/loading.gif +0 -0
  11. data/frameworks/jspec/lib/images/sprites.bg.png +0 -0
  12. data/frameworks/jspec/lib/images/sprites.png +0 -0
  13. data/frameworks/jspec/lib/images/vr.png +0 -0
  14. data/frameworks/jspec/lib/jspec.css +149 -0
  15. data/frameworks/jspec/lib/jspec.growl.js +115 -0
  16. data/frameworks/jspec/lib/jspec.jquery.js +72 -0
  17. data/frameworks/jspec/lib/jspec.js +1756 -0
  18. data/frameworks/jspec/lib/jspec.shell.js +39 -0
  19. data/frameworks/jspec/lib/jspec.timers.js +90 -0
  20. data/frameworks/jspec/lib/jspec.xhr.js +195 -0
  21. data/frameworks/uki/README.rdoc +179 -0
  22. data/frameworks/uki/compiler.jar +0 -0
  23. data/frameworks/uki/run.rb +2 -0
  24. data/frameworks/uki/spec/commands/example_command.rb +19 -0
  25. data/frameworks/uki/spec/dom.html +39 -0
  26. data/frameworks/uki/spec/support/images/bg.png +0 -0
  27. data/frameworks/uki/spec/support/images/hr.png +0 -0
  28. data/frameworks/uki/spec/support/images/loading.gif +0 -0
  29. data/frameworks/uki/spec/support/images/sprites.bg.png +0 -0
  30. data/frameworks/uki/spec/support/images/sprites.png +0 -0
  31. data/frameworks/uki/spec/support/images/vr.png +0 -0
  32. data/frameworks/uki/spec/support/jspec.css +149 -0
  33. data/frameworks/uki/spec/support/jspec.js +1773 -0
  34. data/frameworks/uki/spec/support/jspec.xhr.js +193 -0
  35. data/frameworks/uki/spec/support/spec.helper.js +1 -0
  36. data/frameworks/uki/spec/unit/background.spec.js +29 -0
  37. data/frameworks/uki/spec/unit/builder.spec.js +51 -0
  38. data/frameworks/uki/spec/unit/data/model.spec.js +29 -0
  39. data/frameworks/uki/spec/unit/dom/dnd.spec.js +71 -0
  40. data/frameworks/uki/spec/unit/dom/event.spec.js +78 -0
  41. data/frameworks/uki/spec/unit/dom.spec.js +28 -0
  42. data/frameworks/uki/spec/unit/geometry.spec.js +79 -0
  43. data/frameworks/uki/spec/unit/selector.spec.js +140 -0
  44. data/frameworks/uki/spec/unit/theme/template.spec.js +31 -0
  45. data/frameworks/uki/spec/unit/utils.spec.js +176 -0
  46. data/frameworks/uki/spec/unit/view/base.spec.js +86 -0
  47. data/frameworks/uki/spec/unit/view/container.spec.js +73 -0
  48. data/frameworks/uki/spec/unit/view.spec.js +13 -0
  49. data/frameworks/uki/src/airport.js +1 -0
  50. data/frameworks/uki/src/uki-core/attachment.js +175 -0
  51. data/frameworks/uki/src/uki-core/background/css.js +37 -0
  52. data/frameworks/uki/src/uki-core/background/cssBox.js +73 -0
  53. data/frameworks/uki/src/uki-core/background/multi.js +20 -0
  54. data/frameworks/uki/src/uki-core/background/null.js +10 -0
  55. data/frameworks/uki/src/uki-core/background/rows.js +77 -0
  56. data/frameworks/uki/src/uki-core/background/sliced9.js +206 -0
  57. data/frameworks/uki/src/uki-core/background.js +35 -0
  58. data/frameworks/uki/src/uki-core/builder.js +68 -0
  59. data/frameworks/uki/src/uki-core/collection.js +278 -0
  60. data/frameworks/uki/src/uki-core/const.js +17 -0
  61. data/frameworks/uki/src/uki-core/dom/dnd.js +93 -0
  62. data/frameworks/uki/src/uki-core/dom/event.js +194 -0
  63. data/frameworks/uki/src/uki-core/dom/nativeLayout.js +18 -0
  64. data/frameworks/uki/src/uki-core/dom/offset.js +130 -0
  65. data/frameworks/uki/src/uki-core/dom/w3cdnd.js +333 -0
  66. data/frameworks/uki/src/uki-core/dom.js +109 -0
  67. data/frameworks/uki/src/uki-core/geometry.js +658 -0
  68. data/frameworks/uki/src/uki-core/image.js +90 -0
  69. data/frameworks/uki/src/uki-core/selector.js +201 -0
  70. data/frameworks/uki/src/uki-core/theme/base.js +39 -0
  71. data/frameworks/uki/src/uki-core/theme/template.js +26 -0
  72. data/frameworks/uki/src/uki-core/theme.js +45 -0
  73. data/frameworks/uki/src/uki-core/uki.js +45 -0
  74. data/frameworks/uki/src/uki-core/utils.js +399 -0
  75. data/frameworks/uki/src/uki-core/view/base.js +480 -0
  76. data/frameworks/uki/src/uki-core/view/container.js +155 -0
  77. data/frameworks/uki/src/uki-core/view/focusable.js +93 -0
  78. data/frameworks/uki/src/uki-core/view/observable.js +66 -0
  79. data/frameworks/uki/src/uki-core/view/styleable.js +70 -0
  80. data/frameworks/uki/src/uki-core/view/utils.js +66 -0
  81. data/frameworks/uki/src/uki-core/view.js +21 -0
  82. data/frameworks/uki/src/uki-core.js +36 -0
  83. data/frameworks/uki/src/uki-data/data.js +1 -0
  84. data/frameworks/uki/src/uki-data/model.js +28 -0
  85. data/frameworks/uki/src/uki-data/observable.js +34 -0
  86. data/frameworks/uki/src/uki-data.js +1 -0
  87. data/frameworks/uki/src/uki-more/more/utils.js +20 -0
  88. data/frameworks/uki/src/uki-more/more/view/listContainer.js +4 -0
  89. data/frameworks/uki/src/uki-more/more/view/multiselectList.js +196 -0
  90. data/frameworks/uki/src/uki-more/more/view/radioButton.js +27 -0
  91. data/frameworks/uki/src/uki-more/more/view/splitTable.js +79 -0
  92. data/frameworks/uki/src/uki-more/more/view/toggleButton.js +24 -0
  93. data/frameworks/uki/src/uki-more/more/view/treeList/render.js +53 -0
  94. data/frameworks/uki/src/uki-more/more/view/treeList.js +110 -0
  95. data/frameworks/uki/src/uki-more/more/view.js +2 -0
  96. data/frameworks/uki/src/uki-more/more.js +1 -0
  97. data/frameworks/uki/src/uki-more.js +4 -0
  98. data/frameworks/uki/src/uki-theamless.js +15 -0
  99. data/frameworks/uki/src/uki-theme/airport/i/button/down-c.gif +0 -0
  100. data/frameworks/uki/src/uki-theme/airport/i/button/down-c.png +0 -0
  101. data/frameworks/uki/src/uki-theme/airport/i/button/down-h.gif +0 -0
  102. data/frameworks/uki/src/uki-theme/airport/i/button/down-h.png +0 -0
  103. data/frameworks/uki/src/uki-theme/airport/i/button/down-m.png +0 -0
  104. data/frameworks/uki/src/uki-theme/airport/i/button/down-v.png +0 -0
  105. data/frameworks/uki/src/uki-theme/airport/i/button/focusRing-c.png +0 -0
  106. data/frameworks/uki/src/uki-theme/airport/i/button/focusRing-h.png +0 -0
  107. data/frameworks/uki/src/uki-theme/airport/i/button/focusRing-m.png +0 -0
  108. data/frameworks/uki/src/uki-theme/airport/i/button/focusRing-v.png +0 -0
  109. data/frameworks/uki/src/uki-theme/airport/i/button/focusRing.png +0 -0
  110. data/frameworks/uki/src/uki-theme/airport/i/button/hover-c.gif +0 -0
  111. data/frameworks/uki/src/uki-theme/airport/i/button/hover-c.png +0 -0
  112. data/frameworks/uki/src/uki-theme/airport/i/button/hover-h.gif +0 -0
  113. data/frameworks/uki/src/uki-theme/airport/i/button/hover-h.png +0 -0
  114. data/frameworks/uki/src/uki-theme/airport/i/button/hover-m.png +0 -0
  115. data/frameworks/uki/src/uki-theme/airport/i/button/hover-v.png +0 -0
  116. data/frameworks/uki/src/uki-theme/airport/i/button/hover.png +0 -0
  117. data/frameworks/uki/src/uki-theme/airport/i/button/normal-c.gif +0 -0
  118. data/frameworks/uki/src/uki-theme/airport/i/button/normal-c.png +0 -0
  119. data/frameworks/uki/src/uki-theme/airport/i/button/normal-h.gif +0 -0
  120. data/frameworks/uki/src/uki-theme/airport/i/button/normal-h.png +0 -0
  121. data/frameworks/uki/src/uki-theme/airport/i/button/normal-m.png +0 -0
  122. data/frameworks/uki/src/uki-theme/airport/i/button/normal-v.png +0 -0
  123. data/frameworks/uki/src/uki-theme/airport/i/button/normal.png +0 -0
  124. data/frameworks/uki/src/uki-theme/airport/i/checkbox/checkbox.png +0 -0
  125. data/frameworks/uki/src/uki-theme/airport/i/checkbox/focus.png +0 -0
  126. data/frameworks/uki/src/uki-theme/airport/i/checkbox/normal.gif +0 -0
  127. data/frameworks/uki/src/uki-theme/airport/i/checkbox/normal.png +0 -0
  128. data/frameworks/uki/src/uki-theme/airport/i/panel/dark-h.gif +0 -0
  129. data/frameworks/uki/src/uki-theme/airport/i/panel/dark-h.png +0 -0
  130. data/frameworks/uki/src/uki-theme/airport/i/panel/dark-m.png +0 -0
  131. data/frameworks/uki/src/uki-theme/airport/i/panel/dark.png +0 -0
  132. data/frameworks/uki/src/uki-theme/airport/i/popup/normal.png +0 -0
  133. data/frameworks/uki/src/uki-theme/airport/i/radio/focus.png +0 -0
  134. data/frameworks/uki/src/uki-theme/airport/i/radio/normal.gif +0 -0
  135. data/frameworks/uki/src/uki-theme/airport/i/radio/normal.png +0 -0
  136. data/frameworks/uki/src/uki-theme/airport/i/radio/radio.png +0 -0
  137. data/frameworks/uki/src/uki-theme/airport/i/shadow/large-c.png +0 -0
  138. data/frameworks/uki/src/uki-theme/airport/i/shadow/large-h.png +0 -0
  139. data/frameworks/uki/src/uki-theme/airport/i/shadow/large-m.png +0 -0
  140. data/frameworks/uki/src/uki-theme/airport/i/shadow/large-v.png +0 -0
  141. data/frameworks/uki/src/uki-theme/airport/i/shadow/large.png +0 -0
  142. data/frameworks/uki/src/uki-theme/airport/i/slider/bar-m.gif +0 -0
  143. data/frameworks/uki/src/uki-theme/airport/i/slider/bar-m.png +0 -0
  144. data/frameworks/uki/src/uki-theme/airport/i/slider/bar-v.gif +0 -0
  145. data/frameworks/uki/src/uki-theme/airport/i/slider/bar-v.png +0 -0
  146. data/frameworks/uki/src/uki-theme/airport/i/slider/bar.png +0 -0
  147. data/frameworks/uki/src/uki-theme/airport/i/slider/focus.png +0 -0
  148. data/frameworks/uki/src/uki-theme/airport/i/slider/handle.gif +0 -0
  149. data/frameworks/uki/src/uki-theme/airport/i/splitPane/horizontal.gif +0 -0
  150. data/frameworks/uki/src/uki-theme/airport/i/splitPane/horizontal.png +0 -0
  151. data/frameworks/uki/src/uki-theme/airport/i/splitPane/vertical.gif +0 -0
  152. data/frameworks/uki/src/uki-theme/airport/i/x.gif +0 -0
  153. data/frameworks/uki/src/uki-theme/airport.js +322 -0
  154. data/frameworks/uki/src/uki-theme/aristo/i/button/down-c.gif +0 -0
  155. data/frameworks/uki/src/uki-theme/aristo/i/button/down-c.png +0 -0
  156. data/frameworks/uki/src/uki-theme/aristo/i/button/down-h.png +0 -0
  157. data/frameworks/uki/src/uki-theme/aristo/i/button/down-m.png +0 -0
  158. data/frameworks/uki/src/uki-theme/aristo/i/button/down-v.png +0 -0
  159. data/frameworks/uki/src/uki-theme/aristo/i/button/down.png +0 -0
  160. data/frameworks/uki/src/uki-theme/aristo/i/button/focusRing-c.png +0 -0
  161. data/frameworks/uki/src/uki-theme/aristo/i/button/focusRing-h.png +0 -0
  162. data/frameworks/uki/src/uki-theme/aristo/i/button/focusRing-m.png +0 -0
  163. data/frameworks/uki/src/uki-theme/aristo/i/button/focusRing-v.png +0 -0
  164. data/frameworks/uki/src/uki-theme/aristo/i/button/focusRing.png +0 -0
  165. data/frameworks/uki/src/uki-theme/aristo/i/button/normal-c.gif +0 -0
  166. data/frameworks/uki/src/uki-theme/aristo/i/button/normal-c.png +0 -0
  167. data/frameworks/uki/src/uki-theme/aristo/i/button/normal-h.png +0 -0
  168. data/frameworks/uki/src/uki-theme/aristo/i/button/normal-m.png +0 -0
  169. data/frameworks/uki/src/uki-theme/aristo/i/button/normal-v.png +0 -0
  170. data/frameworks/uki/src/uki-theme/aristo/i/button/normal.png +0 -0
  171. data/frameworks/uki/src/uki-theme/aristo/i/checkbox/focus.png +0 -0
  172. data/frameworks/uki/src/uki-theme/aristo/i/checkbox/normal.gif +0 -0
  173. data/frameworks/uki/src/uki-theme/aristo/i/checkbox/normal.png +0 -0
  174. data/frameworks/uki/src/uki-theme/aristo/i/panel/normal-h.png +0 -0
  175. data/frameworks/uki/src/uki-theme/aristo/i/panel/normal-m.png +0 -0
  176. data/frameworks/uki/src/uki-theme/aristo/i/panel/normal.png +0 -0
  177. data/frameworks/uki/src/uki-theme/aristo/i/popup/normal.png +0 -0
  178. data/frameworks/uki/src/uki-theme/aristo/i/radio/focus.png +0 -0
  179. data/frameworks/uki/src/uki-theme/aristo/i/radio/normal.gif +0 -0
  180. data/frameworks/uki/src/uki-theme/aristo/i/radio/normal.png +0 -0
  181. data/frameworks/uki/src/uki-theme/aristo/i/shadow/large-c.png +0 -0
  182. data/frameworks/uki/src/uki-theme/aristo/i/shadow/large-h.png +0 -0
  183. data/frameworks/uki/src/uki-theme/aristo/i/shadow/large-m.png +0 -0
  184. data/frameworks/uki/src/uki-theme/aristo/i/shadow/large-v.png +0 -0
  185. data/frameworks/uki/src/uki-theme/aristo/i/shadow/large.png +0 -0
  186. data/frameworks/uki/src/uki-theme/aristo/i/slider/bar-m.gif +0 -0
  187. data/frameworks/uki/src/uki-theme/aristo/i/slider/bar-m.png +0 -0
  188. data/frameworks/uki/src/uki-theme/aristo/i/slider/bar-v.gif +0 -0
  189. data/frameworks/uki/src/uki-theme/aristo/i/slider/bar-v.png +0 -0
  190. data/frameworks/uki/src/uki-theme/aristo/i/slider/bar.png +0 -0
  191. data/frameworks/uki/src/uki-theme/aristo/i/slider/handle.gif +0 -0
  192. data/frameworks/uki/src/uki-theme/aristo/i/slider/handle.png +0 -0
  193. data/frameworks/uki/src/uki-theme/aristo/i/splitPane/horizontal.gif +0 -0
  194. data/frameworks/uki/src/uki-theme/aristo/i/splitPane/horizontal.png +0 -0
  195. data/frameworks/uki/src/uki-theme/aristo/i/splitPane/vertical.gif +0 -0
  196. data/frameworks/uki/src/uki-theme/aristo/i/x.gif +0 -0
  197. data/frameworks/uki/src/uki-theme/aristo.js +217 -0
  198. data/frameworks/uki/src/uki-view/view/box.js +1 -0
  199. data/frameworks/uki/src/uki-view/view/button.js +126 -0
  200. data/frameworks/uki/src/uki-view/view/checkbox.js +36 -0
  201. data/frameworks/uki/src/uki-view/view/flow.js +48 -0
  202. data/frameworks/uki/src/uki-view/view/image.js +9 -0
  203. data/frameworks/uki/src/uki-view/view/label.js +123 -0
  204. data/frameworks/uki/src/uki-view/view/list/render.js +23 -0
  205. data/frameworks/uki/src/uki-view/view/list.js +442 -0
  206. data/frameworks/uki/src/uki-view/view/popup.js +113 -0
  207. data/frameworks/uki/src/uki-view/view/radio.js +57 -0
  208. data/frameworks/uki/src/uki-view/view/scrollPane.js +139 -0
  209. data/frameworks/uki/src/uki-view/view/slider.js +154 -0
  210. data/frameworks/uki/src/uki-view/view/splitPane.js +213 -0
  211. data/frameworks/uki/src/uki-view/view/table/column.js +96 -0
  212. data/frameworks/uki/src/uki-view/view/table/header.js +53 -0
  213. data/frameworks/uki/src/uki-view/view/table/render.js +25 -0
  214. data/frameworks/uki/src/uki-view/view/table.js +71 -0
  215. data/frameworks/uki/src/uki-view/view/textField.js +145 -0
  216. data/frameworks/uki/src/uki-view/view/toolbar.js +93 -0
  217. data/frameworks/uki/src/uki-view.js +15 -0
  218. data/frameworks/uki/src/uki.js +2 -0
  219. data/frameworks/uki/thin.yaml +11 -0
  220. data/frameworks/uki/uki.rb +38 -0
  221. data/frameworks/uki/uki.ru +2 -0
  222. data/lib/uki/include_js.rb +50 -0
  223. data/lib/uki/project.rb +207 -0
  224. data/lib/uki/routes.rb +20 -0
  225. data/lib/uki/server.rb +42 -0
  226. data/lib/uki.rb +9 -0
  227. data/templates/index.html.erb +10 -0
  228. data/templates/model.js.erb +5 -0
  229. data/templates/myapp.js.erb +44 -0
  230. data/templates/package.js.erb +3 -0
  231. data/templates/spec.html.erb +23 -0
  232. data/templates/spec.js.erb +6 -0
  233. data/templates/view.js.erb +10 -0
  234. data/uki.gemspec +281 -0
  235. metadata +317 -0
@@ -0,0 +1,399 @@
1
+ include('uki.js');
2
+
3
+ var toString = Object.prototype.toString,
4
+ trim = String.prototype.trim,
5
+
6
+ trimRe = /^\s+|\s+$/g;
7
+
8
+ var marked = '__uki_marked';
9
+
10
+ var utils =
11
+ /**
12
+ * Utility functions. Can be called both as uki.utils.function or uki.function
13
+ * @namespace
14
+ */
15
+ uki.utils = {
16
+
17
+ /**
18
+ * Sets or retrieves attribute on an object.
19
+ * <p>If target has function with attr it will be called target[attr](value=)
20
+ * If no function present attribute will be set/get directly: target[attr] = value or return target[attr]</p>
21
+ *
22
+ * @example
23
+ * uki.attr(view, 'name', 'funny') // sets name to funny on view
24
+ * uki.attr(view, 'id') // gets id attribute of view
25
+ *
26
+ * @param {object} target
27
+ * @param {string} attr Attribute name
28
+ * @param {object=} value Value to set
29
+ * @returns {object} target if value is being set, retrieved value otherwise
30
+ */
31
+ attr: function(target, attr, value) {
32
+ if (value !== undefined) {
33
+ // if (target[attr].apply) {
34
+ if (utils.isFunction(target[attr])) {
35
+ target[attr](value);
36
+ } else {
37
+ target[attr] = value;
38
+ }
39
+ return target;
40
+ } else {
41
+ // if (target[attr].apply) {
42
+ if (utils.isFunction(target[attr])) {
43
+ return target[attr]();
44
+ } else {
45
+ return target[attr];
46
+ }
47
+ }
48
+ },
49
+
50
+ /**
51
+ * Runs a function in a given context
52
+ *
53
+ * @param {function()} fn
54
+ * @param {object} context
55
+ */
56
+ proxy: function(fn, context) {
57
+ return function() {
58
+ return fn.apply(context, arguments);
59
+ }
60
+ },
61
+
62
+ /**
63
+ * Checks if obj is a function
64
+ *
65
+ * @param {object} object Object to check
66
+ * @returns {boolean}
67
+ */
68
+ isFunction: function( obj ) {
69
+ return toString.call(obj) === "[object Function]";
70
+ },
71
+
72
+ /**
73
+ * Checks if obj is an Array
74
+ *
75
+ * @param {object} object Object to check
76
+ * @returns {boolean}
77
+ */
78
+ isArray: function( obj ) {
79
+ return toString.call(obj) === "[object Array]";
80
+ },
81
+
82
+ /**
83
+ * Trims the string
84
+ *
85
+ * @param {string} text
86
+ * @returns {string} trimmed text
87
+ */
88
+ trim: function( text ) {
89
+ text = text || '';
90
+ return trim ? trim.call(text) : text.replace( trimRe, "" );
91
+ },
92
+
93
+ /**
94
+ * Converts unsafe symbols to entities
95
+ *
96
+ * @param {string} html
97
+ * @returns {string} escaped html
98
+ */
99
+ escapeHTML: function( html ) {
100
+ var trans = {
101
+ '&': '&amp;',
102
+ '<': '&lt;',
103
+ '>': '&gt;',
104
+ '"': '&quot;',
105
+ "'": '&#x27;'
106
+ };
107
+ return html.replace(/[&<>\"\']/g, function(c) { return trans[c]; });
108
+ },
109
+
110
+ /**
111
+ * Iterates through all non empty values of object or an Array
112
+ *
113
+ * @param {object|Array} object Object to iterate through
114
+ * @param {function(number, object):boolean} callback Called for every item, may return false to stop iteration
115
+ * @param {object} context Context in which callback should called. If not specified context will be set to
116
+ * current item
117
+ * @returns {object}
118
+ */
119
+ each: function( object, callback, context ) {
120
+ var name, i = 0, length = object.length;
121
+
122
+ if ( length === undefined ) {
123
+ for ( name in object ) {
124
+ if ( !name || object[ name ] === undefined || !object.hasOwnProperty(name) ) continue;
125
+ if ( callback.call( context || object[ name ], name, object[ name ] ) === false ) { break; }
126
+ }
127
+ } else {
128
+ for ( var value = object[0]; i < length && callback.call( context || value, i, value ) !== false; value = object[++i] ){}
129
+ }
130
+ return object;
131
+ },
132
+
133
+ /**
134
+ * Checks if elem is in array
135
+ *
136
+ * @param {object} elem
137
+ * @param {object} array
138
+ * @returns {boolean}
139
+ */
140
+ inArray: function( elem, array ) {
141
+ for ( var i = 0, length = array.length; i < length; i++ ) {
142
+ if ( array[ i ] === elem ) { return i; }
143
+ }
144
+
145
+ return -1;
146
+ },
147
+
148
+ /**
149
+ * Returns unique elements in array
150
+ *
151
+ * @param {Array} array
152
+ * @returns {Array}
153
+ */
154
+ unique: function( array ) {
155
+ if (array.length && (typeof array[0] == 'object' || typeof array[0] == 'function')) {
156
+ var result = [],
157
+ i;
158
+
159
+ for (i = 0; i < array.length; i++) {
160
+ if (!array[i][marked]) { result[result.length] = array[i]; }
161
+ array[i][marked] = true;
162
+ };
163
+ for (i = 0; i < result.length; i++) {
164
+ delete result[i][marked]
165
+ };
166
+ return result;
167
+
168
+ } else {
169
+
170
+ var ret = [],
171
+ done = {};
172
+
173
+ for ( var i = 0, length = array.length; i < length; i++ ) {
174
+ var id = array[ i ];
175
+
176
+ if ( !done[ id ] ) {
177
+ done[ id ] = true;
178
+ ret.push( array[ i ] );
179
+ }
180
+ }
181
+
182
+ return ret;
183
+ }
184
+ },
185
+
186
+ /**
187
+ * Searches for all items matching given criteria
188
+ *
189
+ * @param {Array} elems Element to search through
190
+ * @param {function(object, number)} callback Returns true for every matched element
191
+ * @returns {Array} matched elements
192
+ */
193
+ grep: function( elems, callback ) {
194
+ var ret = [];
195
+
196
+ for ( var i = 0, length = elems.length; i < length; i++ ) {
197
+ if ( callback( elems[ i ], i ) ) { ret.push( elems[ i ] ); }
198
+ }
199
+
200
+ return ret;
201
+ },
202
+
203
+ /**
204
+ * Maps elements passing them to callback
205
+ * @example
206
+ * x = uki.map([1, 2, 3], function(item) { return -item });
207
+ *
208
+ * @param {Array} elems Elements to map
209
+ * @param {function(object, number)} mapping function
210
+ * @param {object} context Context in which callback should called. If not specified context will be set to
211
+ * current item
212
+ * @returns {Array} mapped values
213
+ */
214
+ map: function( elems, callback, context ) {
215
+ var ret = [],
216
+ mapper = utils.isFunction(callback) ? callback :
217
+ function(e) { return utils.attr(e, callback); };
218
+
219
+ for ( var i = 0, length = elems.length; i < length; i++ ) {
220
+ var value = mapper.call( context || elems[ i ], elems[ i ], i );
221
+
222
+ if ( value != null ) { ret[ ret.length ] = value; }
223
+ }
224
+
225
+ return ret;
226
+ },
227
+
228
+ /**
229
+ * Reduces array
230
+ * @example
231
+ * x = uki.reduce(1, [1, 2, 3], function(p, x) { return p * x}) // calculates product
232
+ *
233
+ * @param {object} initial Initial value
234
+ * @param {Array} elems Elements to reduce
235
+ * @param {function(object, number)} reduce function
236
+ * @param {object} context Context in which callback should called. If not specified context will be set to
237
+ * current item
238
+ * @returns {object}
239
+ */
240
+ reduce: function( initial, elems, callback, context ) {
241
+ for ( var i = 0, length = elems.length; i < length; i++ ) {
242
+ initial = callback.call( context || elems[ i ], initial, elems[ i ], i );
243
+ }
244
+ return initial;
245
+ },
246
+
247
+ /**
248
+ * Copies properties from one object to another
249
+ * @example
250
+ * uki.extend(x, { width: 13, height: 14 }) // sets x.width = 13, x.height = 14
251
+ * options = uki.extend({}, defaultOptions, options)
252
+ *
253
+ * @param {object} target Object to copy properties into
254
+ * @param {...object} sources Objects to take properties from
255
+ * @returns Describe what it returns
256
+ */
257
+ extend: function() {
258
+ var target = arguments[0] || {}, i = 1, length = arguments.length, options;
259
+
260
+ for ( ; i < length; i++ ) {
261
+ if ( (options = arguments[i]) != null ) {
262
+
263
+ for ( var name in options ) {
264
+ var copy = options[ name ];
265
+
266
+ if ( copy !== undefined ) {
267
+ target[ name ] = copy;
268
+ }
269
+
270
+ }
271
+ }
272
+ }
273
+
274
+ return target;
275
+ },
276
+
277
+ /**
278
+ * Creates a new class inherited from base classes. Init function is used as constructor
279
+ * @example
280
+ * baseClass = uki.newClass({
281
+ * init: function() { this.x = 3 }
282
+ * });
283
+ *
284
+ * childClass = uki.newClass(baseClass, {
285
+ * getSqrt: function() { return this.x*this.x }
286
+ * });
287
+ *
288
+ * @param {object=} superClass If superClass has prototype "real" prototype base inheritance is used,
289
+ * otherwise superClass properties are simply copied to newClass prototype
290
+ * @param {Array.<object>=} mixins
291
+ * @param {object} methods
292
+ * @returns Describe what it returns
293
+ */
294
+ newClass: function(/* [[superClass], mixin1, mixin2, ..] */ methods) {
295
+ var klass = function() {
296
+ this.init.apply(this, arguments);
297
+ };
298
+
299
+ var inheritance, i, startFrom = 0, tmp, baseClasses = [];
300
+
301
+ if (arguments.length > 1) {
302
+ if (arguments[0].prototype) { // real inheritance
303
+ /** @ignore */
304
+ inheritance = function() {};
305
+ inheritance.prototype = arguments[0].prototype;
306
+ klass.prototype = new inheritance();
307
+ startFrom = 1;
308
+ baseClasses = [inheritance.prototype];
309
+ }
310
+ }
311
+ for (i=startFrom; i < arguments.length; i++) {
312
+ tmp = arguments[i];
313
+ if (this.isFunction(tmp)) tmp = tmp.apply(tmp, baseClasses);
314
+ baseClasses.push(tmp);
315
+ utils.extend(klass.prototype, arguments[i]);
316
+ };
317
+ if (!klass.prototype.init) klass.prototype.init = function() {};
318
+ return klass;
319
+ },
320
+
321
+ /**
322
+ * Search closest value in a sorted array
323
+ * @param {nubmer} value to search
324
+ * @param {array} array sorted array
325
+ * @returns {number} index of closest value
326
+ */
327
+ binarySearch: function (value, array) {
328
+ var low = 0, high = array.length, mid;
329
+ while (low < high) {
330
+ mid = (low + high) >> 1;
331
+ array[mid] < value ? low = mid + 1 : high = mid;
332
+ }
333
+ return low;
334
+ },
335
+
336
+
337
+ /**
338
+ * Creates default uki property function
339
+ * <p>If value is given to this function it sets property to value
340
+ * If no arguments given than function returns current property value</p>
341
+ *
342
+ * <p>Optional setter can be given. In this case setter will be called instead
343
+ * of simple this[field] = value</p>
344
+ *
345
+ * <p>If used as setter function returns self</p>
346
+ *
347
+ * @example
348
+ * x.width = uki.newProperty('_width');
349
+ * x.width(12); // x._width = 12
350
+ * x.width(); // return 12
351
+ *
352
+ * @param {string} field Field name
353
+ * @param {function(object)=} setter
354
+ * @returns {function(object=):object}
355
+ */
356
+ newProp: function(field, setter) {
357
+ return function(value) {
358
+ if (value === undefined) return this[field];
359
+ if (setter) { setter.call(this, value); } else { this[field] = value; };
360
+ return this;
361
+ };
362
+ },
363
+
364
+ /**
365
+ * Adds several properties (uki.newProp) to a given object.
366
+ * <p>Field name equals to '_' + property name</p>
367
+ *
368
+ * @example
369
+ * uki.addProps(x, ['width', 'height'])
370
+ *
371
+ * @param {object} proto Object to add properties to
372
+ * @param {Array.<string>} props Property names
373
+ */
374
+ addProps: function(proto, props) {
375
+ utils.each(props, function() { proto[this] = utils.newProp('_' + this); });
376
+ },
377
+
378
+ toArray: function(arr) {
379
+ return Array.prototype.slice.call(arr, 0);
380
+ },
381
+
382
+ delegateProp: function(proto, name, target) {
383
+ var propName = '_' + name;
384
+ proto[name] = function(value) {
385
+ if (value === undefined) {
386
+ if (this[target]) return utils.attr(this[target], name, value);
387
+ return this[propName];
388
+ }
389
+ if (this[target]) {
390
+ utils.attr(this[target], name, value);
391
+ } else {
392
+ this[propName] = value;
393
+ }
394
+ return this;
395
+ };
396
+ }
397
+ };
398
+
399
+ utils.extend(uki, utils);