/static/scripts/tiny_mce/themes/advanced/editor_template_src.js

http://n23.googlecode.com/ · JavaScript · 1052 lines · 762 code · 227 blank · 63 comment · 148 complexity · e8a0826e6271cd6350cc7e81efce96c3 MD5 · raw file

  1. /**
  2. * $Id: editor_template_src.js 829 2008-04-30 14:35:32Z spocke $
  3. *
  4. * @author Moxiecode
  5. * @copyright Copyright Š 2004-2008, Moxiecode Systems AB, All rights reserved.
  6. */
  7. (function() {
  8. var DOM = tinymce.DOM, Event = tinymce.dom.Event, extend = tinymce.extend, each = tinymce.each, Cookie = tinymce.util.Cookie, lastExtID, explode = tinymce.explode;
  9. // Tell it to load theme specific language pack(s)
  10. tinymce.ThemeManager.requireLangPack('advanced');
  11. tinymce.create('tinymce.themes.AdvancedTheme', {
  12. // Control name lookup, format: title, command
  13. controls : {
  14. bold : ['bold_desc', 'Bold'],
  15. italic : ['italic_desc', 'Italic'],
  16. underline : ['underline_desc', 'Underline'],
  17. strikethrough : ['striketrough_desc', 'Strikethrough'],
  18. justifyleft : ['justifyleft_desc', 'JustifyLeft'],
  19. justifycenter : ['justifycenter_desc', 'JustifyCenter'],
  20. justifyright : ['justifyright_desc', 'JustifyRight'],
  21. justifyfull : ['justifyfull_desc', 'JustifyFull'],
  22. bullist : ['bullist_desc', 'InsertUnorderedList'],
  23. numlist : ['numlist_desc', 'InsertOrderedList'],
  24. outdent : ['outdent_desc', 'Outdent'],
  25. indent : ['indent_desc', 'Indent'],
  26. cut : ['cut_desc', 'Cut'],
  27. copy : ['copy_desc', 'Copy'],
  28. paste : ['paste_desc', 'Paste'],
  29. undo : ['undo_desc', 'Undo'],
  30. redo : ['redo_desc', 'Redo'],
  31. link : ['link_desc', 'mceLink'],
  32. unlink : ['unlink_desc', 'unlink'],
  33. image : ['image_desc', 'mceImage'],
  34. cleanup : ['cleanup_desc', 'mceCleanup'],
  35. help : ['help_desc', 'mceHelp'],
  36. code : ['code_desc', 'mceCodeEditor'],
  37. hr : ['hr_desc', 'InsertHorizontalRule'],
  38. removeformat : ['removeformat_desc', 'RemoveFormat'],
  39. sub : ['sub_desc', 'subscript'],
  40. sup : ['sup_desc', 'superscript'],
  41. forecolor : ['forecolor_desc', 'ForeColor'],
  42. forecolorpicker : ['forecolor_desc', 'mceForeColor'],
  43. backcolor : ['backcolor_desc', 'HiliteColor'],
  44. backcolorpicker : ['backcolor_desc', 'mceBackColor'],
  45. charmap : ['charmap_desc', 'mceCharMap'],
  46. visualaid : ['visualaid_desc', 'mceToggleVisualAid'],
  47. anchor : ['anchor_desc', 'mceInsertAnchor'],
  48. newdocument : ['newdocument_desc', 'mceNewDocument'],
  49. blockquote : ['blockquote_desc', 'mceBlockQuote']
  50. },
  51. stateControls : ['bold', 'italic', 'underline', 'strikethrough', 'bullist', 'numlist', 'justifyleft', 'justifycenter', 'justifyright', 'justifyfull', 'sub', 'sup', 'blockquote'],
  52. init : function(ed, url) {
  53. var t = this, s, v;
  54. t.editor = ed;
  55. t.url = url;
  56. t.onResolveName = new tinymce.util.Dispatcher(this);
  57. // Default settings
  58. t.settings = s = extend({
  59. theme_advanced_path : true,
  60. theme_advanced_toolbar_location : 'bottom',
  61. theme_advanced_buttons1 : "bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|,styleselect,formatselect",
  62. theme_advanced_buttons2 : "bullist,numlist,|,outdent,indent,|,undo,redo,|,link,unlink,anchor,image,cleanup,help,code",
  63. theme_advanced_buttons3 : "hr,removeformat,visualaid,|,sub,sup,|,charmap",
  64. theme_advanced_blockformats : "p,address,pre,h1,h2,h3,h4,h5,h6",
  65. theme_advanced_toolbar_align : "center",
  66. theme_advanced_fonts : "Andale Mono=andale mono,times;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;Comic Sans MS=comic sans ms,sans-serif;Courier New=courier new,courier;Georgia=georgia,palatino;Helvetica=helvetica;Impact=impact,chicago;Symbol=symbol;Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal,monaco;Times New Roman=times new roman,times;Trebuchet MS=trebuchet ms,geneva;Verdana=verdana,geneva;Webdings=webdings;Wingdings=wingdings,zapf dingbats",
  67. theme_advanced_font_sizes : "1,2,3,4,5,6,7",
  68. theme_advanced_more_colors : 1,
  69. theme_advanced_row_height : 23,
  70. theme_advanced_resize_horizontal : 1,
  71. theme_advanced_resizing_use_cookie : 1
  72. }, ed.settings);
  73. if ((v = s.theme_advanced_path_location) && v != 'none')
  74. s.theme_advanced_statusbar_location = s.theme_advanced_path_location;
  75. if (s.theme_advanced_statusbar_location == 'none')
  76. s.theme_advanced_statusbar_location = 0;
  77. // Init editor
  78. ed.onInit.add(function() {
  79. ed.onNodeChange.add(t._nodeChanged, t);
  80. if (ed.settings.content_css !== false)
  81. ed.dom.loadCSS(ed.baseURI.toAbsolute("themes/advanced/skins/" + ed.settings.skin + "/content.css"));
  82. });
  83. ed.onSetProgressState.add(function(ed, b, ti) {
  84. var co, id = ed.id, tb;
  85. if (b) {
  86. t.progressTimer = setTimeout(function() {
  87. co = ed.getContainer();
  88. co = co.insertBefore(DOM.create('DIV', {style : 'position:relative'}), co.firstChild);
  89. tb = DOM.get(ed.id + '_tbl');
  90. DOM.add(co, 'div', {id : id + '_blocker', 'class' : 'mceBlocker', style : {width : tb.clientWidth + 2, height : tb.clientHeight + 2}});
  91. DOM.add(co, 'div', {id : id + '_progress', 'class' : 'mceProgress', style : {left : tb.clientWidth / 2, top : tb.clientHeight / 2}});
  92. }, ti || 0);
  93. } else {
  94. DOM.remove(id + '_blocker');
  95. DOM.remove(id + '_progress');
  96. clearTimeout(t.progressTimer);
  97. }
  98. });
  99. DOM.loadCSS(ed.baseURI.toAbsolute(s.editor_css || "themes/advanced/skins/" + ed.settings.skin + "/ui.css"));
  100. if (s.skin_variant)
  101. DOM.loadCSS(ed.baseURI.toAbsolute(s.editor_css || "themes/advanced/skins/" + ed.settings.skin + "/ui_" + s.skin_variant + ".css"));
  102. },
  103. createControl : function(n, cf) {
  104. var cd, c;
  105. if (c = cf.createControl(n))
  106. return c;
  107. switch (n) {
  108. case "styleselect":
  109. return this._createStyleSelect();
  110. case "formatselect":
  111. return this._createBlockFormats();
  112. case "fontselect":
  113. return this._createFontSelect();
  114. case "fontsizeselect":
  115. return this._createFontSizeSelect();
  116. case "forecolor":
  117. return this._createForeColorMenu();
  118. case "backcolor":
  119. return this._createBackColorMenu();
  120. }
  121. if ((cd = this.controls[n]))
  122. return cf.createButton(n, {title : "advanced." + cd[0], cmd : cd[1], ui : cd[2], value : cd[3]});
  123. },
  124. execCommand : function(cmd, ui, val) {
  125. var f = this['_' + cmd];
  126. if (f) {
  127. f.call(this, ui, val);
  128. return true;
  129. }
  130. return false;
  131. },
  132. _importClasses : function() {
  133. var ed = this.editor, c = ed.controlManager.get('styleselect');
  134. if (c.getLength() == 0) {
  135. each(ed.dom.getClasses(), function(o) {
  136. c.add(o['class'], o['class']);
  137. });
  138. }
  139. },
  140. _createStyleSelect : function(n) {
  141. var t = this, ed = t.editor, cf = ed.controlManager, c = cf.createListBox('styleselect', {
  142. title : 'advanced.style_select',
  143. onselect : function(v) {
  144. if (c.selectedValue === v) {
  145. ed.execCommand('mceSetStyleInfo', 0, {command : 'removeformat'});
  146. c.select();
  147. return false;
  148. } else
  149. ed.execCommand('mceSetCSSClass', 0, v);
  150. }
  151. });
  152. if (c) {
  153. each(ed.getParam('theme_advanced_styles', '', 'hash'), function(v, k) {
  154. if (v)
  155. c.add(t.editor.translate(k), v);
  156. });
  157. c.onPostRender.add(function(ed, n) {
  158. Event.add(n, 'focus', t._importClasses, t);
  159. Event.add(n, 'mousedown', t._importClasses, t);
  160. });
  161. }
  162. return c;
  163. },
  164. _createFontSelect : function() {
  165. var c, t = this, ed = t.editor;
  166. c = ed.controlManager.createListBox('fontselect', {title : 'advanced.fontdefault', cmd : 'FontName'});
  167. if (c) {
  168. each(ed.getParam('theme_advanced_fonts', t.settings.theme_advanced_fonts, 'hash'), function(v, k) {
  169. c.add(ed.translate(k), v, {style : v.indexOf('dings') == -1 ? 'font-family:' + v : ''});
  170. });
  171. }
  172. return c;
  173. },
  174. _createFontSizeSelect : function() {
  175. var t = this, ed = t.editor, c, lo = [
  176. "1 (8 pt)",
  177. "2 (10 pt)",
  178. "3 (12 pt)",
  179. "4 (14 pt)",
  180. "5 (18 pt)",
  181. "6 (24 pt)",
  182. "7 (36 pt)"
  183. ], fz = [8, 10, 12, 14, 18, 24, 36];
  184. c = ed.controlManager.createListBox('fontsizeselect', {title : 'advanced.font_size', cmd : 'FontSize'});
  185. if (c) {
  186. each(ed.getParam('theme_advanced_font_sizes', t.settings.theme_advanced_font_sizes, 'hash'), function(v, k) {
  187. c.add(k != v ? k : lo[parseInt(v) - 1], v, {'style' : 'font-size:' + fz[v - 1] + 'pt', 'class' : 'mceFontSize' + v});
  188. });
  189. }
  190. return c;
  191. },
  192. _createBlockFormats : function() {
  193. var c, fmts = {
  194. p : 'advanced.paragraph',
  195. address : 'advanced.address',
  196. pre : 'advanced.pre',
  197. h1 : 'advanced.h1',
  198. h2 : 'advanced.h2',
  199. h3 : 'advanced.h3',
  200. h4 : 'advanced.h4',
  201. h5 : 'advanced.h5',
  202. h6 : 'advanced.h6',
  203. div : 'advanced.div',
  204. blockquote : 'advanced.blockquote',
  205. code : 'advanced.code',
  206. dt : 'advanced.dt',
  207. dd : 'advanced.dd',
  208. samp : 'advanced.samp'
  209. }, t = this;
  210. c = t.editor.controlManager.createListBox('formatselect', {title : 'advanced.block', cmd : 'FormatBlock'});
  211. if (c) {
  212. each(t.editor.getParam('theme_advanced_blockformats', t.settings.theme_advanced_blockformats, 'hash'), function(v, k) {
  213. c.add(t.editor.translate(k != v ? k : fmts[v]), v, {'class' : 'mce_formatPreview mce_' + v});
  214. });
  215. }
  216. return c;
  217. },
  218. _createForeColorMenu : function() {
  219. var c, t = this, s = t.settings, o = {}, v;
  220. if (s.theme_advanced_more_colors) {
  221. o.more_colors_func = function() {
  222. t._mceColorPicker(0, {
  223. color : c.value,
  224. func : function(co) {
  225. c.setColor(co);
  226. }
  227. });
  228. };
  229. }
  230. if (v = s.theme_advanced_text_colors)
  231. o.colors = v;
  232. o.title = 'advanced.forecolor_desc';
  233. o.cmd = 'ForeColor';
  234. o.scope = this;
  235. c = t.editor.controlManager.createColorSplitButton('forecolor', o);
  236. return c;
  237. },
  238. _createBackColorMenu : function() {
  239. var c, t = this, s = t.settings, o = {}, v;
  240. if (s.theme_advanced_more_colors) {
  241. o.more_colors_func = function() {
  242. t._mceColorPicker(0, {
  243. color : c.value,
  244. func : function(co) {
  245. c.setColor(co);
  246. }
  247. });
  248. };
  249. }
  250. if (v = s.theme_advanced_background_colors)
  251. o.colors = v;
  252. o.title = 'advanced.backcolor_desc';
  253. o.cmd = 'HiliteColor';
  254. o.scope = this;
  255. c = t.editor.controlManager.createColorSplitButton('backcolor', o);
  256. return c;
  257. },
  258. renderUI : function(o) {
  259. var n, ic, tb, t = this, ed = t.editor, s = t.settings, sc, p, nl;
  260. n = p = DOM.create('span', {id : ed.id + '_parent', 'class' : 'mceEditor ' + ed.settings.skin + 'Skin' + (s.skin_variant ? ' ' + ed.settings.skin + 'Skin' + t._ufirst(s.skin_variant) : '')});
  261. if (!DOM.boxModel)
  262. n = DOM.add(n, 'div', {'class' : 'mceOldBoxModel'});
  263. n = sc = DOM.add(n, 'table', {id : ed.id + '_tbl', 'class' : 'mceLayout', cellSpacing : 0, cellPadding : 0});
  264. n = tb = DOM.add(n, 'tbody');
  265. switch ((s.theme_advanced_layout_manager || '').toLowerCase()) {
  266. case "rowlayout":
  267. ic = t._rowLayout(s, tb, o);
  268. break;
  269. case "customlayout":
  270. ic = ed.execCallback("theme_advanced_custom_layout", s, tb, o, p);
  271. break;
  272. default:
  273. ic = t._simpleLayout(s, tb, o, p);
  274. }
  275. n = o.targetNode;
  276. // Add classes to first and last TRs
  277. nl = DOM.stdMode ? sc.getElementsByTagName('tr') : sc.rows; // Quick fix for IE 8
  278. DOM.addClass(nl[0], 'mceFirst');
  279. DOM.addClass(nl[nl.length - 1], 'mceLast');
  280. // Add classes to first and last TDs
  281. each(DOM.select('tr', tb), function(n) {
  282. DOM.addClass(n.firstChild, 'mceFirst');
  283. DOM.addClass(n.childNodes[n.childNodes.length - 1], 'mceLast');
  284. });
  285. if (DOM.get(s.theme_advanced_toolbar_container))
  286. DOM.get(s.theme_advanced_toolbar_container).appendChild(p);
  287. else
  288. DOM.insertAfter(p, n);
  289. Event.add(ed.id + '_path_row', 'click', function(e) {
  290. e = e.target;
  291. if (e.nodeName == 'A') {
  292. t._sel(e.className.replace(/^.*mcePath_([0-9]+).*$/, '$1'));
  293. return Event.cancel(e);
  294. }
  295. });
  296. /*
  297. if (DOM.get(ed.id + '_path_row')) {
  298. Event.add(ed.id + '_tbl', 'mouseover', function(e) {
  299. var re;
  300. e = e.target;
  301. if (e.nodeName == 'SPAN' && DOM.hasClass(e.parentNode, 'mceButton')) {
  302. re = DOM.get(ed.id + '_path_row');
  303. t.lastPath = re.innerHTML;
  304. DOM.setHTML(re, e.parentNode.title);
  305. }
  306. });
  307. Event.add(ed.id + '_tbl', 'mouseout', function(e) {
  308. if (t.lastPath) {
  309. DOM.setHTML(ed.id + '_path_row', t.lastPath);
  310. t.lastPath = 0;
  311. }
  312. });
  313. }
  314. */
  315. if (!ed.getParam('accessibility_focus') || ed.getParam('tab_focus'))
  316. Event.add(DOM.add(p, 'a', {href : '#'}, '<!-- IE -->'), 'focus', function() {tinyMCE.get(ed.id).focus();});
  317. if (s.theme_advanced_toolbar_location == 'external')
  318. o.deltaHeight = 0;
  319. t.deltaHeight = o.deltaHeight;
  320. o.targetNode = null;
  321. return {
  322. iframeContainer : ic,
  323. editorContainer : ed.id + '_parent',
  324. sizeContainer : sc,
  325. deltaHeight : o.deltaHeight
  326. };
  327. },
  328. getInfo : function() {
  329. return {
  330. longname : 'Advanced theme',
  331. author : 'Moxiecode Systems AB',
  332. authorurl : 'http://tinymce.moxiecode.com',
  333. version : tinymce.majorVersion + "." + tinymce.minorVersion
  334. }
  335. },
  336. resizeBy : function(dw, dh) {
  337. var e = DOM.get(this.editor.id + '_tbl');
  338. this.resizeTo(e.clientWidth + dw, e.clientHeight + dh);
  339. },
  340. resizeTo : function(w, h) {
  341. var ed = this.editor, s = ed.settings, e = DOM.get(ed.id + '_tbl'), ifr = DOM.get(ed.id + '_ifr'), dh;
  342. // Boundery fix box
  343. w = Math.max(s.theme_advanced_resizing_min_width || 100, w);
  344. h = Math.max(s.theme_advanced_resizing_min_height || 100, h);
  345. w = Math.min(s.theme_advanced_resizing_max_width || 0xFFFF, w);
  346. h = Math.min(s.theme_advanced_resizing_max_height || 0xFFFF, h);
  347. // Calc difference between iframe and container
  348. dh = e.clientHeight - ifr.clientHeight;
  349. // Resize iframe and container
  350. DOM.setStyle(ifr, 'height', h - dh);
  351. DOM.setStyles(e, {width : w, height : h});
  352. },
  353. destroy : function() {
  354. var id = this.editor.id;
  355. Event.clear(id + '_resize');
  356. Event.clear(id + '_path_row');
  357. Event.clear(id + '_external_close');
  358. },
  359. // Internal functions
  360. _simpleLayout : function(s, tb, o, p) {
  361. var t = this, ed = t.editor, lo = s.theme_advanced_toolbar_location, sl = s.theme_advanced_statusbar_location, n, ic, etb, c;
  362. // Create toolbar container at top
  363. if (lo == 'top')
  364. t._addToolbars(tb, o);
  365. // Create external toolbar
  366. if (lo == 'external') {
  367. n = c = DOM.create('div', {style : 'position:relative'});
  368. n = DOM.add(n, 'div', {id : ed.id + '_external', 'class' : 'mceExternalToolbar'});
  369. DOM.add(n, 'a', {id : ed.id + '_external_close', href : 'javascript:;', 'class' : 'mceExternalClose'});
  370. n = DOM.add(n, 'table', {id : ed.id + '_tblext', cellSpacing : 0, cellPadding : 0});
  371. etb = DOM.add(n, 'tbody');
  372. if (p.firstChild.className == 'mceOldBoxModel')
  373. p.firstChild.appendChild(c);
  374. else
  375. p.insertBefore(c, p.firstChild);
  376. t._addToolbars(etb, o);
  377. ed.onMouseUp.add(function() {
  378. var e = DOM.get(ed.id + '_external');
  379. DOM.show(e);
  380. DOM.hide(lastExtID);
  381. var f = Event.add(ed.id + '_external_close', 'click', function() {
  382. DOM.hide(ed.id + '_external');
  383. Event.remove(ed.id + '_external_close', 'click', f);
  384. });
  385. DOM.show(e);
  386. DOM.setStyle(e, 'top', 0 - DOM.getRect(ed.id + '_tblext').h - 1);
  387. // Fixes IE rendering bug
  388. DOM.hide(e);
  389. DOM.show(e);
  390. e.style.filter = '';
  391. lastExtID = ed.id + '_external';
  392. e = null;
  393. });
  394. }
  395. if (sl == 'top')
  396. t._addStatusBar(tb, o);
  397. // Create iframe container
  398. if (!s.theme_advanced_toolbar_container) {
  399. n = DOM.add(tb, 'tr');
  400. n = ic = DOM.add(n, 'td', {'class' : 'mceIframeContainer'});
  401. }
  402. // Create toolbar container at bottom
  403. if (lo == 'bottom')
  404. t._addToolbars(tb, o);
  405. if (sl == 'bottom')
  406. t._addStatusBar(tb, o);
  407. return ic;
  408. },
  409. _rowLayout : function(s, tb, o) {
  410. var t = this, ed = t.editor, dc, da, cf = ed.controlManager, n, ic, to, a;
  411. dc = s.theme_advanced_containers_default_class || '';
  412. da = s.theme_advanced_containers_default_align || 'center';
  413. each(explode(s.theme_advanced_containers || ''), function(c, i) {
  414. var v = s['theme_advanced_container_' + c] || '';
  415. switch (v.toLowerCase()) {
  416. case 'mceeditor':
  417. n = DOM.add(tb, 'tr');
  418. n = ic = DOM.add(n, 'td', {'class' : 'mceIframeContainer'});
  419. break;
  420. case 'mceelementpath':
  421. t._addStatusBar(tb, o);
  422. break;
  423. default:
  424. a = (s['theme_advanced_container_' + c + '_align'] || da).toLowerCase();
  425. a = 'mce' + t._ufirst(a);
  426. n = DOM.add(DOM.add(tb, 'tr'), 'td', {
  427. 'class' : 'mceToolbar ' + (s['theme_advanced_container_' + c + '_class'] || dc) + ' ' + a || da
  428. });
  429. to = cf.createToolbar("toolbar" + i);
  430. t._addControls(v, to);
  431. DOM.setHTML(n, to.renderHTML());
  432. o.deltaHeight -= s.theme_advanced_row_height;
  433. }
  434. });
  435. return ic;
  436. },
  437. _addControls : function(v, tb) {
  438. var t = this, s = t.settings, di, cf = t.editor.controlManager;
  439. if (s.theme_advanced_disable && !t._disabled) {
  440. di = {};
  441. each(explode(s.theme_advanced_disable), function(v) {
  442. di[v] = 1;
  443. });
  444. t._disabled = di;
  445. } else
  446. di = t._disabled;
  447. each(explode(v), function(n) {
  448. var c;
  449. if (di && di[n])
  450. return;
  451. // Compatiblity with 2.x
  452. if (n == 'tablecontrols') {
  453. each(["table","|","row_props","cell_props","|","row_before","row_after","delete_row","|","col_before","col_after","delete_col","|","split_cells","merge_cells"], function(n) {
  454. n = t.createControl(n, cf);
  455. if (n)
  456. tb.add(n);
  457. });
  458. return;
  459. }
  460. c = t.createControl(n, cf);
  461. if (c)
  462. tb.add(c);
  463. });
  464. },
  465. _addToolbars : function(c, o) {
  466. var t = this, i, tb, ed = t.editor, s = t.settings, v, cf = ed.controlManager, di, n, h = [], a;
  467. a = s.theme_advanced_toolbar_align.toLowerCase();
  468. a = 'mce' + t._ufirst(a);
  469. n = DOM.add(DOM.add(c, 'tr'), 'td', {'class' : 'mceToolbar ' + a});
  470. if (!ed.getParam('accessibility_focus') || ed.getParam('tab_focus'))
  471. h.push(DOM.createHTML('a', {href : '#', onfocus : 'tinyMCE.get(\'' + ed.id + '\').focus();'}, '<!-- IE -->'));
  472. h.push(DOM.createHTML('a', {href : '#', accesskey : 'q', title : ed.getLang("advanced.toolbar_focus")}, '<!-- IE -->'));
  473. // Create toolbar and add the controls
  474. for (i=1; (v = s['theme_advanced_buttons' + i]); i++) {
  475. tb = cf.createToolbar("toolbar" + i, {'class' : 'mceToolbarRow' + i});
  476. if (s['theme_advanced_buttons' + i + '_add'])
  477. v += ',' + s['theme_advanced_buttons' + i + '_add'];
  478. if (s['theme_advanced_buttons' + i + '_add_before'])
  479. v = s['theme_advanced_buttons' + i + '_add_before'] + ',' + v;
  480. t._addControls(v, tb);
  481. //n.appendChild(n = tb.render());
  482. h.push(tb.renderHTML());
  483. o.deltaHeight -= s.theme_advanced_row_height;
  484. }
  485. h.push(DOM.createHTML('a', {href : '#', accesskey : 'z', title : ed.getLang("advanced.toolbar_focus"), onfocus : 'tinyMCE.getInstanceById(\'' + ed.id + '\').focus();'}, '<!-- IE -->'));
  486. DOM.setHTML(n, h.join(''));
  487. },
  488. _addStatusBar : function(tb, o) {
  489. var n, t = this, ed = t.editor, s = t.settings, r, mf, me, td;
  490. n = DOM.add(tb, 'tr');
  491. n = td = DOM.add(n, 'td', {'class' : 'mceStatusbar'});
  492. n = DOM.add(n, 'div', {id : ed.id + '_path_row'}, s.theme_advanced_path ? ed.translate('advanced.path') + ': ' : '&nbsp;');
  493. DOM.add(n, 'a', {href : '#', accesskey : 'x'});
  494. if (s.theme_advanced_resizing && !tinymce.isOldWebKit) {
  495. DOM.add(td, 'a', {id : ed.id + '_resize', href : 'javascript:;', onclick : "return false;", 'class' : 'mceResize'});
  496. if (s.theme_advanced_resizing_use_cookie) {
  497. ed.onPostRender.add(function() {
  498. var o = Cookie.getHash("TinyMCE_" + ed.id + "_size"), c = DOM.get(ed.id + '_tbl');
  499. if (!o)
  500. return;
  501. if (s.theme_advanced_resize_horizontal)
  502. c.style.width = Math.max(10, o.cw) + 'px';
  503. c.style.height = Math.max(10, o.ch) + 'px';
  504. DOM.get(ed.id + '_ifr').style.height = Math.max(10, parseInt(o.ch) + t.deltaHeight) + 'px';
  505. });
  506. }
  507. ed.onPostRender.add(function() {
  508. Event.add(ed.id + '_resize', 'mousedown', function(e) {
  509. var c, p, w, h, n, pa;
  510. // Measure container
  511. c = DOM.get(ed.id + '_tbl');
  512. w = c.clientWidth;
  513. h = c.clientHeight;
  514. miw = s.theme_advanced_resizing_min_width || 100;
  515. mih = s.theme_advanced_resizing_min_height || 100;
  516. maw = s.theme_advanced_resizing_max_width || 0xFFFF;
  517. mah = s.theme_advanced_resizing_max_height || 0xFFFF;
  518. // Setup placeholder
  519. p = DOM.add(DOM.get(ed.id + '_parent'), 'div', {'class' : 'mcePlaceHolder'});
  520. DOM.setStyles(p, {width : w, height : h});
  521. // Replace with placeholder
  522. DOM.hide(c);
  523. DOM.show(p);
  524. // Create internal resize obj
  525. r = {
  526. x : e.screenX,
  527. y : e.screenY,
  528. w : w,
  529. h : h,
  530. dx : null,
  531. dy : null
  532. };
  533. // Start listening
  534. mf = Event.add(DOM.doc, 'mousemove', function(e) {
  535. var w, h;
  536. // Calc delta values
  537. r.dx = e.screenX - r.x;
  538. r.dy = e.screenY - r.y;
  539. // Boundery fix box
  540. w = Math.max(miw, r.w + r.dx);
  541. h = Math.max(mih, r.h + r.dy);
  542. w = Math.min(maw, w);
  543. h = Math.min(mah, h);
  544. // Resize placeholder
  545. if (s.theme_advanced_resize_horizontal)
  546. p.style.width = w + 'px';
  547. p.style.height = h + 'px';
  548. return Event.cancel(e);
  549. });
  550. me = Event.add(DOM.doc, 'mouseup', function(e) {
  551. var ifr;
  552. // Stop listening
  553. Event.remove(DOM.doc, 'mousemove', mf);
  554. Event.remove(DOM.doc, 'mouseup', me);
  555. c.style.display = '';
  556. DOM.remove(p);
  557. if (r.dx === null)
  558. return;
  559. ifr = DOM.get(ed.id + '_ifr');
  560. if (s.theme_advanced_resize_horizontal)
  561. c.style.width = Math.max(10, r.w + r.dx) + 'px';
  562. c.style.height = Math.max(10, r.h + r.dy) + 'px';
  563. ifr.style.height = Math.max(10, ifr.clientHeight + r.dy) + 'px';
  564. if (s.theme_advanced_resizing_use_cookie) {
  565. Cookie.setHash("TinyMCE_" + ed.id + "_size", {
  566. cw : r.w + r.dx,
  567. ch : r.h + r.dy
  568. });
  569. }
  570. });
  571. return Event.cancel(e);
  572. });
  573. });
  574. }
  575. o.deltaHeight -= 21;
  576. n = tb = null;
  577. },
  578. _nodeChanged : function(ed, cm, n, co) {
  579. var t = this, p, de = 0, v, c, s = t.settings;
  580. tinymce.each(t.stateControls, function(c) {
  581. cm.setActive(c, ed.queryCommandState(t.controls[c][1]));
  582. });
  583. cm.setActive('visualaid', ed.hasVisual);
  584. cm.setDisabled('undo', !ed.undoManager.hasUndo() && !ed.typing);
  585. cm.setDisabled('redo', !ed.undoManager.hasRedo());
  586. cm.setDisabled('outdent', !ed.queryCommandState('Outdent'));
  587. p = DOM.getParent(n, 'A');
  588. if (c = cm.get('link')) {
  589. if (!p || !p.name) {
  590. c.setDisabled(!p && co);
  591. c.setActive(!!p);
  592. }
  593. }
  594. if (c = cm.get('unlink')) {
  595. c.setDisabled(!p && co);
  596. c.setActive(!!p && !p.name);
  597. }
  598. if (c = cm.get('anchor')) {
  599. c.setActive(!!p && p.name);
  600. if (tinymce.isWebKit) {
  601. p = DOM.getParent(n, 'IMG');
  602. c.setActive(!!p && DOM.getAttrib(p, 'mce_name') == 'a');
  603. }
  604. }
  605. p = DOM.getParent(n, 'IMG');
  606. if (c = cm.get('image'))
  607. c.setActive(!!p && n.className.indexOf('mceItem') == -1);
  608. if (c = cm.get('styleselect')) {
  609. if (n.className) {
  610. t._importClasses();
  611. c.select(n.className);
  612. } else
  613. c.select();
  614. }
  615. if (c = cm.get('formatselect')) {
  616. p = DOM.getParent(n, DOM.isBlock);
  617. if (p)
  618. c.select(p.nodeName.toLowerCase());
  619. }
  620. if (c = cm.get('fontselect'))
  621. c.select(ed.queryCommandValue('FontName'));
  622. if (c = cm.get('fontsizeselect'))
  623. c.select('' + ed.queryCommandValue('FontSize'));
  624. if (s.theme_advanced_path && s.theme_advanced_statusbar_location) {
  625. p = DOM.get(ed.id + '_path') || DOM.add(ed.id + '_path_row', 'span', {id : ed.id + '_path'});
  626. DOM.setHTML(p, '');
  627. ed.dom.getParent(n, function(n) {
  628. var na = n.nodeName.toLowerCase(), u, pi, ti = '';
  629. // Ignore non element and hidden elements
  630. if (n.nodeType != 1 || (DOM.hasClass(n, 'mceItemHidden') || DOM.hasClass(n, 'mceItemRemoved')))
  631. return;
  632. // Fake name
  633. if (v = DOM.getAttrib(n, 'mce_name'))
  634. na = v;
  635. // Handle prefix
  636. if (tinymce.isIE && n.scopeName !== 'HTML')
  637. na = n.scopeName + ':' + na;
  638. // Remove internal prefix
  639. na = na.replace(/mce\:/g, '');
  640. // Handle node name
  641. switch (na) {
  642. case 'b':
  643. na = 'strong';
  644. break;
  645. case 'i':
  646. na = 'em';
  647. break;
  648. case 'img':
  649. if (v = DOM.getAttrib(n, 'src'))
  650. ti += 'src: ' + v + ' ';
  651. break;
  652. case 'a':
  653. if (v = DOM.getAttrib(n, 'name')) {
  654. ti += 'name: ' + v + ' ';
  655. na += '#' + v;
  656. }
  657. if (v = DOM.getAttrib(n, 'href'))
  658. ti += 'href: ' + v + ' ';
  659. break;
  660. case 'font':
  661. if (s.convert_fonts_to_spans)
  662. na = 'span';
  663. if (v = DOM.getAttrib(n, 'face'))
  664. ti += 'font: ' + v + ' ';
  665. if (v = DOM.getAttrib(n, 'size'))
  666. ti += 'size: ' + v + ' ';
  667. if (v = DOM.getAttrib(n, 'color'))
  668. ti += 'color: ' + v + ' ';
  669. break;
  670. case 'span':
  671. if (v = DOM.getAttrib(n, 'style'))
  672. ti += 'style: ' + v + ' ';
  673. break;
  674. }
  675. if (v = DOM.getAttrib(n, 'id'))
  676. ti += 'id: ' + v + ' ';
  677. if (v = n.className) {
  678. v = v.replace(/(webkit-[\w\-]+|Apple-[\w\-]+|mceItem\w+|mceVisualAid)/g, '');
  679. if (v && v.indexOf('mceItem') == -1) {
  680. ti += 'class: ' + v + ' ';
  681. if (DOM.isBlock(n) || na == 'img' || na == 'span')
  682. na += '.' + v;
  683. }
  684. }
  685. na = na.replace(/(html:)/g, '');
  686. na = {name : na, node : n, title : ti};
  687. t.onResolveName.dispatch(t, na);
  688. ti = na.title;
  689. na = na.name;
  690. //u = "javascript:tinymce.EditorManager.get('" + ed.id + "').theme._sel('" + (de++) + "');";
  691. pi = DOM.create('a', {'href' : "javascript:;", onmousedown : "return false;", title : ti, 'class' : 'mcePath_' + (de++)}, na);
  692. if (p.hasChildNodes()) {
  693. p.insertBefore(DOM.doc.createTextNode(' \u00bb '), p.firstChild);
  694. p.insertBefore(pi, p.firstChild);
  695. } else
  696. p.appendChild(pi);
  697. }, ed.getBody());
  698. }
  699. },
  700. // Commands gets called by execCommand
  701. _sel : function(v) {
  702. this.editor.execCommand('mceSelectNodeDepth', false, v);
  703. },
  704. _mceInsertAnchor : function(ui, v) {
  705. var ed = this.editor;
  706. ed.windowManager.open({
  707. url : tinymce.baseURL + '/themes/advanced/anchor.htm',
  708. width : 320 + parseInt(ed.getLang('advanced.anchor_delta_width', 0)),
  709. height : 90 + parseInt(ed.getLang('advanced.anchor_delta_height', 0)),
  710. inline : true
  711. }, {
  712. theme_url : this.url
  713. });
  714. },
  715. _mceCharMap : function() {
  716. var ed = this.editor;
  717. ed.windowManager.open({
  718. url : tinymce.baseURL + '/themes/advanced/charmap.htm',
  719. width : 550 + parseInt(ed.getLang('advanced.charmap_delta_width', 0)),
  720. height : 250 + parseInt(ed.getLang('advanced.charmap_delta_height', 0)),
  721. inline : true
  722. }, {
  723. theme_url : this.url
  724. });
  725. },
  726. _mceHelp : function() {
  727. var ed = this.editor;
  728. ed.windowManager.open({
  729. url : tinymce.baseURL + '/themes/advanced/about.htm',
  730. width : 480,
  731. height : 380,
  732. inline : true
  733. }, {
  734. theme_url : this.url
  735. });
  736. },
  737. _mceColorPicker : function(u, v) {
  738. var ed = this.editor;
  739. v = v || {};
  740. ed.windowManager.open({
  741. url : tinymce.baseURL + '/themes/advanced/color_picker.htm',
  742. width : 375 + parseInt(ed.getLang('advanced.colorpicker_delta_width', 0)),
  743. height : 250 + parseInt(ed.getLang('advanced.colorpicker_delta_height', 0)),
  744. close_previous : false,
  745. inline : true
  746. }, {
  747. input_color : v.color,
  748. func : v.func,
  749. theme_url : this.url
  750. });
  751. },
  752. _mceCodeEditor : function(ui, val) {
  753. var ed = this.editor;
  754. ed.windowManager.open({
  755. url : tinymce.baseURL + '/themes/advanced/source_editor.htm',
  756. width : parseInt(ed.getParam("theme_advanced_source_editor_width", 720)),
  757. height : parseInt(ed.getParam("theme_advanced_source_editor_height", 580)),
  758. inline : true,
  759. resizable : true,
  760. maximizable : true
  761. }, {
  762. theme_url : this.url
  763. });
  764. },
  765. _mceImage : function(ui, val) {
  766. var ed = this.editor;
  767. // Internal image object like a flash placeholder
  768. if (ed.dom.getAttrib(ed.selection.getNode(), 'class').indexOf('mceItem') != -1)
  769. return;
  770. ed.windowManager.open({
  771. url : tinymce.baseURL + '/themes/advanced/image.htm',
  772. width : 355 + parseInt(ed.getLang('advanced.image_delta_width', 0)),
  773. height : 275 + parseInt(ed.getLang('advanced.image_delta_height', 0)),
  774. inline : true
  775. }, {
  776. theme_url : this.url
  777. });
  778. },
  779. _mceLink : function(ui, val) {
  780. var ed = this.editor;
  781. ed.windowManager.open({
  782. url : tinymce.baseURL + '/themes/advanced/link.htm',
  783. width : 310 + parseInt(ed.getLang('advanced.link_delta_width', 0)),
  784. height : 200 + parseInt(ed.getLang('advanced.link_delta_height', 0)),
  785. inline : true
  786. }, {
  787. theme_url : this.url
  788. });
  789. },
  790. _mceNewDocument : function() {
  791. var ed = this.editor;
  792. ed.windowManager.confirm('advanced.newdocument', function(s) {
  793. if (s)
  794. ed.execCommand('mceSetContent', false, '');
  795. });
  796. },
  797. _mceForeColor : function() {
  798. var t = this;
  799. this._mceColorPicker(0, {
  800. color: t.fgColor,
  801. func : function(co) {
  802. t.fgColor = co;
  803. t.editor.execCommand('ForeColor', false, co);
  804. }
  805. });
  806. },
  807. _mceBackColor : function() {
  808. var t = this;
  809. this._mceColorPicker(0, {
  810. color: t.bgColor,
  811. func : function(co) {
  812. t.bgColor = co;
  813. t.editor.execCommand('HiliteColor', false, co);
  814. }
  815. });
  816. },
  817. _ufirst : function(s) {
  818. return s.substring(0, 1).toUpperCase() + s.substring(1);
  819. }
  820. });
  821. tinymce.ThemeManager.add('advanced', tinymce.themes.AdvancedTheme);
  822. }());