Bug 5917 : Converted templates
[koha.git] / koha-tt / intranet-tmpl / prog / en / js / tinymce / jscripts / tiny_mce / plugins / template / editor_plugin_src.js
1 /**\r
2  * $Id: editor_plugin_src.js 162 2007-01-03 16:16:52Z spocke $\r
3  *\r
4  * @author Moxiecode\r
5  * @copyright Copyright © 2004-2007, Moxiecode Systems AB, All rights reserved.\r
6  */\r
7 \r
8 tinyMCE.importPluginLanguagePack('template');\r
9 \r
10 var TinyMCE_TemplatePlugin = {\r
11         getInfo : function() {\r
12                 return {\r
13                         longname : 'Template plugin',\r
14                         author : 'Moxiecode Systems AB',\r
15                         authorurl : 'http://www.moxiecode.com',\r
16                         infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/template',\r
17                         version : tinyMCE.majorVersion + "." + tinyMCE.minorVersion\r
18                 };\r
19         },\r
20 \r
21         initInstance : function(inst) {\r
22                 var cdate, mdate, content, x = 0, key, value, rvals, ds = inst.getData('template');\r
23 \r
24                 // ensure the required elements and sttributes are added\r
25                 //inst.cleanup.addRuleStr('*[' + TinyMCE_TemplatePlugin.TMPL_DATE_SRC_ATTR + '],div[title,tsrc]');\r
26 \r
27                 //setup template content functions\r
28                 // creation date and modified date classes\r
29                 cdate = tinyMCE.getParam("template_cdate_classes", '').split(/\s+/);\r
30                 mdate = tinyMCE.getParam("template_mdate_classes", '').split(/\s+/);\r
31 \r
32                 // classes that specify where selected content should go\r
33                 content = tinyMCE.getParam("template_selected_content_classes", '').split(/\s+/);\r
34 \r
35                 for (x = 0; x < cdate.length; x++)\r
36                         TinyMCE_TemplatePlugin.functions[cdate[x]] = TinyMCE_TemplatePlugin.functions['cdate']; \r
37 \r
38                 for (x = 0; x < mdate.length; x++)\r
39                         TinyMCE_TemplatePlugin.functions[mdate[x]] = TinyMCE_TemplatePlugin.functions['mdate'];\r
40 \r
41                 for (x = 0; x < content.length; x++)\r
42                         TinyMCE_TemplatePlugin.functions[content[x]] = TinyMCE_TemplatePlugin.functions['selectedContent'];\r
43 \r
44                 // special template functions for replacing template content\r
45                 rvals = tinyMCE.getParam("template_replace_values", false);\r
46                 for (key in rvals) {\r
47                         value = rvals[key];\r
48 \r
49                         if (typeof value == "function")\r
50                                 TinyMCE_TemplatePlugin.functions[key] = value;\r
51                         else\r
52                                 TinyMCE_TemplatePlugin.functions[key] = TinyMCE_TemplatePlugin.functions['generateReplacer'](value);\r
53                 }\r
54 \r
55                 // Setup replace_items\r
56                 rvals = tinyMCE.getParam("template_replace_values", false);\r
57                 ds.replace_items = {};\r
58 \r
59                 for (key in rvals)\r
60                         ds.replace_items[key] = rvals[key];\r
61 \r
62                 inst.addShortcut('ctrl', 't', 'lang_template_desc', 'mceTemplate');\r
63 \r
64                 // Setup data storage\r
65                 ds.currentAction = "insert";\r
66                 ds.currentTmplNode = null;\r
67         },\r
68 \r
69         getControlHTML : function(cn) {\r
70                 switch (cn) {\r
71                         case "template":\r
72                                 return tinyMCE.getButtonHTML(cn, 'lang_template_desc', '{$pluginurl}/images/template.gif', 'mceTemplate', true);\r
73                 }\r
74 \r
75                 return "";\r
76         },\r
77 \r
78         execCommand : function(editor_id, element, command, user_interface, value) {\r
79                 var nodeArray, current, newTmpl, x, inst = tinyMCE.getInstanceById(editor_id), ds = inst.getData('template'), telm;\r
80 \r
81                 switch (command) {\r
82                         case "mceTemplate":\r
83                                 if (user_interface) {\r
84                                         // called from toolbar button - show the popup\r
85                                         tinyMCE.openWindow({\r
86                                                 file : '../../plugins/template/template.htm', // Relative to theme\r
87                                                 width : tinyMCE.getParam('template_popup_width', 750),\r
88                                                 height : tinyMCE.getParam('template_popup_height', 600)\r
89                                         }, {editor_id : editor_id, resizable : "yes", scrollbars : "no", pluginObj : TinyMCE_TemplatePlugin});\r
90                                 } else {\r
91                                         // internal command do the template stuff\r
92 \r
93                                         // get the returned HTML string from the pop-up and appened it to a DIV element\r
94                                         telm = TinyMCE_TemplatePlugin._convertToNode(value.body);\r
95 \r
96                                         // Find template body\r
97                                         nodeArray = tinyMCE.selectElements(telm, 'div', function(n) {\r
98                                                 return tinyMCE.hasCSSClass(n, TinyMCE_TemplatePlugin.TMPL);\r
99                                         });\r
100 \r
101                                         telm = nodeArray.length > 0 ? nodeArray[0] : null;\r
102                                         nodeArray = [];\r
103 \r
104                                         if (ds.currentAction == "insert") {\r
105                                                 //insert new template after applying all the template content functions\r
106 \r
107                                                 // Is it a template or snippet\r
108                                                 if (telm) {\r
109                                                         tinyMCE.execCommand('mceBeginUndoLevel');\r
110                                                         ds.currentAction = "insert-new";\r
111                                                         TinyMCE_TemplatePlugin._insertTemplate(editor_id, telm, value.title, value.tsrc, true);\r
112                                                         ds.currentAction == "insert";\r
113                                                         tinyMCE.execCommand('mceEndUndoLevel');\r
114                                                         tinyMCE.execInstanceCommand(editor_id, 'mceCleanup', false);\r
115                                                 } else\r
116                                                         tinyMCE.execCommand('mceInsertContent', false, this._replaceValues(value.body));\r
117                                         } else {\r
118                                                 // First collect the selected template in the editor\r
119                                                 nodeArray = TinyMCE_TemplatePlugin._collectTemplateElements(ds.currentTmplNode);\r
120                                                 current = [];\r
121                                                 newTmpl = [];\r
122                                                 tinyMCE.getNodeTree(telm, newTmpl);\r
123 \r
124                                                 for (x=0; x<nodeArray.length; x++)\r
125                                                         tinyMCE.getNodeTree(nodeArray[x], current);\r
126 \r
127                                                 /** \r
128                                                  * inner function used in the loop below.\r
129                                                  * compares the supplied HTML element to the new template to:\r
130                                                  * - find a match with the new template and copy the element's content over\r
131                                                  * - find no match and indicate content will be lost\r
132                                                  */\r
133                                                 var _test = function(elm) {\r
134                                                         var replaced = true;\r
135 \r
136                                                         if (elm.className) {\r
137                                                                 var names = elm.className.split(/\s+/), c, n;\r
138 \r
139                                                                 for (c = 0; c<names.length; c++) {\r
140                                                                         if (names[c].match(/^mce/i))\r
141                                                                                 continue; // ignore all internal class names\r
142 \r
143                                                                         for (n=0; n<newTmpl.length; n++){\r
144                                                                                 replaced = false;\r
145 \r
146                                                                                 if (newTmpl[n].className && newTmpl[n].className.match(new RegExp(names[c], "gi"))) {\r
147                                                                                         newTmpl[n].innerHTML = elm.innerHTML;\r
148                                                                                         //if(tinyMCE.getAttrib(elm,TinyMCE_TemplatePlugin.TMPL_DATE_SRC_ATTR,"") != "") {\r
149                                                                                         //      tinyMCE.setAttrib(newTmpl[n], TinyMCE_TemplatePlugin.TMPL_DATE_SRC_ATTR, tinyMCE.getAttrib(elm,TinyMCE_TemplatePlugin.TMPL_DATE_SRC_ATTR)); \r
150                                                                                         //}\r
151                                                                                         replaced = true;\r
152                                                                                         break;\r
153                                                                                 }\r
154 \r
155                                                                         }\r
156                                                                 }\r
157                                                         }\r
158         \r
159                                                         return replaced;\r
160                                                 };\r
161 \r
162                                                 // comparison loop - first mis-match alerts user for confirmation.\r
163                                                 var cont = true;\r
164                                                 var asked = false;\r
165 \r
166                                                 for (x = 0; x < current.length; x++) {\r
167                                                         if(!_test(current[x])) {\r
168                                                                 cont = (asked || confirm("The new template has less elements than the currently selected content.\nIf you proceed you will loose content.\nAre you sure you want to proceed?", "Proceed?"));\r
169                                                                 asked = true;\r
170 \r
171                                                                 if (!cont)\r
172                                                                         break;\r
173                                                         }\r
174                                                 };\r
175 \r
176                                                 // apply replacement if allowed to\r
177                                                 if (cont) {\r
178                                                         tinyMCE.execCommand('mceBeginUndoLevel');\r
179                                                         TinyMCE_TemplatePlugin._replaceTemplateContent(current[0], editor_id, telm, value.title, value.tsrc);\r
180                                                         tinyMCE.execCommand('mceEndUndoLevel');\r
181                                                         tinyMCE.execInstanceCommand(editor_id, 'mceCleanup', false);\r
182                                                 }\r
183                                         }\r
184 \r
185                                         tinyMCE.triggerNodeChange(true);\r
186                                 }\r
187 \r
188                                 return true;\r
189                 }\r
190 \r
191                 return false;\r
192         },\r
193 \r
194         handleNodeChange : function(editor_id, node, undo_index, undo_levels, visual_aid, any_selection) {\r
195                 var inst = tinyMCE.getInstanceById(editor_id), ds = inst.getData('template');\r
196 \r
197                 if (tinyMCE.hasCSSClass(node, TinyMCE_TemplatePlugin.TMPL_ELEMENT) || tinyMCE.hasCSSClass(node.parentNode, TinyMCE_TemplatePlugin.TMPL_ELEMENT)) {\r
198                         tinyMCE.switchClass(editor_id + '_template', 'mceButtonSelected');\r
199                         ds.currentAction = "update";\r
200                         ds.currentTmplNode = node;\r
201 \r
202                         return true;\r
203                 }\r
204 \r
205                 ds.currentAction = "insert";\r
206                 ds.currentTmplNode = null;\r
207                 tinyMCE.switchClass(editor_id + '_template', 'mceButtonNormal');\r
208 \r
209                 return false;\r
210         },\r
211 \r
212         cleanup : function(type, content, inst) {\r
213                 var nodes = [];\r
214 \r
215                 switch (type) {\r
216                         case "get_from_editor":\r
217                                 // replace the opening wrapper div tag with a HTML comment\r
218                                 content = content.replace(\r
219                                         new RegExp('<div class="' + TinyMCE_TemplatePlugin.TMPL + '">', 'gi'),\r
220                                         '<!-- ' + TinyMCE_TemplatePlugin.TMPL_BEGINS + ' -->'\r
221                                 );\r
222 \r
223                                 // delete any empty template wrappers\r
224                                 content = content.replace(\r
225                                         new RegExp('<div class="' + TinyMCE_TemplatePlugin.TMPL + '">(\s|&nbsp;|&#160;)?(<!-- ' + TinyMCE_TemplatePlugin.TMPL_ENDS + ' -->|\s)?</div>', 'gi'),\r
226                                         ''\r
227                                 );\r
228 \r
229                                 // replace the closing wrapper tag\r
230                                 content = content.replace(\r
231                                         new RegExp('<!-- ' + TinyMCE_TemplatePlugin.TMPL_ENDS + ' --></div>', 'gi'),\r
232                                         '<!-- ' + TinyMCE_TemplatePlugin.TMPL_ENDS + ' -->'\r
233                                 );\r
234 \r
235                                 break;\r
236 \r
237                         case "insert_to_editor":\r
238                                 // replace HTML comment with DIV wrapper\r
239                                 content = content.replace(\r
240                                         new RegExp('<!-- ' + TinyMCE_TemplatePlugin.TMPL_BEGINS + ' -->', 'gi'),\r
241                                         '<div class="' + TinyMCE_TemplatePlugin.TMPL + '">'\r
242                                 );\r
243 \r
244                                 content = content.replace(\r
245                                         new RegExp('<!-- ' + TinyMCE_TemplatePlugin.TMPL_ENDS + ' -->', 'gi'),\r
246                                         '<!-- ' + TinyMCE_TemplatePlugin.TMPL_ENDS + ' --></div>'\r
247                                 );\r
248 \r
249                                 break;\r
250 \r
251                         case "get_from_editor_dom":\r
252                                 // apply template content replacement functions\r
253                                 nodes = tinyMCE.selectNodes(content, function(n) {\r
254                                                 return tinyMCE.hasCSSClass(n, TinyMCE_TemplatePlugin.TMPL_ELEMENT);\r
255                                         }\r
256                                 );\r
257 \r
258                                 TinyMCE_TemplatePlugin._applyFunctions(nodes, type);\r
259 \r
260                                 break;\r
261 \r
262                         case "insert_to_editor_dom":\r
263                                 // apply template content replacement functions\r
264                                 nodes = tinyMCE.selectNodes(content, function(n) {\r
265                                                 return tinyMCE.hasCSSClass(n, TinyMCE_TemplatePlugin.TMPL_ELEMENT);\r
266                                         }\r
267                                 );\r
268 \r
269                                 TinyMCE_TemplatePlugin._applyFunctions(nodes, type);\r
270 \r
271                                 break;\r
272                 }\r
273 \r
274                 return content;\r
275         },\r
276 \r
277         // Private plugin internal methods\r
278 \r
279         /**\r
280          * Creates a HTML DIV element and sets the innerHTML to equal the temlate innerHTML so that the template can be manipulated as DOM nodes.\r
281          *\r
282          * @param {string} Template innerHTML\r
283          * @return a HTML Element\r
284          * @type HTMLElement\r
285          */\r
286         _convertToNode : function(html) {\r
287                 var elm = document.createElement('div');\r
288 \r
289                 elm.innerHTML = html;\r
290 \r
291                 return elm;\r
292         },\r
293 \r
294         /**\r
295          * pass an array of template html elements and they will have the template class name added and any template functions applied\r
296          *\r
297          * @param {array} template HTML elements\r
298          * @return array of template HTML elements\r
299          * @type array\r
300          */\r
301         _prepareTemplateContent : function(elms) {\r
302                 var x, n, nodes = [];\r
303 \r
304                 if (!elms)\r
305                         return {};\r
306 \r
307                 if (!elms.length)\r
308                         elms = [elms];\r
309 \r
310                 for (x = 0; x<elms.length; x++)\r
311                         tinyMCE.getNodeTree(elms[x], nodes, 1);\r
312 \r
313                 for (n = 0; n<nodes.length; n++) {\r
314                         tinyMCE.addCSSClass(nodes[n], TinyMCE_TemplatePlugin.TMPL_ELEMENT);\r
315                         TinyMCE_TemplatePlugin._applyFunctions(nodes[n], TinyMCE_TemplatePlugin.TMPL_TEMPLATE_EVENT);\r
316                 }\r
317 \r
318                 return elms;\r
319         },\r
320 \r
321         _replaceValues : function(s) {\r
322                 var t = this, ds = tinyMCE.selectedInstance.getData('template');\r
323 \r
324                 return s.replace(/\{\$([^\}]+)\}/g, function(a, b) {\r
325                         var it = ds.replace_items[b];\r
326 \r
327                         if (it) {\r
328                                 // Only supports text for now\r
329                                 if (typeof(it) != 'function')\r
330                                         return it;\r
331                         }\r
332 \r
333                         return b;\r
334                 });\r
335         },\r
336 \r
337         /**\r
338          * Applies any special functions to the template elements\r
339          *\r
340          * @param {array} template HTML elements\r
341          * @return array of template HTML elements\r
342          * @type array\r
343          */\r
344         _applyFunctions : function(elms, editor_event) {\r
345                 var x, elm, names, c, f;\r
346 \r
347                 if (!elms)\r
348                         return {};\r
349 \r
350                 if (!elms.length)\r
351                         elms = [elms];\r
352 \r
353                 for(x = 0; x < elms.length; x++) {\r
354                         elm = elms[x];\r
355 \r
356                         if (elm.className){\r
357                                 names = elm.className.split(/\s+/);\r
358 \r
359                                 for (c = 0; c < names.length; c++){\r
360                                         if (names[c] == TinyMCE_TemplatePlugin.TMPL_ELEMENT)\r
361                                                 continue;\r
362 \r
363                                         f = (TinyMCE_TemplatePlugin.functions[names[c]] ? TinyMCE_TemplatePlugin.functions[names[c]] : TinyMCE_TemplatePlugin.functions['blank']);\r
364                                         f(elm, editor_event);\r
365                                 }\r
366                         }\r
367                 }\r
368 \r
369                 return elms;\r
370         },\r
371 \r
372         /**\r
373          * Given one node reference this function will collect all the nodes of the template to which it belongs.\r
374          * It does this by finding the parent template wrapper DIV and returning all child nodes.\r
375          *\r
376          * @param {HTMLElement} a HTMLElement which is part of a template\r
377          * @return array of template HTML elements\r
378          * @type array\r
379          */\r
380         _collectTemplateElements : function(node) {\r
381                 var nodeArray = [], p;\r
382 \r
383                 p = tinyMCE.getParentElement(node, 'DIV', function(n) {\r
384                         return tinyMCE.hasCSSClass(n, TinyMCE_TemplatePlugin.TMPL);\r
385                 });\r
386 \r
387                 if (p)\r
388                         tinyMCE.getNodeTree(p, nodeArray);\r
389 \r
390                 return nodeArray;\r
391         },\r
392 \r
393         /**\r
394          * Simply calls TinyMCE_TemplatePlugin._deleteTemplateContent and then TinyMCE_TemplatePlugin._insertTemplate\r
395          *\r
396          * @param {HTMLElement} currently selected template node in editor\r
397          * @param {string} id of editor instance\r
398          * @param {HTMLElement} template contents as a HTMLElement (the parent DIV wrapper)\r
399          * @param {string} title of template (unused as yet)\r
400          * @param {string} source URI of the template file (unused as yet)\r
401          * @return array of template HTML elements\r
402          * @type array\r
403          */\r
404         _replaceTemplateContent : function(currentNode, editor_id, newTemplate, title, tsrc) {\r
405                 TinyMCE_TemplatePlugin._deleteTemplateContent(currentNode);\r
406                 TinyMCE_TemplatePlugin._insertTemplate(editor_id, newTemplate, title, tsrc, false);\r
407         },\r
408 \r
409         /**\r
410          * Deletes a template from the editor content\r
411          * Finds the parent DIV wrapper and deletes it and all children\r
412          * @param {HTMLElement} currently selected template node in editor\r
413          */\r
414         _deleteTemplateContent : function(node) {\r
415                 var p = tinyMCE.getParentElement(node, 'DIV', function(n) {\r
416                         return tinyMCE.hasCSSClass(n, TinyMCE_TemplatePlugin.TMPL);\r
417                 });\r
418 \r
419                 if (p)\r
420                         p.parentNode.removeChild(p, true);\r
421         },\r
422 \r
423         /**\r
424          *  Inserts a template into the specified editor\r
425          *\r
426          * @param {string} id of editor instance\r
427          * @param {HTMLElement} template contents as a HTMLElement (the parent DIV wrapper)\r
428          * @param {string} title of template (unused as yet)\r
429          * @param {string} source URI of the template file (unused as yet)\r
430          */\r
431         _insertTemplate : function(editor_id, elm, title, tsrc, incComments) {\r
432                 var html;\r
433 \r
434                 TinyMCE_TemplatePlugin._prepareTemplateContent(elm);\r
435 \r
436                 html = '<div class="' + TinyMCE_TemplatePlugin.TMPL + '">';\r
437                 html += elm.innerHTML;\r
438                 html += '<!-- ' + TinyMCE_TemplatePlugin.TMPL_ENDS + ' --></div>';\r
439 \r
440                 tinyMCE.execInstanceCommand(editor_id, 'mceInsertContent', false, html);\r
441         },\r
442 \r
443         /**\r
444          * template functions - functions for modifying template content\r
445          */\r
446         functions : { \r
447                 blank : function(elm, editor_event) {},\r
448 \r
449                 cdate : function(elm, editor_event) {\r
450                         var d, dsrc;\r
451 \r
452                         if (editor_event != TinyMCE_TemplatePlugin.TMPL_TEMPLATE_EVENT)\r
453                                 return;\r
454 \r
455                         d = new Date();\r
456                         // find out if the creation date was previously stored\r
457                         dsrc = elm.innerHTML.match(new RegExp("<!-- " + TinyMCE_TemplatePlugin.TMPL_DATE_SRC_ATTR + ":(.*)  -->", "gi"));\r
458 \r
459                         if (dsrc)\r
460                                 d = new Date(RegExp.$1);\r
461 \r
462                         elm.innerHTML = TinyMCE_TemplatePlugin._getDateTime(d, tinyMCE.getParam("template_cdate_format", tinyMCE.getLang("lang_template_def_date_format")));\r
463                         //now we have to store the date value in a format easily read again, in case a future template change changes the date format...\r
464                         elm.innerHTML += "<!-- " + TinyMCE_TemplatePlugin.TMPL_DATE_SRC_ATTR + ":" + d.toUTCString() + "  -->";\r
465                 },\r
466 \r
467                 mdate : function(elm, editor_event) {\r
468                         var d = new Date();\r
469                         elm.innerHTML = TinyMCE_TemplatePlugin._getDateTime(d, tinyMCE.getParam("template_mdate_format", tinyMCE.getLang("lang_template_def_date_format")));\r
470                 },\r
471 \r
472                 /**\r
473                  * This will insert the currently selected editor content into the template element.\r
474                  * It only does this if the template inserted is a new one and if the element does not have the special class.\r
475                  * The special class name prevents this from happening more than once.\r
476                  */\r
477                 selectedContent : function(elm, editor_event) {\r
478                         var ds = tinyMCE.selectedInstance.getData('template');\r
479         \r
480                         if (editor_event != TinyMCE_TemplatePlugin.TMPL_TEMPLATE_EVENT)\r
481                                 return;\r
482 \r
483                         if (ds.currentAction == "insert-new" && !tinyMCE.hasCSSClass(elm, TinyMCE_TemplatePlugin.TMPL_SEL_HTML_DONE)) {\r
484                                 elm.innerHTML = tinyMCE.selectedInstance.selection.getSelectedHTML();\r
485                                 tinyMCE.addCSSClass(elm, TinyMCE_TemplatePlugin.TMPL_SEL_HTML_DONE);\r
486                         }\r
487                 },\r
488 \r
489                 /**\r
490                  * When the plugin is initialised this generates the functions that insert configured strings into template elements.\r
491                  */\r
492                 generateReplacer : function(s) {\r
493                         return function(elm, editor_event) {elm.innerHTML = "" + s;};\r
494                 }\r
495         },\r
496 \r
497         /**\r
498          * formats a date according to the format string - straight from the 'insert date/time' plugin\r
499          *\r
500          * @param {Date} date object\r
501          * @param {string} format string\r
502          * @return formatted date\r
503          * @type string\r
504          */\r
505         _getDateTime : function(d,fmt) {\r
506                         if (!fmt)\r
507                                 return "";\r
508 \r
509                         function addZeros(value, len) {\r
510                                 var i;\r
511 \r
512                                 value = "" + value;\r
513 \r
514                                 if (value.length < len) {\r
515                                         for (i=0; i<(len-value.length); i++)\r
516                                                 value = "0" + value;\r
517                                 }\r
518 \r
519                                 return value;\r
520                         }\r
521 \r
522                         fmt = fmt.replace("%D", "%m/%d/%y");\r
523                         fmt = fmt.replace("%r", "%I:%M:%S %p");\r
524                         fmt = fmt.replace("%Y", "" + d.getFullYear());\r
525                         fmt = fmt.replace("%y", "" + d.getYear());\r
526                         fmt = fmt.replace("%m", addZeros(d.getMonth()+1, 2));\r
527                         fmt = fmt.replace("%d", addZeros(d.getDate(), 2));\r
528                         fmt = fmt.replace("%H", "" + addZeros(d.getHours(), 2));\r
529                         fmt = fmt.replace("%M", "" + addZeros(d.getMinutes(), 2));\r
530                         fmt = fmt.replace("%S", "" + addZeros(d.getSeconds(), 2));\r
531                         fmt = fmt.replace("%I", "" + ((d.getHours() + 11) % 12 + 1));\r
532                         fmt = fmt.replace("%p", "" + (d.getHours() < 12 ? "AM" : "PM"));\r
533                         fmt = fmt.replace("%B", "" + tinyMCE.getLang("lang_template_months_long")[d.getMonth()]);\r
534                         fmt = fmt.replace("%b", "" + tinyMCE.getLang("lang_template_months_short")[d.getMonth()]);\r
535                         fmt = fmt.replace("%A", "" + tinyMCE.getLang("lang_template_day_long")[d.getDay()]);\r
536                         fmt = fmt.replace("%a", "" + tinyMCE.getLang("lang_template_day_short")[d.getDay()]);\r
537                         fmt = fmt.replace("%%", "%");\r
538 \r
539                         return fmt;\r
540         },\r
541 \r
542         TMPL_ELEMENT : 'mceTmplElm',\r
543         TMPL : 'mceTmpl',\r
544         TMPL_BEGINS : 'mceTmplBegins',\r
545         TMPL_SEL_HTML_DONE : 'mceSelHTMLDone',\r
546         TMPL_ENDS : 'mceTmplEnds',\r
547         TMPL_DATE_SRC_ATTR : 'mcetmpldtesrc',\r
548         TMPL_TEMPLATE_EVENT : 'prepare_template'\r
549 };\r
550 \r
551 tinyMCE.addPlugin("template", TinyMCE_TemplatePlugin);\r