uki 1.0.0

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