]>
Commit | Line | Data |
---|---|---|
947f0963 TL |
1 | /* |
2 | * This file is generated by Sencha Cmd and should NOT be edited. It will be replaced | |
3 | * during an upgrade. | |
4 | */ | |
5 | ||
6 | // This flag is checked by many Components to avoid compatibility warnings when | |
7 | // the code is running under the slicer | |
8 | Ext.slicer = true; | |
9 | ||
10 | Ext.require([ | |
11 | 'Ext.layout.Context' | |
12 | ]); | |
13 | ||
14 | Ext.theme = Ext.apply(Ext.theme || {}, { | |
15 | /** | |
16 | * The array of all component manifests. These objects have the following set of | |
17 | * properties recognized by the slicer: | |
18 | * @private | |
19 | */ | |
20 | _manifest: [], | |
21 | ||
22 | /** | |
23 | * The collection of shortcuts for a given alias (e.g., 'widget.panel'). This is an | |
24 | * object keyed by alias whose values are arrays of shortcut definitions. | |
25 | * @private | |
26 | */ | |
27 | _shortcuts: {}, | |
28 | ||
29 | doRequire: function(xtype) { | |
30 | if (xtype.indexOf("widget.") != 0) { | |
31 | xtype = "widget." + xtype; | |
32 | } | |
33 | ||
34 | Ext.require([xtype]); | |
35 | }, | |
36 | ||
37 | /** | |
38 | * Adds one ore more component entries to the theme manifest. These entries will be | |
39 | * instantiated by the `Ext.theme.render` method when the page is ready. | |
40 | * | |
41 | * Usage: | |
42 | * | |
43 | * Ext.theme.addManifest({ | |
44 | * xtype: 'widget.menu', | |
45 | * folder: 'menu', | |
46 | * delegate: '.x-menu-item-link', | |
47 | * filename: 'menu-item-active', | |
48 | * config: { | |
49 | * floating: false, | |
50 | * width: 200, | |
51 | * items: [{ | |
52 | * text: 'test', | |
53 | * cls: 'x-menu-item-active' | |
54 | * }] | |
55 | * } | |
56 | * },{ | |
57 | * //... | |
58 | * }); | |
59 | * | |
60 | * @param manifest {Object} An object with type of component, slicing information and | |
61 | * component configuration. If this parameter is an array, each element is treated as | |
62 | * a manifest entry. Otherwise, each argument passed is treated as a manifest entry. | |
63 | * | |
64 | * @param manifest.xtype {String} The xtype ('grid') or alias ('widget.grid'). This | |
65 | * is used to specify the type of component to create as well as a potential key to | |
66 | * any `shortcuts` defined for the xtype. | |
67 | * | |
68 | * @param manifest.config {Object} The component configuration object. The properties | |
69 | * of this depend on the `xtype` of the component. | |
70 | * | |
71 | * @param [manifest.delegate] {String} The DOM query to use to select the element to | |
72 | * slice. The default is to slice the primary element of the component. | |
73 | * | |
74 | * @param [manifest.parentCls] An optional CSS class to add to the parent of the | |
75 | * component. | |
76 | * | |
77 | * @param [manifest.setup] {Function} An optional function to be called to initialize | |
78 | * the component. | |
79 | * @param manifest.setup.component {Ext.Component} The component instance | |
80 | * @param manifest.setup.container {Element} The component's container. | |
81 | * | |
82 | * @param [manifest.folder] {String} The folder in to which to produce image slices. | |
83 | * Only applies to Ext JS 4.1 (removed in 4.2). | |
84 | * | |
85 | * @param [manifest.filename] {String} The base filename for slices. | |
86 | * Only applies to Ext JS 4.1 (removed in 4.2). | |
87 | * | |
88 | * @param [manifest.reverse] {Boolean} True to position the slices for linear gradient | |
89 | * background at then opposite "end" (right or bottom) and apply the stretch to the | |
90 | * area before it (left or top). Only applies to Ext JS 4.1 (removed in 4.2). | |
91 | */ | |
92 | addManifest: function(manifest) { | |
93 | var all = Ext.theme._manifest, | |
94 | add = Ext.isArray(manifest) ? manifest : arguments; | |
95 | ||
96 | if (manifest.xtype) { | |
97 | Ext.theme.doRequire(manifest.xtype); | |
98 | } | |
99 | ||
100 | for (var i = 0, n = add.length; i < n; ++i) { | |
101 | if (add[i].xtype) { | |
102 | Ext.theme.doRequire(add[i].xtype); | |
103 | } | |
104 | ||
105 | all.push(add[i]); | |
106 | } | |
107 | }, | |
108 | ||
109 | /** | |
110 | * Adds one or more shortcuts to the rendering process. A `shortcut` is an object that | |
111 | * looks the same as a `manifest` entry. These are combined by copying the properties | |
112 | * from the shortcut over those of the manifest entry. In basic terms: | |
113 | * | |
114 | * var config = Ext.apply(Ext.apply({}, manfiest.config), shortcut.config); | |
115 | * var entry = Ext.apply(Ext.apply({}, manfiest), shortcut); | |
116 | * entry.config = config; | |
117 | * | |
118 | * This is not exactly the process, but the idea is the same. The difference is that | |
119 | * the `ui` of the manifest entry is used to replace any `"{ui}"` substrings found in | |
120 | * any string properties of the shortcut or its `config` object. | |
121 | * | |
122 | * Usage: | |
123 | * | |
124 | * Ext.theme.addShortcuts({ | |
125 | * 'widget.foo': [{ | |
126 | * config: { | |
127 | * } | |
128 | * },{ | |
129 | * config: { | |
130 | * } | |
131 | * }], | |
132 | * | |
133 | * 'widget.bar': [ ... ] | |
134 | * }); | |
135 | */ | |
136 | addShortcuts: function(shortcuts) { | |
137 | var all = Ext.theme._shortcuts; | |
138 | ||
139 | for (var key in shortcuts) { | |
140 | ||
141 | var add = shortcuts[key], | |
142 | xtype = Ext.theme.addWidget(key), | |
143 | existing = all[xtype]; | |
144 | ||
145 | Ext.theme.doRequire(xtype); | |
146 | ||
147 | for (var i = 0; i < add.length; i++) { | |
148 | var config = add[i]; | |
149 | ||
150 | if (config.xtype) { | |
151 | Ext.theme.doRequire(config.xtype); | |
152 | } | |
153 | } | |
154 | ||
155 | if (!existing) { | |
156 | all[xtype] = existing = []; | |
157 | } | |
158 | ||
159 | existing.push.apply(existing, add); | |
160 | } | |
161 | }, | |
162 | ||
163 | /** | |
164 | * This method ensures that a given string has the specified prefix (e.g., "widget."). | |
165 | * @private | |
166 | */ | |
167 | addPrefix: function(prefix, s) { | |
168 | if (!s || (s.length > prefix.length && s.substring(0, prefix.length) === prefix)) { | |
169 | return s; | |
170 | } | |
171 | ||
172 | return prefix + s; | |
173 | }, | |
174 | ||
175 | /** | |
176 | * This method returns the given string with "widget." added to the front if that is | |
177 | * not already present. | |
178 | * @private | |
179 | */ | |
180 | addWidget: function(str) { | |
181 | return Ext.theme.addPrefix('widget.', str); | |
182 | }, | |
183 | ||
184 | /** | |
185 | * This method accepts an manifest entry and a shortcut entry and returns the merged | |
186 | * version. | |
187 | * @private | |
188 | */ | |
189 | applyShortcut: function(manifestEntry, shortcut) { | |
190 | var ui = manifestEntry.ui, | |
191 | config = Ext.theme.copyProps({}, manifestEntry.config), | |
192 | entry = Ext.theme.copyProps({}, manifestEntry); | |
193 | ||
194 | if (ui && !config.ui) { | |
195 | config.ui = ui; | |
196 | } | |
197 | ||
198 | if (shortcut) { | |
199 | var tpl = { ui: ui }; | |
200 | ||
201 | Ext.theme.copyProps(entry, shortcut, tpl); | |
202 | Ext.theme.copyProps(config, shortcut.config, tpl); | |
203 | } | |
204 | ||
205 | entry.xtype = Ext.theme.addWidget(entry.xtype); | |
206 | entry.config = config; // both guys have "config" so smash merged one on now... | |
207 | ||
208 | return entry; | |
209 | }, | |
210 | ||
211 | /** | |
212 | * This method copies property from a `src` object to a `dest` object and reaplces | |
213 | * `"{foo}"` fragments of any string properties as defined in the `tpl` object. | |
214 | * | |
215 | * var obj = Ext.theme.copyProps({}, { | |
216 | * foo: 'Hello-{ui}' | |
217 | * }, { | |
218 | * ui: 'World' | |
219 | * }); | |
220 | * | |
221 | * console.log('obj.foo: ' + obj.foo); // logs "Hello-World" | |
222 | * | |
223 | * @return {Object} The `dest` object or a new object (if `dest` was null). | |
224 | * @private | |
225 | */ | |
226 | copyProps: function(dest, src, tpl) { | |
227 | var out = dest || {}, | |
228 | replacements = [], | |
229 | token; | |
230 | ||
231 | if (src) { | |
232 | if (tpl) { | |
233 | for (token in tpl) { | |
234 | replacements.push({ | |
235 | re: new RegExp('\\{' + token + '\\}', 'g'), | |
236 | value: tpl[token] | |
237 | }); | |
238 | } | |
239 | } | |
240 | ||
241 | for (var key in src) { | |
242 | var val = src[key]; | |
243 | ||
244 | if (tpl && typeof val === 'string') { | |
245 | for (var i = 0; i < replacements.length; ++ i) { | |
246 | val = val.replace(replacements[i].re, replacements[i].value); | |
247 | } | |
248 | } | |
249 | ||
250 | out[key] = val; | |
251 | } | |
252 | } | |
253 | ||
254 | return out; | |
255 | }, | |
256 | ||
257 | /** | |
258 | * Renders a component given its manifest and shortcut entries. | |
259 | * @private | |
260 | */ | |
261 | renderWidget: function(manifestEntry, shortcut) { | |
262 | var entry = Ext.theme.applyShortcut(manifestEntry, shortcut), | |
263 | config = entry.config, | |
264 | widget = Ext.create(entry.xtype, config), | |
265 | ct = Ext.fly(document.body).createChild({ cls: 'widget-container' }); | |
266 | ||
267 | Ext.theme.currentWidget = widget; | |
268 | ||
269 | if (widget.floating === true) { | |
270 | widget.floating = { shadow: false }; | |
271 | } | |
272 | ||
273 | if (widget.floating) { | |
274 | widget.focusOnToFront = false; | |
275 | } | |
276 | ||
277 | if (entry.setup) { | |
278 | entry.setup.call(widget, widget, ct); | |
279 | } | |
280 | else { | |
281 | widget.render(ct); | |
282 | ||
283 | if (widget.floating) { | |
284 | widget.showAt(0, 0); | |
285 | ct.setHeight(widget.getHeight()); | |
286 | } | |
287 | } | |
288 | ||
289 | var el = widget.el; | |
290 | ||
291 | if (entry.delegate) { | |
292 | el = el.down(entry.delegate); | |
293 | } | |
294 | ||
295 | el.addCls('x-slicer-target'); // this is what generateSlicerManifest looks for | |
296 | ||
297 | if (entry.over) { | |
298 | widget.addOverCls(); | |
299 | } | |
300 | ||
301 | if (config.parentCls) { | |
302 | el.parent().addCls(config.parentCls); | |
303 | } | |
304 | ||
305 | if (Ext.theme.legacy) { | |
306 | // The 4.1 approach has some interesting extra pieces | |
307 | // | |
308 | var data = {}; | |
309 | ||
310 | if (entry.reverse) { | |
311 | data.reverse = true; | |
312 | } | |
313 | ||
314 | if (entry.filename) { | |
315 | data.filename = entry.filename; | |
316 | } | |
317 | ||
318 | if (entry.folder) { | |
319 | data.folder = entry.folder; | |
320 | } | |
321 | ||
322 | if (entry.offsets) { | |
323 | data.offsets = entry.offsets; | |
324 | } | |
325 | ||
326 | Ext.theme.setData(el.dom, data); | |
327 | } | |
328 | ||
329 | Ext.theme.currentWidget = null; | |
330 | }, | |
331 | ||
332 | /** | |
333 | * Renders all of the components that have been added to the manifest. | |
334 | * @private | |
335 | */ | |
336 | render: function() { | |
337 | console.log("rendering widgets..."); | |
338 | var manifest = Ext.theme._manifest, | |
339 | shortcuts = Ext.theme._shortcuts; | |
340 | ||
341 | for (var k = 0, n = manifest ? manifest.length : 0; k < n; ++k) { | |
342 | var manifestEntry = manifest[k], | |
343 | xtype = Ext.theme.addWidget(manifestEntry.xtype), | |
344 | widgetShortcuts = xtype ? shortcuts[xtype] : null; | |
345 | ||
346 | if (xtype && manifestEntry.ui && widgetShortcuts) { | |
347 | for (var i = 0; i < widgetShortcuts.length; i++) { | |
348 | Ext.theme.renderWidget(manifestEntry, widgetShortcuts[i]); | |
349 | } | |
350 | } | |
351 | else { | |
352 | Ext.theme.renderWidget(manifestEntry); | |
353 | } | |
354 | } | |
355 | }, | |
356 | ||
357 | /** | |
358 | * Renders all components (see `render`) and notifies the Slicer that things are ready. | |
359 | * @private | |
360 | */ | |
361 | run: function() { | |
362 | var extjsVer = Ext.versions.extjs, | |
363 | globalData = {}; | |
364 | ||
365 | if (Ext.layout.Context) { | |
366 | Ext.override(Ext.layout.Context, { | |
367 | run: function() { | |
368 | var ok = this.callParent(), | |
369 | widget = Ext.theme.currentWidget; | |
370 | ||
371 | if (!ok && widget) { | |
372 | Ext.Error.raise("Layout run failed: " + widget.id); | |
373 | } | |
374 | ||
375 | return ok; | |
376 | } | |
377 | }); | |
378 | } | |
379 | ||
380 | console.log("loading widget definitions..."); | |
381 | ||
382 | // Previous to Ext JS 4.2, themes and their manifests where defined differently. | |
383 | // So pass this along if we are hosting a pre-4.2 theme. | |
384 | // | |
385 | if (extjsVer && extjsVer.isLessThan(new Ext.Version("4.2"))) { | |
386 | globalData.format = "1.0"; // tell the Slicer tool | |
387 | Ext.theme.legacy = true; // not for our own data collection | |
388 | ||
389 | // Check for the Cmd3.0/ExtJS4.1 variables: | |
390 | // | |
391 | if (Ext.manifest && Ext.manifest.widgets) { | |
392 | Ext.theme.addManifest(Ext.manifest.widgets); | |
393 | } | |
394 | ||
395 | if (Ext.shortcuts) { | |
396 | Ext.theme.addShortcuts(Ext.shortcuts); | |
397 | } | |
398 | ||
399 | if (Ext.userManifest && Ext.userManifest.widgets) { | |
400 | Ext.theme.addManifest(Ext.userManifest.widgets); | |
401 | } | |
402 | } | |
403 | ||
404 | Ext.theme.setData(document.body, globalData); | |
405 | Ext.theme.render(); | |
406 | Ext.theme.generateSlicerManifest(); | |
407 | }, | |
408 | ||
409 | generateSlicerManifest: function() { | |
410 | var now = new Date().getTime(), | |
411 | me = Ext.theme, | |
412 | // This function is defined by slicer.js (the framework-independent piece) | |
413 | gsm = window && window.generateSlicerManifest, | |
414 | delta; | |
415 | ||
416 | me.generateStart = me.generateStart || now; | |
417 | delta = now - me.generateStart; | |
418 | ||
419 | if (gsm) { | |
420 | gsm(); | |
421 | } | |
422 | else if (delta < (10 * 1000)) { | |
423 | // allow the outer script wrapper a chance to inject the capture function | |
424 | // but stop trying after 10 seconds | |
425 | Ext.defer(Ext.theme.generateSlicerManifest, 100); | |
426 | } | |
427 | }, | |
428 | ||
429 | /** | |
430 | * Sets the `data-slicer` attribute to the JSON-encoded value of the provided data. | |
431 | * @private | |
432 | */ | |
433 | setData: function(el, data) { | |
434 | if (data) { | |
435 | var json = Ext.encode(data); | |
436 | ||
437 | if (json !== '{}') { | |
438 | el.setAttribute('data-slicer', json); | |
439 | } | |
440 | } | |
441 | }, | |
442 | ||
443 | /** | |
444 | * This used to be `loadExtStylesheet`. | |
445 | * @private | |
446 | */ | |
447 | loadCss: function(src, callback) { | |
448 | var xhr = new XMLHttpRequest(); | |
449 | ||
450 | xhr.open('GET', src); | |
451 | ||
452 | xhr.onload = function() { | |
453 | var css = xhr.responseText, | |
454 | head = document.getElementsByTagName('head')[0], | |
455 | style = document.createElement('style'); | |
456 | ||
457 | // There's bugginess in the next gradient syntax in WebKit r84622 | |
458 | // This might be fixed in a later WebKit, but for now we're going to | |
459 | // strip it out here since compass generates it. | |
460 | // | |
461 | // TODO: Upgrade to later WebKit revision | |
462 | css = css.replace(/background(-image)?: ?-webkit-linear-gradient(?:.*?);/g, ''); | |
463 | ||
464 | style.type = 'text/css'; | |
465 | style.innerText = css; | |
466 | ||
467 | head.appendChild(style); | |
468 | callback(); | |
469 | }; | |
470 | ||
471 | xhr.send(null); | |
472 | } | |
473 | }); | |
474 | ||
475 | console.log("registering ready listener..."); | |
476 | Ext.onReady(Ext.theme.run, Ext.theme); |