sproutcore 0.9.1 → 0.9.2
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +233 -0
- data/Manifest.txt +67 -34
- data/bin/sc-build +12 -1
- data/bin/sc-gen +1 -1
- data/bin/sproutcore +14 -0
- data/clients/sc_docs/controllers/docs.js +38 -8
- data/clients/sc_docs/english.lproj/body.css +80 -127
- data/clients/sc_docs/english.lproj/body.rhtml +43 -23
- data/clients/sc_docs/english.lproj/no_docs.rhtml +2 -1
- data/clients/sc_docs/english.lproj/tabs.rhtml +16 -0
- data/clients/sc_docs/main.js +14 -9
- data/clients/sc_docs/models/doc.js +1 -1
- data/clients/sc_docs/tests/controllers/docs.rhtml +1 -2
- data/clients/sc_docs/tests/models/doc.rhtml +1 -2
- data/clients/sc_docs/tests/views/doc_frame.rhtml +1 -2
- data/clients/sc_docs/tests/views/doc_label_view.rhtml +1 -2
- data/clients/sc_docs/views/doc_frame.js +1 -1
- data/clients/sc_test_runner/controllers/runner.js +31 -8
- data/clients/sc_test_runner/english.lproj/body.css +62 -122
- data/clients/sc_test_runner/english.lproj/body.rhtml +62 -26
- data/clients/sc_test_runner/main.js +1 -6
- data/clients/sc_test_runner/models/test.js +14 -1
- data/clients/sc_test_runner/views/runner_frame.js +4 -2
- data/clients/view_builder/builders/builder.js +339 -0
- data/clients/view_builder/builders/button.js +81 -0
- data/clients/view_builder/controllers/document.js +21 -0
- data/clients/view_builder/core.js +19 -0
- data/clients/view_builder/english.lproj/body.css +77 -0
- data/clients/view_builder/english.lproj/body.rhtml +41 -0
- data/clients/{sc_docs → view_builder}/english.lproj/controls.css +0 -0
- data/clients/view_builder/english.lproj/strings.js +14 -0
- data/clients/view_builder/main.js +38 -0
- data/clients/view_builder/tests/controllers/document.rhtml +20 -0
- data/clients/view_builder/tests/views/builder.rhtml +20 -0
- data/clients/view_builder/views/builder.js +23 -0
- data/frameworks/prototype/prototype.js +1 -1
- data/frameworks/sproutcore/Core.js +32 -7
- data/frameworks/sproutcore/README +1 -1
- data/frameworks/sproutcore/animation/animation.js +411 -0
- data/frameworks/sproutcore/controllers/array.js +17 -9
- data/frameworks/sproutcore/controllers/collection.js +9 -110
- data/frameworks/sproutcore/controllers/controller.js +1 -1
- data/frameworks/sproutcore/controllers/object.js +2 -1
- data/frameworks/sproutcore/drag/drag.js +267 -56
- data/frameworks/sproutcore/drag/drag_data_source.js +24 -16
- data/frameworks/sproutcore/drag/drag_source.js +53 -42
- data/frameworks/sproutcore/drag/drop_target.js +2 -2
- data/frameworks/sproutcore/english.lproj/buttons.css +337 -236
- data/frameworks/sproutcore/english.lproj/core.css +115 -0
- data/frameworks/sproutcore/english.lproj/icons.css +227 -0
- data/{clients/sc_docs → frameworks/sproutcore}/english.lproj/images/indicator.gif +0 -0
- data/frameworks/sproutcore/english.lproj/images/sc-theme-sprite.png +0 -0
- data/frameworks/sproutcore/english.lproj/images/sc-theme-ysprite.png +0 -0
- data/frameworks/sproutcore/english.lproj/images/shared-icons.png +0 -0
- data/frameworks/sproutcore/english.lproj/menu.css +1 -1
- data/frameworks/sproutcore/english.lproj/strings.js +1 -1
- data/frameworks/sproutcore/english.lproj/theme.css +405 -31
- data/frameworks/sproutcore/foundation/application.js +15 -11
- data/frameworks/sproutcore/foundation/benchmark.js +1 -1
- data/frameworks/sproutcore/foundation/binding.js +2 -2
- data/frameworks/sproutcore/foundation/date.js +1 -1
- data/frameworks/sproutcore/foundation/error.js +1 -1
- data/frameworks/sproutcore/foundation/input_manager.js +32 -21
- data/frameworks/sproutcore/foundation/mock.js +1 -1
- data/frameworks/sproutcore/foundation/node_descriptor.js +9 -6
- data/frameworks/sproutcore/foundation/object.js +249 -177
- data/frameworks/sproutcore/foundation/page.js +5 -2
- data/frameworks/sproutcore/foundation/path_module.js +11 -10
- data/frameworks/sproutcore/foundation/responder.js +5 -2
- data/frameworks/sproutcore/foundation/routes.js +17 -13
- data/frameworks/sproutcore/foundation/run_loop.js +249 -11
- data/frameworks/sproutcore/foundation/server.js +1 -1
- data/frameworks/sproutcore/foundation/set.js +3 -3
- data/frameworks/sproutcore/foundation/string.js +5 -3
- data/frameworks/sproutcore/foundation/timer.js +371 -0
- data/frameworks/sproutcore/foundation/undo_manager.js +1 -1
- data/frameworks/sproutcore/foundation/unittest.js +3 -3
- data/frameworks/sproutcore/foundation/utils.js +161 -2
- data/frameworks/sproutcore/globals/panels.js +1 -1
- data/frameworks/sproutcore/globals/popups.js +4 -3
- data/frameworks/sproutcore/globals/window.js +44 -4
- data/frameworks/sproutcore/lib/button_views.rb +328 -0
- data/frameworks/sproutcore/lib/collection_view.rb +80 -0
- data/frameworks/sproutcore/lib/core_views.rb +281 -0
- data/frameworks/sproutcore/lib/form_views.rb +253 -0
- data/frameworks/sproutcore/lib/index.rhtml +2 -0
- data/frameworks/sproutcore/lib/menu_views.rb +88 -0
- data/frameworks/sproutcore/{foundation → mixins}/array.js +60 -29
- data/frameworks/sproutcore/mixins/control.js +265 -0
- data/frameworks/sproutcore/mixins/delegate_support.js +66 -0
- data/frameworks/sproutcore/{foundation → mixins}/observable.js +176 -6
- data/frameworks/sproutcore/mixins/scrollable.js +245 -0
- data/frameworks/sproutcore/mixins/selection_support.js +148 -0
- data/frameworks/sproutcore/mixins/validatable.js +152 -0
- data/frameworks/sproutcore/models/collection.js +5 -5
- data/frameworks/sproutcore/models/record.js +1 -1
- data/frameworks/sproutcore/models/store.js +1 -1
- data/frameworks/sproutcore/panes/dialog.js +1 -1
- data/frameworks/sproutcore/panes/manager.js +1 -1
- data/frameworks/sproutcore/panes/menu.js +1 -1
- data/frameworks/sproutcore/panes/overlay.js +2 -2
- data/frameworks/sproutcore/panes/panel.js +1 -1
- data/frameworks/sproutcore/panes/picker.js +1 -1
- data/frameworks/sproutcore/tests/controllers/array.rhtml +44 -4
- data/frameworks/sproutcore/tests/foundation/timer/invalidate.rhtml +33 -0
- data/frameworks/sproutcore/tests/foundation/timer/invokeLater.rhtml +145 -0
- data/frameworks/sproutcore/tests/foundation/timer/isPaused.rhtml +70 -0
- data/frameworks/sproutcore/tests/foundation/timer/schedule.rhtml +145 -0
- data/frameworks/sproutcore/tests/views/{scroll.rhtml → checkbox.rhtml} +3 -3
- data/frameworks/sproutcore/tests/views/{collection.rhtml → collection/base.rhtml} +33 -32
- data/frameworks/sproutcore/tests/views/collection/incremental_rendering.rhtml +260 -0
- data/frameworks/sproutcore/tests/views/image_cell.rhtml +19 -0
- data/frameworks/sproutcore/tests/views/label_item.rhtml +2 -4
- data/frameworks/sproutcore/tests/views/list.rhtml +2 -3
- data/frameworks/sproutcore/tests/views/list_item.rhtml +20 -0
- data/frameworks/sproutcore/tests/views/slider.rhtml +20 -0
- data/frameworks/sproutcore/tests/views/text_cell.rhtml +19 -0
- data/frameworks/sproutcore/tests/views/view/clippingFrame.rhtml +395 -0
- data/frameworks/sproutcore/tests/views/view/frame.rhtml +353 -0
- data/frameworks/sproutcore/tests/views/view/innerFrame.rhtml +347 -0
- data/frameworks/sproutcore/tests/views/view/isVisibleInWindow.rhtml +148 -0
- data/frameworks/sproutcore/tests/views/view/scrollFrame.rhtml +468 -0
- data/frameworks/sproutcore/validators/credit_card.js +33 -13
- data/frameworks/sproutcore/validators/date.js +26 -6
- data/frameworks/sproutcore/validators/email.js +21 -3
- data/frameworks/sproutcore/validators/not_empty.js +11 -1
- data/frameworks/sproutcore/validators/number.js +18 -4
- data/frameworks/sproutcore/validators/password.js +12 -1
- data/frameworks/sproutcore/validators/validator.js +204 -194
- data/frameworks/sproutcore/views/{button.js → button/button.js} +96 -94
- data/frameworks/sproutcore/views/button/checkbox.js +29 -0
- data/frameworks/sproutcore/views/button/disclosure.js +42 -0
- data/frameworks/sproutcore/views/button/radio.js +29 -0
- data/frameworks/sproutcore/views/{collection.js → collection/collection.js} +1373 -1024
- data/frameworks/sproutcore/views/collection/grid.js +124 -46
- data/frameworks/sproutcore/views/collection/image_cell.js +17 -46
- data/frameworks/sproutcore/views/collection/list.js +45 -35
- data/frameworks/sproutcore/views/collection/source_list.js +386 -0
- data/frameworks/sproutcore/views/collection/table.js +118 -0
- data/frameworks/sproutcore/views/container.js +7 -2
- data/frameworks/sproutcore/views/error_explanation.js +23 -10
- data/frameworks/sproutcore/views/{checkbox_field.js → field/checkbox_field.js} +16 -6
- data/frameworks/sproutcore/views/field/field.js +219 -0
- data/frameworks/sproutcore/views/{radio_field.js → field/radio_field.js} +27 -12
- data/frameworks/sproutcore/views/{select_field.js → field/select_field.js} +116 -90
- data/frameworks/sproutcore/views/{text_field.js → field/text_field.js} +57 -8
- data/frameworks/sproutcore/views/{textarea_field.js → field/textarea_field.js} +13 -3
- data/frameworks/sproutcore/views/filter_button.js +2 -2
- data/frameworks/sproutcore/views/form.js +3 -3
- data/frameworks/sproutcore/views/image.js +128 -21
- data/frameworks/sproutcore/views/inline_text_editor.js +1 -1
- data/frameworks/sproutcore/views/label.js +149 -92
- data/frameworks/sproutcore/views/list_item.js +225 -0
- data/frameworks/sproutcore/views/menu_item.js +10 -4
- data/frameworks/sproutcore/views/pagination.js +11 -4
- data/frameworks/sproutcore/views/popup_button.js +25 -21
- data/frameworks/sproutcore/views/popup_menu.js +10 -4
- data/frameworks/sproutcore/views/progress.js +29 -16
- data/frameworks/sproutcore/views/radio_group.js +1 -1
- data/frameworks/sproutcore/views/scroll.js +60 -20
- data/frameworks/sproutcore/views/segmented.js +1 -1
- data/frameworks/sproutcore/views/slider.js +132 -0
- data/frameworks/sproutcore/views/source_list_group.js +130 -0
- data/frameworks/sproutcore/views/spinner.js +1 -1
- data/frameworks/sproutcore/views/split.js +292 -0
- data/frameworks/sproutcore/views/split_divider.js +109 -0
- data/frameworks/sproutcore/views/tab.js +1 -1
- data/frameworks/sproutcore/views/toolbar.js +1 -1
- data/frameworks/sproutcore/views/view.js +1272 -591
- data/generators/client/templates/english.lproj/body.css +1 -1
- data/generators/controller/controller_generator.rb +1 -1
- data/generators/controller/templates/test.rhtml +2 -1
- data/generators/model/templates/test.rhtml +1 -1
- data/generators/test/templates/test.rhtml +1 -1
- data/generators/view/templates/test.rhtml +1 -1
- data/jsdoc/templates/sproutcore/class.tmpl +241 -338
- data/jsdoc/templates/sproutcore/default.css +105 -155
- data/jsdoc/templates/sproutcore/index.tmpl +43 -8
- data/jsdoc/templates/sproutcore/publish.js +9 -4
- data/lib/sproutcore/build_tools/html_builder.rb +29 -13
- data/lib/sproutcore/build_tools/resource_builder.rb +1 -1
- data/lib/sproutcore/bundle.rb +86 -25
- data/lib/sproutcore/jsdoc.rb +2 -0
- data/lib/sproutcore/version.rb +1 -1
- data/lib/sproutcore/view_helpers.rb +36 -3
- data/tasks/deployment.rake +1 -1
- metadata +69 -36
- data/clients/sc_docs/english.lproj/icons/small/next.png +0 -0
- data/clients/sc_docs/english.lproj/icons/small/reset.png +0 -0
- data/clients/sc_docs/english.lproj/images/gradients.png +0 -0
- data/clients/sc_docs/english.lproj/images/toolbar.png +0 -0
- data/clients/sc_docs/english.lproj/warning.rhtml +0 -6
- data/clients/sc_test_runner/english.lproj/warning.rhtml +0 -6
- data/frameworks/sproutcore/english.lproj/buttons.png +0 -0
- data/frameworks/sproutcore/english.lproj/collections.css +0 -82
- data/frameworks/sproutcore/english.lproj/images/buttons-sprite.png +0 -0
- data/frameworks/sproutcore/views/collection/collection_item.js +0 -36
- data/frameworks/sproutcore/views/collection/text_cell.js +0 -128
- data/frameworks/sproutcore/views/field.js +0 -214
- data/frameworks/sproutcore/views/workspace.js +0 -170
- data/generators/client/templates/english.lproj/controls.css +0 -0
- data/generators/framework/templates/english.lproj/body.css +0 -0
- data/generators/framework/templates/english.lproj/body.rhtml +0 -3
- data/generators/framework/templates/english.lproj/controls.css +0 -0
- data/lib/sproutcore/view_helpers/button_views.rb +0 -302
- data/lib/sproutcore/view_helpers/core_views.rb +0 -292
- data/lib/sproutcore/view_helpers/form_views.rb +0 -258
- data/lib/sproutcore/view_helpers/menu_views.rb +0 -94
@@ -12,15 +12,10 @@ function main() {
|
|
12
12
|
var clientName = indexRoot.match(/([^\/]+)\/-tests/)[1];
|
13
13
|
var urlRoot = indexRoot.replace(new RegExp("^%@/?".fmt(window.indexPrefix)), window.urlPrefix + '/');
|
14
14
|
console.log('indexRoot: %@ clientName: %@ urlRoot: %@'.fmt( indexRoot, clientName, urlRoot));
|
15
|
-
|
15
|
+
|
16
16
|
TestRunner.runnerController.set('selection',[]) ;
|
17
17
|
TestRunner.runnerController.set('urlRoot', urlRoot) ;
|
18
18
|
TestRunner.runnerController.set('indexRoot', indexRoot) ;
|
19
19
|
TestRunner.runnerController.set('clientName', clientName) ;
|
20
20
|
TestRunner.runnerController.reloadTests() ;
|
21
21
|
} ;
|
22
|
-
|
23
|
-
TestRunner.hidePanels = function() {
|
24
|
-
SC.page.get('warningPanel').set('isVisible', false) ;
|
25
|
-
SC.page.get('noTestsPanel').set('isVisible',false) ;
|
26
|
-
} ;
|
@@ -8,7 +8,20 @@ TestRunner.Test = SC.Record.extend({
|
|
8
8
|
|
9
9
|
// TODO: Add your own code here.
|
10
10
|
title: function() {
|
11
|
-
|
11
|
+
if (!this._title) {
|
12
|
+
var parts = (this.get('name') || '').split('/') ;
|
13
|
+
var ret = parts.pop() || '' ;
|
14
|
+
this._title = ret.replace(/\.rhtml$/,'').replace(/_/g,' ');
|
15
|
+
}
|
16
|
+
return this._title ;
|
17
|
+
}.property('name'),
|
18
|
+
|
19
|
+
group: function() {
|
20
|
+
if (!this._group) {
|
21
|
+
var parts = (this.get('name') || '').split('/') ;
|
22
|
+
this._group = parts.slice(0,parts.length-1).join('/').toLowerCase() ;
|
23
|
+
}
|
24
|
+
return this._group;
|
12
25
|
}.property('name')
|
13
26
|
|
14
27
|
}) ;
|
@@ -29,7 +29,9 @@ TestRunner.RunnerFrameView = SC.View.extend({
|
|
29
29
|
|
30
30
|
// if the document URL is already loaded, then reload it...
|
31
31
|
if (url == this.rootElement.src) {
|
32
|
-
|
32
|
+
this.rootElement.src = 'javascript:;' ;
|
33
|
+
this.rootElement.src = url ;
|
34
|
+
// if (doc && doc.location) doc.location.reload() ;
|
33
35
|
|
34
36
|
// otherwise set to the new URL.
|
35
37
|
} else {
|
@@ -65,7 +67,7 @@ TestRunner.RunnerFrameView = SC.View.extend({
|
|
65
67
|
}
|
66
68
|
|
67
69
|
if (this.get('state') != status) this.set('state', status) ;
|
68
|
-
if (reschedule)
|
70
|
+
if (reschedule) this.invokeLater(this.checkState,100) ;
|
69
71
|
|
70
72
|
}
|
71
73
|
|
@@ -0,0 +1,339 @@
|
|
1
|
+
// ==========================================================================
|
2
|
+
// Basic View Builder
|
3
|
+
// ==========================================================================
|
4
|
+
|
5
|
+
/**
|
6
|
+
A Builder can generate HTML, JavaScript and CSS based on a set of input
|
7
|
+
attributes. It expects to have the following attributes defined:
|
8
|
+
|
9
|
+
- targetClass: The name of the output class for JavaScript purposes.
|
10
|
+
- name: the human readable name
|
11
|
+
- guid: an internally unique id used to identify the resource.
|
12
|
+
|
13
|
+
- htmlTemplate: the html template to render.
|
14
|
+
- tagName: the tag name
|
15
|
+
- htmlId: ID used for tag
|
16
|
+
- cssClassNames: class names to add to tag.
|
17
|
+
- attributes: { src: "item" } -- HTML attrs to include.
|
18
|
+
|
19
|
+
- targetClass: name of output class.
|
20
|
+
- key: name of object when added to parent.
|
21
|
+
- properties: properties to place on JS object.
|
22
|
+
- bind: named bindings. each binding is like:
|
23
|
+
{ to: path, kind: 'SC.Binding.Kind', isEnabled: YES }
|
24
|
+
|
25
|
+
- children: Array of child view builder records, in order. If any.
|
26
|
+
- parent: parent builder or null if top level.
|
27
|
+
- inPage: YES if should be added to SC.page.
|
28
|
+
|
29
|
+
You can add any other properties as well. Use them when your callbacks are
|
30
|
+
invoked to enhance these properties before they are generated.
|
31
|
+
*/
|
32
|
+
SC.Builder = SC.Record.extend({
|
33
|
+
|
34
|
+
_targetClass: 'SC.Object',
|
35
|
+
|
36
|
+
/**
|
37
|
+
Defined by subclasses. If this is true, then the content of the view
|
38
|
+
is the HTML generated by children.
|
39
|
+
*/
|
40
|
+
isContainer: NO,
|
41
|
+
|
42
|
+
/**
|
43
|
+
Defined by subclasses. If true, then views will be generated with an
|
44
|
+
outletFor() attached to them.
|
45
|
+
*/
|
46
|
+
isOutletView: YES,
|
47
|
+
|
48
|
+
childrenType: 'SC.Builder',
|
49
|
+
|
50
|
+
parentType: 'SC.Builder',
|
51
|
+
|
52
|
+
/**
|
53
|
+
The default profile. New records will inherit a cloned set of these
|
54
|
+
attributes.
|
55
|
+
*/
|
56
|
+
defaultAttributes: {
|
57
|
+
propertySettings: {},
|
58
|
+
bindSettings: {},
|
59
|
+
attributeSettings: {},
|
60
|
+
htmlTemplate: '<{%TagName%}{%Attributes%}>{%Content%}</{%TagName%}>',
|
61
|
+
cssClassNames: [],
|
62
|
+
innerHtml: '',
|
63
|
+
lazyOutlet: NO
|
64
|
+
},
|
65
|
+
|
66
|
+
init: function() {
|
67
|
+
arguments.callee.base.apply(this) ;
|
68
|
+
if (this.get('newRecord')) {
|
69
|
+
var attrs = this._deepClone(this.get('defaultAttributes'));
|
70
|
+
attrs.name = attrs.targetClass = this._targetClass ;
|
71
|
+
attrs.guid = attrs.htmlId = 'id%@'.fmt(Date.now().toString());
|
72
|
+
this.updateAttributes(attrs, YES, YES);
|
73
|
+
}
|
74
|
+
},
|
75
|
+
|
76
|
+
/**
|
77
|
+
Invoked just before the attributes are written out. You can add anything
|
78
|
+
you want here.
|
79
|
+
*/
|
80
|
+
prepareAttributes: function(attrs) {
|
81
|
+
return attrs ;
|
82
|
+
},
|
83
|
+
|
84
|
+
/**
|
85
|
+
Invoked just before the class name is set. Add anything you want here.
|
86
|
+
*/
|
87
|
+
prepareClassNames: function(classNames) {
|
88
|
+
return classNames ;
|
89
|
+
},
|
90
|
+
|
91
|
+
/**
|
92
|
+
Invoked just before outlets are added and the final JS is generated. Add
|
93
|
+
anything here you might pull from specialized preferences.
|
94
|
+
*/
|
95
|
+
prepareProperties: function(props) { return props; },
|
96
|
+
|
97
|
+
/**
|
98
|
+
Invoked just before bindings are blended into properties. Add your own.
|
99
|
+
*/
|
100
|
+
prepareBindings: function(binds) { return binds; },
|
101
|
+
|
102
|
+
// ..........................................
|
103
|
+
// HTML RENDERING
|
104
|
+
//
|
105
|
+
|
106
|
+
/**
|
107
|
+
Computes the HTML for this builder. HTML is built by interpolating the
|
108
|
+
htmlTemplate. Any variables must match a corresponding property on the
|
109
|
+
record with 'html' added to the beginning.
|
110
|
+
*/
|
111
|
+
htmlPart: function() {
|
112
|
+
var template = this.get('htmlTemplate') ;
|
113
|
+
if (!template) return null ;
|
114
|
+
|
115
|
+
var that = this;
|
116
|
+
return template.replace(/{%(.+?)%}/g,function(m,p) {
|
117
|
+
return (p[0] == '%') ? p.slice(1,p.length) : that.get('html' + p) ;
|
118
|
+
}) ;
|
119
|
+
}.property('htmlTemplate', 'htmlContent', 'htmlTagName', 'htmlAttributes'),
|
120
|
+
|
121
|
+
/**
|
122
|
+
The tag name for the HTML. Usually specified by tagName in the
|
123
|
+
attributes.
|
124
|
+
*/
|
125
|
+
htmlTagName: function() {
|
126
|
+
return this.get('tagName') || 'div';
|
127
|
+
}.property('tagName'),
|
128
|
+
|
129
|
+
/**
|
130
|
+
The attributes for the HTML. Combines attributes hash, css classes,
|
131
|
+
and id. It then calls prepareAttributes() so you can do any extra
|
132
|
+
processing you need.
|
133
|
+
*/
|
134
|
+
htmlAttributes: function() {
|
135
|
+
// start with attributeSettings.
|
136
|
+
var attrs = this._deepClone(this.get('attributeSettings')) || {} ;
|
137
|
+
|
138
|
+
// add id
|
139
|
+
attrs.id = this.get('htmlId') ;
|
140
|
+
|
141
|
+
// merge in CSS class names
|
142
|
+
var cssClassNames = this.get('cssClassNames') || [] ;
|
143
|
+
if ($type(cssClassNames) === T_STRING) {
|
144
|
+
cssClassNames = cssClassNames.split(' ') ;
|
145
|
+
}
|
146
|
+
|
147
|
+
var cur = attrs['class'] || [] ;
|
148
|
+
if ($type(cur) === T_STRING) {
|
149
|
+
cur = cur.split(' ') ;
|
150
|
+
}
|
151
|
+
|
152
|
+
cur = cur.concat(cssClassNames).uniq().compact().sort() ;
|
153
|
+
cur.push(attrs.id) ;
|
154
|
+
cur = this.prepareClassNames(cur) || cur;
|
155
|
+
if (cur.length > 0) {
|
156
|
+
attrs['class'] = cur.join(' ') ;
|
157
|
+
} else delete attrs['class'] ;
|
158
|
+
|
159
|
+
attrs = this.prepareAttributes(attrs) || attrs ;
|
160
|
+
|
161
|
+
// now convert to a string.
|
162
|
+
var ret = [''];
|
163
|
+
for(var key in attrs) {
|
164
|
+
if (!attrs.hasOwnProperty(key)) continue ;
|
165
|
+
ret.push('%@="%@"'.fmt(key, attrs[key])) ;
|
166
|
+
}
|
167
|
+
|
168
|
+
return (ret.length > 1) ? ret.join(' ') : '';
|
169
|
+
}.property('cssClassNames', 'attributeSettings', 'htmlId'),
|
170
|
+
|
171
|
+
/**
|
172
|
+
The inner content for the HTML. If isContainer is true, then we get
|
173
|
+
the children for this view and use their HTML, otherwise get the
|
174
|
+
innerHtml property.
|
175
|
+
*/
|
176
|
+
htmlContent: function() {
|
177
|
+
if (this.get('isContainer')) {
|
178
|
+
var children = this.get('children') || [] ;
|
179
|
+
var ret = [];
|
180
|
+
for(var idx=0;idx<children.length;idx++) {
|
181
|
+
var child = children.objectAt(idx) ;
|
182
|
+
ret.push(child.get('htmlPart')) ;
|
183
|
+
}
|
184
|
+
|
185
|
+
return ret.join('') ;
|
186
|
+
} else return this.get('innerHtml') ;
|
187
|
+
}.property('innerHtml', 'isContainer', 'children'),
|
188
|
+
|
189
|
+
// ..........................................
|
190
|
+
// JAVASCRIPT RENDERING
|
191
|
+
//
|
192
|
+
|
193
|
+
/**
|
194
|
+
Generates the JavaScript for this part.
|
195
|
+
|
196
|
+
This works by merging the propertySettings and bindSettings. Then it
|
197
|
+
calls your prepareProperties and finally merges in any outlets. With the
|
198
|
+
properties combined, it then generates the code to build a view.
|
199
|
+
*/
|
200
|
+
javascriptPart: function() {
|
201
|
+
var props = this.get('javascriptProperties') ;
|
202
|
+
|
203
|
+
var outlets = this.get('javascriptOutlets') ;
|
204
|
+
for(var key in outlets) {
|
205
|
+
if (!outlets.hasOwnProperty(key)) continue ;
|
206
|
+
props[key] = outlets[key] ;
|
207
|
+
}
|
208
|
+
|
209
|
+
var outletDeclaration = '' ;
|
210
|
+
var verb = 'create' ;
|
211
|
+
if (this.get('isOutletView')) {
|
212
|
+
verb = 'extend' ;
|
213
|
+
outletDeclaration = '.outletFor(".%@?")'.fmt(this.get('htmlId'));
|
214
|
+
}
|
215
|
+
|
216
|
+
return '%@.%@(%@)%@'.fmt(this.get('targetClass'), verb, this._stringify(props), outletDeclaration) ;
|
217
|
+
}.property(),
|
218
|
+
|
219
|
+
/**
|
220
|
+
Generates the properties for the JavaScript sans any outlets.
|
221
|
+
*/
|
222
|
+
javascriptProperties: function() {
|
223
|
+
var props = this._deepClone(this.get('propertySettings')) ;
|
224
|
+
props = this.prepareProperties(props) || props ;
|
225
|
+
|
226
|
+
var binds = this._deepClone(this.get('bindSettings')) ;
|
227
|
+
binds = this.prepareBindings(binds) || binds ;
|
228
|
+
for(var key in binds) {
|
229
|
+
if (!binds.hasOwnProperty(key)) continue ;
|
230
|
+
|
231
|
+
var bind = binds[key] ;
|
232
|
+
if (!bind.isEnabled) continue ;
|
233
|
+
bind = (bind.kind) ? "%@('%@')".fmt(bind.kind, bind.to) : "'%@'".fmt(bind.to) ;
|
234
|
+
props[key + 'Binding'] = bind ;
|
235
|
+
}
|
236
|
+
|
237
|
+
return props ;
|
238
|
+
}.property(),
|
239
|
+
|
240
|
+
/**
|
241
|
+
Generates the outlet properties for the JavaScript.
|
242
|
+
*/
|
243
|
+
javascriptOutlets: function() {
|
244
|
+
var ret = {} ;
|
245
|
+
var outlets = [] ;
|
246
|
+
|
247
|
+
// loop through children.
|
248
|
+
var children = this.get('children') || [];
|
249
|
+
var idx = children.length ;
|
250
|
+
if (idx <= 0) return {} ;
|
251
|
+
while(--idx >= 0) {
|
252
|
+
var child = children.objectAt(idx) ;
|
253
|
+
var outletName = child.get('outletName') ;
|
254
|
+
var js = child.get('javascriptPart') ;
|
255
|
+
ret[outletName] = js ;
|
256
|
+
if (!child.get('lazyOutlet')) outlets.push(outletName) ;
|
257
|
+
}
|
258
|
+
|
259
|
+
ret.outlets = outletName ;
|
260
|
+
return ret ;
|
261
|
+
}.property(),
|
262
|
+
|
263
|
+
outletName: function(key, value) {
|
264
|
+
if (value !== undefined) this.writeAttribute('outletName', value) ;
|
265
|
+
return this.readAttribute('outletName') || this.get('htmlId') ;
|
266
|
+
}.property(),
|
267
|
+
|
268
|
+
// ..........................................
|
269
|
+
// INTERNAL METHODS
|
270
|
+
//
|
271
|
+
|
272
|
+
// deep clones a hash of properties. expects only Hash, Array or
|
273
|
+
// primitives.
|
274
|
+
_deepClone: function(obj) {
|
275
|
+
var ret = obj ;
|
276
|
+
|
277
|
+
switch($type(obj)) {
|
278
|
+
case T_HASH:
|
279
|
+
ret = {} ;
|
280
|
+
for(var key in obj) {
|
281
|
+
if (!obj.hasOwnProperty(key)) continue ;
|
282
|
+
ret[key] = this._deepClone(obj[key]) ;
|
283
|
+
}
|
284
|
+
break ;
|
285
|
+
case T_ARRAY:
|
286
|
+
ret = [] ;
|
287
|
+
for(var idx=0;idx < obj.length; idx++) {
|
288
|
+
ret.push(this._deepClone(obj[idx])) ;
|
289
|
+
}
|
290
|
+
break ;
|
291
|
+
}
|
292
|
+
return ret ;
|
293
|
+
},
|
294
|
+
|
295
|
+
// converts the input object into a eval-able string
|
296
|
+
_stringify: function(obj) {
|
297
|
+
var ret = obj ;
|
298
|
+
switch($type(obj)) {
|
299
|
+
case T_HASH:
|
300
|
+
ret = [] ;
|
301
|
+
for(var key in obj) {
|
302
|
+
if (!obj.hasOwnProperty(key)) continue ;
|
303
|
+
ret.push([key, this._stringify(obj[key])].join(': ')) ;
|
304
|
+
}
|
305
|
+
ret = "{ %@ }".fmt(ret.join(",\n ")) ;
|
306
|
+
break ;
|
307
|
+
|
308
|
+
case T_ARRAY:
|
309
|
+
ret = [] ;
|
310
|
+
for(var idx=0; idx < obj.length; idx++) {
|
311
|
+
ret.push(this._stringify(obj[idx])) ;
|
312
|
+
}
|
313
|
+
ret = '[%@]'.fmt(ret.join(', ')) ;
|
314
|
+
break ;
|
315
|
+
|
316
|
+
case T_NULL:
|
317
|
+
ret = 'null' ;
|
318
|
+
break ;
|
319
|
+
|
320
|
+
// Strings can be either property paths or quoted strings. They are
|
321
|
+
// quoted strings if they are in "quotes". If they are strings they
|
322
|
+
// should be already quoted, etc.
|
323
|
+
case T_STRING:
|
324
|
+
ret = obj ;
|
325
|
+
break ;
|
326
|
+
|
327
|
+
default:
|
328
|
+
ret = (obj.toString) ? obj.toString() : obj ;
|
329
|
+
}
|
330
|
+
return ret ;
|
331
|
+
}
|
332
|
+
|
333
|
+
}) ;
|
334
|
+
|
335
|
+
SC.Builder.newBuilder = function(attrs) {
|
336
|
+
if (!attrs) attrs = {} ;
|
337
|
+
attrs.newRecord = YES ;
|
338
|
+
return this.create(attrs) ;
|
339
|
+
} ;
|
@@ -0,0 +1,81 @@
|
|
1
|
+
// ==========================================================================
|
2
|
+
// Button View Builder
|
3
|
+
// ==========================================================================
|
4
|
+
|
5
|
+
require('builders/builder') ;
|
6
|
+
|
7
|
+
/**
|
8
|
+
*/
|
9
|
+
SC.ButtonView.Builder = SC.Builder.extend({
|
10
|
+
|
11
|
+
_targetClass: 'SC.ButtonView',
|
12
|
+
|
13
|
+
/**
|
14
|
+
Defined by subclasses. If this is true, then the content of the view
|
15
|
+
is the HTML generated by children.
|
16
|
+
*/
|
17
|
+
isContainer: NO,
|
18
|
+
|
19
|
+
/**
|
20
|
+
Defined by subclasses. If true, then views will be generated with an
|
21
|
+
outletFor() attached to them.
|
22
|
+
*/
|
23
|
+
isOutletView: YES,
|
24
|
+
|
25
|
+
/**
|
26
|
+
The default profile. New records will inherit a cloned set of these
|
27
|
+
attributes.
|
28
|
+
*/
|
29
|
+
defaultAttributes: {
|
30
|
+
propertySettings: {},
|
31
|
+
bindSettings: {},
|
32
|
+
attributeSettings: {},
|
33
|
+
htmlTemplate: '<{%TagName%}{%Attributes%}><span class="button-inner"><span class="label">{%Content%}</span></span></{%TagName%}>',
|
34
|
+
cssClassNames: ['sc-button-view', 'regular', 'normal'],
|
35
|
+
lazyOutlet: NO,
|
36
|
+
tagName: 'a',
|
37
|
+
|
38
|
+
title: 'Hello!'
|
39
|
+
},
|
40
|
+
|
41
|
+
init: function() {
|
42
|
+
arguments.callee.base.apply(this) ;
|
43
|
+
if (this.get('newRecord')) {
|
44
|
+
var attrs = this._deepClone(this.get('defaultAttributes'));
|
45
|
+
attrs.name = attrs.targetClass = this._targetClass ;
|
46
|
+
attrs.guid = attrs.htmlId = 'id%@'.fmt(Date.now().toString());
|
47
|
+
this.updateAttributes(attrs, YES, YES);
|
48
|
+
}
|
49
|
+
},
|
50
|
+
|
51
|
+
/**
|
52
|
+
Invoked just before the attributes are written out. You can add anything
|
53
|
+
you want here.
|
54
|
+
*/
|
55
|
+
prepareAttributes: function(attrs) {
|
56
|
+
return attrs ;
|
57
|
+
},
|
58
|
+
|
59
|
+
/**
|
60
|
+
Invoked just before the class name is set. Add anything you want here.
|
61
|
+
*/
|
62
|
+
prepareClassNames: function(classNames) {
|
63
|
+
return classNames ;
|
64
|
+
},
|
65
|
+
|
66
|
+
/**
|
67
|
+
Invoked just before outlets are added and the final JS is generated. Add
|
68
|
+
anything here you might pull from specialized preferences.
|
69
|
+
*/
|
70
|
+
prepareProperties: function(props) { return props; },
|
71
|
+
|
72
|
+
/**
|
73
|
+
Invoked just before bindings are blended into properties. Add your own.
|
74
|
+
*/
|
75
|
+
prepareBindings: function(binds) { return binds; },
|
76
|
+
|
77
|
+
innerHtml: function() {
|
78
|
+
return this.get('title') ;
|
79
|
+
}.property('title')
|
80
|
+
|
81
|
+
}) ;
|