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,658 @@
1
+ include('uki.js');
2
+
3
+ /**
4
+ * Geometry
5
+ *
6
+ * @namespace
7
+ */
8
+ uki.geometry = {};
9
+
10
+
11
+ /**
12
+ * Point with x and y properties
13
+ *
14
+ * @author voloko
15
+ * @name uki.geometry.Point
16
+ * @constructor
17
+ *
18
+ * @param {Integer=} x defaults to 0
19
+ * @param {Integer=} y defaults to 0
20
+ */
21
+ var Point = uki.geometry.Point = function(x, y) {
22
+ this.x = x*1.0 || 0.0;
23
+ this.y = y*1.0 || 0.0;
24
+ };
25
+
26
+ Point.prototype = /** @lends uki.geometry.Point.prototype */ {
27
+
28
+ /**
29
+ * Converts to "100 50" string
30
+ *
31
+ * @this {uki.geometry.Point}
32
+ * @return {string}
33
+ */
34
+ toString: function() {
35
+ return this.x + ' ' + this.y;
36
+ },
37
+
38
+ /**
39
+ * Creates a new Point with the same properties
40
+ *
41
+ * @this {uki.geometry.Point}
42
+ * @return {uki.geometry.Point}
43
+ */
44
+ clone: function() {
45
+ return new Point(this.x, this.y);
46
+ },
47
+
48
+ /**
49
+ * Checks if this equals to another Point
50
+ *
51
+ * @param {uki.geometry.Point} point Point to compare with
52
+ * @this {uki.geometry.Point}
53
+ * @return {boolean}
54
+ */
55
+ eq: function(point) {
56
+ return this.x == point.x && this.y == point.y;
57
+ },
58
+
59
+ /**
60
+ * Moves point by x, y
61
+ *
62
+ * @this {uki.geometry.Point}
63
+ * @return {uki.geometry.Point} self
64
+ */
65
+ offset: function(x, y) {
66
+ if (typeof x == 'object') {
67
+ y = x.y;
68
+ x = x.x;
69
+ }
70
+ this.x += x;
71
+ this.y += y;
72
+ return this;
73
+ },
74
+
75
+ constructor: Point
76
+ };
77
+
78
+ /**
79
+ * Creates point from "x y" string
80
+ *
81
+ * @memberOf uki.geometry.Point
82
+ * @name fromString
83
+ * @function
84
+ *
85
+ * @param {string} string String representation of point
86
+ *
87
+ * @returns {uki.geometry.Point} created point
88
+ */
89
+ Point.fromString = function(string) {
90
+ var parts = string.split(/\s+/);
91
+ return new Point( parts[0], parts[1] );
92
+ };
93
+
94
+
95
+ /**
96
+ * Size with width and height properties
97
+ *
98
+ * @param {number=} width defaults to 0
99
+ * @param {number=} height defaults to 0
100
+ * @name uki.geometry.Size
101
+ * @constructor
102
+ */
103
+ var Size = uki.geometry.Size = function(width, height) {
104
+ this.width = width*1.0 || 0.0;
105
+ this.height = height*1.0 || 0.0;
106
+ };
107
+
108
+ Size.prototype = /** @lends uki.geometry.Size.prototype */ {
109
+ /**
110
+ * Converts size to "300 100" string
111
+ *
112
+ * @this {uki.geometry.Size}
113
+ * @return {string}
114
+ */
115
+ toString: function() {
116
+ return this.width + ' ' + this.height;
117
+ },
118
+
119
+ /**
120
+ * Creates a new Size with same properties
121
+ *
122
+ * @this {uki.geometry.Size}
123
+ * @return {uki.geometry.Size} new Size
124
+ */
125
+ clone: function() {
126
+ return new Size(this.width, this.height);
127
+ },
128
+
129
+ /**
130
+ * Checks if this equals to another Size
131
+ *
132
+ * @param {uki.geometry.Size} size Size to compare with
133
+ * @this {uki.geometry.Size}
134
+ * @return {boolean}
135
+ */
136
+ eq: function(size) {
137
+ return this.width == size.width && this.height == size.height;
138
+ },
139
+
140
+ /**
141
+ * Checks if this size has non-positive width or height
142
+ *
143
+ * @this {uki.geometry.Size}
144
+ * @return {boolean}
145
+ */
146
+ empty: function() {
147
+ return this.width <= 0 || this.height <= 0;
148
+ },
149
+
150
+ constructor: Size
151
+ };
152
+
153
+ /**
154
+ * Creates size from "width height" string
155
+ *
156
+ * @memberOf uki.geometry.Size
157
+ * @name fromString
158
+ * @function
159
+ *
160
+ * @param {string} string String representation of size
161
+ *
162
+ * @returns {uki.geometry.Size} created size
163
+ */
164
+ Size.fromString = function(string) {
165
+ var parts = string.split(/\s+/);
166
+ return new Size( parts[0], parts[1] );
167
+ };
168
+
169
+ /**
170
+ * Creates size from different representations
171
+ * - if no params given returns null
172
+ * - if uki.geometry.Size given returns it
173
+ * - if "200 300" string converts it to size
174
+ * - if two params given creates size from them
175
+ *
176
+ * @memberOf uki.geometry.Size
177
+ * @name create
178
+ * @function
179
+ *
180
+ * @param {...string|number|uki.geometry.Size} var_args Size representation
181
+ *
182
+ * @returns {uki.geometry.Size} created size
183
+ */
184
+ Size.create = function(a1, a2) {
185
+ if (a1 === undefined) return null;
186
+ if (a1.width !== undefined) return a1;
187
+ if (/\S+\s+\S+/.test(a1 + '')) return Size.fromString(a1, a2);
188
+ return new Size(a1, a2);
189
+ };
190
+
191
+
192
+ /**
193
+ * Rectangle with x, y, width and height properties
194
+ * May be used as uki.geometry.Point or uki.geometry.Size
195
+ * - if 4 arguments given creates size with x,y,width,height set to the given arguments
196
+ * - if 2 number arguments given creates size with x = y = 0 and width and height set
197
+ * set to the given arguments
198
+ * - if a Point and a Size given creates rect with point as an origin and given size
199
+ *
200
+ * @param {...number|uki.geometry.Point|uki.geometry.Size} var_args
201
+ * @name uki.geometry.Rect
202
+ * @augments uki.geometry.Size
203
+ * @augments uki.geometry.Point
204
+ * @constructor
205
+ */
206
+ var Rect = uki.geometry.Rect = function(a1, a2, a3, a4) {
207
+ if (a3 !== undefined) {
208
+ this.x = a1*1.0 || 0.0;
209
+ this.y = a2*1.0 || 0.0;
210
+ this.width = a3*1.0 || 0.0;
211
+ this.height = a4*1.0 || 0.0;
212
+ } else if (a1 === undefined || a1.x === undefined) {
213
+ this.x = 0;
214
+ this.y = 0;
215
+ this.width = a1*1.0 || 0.0;
216
+ this.height = a2*1.0 || 0.0;
217
+ } else {
218
+ this.x = a1 ? a1.x*1.0 : 0;
219
+ this.y = a1 ? a1.y*1.0 : 0;
220
+ this.width = a2 ? a2.width*1.0 : 0;
221
+ this.height = a2 ? a2.height*1.0 : 0;
222
+ }
223
+ };
224
+
225
+ Rect.prototype = /** @lends uki.geometry.Rect.prototype */ {
226
+ /**
227
+ * Converts Rect to "x y width height" string
228
+ *
229
+ * @this {uki.geometry.Rect}
230
+ * @returns {string}
231
+ */
232
+ toString: function() {
233
+ return [this.x, this.y, this.width, this.height].join(' ');
234
+ },
235
+
236
+ /**
237
+ * Converts Rect to "x y maxX maxY" string
238
+ *
239
+ * @this {uki.geometry.Rect}
240
+ * @returns {string}
241
+ */
242
+ toCoordsString: function() {
243
+ return [this.x, this.y, this.maxX(), this.maxY()].join(' ');
244
+ },
245
+
246
+ /**
247
+ * Creates a new Rect with same properties
248
+ *
249
+ * @this {uki.geometry.Size}
250
+ * @return {uki.geometry.Size} new Size
251
+ */
252
+ clone: function() {
253
+ return new Rect(this.x, this.y, this.width, this.height);
254
+ },
255
+
256
+ /**
257
+ * Equals to .x
258
+ *
259
+ * @this {uki.geometry.Rect}
260
+ * @returns {number}
261
+ */
262
+ minX: function() {
263
+ return this.x;
264
+ },
265
+
266
+ /**
267
+ * Equals to x + width
268
+ *
269
+ * @this {uki.geometry.Rect}
270
+ * @returns {number}
271
+ */
272
+ maxX: function() {
273
+ return this.x + this.width;
274
+ },
275
+
276
+ /**
277
+ * Point between minX and maxX
278
+ *
279
+ * @this {uki.geometry.Rect}
280
+ * @returns {number}
281
+ */
282
+ midX: function() {
283
+ return this.x + this.width / 2.0;
284
+ },
285
+
286
+ /**
287
+ * Equals to .y
288
+ *
289
+ * @this {uki.geometry.Rect}
290
+ * @returns {number}
291
+ */
292
+ minY: function() {
293
+ return this.y;
294
+ },
295
+
296
+ /**
297
+ * Point between minY and maxY
298
+ *
299
+ * @this {uki.geometry.Rect}
300
+ * @returns {number}
301
+ */
302
+ midY: function() {
303
+ return this.y + this.height / 2.0;
304
+ },
305
+
306
+ /**
307
+ * Equals to y + height
308
+ *
309
+ * @this {uki.geometry.Rect}
310
+ * @returns {number}
311
+ */
312
+ maxY: function() {
313
+ return this.y + this.height;
314
+ },
315
+
316
+ /**
317
+ * Moves origin to 0,0 point
318
+ *
319
+ * @this {uki.geometry.Rect}
320
+ * @returns {uki.geometry.Point} self
321
+ */
322
+ normalize: function() {
323
+ this.x = this.y = 0;
324
+ return this;
325
+ },
326
+
327
+ /**
328
+ * Checks if this rect has non-positive width or height
329
+ *
330
+ * @this {uki.geometry.Rect}
331
+ * @function
332
+ * @return {boolean}
333
+ */
334
+ empty: Size.prototype.empty,
335
+
336
+ /**
337
+ * Checks if this equals to another Rect
338
+ *
339
+ * @param {uki.geometry.Rect} rect Rect to compare with
340
+ * @this {uki.geometry.Rect}
341
+ * @return {boolean}
342
+ */
343
+ eq: function(rect) {
344
+ return rect && this.x == rect.x && this.y == rect.y && this.height == rect.height && this.width == rect.width;
345
+ },
346
+
347
+ /**
348
+ * Insets size with dx and dy
349
+ *
350
+ * @param {number} dx
351
+ * @param {number} dy
352
+ * @this {uki.geometry.Rect}
353
+ * @returns {uki.geometry.Rect} sefl
354
+ */
355
+ inset: function(dx, dy) {
356
+ this.x += dx;
357
+ this.y += dy;
358
+ this.width -= dx*2.0;
359
+ this.height -= dy*2.0;
360
+ return this;
361
+ },
362
+
363
+ /**
364
+ * Moves origin point by x, y
365
+ *
366
+ * @this {uki.geometry.Rect}
367
+ * @function
368
+ * @return {uki.geometry.Rect} self
369
+ */
370
+ offset: Point.prototype.offset,
371
+
372
+ /**
373
+ * Intersects this with given rect
374
+ *
375
+ * @this {uki.geometry.Rect}
376
+ * @param {uki.geometry.Rect} rect Rect to intersect with
377
+ * @returns {uki.geometry.Rect} intersection
378
+ */
379
+ intersection: function(rect) {
380
+ var origin = new Point(
381
+ MAX(this.x, rect.x),
382
+ MAX(this.y, rect.y)
383
+ ),
384
+ size = new Size(
385
+ MIN(this.maxX(), rect.maxX()) - origin.x,
386
+ MIN(this.maxY(), rect.maxY()) - origin.y
387
+ );
388
+ return size.empty() ? new Rect() : new Rect(origin, size);
389
+ },
390
+
391
+ /**
392
+ * Union rect of this and given rect
393
+ *
394
+ * @this {uki.geometry.Rect}
395
+ * @param {uki.geometry.Rect} rect
396
+ * @returns {uki.geometry.Rect} union
397
+ */
398
+ union: function(rect) {
399
+ return Rect.fromCoords(
400
+ MIN(this.x, rect.x),
401
+ MIN(this.y, rect.y),
402
+ MAX(this.maxX(), rect.maxX()),
403
+ MAX(this.maxY(), rect.maxY())
404
+ );
405
+ },
406
+
407
+ /**
408
+ * Checks if point is within this
409
+ *
410
+ * @this {uki.geometry.Rect}
411
+ * @param {uki.geometry.Point} point
412
+ * @returns {boolean}
413
+ */
414
+ containsPoint: function(point) {
415
+ return point.x >= this.minX() &&
416
+ point.x <= this.maxX() &&
417
+ point.y >= this.minY() &&
418
+ point.y <= this.maxY();
419
+ },
420
+
421
+ /**
422
+ * Checks if this contains given rect
423
+ *
424
+ * @this {uki.geometry.Rect}
425
+ * @param {uki.geometry.Rect} rect
426
+ * @returns {boolean}
427
+ */
428
+ containsRect: function(rect) {
429
+ return this.eq(this.union(rect));
430
+ },
431
+
432
+ constructor: Rect
433
+ };
434
+
435
+ Rect.prototype.left = Rect.prototype.minX;
436
+ Rect.prototype.top = Rect.prototype.minY;
437
+
438
+ /**
439
+ * Creates Rect from minX, minY, maxX, maxY
440
+ *
441
+ * @memberOf uki.geometry.Rect
442
+ * @name fromCoords
443
+ * @function
444
+ *
445
+ * @param {number} minX
446
+ * @param {number} maxX
447
+ * @param {number} minY
448
+ * @param {number} maxY
449
+ * @returns {uki.geometry.Rect}
450
+ */
451
+ Rect.fromCoords = function(minX, minY, maxX, maxY) {
452
+ if (maxX === undefined) {
453
+ return new Rect(
454
+ minX.x,
455
+ minX.y,
456
+ minY.x - minX.x,
457
+ minY.y - minX.y
458
+ );
459
+ }
460
+ return new Rect(minX, minY, maxX - minX, maxY - minY);
461
+ };
462
+
463
+ /**
464
+ * Creates Rect from "minX minY maxX maxY" string
465
+ *
466
+ * @memberOf uki.geometry.Rect
467
+ * @name fromCoordsString
468
+ * @function
469
+ *
470
+ * @param {string} string
471
+ * @returns {uki.geometry.Rect}
472
+ */
473
+ Rect.fromCoordsString = function(string) {
474
+ var parts = string.split(/\s+/);
475
+ return Rect.fromCoords(
476
+ parts[0],
477
+ parts[1],
478
+ parts[2],
479
+ parts[3]
480
+ ) ;
481
+ };
482
+
483
+ /**
484
+ * Creates Rect from "x y width height" or "width height" string
485
+ *
486
+ * @memberOf uki.geometry.Rect
487
+ * @name fromString
488
+ * @function
489
+ *
490
+ * @param {string} string
491
+ * @returns {uki.geometry.Rect}
492
+ */
493
+ Rect.fromString = function(string) {
494
+ var parts = string.split(/\s+/);
495
+
496
+ if (parts.length > 2) return new Rect(
497
+ parts[0],
498
+ parts[1],
499
+ parts[2],
500
+ parts[3]
501
+ );
502
+ return new Rect(
503
+ parts[0],
504
+ parts[1]
505
+ ) ;
506
+ };
507
+
508
+ /**
509
+ * Creates rect from different representations
510
+ * - if no params given returns null
511
+ * - if uki.geometry.Rect given returns it
512
+ * - if "200 300" or "0 10 200 300" string converts it to rect
513
+ * - if two or four params given creates rect from them
514
+ *
515
+ * @memberOf uki.geometry.Rect
516
+ * @name creates
517
+ * @function
518
+ *
519
+ * @param {...string|number|uki.geometry.Rect} var_args Rect representation
520
+ *
521
+ * @returns {uki.geometry.Rect} created size
522
+ */
523
+ Rect.create = function(a1, a2, a3, a4) {
524
+ if (a1 === undefined) return null;
525
+ if (a1.x !== undefined) return a1;
526
+ if (/\S+\s+\S+/.test(a1 + '')) return Rect.fromString(a1, a2);
527
+ if (a3 === undefined) return new Rect(a1, a2);
528
+ return new Rect(a1, a2, a3, a4);
529
+ };
530
+
531
+
532
+ /**
533
+ * Inset with top, right, bottom and left properties
534
+ * - if no params given top = right = bottom = left = 0
535
+ * - if two params given top = bottom and right = left
536
+ *
537
+ * @param {number=} top
538
+ * @param {number=} right
539
+ * @param {number=} bottom
540
+ * @param {number=} left
541
+ *
542
+ * @name uki.geometry.Inset
543
+ * @constructor
544
+ */
545
+ var Inset = uki.geometry.Inset = function(top, right, bottom, left) {
546
+ this.top = top*1.0 || 0;
547
+ this.right = right*1.0 || 0;
548
+ this.bottom = bottom === undefined ? this.top*1.0 : bottom*1.0;
549
+ this.left = left === undefined ? this.right*1.0 : left*1.0;
550
+ };
551
+
552
+ Inset.prototype = /** @lends uki.geometry.Inset.prototype */ {
553
+
554
+ /**
555
+ * Converts Inset to "top right bottom left" string
556
+ *
557
+ * @returns {string}
558
+ */
559
+ toString: function() {
560
+ return [this.top, this.right, this.bottom, this.left].join(' ');
561
+ },
562
+
563
+ /**
564
+ * Creates a new Inset with same properties
565
+ *
566
+ * @this {uki.geometry.Inset}
567
+ * @return {uki.geometry.Inset} new Inset
568
+ */
569
+ clone: function() {
570
+ return new Inset(this.top, this.right, this.bottom, this.left);
571
+ },
572
+
573
+ /**
574
+ * left + right
575
+ *
576
+ * @this {uki.geometry.Inset}
577
+ * @return {number}
578
+ */
579
+ width: function() {
580
+ return this.left + this.right;
581
+ },
582
+
583
+ /**
584
+ * top + bottom
585
+ *
586
+ * @this {uki.geometry.Inset}
587
+ * @return {number}
588
+ */
589
+ height: function() {
590
+ return this.top + this.bottom;
591
+ },
592
+
593
+ /**
594
+ * True if any property < 0
595
+ *
596
+ * @this {uki.geometry.Inset}
597
+ * @return {boolean}
598
+ */
599
+ negative: function() {
600
+ return this.top < 0 || this.left < 0 || this.right < 0 || this.bottom < 0;
601
+ },
602
+
603
+ /**
604
+ * True if all properties = 0
605
+ *
606
+ * @this {uki.geometry.Inset}
607
+ * @return {boolean}
608
+ */
609
+ empty: function() {
610
+ return !this.top && !this.left && !this.right && !this.bottom;
611
+ }
612
+ };
613
+
614
+ /**
615
+ * Creates Rect from "top right bottom left" or "top right" string
616
+ *
617
+ * @memberOf uki.geometry.Inset
618
+ * @name fromString
619
+ * @function
620
+ *
621
+ * @param {string} string
622
+ * @returns {uki.geometry.Inset}
623
+ */
624
+ Inset.fromString = function(string) {
625
+ var parts = string.split(/\s+/);
626
+ if (parts.length < 3) parts[2] = parts[0];
627
+ if (parts.length < 4) parts[3] = parts[1];
628
+
629
+ return new Inset(
630
+ parts[0],
631
+ parts[1],
632
+ parts[2],
633
+ parts[3]
634
+ );
635
+ };
636
+
637
+ /**
638
+ * Creates rect from different representations
639
+ * - if no params given returns null
640
+ * - if uki.geometry.Inset given returns it
641
+ * - if "200 300" or "0 10 200 300" string converts it to inset
642
+ * - if two or four params given creates inset from them
643
+ *
644
+ * @memberOf uki.geometry.Inset
645
+ * @name create
646
+ * @function
647
+ *
648
+ * @param {...string|number|uki.geometry.Inset} var_args Rect representation
649
+ *
650
+ * @returns {uki.geometry.Inset} created inset
651
+ */
652
+ Inset.create = function(a1, a2, a3, a4) {
653
+ if (a1 === undefined) return null;
654
+ if (a1.top !== undefined) return a1;
655
+ if (/\S+\s+\S+/.test(a1 + '')) return Inset.fromString(a1, a2);
656
+ if (a3 === undefined) return new Inset(a1, a2);
657
+ return new Inset(a1, a2, a3, a4);
658
+ };