ここの情報は古いです。ご理解頂いた上でお取り扱いください。

source: OpenPNE/trunk/public_html/js/tiny_mce/plugins/openpne/editor_plugin.js.src @ 7407

Last change on this file since 7407 was 7407, checked in by ebihara, 12 years ago

#2530:小窓ボタンのリンク先URLを変更できるようにした

File size: 19.9 KB
Line 
1/**
2 * TinyMCE Plugin for OpenPNE
3 *
4 * @author Kousuke Ebihara
5 */
6
7(function() {
8
9    tinymce.create('tinymce.ui.OpenPNEColorButton:tinymce.ui.ColorSplitButton', {
10        renderHTML : function() {
11            var s = this.settings, h = '<a id="' + this.id + '" href="javascript:;" class="mceButton mceButtonEnabled ' + s['class']
12                + '" onmousedown="return false;" onclick="return false;" title="' + tinymce.DOM.encode(s.title) + '">';
13
14            if (s.image) {
15                h += '<img class="mceIcon" src="' + s.image + '" /></a>';
16            } else {
17                h += '<span class="mceIcon ' + s['class'] + '"></span></a>';
18            }
19
20            return h;
21        },
22
23        postRender : function() {
24            tinymce.dom.Event.add(this.id, 'click', this.showMenu, this);
25        },
26
27        setColor : function(c) {
28            this.value = c;
29            this.hideMenu();
30            this.settings.onselect(c);
31        }
32    });
33
34    tinymce.create('tinymce.ui.OpenPNEEmojiButton:tinymce.ui.ColorSplitButton', {
35        OpenPNEEmojiButton : function(id, s) {
36            var t = this;
37
38            t.parent(id, s);
39
40            t.settings = s;
41        },
42
43        renderMenu : function() {
44            var t = this, m, i = 0, s = t.settings, n, tb, tr, w;
45            var DOM = tinymce.DOM, Event = tinymce.dom.Event, is = tinymce.is, each = tinymce.each;
46            w = DOM.add(s.menu_container, 'div', {id : t.id + '_menu', dir : 'ltr', 'class' : s['menu_class'] + ' ' + s['class'],
47                style : 'position:absolute;left:0;top:-1000px;'});
48            m = DOM.add(w, 'div', {'class' : s['class'] + ' mceSplitButtonMenu'});
49            DOM.add(m, 'span', {'class' : 'mceMenuLine'});
50
51            n = DOM.add(m, 'table', {'class' : 'mceEmojiSplitMenu'});
52            tb = DOM.add(n, 'tbody');
53
54            for (var num in s.emoji) {
55                var emoji = s.emoji[num];
56                for (var i = emoji.start; i <= emoji.end; i++) {
57                    if (i == emoji.start || i % 25 == 0) {
58                        tr = DOM.add(tb, 'tr');
59                    }
60                    n = DOM.add(tr, 'td');
61
62                    n = DOM.add(n, 'img', {
63                        src : "./skin/default/img/emoji/" + s.carrier +"/" + s.carrier + i + ".gif",
64                        alt : "[" + s.carrier + ":" + i + "]"
65                    });
66
67                    Event.add(n, 'mousedown', function(e) {
68                        if (Prototype.Browser.IE) {
69                            tinyMCE.execCommand("mceInsertContent", false, e.srcElement.getAttribute("alt"));
70                        } else {
71                            tinyMCE.execCommand("mceInsertContent", false, e.element().getAttribute("alt"));
72                        }
73                    });
74                }
75            }
76
77            DOM.addClass(m, 'mceColorSplitMenu');
78
79            return w;
80        },
81
82        renderHTML : function() {
83            var s = this.settings, h = '<a id="' + this.id + '" href="javascript:;" class="mceButton mceButtonEnabled ' + s['class']
84                + '" onmousedown="return false;" onclick="return false;" title="' + tinymce.DOM.encode(s.title) + '">';
85
86            if (s.image) {
87                h += '<img class="mceIcon" src="' + s.image + '" /></a>';
88            } else {
89                h += '<span class="mceIcon ' + s['class'] + '"></span></a>';
90            }
91
92            return h;
93        },
94
95        postRender : function() {
96            tinymce.dom.Event.add(this.id, 'click', this.showMenu, this);
97        }
98    });
99
100    tinymce.create('tinymce.ui.OpenPNECmdButton:tinymce.ui.Button', {
101        renderHTML : function() {
102            var s = this.settings;
103            var h = '<a id="' + this.id + '" href="javascript:;" class="mceButton mceButtonEnabled ' + s['class'] + '" style="width:40px; margin-left: 25px;" onmousedown="return false;" onclick="return false;" title="' + tinymce.DOM.encode(s.title) + '"><img class="mceIcon" style="width:40px;" src="' + s.image + '" /></a>';
104
105            return h;
106        }
107    });
108
109    tinymce.PluginManager.requireLangPack('openpne');
110
111    var config = pne_mce_editor_get_config();
112
113    tinymce.create('tinymce.plugins.OpenPNEPlugin', {
114        init : function(ed, url) {
115            var t = this;
116
117            // change the editor setting
118            ed.settings.content_css = url + "/css/editor.css";
119
120            // command
121            ed.addCommand('mceOpenPNE_op_b', function() {
122                tinyMCE.execCommand("Bold");
123            });
124            ed.addCommand('mceOpenPNE_op_u', function() {
125                tinyMCE.execCommand("Underline");
126            });
127            ed.addCommand('mceOpenPNE_op_s', function() {
128                tinyMCE.execCommand("Strikethrough");
129            });
130            ed.addCommand('mceOpenPNE_op_i', function() {
131                tinyMCE.execCommand("Italic");
132            });
133            ed.addCommand('mceOpenPNE_op_large', function() {
134                tinyMCE.execCommand("Fontsize", false, 5);
135            });
136            ed.addCommand('mceOpenPNE_op_small', function() {
137                tinyMCE.execCommand("Fontsize", false, 1);
138            });
139            ed.addCommand('mceOpenPNE_op_image', function() {
140                window.open(config.op_image.contentURL, '', 'width=600,height=550,toolbar=no,scrollbars=yes,left=10,top=10');
141            });
142            ed.addCommand('mceOpenPNE_op_cmd', function() {
143                window.open(config.op_cmd.contentURL);
144            });
145
146            // button
147            for (var key in config) {
148                var value = config[key];
149                if (value.isEnabled && key != "op_color") {
150                    ed.addButton(key, {title : '{#openpne.' + key + '}', image: value.imageURL, cmd : 'mceOpenPNE_' + key});
151                }
152            }
153
154            // event
155            ed.onBeforeSetContent.add(function(ed, o) {  // To preview mode
156                o.content = t._textToPreview(o.content);
157            });
158            ed.onPostProcess.add(function(ed, o) {  // To text mode
159                if (o.save) {
160                    if (ed.isHidden()) {
161                        o.content = ed.getElement().value.replace(/\n\n/g, "\n \n");
162                    } else {
163                        o.content = t._previewToText(o.content, ed);
164                    }
165                }
166            });
167            ed.onNodeChange.add(function(ed, cm, n) {
168                cm.setActive('mce_editor_textarea_op_b', false);
169                cm.setActive('mce_editor_textarea_op_u', false);
170                cm.setActive('mce_editor_textarea_op_s', false);
171                cm.setActive('mce_editor_textarea_op_i', false);
172                cm.setActive('mce_editor_textarea_op_large', false);
173                cm.setActive('mce_editor_textarea_op_small', false);
174
175                var elm = n;
176                while (elm.parentNode) {
177                    var tagname = t._getTagName(elm);
178                    if ((tagname == "large" || tagname == "small") && (cm.get('mce_editor_textarea_op_large').isActive() || cm.get('mce_editor_textarea_op_small').isActive())) {
179                        elm = elm.parentNode;
180                        continue;
181                    }
182                    cm.setActive('mce_editor_textarea_op_' + tagname,  true);
183                    elm = elm.parentNode;
184                }
185            });
186        },
187
188        createControl: function(n, cm) {
189            var c = null;
190            if (n == "op_color" && config["op_color"].isEnabled) {
191                c = this._createOpenPNEColorButton("op_color", { title : "{#openpne.op_color}", image: config["op_color"].imageURL, cmd : "ForeColor"}, cm);
192            }
193
194            if (n == "op_emoji_docomo" || n == "op_emoji_au" && config["op_emoji_au"].isEnabled || n == "op_emoji_softbank" && config["op_emoji_softbank"].isEnabled) {
195                var emoji_config = {
196                    op_emoji_docomo : {
197                        carrier : "i",
198                        emoji : [ {start : 1, end : 252} ],
199                        title : "{#openpne." + n + "}",
200                        image: config[n].imageURL
201                    },
202                    op_emoji_au : {
203                        carrier : "e",
204                        emoji : [ {start : 1, end : 518}, {start : 700, end : 822} ],
205                        title : "{#openpne." + n + "}",
206                        image: config[n].imageURL
207                    },
208                    op_emoji_softbank : {
209                        carrier : "s",
210                        emoji : [ {start : 1, end : 485} ],
211                        title : "{#openpne." + n + "}",
212                        image: config[n].imageURL
213                    }
214                }
215                c = this._createOpenPNEEmojiButton(n, emoji_config[n], cm);
216            }
217
218            if (n == "op_cmd" && config["op_cmd"].isEnabled) {
219                c = this._createOpenPNECmdButton(n, {title: "{#openpne.op_cmd}", image: config["op_cmd"].imageURL, cmd: "mceOpenPNE_op_cmd"}, cm);
220            }
221
222            return c;
223        },
224
225        getInfo : function() {
226            return {
227                longname : 'OpenPNE plugin',
228                author : 'Kousuke Ebihara',
229                version : "1.0"
230            }
231        },
232
233        _getTagName : function(elm) {
234            var tagname = elm.nodeName.toLowerCase();
235            if (Prototype.Browser.WebKit && tagname == "span") {
236                if (elm.style.fontWeight == 'bold') { return 'b'; }
237                if (elm.style.textDecoration == 'underline') { return 'u'; }
238                if (elm.style.textDecoration == 'line-through') { return 's'; }
239                if (elm.style.fontStyle == 'italic') { return 'i'; }
240                if (elm.style.fontSize == 'x-large') { return 'large'; }
241                if (elm.style.fontSize == 'x-small') { return 'small'; }
242            } else if (tagname != "span") {
243                var convertList = {strike: "s", strong: "b", em: "i"};
244                if (convertList[tagname]) {
245                    return convertList[tagname];
246                }
247
248                var size = elm.getAttribute("size");
249                if (tagname == "font" && size == "5") {
250                    return "large";
251                }
252                if (tagname == "font" && size == "1") {
253                    return "small";
254                }
255            }
256
257            return tagname;
258        },
259
260        _createOpenPNEColorButton : function(id, s, cm) {
261            var t = cm, ed = t.editor, cmd, c;
262
263            if (t.get(id)) {
264                return null;
265            }
266
267            s.title = ed.translate(s.title);
268            s.scope = s.scope || ed;
269
270            if (!s.onclick) {
271                s.onclick = function(v) { ed.execCommand(s.cmd, s.ui || false, v || s.value); };
272            }
273
274            if (!s.onselect) {
275                s.onselect = function(v) { ed.execCommand(s.cmd, s.ui || false, v || s.value); };
276            }
277
278            id = t.prefix + id;
279
280            s = tinymce.extend({ title : s.title, 'class' : 'mce_' + id, 'menu_class' : ed.getParam('skin') + 'Skin', scope : s.scope, more_colors_title : ed.getLang('more_colors') }, s);
281
282            c = new tinymce.ui.OpenPNEColorButton(id, s);
283            ed.onMouseDown.add(c.hideMenu, c);
284
285            ed.onRemove.add(function() {
286                c.destroy();
287            });
288
289            return t.add(c);
290        },
291
292        _createOpenPNEEmojiButton : function(id, s, cm) {
293            var t = cm, ed = t.editor, cmd, c;
294
295            if (t.get(id)) {
296                return null;
297            }
298
299            s.title = ed.translate(s.title);
300            s.scope = s.scope || ed;
301
302            if (!s.onclick) {
303                s.onclick = function(v) { ed.execCommand(s.cmd, s.ui || false, v || s.value); };
304            }
305
306            if (!s.onselect) {
307                s.onselect = function(v) { ed.execCommand(s.cmd, s.ui || false, v || s.value); };
308            }
309
310            id = t.prefix + id;
311
312            s = tinymce.extend({ title : s.title, 'class' : 'mce_' + id, 'menu_class' : ed.getParam('skin') + 'Skin', scope : s.scope}, s);
313
314            c = new tinymce.ui.OpenPNEEmojiButton(id, s);
315            ed.onMouseDown.add(c.hideMenu, c);
316
317            ed.onRemove.add(function() {
318                c.destroy();
319            });
320
321            return t.add(c);
322        },
323
324        _createOpenPNECmdButton : function(id, s, cm) {
325            var t = cm, ed = t.editor, cmd, c;
326
327            if (t.get(id)) {
328                return null;
329            }
330
331            s.title = ed.translate(s.title);
332            s.scope = s.scope || ed;
333
334            if (!s.onclick) {
335                s.onclick = function(v) { ed.execCommand(s.cmd, s.ui || false, v || s.value); };
336            }
337
338            if (!s.onselect) {
339                s.onselect = function(v) { ed.execCommand(s.cmd, s.ui || false, v || s.value); };
340            }
341
342            id = t.prefix + id;
343
344            s = tinymce.extend({ title : s.title, 'class' : 'mce_' + id, 'menu_class' : ed.getParam('skin') + 'Skin', scope : s.scope}, s);
345
346            c = new tinymce.ui.OpenPNECmdButton(id, s);
347
348            ed.onPostRender.add(function() {
349                var parentContainer = document.getElementById(c.id).parentNode;
350                parentContainer.style.width = "70px";
351            });
352
353            ed.onRemove.add(function() {
354                c.destroy();
355            });
356
357            return t.add(c);
358        },
359
360        _previewToText : function(s, editor) {
361            var editorDoc = editor.getBody();
362
363            function rep(re, str) {
364                s = s.replace(re, str);
365            };
366
367            if (!tinymce.isWebKit) {  // not safari
368                s = tinymce.trim(s);
369                rep('/<(\/?)strong>/gi', '<\1b>');
370                rep('/<(\/?)strike>/gi', '<\1s>');
371                rep('/<(\/?)em>/gi', '<\1i>');
372                editor.dom.setHTML(editor.getBody(), s);
373            }
374
375            function convertHtmlTagToDecoTag(doc, tagname)
376            {
377                var tagList = doc.getElementsByTagName(tagname);
378                var org_tagname = tagname;
379                var args = {};
380
381                if (Prototype.Browser.IE && org_tagname != "font") {
382                    return;
383                }
384
385                while (tagList.length) {
386                    targetObj = tagList[0];
387
388                    if (org_tagname == "font") {
389                        var size = targetObj.getAttribute("size");
390                        var color = targetObj.getAttribute("color");
391
392                        if (size && color) {
393                            if (tinymce.isIE) {
394                                targetObj.removeAttribute("color");
395                                targetObj.innerHTML = '<font color="' + color + '">' + targetObj.innerHTML + "</font>";
396                            } else {
397                                var fontSize = document.createElement("font");
398                                fontSize.setAttribute("size", size);
399                                fontSize.removeAttribute("color");
400
401                                var clone = targetObj.cloneNode(true);
402                                clone.removeAttribute("size");
403
404                                fontSize.appendChild(clone);
405                                targetObj.parentNode.replaceChild(fontSize, targetObj);
406                            }
407
408                            // initialize
409                            tagList = doc.getElementsByTagName(org_tagname);
410                            args = {};
411
412                            continue;
413                        }
414
415                        if (size == '5') {
416                            tagname = 'op:large';
417                        } else if (size == '1') {
418                            tagname = 'op:small';
419                        }
420
421                        if (color) {
422                            tagname = 'op:color';
423                            args = {
424                                code: color
425                            };
426                        }
427                    } else if (org_tagname == 'span') {  // for safari
428                        if (targetObj.style.fontWeight == 'bold') {
429                            tagname = 'op:b';
430                        } else if (targetObj.style.textDecoration == 'underline') {
431                            tagname = 'op:u';
432                        } else if (targetObj.style.textDecoration == 'line-through') {
433                            tagname = 'op:s';
434                        } else if (targetObj.style.fontStyle == 'italic') {
435                            tagname = 'op:i';
436                        } else if (targetObj.style.color) {
437                            var color = tinyMCE.activeEditor.dom.toHex(targetObj.style.color);
438                            tagname = 'op:color';
439                            args = {
440                                code: color
441                            };
442                        } else if (targetObj.style.fontSize == 'x-large') {
443                            tagname = 'op:large';
444                        } else if (targetObj.style.fontSize == 'x-small') {
445                            tagname = 'op:small';
446                        } else {
447                            editor.dom.remove(targetObj, true);
448                            continue;
449                        }
450                    } else {
451                        tagname = 'op:' + org_tagname;
452                    }
453
454                    if (tinymce.isIE) {
455                        tagname = tagname.replace("op:", "op");
456                    }
457
458                    var newObj = editor.dom.create(tagname);
459                    editor.dom.setAttribs(newObj, args);
460
461                    if (tinymce.isIE) {
462                        newObj.innerHTML = targetObj.innerHTML;
463                        targetObj.parentNode.replaceChild(newObj, targetObj);
464                    } else {
465                        editor.dom.replace(newObj, targetObj, true);
466                    }
467                    tagList = doc.getElementsByTagName(org_tagname);
468                }
469                s = editorDoc.innerHTML;
470            }
471
472            var convertList = new Array('span', 'font', 'b', 'u', 's', 'i');
473            for (var i = 0; i < convertList.length; i++) {
474                convertHtmlTagToDecoTag(editor.getBody(), convertList[i]);
475            }
476
477            rep(/<\/?div>/gi,"");  // for Safari
478
479            if (Prototype.Browser.IE) {
480                rep(/<(\/?)(b|u|s|i)>/gi, '<$1op:$2>');
481                rep(/<(\/?)op(large|small|color)/gi, '<$1op:$2');
482            }
483
484            rep(/<br\s?\/?[^>]*>/gi,"\n\n");
485            rep(/&nbsp;/gi," ");
486            rep(/&quot;/gi,"\"");
487            rep(/&lt;/gi,"<");
488            rep(/&gt;/gi,">");
489            rep(/&amp;/gi,"&");
490
491            return s;
492        },
493
494        _textToPreview : function(s) {
495            s = tinymce.trim(s);
496            var rule = /&lt;op:(b|u|s|i|large|small|color)( code="(#[0-9a-f]{3,6})"|)&gt;(.*?)&lt;\/op:\1&gt;/i;
497
498            function rep(re, str) {
499                s = s.replace(re, str);
500            };
501
502            function convertDecoTagToHtmlTag(matches)
503            {
504                var tagname = matches[1];
505                var color = matches[3];
506                var value = matches[4].gsub(rule, convertDecoTagToHtmlTag);
507                var opt = '';
508
509                if (tagname == 'color' && color) {
510                    tagname = 'font';
511                    opt = ' color="' + color + '"';
512                }
513
514                if (tagname == 'large') {
515                    tagname = 'font';
516                    opt = ' size="5"';
517                }
518           
519                if (tagname == 'small') {
520                    tagname = 'font';
521                    opt = ' size="1"';
522                }
523
524                var converted = "<" + tagname + opt + ">" + value + "</" + tagname + ">";
525                return converted;
526            };
527
528            rep(/</gi,"&lt;");
529            rep(/>/gi,"&gt;");
530            rep(/\n/gi,"<br />");
531            s = s.gsub(rule, convertDecoTagToHtmlTag);
532
533            return s;
534        }
535    });
536
537    // Register plugin
538    tinymce.PluginManager.add('openpne', tinymce.plugins.OpenPNEPlugin);
539})();
Note: See TracBrowser for help on using the repository browser.