lsd_rails 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (110) hide show
  1. data/Packages/Sheet.js/Source/SheetParser.Value.js +1 -1
  2. data/Packages/lsd/Source/Action/Clone.js +2 -12
  3. data/Packages/lsd/Source/Action/Delete.js +1 -7
  4. data/Packages/lsd/Source/Action/Display.js +7 -7
  5. data/Packages/lsd/Source/Action/Edit.js +2 -2
  6. data/Packages/lsd/Source/Action/Invoke.js +2 -2
  7. data/Packages/lsd/Source/Action/Submit.js +2 -0
  8. data/Packages/lsd/Source/Action/Toggle.js +4 -0
  9. data/Packages/lsd/Source/Action/Update.js +2 -1
  10. data/Packages/lsd/Source/Action.js +4 -5
  11. data/Packages/lsd/Source/Document.js +10 -7
  12. data/Packages/lsd/Source/LSD.js +22 -127
  13. data/Packages/lsd/Source/Layer.js +4 -4
  14. data/Packages/lsd/Source/Layout.js +1077 -259
  15. data/Packages/lsd/Source/Mixin/Animation.js +1 -1
  16. data/Packages/lsd/Source/Mixin/Choice.js +2 -2
  17. data/Packages/lsd/Source/Mixin/Command.js +26 -8
  18. data/Packages/lsd/Source/Mixin/ContentEditable.js +2 -1
  19. data/Packages/lsd/Source/{Trait → Mixin}/Date.js +21 -11
  20. data/Packages/lsd/Source/{Trait/Menu.js → Mixin/Details.js} +6 -1
  21. data/Packages/lsd/Source/Mixin/Draggable.js +1 -1
  22. data/Packages/lsd/Source/Mixin/Fieldset.js +51 -49
  23. data/Packages/lsd/Source/Mixin/Focusable.js +38 -39
  24. data/Packages/lsd/Source/Mixin/Invokable.js +13 -14
  25. data/Packages/lsd/Source/Mixin/List.js +9 -17
  26. data/Packages/lsd/Source/Mixin/Placeholder.js +2 -7
  27. data/Packages/lsd/Source/Mixin/Request.js +5 -3
  28. data/Packages/lsd/Source/Mixin/Resizable.js +3 -3
  29. data/Packages/lsd/Source/Mixin/Resource.js +1 -1
  30. data/Packages/lsd/Source/Mixin/Root.js +17 -1
  31. data/Packages/lsd/Source/Mixin/Scrollable.js +1 -1
  32. data/Packages/lsd/Source/{Trait → Mixin}/Slider.js +0 -0
  33. data/Packages/lsd/Source/Mixin/Sortable.js +2 -2
  34. data/Packages/lsd/Source/Mixin/Submittable.js +2 -1
  35. data/Packages/lsd/Source/Mixin/Target.js +11 -6
  36. data/Packages/lsd/Source/Mixin/Touchable.js +2 -2
  37. data/Packages/lsd/Source/Mixin/Unselectable.js +1 -1
  38. data/Packages/lsd/Source/Mixin/Uploader.js +11 -13
  39. data/Packages/lsd/Source/Mixin/Validity.js +35 -9
  40. data/Packages/lsd/Source/Mixin/Value.js +5 -3
  41. data/Packages/lsd/Source/Module/Accessories/Attributes.js +90 -89
  42. data/Packages/lsd/Source/Module/Accessories/Chain.js +40 -25
  43. data/Packages/lsd/Source/Module/Accessories/Element.js +59 -58
  44. data/Packages/lsd/Source/Module/Accessories/Events.js +25 -10
  45. data/Packages/lsd/Source/Module/Accessories/Options.js +11 -13
  46. data/Packages/lsd/Source/Module/Accessories/States.js +42 -5
  47. data/Packages/lsd/Source/Module/Accessories/Styles.js +1 -1
  48. data/Packages/lsd/Source/Module/Accessories/Tag.js +21 -7
  49. data/Packages/lsd/Source/Module/Ambient/Allocations.js +178 -64
  50. data/Packages/lsd/Source/Module/Ambient/DOM.js +98 -55
  51. data/Packages/lsd/Source/Module/Ambient/Expectations.js +57 -8
  52. data/Packages/lsd/Source/Module/Ambient/Interpolations.js +147 -0
  53. data/Packages/lsd/Source/Module/Ambient/Layout.js +52 -15
  54. data/Packages/lsd/Source/Module/Ambient/Proxies.js +44 -36
  55. data/Packages/lsd/Source/Module/Ambient/Relations.js +3 -1
  56. data/Packages/lsd/Source/Module/Ambient/Selectors.js +3 -3
  57. data/Packages/lsd/Source/Module/Ambient.js +2 -2
  58. data/Packages/lsd/Source/Module/Graphics/Layers.js +1 -1
  59. data/Packages/lsd/Source/Module/Graphics/Render.js +1 -1
  60. data/Packages/lsd/Source/Relation.js +19 -20
  61. data/Packages/lsd/Source/Sheet.js +4 -5
  62. data/Packages/lsd/Source/{Behavior.js → Tools/Behavior.js} +0 -0
  63. data/Packages/lsd/Source/Tools/Command.js +190 -0
  64. data/Packages/lsd/Source/Tools/Helpers.js +109 -0
  65. data/Packages/lsd/Source/Tools/Interpolation.js +351 -0
  66. data/Packages/lsd/Source/Tools/Microdata.js +75 -0
  67. data/Packages/lsd/Source/Tools/Object.js +192 -0
  68. data/Packages/lsd/Source/Tools/Position.js +208 -0
  69. data/Packages/lsd/Source/Tools/Require.js +76 -0
  70. data/Packages/lsd/Source/Type.js +2 -2
  71. data/Packages/lsd/package.yml +11 -7
  72. data/Packages/lsd-mobile/Source/Body/Dialog.js +2 -2
  73. data/Packages/lsd-mobile/Source/Input/Date.js +9 -84
  74. data/Packages/lsd-native/Source/Input/Checkbox.js +4 -4
  75. data/Packages/lsd-native/Source/Input/Date.js +46 -6
  76. data/Packages/lsd-native/Source/Input/Radio.js +1 -4
  77. data/Packages/lsd-native/Source/Input.js +5 -6
  78. data/Packages/lsd-widgets/Source/Body/Dialog.js +9 -6
  79. data/Packages/lsd-widgets/Source/Body/Page.js +1 -1
  80. data/Packages/lsd-widgets/Source/Body.js +1 -1
  81. data/Packages/lsd-widgets/Source/Button.js +1 -1
  82. data/Packages/lsd-widgets/Source/Form.js +1 -1
  83. data/Packages/lsd-widgets/Source/Input/Checkbox.js +2 -2
  84. data/Packages/lsd-widgets/Source/Input/Date.js +45 -16
  85. data/Packages/lsd-widgets/Source/Input/File.js +2 -2
  86. data/Packages/lsd-widgets/Source/Input/HTML.js +2 -2
  87. data/Packages/lsd-widgets/Source/Input/Radio.js +1 -1
  88. data/Packages/lsd-widgets/Source/Input/Range.js +2 -2
  89. data/Packages/lsd-widgets/Source/Input/Submit.js +1 -1
  90. data/Packages/lsd-widgets/Source/Input.js +2 -11
  91. data/Packages/lsd-widgets/Source/Label.js +4 -8
  92. data/Packages/lsd-widgets/Source/Menu/List.js +3 -3
  93. data/Packages/lsd-widgets/Source/Menu.js +2 -2
  94. data/Packages/lsd-widgets/Source/Progress.js +1 -1
  95. data/Packages/lsd-widgets/Source/Select.js +7 -6
  96. data/Packages/lsd-widgets/Source/Table/Calendar.js +41 -15
  97. data/Packages/lsd-widgets/Source/Table.js +7 -2
  98. data/Packages/mootools-ext/Source/Core/Class.Mixin.js +43 -38
  99. data/Packages/mootools-ext/Source/Core/Class.States.js +26 -22
  100. data/Packages/mootools-ext/Source/Element/Element.from.js +1 -1
  101. data/Packages/mootools-ext/Source/Element/Properties/Item.js +1 -2
  102. data/Packages/mootools-ext/Source/Request/Request.Statuses.js +9 -7
  103. data/Packages/mootools-ext/Source/Types/{FastArray.js → Object.Array.js} +8 -14
  104. data/Packages/mootools-ext/package.yml +1 -2
  105. data/lib/lsd.rake +28 -0
  106. metadata +15 -11
  107. data/Packages/lsd/Source/Command.js +0 -135
  108. data/Packages/lsd/Source/Interpolation.js +0 -103
  109. data/Packages/lsd/Source/Module/Ambient/Container.js +0 -56
  110. data/Packages/mootools-ext/Source/Element/Element.onDispose.js +0 -36
