sproutcore 0.9.0
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.
- data/History.txt +4 -0
- data/License.txt +20 -0
- data/Manifest.txt +269 -0
- data/README.txt +67 -0
- data/Rakefile +4 -0
- data/app_generators/sproutcore/USAGE +5 -0
- data/app_generators/sproutcore/sproutcore_generator.rb +66 -0
- data/app_generators/sproutcore/templates/README +77 -0
- data/app_generators/sproutcore/templates/environment.yml +4 -0
- data/bin/sc-build +145 -0
- data/bin/sc-gen +24 -0
- data/bin/sc-server +63 -0
- data/bin/sproutcore +21 -0
- data/clients/sc_docs/controllers/docs.js +118 -0
- data/clients/sc_docs/core.js +19 -0
- data/clients/sc_docs/english.lproj/body.css +159 -0
- data/clients/sc_docs/english.lproj/body.rhtml +33 -0
- data/clients/sc_docs/english.lproj/controls.css +0 -0
- 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/indicator.gif +0 -0
- data/clients/sc_docs/english.lproj/images/toolbar.png +0 -0
- data/clients/sc_docs/english.lproj/no_docs.rhtml +7 -0
- data/clients/sc_docs/english.lproj/strings.js +14 -0
- data/clients/sc_docs/english.lproj/warning.rhtml +6 -0
- data/clients/sc_docs/fixtures/doc.js +11 -0
- data/clients/sc_docs/main.js +21 -0
- data/clients/sc_docs/models/doc.js +9 -0
- data/clients/sc_docs/tests/controllers/docs.rhtml +21 -0
- data/clients/sc_docs/tests/models/doc.rhtml +21 -0
- data/clients/sc_docs/tests/views/doc_frame.rhtml +21 -0
- data/clients/sc_docs/tests/views/doc_label_view.rhtml +21 -0
- data/clients/sc_docs/views/doc_frame.js +33 -0
- data/clients/sc_docs/views/doc_label.js +20 -0
- data/clients/sc_test_runner/controllers/runner.js +175 -0
- data/clients/sc_test_runner/core.js +19 -0
- data/clients/sc_test_runner/english.lproj/body.css +151 -0
- data/clients/sc_test_runner/english.lproj/body.rhtml +35 -0
- data/clients/sc_test_runner/english.lproj/controls.css +0 -0
- data/clients/sc_test_runner/english.lproj/icons/small/next.png +0 -0
- data/clients/sc_test_runner/english.lproj/icons/small/reset.png +0 -0
- data/clients/sc_test_runner/english.lproj/images/gradients.png +0 -0
- data/clients/sc_test_runner/english.lproj/images/indicator.gif +0 -0
- data/clients/sc_test_runner/english.lproj/images/toolbar.png +0 -0
- data/clients/sc_test_runner/english.lproj/no_tests.rhtml +6 -0
- data/clients/sc_test_runner/english.lproj/strings.js +14 -0
- data/clients/sc_test_runner/english.lproj/warning.rhtml +6 -0
- data/clients/sc_test_runner/fixtures/test.js +12 -0
- data/clients/sc_test_runner/main.js +26 -0
- data/clients/sc_test_runner/models/test.js +11 -0
- data/clients/sc_test_runner/views/runner_frame.js +72 -0
- data/clients/sc_test_runner/views/test_label.js +20 -0
- data/config/hoe.rb +70 -0
- data/config/requirements.rb +17 -0
- data/environment.yml +9 -0
- data/frameworks/prototype/prototype.js +4186 -0
- data/frameworks/sproutcore/Core.js +378 -0
- data/frameworks/sproutcore/README +3 -0
- data/frameworks/sproutcore/controllers/array.js +236 -0
- data/frameworks/sproutcore/controllers/collection.js +305 -0
- data/frameworks/sproutcore/controllers/controller.js +323 -0
- data/frameworks/sproutcore/controllers/object.js +372 -0
- data/frameworks/sproutcore/drag/drag.js +549 -0
- data/frameworks/sproutcore/drag/drag_data_source.js +32 -0
- data/frameworks/sproutcore/drag/drag_source.js +64 -0
- data/frameworks/sproutcore/drag/drop_target.js +153 -0
- data/frameworks/sproutcore/english.lproj/blank.gif +0 -0
- data/frameworks/sproutcore/english.lproj/buttons.css +589 -0
- data/frameworks/sproutcore/english.lproj/buttons.png +0 -0
- data/frameworks/sproutcore/english.lproj/inline_text_editor.css +21 -0
- data/frameworks/sproutcore/english.lproj/menu.css +121 -0
- data/frameworks/sproutcore/english.lproj/panels/background-fat.jpg +0 -0
- data/frameworks/sproutcore/english.lproj/panels/background-thin.jpg +0 -0
- data/frameworks/sproutcore/english.lproj/panels/bottom-edge.png +0 -0
- data/frameworks/sproutcore/english.lproj/panels/bottom-left-corner.png +0 -0
- data/frameworks/sproutcore/english.lproj/panels/bottom-right-corner.png +0 -0
- data/frameworks/sproutcore/english.lproj/panels/left-edge.png +0 -0
- data/frameworks/sproutcore/english.lproj/panels/overlay.png +0 -0
- data/frameworks/sproutcore/english.lproj/panels/right-edge.png +0 -0
- data/frameworks/sproutcore/english.lproj/panels/top-edge.png +0 -0
- data/frameworks/sproutcore/english.lproj/panels/top-left-corner.png +0 -0
- data/frameworks/sproutcore/english.lproj/panels/top-right-corner.png +0 -0
- data/frameworks/sproutcore/english.lproj/panes.css +155 -0
- data/frameworks/sproutcore/english.lproj/picker.css +22 -0
- data/frameworks/sproutcore/english.lproj/strings.js +15 -0
- data/frameworks/sproutcore/english.lproj/tab.css +23 -0
- data/frameworks/sproutcore/english.lproj/tests.css +67 -0
- data/frameworks/sproutcore/english.lproj/theme.css +77 -0
- data/frameworks/sproutcore/foundation/animator.js +670 -0
- data/frameworks/sproutcore/foundation/application.js +199 -0
- data/frameworks/sproutcore/foundation/array.js +348 -0
- data/frameworks/sproutcore/foundation/benchmark.js +211 -0
- data/frameworks/sproutcore/foundation/binding.js +384 -0
- data/frameworks/sproutcore/foundation/date.js +357 -0
- data/frameworks/sproutcore/foundation/error.js +39 -0
- data/frameworks/sproutcore/foundation/input_manager.js +153 -0
- data/frameworks/sproutcore/foundation/json.js +296 -0
- data/frameworks/sproutcore/foundation/mock.js +42 -0
- data/frameworks/sproutcore/foundation/node_descriptor.js +56 -0
- data/frameworks/sproutcore/foundation/object.js +777 -0
- data/frameworks/sproutcore/foundation/observable.js +451 -0
- data/frameworks/sproutcore/foundation/page.js +63 -0
- data/frameworks/sproutcore/foundation/path_module.js +413 -0
- data/frameworks/sproutcore/foundation/responder.js +310 -0
- data/frameworks/sproutcore/foundation/routes.js +371 -0
- data/frameworks/sproutcore/foundation/run_loop.js +21 -0
- data/frameworks/sproutcore/foundation/server.js +491 -0
- data/frameworks/sproutcore/foundation/set.js +96 -0
- data/frameworks/sproutcore/foundation/string.js +149 -0
- data/frameworks/sproutcore/foundation/undo_manager.js +186 -0
- data/frameworks/sproutcore/foundation/unittest.js +622 -0
- data/frameworks/sproutcore/foundation/utils.js +61 -0
- data/frameworks/sproutcore/globals/panels.js +182 -0
- data/frameworks/sproutcore/globals/popups.js +60 -0
- data/frameworks/sproutcore/globals/window.js +381 -0
- data/frameworks/sproutcore/lib/index.rhtml +66 -0
- data/frameworks/sproutcore/models/collection.js +395 -0
- data/frameworks/sproutcore/models/record.js +622 -0
- data/frameworks/sproutcore/models/store.js +295 -0
- data/frameworks/sproutcore/panes/dialog.js +16 -0
- data/frameworks/sproutcore/panes/manager.js +164 -0
- data/frameworks/sproutcore/panes/menu.js +45 -0
- data/frameworks/sproutcore/panes/overlay.js +231 -0
- data/frameworks/sproutcore/panes/pane.js +90 -0
- data/frameworks/sproutcore/panes/panel.js +19 -0
- data/frameworks/sproutcore/panes/picker.js +45 -0
- data/frameworks/sproutcore/tests/controllers/array.rhtml +86 -0
- data/frameworks/sproutcore/tests/controllers/controller.rhtml +273 -0
- data/frameworks/sproutcore/tests/controllers/object.rhtml +327 -0
- data/frameworks/sproutcore/tests/foundation/application.rhtml +125 -0
- data/frameworks/sproutcore/tests/foundation/array.rhtml +221 -0
- data/frameworks/sproutcore/tests/foundation/object.rhtml +69 -0
- data/frameworks/sproutcore/tests/globals/window.rhtml +45 -0
- data/frameworks/sproutcore/tests/panes/pane.rhtml +88 -0
- data/frameworks/sproutcore/tests/views/collection.rhtml +137 -0
- data/frameworks/sproutcore/tests/views/popup_button.rhtml +115 -0
- data/frameworks/sproutcore/tests/views/text_field.rhtml +37 -0
- data/frameworks/sproutcore/validators/credit_card.js +92 -0
- data/frameworks/sproutcore/validators/date.js +36 -0
- data/frameworks/sproutcore/validators/email.js +29 -0
- data/frameworks/sproutcore/validators/not_empty.js +24 -0
- data/frameworks/sproutcore/validators/number.js +55 -0
- data/frameworks/sproutcore/validators/password.js +78 -0
- data/frameworks/sproutcore/validators/validator.js +304 -0
- data/frameworks/sproutcore/views/button.js +425 -0
- data/frameworks/sproutcore/views/checkbox_field.js +30 -0
- data/frameworks/sproutcore/views/collection.js +1521 -0
- data/frameworks/sproutcore/views/container.js +62 -0
- data/frameworks/sproutcore/views/error_explanation.js +45 -0
- data/frameworks/sproutcore/views/field.js +214 -0
- data/frameworks/sproutcore/views/filter_button.js +29 -0
- data/frameworks/sproutcore/views/form.js +591 -0
- data/frameworks/sproutcore/views/image.js +141 -0
- data/frameworks/sproutcore/views/inline_text_editor.js +96 -0
- data/frameworks/sproutcore/views/label.js +176 -0
- data/frameworks/sproutcore/views/menu_item.js +90 -0
- data/frameworks/sproutcore/views/pagination.js +54 -0
- data/frameworks/sproutcore/views/popup_button.js +86 -0
- data/frameworks/sproutcore/views/popup_menu.js +137 -0
- data/frameworks/sproutcore/views/progress.js +100 -0
- data/frameworks/sproutcore/views/radio_field.js +107 -0
- data/frameworks/sproutcore/views/radio_group.js +48 -0
- data/frameworks/sproutcore/views/segmented.js +80 -0
- data/frameworks/sproutcore/views/select_field.js +272 -0
- data/frameworks/sproutcore/views/spinner.js +11 -0
- data/frameworks/sproutcore/views/tab.js +126 -0
- data/frameworks/sproutcore/views/text_field.js +179 -0
- data/frameworks/sproutcore/views/textarea_field.js +14 -0
- data/frameworks/sproutcore/views/toolbar.js +29 -0
- data/frameworks/sproutcore/views/view.js +1389 -0
- data/frameworks/sproutcore/views/workspace.js +170 -0
- data/generators/client/README +3 -0
- data/generators/client/USAGE +12 -0
- data/generators/client/client_generator.rb +53 -0
- data/generators/client/templates/core.js +19 -0
- data/generators/client/templates/english.lproj/body.css +0 -0
- data/generators/client/templates/english.lproj/body.rhtml +3 -0
- data/generators/client/templates/english.lproj/controls.css +0 -0
- data/generators/client/templates/english.lproj/strings.js +14 -0
- data/generators/client/templates/main.js +37 -0
- data/generators/controller/USAGE +16 -0
- data/generators/controller/controller_generator.rb +51 -0
- data/generators/controller/templates/controller.js +21 -0
- data/generators/controller/templates/test.rhtml +21 -0
- data/generators/framework/README +7 -0
- data/generators/framework/USAGE +12 -0
- data/generators/framework/framework_generator.rb +53 -0
- data/generators/framework/templates/core.js +20 -0
- data/generators/framework/templates/english.lproj/body.css +0 -0
- data/generators/framework/templates/english.lproj/body.rhtml +3 -0
- data/generators/framework/templates/english.lproj/controls.css +0 -0
- data/generators/framework/templates/english.lproj/strings.js +14 -0
- data/generators/language/USAGE +16 -0
- data/generators/language/language_generator.rb +47 -0
- data/generators/language/templates/strings.js +10 -0
- data/generators/model/USAGE +24 -0
- data/generators/model/model_generator.rb +55 -0
- data/generators/model/templates/fixture.js +11 -0
- data/generators/model/templates/model.js +20 -0
- data/generators/model/templates/test.rhtml +21 -0
- data/generators/test/USAGE +16 -0
- data/generators/test/templates/test.rhtml +21 -0
- data/generators/test/test_generator.rb +47 -0
- data/generators/view/USAGE +16 -0
- data/generators/view/templates/test.rhtml +21 -0
- data/generators/view/templates/view.js +20 -0
- data/generators/view/view_generator.rb +51 -0
- data/jsdoc/README.txt +119 -0
- data/jsdoc/app/DocFile.js +137 -0
- data/jsdoc/app/DocTag.js +110 -0
- data/jsdoc/app/Doclet.js +63 -0
- data/jsdoc/app/Dumper.js +143 -0
- data/jsdoc/app/JsDoc.js +103 -0
- data/jsdoc/app/JsHilite.js +45 -0
- data/jsdoc/app/JsIO.js +163 -0
- data/jsdoc/app/JsParse.js +385 -0
- data/jsdoc/app/JsPlate.js +130 -0
- data/jsdoc/app/JsTestrun.js +129 -0
- data/jsdoc/app/JsToke.js +564 -0
- data/jsdoc/app/Symbol.js +298 -0
- data/jsdoc/app/Transformer.js +14 -0
- data/jsdoc/app/Util.js +97 -0
- data/jsdoc/app/js.jar +0 -0
- data/jsdoc/app/run.js +144 -0
- data/jsdoc/plugins/min.js +316 -0
- data/jsdoc/plugins/strip.js +20 -0
- data/jsdoc/templates/sproutcore/class.tmpl +438 -0
- data/jsdoc/templates/sproutcore/default.css +241 -0
- data/jsdoc/templates/sproutcore/index.html +13 -0
- data/jsdoc/templates/sproutcore/index.tmpl +21 -0
- data/jsdoc/templates/sproutcore/prototype.js +4186 -0
- data/jsdoc/templates/sproutcore/publish.js +236 -0
- data/jsdoc/templates/sproutcore/splash.html +7 -0
- data/lib/sproutcore/build_tools/html_builder.rb +88 -0
- data/lib/sproutcore/build_tools/resource_builder.rb +194 -0
- data/lib/sproutcore/build_tools.rb +44 -0
- data/lib/sproutcore/bundle.rb +517 -0
- data/lib/sproutcore/bundle_manifest.rb +397 -0
- data/lib/sproutcore/generator_helper.rb +170 -0
- data/lib/sproutcore/helpers/capture_helper.rb +42 -0
- data/lib/sproutcore/helpers/static_helper.rb +80 -0
- data/lib/sproutcore/helpers/tag_helper.rb +110 -0
- data/lib/sproutcore/helpers/text_helper.rb +336 -0
- data/lib/sproutcore/helpers.rb +3 -0
- data/lib/sproutcore/jsdoc.rb +40 -0
- data/lib/sproutcore/jsmin.rb +247 -0
- data/lib/sproutcore/library.rb +258 -0
- data/lib/sproutcore/merb/bundle_controller.rb +179 -0
- data/lib/sproutcore/merb/router.rb +43 -0
- data/lib/sproutcore/merb.rb +27 -0
- data/lib/sproutcore/version.rb +9 -0
- data/lib/sproutcore/view_helpers/button_views.rb +302 -0
- data/lib/sproutcore/view_helpers/core_views.rb +284 -0
- data/lib/sproutcore/view_helpers/form_views.rb +258 -0
- data/lib/sproutcore/view_helpers/menu_views.rb +94 -0
- data/lib/sproutcore/view_helpers.rb +628 -0
- data/lib/sproutcore.rb +30 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/script/txt2html +74 -0
- data/setup.rb +1585 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/sproutcore_spec.rb +11 -0
- data/tasks/deployment.rake +34 -0
- data/tasks/environment.rake +7 -0
- data/tasks/rspec.rake +21 -0
- data/tasks/website.rake +17 -0
- metadata +365 -0
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
// ========================================================================
|
|
2
|
+
// SproutCore
|
|
3
|
+
// copyright 2006-2007 Sprout Systems, Inc.
|
|
4
|
+
// ========================================================================
|
|
5
|
+
|
|
6
|
+
require('views/view') ;
|
|
7
|
+
|
|
8
|
+
lc_cnt = 0 ;
|
|
9
|
+
|
|
10
|
+
SC.ImageView = SC.View.extend({
|
|
11
|
+
emptyElement: '<img />',
|
|
12
|
+
|
|
13
|
+
status: 'unknown',
|
|
14
|
+
|
|
15
|
+
content: null, // becomes the url.
|
|
16
|
+
contentBindingDefault: SC.Binding.Single,
|
|
17
|
+
|
|
18
|
+
// override with your own function to transform content into a URL.
|
|
19
|
+
transform: function(content) { return content; },
|
|
20
|
+
|
|
21
|
+
contentObserver: function() {
|
|
22
|
+
var prop = this.get('content') || '' ;
|
|
23
|
+
var url = this.transform(prop) ;
|
|
24
|
+
|
|
25
|
+
if (url && url.length > 0) {
|
|
26
|
+
this.beginPropertyChanges() ;
|
|
27
|
+
this.set('status','loading') ;
|
|
28
|
+
SC.imageCache.loadImage(url, this, this._onLoadComplete) ;
|
|
29
|
+
this.endPropertyChanges() ;
|
|
30
|
+
} else {
|
|
31
|
+
this.rootElement.src = '' ;
|
|
32
|
+
this.set('status','unknown') ;
|
|
33
|
+
}
|
|
34
|
+
}.observes('content') ,
|
|
35
|
+
|
|
36
|
+
_onLoadComplete: function(url, status, img) {
|
|
37
|
+
this.beginPropertyChanges() ;
|
|
38
|
+
this.set('imageWidth', parseInt(img.width,0)) ;
|
|
39
|
+
this.set('imageHeight', parseInt(img.height,0)) ;
|
|
40
|
+
this.set('status',status) ;
|
|
41
|
+
this.endPropertyChanges() ;
|
|
42
|
+
|
|
43
|
+
if (status == 'loaded') {
|
|
44
|
+
if (this.imageDidLoad) this.imageDidLoad(url) ;
|
|
45
|
+
this.rootElement.src = url ;
|
|
46
|
+
} else {
|
|
47
|
+
if (this.imageDidFail) this.imageDidFail(url, status) ;
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
init: function() {
|
|
52
|
+
arguments.callee.base.apply(this,arguments) ;
|
|
53
|
+
if (this.rootElement.src) {
|
|
54
|
+
this.set('imageWidth',parseInt(this.rootElement.width,0)) ;
|
|
55
|
+
this.set('imageHeight',parseInt(this.rootElement.height,0)) ;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
}) ;
|
|
60
|
+
|
|
61
|
+
// The image cache will create Image objects to preload a set of
|
|
62
|
+
// images. This will control the number of images being loaded to maximize
|
|
63
|
+
// browser throughput.
|
|
64
|
+
SC.imageCache = SC.Object.create({
|
|
65
|
+
|
|
66
|
+
// this restricts the maximum number of images that can load in.
|
|
67
|
+
loadLimit: 4,
|
|
68
|
+
|
|
69
|
+
// this is the primary entry point for the imageCache. Use this method to
|
|
70
|
+
// ask the cache to load an image and then invoke the callback when its
|
|
71
|
+
// available. You can pass either a function or an object + a function.
|
|
72
|
+
// Your callback should have this pattern:
|
|
73
|
+
//
|
|
74
|
+
// method(url, status, imgObject)
|
|
75
|
+
// url: the original URL you passed in.
|
|
76
|
+
// status: loaded | error | aborted
|
|
77
|
+
// imgObject: the image object. This parameter is optional.
|
|
78
|
+
//
|
|
79
|
+
loadImage: function(url, objOrFunc, method) {
|
|
80
|
+
var dta = this._images[url] = (this._images[url] || { url: url,
|
|
81
|
+
img: null, handlers: [], status: 'unknown' }) ;
|
|
82
|
+
|
|
83
|
+
if (dta.img == null) {
|
|
84
|
+
this._queue.push(dta) ;
|
|
85
|
+
if (!this._imgTimeout) {
|
|
86
|
+
this._imgTimeout = setTimeout(this.loadNextImage.bind(this),100) ;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// you can pass either just a function or an object + a method. This will
|
|
91
|
+
// handle both.
|
|
92
|
+
var handler = (method) ? [objOrFunc, method] : [this, objOrFunc] ;
|
|
93
|
+
if (dta.status == 'unknown') {
|
|
94
|
+
dta.handlers.push(handler) ;
|
|
95
|
+
} else if (handler[1]) {
|
|
96
|
+
handler[1].call(handler[0], url, dta.status, dta.img) ;
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
|
|
100
|
+
// this is called to load images that need
|
|
101
|
+
loadNextImage: function() {
|
|
102
|
+
this._imgTimeout = null ;
|
|
103
|
+
while((this._queue.length > 0) && (this._loading.length < this.loadLimit)) {
|
|
104
|
+
var dta = this._queue.pop() ;
|
|
105
|
+
var url = dta.url ;
|
|
106
|
+
dta.img = new Image() ;
|
|
107
|
+
dta.img.onabort = this._onAbort.bind(this,url) ;
|
|
108
|
+
dta.img.onerror = this._onError.bind(this,url) ;
|
|
109
|
+
dta.img.onload = this._onLoad.bind(this, url) ;
|
|
110
|
+
dta.img.src = dta.url ;
|
|
111
|
+
|
|
112
|
+
// add to loading queue.
|
|
113
|
+
this._loading.push(dta.url) ;
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
|
|
117
|
+
_onAbort: function(url) { this._changeStatus(url, 'aborted') ; },
|
|
118
|
+
_onError: function(url) { this._changeStatus(url, 'error'); },
|
|
119
|
+
_onLoad: function(url) { this._changeStatus(url, 'loaded'); },
|
|
120
|
+
|
|
121
|
+
// update the status in the queue and call any queued handlers.
|
|
122
|
+
_changeStatus: function(url, status) {
|
|
123
|
+
var dta = this._images[url] ;
|
|
124
|
+
if (!dta) return ;
|
|
125
|
+
dta.status = status ;
|
|
126
|
+
|
|
127
|
+
var handler ;
|
|
128
|
+
while(handler = dta.handlers.pop()) {
|
|
129
|
+
if (handler[1]) handler[1].call(handler[0], url, dta.status, dta.img) ;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// get the next image, if needed.
|
|
133
|
+
this._loading = this._loading.without(dta.url) ;
|
|
134
|
+
this.loadNextImage() ;
|
|
135
|
+
},
|
|
136
|
+
|
|
137
|
+
_images: {},
|
|
138
|
+
_loading: [],
|
|
139
|
+
_queue: []
|
|
140
|
+
|
|
141
|
+
});
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
// ========================================================================
|
|
2
|
+
// SproutCore
|
|
3
|
+
// copyright 2006-2007 Sprout Systems, Inc.
|
|
4
|
+
// ========================================================================
|
|
5
|
+
|
|
6
|
+
SC.inlineTextEditor = SC.View.extend({
|
|
7
|
+
|
|
8
|
+
multiline: true,
|
|
9
|
+
|
|
10
|
+
emptyElement: [
|
|
11
|
+
'<div class="inline_editor">',
|
|
12
|
+
'<div class="inline_editor_sizer"></div>',
|
|
13
|
+
'<textarea class="inline_editor_field" wrap="off"></textarea>',
|
|
14
|
+
//'<input type="text" class="inline_editor_field" />',
|
|
15
|
+
'</div>'
|
|
16
|
+
].join(''),
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Set the size of the textarea to the width and height of the text value
|
|
20
|
+
*/
|
|
21
|
+
render: function()
|
|
22
|
+
{
|
|
23
|
+
var editor = this.get('rootElement');
|
|
24
|
+
var sizer = editor.childNodes[0];
|
|
25
|
+
var field = editor.childNodes[1];
|
|
26
|
+
|
|
27
|
+
// XSS attack waiting to happen... escape the form input;
|
|
28
|
+
var text = (this.field.get('value') || '').escapeHTML();
|
|
29
|
+
// we don't want the text to wrap inside of the sizer...
|
|
30
|
+
text = text.replace(/ /g, " ");
|
|
31
|
+
// convert the textarea's newlines into something comparable for the sizer div
|
|
32
|
+
// appending a space to give a line with no text a visible height.
|
|
33
|
+
text = text.replace(/\n/g, "<br /> ");
|
|
34
|
+
|
|
35
|
+
// get the text size
|
|
36
|
+
sizer.innerHTML = text || " ";
|
|
37
|
+
var w = sizer.offsetWidth;
|
|
38
|
+
var h = sizer.offsetHeight;
|
|
39
|
+
|
|
40
|
+
// add it to the editor w/ some wiggle room to prevent
|
|
41
|
+
// the textarea's scrollbars from fickering
|
|
42
|
+
field.style.width = (w + 20) + "px";
|
|
43
|
+
field.style.height = (h + 5) + "px";
|
|
44
|
+
},
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
outlets: ['field'],
|
|
48
|
+
field: SC.TextFieldView.extend({
|
|
49
|
+
|
|
50
|
+
mouseDown: function(e)
|
|
51
|
+
{
|
|
52
|
+
e._stopWhenHandled = false;
|
|
53
|
+
return this.owner.get('parentNode').get('isEditing');
|
|
54
|
+
},
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* resize the editor whenever the field value changes
|
|
58
|
+
* @private
|
|
59
|
+
* @observes value
|
|
60
|
+
*/
|
|
61
|
+
valueObserver: function()
|
|
62
|
+
{
|
|
63
|
+
this.owner.render();
|
|
64
|
+
}.observes('value'),
|
|
65
|
+
|
|
66
|
+
willRemoveFromParent: function()
|
|
67
|
+
{
|
|
68
|
+
// [Safari] if you don't take key focus away from an element before you remove it from the DOM
|
|
69
|
+
// key events are no longer sent to the browser.
|
|
70
|
+
this.get('rootElement').blur();
|
|
71
|
+
},
|
|
72
|
+
willLoseFirstResponder: function()
|
|
73
|
+
{
|
|
74
|
+
// should have been covered by willRemoveFromParent, but this was needed too.
|
|
75
|
+
this.get('rootElement').blur();
|
|
76
|
+
var parentNode = this.owner.get('parentNode');
|
|
77
|
+
if ( parentNode )
|
|
78
|
+
{
|
|
79
|
+
if (parentNode.get('isEditing')) parentNode.endInlineEdit();
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
|
|
83
|
+
cancel: function()
|
|
84
|
+
{
|
|
85
|
+
var parentNode = this.owner.get('parentNode');
|
|
86
|
+
if (parentNode && parentNode.cancel) parentNode.cancel();
|
|
87
|
+
},
|
|
88
|
+
insertNewline: function()
|
|
89
|
+
{
|
|
90
|
+
var parentNode = this.owner.get('parentNode');
|
|
91
|
+
if (parentNode && parentNode.insertNewline) parentNode.insertNewline();
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
}).outletFor('.inline_editor_field?')
|
|
95
|
+
|
|
96
|
+
}).viewFor(null);
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
// ========================================================================
|
|
2
|
+
// SproutCore
|
|
3
|
+
// copyright 2006-2007 Sprout Systems, Inc.
|
|
4
|
+
// ========================================================================
|
|
5
|
+
|
|
6
|
+
require('views/view') ;
|
|
7
|
+
|
|
8
|
+
SC.LabelView = SC.View.extend({
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Can the label be edited using the inline editor?
|
|
12
|
+
* @type Boolean
|
|
13
|
+
**/
|
|
14
|
+
isEditable: false,
|
|
15
|
+
/**
|
|
16
|
+
* Is the editor open?
|
|
17
|
+
* @type Boolean
|
|
18
|
+
**/
|
|
19
|
+
isEditing: false,
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
// set to true to have any markup in the content escaped.
|
|
23
|
+
escapeHTML: true,
|
|
24
|
+
|
|
25
|
+
// set to true to have the value you set automatically localized.
|
|
26
|
+
localize: false,
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @constructor
|
|
31
|
+
*/
|
|
32
|
+
init: function()
|
|
33
|
+
{
|
|
34
|
+
arguments.callee.base.call(this) ;
|
|
35
|
+
if (this.get("localize"))
|
|
36
|
+
{
|
|
37
|
+
var inner = this.get("asHTML");
|
|
38
|
+
if (inner !== "") this.set("content", inner);
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Event dispatcher callback.
|
|
44
|
+
* If isEditable is set to true, opens the inline text editor view.
|
|
45
|
+
* @param {DOMMouseEvent} evt DOM event
|
|
46
|
+
*/
|
|
47
|
+
doubleClick: function( evt )
|
|
48
|
+
{
|
|
49
|
+
this.beginInlineEdit();
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Opens the inline text editor (closing it if it was already open for another view).
|
|
55
|
+
* @return void
|
|
56
|
+
**/
|
|
57
|
+
beginInlineEdit: function()
|
|
58
|
+
{
|
|
59
|
+
if ( !this.get('isEditable') ) return;
|
|
60
|
+
if ( this.get('isEditing') ) return;
|
|
61
|
+
|
|
62
|
+
this.set('isEditing', true);
|
|
63
|
+
this.set("asHTML", ''); // blank out the label contents
|
|
64
|
+
this.appendChild( SC.inlineTextEditor );
|
|
65
|
+
SC.inlineTextEditor.field.set('value', this.get('content'));
|
|
66
|
+
SC.inlineTextEditor.field.becomeFirstResponder();
|
|
67
|
+
},
|
|
68
|
+
/**
|
|
69
|
+
* Closes the inline text editor.
|
|
70
|
+
* @return void
|
|
71
|
+
**/
|
|
72
|
+
endInlineEdit: function()
|
|
73
|
+
{
|
|
74
|
+
if ( !this.get('isEditing') ) return;
|
|
75
|
+
|
|
76
|
+
// if there were changes, then commit them...
|
|
77
|
+
if ( SC.inlineTextEditor.field.get('value') != this.get('content') )
|
|
78
|
+
{
|
|
79
|
+
this._inlineEditValue = SC.inlineTextEditor.field.get('value') ;
|
|
80
|
+
this._closeInlineEditor(false) ;
|
|
81
|
+
}
|
|
82
|
+
else
|
|
83
|
+
{
|
|
84
|
+
this.cancelInlineEdit() ;
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
|
|
88
|
+
_inlineEditValue: '',
|
|
89
|
+
|
|
90
|
+
cancelInlineEdit: function()
|
|
91
|
+
{
|
|
92
|
+
if ( !this.get('isEditing') ) return;
|
|
93
|
+
this._closeInlineEditor(true);
|
|
94
|
+
},
|
|
95
|
+
|
|
96
|
+
_closeInlineEditor: function(canceled)
|
|
97
|
+
{
|
|
98
|
+
this.set('isEditing', false);
|
|
99
|
+
this.removeChild( SC.inlineTextEditor );
|
|
100
|
+
if(!canceled)
|
|
101
|
+
{
|
|
102
|
+
this.set('content',this._inlineEditValue) ;
|
|
103
|
+
this.commitInlineEdit();
|
|
104
|
+
}
|
|
105
|
+
else
|
|
106
|
+
{
|
|
107
|
+
this._updateValue() ; // restore value.
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
|
|
111
|
+
// abstract method... implement to persist changes made in the editor.
|
|
112
|
+
commitInlineEdit: function() {},
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
// setting this to a non-null value will cause the label to get the
|
|
116
|
+
// property value and use that for display.
|
|
117
|
+
property: function(key, value) {
|
|
118
|
+
if ((value !== undefined) && (value != this._property)) {
|
|
119
|
+
if (this._content) {
|
|
120
|
+
var func = this._boundObserver() ;
|
|
121
|
+
if (this._property && this._content && this._content.removeObserver) this._content.removeObserver(this._property,func);
|
|
122
|
+
this._property = value ;
|
|
123
|
+
if (this._property && this._content && this._content.addObserver) this._content.addObserver(this._property,func) ;
|
|
124
|
+
} else this._property = value ;
|
|
125
|
+
}
|
|
126
|
+
return this._property ;
|
|
127
|
+
}.property(),
|
|
128
|
+
|
|
129
|
+
// set to a validator object to have your content converted using the
|
|
130
|
+
// validator. The formatter will be applied before localization.
|
|
131
|
+
formatter: null,
|
|
132
|
+
|
|
133
|
+
// change this property value to update the content.
|
|
134
|
+
content: function(key,value) {
|
|
135
|
+
if ((value !== undefined) && (this._content != value)) {
|
|
136
|
+
var prop = this.get('property') ;
|
|
137
|
+
var func = this._boundObserver() ;
|
|
138
|
+
if (prop && this._content && this._content.removeObserver) this._content.removeObserver(prop, func) ;
|
|
139
|
+
this._content = value ;
|
|
140
|
+
if (prop && this._content && this._content.addObserver) this._content.addObserver(prop, func) ;
|
|
141
|
+
this._updateValue() ;
|
|
142
|
+
}
|
|
143
|
+
return this._content ;
|
|
144
|
+
}.property(),
|
|
145
|
+
|
|
146
|
+
contentBindingDefault: SC.Binding.Single,
|
|
147
|
+
|
|
148
|
+
_updateValue: function() {
|
|
149
|
+
var value = this._content ;
|
|
150
|
+
var prop = this.get('property') ;
|
|
151
|
+
if (prop && value && value.get) value = value.get(prop) ;
|
|
152
|
+
|
|
153
|
+
// apply formatter
|
|
154
|
+
var formatter = this.get('formatter') ;
|
|
155
|
+
if (formatter) {
|
|
156
|
+
var formattedValue = (SC.typeOf(formatter) == "function") ? formatter(value,this) : formatter.fieldValueForObject(value) ;
|
|
157
|
+
if (formattedValue) value = formattedValue ;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if ($type(value) == 'number') value = value.toString() ; // handle 0
|
|
161
|
+
|
|
162
|
+
// localize
|
|
163
|
+
if (value && this.get('localize')) value = value.loc() ;
|
|
164
|
+
if (value && this.get('escapeHTML') && value.escapeHTML) value = value.escapeHTML() ;
|
|
165
|
+
|
|
166
|
+
// set
|
|
167
|
+
this.set('asHTML',value || '') ;
|
|
168
|
+
|
|
169
|
+
},
|
|
170
|
+
|
|
171
|
+
_boundObserver: function() {
|
|
172
|
+
if (!this._observer) this._observer = this._updateValue.bind(this) ;
|
|
173
|
+
return this._observer ;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
});
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
// ========================================================================
|
|
2
|
+
// SproutCore
|
|
3
|
+
// copyright 2006-2007 Sprout Systems, Inc.
|
|
4
|
+
// ========================================================================
|
|
5
|
+
|
|
6
|
+
require('views/view') ;
|
|
7
|
+
|
|
8
|
+
// This is a basic menu item for inclusion in a popup menu. This is a type
|
|
9
|
+
// of button that will automatically close the popup menu when it is
|
|
10
|
+
// pressed.
|
|
11
|
+
SC.MenuItemView = SC.ButtonView.extend({
|
|
12
|
+
|
|
13
|
+
emptyElement: [
|
|
14
|
+
'<li class="button menu-item">',
|
|
15
|
+
'<a href="javascript:;">',
|
|
16
|
+
'<span class="sel">✓</span>',
|
|
17
|
+
'<span class="mixed">-</span>',
|
|
18
|
+
'<span class="inner">',
|
|
19
|
+
'<span class="label"></span>',
|
|
20
|
+
'</span>',
|
|
21
|
+
'<span class="shortcut"></span>',
|
|
22
|
+
'</a>',
|
|
23
|
+
'</li>'].join(''),
|
|
24
|
+
|
|
25
|
+
// this method returns the computed required width. This is potentially
|
|
26
|
+
// expensive, so don't call it often. It is intended to be used with the
|
|
27
|
+
// wrapper MenuView that will decide how wide to make the menu.
|
|
28
|
+
computedRequiredWidth: function() {
|
|
29
|
+
|
|
30
|
+
var ret = 0;
|
|
31
|
+
|
|
32
|
+
// first, get the left edge offset for the .inner span.
|
|
33
|
+
// we expect this to make room for any checkboxes that might appear on
|
|
34
|
+
// the left and required spacing on the right.
|
|
35
|
+
var el = this.$sel('.inner') ;
|
|
36
|
+
if (el) {
|
|
37
|
+
ret = el.offsetLeft ;
|
|
38
|
+
ret += parseInt(Element.getStyle(el, 'padding-left'),0) ;
|
|
39
|
+
ret += parseInt(Element.getStyle(el, 'padding-right'),0) ;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// next, add in the width of any img tag.
|
|
43
|
+
var img = Element.$sel(el,'img') ;
|
|
44
|
+
if (img) {
|
|
45
|
+
ret += Element.getDimensions(img).width ;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// next add in the width of any label. We assume this includes the width
|
|
49
|
+
// of the label text itself.
|
|
50
|
+
el = Element.$sel(el, '.label') ;
|
|
51
|
+
if (el) {
|
|
52
|
+
ret += Element.getDimensions(el).width ;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// finally, add the width of any shortcut. We assume this includes any
|
|
56
|
+
// padding required to go between the label and the shortcut.
|
|
57
|
+
el = this.$sel('.shortcut') ;
|
|
58
|
+
if (el) {
|
|
59
|
+
ret += Element.getDimensions(el).width ;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// that should do it...
|
|
63
|
+
return ret ;
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
mouseMoved: function(evt)
|
|
67
|
+
{
|
|
68
|
+
if (!this.get('isDefault')) this.get('parentNode').set('currentSelectedMenuItem', this);
|
|
69
|
+
},
|
|
70
|
+
mouseOut: function(evt)
|
|
71
|
+
{
|
|
72
|
+
this.set('isDefault', false);
|
|
73
|
+
},
|
|
74
|
+
|
|
75
|
+
mouseUp: function(evt)
|
|
76
|
+
{
|
|
77
|
+
arguments.callee.base.apply(this, arguments);
|
|
78
|
+
this._closeParentMenu();
|
|
79
|
+
},
|
|
80
|
+
didTriggerAction: function()
|
|
81
|
+
{
|
|
82
|
+
this._closeParentMenu();
|
|
83
|
+
},
|
|
84
|
+
_closeParentMenu: function()
|
|
85
|
+
{
|
|
86
|
+
var menu = this.get('parentNode');
|
|
87
|
+
if (menu) menu.set('isVisible', false);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// ========================================================================
|
|
2
|
+
// SproutCore
|
|
3
|
+
// copyright 2006-2007 Sprout Systems, Inc.
|
|
4
|
+
// ========================================================================
|
|
5
|
+
|
|
6
|
+
require('views/view') ;
|
|
7
|
+
require('controllers/collection') ;
|
|
8
|
+
|
|
9
|
+
// A pagination view renders a widget for showing the total number of pages and
|
|
10
|
+
// for switching between them. It includes a forward arrow, back arrow, and
|
|
11
|
+
// a popup.
|
|
12
|
+
SC.PaginationView = SC.View.extend({
|
|
13
|
+
|
|
14
|
+
// ......................................
|
|
15
|
+
// PROPERTIES
|
|
16
|
+
|
|
17
|
+
// Bind these to the controller properties to support pagination.
|
|
18
|
+
pageSize: 0,
|
|
19
|
+
pageCount: 0,
|
|
20
|
+
currentPage: 0,
|
|
21
|
+
|
|
22
|
+
// This is the format string used for the page count. Will be localized.
|
|
23
|
+
currentPageString: "_%@-%@ of %@",
|
|
24
|
+
|
|
25
|
+
// This is the format string used for the page popup.
|
|
26
|
+
pageOptionString: "_Page %@: %@-%@",
|
|
27
|
+
|
|
28
|
+
hasPreviousPage: function() {
|
|
29
|
+
return this.get('currentPage') > 0 ;
|
|
30
|
+
}.property(),
|
|
31
|
+
|
|
32
|
+
hasNextPage: function() {
|
|
33
|
+
return this.get('currentPage') < this.get('pageCount') ;
|
|
34
|
+
}.property(),
|
|
35
|
+
|
|
36
|
+
// ......................................
|
|
37
|
+
// STRUCTURE
|
|
38
|
+
|
|
39
|
+
// This is the generated element.
|
|
40
|
+
emptyElement: '<div class="pagination">\
|
|
41
|
+
<button class="prev">«</button>\
|
|
42
|
+
<button class="page"></button>\
|
|
43
|
+
<button class="next">»</button>\
|
|
44
|
+
</div>',
|
|
45
|
+
|
|
46
|
+
outlets: ['prevButton','nextButton','pageButton'],
|
|
47
|
+
|
|
48
|
+
prevButton: SC.ButtonView.extend({
|
|
49
|
+
action: function() { this.owner.decrementProperty('currentPage'); },
|
|
50
|
+
isEnabledBinding: "*owner.hasPreviousPage"
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
}) ;
|
|
54
|
+
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
require('views/button') ;
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @class
|
|
5
|
+
* @constructor
|
|
6
|
+
* @extends SC.ButtonView
|
|
7
|
+
* @author Skip Baney
|
|
8
|
+
* @copyright 2006-2007, Sprout Systems, Inc. and contributors.
|
|
9
|
+
* @version 0.1
|
|
10
|
+
*/
|
|
11
|
+
SC.PopupButtonView = SC.ButtonView.extend({
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Overriding the default SC.ButtonView#performKeyEquivalent method to pass it onto the menu
|
|
15
|
+
* @param {string} keystring method name corresponding to the keys pressed (i.e alt_shift_z)
|
|
16
|
+
* @param {DOMMouseEvent} evt mousedown event
|
|
17
|
+
*/
|
|
18
|
+
performKeyEquivalent: function( keystring, evt )
|
|
19
|
+
{
|
|
20
|
+
if (!this.get('isEnabled')) return false;
|
|
21
|
+
|
|
22
|
+
// is it our own keyEquivalent?
|
|
23
|
+
if (arguments.callee.base.apply(this,arguments)) return true;
|
|
24
|
+
|
|
25
|
+
// is it any of our menu items keyEquivalent?
|
|
26
|
+
var menu = this.get('menu');
|
|
27
|
+
return (!!menu && menu.performKeyEquivalent(keystring, evt));
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Name of the menu view to use.
|
|
32
|
+
* @type {string}
|
|
33
|
+
*/
|
|
34
|
+
menuName: null,
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* PopupMenu reference. Will be lazy-loaded from the 'menuName' string.
|
|
38
|
+
* @type {SC.PopupMenu}
|
|
39
|
+
*/
|
|
40
|
+
menu: function( key, value )
|
|
41
|
+
{
|
|
42
|
+
if ( value !== undefined )
|
|
43
|
+
{
|
|
44
|
+
value.set('isVisible', false);
|
|
45
|
+
this.set('_menu', value);
|
|
46
|
+
}
|
|
47
|
+
if ( !this._menu )
|
|
48
|
+
{
|
|
49
|
+
var menu = SC.page.get(this.get('menuName'));
|
|
50
|
+
if (menu) menu.set('isVisible', false);
|
|
51
|
+
// calling set so that the isSelectedBinding is triggered
|
|
52
|
+
this.set('_menu', menu);
|
|
53
|
+
}
|
|
54
|
+
return this._menu;
|
|
55
|
+
}.property(),
|
|
56
|
+
/**
|
|
57
|
+
* Binds the button's selection state to the menu's visibility.
|
|
58
|
+
* @private
|
|
59
|
+
*/
|
|
60
|
+
isSelectedBinding: '*_menu.isVisible',
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Button action handler
|
|
64
|
+
* @param {DOMMouseEvent} evt mouseup event that triggered the action
|
|
65
|
+
*/
|
|
66
|
+
action: function( evt )
|
|
67
|
+
{
|
|
68
|
+
var menu = this.get('menu');
|
|
69
|
+
// no menu to toggle... bail...
|
|
70
|
+
if (!menu) return false;
|
|
71
|
+
|
|
72
|
+
if (!this._didFirstRun) {
|
|
73
|
+
// for some reason the menu#isVisible is true the first time we get it...
|
|
74
|
+
// and since this#isSelected is bound to it... we get an incorrect conditional check.
|
|
75
|
+
// hacking it here to keep moving.
|
|
76
|
+
menu.popup(this, evt);
|
|
77
|
+
this._didFirstRun = true;
|
|
78
|
+
} else {
|
|
79
|
+
// toggle the menu...
|
|
80
|
+
this.get('isSelected') ? menu.set('isVisible', false) : menu.popup(this, evt);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
});
|