render.js 14 KB

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