Control.js 39 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588
  1. /**
  2. * Control.js
  3. *
  4. * Copyright, Moxiecode Systems AB
  5. * Released under LGPL License.
  6. *
  7. * License: http://www.tinymce.com/license
  8. * Contributing: http://www.tinymce.com/contributing
  9. */
  10. /*eslint consistent-this:0 */
  11. /**
  12. * This is the base class for all controls and containers. All UI control instances inherit
  13. * from this one as it has the base logic needed by all of them.
  14. *
  15. * @class tinymce.ui.Control
  16. */
  17. define("tinymce/ui/Control", [
  18. "tinymce/util/Class",
  19. "tinymce/util/Tools",
  20. "tinymce/ui/Collection",
  21. "tinymce/ui/DomUtils"
  22. ], function(Class, Tools, Collection, DomUtils) {
  23. "use strict";
  24. var nativeEvents = Tools.makeMap("focusin focusout scroll click dblclick mousedown mouseup mousemove mouseover" +
  25. " mouseout mouseenter mouseleave wheel keydown keypress input keyup contextmenu", " ");
  26. var elementIdCache = {};
  27. var hasMouseWheelEventSupport = "onmousewheel" in document;
  28. var hasWheelEventSupport = false;
  29. var classPrefix = "mce-";
  30. var Control = Class.extend({
  31. Statics: {
  32. elementIdCache: elementIdCache,
  33. classPrefix: classPrefix
  34. },
  35. isRtl: function() {
  36. return Control.rtl;
  37. },
  38. /**
  39. * Class/id prefix to use for all controls.
  40. *
  41. * @final
  42. * @field {String} classPrefix
  43. */
  44. classPrefix: classPrefix,
  45. /**
  46. * Constructs a new control instance with the specified settings.
  47. *
  48. * @constructor
  49. * @param {Object} settings Name/value object with settings.
  50. * @setting {String} style Style CSS properties to add.
  51. * @setting {String} border Border box values example: 1 1 1 1
  52. * @setting {String} padding Padding box values example: 1 1 1 1
  53. * @setting {String} margin Margin box values example: 1 1 1 1
  54. * @setting {Number} minWidth Minimal width for the control.
  55. * @setting {Number} minHeight Minimal height for the control.
  56. * @setting {String} classes Space separated list of classes to add.
  57. * @setting {String} role WAI-ARIA role to use for control.
  58. * @setting {Boolean} hidden Is the control hidden by default.
  59. * @setting {Boolean} disabled Is the control disabled by default.
  60. * @setting {String} name Name of the control instance.
  61. */
  62. init: function(settings) {
  63. var self = this, classes, i;
  64. self.settings = settings = Tools.extend({}, self.Defaults, settings);
  65. // Initial states
  66. self._id = settings.id || DomUtils.id();
  67. self._text = self._name = '';
  68. self._width = self._height = 0;
  69. self._aria = {role: settings.role};
  70. // Setup classes
  71. classes = settings.classes;
  72. if (classes) {
  73. classes = classes.split(' ');
  74. classes.map = {};
  75. i = classes.length;
  76. while (i--) {
  77. classes.map[classes[i]] = true;
  78. }
  79. }
  80. self._classes = classes || [];
  81. self.visible(true);
  82. // Set some properties
  83. Tools.each('title text width height name classes visible disabled active value'.split(' '), function(name) {
  84. var value = settings[name], undef;
  85. if (value !== undef) {
  86. self[name](value);
  87. } else if (self['_' + name] === undef) {
  88. self['_' + name] = false;
  89. }
  90. });
  91. self.on('click', function() {
  92. if (self.disabled()) {
  93. return false;
  94. }
  95. });
  96. // TODO: Is this needed duplicate code see above?
  97. if (settings.classes) {
  98. Tools.each(settings.classes.split(' '), function(cls) {
  99. self.addClass(cls);
  100. });
  101. }
  102. /**
  103. * Name/value object with settings for the current control.
  104. *
  105. * @field {Object} settings
  106. */
  107. self.settings = settings;
  108. self._borderBox = self.parseBox(settings.border);
  109. self._paddingBox = self.parseBox(settings.padding);
  110. self._marginBox = self.parseBox(settings.margin);
  111. if (settings.hidden) {
  112. self.hide();
  113. }
  114. },
  115. // Will generate getter/setter methods for these properties
  116. Properties: 'parent,title,text,width,height,disabled,active,name,value',
  117. // Will generate empty dummy functions for these
  118. Methods: 'renderHtml',
  119. /**
  120. * Returns the root element to render controls into.
  121. *
  122. * @method getContainerElm
  123. * @return {Element} HTML DOM element to render into.
  124. */
  125. getContainerElm: function() {
  126. return document.body;
  127. },
  128. /**
  129. * Returns a control instance for the current DOM element.
  130. *
  131. * @method getParentCtrl
  132. * @param {Element} elm HTML dom element to get parent control from.
  133. * @return {tinymce.ui.Control} Control instance or undefined.
  134. */
  135. getParentCtrl: function(elm) {
  136. var ctrl, lookup = this.getRoot().controlIdLookup;
  137. while (elm && lookup) {
  138. ctrl = lookup[elm.id];
  139. if (ctrl) {
  140. break;
  141. }
  142. elm = elm.parentNode;
  143. }
  144. return ctrl;
  145. },
  146. /**
  147. * Parses the specified box value. A box value contains 1-4 properties in clockwise order.
  148. *
  149. * @method parseBox
  150. * @param {String/Number} value Box value "0 1 2 3" or "0" etc.
  151. * @return {Object} Object with top/right/bottom/left properties.
  152. * @private
  153. */
  154. parseBox: function(value) {
  155. var len, radix = 10;
  156. if (!value) {
  157. return;
  158. }
  159. if (typeof(value) === "number") {
  160. value = value || 0;
  161. return {
  162. top: value,
  163. left: value,
  164. bottom: value,
  165. right: value
  166. };
  167. }
  168. value = value.split(' ');
  169. len = value.length;
  170. if (len === 1) {
  171. value[1] = value[2] = value[3] = value[0];
  172. } else if (len === 2) {
  173. value[2] = value[0];
  174. value[3] = value[1];
  175. } else if (len === 3) {
  176. value[3] = value[1];
  177. }
  178. return {
  179. top: parseInt(value[0], radix) || 0,
  180. right: parseInt(value[1], radix) || 0,
  181. bottom: parseInt(value[2], radix) || 0,
  182. left: parseInt(value[3], radix) || 0
  183. };
  184. },
  185. borderBox: function() {
  186. return this._borderBox;
  187. },
  188. paddingBox: function() {
  189. return this._paddingBox;
  190. },
  191. marginBox: function() {
  192. return this._marginBox;
  193. },
  194. measureBox: function(elm, prefix) {
  195. function getStyle(name) {
  196. var defaultView = document.defaultView;
  197. if (defaultView) {
  198. // Remove camelcase
  199. name = name.replace(/[A-Z]/g, function(a) {
  200. return '-' + a;
  201. });
  202. return defaultView.getComputedStyle(elm, null).getPropertyValue(name);
  203. }
  204. return elm.currentStyle[name];
  205. }
  206. function getSide(name) {
  207. var val = parseFloat(getStyle(name), 10);
  208. return isNaN(val) ? 0 : val;
  209. }
  210. return {
  211. top: getSide(prefix + "TopWidth"),
  212. right: getSide(prefix + "RightWidth"),
  213. bottom: getSide(prefix + "BottomWidth"),
  214. left: getSide(prefix + "LeftWidth")
  215. };
  216. },
  217. /**
  218. * Initializes the current controls layout rect.
  219. * This will be executed by the layout managers to determine the
  220. * default minWidth/minHeight etc.
  221. *
  222. * @method initLayoutRect
  223. * @return {Object} Layout rect instance.
  224. */
  225. initLayoutRect: function() {
  226. var self = this, settings = self.settings, borderBox, layoutRect;
  227. var elm = self.getEl(), width, height, minWidth, minHeight, autoResize;
  228. var startMinWidth, startMinHeight, initialSize;
  229. // Measure the current element
  230. borderBox = self._borderBox = self._borderBox || self.measureBox(elm, 'border');
  231. self._paddingBox = self._paddingBox || self.measureBox(elm, 'padding');
  232. self._marginBox = self._marginBox || self.measureBox(elm, 'margin');
  233. initialSize = DomUtils.getSize(elm);
  234. // Setup minWidth/minHeight and width/height
  235. startMinWidth = settings.minWidth;
  236. startMinHeight = settings.minHeight;
  237. minWidth = startMinWidth || initialSize.width;
  238. minHeight = startMinHeight || initialSize.height;
  239. width = settings.width;
  240. height = settings.height;
  241. autoResize = settings.autoResize;
  242. autoResize = typeof(autoResize) != "undefined" ? autoResize : !width && !height;
  243. width = width || minWidth;
  244. height = height || minHeight;
  245. var deltaW = borderBox.left + borderBox.right;
  246. var deltaH = borderBox.top + borderBox.bottom;
  247. var maxW = settings.maxWidth || 0xFFFF;
  248. var maxH = settings.maxHeight || 0xFFFF;
  249. // Setup initial layout rect
  250. self._layoutRect = layoutRect = {
  251. x: settings.x || 0,
  252. y: settings.y || 0,
  253. w: width,
  254. h: height,
  255. deltaW: deltaW,
  256. deltaH: deltaH,
  257. contentW: width - deltaW,
  258. contentH: height - deltaH,
  259. innerW: width - deltaW,
  260. innerH: height - deltaH,
  261. startMinWidth: startMinWidth || 0,
  262. startMinHeight: startMinHeight || 0,
  263. minW: Math.min(minWidth, maxW),
  264. minH: Math.min(minHeight, maxH),
  265. maxW: maxW,
  266. maxH: maxH,
  267. autoResize: autoResize,
  268. scrollW: 0
  269. };
  270. self._lastLayoutRect = {};
  271. return layoutRect;
  272. },
  273. /**
  274. * Getter/setter for the current layout rect.
  275. *
  276. * @method layoutRect
  277. * @param {Object} [newRect] Optional new layout rect.
  278. * @return {tinymce.ui.Control/Object} Current control or rect object.
  279. */
  280. layoutRect: function(newRect) {
  281. var self = this, curRect = self._layoutRect, lastLayoutRect, size, deltaWidth, deltaHeight, undef, repaintControls;
  282. // Initialize default layout rect
  283. if (!curRect) {
  284. curRect = self.initLayoutRect();
  285. }
  286. // Set new rect values
  287. if (newRect) {
  288. // Calc deltas between inner and outer sizes
  289. deltaWidth = curRect.deltaW;
  290. deltaHeight = curRect.deltaH;
  291. // Set x position
  292. if (newRect.x !== undef) {
  293. curRect.x = newRect.x;
  294. }
  295. // Set y position
  296. if (newRect.y !== undef) {
  297. curRect.y = newRect.y;
  298. }
  299. // Set minW
  300. if (newRect.minW !== undef) {
  301. curRect.minW = newRect.minW;
  302. }
  303. // Set minH
  304. if (newRect.minH !== undef) {
  305. curRect.minH = newRect.minH;
  306. }
  307. // Set new width and calculate inner width
  308. size = newRect.w;
  309. if (size !== undef) {
  310. size = size < curRect.minW ? curRect.minW : size;
  311. size = size > curRect.maxW ? curRect.maxW : size;
  312. curRect.w = size;
  313. curRect.innerW = size - deltaWidth;
  314. }
  315. // Set new height and calculate inner height
  316. size = newRect.h;
  317. if (size !== undef) {
  318. size = size < curRect.minH ? curRect.minH : size;
  319. size = size > curRect.maxH ? curRect.maxH : size;
  320. curRect.h = size;
  321. curRect.innerH = size - deltaHeight;
  322. }
  323. // Set new inner width and calculate width
  324. size = newRect.innerW;
  325. if (size !== undef) {
  326. size = size < curRect.minW - deltaWidth ? curRect.minW - deltaWidth : size;
  327. size = size > curRect.maxW - deltaWidth ? curRect.maxW - deltaWidth : size;
  328. curRect.innerW = size;
  329. curRect.w = size + deltaWidth;
  330. }
  331. // Set new height and calculate inner height
  332. size = newRect.innerH;
  333. if (size !== undef) {
  334. size = size < curRect.minH - deltaHeight ? curRect.minH - deltaHeight : size;
  335. size = size > curRect.maxH - deltaHeight ? curRect.maxH - deltaHeight : size;
  336. curRect.innerH = size;
  337. curRect.h = size + deltaHeight;
  338. }
  339. // Set new contentW
  340. if (newRect.contentW !== undef) {
  341. curRect.contentW = newRect.contentW;
  342. }
  343. // Set new contentH
  344. if (newRect.contentH !== undef) {
  345. curRect.contentH = newRect.contentH;
  346. }
  347. // Compare last layout rect with the current one to see if we need to repaint or not
  348. lastLayoutRect = self._lastLayoutRect;
  349. if (lastLayoutRect.x !== curRect.x || lastLayoutRect.y !== curRect.y ||
  350. lastLayoutRect.w !== curRect.w || lastLayoutRect.h !== curRect.h) {
  351. repaintControls = Control.repaintControls;
  352. if (repaintControls) {
  353. if (repaintControls.map && !repaintControls.map[self._id]) {
  354. repaintControls.push(self);
  355. repaintControls.map[self._id] = true;
  356. }
  357. }
  358. lastLayoutRect.x = curRect.x;
  359. lastLayoutRect.y = curRect.y;
  360. lastLayoutRect.w = curRect.w;
  361. lastLayoutRect.h = curRect.h;
  362. }
  363. return self;
  364. }
  365. return curRect;
  366. },
  367. /**
  368. * Repaints the control after a layout operation.
  369. *
  370. * @method repaint
  371. */
  372. repaint: function() {
  373. var self = this, style, bodyStyle, rect, borderBox, borderW = 0, borderH = 0, lastRepaintRect, round;
  374. // Use Math.round on all values on IE < 9
  375. round = !document.createRange ? Math.round : function(value) {
  376. return value;
  377. };
  378. style = self.getEl().style;
  379. rect = self._layoutRect;
  380. lastRepaintRect = self._lastRepaintRect || {};
  381. borderBox = self._borderBox;
  382. borderW = borderBox.left + borderBox.right;
  383. borderH = borderBox.top + borderBox.bottom;
  384. if (rect.x !== lastRepaintRect.x) {
  385. style.left = round(rect.x) + 'px';
  386. lastRepaintRect.x = rect.x;
  387. }
  388. if (rect.y !== lastRepaintRect.y) {
  389. style.top = round(rect.y) + 'px';
  390. lastRepaintRect.y = rect.y;
  391. }
  392. if (rect.w !== lastRepaintRect.w) {
  393. style.width = round(rect.w - borderW) + 'px';
  394. lastRepaintRect.w = rect.w;
  395. }
  396. if (rect.h !== lastRepaintRect.h) {
  397. style.height = round(rect.h - borderH) + 'px';
  398. lastRepaintRect.h = rect.h;
  399. }
  400. // Update body if needed
  401. if (self._hasBody && rect.innerW !== lastRepaintRect.innerW) {
  402. bodyStyle = self.getEl('body').style;
  403. bodyStyle.width = round(rect.innerW) + 'px';
  404. lastRepaintRect.innerW = rect.innerW;
  405. }
  406. if (self._hasBody && rect.innerH !== lastRepaintRect.innerH) {
  407. bodyStyle = bodyStyle || self.getEl('body').style;
  408. bodyStyle.height = round(rect.innerH) + 'px';
  409. lastRepaintRect.innerH = rect.innerH;
  410. }
  411. self._lastRepaintRect = lastRepaintRect;
  412. self.fire('repaint', {}, false);
  413. },
  414. /**
  415. * Binds a callback to the specified event. This event can both be
  416. * native browser events like "click" or custom ones like PostRender.
  417. *
  418. * The callback function will be passed a DOM event like object that enables yout do stop propagation.
  419. *
  420. * @method on
  421. * @param {String} name Name of the event to bind. For example "click".
  422. * @param {String/function} callback Callback function to execute ones the event occurs.
  423. * @return {tinymce.ui.Control} Current control object.
  424. */
  425. on: function(name, callback) {
  426. var self = this, bindings, handlers, names, i;
  427. function resolveCallbackName(name) {
  428. var callback, scope;
  429. return function(e) {
  430. if (!callback) {
  431. self.parentsAndSelf().each(function(ctrl) {
  432. var callbacks = ctrl.settings.callbacks;
  433. if (callbacks && (callback = callbacks[name])) {
  434. scope = ctrl;
  435. return false;
  436. }
  437. });
  438. }
  439. return callback.call(scope, e);
  440. };
  441. }
  442. if (callback) {
  443. if (typeof(callback) == 'string') {
  444. callback = resolveCallbackName(callback);
  445. }
  446. names = name.toLowerCase().split(' ');
  447. i = names.length;
  448. while (i--) {
  449. name = names[i];
  450. bindings = self._bindings;
  451. if (!bindings) {
  452. bindings = self._bindings = {};
  453. }
  454. handlers = bindings[name];
  455. if (!handlers) {
  456. handlers = bindings[name] = [];
  457. }
  458. handlers.push(callback);
  459. if (nativeEvents[name]) {
  460. if (!self._nativeEvents) {
  461. self._nativeEvents = {};
  462. }
  463. self._nativeEvents[name] = true;
  464. if (self._rendered) {
  465. self.bindPendingEvents();
  466. }
  467. }
  468. }
  469. }
  470. return self;
  471. },
  472. /**
  473. * Unbinds the specified event and optionally a specific callback. If you omit the name
  474. * parameter all event handlers will be removed. If you omit the callback all event handles
  475. * by the specified name will be removed.
  476. *
  477. * @method off
  478. * @param {String} [name] Name for the event to unbind.
  479. * @param {function} [callback] Callback function to unbind.
  480. * @return {mxex.ui.Control} Current control object.
  481. */
  482. off: function(name, callback) {
  483. var self = this, i, bindings = self._bindings, handlers, bindingName, names, hi;
  484. if (bindings) {
  485. if (name) {
  486. names = name.toLowerCase().split(' ');
  487. i = names.length;
  488. while (i--) {
  489. name = names[i];
  490. handlers = bindings[name];
  491. // Unbind all handlers
  492. if (!name) {
  493. for (bindingName in bindings) {
  494. bindings[bindingName].length = 0;
  495. }
  496. return self;
  497. }
  498. if (handlers) {
  499. // Unbind all by name
  500. if (!callback) {
  501. handlers.length = 0;
  502. } else {
  503. // Unbind specific ones
  504. hi = handlers.length;
  505. while (hi--) {
  506. if (handlers[hi] === callback) {
  507. handlers.splice(hi, 1);
  508. }
  509. }
  510. }
  511. }
  512. }
  513. } else {
  514. self._bindings = [];
  515. }
  516. }
  517. return self;
  518. },
  519. /**
  520. * Fires the specified event by name and arguments on the control. This will execute all
  521. * bound event handlers.
  522. *
  523. * @method fire
  524. * @param {String} name Name of the event to fire.
  525. * @param {Object} [args] Arguments to pass to the event.
  526. * @param {Boolean} [bubble] Value to control bubbeling. Defaults to true.
  527. * @return {Object} Current arguments object.
  528. */
  529. fire: function(name, args, bubble) {
  530. var self = this, i, l, handlers, parentCtrl;
  531. name = name.toLowerCase();
  532. // Dummy function that gets replaced on the delegation state functions
  533. function returnFalse() {
  534. return false;
  535. }
  536. // Dummy function that gets replaced on the delegation state functions
  537. function returnTrue() {
  538. return true;
  539. }
  540. // Setup empty object if args is omited
  541. args = args || {};
  542. // Stick type into event object
  543. if (!args.type) {
  544. args.type = name;
  545. }
  546. // Stick control into event
  547. if (!args.control) {
  548. args.control = self;
  549. }
  550. // Add event delegation methods if they are missing
  551. if (!args.preventDefault) {
  552. // Add preventDefault method
  553. args.preventDefault = function() {
  554. args.isDefaultPrevented = returnTrue;
  555. };
  556. // Add stopPropagation
  557. args.stopPropagation = function() {
  558. args.isPropagationStopped = returnTrue;
  559. };
  560. // Add stopImmediatePropagation
  561. args.stopImmediatePropagation = function() {
  562. args.isImmediatePropagationStopped = returnTrue;
  563. };
  564. // Add event delegation states
  565. args.isDefaultPrevented = returnFalse;
  566. args.isPropagationStopped = returnFalse;
  567. args.isImmediatePropagationStopped = returnFalse;
  568. }
  569. if (self._bindings) {
  570. handlers = self._bindings[name];
  571. if (handlers) {
  572. for (i = 0, l = handlers.length; i < l; i++) {
  573. // Execute callback and break if the callback returns a false
  574. if (!args.isImmediatePropagationStopped() && handlers[i].call(self, args) === false) {
  575. break;
  576. }
  577. }
  578. }
  579. }
  580. // Bubble event up to parent controls
  581. if (bubble !== false) {
  582. parentCtrl = self.parent();
  583. while (parentCtrl && !args.isPropagationStopped()) {
  584. parentCtrl.fire(name, args, false);
  585. parentCtrl = parentCtrl.parent();
  586. }
  587. }
  588. return args;
  589. },
  590. /**
  591. * Returns true/false if the specified event has any listeners.
  592. *
  593. * @method hasEventListeners
  594. * @param {String} name Name of the event to check for.
  595. * @return {Boolean} True/false state if the event has listeners.
  596. */
  597. hasEventListeners: function(name) {
  598. return name in this._bindings;
  599. },
  600. /**
  601. * Returns a control collection with all parent controls.
  602. *
  603. * @method parents
  604. * @param {String} selector Optional selector expression to find parents.
  605. * @return {tinymce.ui.Collection} Collection with all parent controls.
  606. */
  607. parents: function(selector) {
  608. var self = this, ctrl, parents = new Collection();
  609. // Add each parent to collection
  610. for (ctrl = self.parent(); ctrl; ctrl = ctrl.parent()) {
  611. parents.add(ctrl);
  612. }
  613. // Filter away everything that doesn't match the selector
  614. if (selector) {
  615. parents = parents.filter(selector);
  616. }
  617. return parents;
  618. },
  619. /**
  620. * Returns the current control and it's parents.
  621. *
  622. * @method parentsAndSelf
  623. * @param {String} selector Optional selector expression to find parents.
  624. * @return {tinymce.ui.Collection} Collection with all parent controls.
  625. */
  626. parentsAndSelf: function(selector) {
  627. return new Collection(this).add(this.parents(selector));
  628. },
  629. /**
  630. * Returns the control next to the current control.
  631. *
  632. * @method next
  633. * @return {tinymce.ui.Control} Next control instance.
  634. */
  635. next: function() {
  636. var parentControls = this.parent().items();
  637. return parentControls[parentControls.indexOf(this) + 1];
  638. },
  639. /**
  640. * Returns the control previous to the current control.
  641. *
  642. * @method prev
  643. * @return {tinymce.ui.Control} Previous control instance.
  644. */
  645. prev: function() {
  646. var parentControls = this.parent().items();
  647. return parentControls[parentControls.indexOf(this) - 1];
  648. },
  649. /**
  650. * Find the common ancestor for two control instances.
  651. *
  652. * @method findCommonAncestor
  653. * @param {tinymce.ui.Control} ctrl1 First control.
  654. * @param {tinymce.ui.Control} ctrl2 Second control.
  655. * @return {tinymce.ui.Control} Ancestor control instance.
  656. */
  657. findCommonAncestor: function(ctrl1, ctrl2) {
  658. var parentCtrl;
  659. while (ctrl1) {
  660. parentCtrl = ctrl2;
  661. while (parentCtrl && ctrl1 != parentCtrl) {
  662. parentCtrl = parentCtrl.parent();
  663. }
  664. if (ctrl1 == parentCtrl) {
  665. break;
  666. }
  667. ctrl1 = ctrl1.parent();
  668. }
  669. return ctrl1;
  670. },
  671. /**
  672. * Returns true/false if the specific control has the specific class.
  673. *
  674. * @method hasClass
  675. * @param {String} cls Class to check for.
  676. * @param {String} [group] Sub element group name.
  677. * @return {Boolean} True/false if the control has the specified class.
  678. */
  679. hasClass: function(cls, group) {
  680. var classes = this._classes[group || 'control'];
  681. cls = this.classPrefix + cls;
  682. return classes && !!classes.map[cls];
  683. },
  684. /**
  685. * Adds the specified class to the control
  686. *
  687. * @method addClass
  688. * @param {String} cls Class to check for.
  689. * @param {String} [group] Sub element group name.
  690. * @return {tinymce.ui.Control} Current control object.
  691. */
  692. addClass: function(cls, group) {
  693. var self = this, classes, elm;
  694. cls = this.classPrefix + cls;
  695. classes = self._classes[group || 'control'];
  696. if (!classes) {
  697. classes = [];
  698. classes.map = {};
  699. self._classes[group || 'control'] = classes;
  700. }
  701. if (!classes.map[cls]) {
  702. classes.map[cls] = cls;
  703. classes.push(cls);
  704. if (self._rendered) {
  705. elm = self.getEl(group);
  706. if (elm) {
  707. elm.className = classes.join(' ');
  708. }
  709. }
  710. }
  711. return self;
  712. },
  713. /**
  714. * Removes the specified class from the control.
  715. *
  716. * @method removeClass
  717. * @param {String} cls Class to remove.
  718. * @param {String} [group] Sub element group name.
  719. * @return {tinymce.ui.Control} Current control object.
  720. */
  721. removeClass: function(cls, group) {
  722. var self = this, classes, i, elm;
  723. cls = this.classPrefix + cls;
  724. classes = self._classes[group || 'control'];
  725. if (classes && classes.map[cls]) {
  726. delete classes.map[cls];
  727. i = classes.length;
  728. while (i--) {
  729. if (classes[i] === cls) {
  730. classes.splice(i, 1);
  731. }
  732. }
  733. }
  734. if (self._rendered) {
  735. elm = self.getEl(group);
  736. if (elm) {
  737. elm.className = classes.join(' ');
  738. }
  739. }
  740. return self;
  741. },
  742. /**
  743. * Toggles the specified class on the control.
  744. *
  745. * @method toggleClass
  746. * @param {String} cls Class to remove.
  747. * @param {Boolean} state True/false state to add/remove class.
  748. * @param {String} [group] Sub element group name.
  749. * @return {tinymce.ui.Control} Current control object.
  750. */
  751. toggleClass: function(cls, state, group) {
  752. var self = this;
  753. if (state) {
  754. self.addClass(cls, group);
  755. } else {
  756. self.removeClass(cls, group);
  757. }
  758. return self;
  759. },
  760. /**
  761. * Returns the class string for the specified group name.
  762. *
  763. * @method classes
  764. * @param {String} [group] Group to get clases by.
  765. * @return {String} Classes for the specified group.
  766. */
  767. classes: function(group) {
  768. var classes = this._classes[group || 'control'];
  769. return classes ? classes.join(' ') : '';
  770. },
  771. /**
  772. * Sets the inner HTML of the control element.
  773. *
  774. * @method innerHtml
  775. * @param {String} html Html string to set as inner html.
  776. * @return {tinymce.ui.Control} Current control object.
  777. */
  778. innerHtml: function(html) {
  779. DomUtils.innerHtml(this.getEl(), html);
  780. return this;
  781. },
  782. /**
  783. * Returns the control DOM element or sub element.
  784. *
  785. * @method getEl
  786. * @param {String} [suffix] Suffix to get element by.
  787. * @param {Boolean} [dropCache] True if the cache for the element should be dropped.
  788. * @return {Element} HTML DOM element for the current control or it's children.
  789. */
  790. getEl: function(suffix, dropCache) {
  791. var elm, id = suffix ? this._id + '-' + suffix : this._id;
  792. elm = elementIdCache[id] = (dropCache === true ? null : elementIdCache[id]) || DomUtils.get(id);
  793. return elm;
  794. },
  795. /**
  796. * Sets/gets the visible for the control.
  797. *
  798. * @method visible
  799. * @param {Boolean} state Value to set to control.
  800. * @return {Boolean/tinymce.ui.Control} Current control on a set operation or current state on a get.
  801. */
  802. visible: function(state) {
  803. var self = this, parentCtrl;
  804. if (typeof(state) !== "undefined") {
  805. if (self._visible !== state) {
  806. if (self._rendered) {
  807. self.getEl().style.display = state ? '' : 'none';
  808. }
  809. self._visible = state;
  810. // Parent container needs to reflow
  811. parentCtrl = self.parent();
  812. if (parentCtrl) {
  813. parentCtrl._lastRect = null;
  814. }
  815. self.fire(state ? 'show' : 'hide');
  816. }
  817. return self;
  818. }
  819. return self._visible;
  820. },
  821. /**
  822. * Sets the visible state to true.
  823. *
  824. * @method show
  825. * @return {tinymce.ui.Control} Current control instance.
  826. */
  827. show: function() {
  828. return this.visible(true);
  829. },
  830. /**
  831. * Sets the visible state to false.
  832. *
  833. * @method hide
  834. * @return {tinymce.ui.Control} Current control instance.
  835. */
  836. hide: function() {
  837. return this.visible(false);
  838. },
  839. /**
  840. * Focuses the current control.
  841. *
  842. * @method focus
  843. * @return {tinymce.ui.Control} Current control instance.
  844. */
  845. focus: function() {
  846. try {
  847. this.getEl().focus();
  848. } catch (ex) {
  849. // Ignore IE error
  850. }
  851. return this;
  852. },
  853. /**
  854. * Blurs the current control.
  855. *
  856. * @method blur
  857. * @return {tinymce.ui.Control} Current control instance.
  858. */
  859. blur: function() {
  860. this.getEl().blur();
  861. return this;
  862. },
  863. /**
  864. * Sets the specified aria property.
  865. *
  866. * @method aria
  867. * @param {String} name Name of the aria property to set.
  868. * @param {String} value Value of the aria property.
  869. * @return {tinymce.ui.Control} Current control instance.
  870. */
  871. aria: function(name, value) {
  872. var self = this, elm = self.getEl(self.ariaTarget);
  873. if (typeof(value) === "undefined") {
  874. return self._aria[name];
  875. } else {
  876. self._aria[name] = value;
  877. }
  878. if (self._rendered) {
  879. elm.setAttribute(name == 'role' ? name : 'aria-' + name, value);
  880. }
  881. return self;
  882. },
  883. /**
  884. * Encodes the specified string with HTML entities. It will also
  885. * translate the string to different languages.
  886. *
  887. * @method encode
  888. * @param {String/Object/Array} text Text to entity encode.
  889. * @param {Boolean} [translate=true] False if the contents shouldn't be translated.
  890. * @return {String} Encoded and possible traslated string.
  891. */
  892. encode: function(text, translate) {
  893. if (translate !== false) {
  894. text = this.translate(text);
  895. }
  896. return (text || '').replace(/[&<>"]/g, function(match) {
  897. return '&#' + match.charCodeAt(0) + ';';
  898. });
  899. },
  900. /**
  901. * Returns the translated string.
  902. *
  903. * @method translate
  904. * @param {String} text Text to translate.
  905. * @return {String} Translated string or the same as the input.
  906. */
  907. translate: function(text) {
  908. return Control.translate ? Control.translate(text) : text;
  909. },
  910. /**
  911. * Adds items before the current control.
  912. *
  913. * @method before
  914. * @param {Array/tinymce.ui.Collection} items Array of items to prepend before this control.
  915. * @return {tinymce.ui.Control} Current control instance.
  916. */
  917. before: function(items) {
  918. var self = this, parent = self.parent();
  919. if (parent) {
  920. parent.insert(items, parent.items().indexOf(self), true);
  921. }
  922. return self;
  923. },
  924. /**
  925. * Adds items after the current control.
  926. *
  927. * @method after
  928. * @param {Array/tinymce.ui.Collection} items Array of items to append after this control.
  929. * @return {tinymce.ui.Control} Current control instance.
  930. */
  931. after: function(items) {
  932. var self = this, parent = self.parent();
  933. if (parent) {
  934. parent.insert(items, parent.items().indexOf(self));
  935. }
  936. return self;
  937. },
  938. /**
  939. * Removes the current control from DOM and from UI collections.
  940. *
  941. * @method remove
  942. * @return {tinymce.ui.Control} Current control instance.
  943. */
  944. remove: function() {
  945. var self = this, elm = self.getEl(), parent = self.parent(), newItems, i;
  946. if (self.items) {
  947. var controls = self.items().toArray();
  948. i = controls.length;
  949. while (i--) {
  950. controls[i].remove();
  951. }
  952. }
  953. if (parent && parent.items) {
  954. newItems = [];
  955. parent.items().each(function(item) {
  956. if (item !== self) {
  957. newItems.push(item);
  958. }
  959. });
  960. parent.items().set(newItems);
  961. parent._lastRect = null;
  962. }
  963. if (self._eventsRoot && self._eventsRoot == self) {
  964. DomUtils.off(elm);
  965. }
  966. var lookup = self.getRoot().controlIdLookup;
  967. if (lookup) {
  968. delete lookup[self._id];
  969. }
  970. delete elementIdCache[self._id];
  971. if (elm && elm.parentNode) {
  972. var nodes = elm.getElementsByTagName('*');
  973. i = nodes.length;
  974. while (i--) {
  975. delete elementIdCache[nodes[i].id];
  976. }
  977. elm.parentNode.removeChild(elm);
  978. }
  979. self._rendered = false;
  980. return self;
  981. },
  982. /**
  983. * Renders the control before the specified element.
  984. *
  985. * @method renderBefore
  986. * @param {Element} elm Element to render before.
  987. * @return {tinymce.ui.Control} Current control instance.
  988. */
  989. renderBefore: function(elm) {
  990. var self = this;
  991. elm.parentNode.insertBefore(DomUtils.createFragment(self.renderHtml()), elm);
  992. self.postRender();
  993. return self;
  994. },
  995. /**
  996. * Renders the control to the specified element.
  997. *
  998. * @method renderBefore
  999. * @param {Element} elm Element to render to.
  1000. * @return {tinymce.ui.Control} Current control instance.
  1001. */
  1002. renderTo: function(elm) {
  1003. var self = this;
  1004. elm = elm || self.getContainerElm();
  1005. elm.appendChild(DomUtils.createFragment(self.renderHtml()));
  1006. self.postRender();
  1007. return self;
  1008. },
  1009. /**
  1010. * Post render method. Called after the control has been rendered to the target.
  1011. *
  1012. * @method postRender
  1013. * @return {tinymce.ui.Control} Current control instance.
  1014. */
  1015. postRender: function() {
  1016. var self = this, settings = self.settings, elm, box, parent, name, parentEventsRoot;
  1017. // Bind on<event> settings
  1018. for (name in settings) {
  1019. if (name.indexOf("on") === 0) {
  1020. self.on(name.substr(2), settings[name]);
  1021. }
  1022. }
  1023. if (self._eventsRoot) {
  1024. for (parent = self.parent(); !parentEventsRoot && parent; parent = parent.parent()) {
  1025. parentEventsRoot = parent._eventsRoot;
  1026. }
  1027. if (parentEventsRoot) {
  1028. for (name in parentEventsRoot._nativeEvents) {
  1029. self._nativeEvents[name] = true;
  1030. }
  1031. }
  1032. }
  1033. self.bindPendingEvents();
  1034. if (settings.style) {
  1035. elm = self.getEl();
  1036. if (elm) {
  1037. elm.setAttribute('style', settings.style);
  1038. elm.style.cssText = settings.style;
  1039. }
  1040. }
  1041. if (!self._visible) {
  1042. DomUtils.css(self.getEl(), 'display', 'none');
  1043. }
  1044. if (self.settings.border) {
  1045. box = self.borderBox();
  1046. DomUtils.css(self.getEl(), {
  1047. 'border-top-width': box.top,
  1048. 'border-right-width': box.right,
  1049. 'border-bottom-width': box.bottom,
  1050. 'border-left-width': box.left
  1051. });
  1052. }
  1053. // Add instance to lookup
  1054. var root = self.getRoot();
  1055. if (!root.controlIdLookup) {
  1056. root.controlIdLookup = {};
  1057. }
  1058. root.controlIdLookup[self._id] = self;
  1059. for (var key in self._aria) {
  1060. self.aria(key, self._aria[key]);
  1061. }
  1062. self.fire('postrender', {}, false);
  1063. },
  1064. /**
  1065. * Scrolls the current control into view.
  1066. *
  1067. * @method scrollIntoView
  1068. * @param {String} align Alignment in view top|center|bottom.
  1069. * @return {tinymce.ui.Control} Current control instance.
  1070. */
  1071. scrollIntoView: function(align) {
  1072. function getOffset(elm, rootElm) {
  1073. var x, y, parent = elm;
  1074. x = y = 0;
  1075. while (parent && parent != rootElm && parent.nodeType) {
  1076. x += parent.offsetLeft || 0;
  1077. y += parent.offsetTop || 0;
  1078. parent = parent.offsetParent;
  1079. }
  1080. return {x: x, y: y};
  1081. }
  1082. var elm = this.getEl(), parentElm = elm.parentNode;
  1083. var x, y, width, height, parentWidth, parentHeight;
  1084. var pos = getOffset(elm, parentElm);
  1085. x = pos.x;
  1086. y = pos.y;
  1087. width = elm.offsetWidth;
  1088. height = elm.offsetHeight;
  1089. parentWidth = parentElm.clientWidth;
  1090. parentHeight = parentElm.clientHeight;
  1091. if (align == "end") {
  1092. x -= parentWidth - width;
  1093. y -= parentHeight - height;
  1094. } else if (align == "center") {
  1095. x -= (parentWidth / 2) - (width / 2);
  1096. y -= (parentHeight / 2) - (height / 2);
  1097. }
  1098. parentElm.scrollLeft = x;
  1099. parentElm.scrollTop = y;
  1100. return this;
  1101. },
  1102. /**
  1103. * Binds pending DOM events.
  1104. *
  1105. * @private
  1106. */
  1107. bindPendingEvents: function() {
  1108. var self = this, i, l, parents, eventRootCtrl, nativeEvents, name;
  1109. function delegate(e) {
  1110. var control = self.getParentCtrl(e.target);
  1111. if (control) {
  1112. control.fire(e.type, e);
  1113. }
  1114. }
  1115. function mouseLeaveHandler() {
  1116. var ctrl = eventRootCtrl._lastHoverCtrl;
  1117. if (ctrl) {
  1118. ctrl.fire("mouseleave", {target: ctrl.getEl()});
  1119. ctrl.parents().each(function(ctrl) {
  1120. ctrl.fire("mouseleave", {target: ctrl.getEl()});
  1121. });
  1122. eventRootCtrl._lastHoverCtrl = null;
  1123. }
  1124. }
  1125. function mouseEnterHandler(e) {
  1126. var ctrl = self.getParentCtrl(e.target), lastCtrl = eventRootCtrl._lastHoverCtrl, idx = 0, i, parents, lastParents;
  1127. // Over on a new control
  1128. if (ctrl !== lastCtrl) {
  1129. eventRootCtrl._lastHoverCtrl = ctrl;
  1130. parents = ctrl.parents().toArray().reverse();
  1131. parents.push(ctrl);
  1132. if (lastCtrl) {
  1133. lastParents = lastCtrl.parents().toArray().reverse();
  1134. lastParents.push(lastCtrl);
  1135. for (idx = 0; idx < lastParents.length; idx++) {
  1136. if (parents[idx] !== lastParents[idx]) {
  1137. break;
  1138. }
  1139. }
  1140. for (i = lastParents.length - 1; i >= idx; i--) {
  1141. lastCtrl = lastParents[i];
  1142. lastCtrl.fire("mouseleave", {
  1143. target : lastCtrl.getEl()
  1144. });
  1145. }
  1146. }
  1147. for (i = idx; i < parents.length; i++) {
  1148. ctrl = parents[i];
  1149. ctrl.fire("mouseenter", {
  1150. target : ctrl.getEl()
  1151. });
  1152. }
  1153. }
  1154. }
  1155. function fixWheelEvent(e) {
  1156. e.preventDefault();
  1157. if (e.type == "mousewheel") {
  1158. e.deltaY = -1 / 40 * e.wheelDelta;
  1159. if (e.wheelDeltaX) {
  1160. e.deltaX = -1 / 40 * e.wheelDeltaX;
  1161. }
  1162. } else {
  1163. e.deltaX = 0;
  1164. e.deltaY = e.detail;
  1165. }
  1166. e = self.fire("wheel", e);
  1167. }
  1168. self._rendered = true;
  1169. nativeEvents = self._nativeEvents;
  1170. if (nativeEvents) {
  1171. // Find event root element if it exists
  1172. parents = self.parents().toArray();
  1173. parents.unshift(self);
  1174. for (i = 0, l = parents.length; !eventRootCtrl && i < l; i++) {
  1175. eventRootCtrl = parents[i]._eventsRoot;
  1176. }
  1177. // Event root wasn't found the use the root control
  1178. if (!eventRootCtrl) {
  1179. eventRootCtrl = parents[parents.length - 1] || self;
  1180. }
  1181. // Set the eventsRoot property on children that didn't have it
  1182. self._eventsRoot = eventRootCtrl;
  1183. for (l = i, i = 0; i < l; i++) {
  1184. parents[i]._eventsRoot = eventRootCtrl;
  1185. }
  1186. var eventRootDelegates = eventRootCtrl._delegates;
  1187. if (!eventRootDelegates) {
  1188. eventRootDelegates = eventRootCtrl._delegates = {};
  1189. }
  1190. // Bind native event delegates
  1191. for (name in nativeEvents) {
  1192. if (!nativeEvents) {
  1193. return false;
  1194. }
  1195. if (name === "wheel" && !hasWheelEventSupport) {
  1196. if (hasMouseWheelEventSupport) {
  1197. DomUtils.on(self.getEl(), "mousewheel", fixWheelEvent);
  1198. } else {
  1199. DomUtils.on(self.getEl(), "DOMMouseScroll", fixWheelEvent);
  1200. }
  1201. continue;
  1202. }
  1203. // Special treatment for mousenter/mouseleave since these doesn't bubble
  1204. if (name === "mouseenter" || name === "mouseleave") {
  1205. // Fake mousenter/mouseleave
  1206. if (!eventRootCtrl._hasMouseEnter) {
  1207. DomUtils.on(eventRootCtrl.getEl(), "mouseleave", mouseLeaveHandler);
  1208. DomUtils.on(eventRootCtrl.getEl(), "mouseover", mouseEnterHandler);
  1209. eventRootCtrl._hasMouseEnter = 1;
  1210. }
  1211. } else if (!eventRootDelegates[name]) {
  1212. DomUtils.on(eventRootCtrl.getEl(), name, delegate);
  1213. eventRootDelegates[name] = true;
  1214. }
  1215. // Remove the event once it's bound
  1216. nativeEvents[name] = false;
  1217. }
  1218. }
  1219. },
  1220. getRoot: function() {
  1221. var ctrl = this, rootControl, parents = [];
  1222. while (ctrl) {
  1223. if (ctrl.rootControl) {
  1224. rootControl = ctrl.rootControl;
  1225. break;
  1226. }
  1227. parents.push(ctrl);
  1228. rootControl = ctrl;
  1229. ctrl = ctrl.parent();
  1230. }
  1231. if (!rootControl) {
  1232. rootControl = this;
  1233. }
  1234. var i = parents.length;
  1235. while (i--) {
  1236. parents[i].rootControl = rootControl;
  1237. }
  1238. return rootControl;
  1239. },
  1240. /**
  1241. * Reflows the current control and it's parents.
  1242. * This should be used after you for example append children to the current control so
  1243. * that the layout managers know that they need to reposition everything.
  1244. *
  1245. * @example
  1246. * container.append({type: 'button', text: 'My button'}).reflow();
  1247. *
  1248. * @method reflow
  1249. * @return {tinymce.ui.Control} Current control instance.
  1250. */
  1251. reflow: function() {
  1252. this.repaint();
  1253. return this;
  1254. }
  1255. /**
  1256. * Sets/gets the parent container for the control.
  1257. *
  1258. * @method parent
  1259. * @param {tinymce.ui.Container} parent Optional parent to set.
  1260. * @return {tinymce.ui.Control} Parent control or the current control on a set action.
  1261. */
  1262. // parent: function(parent) {} -- Generated
  1263. /**
  1264. * Sets/gets the text for the control.
  1265. *
  1266. * @method text
  1267. * @param {String} value Value to set to control.
  1268. * @return {String/tinymce.ui.Control} Current control on a set operation or current value on a get.
  1269. */
  1270. // text: function(value) {} -- Generated
  1271. /**
  1272. * Sets/gets the width for the control.
  1273. *
  1274. * @method width
  1275. * @param {Number} value Value to set to control.
  1276. * @return {Number/tinymce.ui.Control} Current control on a set operation or current value on a get.
  1277. */
  1278. // width: function(value) {} -- Generated
  1279. /**
  1280. * Sets/gets the height for the control.
  1281. *
  1282. * @method height
  1283. * @param {Number} value Value to set to control.
  1284. * @return {Number/tinymce.ui.Control} Current control on a set operation or current value on a get.
  1285. */
  1286. // height: function(value) {} -- Generated
  1287. /**
  1288. * Sets/gets the disabled state on the control.
  1289. *
  1290. * @method disabled
  1291. * @param {Boolean} state Value to set to control.
  1292. * @return {Boolean/tinymce.ui.Control} Current control on a set operation or current state on a get.
  1293. */
  1294. // disabled: function(state) {} -- Generated
  1295. /**
  1296. * Sets/gets the active for the control.
  1297. *
  1298. * @method active
  1299. * @param {Boolean} state Value to set to control.
  1300. * @return {Boolean/tinymce.ui.Control} Current control on a set operation or current state on a get.
  1301. */
  1302. // active: function(state) {} -- Generated
  1303. /**
  1304. * Sets/gets the name for the control.
  1305. *
  1306. * @method name
  1307. * @param {String} value Value to set to control.
  1308. * @return {String/tinymce.ui.Control} Current control on a set operation or current value on a get.
  1309. */
  1310. // name: function(value) {} -- Generated
  1311. /**
  1312. * Sets/gets the title for the control.
  1313. *
  1314. * @method title
  1315. * @param {String} value Value to set to control.
  1316. * @return {String/tinymce.ui.Control} Current control on a set operation or current value on a get.
  1317. */
  1318. // title: function(value) {} -- Generated
  1319. });
  1320. return Control;
  1321. });