uki 1.1.1 → 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (144) hide show
  1. data/VERSION +1 -1
  2. data/bin/uki +1 -1
  3. data/frameworks/uki/README.rdoc +1 -1
  4. data/frameworks/uki/examples/core-examples/controls/controls.js +6 -6
  5. data/frameworks/uki/examples/core-examples/flow/flow.js +4 -4
  6. data/frameworks/uki/examples/core-examples/linearGradient/gradient.svg +11 -0
  7. data/frameworks/uki/examples/core-examples/linearGradient/linearGradient.js +87 -0
  8. data/frameworks/uki/examples/core-examples/popup/popup.js +23 -10
  9. data/frameworks/uki/examples/core-examples/resizeToContents/resizeToContents.js +12 -1
  10. data/frameworks/uki/examples/core-examples/slider/slider.js +1 -1
  11. data/frameworks/uki/examples/core-examples/splitPaneExtended/splitPaneExtended.js +1 -1
  12. data/frameworks/uki/examples/core-examples/table/table.js +19 -2
  13. data/frameworks/uki/examples/core-examples/wave/wave-theme.js +1 -1
  14. data/frameworks/uki/examples/core-examples/wave/wave.js +1 -1
  15. data/frameworks/uki/examples/more-examples/radioButton/radioButton.js +3 -3
  16. data/frameworks/uki/examples/more-examples/select/select.js +35 -0
  17. data/frameworks/uki/examples/touch-examples/scrollPane/scrollPane.js +53 -0
  18. data/frameworks/uki/spec/unit/background.spec.js +1 -1
  19. data/frameworks/uki/spec/unit/selector.spec.js +28 -12
  20. data/frameworks/uki/spec/unit/utils.spec.js +14 -0
  21. data/frameworks/uki/src/uki-core.js +3 -1
  22. data/frameworks/uki/src/uki-core/after.js +57 -0
  23. data/frameworks/uki/src/uki-core/attachment.js +15 -6
  24. data/frameworks/uki/src/uki-core/background.js +4 -3
  25. data/frameworks/uki/src/uki-core/background/css.js +1 -0
  26. data/frameworks/uki/src/uki-core/background/cssBox.js +5 -3
  27. data/frameworks/uki/src/uki-core/background/linearGradient.js +112 -0
  28. data/frameworks/uki/src/uki-core/background/multi.js +2 -2
  29. data/frameworks/uki/src/uki-core/background/rows.js +1 -0
  30. data/frameworks/uki/src/uki-core/background/sliced9.js +5 -2
  31. data/frameworks/uki/src/uki-core/builder.js +5 -4
  32. data/frameworks/uki/src/uki-core/collection.js +18 -13
  33. data/frameworks/uki/src/uki-core/dom/browser.js +114 -0
  34. data/frameworks/uki/src/uki-core/dom/event.js +3 -0
  35. data/frameworks/uki/src/uki-core/image.js +1 -26
  36. data/frameworks/uki/src/uki-core/selector.js +5 -0
  37. data/frameworks/uki/src/uki-core/theme.js +24 -23
  38. data/frameworks/uki/src/uki-core/theme/template.js +1 -1
  39. data/frameworks/uki/src/uki-core/uki.js +7 -4
  40. data/frameworks/uki/src/uki-core/utils.js +51 -26
  41. data/frameworks/uki/src/uki-core/view.js +6 -3
  42. data/frameworks/uki/src/uki-core/view/base.js +16 -1
  43. data/frameworks/uki/src/uki-core/view/container.js +15 -5
  44. data/frameworks/uki/src/uki-core/view/focusable.js +17 -4
  45. data/frameworks/uki/src/uki-core/view/observable.js +15 -2
  46. data/frameworks/uki/src/uki-core/view/styleable.js +4 -11
  47. data/frameworks/uki/src/uki-data/ajax.js +4 -30
  48. data/frameworks/uki/src/uki-data/json.js +191 -0
  49. data/frameworks/uki/src/uki-data/localStore.js +37 -0
  50. data/frameworks/uki/src/uki-data/model.js +1 -1
  51. data/frameworks/uki/src/uki-more.js +4 -0
  52. data/frameworks/uki/src/uki-more/more/background.js +2 -0
  53. data/frameworks/uki/src/uki-more/more/color.js +168 -0
  54. data/frameworks/uki/src/uki-more/more/utils.js +5 -12
  55. data/frameworks/uki/src/uki-more/more/view.js +3 -1
  56. data/frameworks/uki/src/uki-more/more/view/form.js +30 -0
  57. data/frameworks/uki/src/uki-more/more/view/hTile.js +59 -0
  58. data/frameworks/uki/src/uki-more/more/view/nativeButton.js +3 -0
  59. data/frameworks/uki/src/uki-more/more/view/nativeCheckbox.js +38 -0
  60. data/frameworks/uki/src/uki-more/more/view/nativeControl.js +40 -0
  61. data/frameworks/uki/src/uki-more/more/view/nativeInput.js +78 -0
  62. data/frameworks/uki/src/uki-more/more/view/nativeSelect.js +29 -0
  63. data/frameworks/uki/src/uki-more/more/view/radioButton.js +1 -1
  64. data/frameworks/uki/src/uki-more/more/view/select-theme.js +55 -0
  65. data/frameworks/uki/src/uki-more/more/view/select.js +208 -0
  66. data/frameworks/uki/src/uki-theme/airport.js +145 -88
  67. data/frameworks/uki/src/uki-theme/airport/i/table/a-down.png +0 -0
  68. data/frameworks/uki/src/uki-theme/airport/i/table/a-up.png +0 -0
  69. data/frameworks/uki/src/uki-touch.js +2 -0
  70. data/frameworks/uki/src/uki-touch/touch.js +1 -0
  71. data/frameworks/uki/src/uki-touch/touch/const.js +24 -0
  72. data/frameworks/uki/src/uki-touch/touch/setup.js +52 -0
  73. data/frameworks/uki/src/uki-touch/touch/view.js +4 -0
  74. data/frameworks/uki/src/uki-touch/touch/view/scrollPane.js +505 -0
  75. data/frameworks/uki/src/uki-touch/touch/view/scrollableList.js +27 -0
  76. data/frameworks/uki/src/uki-view/view/box.js +9 -0
  77. data/frameworks/uki/src/uki-view/view/button.js +36 -1
  78. data/frameworks/uki/src/uki-view/view/checkbox.js +32 -3
  79. data/frameworks/uki/src/uki-view/view/flow.js +37 -9
  80. data/frameworks/uki/src/uki-view/view/image.js +14 -1
  81. data/frameworks/uki/src/uki-view/view/label.js +72 -11
  82. data/frameworks/uki/src/uki-view/view/list.js +143 -13
  83. data/frameworks/uki/src/uki-view/view/list/render.js +1 -0
  84. data/frameworks/uki/src/uki-view/view/popup.js +46 -2
  85. data/frameworks/uki/src/uki-view/view/radio.js +19 -4
  86. data/frameworks/uki/src/uki-view/view/scrollPane.js +91 -33
  87. data/frameworks/uki/src/uki-view/view/slider.js +67 -54
  88. data/frameworks/uki/src/uki-view/view/splitPane.js +102 -9
  89. data/frameworks/uki/src/uki-view/view/table.js +59 -2
  90. data/frameworks/uki/src/uki-view/view/table/column.js +45 -17
  91. data/frameworks/uki/src/uki-view/view/table/header.js +40 -12
  92. data/frameworks/uki/src/uki-view/view/table/render.js +4 -0
  93. data/frameworks/uki/src/uki-view/view/textField.js +75 -21
  94. data/frameworks/uki/src/uki-view/view/toolbar.js +16 -0
  95. data/lib/uki/builder.rb +1 -1
  96. data/lib/uki/include_js.rb +2 -2
  97. data/lib/uki/project.rb +14 -14
  98. data/templates/index.html.erb +2 -2
  99. data/templates/myapp.js.erb +2 -2
  100. data/uki.gemspec +34 -48
  101. metadata +44 -47
  102. data/frameworks/uki/src/uki-core/dom/nativeLayout.js +0 -18
  103. data/frameworks/uki/src/uki-theme/airport/i/button/down-c.gif +0 -0
  104. data/frameworks/uki/src/uki-theme/airport/i/button/down-c.png +0 -0
  105. data/frameworks/uki/src/uki-theme/airport/i/button/down-h.gif +0 -0
  106. data/frameworks/uki/src/uki-theme/airport/i/button/down-h.png +0 -0
  107. data/frameworks/uki/src/uki-theme/airport/i/button/down-m.png +0 -0
  108. data/frameworks/uki/src/uki-theme/airport/i/button/down-v.png +0 -0
  109. data/frameworks/uki/src/uki-theme/airport/i/button/focusRing-c.png +0 -0
  110. data/frameworks/uki/src/uki-theme/airport/i/button/focusRing-h.png +0 -0
  111. data/frameworks/uki/src/uki-theme/airport/i/button/focusRing-m.png +0 -0
  112. data/frameworks/uki/src/uki-theme/airport/i/button/focusRing-v.png +0 -0
  113. data/frameworks/uki/src/uki-theme/airport/i/button/focusRing.png +0 -0
  114. data/frameworks/uki/src/uki-theme/airport/i/button/hover-c.gif +0 -0
  115. data/frameworks/uki/src/uki-theme/airport/i/button/hover-c.png +0 -0
  116. data/frameworks/uki/src/uki-theme/airport/i/button/hover-h.gif +0 -0
  117. data/frameworks/uki/src/uki-theme/airport/i/button/hover-h.png +0 -0
  118. data/frameworks/uki/src/uki-theme/airport/i/button/hover-m.png +0 -0
  119. data/frameworks/uki/src/uki-theme/airport/i/button/hover-v.png +0 -0
  120. data/frameworks/uki/src/uki-theme/airport/i/button/hover.png +0 -0
  121. data/frameworks/uki/src/uki-theme/airport/i/button/normal-c.gif +0 -0
  122. data/frameworks/uki/src/uki-theme/airport/i/button/normal-c.png +0 -0
  123. data/frameworks/uki/src/uki-theme/airport/i/button/normal-h.gif +0 -0
  124. data/frameworks/uki/src/uki-theme/airport/i/button/normal-h.png +0 -0
  125. data/frameworks/uki/src/uki-theme/airport/i/button/normal-m.png +0 -0
  126. data/frameworks/uki/src/uki-theme/airport/i/button/normal-v.png +0 -0
  127. data/frameworks/uki/src/uki-theme/airport/i/button/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/shadow/large-c.png +0 -0
  134. data/frameworks/uki/src/uki-theme/airport/i/shadow/large-h.png +0 -0
  135. data/frameworks/uki/src/uki-theme/airport/i/shadow/large-m.png +0 -0
  136. data/frameworks/uki/src/uki-theme/airport/i/shadow/large-v.png +0 -0
  137. data/frameworks/uki/src/uki-theme/airport/i/shadow/large.png +0 -0
  138. data/frameworks/uki/src/uki-theme/airport/i/slider/bar-m.gif +0 -0
  139. data/frameworks/uki/src/uki-theme/airport/i/slider/bar-m.png +0 -0
  140. data/frameworks/uki/src/uki-theme/airport/i/slider/bar-v.gif +0 -0
  141. data/frameworks/uki/src/uki-theme/airport/i/slider/bar-v.png +0 -0
  142. data/frameworks/uki/src/uki-theme/airport/i/slider/bar.png +0 -0
  143. data/frameworks/uki/src/uki-theme/airport/i/slider/focus.png +0 -0
  144. data/frameworks/uki/src/uki-theme/airport/i/slider/handle.gif +0 -0
