~kosova/+junk/tuxfamily-twiki

« back to all changes in this revision

Viewing changes to foswiki/pub/System/TinyMCEPlugin/tinymce/jscripts/tiny_mce/plugins/template/editor_plugin_src.js

  • Committer: James Michael DuPont
  • Date: 2009-07-18 19:58:49 UTC
  • Revision ID: jamesmikedupont@gmail.com-20090718195849-vgbmaht2ys791uo2
added foswiki

Show diffs side-by-side

added added

removed removed

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