@@ -74,4 +74,4 @@ LSD.Mixin.Animation = new Class({
74
74
 
75
75
  });
76
76
 
77
- LSD.Behavior.define('[animation]', LSD.Mixin.Animation);
77
+ LSD.Behavior.define('[animation]', 'animation');
@@ -23,7 +23,7 @@ LSD.Mixin.Choice = new Class({
23
23
  many: {
24
24
  items: {
25
25
  states: {
26
- add: Array.fast('chosen')
26
+ add: Array.object('chosen')
27
27
  }
28
28
  }
29
29
  }
@@ -59,4 +59,4 @@ LSD.Mixin.Choice = new Class({
59
59
  });
60
60
 
61
61
 
62
- LSD.Behavior.define(':choice', LSD.Mixin.Choice);
62
+ LSD.Behavior.define(':choice', 'choice');
@@ -43,7 +43,10 @@ LSD.Mixin.Command = new Class({
43
43
  },
44
44
  events: {
45
45
  _command: {
46
- 'setDocument': 'getCommand'
46
+ 'setDocument': function() {
47
+ this.getCommand();
48
+ this.eachLink('quickstart', true, true, !this.getCommandState());
49
+ },
47
50
  }
48
51
  }
49
52
  },
@@ -57,9 +60,14 @@ LSD.Mixin.Command = new Class({
57
60
 
58
61
  click: function() {
59
62
  if (this.disabled) return false;
60
- this.fireEvent('click');
63
+ this.fireEvent('click', arguments);
61
64
  this.getCommand().click();
62
- this.callChain();
65
+ var method = this.getCommandState() ? 'callChain' : 'uncallChain';
66
+ return this[method].apply(this, arguments) != false;
67
+ },
68
+
69
+ unclick: function() {
70
+ return this.uncallChain.apply(this, arguments);
63
71
  },
64
72
 
65
73
  setCommandType: function(type) {
@@ -72,10 +80,6 @@ LSD.Mixin.Command = new Class({
72
80
  delete this.commandType
73
81
  },
74
82
 
75
- getCommandType: function() {
76
- return this.commandType || (this.pseudos.checkbox && 'checkbox') || (this.pseudos.radio && 'radio') || 'command';
77
- },
78
-
79
83
  getCommandAction: function() {
80
84
  return this.attributes.commandaction || this.options.commandAction || this.captureEvent('getCommandAction', arguments);
81
85
  },
@@ -90,9 +94,23 @@ LSD.Mixin.Command = new Class({
90
94
 
91
95
  });
92
96
 
97
+ Object.append(LSD.Mixin.Command, {
98
+ getCommandType: function() {
99
+ return this.commandType || (this.pseudos.checkbox && 'checkbox') || (this.pseudos.radio && 'radio') || 'command';
100
+ },
101
+
102
+ getCommandState: function() {
103
+ return (LSD.Mixin.Command.getCommandType.call(this) == 'command') || this.checked;
104
+ }
105
+ });
106
+
107
+ ['getCommandType', 'getCommandState'].each(function(method) {
108
+ LSD.Mixin.Command.implement(method, LSD.Mixin.Command[method]);
109
+ });
110
+
93
111
  LSD.Options.commandType = {
94
112
  add: 'setCommandType',
95
113
  remove: 'unsetCommandType'
96
114
  };
97
115
 
98
- LSD.Behavior.define(':command, :radio, :checkbox, [accesskey]', LSD.Mixin.Command);
116
+ LSD.Behavior.define(':command, :radio, :checkbox, [accesskey]', 'command');
@@ -9,6 +9,7 @@ license: Public domain (http://unlicense.org).
9
9
 
10
10
  requires:
11
11
  - LSD.Mixin
12
+ - require
12
13
 
13
14
  uses:
14
15
  - CKEDITOR
@@ -121,4 +122,4 @@ LSD.Mixin.ContentEditable = new Class({
121
122
  }
122
123
  });
123
124
 
124
- LSD.Behavior.define('[contenteditable=editor]', LSD.Mixin.ContentEditable);
125
+ LSD.Behavior.define('[contenteditable=editor]', 'content_editable');
@@ -10,16 +10,16 @@ license: Public domain (http://unlicense.org).
10
10
  authors: Yaroslaff Fedin
11
11
 
12
12
  requires:
13
- - LSD.Trait
13
+ - LSD.Mixin
14
14
  - More/Date
15
15
 
16
16
  provides:
17
- - LSD.Trait.Date
17
+ - LSD.Mixin.Date
18
18
 
19
19
  ...
20
20
  */
21
21
 
22
- LSD.Trait.Date = new Class({
22
+ LSD.Mixin.Date = new Class({
23
23
  options: {
24
24
  date: {
25
25
  interval: 'month',
@@ -28,8 +28,15 @@ LSD.Trait.Date = new Class({
28
28
  },
29
29
 
30
30
  setDate: function(date) {
31
+ if (date && !date.getDate) {
32
+ var source = date;
33
+ date = this.parseDate(date);
34
+ }
35
+ if (!date) return;
36
+ if (source) this.dateSource = source;
37
+ else if (this.dateSource) delete this.dateSource;
31
38
  this.date = date;
32
- if (date) this.fireEvent('setDate', date)
39
+ this.fireEvent('setDate', [date, source])
33
40
  },
34
41
 
35
42
  formatDate: function(date) {
@@ -49,18 +56,21 @@ LSD.Trait.Date = new Class({
49
56
  return new Date;
50
57
  },
51
58
 
52
- parseDate: function(date) {
53
- return Date.parse(date);
59
+ parseDate: function(input) {
60
+ var date = Date.parse(input);
61
+ if (date.isValid()) return date;
54
62
  },
55
63
 
56
- increment: function(number) {
64
+ increment: function(number, interval) {
57
65
  number = number.toInt ? number.toInt() : 1;
58
- this.setDate(this.getDate().increment(this.options.date.interval, number))
66
+ this.setDate(this.getDate().clone().increment(interval || this.options.date.interval, number))
59
67
  },
60
68
 
61
- decrement: function(number) {
69
+ decrement: function(number, interval) {
62
70
  number = number.toInt ? number.toInt() : 1;
63
- this.setDate(this.getDate().decrement(this.options.date.interval, number))
71
+ this.setDate(this.getDate().clone().decrement(interval || this.options.date.interval, number))
64
72
  }
65
73
 
66
- });
74
+ });
75
+
76
+ LSD.Behavior.define(':date', 'date');
@@ -14,8 +14,13 @@ requires:
14
14
  - Widgets/LSD.Widget.Menu.Context
15
15
 
16
16
  provides:
17
- - LSD.Trait.Menu
17
+ - LSD.Trait.Details
18
18
 
19
19
  ...
20
20
  */
21
21
 
22
+ LSD.Mixin.Details = new Class({
23
+
24
+ });
25
+
26
+ LSD.Behaviour.define(':details', 'details');
@@ -110,4 +110,4 @@ LSD.Mixin.Draggable = new Class({
110
110
 
111
111
  });
112
112
 
113
- LSD.Behavior.define('[draggable]', LSD.Mixin.Draggable);
113
+ LSD.Behavior.define('[draggable]', 'draggable');
@@ -26,6 +26,9 @@ LSD.Mixin.Fieldset = new Class({
26
26
  scopes: {
27
27
  submittable: {
28
28
  filter: '[name]:valued'
29
+ },
30
+ invalid: {
31
+ filter: ':invalid'
29
32
  }
30
33
  },
31
34
  callbacks: {
@@ -42,41 +45,20 @@ LSD.Mixin.Fieldset = new Class({
42
45
  }
43
46
  },
44
47
 
45
- constructors: {
46
- fieldset: function() {
47
- this.names = {};
48
- this.params = {};
49
- return {
50
- events: {
51
- request: {
52
- request: 'validateFields',
53
- badRequest: 'parseFieldErrors'
54
- },
55
- self: {
56
- beforeNodeBuild: function(query, widget) {
57
- if (!widget.options.clone) return;
58
- var attrs = query.attributes, attributes = widget.attributes;
59
- var name = attributes.name, id = attributes.id;
60
- // bump name index
61
- if (name) (attrs || (attrs = {})).name = Fieldset.bumpName(name) || name;
62
- // bump id index
63
- if (id) (attrs || (attrs = {})).id = Fieldset.bumpId(id) || id;
64
- if (widget.tagName == 'label') {
65
- var four = attributes['for'];
66
- if (four) (attrs || (attrs = {}))['for'] = Fieldset.bumpId(four) || four;
67
- }
68
- if (attrs) query.attributes = attrs;
69
- }
70
- }
71
- }
72
- }
73
- }
48
+ onMix: function() {
49
+ this.names = {};
50
+ this.params = {};
51
+ this.addEvents(LSD.Mixin.Fieldset.events);
52
+ },
53
+
54
+ onUnmix: function() {
55
+ this.removeEvents(LSD.Mixin.Fieldset.events);
74
56
  },
75
57
 
76
58
  checkValidity: function() {
77
- var valid = true;
78
- for (var i = 0, element; element = this.elements[i++];) if (!element.checkValidity()) valid = false;
79
- return valid;
59
+ return this.elements.every(function(element) {
60
+ return element.checkValidity();
61
+ });
80
62
  },
81
63
 
82
64
  getData: function() {
@@ -106,8 +88,19 @@ LSD.Mixin.Fieldset = new Class({
106
88
  var field = this.names[name];
107
89
  if (!field) continue;
108
90
  field.invalidate(errors[name]);
109
- this.invalid = true;
110
91
  }
92
+ this.errors = errors;
93
+ this.addEvent('beforeSubmit:once', this.removeFieldErrors);
94
+ },
95
+
96
+ removeFieldErrors: function() {
97
+ var errors = this.errors;
98
+ for (var name in errors) {
99
+ var field = this.names[name];
100
+ if (!field) continue;
101
+ if (field.invalid) field.setStateTo('invalid', false);
102
+ }
103
+ delete this.errors
111
104
  },
112
105
 
113
106
  parseFieldErrors: function(response) {
@@ -118,8 +111,8 @@ LSD.Mixin.Fieldset = new Class({
118
111
  } else { //rooted response (publication: {errors: {}}), new rails
119
112
  var regex = Fieldset.rPrefixAppender;
120
113
  for (var model in response) {
121
- var value = response[model], errors = value.errors;
122
- if (!errors) continue;
114
+ var value = response[model];
115
+ if (!(errors = value.errors)) continue;
123
116
  for (var i = 0, error; error = errors[i++];)
124
117
  result[Fieldset.getName(model, error[0])] = error[1];
125
118
  }
@@ -178,12 +171,6 @@ LSD.Mixin.Fieldset = new Class({
178
171
  }
179
172
  return object
180
173
  },
181
-
182
- invalidateFields: function(errors) {
183
- this.getFields(errors, function(field, error) {
184
- field.invalidate(error);
185
- });
186
- },
187
174
 
188
175
  getFieldsByName: function(fields, callback, root) {
189
176
  if (fields.call && (callback = fields)) fields = null;
@@ -194,13 +181,6 @@ LSD.Mixin.Fieldset = new Class({
194
181
  }.bind(this));
195
182
  },
196
183
 
197
- validateFields: function(fields) {
198
- if (!this.invalid) return;
199
- this.elements.each(function(field) {
200
- if (field.invalid) field.validate(true);
201
- });
202
- },
203
-
204
184
  getModelName: function() {
205
185
  for (var name in this.params) if (!this.params[name].nodeType) return name;
206
186
  }
@@ -230,6 +210,28 @@ var Fieldset = Object.append(LSD.Mixin.Fieldset, {
230
210
  }
231
211
  });
232
212
 
233
- LSD.Behavior.define(':fieldset', Fieldset);
213
+ Fieldset.events = {
214
+ request: {
215
+ badRequest: 'parseFieldErrors'
216
+ },
217
+ self: {
218
+ beforeNodeBuild: function(query, widget) {
219
+ if (!widget.options.clone) return;
220
+ var attrs = query.attributes, attributes = widget.attributes;
221
+ var name = attributes.name, id = attributes.id;
222
+ // bump name index
223
+ if (name) (attrs || (attrs = {})).name = Fieldset.bumpName(name) || name;
224
+ // bump id index
225
+ if (id) (attrs || (attrs = {})).id = Fieldset.bumpId(id) || id;
226
+ if (widget.tagName == 'label') {
227
+ var four = attributes['for'];
228
+ if (four) (attrs || (attrs = {}))['for'] = Fieldset.bumpId(four) || four;
229
+ }
230
+ if (attrs) query.attributes = attrs;
231
+ }
232
+ }
233
+ };
234
+
235
+ LSD.Behavior.define(':fieldset', 'fieldset');
234
236
 
235
237
  }();
@@ -22,88 +22,87 @@ provides:
22
22
 
23
23
  LSD.Mixin.Focusable = new Class({
24
24
  options: {
25
+ pseudos: Array.object('activatable'),
25
26
  actions: {
26
27
  focusable: {
27
28
  target: false,
28
29
  enable: function(target) {
29
- if (target.tabindex != null) {
30
- target.attributes.tabindex = target.tabindex
31
- if (target.focuser) target.element.set('tabindex', target.tabindex)
32
- delete target.tabindex;
33
- }
34
30
  if (target.attributes.tabindex == -1) return;
35
- target.getFocuser();
36
- target.addEvents(target.events.focus);
37
- target.element.addEvents(target.bindEvents({mousedown: 'retain'}));
31
+ if (!this.isNativelyFocusable()) target.getFocuser();
32
+ target.addEvents(LSD.Mixin.Focusable.events);
38
33
  },
39
34
 
40
35
  disable: function(target) {
41
- target.blur();
42
- if (target.options.tabindex == -1) return;
43
- target.tabindex = target.options.tabindex || 0;
44
- target.element.set('tabindex', -1)
45
- target.attributes.tabindex = -1;
46
- target.removeEvents(target.events.focus);
47
- target.element.removeEvents(target.bindEvents({mousedown: 'retain'}));
36
+ if (target.focused) target.blur();
37
+ if (target.focuser) target.focuser.destroy();
38
+ if (target.attributes.tabindex == -1) return;
39
+ target.removeEvents(LSD.Mixin.Focusable.events);
40
+ target.setAttribute('tabindex', target.tabindex);
48
41
  }
49
42
  }
50
- }
43
+ },
44
+ states: Array.object('focused')
51
45
  },
52
46
 
53
47
  getFocuser: function() {
54
48
  if (!this.focuser) this.focuser = new QFocuser(this.toElement(), {
55
49
  onWidgetFocus: this.onFocus.bind(this),
56
50
  onWidgetBlur: this.onBlur.bind(this),
57
- tabIndex: this.getAttribute('tabindex')
51
+ tabIndex: this.attributes.tabindex
58
52
  });
59
53
  return this.focuser;
60
54
  },
61
55
 
62
56
  focus: function(element) {
63
57
  if (element !== false) {
64
- this.getFocuser().focus(element || this.element);
58
+ if (this.focuser) this.focuser.focus(element.localName ? element : this.element);
59
+ else this.element.focus();
65
60
  this.document.activeElement = this;
66
61
  }
67
- if (this.focused) return;
68
- this.focused = true;
69
- this.fireEvent('focus', arguments);
70
- this.onStateChange('focused', true);
71
62
  LSD.Mixin.Focusable.Propagation.focus(this);
72
63
  },
73
64
 
74
65
  blur: function(propagated) {
75
- if (!this.focused) return;
76
- this.focused = false;
77
- this.fireEvent('blur', arguments);
78
- this.onStateChange('focused', false);
66
+ if (!this.focuser) this.element.blur();
79
67
  if (!propagated) LSD.Mixin.Focusable.Propagation.blur.delay(10, this, this);
80
68
  },
81
69
 
82
- retain: function(e) {
83
- if (e) e.preventDefault();
84
- this.focus();
85
- },
86
-
87
70
  onFocus: function() {
88
71
  this.focus(false);
89
72
  this.document.activeElement = this;
90
73
  },
91
74
 
92
75
  onBlur: function() {
93
- var active = this.document.activeElement;
94
- if (active == this) delete this.document.activeElement;
95
- while (active && (active = active.parentNode)) if (active == this) return;
96
- this.blur();
76
+ this.blurring = true;
77
+ !function() {
78
+ if (this.blurring === false) return;
79
+ delete this.blurring;
80
+ var active = this.document.activeElement;
81
+ if (active == this) delete this.document.activeElement;
82
+ while (active && (active = active.parentNode)) if (active == this) return;
83
+ this.blur();
84
+ }.delay(20, this);
97
85
  },
98
86
 
99
87
  getKeyListener: function() {
100
- return this.getFocuser().getKeyListener()
88
+ return this.isNativelyFocusable() ? this.toElement : this.getFocuser().getKeyListener()
89
+ },
90
+
91
+ isNativelyFocusable: function() {
92
+ return this.getElementTag() == 'input';
101
93
  }
102
94
  });
103
95
 
96
+ LSD.Mixin.Focusable.events = {
97
+ mousedown: 'focus'
98
+ };
99
+
104
100
  LSD.Mixin.Focusable.Propagation = {
105
101
  focus: function(parent) {
106
- while (parent = parent.parentNode) if (parent.getFocuser) parent.focus(false);
102
+ while (parent = parent.parentNode) if (parent.focus) {
103
+ parent.focus(false);
104
+ if (parent.blurring) parent.blurring = false;
105
+ }
107
106
  },
108
107
 
109
108
  blur: function(parent) {
@@ -114,9 +113,9 @@ LSD.Mixin.Focusable.Propagation = {
114
113
  }
115
114
  while (parent = parent.parentNode) {
116
115
  if (active && hierarchy.contains(parent)) break;
117
- if (parent.options && (parent.attributes.tabindex != null) && parent.blur) parent.blur(true);
116
+ if (parent.blur) parent.blur(true);
118
117
  }
119
118
  }
120
119
  };
121
120
 
122
- LSD.Behavior.define('[tabindex][tabindex!=-1], :focusable', LSD.Mixin.Focusable);
121
+ LSD.Behavior.define('[tabindex][tabindex!=-1], :focusable', 'focusable');
@@ -31,36 +31,35 @@ LSD.Mixin.Invokable = new Class({
31
31
  }
32
32
  }
33
33
  },
34
- states: {
35
- invoked: {
36
- enabler: 'invoke',
37
- disabler: 'revoke'
38
- }
39
- },
34
+ states: Array.object('invoked'),
40
35
  events: {
41
36
  _invokable: {
42
37
  submit: function() {
43
38
  this.revoke(true);
44
39
  },
45
- cancel: 'revoke'
40
+ cancel: 'revoke',
41
+ setParent: function(widget) {
42
+ this.invoke(widget)
43
+ },
44
+ unsetParent: 'revoke'
46
45
  }
47
46
  }
48
47
  },
49
48
 
50
- constructors: {
51
- invoker: function() {
52
- var invoker = this.invoker || this.options.invoker;
53
- if (invoker) this.invoke(invoker);
54
- }
49
+ onMix: function() {
50
+ var invoker = this.invoker || this.options.invoker;
51
+ if (invoker) this.invoke(invoker);
55
52
  },
56
53
 
57
54
  invoke: function(invoker) {
55
+ console.error('invoked', invoker.tagName);
58
56
  this.invoker = invoker;
59
- this.fireEvent('invoke', invoker);
57
+ this.fireEvent('invoke', arguments);
60
58
  this.fireEvent('register', ['invoker', invoker]);
61
59
  },
62
60
 
63
61
  revoke: function(soft) {
62
+ console.error('revoked');
64
63
  var invoker = this.invoker;
65
64
  if (soft !== true) this.invoker.uncallChain();
66
65
  this.fireEvent('revoke', invoker);
@@ -80,4 +79,4 @@ LSD.Mixin.Invokable = new Class({
80
79
  }
81
80
  });
82
81
 
83
- LSD.Behavior.define(':invokable', LSD.Mixin.Invokable);
82
+ LSD.Behavior.define(':invokable', 'invokable');
@@ -23,13 +23,6 @@ LSD.Mixin.List = new Class({
23
23
  options: {
24
24
  endless: true,
25
25
  force: false,
26
- proxies: {
27
- container: {
28
- condition: function(widget) {
29
- return !!widget.setList
30
- }
31
- }
32
- },
33
26
  shortcuts: {
34
27
  previous: 'previous',
35
28
  next: 'next'
@@ -38,22 +31,21 @@ LSD.Mixin.List = new Class({
38
31
  many: {
39
32
  items: {
40
33
  selector: ':item',
41
- traits: Array.fast('selectable'),
34
+ traits: Array.object('selectable'),
42
35
  as: 'list',
43
- pseudos: Array.fast('value'),
36
+ pseudos: Array.object('value'),
44
37
  options: function() {
45
38
  if (this.attributes.multiple) {
46
- return {pseudos: Array.fast('checkbox')};
39
+ return {pseudos: Array.object('checkbox')};
47
40
  } else {
48
- return {pseudos: Array.fast('radio'), radiogroup: this.lsd};
41
+ return {pseudos: Array.object('radio'), radiogroup: this.lsd};
49
42
  }
50
43
  },
51
44
  states: {
52
45
  link: {
53
46
  checked: 'selected',
54
47
  selected: 'checked'
55
- },
56
- add: Array.fast('selected', 'checked')
48
+ }
57
49
  },
58
50
  callbacks: {
59
51
  fill: 'fill',
@@ -62,7 +54,7 @@ LSD.Mixin.List = new Class({
62
54
  }
63
55
  }
64
56
  },
65
- states: Array.fast('empty')
57
+ states: Array.object('empty')
66
58
  },
67
59
 
68
60
  findItemByValue: function(value) {
@@ -74,11 +66,11 @@ LSD.Mixin.List = new Class({
74
66
  },
75
67
 
76
68
  sort: function(sort) {
77
- return this.getItems().sort(sort)
69
+ return this.items.sort(sort)
78
70
  },
79
71
 
80
72
  filter: function(filter) {
81
- return this.getItems().filter(filter)
73
+ return this.items.filter(filter)
82
74
  },
83
75
 
84
76
  next: function() {
@@ -96,4 +88,4 @@ LSD.Mixin.List = new Class({
96
88
  });
97
89
 
98
90
 
99
- LSD.Behavior.define(':list', LSD.Mixin.List);
91
+ LSD.Behavior.define(':list', 'list');
@@ -43,12 +43,7 @@ LSD.Mixin.Placeholder = new Class({
43
43
  }
44
44
  }
45
45
  },
46
- states: {
47
- placeheld: {
48
- enabler: 'placehold',
49
- disabler: 'unplacehold'
50
- }
51
- }
46
+ states: Array.object('placeheld')
52
47
  },
53
48
 
54
49
  getPlaceholder: function(){
@@ -74,4 +69,4 @@ LSD.Mixin.Placeholder = new Class({
74
69
 
75
70
  });
76
71
 
77
- LSD.Behavior.define('[placeholder]', LSD.Mixin.Placeholder);
72
+ LSD.Behavior.define('[placeholder]', 'placeholder');
@@ -25,7 +25,7 @@ LSD.Mixin.Request = new Class({
25
25
  request: {
26
26
  method: 'get'
27
27
  },
28
- states: Array.fast('working'),
28
+ states: Array.object('working'),
29
29
  events: {
30
30
  self: {
31
31
  submit: function() {
@@ -65,15 +65,17 @@ LSD.Mixin.Request = new Class({
65
65
  var request = this.getRequest(options);
66
66
  request.addEvent('complete:once', function() {
67
67
  if (callback) callback();
68
- if (request.isSuccess() && this.getCommandAction && this.getCommandAction() == 'submit')
68
+ if (request.isSuccess && request.isSuccess() && this.getCommandAction && this.getCommandAction() == 'submit')
69
69
  if (this.chainPhase == -1 || (this.chainPhase == this.getActionChain().length - 1))
70
70
  this.eachLink('optional', arguments, true);
71
71
  }.bind(this));
72
+ this.fireEvent('send', options);
72
73
  return request.send(options);
73
74
  },
74
75
 
75
76
  stop: function() {
76
77
  if (this.request) this.request.cancel();
78
+ this.fireEvent('stop');
77
79
  return this;
78
80
  },
79
81
 
@@ -117,4 +119,4 @@ LSD.Mixin.Request = new Class({
117
119
  }
118
120
  });
119
121
 
120
- LSD.Behavior.define(':form[action], [src], [href]', LSD.Mixin.Request);
122
+ LSD.Behavior.define(':form[action], [src], [href]', 'request');
@@ -61,7 +61,7 @@ LSD.Mixin.Resizable = new Class({
61
61
  initialize: function() {
62
62
  this.parent.apply(this, arguments);
63
63
  var options = this.options.resizer;
64
- var rules = (new FastArray).concat(this.getAttribute('resizable').split(/\s+/));
64
+ var rules = (new Object.Array).concat(this.getAttribute('resizable').split(/\s+/));
65
65
  options.modifiers.x = (!rules.x && rules.y) ? false : 'width';
66
66
  options.modifiers.y = (!rules.y && rules.x) ? false : 'height';
67
67
  options.fit = !!rules.fit;
@@ -117,7 +117,7 @@ LSD.Mixin.Resizable = new Class({
117
117
  return ((value == 'inherit') || (value == 'auto') || child.style.expressed[prop]) ? value : null
118
118
  }
119
119
  if (!this.liquid) {
120
- this.liquid = LSD.Module.DOM.walk(this, function(child) {
120
+ this.liquid = LSD.Module.DOM.each(this, function(child) {
121
121
  return getLiquid(c, 'width')
122
122
  }) || []
123
123
  this.liquid.include(this.resized);
@@ -179,4 +179,4 @@ LSD.Mixin.Resizable = new Class({
179
179
  }
180
180
  });
181
181
 
182
- LSD.Behavior.define('[resizable][resizable!=false]', LSD.Mixin.Resizable);
182
+ LSD.Behavior.define('[resizable][resizable!=false]', 'resizable');