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
@@ -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);