@@ -1,5 +1,6 @@
1
1
  include('uki.js');
2
-
2
+ (function() {
3
+
3
4
  var toString = Object.prototype.toString,
4
5
  trim = String.prototype.trim,
5
6
  slice = Array.prototype.slice,
@@ -8,7 +9,10 @@ var toString = Object.prototype.toString,
8
9
 
9
10
  var marked = '__uki_marked';
10
11
 
11
-
12
+ // dummy subclass
13
+ /** @ignore */
14
+ function inheritance () {}
15
+
12
16
  /**
13
17
  * Utility functions.
14
18
  */
@@ -164,7 +168,7 @@ var utils = {
164
168
  array[i][marked] = true;
165
169
  };
166
170
  for (i = 0; i < result.length; i++) {
167
- delete result[i][marked]
171
+ delete result[i][marked];
168
172
  };
169
173
  return result;
170
174
 
@@ -259,13 +263,13 @@ var utils = {
259
263
  */
260
264
  extend: function() {
261
265
  var target = arguments[0] || {}, i = 1, length = arguments.length, options;
262
-
266
+
263
267
  for ( ; i < length; i++ ) {
264
268
  if ( (options = arguments[i]) != null ) {
265
269
 
266
270
  for ( var name in options ) {
267
271
  var copy = options[ name ];
268
-
272
+
269
273
  if ( copy !== undefined ) {
270
274
  target[ name ] = copy;
271
275
  }
@@ -273,7 +277,7 @@ var utils = {
273
277
  }
274
278
  }
275
279
  }
276
-
280
+
277
281
  return target;
278
282
  },
279
283
 
@@ -297,32 +301,37 @@ var utils = {
297
301
  newClass: function(/* [[superClass], mixin1, mixin2, ..] */ methods) {
298
302
  var klass = function() {
299
303
  this.init.apply(this, arguments);
300
- };
304
+ },
301
305
 
302
- var inheritance, i, startFrom = 0, tmp, baseClasses = [], base, name, copy;
303
-
304
- if (arguments.length > 1) {
305
- if (arguments[0].prototype) { // real inheritance
306
- /** @ignore */
307
- inheritance = function() {};
308
- inheritance.prototype = arguments[0].prototype;
306
+ i, startFrom = 0, tmp, baseClasses = [], base, name, copy, $arguments = arguments, length;
307
+
308
+ if ((length = $arguments.length) > 1) {
309
+ base = $arguments[0];
310
+ if (base.prototype) { // real inheritance
311
+ inheritance.prototype = base.prototype;
309
312
  klass.prototype = new inheritance();
310
313
  startFrom = 1;
311
314
  baseClasses = [inheritance.prototype];
315
+
316
+ // class method inheritance
317
+ for ( name in base ) {
318
+ copy = base[ name ];
319
+ if ( !base.hasOwnProperty(name) || copy === undefined || name == 'prototype' ) continue;
320
+ klass[ name ] = copy;
321
+ }
312
322
  }
313
323
  }
314
- for (i=startFrom; i < arguments.length; i++) {
315
- base = tmp = arguments[i];
316
- if (this.isFunction(tmp)) tmp = tmp.apply(tmp, baseClasses);
317
- baseClasses.push(tmp);
318
-
319
- for ( name in base ) {
320
- copy = base[ name ];
321
- if ( !base.hasOwnProperty(name) || copy === undefined ) continue;
322
- klass.prototype[ name ] = copy;
324
+
325
+ for (i=startFrom; i < length; i++) {
326
+ base = $arguments[i];
327
+ if (this.isFunction(base)) {
328
+ tmp = {};
329
+ base.apply(tmp, baseClasses);
330
+ base = tmp;
323
331
  }
332
+ baseClasses[ baseClasses.length ] = base;
324
333
 
325
- // uki.extend(klass.prototype, base);
334
+ uki.extend(klass.prototype, base);
326
335
  };
327
336
  if (!klass.prototype.init) klass.prototype.init = function() {};
328
337
  return klass;
@@ -336,10 +345,12 @@ var utils = {
336
345
  */
337
346
  binarySearch: function (value, array) {
338
347
  var low = 0, high = array.length, mid;
348
+
339
349
  while (low < high) {
340
350
  mid = (low + high) >> 1;
341
351
  array[mid] < value ? low = mid + 1 : high = mid;
342
352
  }
353
+
343
354
  return low;
344
355
  },
345
356
 
@@ -382,7 +393,8 @@ var utils = {
382
393
  * @param {Array.<string>} props Property names
383
394
  */
384
395
  addProps: function(proto, props) {
385
- uki.each(props, function() { proto[this] = uki.newProp('_' + this); });
396
+ for (var i =0, len = props.length; i<len; i++)
397
+ proto[ props[i] ] = uki.newProp('_' + props[i]);
386
398
  },
387
399
 
388
400
  toArray: function(arr) {
@@ -403,7 +415,20 @@ var utils = {
403
415
  }
404
416
  return this;
405
417
  };
418
+ },
419
+
420
+ camalize: function(string) {
421
+ return string.replace(/[-_]\S/g, function(v) {
422
+ return v.substr(1).toUpperCase();
423
+ });
424
+ },
425
+
426
+ dasherize: function(string) {
427
+ return string.replace(/[A-Z]/g, function(v) {
428
+ return '-' + v.toLowerCase();
429
+ });
406
430
  }
407
431
  };
408
432
  utils.extend(uki, utils);
409
- delete utils;
433
+
434
+ })();
@@ -7,15 +7,18 @@ uki.view = {
7
7
  klass = uki.newClass.apply(uki, args),
8
8
  parts = name.split('.'),
9
9
  obj = root,
10
- i, part;
10
+ i, part, l = parts.length - 1;
11
11
 
12
12
  klass.prototype.typeName = function() { return name; };
13
- for ( i=0; i < parts.length - 1; i++ ) {
13
+
14
+ for ( i= 0; i < l; i++ ) {
14
15
  part = parts[i];
15
16
  if (!obj[part]) obj[part] = {};
16
17
  obj = obj[part];
18
+
17
19
  };
18
- obj[parts[parts.length - 1]] = klass;
20
+
21
+ obj[ parts[l] ] = klass;
19
22
  return klass;
20
23
  }
21
24
  };
@@ -3,7 +3,6 @@ include('../geometry.js');
3
3
  include('../utils.js');
4
4
  include('../builder.js');
5
5
  include('../dom.js');
6
- include('../dom/nativeLayout.js');
7
6
  include('observable.js');
8
7
  include('styleable.js');
9
8
 
@@ -274,6 +273,10 @@ uki.view.declare('uki.view.Base', uki.view.Observable, uki.view.Styleable, funct
274
273
  this._firstLayout = false;
275
274
  };
276
275
 
276
+ this.layoutIfNeeded = function() {
277
+ if (this._needsLayout && this.visible()) this.layout();
278
+ };
279
+
277
280
 
278
281
  /**
279
282
  * @function uki.view.Base#minSize
@@ -318,6 +321,13 @@ uki.view.declare('uki.view.Base', uki.view.Observable, uki.view.Styleable, funct
318
321
  this.rect(newRect);
319
322
  };
320
323
 
324
+ /**
325
+ * Called when child changes it's size
326
+ */
327
+ this.childResized = function(child) {
328
+ // do nothing, extend in subviews
329
+ };
330
+
321
331
  /**
322
332
  * Resizes view to its contents. Contents size is determined by view.
323
333
  * View can be resized by width, height or both. This is specified through
@@ -442,6 +452,11 @@ uki.view.declare('uki.view.Base', uki.view.Observable, uki.view.Styleable, funct
442
452
  */
443
453
  this._createDom = function() {
444
454
  this._dom = uki.createElement('div', this.defaultCss);
455
+ this._initClassName();
456
+ };
457
+
458
+ this._initClassName = function() {
459
+ this._dom.className = this.typeName().replace(/\./g, '-');
445
460
  };
446
461
 
447
462
  /**
@@ -8,6 +8,8 @@ include('base.js');
8
8
  uki.view.declare('uki.view.Container', uki.view.Base, function(Base) {
9
9
  /**#@+ @memberOf uki.view.Container# */
10
10
 
11
+ this._inset = new Inset();
12
+
11
13
  /** @private */
12
14
  this._setup = function() {
13
15
  this._childViews = [];
@@ -25,11 +27,11 @@ uki.view.declare('uki.view.Container', uki.view.Base, function(Base) {
25
27
  }
26
28
 
27
29
  this.contentsWidth = function() {
28
- return maxProp(this, 'maxX');
30
+ return maxProp(this, 'maxX') + this.inset().right;
29
31
  };
30
32
 
31
33
  this.contentsHeight = function() {
32
- return maxProp(this, 'maxY');
34
+ return maxProp(this, 'maxY') + this.inset().bottom;
33
35
  };
34
36
 
35
37
  this.contentsSize = function() {
@@ -65,6 +67,7 @@ uki.view.declare('uki.view.Container', uki.view.Base, function(Base) {
65
67
  this._childViews[i]._viewIndex--;
66
68
  };
67
69
  this._childViews = uki.grep(this._childViews, function(elem) { return elem != child; });
70
+ this._contentChanged();
68
71
  };
69
72
 
70
73
  /**
@@ -75,6 +78,7 @@ uki.view.declare('uki.view.Container', uki.view.Base, function(Base) {
75
78
  this._childViews.push(child);
76
79
  child.parent(this);
77
80
  this.domForChild(child).appendChild(child.dom());
81
+ this._contentChanged();
78
82
  };
79
83
 
80
84
  /**
@@ -91,6 +95,7 @@ uki.view.declare('uki.view.Container', uki.view.Base, function(Base) {
91
95
  this._childViews.splice(beforeChild._viewIndex-1, 0, child);
92
96
  child.parent(this);
93
97
  this.domForChild(child).insertBefore(child.dom(), beforeChild.dom());
98
+ this._contentChanged();
94
99
  };
95
100
 
96
101
  /**
@@ -101,8 +106,15 @@ uki.view.declare('uki.view.Container', uki.view.Base, function(Base) {
101
106
  return this._dom;
102
107
  };
103
108
 
109
+ this.inset = uki.newProp('_inset', function(v) {
110
+ this._inset = Inset.create(v);
111
+ });
104
112
 
105
113
  /** @private */
114
+ this._contentChanged = function() {
115
+ // called on every insertBefore, appendChild, removeChild
116
+ };
117
+
106
118
  this._layoutDom = function(rect) {
107
119
  Base._layoutDom.call(this, rect);
108
120
  this._layoutChildViews(rect);
@@ -111,9 +123,7 @@ uki.view.declare('uki.view.Container', uki.view.Base, function(Base) {
111
123
  /** @private */
112
124
  this._layoutChildViews = function() {
113
125
  for (var i=0, childViews = this.childViews(); i < childViews.length; i++) {
114
- if (childViews[i]._needsLayout && childViews[i].visible()) {
115
- childViews[i].layout(this._rect);
116
- }
126
+ childViews[i].layoutIfNeeded();
117
127
  };
118
128
  };
119
129
 
@@ -2,7 +2,7 @@ include('../view.js');
2
2
  include('observable.js');
3
3
 
4
4
  /**
5
- * @class
5
+ * @interface
6
6
  */
7
7
  uki.view.Focusable = new function() {/** @lends uki.view.Focusable.prototype */
8
8
 
@@ -45,21 +45,25 @@ uki.view.Focusable = new function() {/** @lends uki.view.Focusable.prototype */
45
45
 
46
46
  if (!preCreatedFocusTarget) {
47
47
  this._focusTarget = uki.createElement('input', 'position:absolute;left:-9999px;top:0;width:1px;height:1px;');
48
+ this._focusTarget.className = 'uki-view-Focusable';
48
49
  this.dom().appendChild(this._focusTarget);
49
50
  }
50
51
  this._hasFocus = false;
51
52
  this._firstFocus = true;
52
53
 
53
54
  uki.dom.bind(this._focusTarget, 'focus', uki.proxy(function(e) {
55
+ this._stopWatingForBlur();
54
56
  if (!this._hasFocus) this._focus(e);
55
57
  }, this));
56
58
 
57
59
  uki.dom.bind(this._focusTarget, 'blur', uki.proxy(function(e) {
58
60
  if (this._hasFocus) {
59
61
  this._hasFocus = false;
60
- setTimeout(uki.proxy(function() { // wait for mousedown refocusing
61
- if (!this._hasFocus) this._blur();
62
- }, this), 1);
62
+ this._waitingForBlur =
63
+ setTimeout(uki.proxy(function() { // wait for mousedown refocusing
64
+ this._waitingForBlur = false;
65
+ if (!this._hasFocus) this._blur();
66
+ }, this), 1);
63
67
  }
64
68
  }, this));
65
69
 
@@ -78,8 +82,17 @@ uki.view.Focusable = new function() {/** @lends uki.view.Focusable.prototype */
78
82
  this._hasFocus = false;
79
83
  }
80
84
 
85
+ this._stopWatingForBlur = function() {
86
+ if (this._waitingForBlur) {
87
+ clearTimeout(this._waitingForBlur);
88
+ this._waitingForBlur = false;
89
+ this._hasFocus = true;
90
+ }
91
+ };
92
+
81
93
  this.focus = function() {
82
94
  if (this._focusable && !this._disabled) {
95
+ this._stopWatingForBlur();
83
96
  if (!this._hasFocus) this._focus();
84
97
  var target = this._focusTarget;
85
98
  setTimeout(function() {
@@ -8,6 +8,10 @@ uki.view.Observable = /** @lends uki.view.Observable.prototype */ {
8
8
  // return null; // should implement
9
9
  // },
10
10
 
11
+ /**
12
+ * @param {String} name Event name
13
+ * @param {function()} callback
14
+ */
11
15
  bind: function(name, callback) {
12
16
  callback.huid = callback.huid || uki.guid++;
13
17
  uki.each(name.split(' '), function(i, name) {
@@ -18,11 +22,20 @@ uki.view.Observable = /** @lends uki.view.Observable.prototype */ {
18
22
  },
19
23
 
20
24
  unbind: function(name, callback) {
21
- uki.each(name.split(' '), function(i, name) {
25
+ if (!this._observers) return;
26
+ var names;
27
+ if (name) {
28
+ names = name.split(' ');
29
+ } else {
30
+ names = [];
31
+ uki.each(this._observers, function(k, v) { names.push(k) });
32
+ }
33
+ uki.each(names, function(i, name) {
22
34
  this._observers[name] = !callback ? [] : uki.grep(this._observersFor(name, true), function(observer) {
23
35
  return observer != callback && observer.huid != callback.huid;
24
36
  });
25
37
  if (this._observers[name].length == 0) {
38
+ this._observers[name] = undefined;
26
39
  this._unbindFromDom(name);
27
40
  }
28
41
  }, this);
@@ -43,7 +56,7 @@ uki.view.Observable = /** @lends uki.view.Observable.prototype */ {
43
56
  },
44
57
 
45
58
  _bindToDom: function(name, target) {
46
- if (!target && !this.dom) return;
59
+ if (!target && !this.dom) return false;
47
60
  this._domHander = this._domHander || uki.proxy(function(e) {
48
61
  e.source = this;
49
62
  this.trigger(e.type, e);
@@ -33,11 +33,6 @@ uki.view.Styleable = new function() {
33
33
  // };
34
34
  // });
35
35
 
36
- var probe = uki.createElement('div').style;
37
- uki.each(['userSelect', 'MozUserSelect', 'WebkitUserSelect'], function(i, name) {
38
- if (typeof probe[name] == 'string') this._textSelectProp = name;
39
- }, this);
40
-
41
36
  /**
42
37
  * Sets whether text of the view can be selected.
43
38
  *
@@ -47,17 +42,15 @@ uki.view.Styleable = new function() {
47
42
  * @param {boolean=} state
48
43
  * @returns {boolean|uki.view.Base} current textSelectable state of self
49
44
  */
50
- this.textSelectable = function(state) {
51
- if (state === undefined) return this._textSelectable;
45
+ this.textSelectable = uki.newProp('_textSelectable', function(state) {
52
46
  this._textSelectable = state;
53
- if (this._textSelectProp) {
54
- this._dom.style[this._textSelectProp] = state ? '' : this._textSelectProp == 'MozUserSelect' ? '-moz-none' : 'none';
47
+ if (uki.browser.cssUserSelect() != 'unsupported') {
48
+ this._dom.style[uki.camalize(uki.browser.cssUserSelect())] = (state ? '' : uki.browser.cssUserSelect() == '-moz-user-select' ? '-moz-none' : 'none');
55
49
  } else {
56
50
  uki.dom[state ? 'unbind' : 'bind'](this.dom(), 'selectstart', uki.dom.preventDefaultHandler);
57
51
  }
58
52
  this._dom.style.cursor = state ? '' : 'default';
59
- return this;
60
- };
53
+ });
61
54
 
62
55
  this.draggable = function(state) {
63
56
  if (state === undefined) return this._dom.getAttribute('draggable');
@@ -1,3 +1,5 @@
1
+ include('json.js');
2
+
1
3
  /**
2
4
  * based on http://github.com/uki/uki/blob/1.4.2/src/ajax.js
3
5
  *
@@ -18,34 +20,6 @@ var jsc = +new Date,
18
20
 
19
21
 
20
22
  uki.extend(uki, {
21
- error: function( msg ) {
22
- throw msg;
23
- },
24
-
25
- parseJSON: function( data ) {
26
- if ( typeof data !== "string" || !data ) {
27
- return null;
28
- }
29
-
30
- // Make sure leading/trailing whitespace is removed (IE can't handle it)
31
- data = uki.trim( data );
32
-
33
- // Make sure the incoming data is actual JSON
34
- // Logic borrowed from http://json.org/json2.js
35
- if ( /^[\],:{}\s]*$/.test(data.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@")
36
- .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]")
37
- .replace(/(?:^|:|,)(?:\s*\[)+/g, "")) ) {
38
-
39
- // Try to use the native JSON parser first
40
- return window.JSON && window.JSON.parse ?
41
- window.JSON.parse( data ) :
42
- (new Function("return " + data))();
43
-
44
- } else {
45
- uki.error( "Invalid JSON: " + data );
46
- }
47
- },
48
-
49
23
  // Evalulates a script in a global context
50
24
  globalEval: function( data ) {
51
25
  if ( data && rnotwhite.test(data) ) {
@@ -240,7 +214,7 @@ uki.extend(uki, {
240
214
  }
241
215
 
242
216
  if ( s.cache === false && type === "GET" ) {
243
- var ts = now();
217
+ var ts = +new Date;
244
218
 
245
219
  // try replacing _= if it is there
246
220
  var ret = s.url.replace(rts, "$1_=" + ts + "$2");
@@ -517,7 +491,7 @@ uki.extend(uki, {
517
491
  data = xml ? xhr.responseXML : xhr.responseText;
518
492
 
519
493
  if ( xml && data.documentElement.nodeName === "parsererror" ) {
520
- uki.error( "parsererror" );
494
+ throw "parsererror";
521
495
  }
522
496
 
523
497
  // Allow a pre-filtering function to sanitize the response