uki 1.1.1 → 1.1.2

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 (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
@@ -0,0 +1,27 @@
1
+ include('../view.js');
2
+ include('../../../uki-view/view/list.js');
3
+ include('touchScrollPane.js');
4
+
5
+ /**
6
+ * Touch scrollable List View
7
+ * Puts a list into a touch.view.ScrollPane
8
+ *
9
+ * @author rsaccon
10
+ * @name uki.touch.view.ScrollableList
11
+ * @class
12
+ * @extends uki.touch.view.ScrollPane
13
+ */
14
+ uki.view.declare('uki.touch.view.ScrollableList', uki.touch.view.ScrollPane, function(Base) {
15
+
16
+ this._createDom = function() {
17
+ Base._createDom.call(this);
18
+ this._list = uki({ view: 'List', rect: this.rect().clone().normalize(), anchors: 'left top right bottom' })[0];
19
+ this.appendChild(this._list);
20
+ };
21
+
22
+ uki.each('data rowHeight render packSize visibleRectExt throttle focusable selectedIndex selectedIndexes selectedRow selectedRows multiselect draggable textSelectable'.split(' '),
23
+ function(i, name) {
24
+ uki.delegateProp(this, name, '_list');
25
+ }, this);
26
+
27
+ });
@@ -1 +1,10 @@
1
+ /**
2
+ * Basic container view
3
+ *
4
+ *
5
+ * @author voloko
6
+ * @name uki.view.Box
7
+ * @class
8
+ * @extends uki.view.Container
9
+ */
1
10
  uki.view.declare('uki.view.Box', uki.view.Container, {});
@@ -1,7 +1,17 @@
1
1
  include('label.js');
2
2
 
3
+ /**
4
+ * Button view
5
+ *
6
+ *
7
+ * @author voloko
8
+ * @name uki.view.Button
9
+ * @class
10
+ * @extends uki.view.Label
11
+ * @implements uki.view.Focusable
12
+ */
3
13
  uki.view.declare('uki.view.Button', uki.view.Label, uki.view.Focusable, function(Base, Focusable) {
4
- var proto = this;
14
+ /** @lends uki.view.Button.prototype */
5
15
 
6
16
  this._backgroundPrefix = 'button-';
7
17
 
@@ -13,8 +23,32 @@ uki.view.declare('uki.view.Button', uki.view.Label, uki.view.Focusable, function
13
23
  this.defaultCss += "cursor:default;-moz-user-select:none;-webkit-user-select:none;" + uki.theme.style('button');
14
24
  };
15
25
 
26
+ /**
27
+ * @function
28
+ * @name uki.view.Button#backgroundPrefix
29
+ */
16
30
  uki.addProps(this, ['backgroundPrefix']);
17
31
 
32
+ /**
33
+ * @function
34
+ * @name uki.view.Button#"normal-background"
35
+ */
36
+ /**
37
+ * @function
38
+ * @name uki.view.Button#"hover-background"
39
+ */
40
+ /**
41
+ * @function
42
+ * @name uki.view.Button#"down-background"
43
+ */
44
+ /**
45
+ * @function
46
+ * @name uki.view.Button#"focus-background"
47
+ */
48
+ /**
49
+ * @function
50
+ * @name uki.view.Button#"disabled-background"
51
+ */
18
52
  uki.each(['normal', 'hover', 'down', 'focus', 'disabled'], function(i, name) {
19
53
  var property = name + '-background';
20
54
  this[property] = function(bg) {
@@ -48,6 +82,7 @@ uki.view.declare('uki.view.Button', uki.view.Label, uki.view.Focusable, function
48
82
  this._createDom = function() {
49
83
  // dom
50
84
  this._dom = uki.createElement('div', this.defaultCss);
85
+ this._initClassName();
51
86
  this._label = uki.createElement('div', this.defaultCss); // text-shadow:0 1px 0px rgba(255,255,255,0.8);
52
87
  this._dom.appendChild(this._label);
53
88
 
@@ -1,7 +1,27 @@
1
+ /**
2
+ * Checkbox
3
+ *
4
+ * @author voloko
5
+ * @name uki.view.Checkbox
6
+ * @class
7
+ * @extends uki.view.Button
8
+ */
1
9
  uki.view.declare('uki.view.Checkbox', uki.view.Button, function(Base) {
2
10
 
3
11
  this._backgroundPrefix = 'checkbox-';
4
12
 
13
+ /**
14
+ * @function
15
+ * @name uki.view.Button#"checked-normal-background"
16
+ */
17
+ /**
18
+ * @function
19
+ * @name uki.view.Button#"checked-hover-background"
20
+ */
21
+ /**
22
+ * @function
23
+ * @name uki.view.Button#"checked-disabled-background"
24
+ */
5
25
  uki.each(['checked-normal', 'checked-hover', 'checked-disabled'], function(i, name) {
6
26
  var property = name + '-background';
7
27
  this[property] = function(bg) {
@@ -22,17 +42,26 @@ uki.view.declare('uki.view.Checkbox', uki.view.Button, function(Base) {
22
42
  this._backgroundByName(name);
23
43
  };
24
44
 
45
+ /**
46
+ * @function
47
+ * @name uki.view.Button#value
48
+ */
49
+ /**
50
+ * @function
51
+ * @name uki.view.Button#checked
52
+ */
25
53
  this.value = this.checked = uki.newProp('_checked', function(state) {
26
- var changed = this._checked != !!state;
27
54
  this._checked = !!state;
28
55
  this._updateBg();
29
- if (changed) this.trigger('change', {checked: this._checked, source: this});
30
56
  });
31
57
 
32
58
  this._mouseup = function(e) {
33
59
  if (!this._down) return;
34
60
  this._down = false;
35
- if (!this._disabled) this.checked(!this.checked())
61
+ if (!this._disabled) {
62
+ this.checked(!this.checked())
63
+ this.trigger('change', {checked: this._checked, source: this});
64
+ }
36
65
  };
37
66
 
38
67
  });
@@ -1,3 +1,12 @@
1
+ /**
2
+ * Vertical Flow
3
+ * Arranges child views verticaly, one after another
4
+ *
5
+ * @author voloko
6
+ * @name uki.view.VFlow
7
+ * @class
8
+ * @extends uki.view.Container
9
+ */
1
10
  uki.view.declare('uki.view.VFlow', uki.view.Container, function(Base) {
2
11
  this.contentsSize = function() {
3
12
  var value = uki.reduce(0, this._childViews, function(sum, e) {
@@ -13,21 +22,12 @@ uki.view.declare('uki.view.VFlow', uki.view.Container, function(Base) {
13
22
  return Base.resizeToContents.call(this, autosizeStr);
14
23
  }
15
24
 
16
- uki.each(['appendChild', 'removeChild', 'insertBefore'], function(i, name) {
17
- this[name] = function(arg1, arg2) {
18
- this._contentChanged = true;
19
- return Base[name].call(this, arg1, arg2);
20
- };
21
- }, this)
22
-
23
25
  this.layout = function() {
24
- if (this._contentChanged) this._resizeChildViews(this._rect);
25
26
  return Base.layout.call(this);
26
27
  };
27
28
 
28
29
  // resize in layout
29
30
  this._resizeChildViews = function(oldRect) {
30
- this._contentChanged = false;
31
31
  var offset = 0, rect, view;
32
32
  for (var i=0, childViews = this.childViews(); i < childViews.length; i++) {
33
33
  view = childViews[i];
@@ -40,8 +40,31 @@ uki.view.declare('uki.view.VFlow', uki.view.Container, function(Base) {
40
40
  if (view.visible()) offset += view._rect.height;
41
41
  };
42
42
  };
43
+
44
+ this.childResized = function() {
45
+ this._needsLayout = true;
46
+ uki.after(uki.proxy(this._afterChildResized, this));
47
+ };
48
+
49
+ this._contentChanged = this.childResized;
50
+
51
+ this._afterChildResized = function() {
52
+ this.resizeToContents('height');
53
+ this.parent().childResized(this);
54
+ this.layoutIfNeeded();
55
+ };
56
+
43
57
  });
44
58
 
59
+ /**
60
+ * Horizontla Flow
61
+ * Arranges child views horizontally
62
+ *
63
+ * @author voloko
64
+ * @name uki.view.HFlow
65
+ * @class
66
+ * @extends uki.view.VFlow
67
+ */
45
68
  uki.view.declare('uki.view.HFlow', uki.view.VFlow, function(Base) {
46
69
  this.contentsSize = function() {
47
70
  var value = uki.reduce(0, this._childViews, function(sum, e) {
@@ -64,4 +87,9 @@ uki.view.declare('uki.view.HFlow', uki.view.VFlow, function(Base) {
64
87
  };
65
88
  };
66
89
 
90
+ this._afterChildResized = function() {
91
+ this.resizeToContents('width');
92
+ this.parent().childResized(this);
93
+ this.layoutIfNeeded();
94
+ };
67
95
  });
@@ -1,9 +1,22 @@
1
+ /**
2
+ * Image
3
+ *
4
+ * @author voloko
5
+ * @name uki.view.Image
6
+ * @class
7
+ * @extends uki.view.Base
8
+ */
1
9
  uki.view.declare('uki.view.Image', uki.view.Base, function() {
2
10
  this.typeName = function() { return 'uki.view.Image'; };
3
11
 
12
+ /**
13
+ * @function
14
+ * @name uki.view.Image#src
15
+ */
4
16
  uki.delegateProp(this, 'src', '_dom');
5
17
 
6
18
  this._createDom = function() {
7
- this._dom = uki.createElement('img', this.defaultCss)
19
+ this._dom = uki.createElement('img', this.defaultCss);
20
+ this._initClassName();
8
21
  };
9
22
  });
@@ -1,5 +1,14 @@
1
1
  include('../../uki-core/const.js');
2
2
 
3
+ /**
4
+ * Label View
5
+ * Contains any html
6
+ *
7
+ * @author voloko
8
+ * @name uki.view.Label
9
+ * @class
10
+ * @extends uki.view.Base
11
+ */
3
12
  uki.view.declare('uki.view.Label', uki.view.Base, function(Base) {
4
13
 
5
14
  this._setup = function() {
@@ -13,12 +22,14 @@ uki.view.declare('uki.view.Label', uki.view.Base, function(Base) {
13
22
  };
14
23
 
15
24
  this._style = function(name, value) {
16
- if (value !== undefined && 'font fontFamily fontWeight fontSize textDecoration textOverflow textAlign overflow color'.indexOf(name) != -1) {
25
+ if (value !== undefined && uki.inArray(name, uki.browser.textStyles) != -1) {
17
26
  this._label.style[name] = value;
18
27
  }
19
28
  return Base._style.call(this, name, value);
20
29
  };
21
30
 
31
+ this.adaptToContents = uki.newProp('_adaptToContents');
32
+
22
33
  this.textSelectable = function(state) {
23
34
  if (state !== undefined && !this._textSelectProp) {
24
35
  this._label.unselectable = state ? '' : 'on';
@@ -35,29 +46,53 @@ uki.view.declare('uki.view.Label', uki.view.Base, function(Base) {
35
46
  uki.dom.probe(clone, function() {
36
47
  size = new Size(clone.offsetWidth + inset.width(), clone.offsetHeight + inset.height());
37
48
  });
38
-
39
49
  return size;
40
50
  };
41
51
 
52
+ /**
53
+ * Read/write escaped html contents
54
+ * @function
55
+ * @name uki.view.Label#text
56
+ */
42
57
  this.text = function(text) {
43
58
  return text === undefined ? this.html() : this.html(uki.escapeHTML(text));
44
59
  };
45
60
 
61
+ /**
62
+ * Read/write html contents
63
+ * @function
64
+ * @name uki.view.Label#html
65
+ */
46
66
  this.html = function(html) {
47
67
  if (html === undefined) return this._label.innerHTML;
48
68
  this._label.innerHTML = html;
49
69
  return this;
50
70
  };
51
71
 
72
+ /**
73
+ * Insets between text and view borders
74
+ * @function
75
+ * @name uki.view.Label#inset
76
+ */
52
77
  this.inset = uki.newProp('_inset', function(inset) {
53
78
  this._inset = Inset.create(inset);
54
79
  });
55
80
 
81
+ /**
82
+ * Whether label have inline scrollbars on not
83
+ * @function
84
+ * @name uki.view.Label#scrollable
85
+ */
56
86
  this.scrollable = uki.newProp('_scrollable', function(state) {
57
87
  this._scrollable = state;
58
88
  this._label.style.overflow = state ? 'auto' : 'hidden';
59
89
  });
60
90
 
91
+ /**
92
+ * Whether can have multiline lines or not
93
+ * @function
94
+ * @name uki.view.Label#multiline
95
+ */
61
96
  this.multiline = uki.newProp('_multiline', function(state) {
62
97
  this._multiline = state;
63
98
  this._label.style.whiteSpace = state ? '' : 'nowrap';
@@ -92,15 +127,10 @@ uki.view.declare('uki.view.Label', uki.view.Base, function(Base) {
92
127
  };
93
128
 
94
129
  this._layoutDom = function() {
95
- Base._layoutDom.apply(this, arguments);
96
-
97
- var inset = this._inset;
98
- if (!this.multiline()) {
99
- var fz = parseInt(this.style('fontSize'), 10) || 12;
100
- this._label.style.lineHeight = (this._rect.height - inset.top - inset.bottom) + 'px';
101
- // this._label.style.paddingTop = MAX(0, this._rect.height/2 - fz/2) + 'px';
102
- }
103
- var l;
130
+ var inset = this._inset,
131
+ l,
132
+ a = this._anchors,
133
+ watchField = '', watchValue;
104
134
 
105
135
  if (uki.supportNativeLayout) {
106
136
  l = {
@@ -117,7 +147,38 @@ uki.view.declare('uki.view.Label', uki.view.Base, function(Base) {
117
147
  height: this._rect.height - inset.height()
118
148
  };
119
149
  }
150
+
151
+ if (!(a & ANCHOR_BOTTOM)) {
152
+ l.height = l.bottom = undefined;
153
+ watchField = 'offsetHeight';
154
+ } else if (!(a & ANCHOR_TOP)) {
155
+ l.height = l.bottom = undefined;
156
+ watchField = 'offsetHeight';
157
+ } else if (!(a & ANCHOR_RIGHT)) {
158
+ l.right = l.width = undefined;
159
+ watchField = 'offsetWidth';
160
+ } else if (!(a & ANCHOR_LEFT)) {
161
+ l.left = l.width = undefined;
162
+ watchField = 'offsetWidth';
163
+ }
164
+
165
+ Base._layoutDom.apply(this, arguments);
166
+
167
+ if (!this.multiline()) {
168
+ var fz = parseInt(this.style('fontSize'), 10) || 12;
169
+ this._label.style.lineHeight = (this._rect.height - inset.top - inset.bottom) + 'px';
170
+ // this._label.style.paddingTop = MAX(0, this._rect.height/2 - fz/2) + 'px';
171
+ }
120
172
  this._lastLabelLayout = uki.dom.layout(this._label.style, l, this._lastLabelLayout);
173
+
174
+ if (this.adaptToContents() && watchField) {
175
+ watchValue = this._label[watchField];
176
+ if (watchValue != this._lastWatchValue && this.parent()) {
177
+ this.resizeToContents(watchField == 'offsetWidth' ? 'width' : 'height');
178
+ this.parent().childResized(this);
179
+ }
180
+ this._lastWatchValue = watchValue;
181
+ }
121
182
  };
122
183
 
123
184
  });
@@ -1,6 +1,17 @@
1
1
  include('scrollPane.js');
2
2
 
3
3
  uki.view.list = {};
4
+ /**
5
+ * List View
6
+ * Progressevly renders list data. Support selection and drag&drop.
7
+ * Renders rows with plain html.
8
+ *
9
+ * @author voloko
10
+ * @name uki.view.List
11
+ * @class
12
+ * @extends uki.view.Base
13
+ * @implements uki.view.Focusable
14
+ */
4
15
  uki.view.declare('uki.view.List', uki.view.Base, uki.view.Focusable, function(Base, Focusable) {
5
16
 
6
17
  this._throttle = 42; // do not try to render more often than every 42ms
@@ -18,21 +29,59 @@ uki.view.declare('uki.view.List', uki.view.Base, uki.view.Focusable, function(Ba
18
29
  });
19
30
  };
20
31
 
32
+ /**
33
+ * @function
34
+ * @name uki.view.List#defaultBackground
35
+ */
21
36
  this.defaultBackground = function() {
22
37
  return uki.theme.background('list', this._rowHeight);
23
38
  };
24
39
 
25
- uki.addProps(this, ['render', 'packSize', 'visibleRectExt', 'throttle', 'contentDraggable', 'lastClickIndex', 'multiselect', 'lastClickIndex']);
26
-
40
+ /**
41
+ * @type uki.view.list.Render
42
+ * @function
43
+ * @name uki.view.List#render
44
+ */
45
+ /**
46
+ * @function
47
+ * @name uki.view.List#packSize
48
+ */
49
+ /**
50
+ * @function
51
+ * @name uki.view.List#visibleRectExt
52
+ */
53
+ /**
54
+ * @function
55
+ * @name uki.view.List#throttle
56
+ */
57
+ /**
58
+ * @function
59
+ * @name uki.view.List#lastClickIndex
60
+ */
61
+ /**
62
+ * @function
63
+ * @name uki.view.List#multiselect
64
+ */
65
+ uki.addProps(this, ['render', 'packSize', 'visibleRectExt', 'throttle', 'lastClickIndex', 'multiselect']);
66
+
67
+ /**
68
+ * @function
69
+ * @name uki.view.List#rowHeight
70
+ */
27
71
  this.rowHeight = uki.newProp('_rowHeight', function(val) {
28
72
  this._rowHeight = val;
29
73
  this.minSize(new Size(this.minSize().width, this._rowHeight * this._data.length));
30
74
  if (this._background) this._background.detach();
31
75
  this._background = null;
32
76
  if (this.background()) this.background().attachTo(this);
33
- this._relayoutParent();
77
+ this._contentChanged();
34
78
  });
35
79
 
80
+ /**
81
+ * @example list.data(['row1', 'row2', ...])
82
+ * @function
83
+ * @name uki.view.List#data
84
+ */
36
85
  this.data = function(d) {
37
86
  if (d === undefined) return this._data;
38
87
  this.clearSelection();
@@ -40,11 +89,16 @@ uki.view.declare('uki.view.List', uki.view.Base, uki.view.Focusable, function(Ba
40
89
  this._packs[0].itemFrom = this._packs[0].itemTo = this._packs[1].itemFrom = this._packs[1].itemTo = 0;
41
90
 
42
91
  this.minSize(new Size(this.minSize().width, this._rowHeight * this._data.length));
43
- this.trigger('selection', {source: this})
44
- this._relayoutParent();
92
+ this.trigger('selection', {source: this});
93
+ this._contentChanged();
45
94
  return this;
46
95
  };
47
96
 
97
+ /**
98
+ * Forces list content update
99
+ * @function
100
+ * @name uki.view.List#relayout
101
+ */
48
102
  this.relayout = function() {
49
103
  this._packs[0].itemFrom = this._packs[0].itemTo = this._packs[1].itemFrom = this._packs[1].itemTo = 0;
50
104
  this.layout();
@@ -54,7 +108,13 @@ uki.view.declare('uki.view.List', uki.view.Base, uki.view.Focusable, function(Ba
54
108
  return new Size(this.rect().width, this._rowHeight * this._data.length);
55
109
  };
56
110
 
57
- // used in search. should be fast
111
+ /**
112
+ * used in search. should be fast
113
+ * @function
114
+ * @param {Number} position
115
+ * @param {String} data
116
+ * @name uki.view.List#addRow
117
+ */
58
118
  this.addRow = function(position, data) {
59
119
  this._data.splice(position, 0, data);
60
120
  var item = this._itemAt(position);
@@ -87,23 +147,40 @@ uki.view.declare('uki.view.List', uki.view.Base, uki.view.Focusable, function(Ba
87
147
 
88
148
  // needed for scrollbar
89
149
  this.minSize(new Size(this.minSize().width, this._rowHeight * this._data.length));
90
- this._relayoutParent();
150
+ this._contentChanged();
91
151
 
92
152
  return this;
93
153
  };
94
154
 
95
- this.removeRow = function(position, data) {
155
+ /**
156
+ * @function
157
+ * @param {Number} position
158
+ * @name uki.view.List#removeRow
159
+ */
160
+ this.removeRow = function(position) {
96
161
  this._data.splice(position, 1);
97
162
  this.data(this._data);
98
163
  return this;
99
164
  };
100
165
 
101
- this.redrawRow = function(row) {
102
- var item = this._itemAt(row);
103
- if (item) item.innerHTML = this._render.render(this._data[row], this._rowRect(row), row);
166
+ /**
167
+ * Forces one particular row to be redrawn
168
+ * @function
169
+ * @param {Number} position
170
+ * @name uki.view.List#removeRow
171
+ */
172
+ this.redrawRow = function(position) {
173
+ var item = this._itemAt(position);
174
+ if (item) item.innerHTML = this._render.render(this._data[position], this._rowRect(position), position);
104
175
  return this;
105
176
  };
106
177
 
178
+ /**
179
+ * Read/write current selected index for selectable lists
180
+ * @function
181
+ * @param {Number} position
182
+ * @name uki.view.List#selectedIndex
183
+ */
107
184
  this.selectedIndex = function(position) {
108
185
  if (position === undefined) return this._selectedIndexes.length ? this._selectedIndexes[0] : -1;
109
186
  this.selectedIndexes([position]);
@@ -111,6 +188,12 @@ uki.view.declare('uki.view.List', uki.view.Base, uki.view.Focusable, function(Ba
111
188
  return this;
112
189
  };
113
190
 
191
+ /**
192
+ * Read/write all selected indexes for multiselectable lists
193
+ * @function
194
+ * @param {Array.<Number>} position
195
+ * @name uki.view.List#selectedIndex
196
+ */
114
197
  this.selectedIndexes = function(indexes) {
115
198
  if (indexes === undefined) return this._selectedIndexes;
116
199
  this.clearSelection(true);
@@ -122,16 +205,30 @@ uki.view.declare('uki.view.List', uki.view.Base, uki.view.Focusable, function(Ba
122
205
  return this;
123
206
  };
124
207
 
208
+ /**
209
+ * Read contents of selected row
210
+ * @function
211
+ * @name uki.view.List#selectedRow
212
+ */
125
213
  this.selectedRow = function() {
126
214
  return this._data[this.selectedIndex()];
127
215
  };
128
216
 
217
+ /**
218
+ * Read contents of all selected rows
219
+ * @function
220
+ * @name uki.view.List#selectedRows
221
+ */
129
222
  this.selectedRows = function() {
130
223
  return uki.map(this.selectedIndexes(), function(index) {
131
224
  return this._data[index];
132
225
  }, this)
133
226
  };
134
227
 
228
+ /**
229
+ * @function
230
+ * @name uki.view.List#clearSelection
231
+ */
135
232
  this.clearSelection = function(skipClickIndex) {
136
233
  for (var i=0; i < this._selectedIndexes.length; i++) {
137
234
  this._setSelected(this._selectedIndexes[i], false);
@@ -140,6 +237,11 @@ uki.view.declare('uki.view.List', uki.view.Base, uki.view.Focusable, function(Ba
140
237
  if (!skipClickIndex) this._lastClickIndex = -1;
141
238
  };
142
239
 
240
+ /**
241
+ * @function
242
+ * @param {Number} index
243
+ * @name uki.view.List#isSelected
244
+ */
143
245
  this.isSelected = function(index) {
144
246
  var found = uki.binarySearch(index, this._selectedIndexes);
145
247
  return this._selectedIndexes[found] == index;
@@ -198,7 +300,13 @@ uki.view.declare('uki.view.List', uki.view.Base, uki.view.Focusable, function(Ba
198
300
  }
199
301
  };
200
302
 
303
+ this._contentChanged = function() {
304
+ this._needsLayout = true;
305
+ uki.after(uki.proxy(this._relayoutParent, this));
306
+ };
307
+
201
308
  this._relayoutParent = function() {
309
+ this.parent().childResized(this);
202
310
  if (!this._scrollableParent) return;
203
311
  var c = this;
204
312
  while ( c && c != this._scrollableParent) {
@@ -295,6 +403,7 @@ uki.view.declare('uki.view.List', uki.view.Base, uki.view.Focusable, function(Ba
295
403
 
296
404
  this._createDom = function() {
297
405
  this._dom = uki.createElement('div', this.defaultCss + 'overflow:hidden');
406
+ this._initClassName();
298
407
 
299
408
  var packDom = uki.createElement('div', 'position:absolute;left:0;top:0px;width:100%;overflow:hidden');
300
409
  this._packs = [
@@ -472,8 +581,29 @@ uki.view.declare('uki.view.List', uki.view.Base, uki.view.Focusable, function(Ba
472
581
 
473
582
  });
474
583
 
475
- uki.Collection.addAttrs(['data','selectedIndex', 'selectedIndexes', 'selectedRows']);
584
+ /** @function
585
+ @name uki.Collection#data */
586
+ /** @function
587
+ @name uki.Collection#selectedIndex */
588
+ /** @function
589
+ @name uki.Collection#selectedIndexes */
590
+ /** @function
591
+ @name uki.Collection#selectedRow */
592
+ /** @function
593
+ @name uki.Collection#selectedRows */
594
+ /** @function
595
+ @name uki.Collection#lastClickIndex */
596
+ uki.Collection.addAttrs(['data', 'selectedIndex', 'selectedIndexes', 'selectedRow', 'selectedRows', 'lastClickIndex']);
476
597
 
598
+ /**
599
+ * Scrollable List View
600
+ * Puts a list into a scroll pane
601
+ *
602
+ * @author voloko
603
+ * @name uki.view.ScrollableList
604
+ * @class
605
+ * @extends uki.view.ScrollPane
606
+ */
477
607
  uki.view.declare('uki.view.ScrollableList', uki.view.ScrollPane, function(Base) {
478
608
 
479
609
  this._createDom = function() {
@@ -482,7 +612,7 @@ uki.view.declare('uki.view.ScrollableList', uki.view.ScrollPane, function(Base)
482
612
  this.appendChild(this._list);
483
613
  };
484
614
 
485
- uki.each('data rowHeight render packSize visibleRectExt throttle focusable selectedIndexes selectedIndex selectedIndexes selectedRows multiselect contentDraggable draggable textSelectable'.split(' '),
615
+ uki.each('data rowHeight render packSize visibleRectExt throttle focusable selectedIndex selectedIndexes selectedRow selectedRows multiselect draggable textSelectable'.split(' '),
486
616
  function(i, name) {
487
617
  uki.delegateProp(this, name, '_list');
488
618
  }, this);