source: trunk/expressoMail1_2/js/rich_text_editor.js @ 5417

Revision 5417, 14.8 KB checked in by gustavo, 12 years ago (diff)

Ticket #2462 - Melhorias na tela de composição de mensagens do ExpressoMail?

  • Property svn:eol-style set to native
  • Property svn:executable set to *
Line 
1function cRichTextEditor(){
2    this.emwindow   = new Array;
3    this.editor = "body_1";
4    this.table = "";
5    this.id = "1";
6    this.saveFlag = 0;
7    this.signatures = false;
8    this.replyController = false;
9    this.newImageId = false;
10    this.plain = new Array;
11    this.editorReady = true;
12}
13
14// This code was written by Tyler Akins and has been placed in the
15// public domain.  It would be nice if you left this header intact.
16// Base64 code from Tyler Akins -- http://rumkin.com
17
18var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
19
20var ua = navigator.userAgent.toLowerCase();
21if (ua.indexOf(" chrome/") >= 0 || ua.indexOf(" firefox/") >= 0 || ua.indexOf(' gecko/') >= 0) {
22    var StringMaker = function () {
23        this.str = "";
24        this.length = 0;
25        this.append = function (s) {
26            this.str += s;
27            this.length += s.length;
28        }
29        this.prepend = function (s) {
30            this.str = s + this.str;
31            this.length += s.length;
32        }
33        this.toString = function () {
34            return this.str;
35        }
36    }
37} else {
38    var StringMaker = function () {
39        this.parts = [];
40        this.length = 0;
41        this.append = function (s) {
42            this.parts.push(s);
43            this.length += s.length;
44        }
45        this.prepend = function (s) {
46            this.parts.unshift(s);
47            this.length += s.length;
48        }
49        this.toString = function () {
50            return this.parts.join('');
51        }
52    }
53}
54
55cRichTextEditor.prototype.fromJSON = function( value )
56{
57    return (new Function( "return " + this.decode64( value )))();
58}
59
60cRichTextEditor.prototype.decode64 = function(input) {
61        if( typeof input === "undefined" ) return '';
62
63        var output = new StringMaker();
64        var chr1, chr2, chr3;
65        var enc1, enc2, enc3, enc4;
66        var i = 0;
67
68        // remove all characters that are not A-Z, a-z, 0-9, +, /, or =
69        input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
70
71        while (i < input.length) {
72                enc1 = keyStr.indexOf(input.charAt(i++));
73                enc2 = keyStr.indexOf(input.charAt(i++));
74                enc3 = keyStr.indexOf(input.charAt(i++));
75                enc4 = keyStr.indexOf(input.charAt(i++));
76
77                chr1 = (enc1 << 2) | (enc2 >> 4);
78                chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
79                chr3 = ((enc3 & 3) << 6) | enc4;
80
81                output.append(String.fromCharCode(chr1));
82
83                if (enc3 != 64) {
84                        output.append(String.fromCharCode(chr2));
85                }
86                if (enc4 != 64) {
87                        output.append(String.fromCharCode(chr3));
88                }
89        }
90
91        return output.toString();
92}
93
94
95cRichTextEditor.prototype.loadEditor = function(ID) {
96       
97        var parentDiv = document.getElementById("body_position_" + ID);
98        var pObj = "body_" + ID;
99        var textArea = document.createElement("TEXTAREA");
100        textArea.id = pObj;
101        textArea.style.width = '100%';
102        parentDiv.appendChild(textArea);
103        RichTextEditor.plain[ID] = false;
104       
105        if(preferences.plain_text_editor == 1)
106                {
107                        RichTextEditor.plain[ID] = true; 
108                        RichTextEditor.editorReady = true;
109                }
110        else
111                        RichTextEditor.active(pObj);
112}
113
114cRichTextEditor.prototype.getSignaturesOptions = function() {
115       
116        if(RichTextEditor.signatures !== false)
117            return RichTextEditor.signatures;
118               
119        var signatures = this.fromJSON( preferences.signatures );
120        var signature_types = this.fromJSON( preferences.signature_types );
121
122        for( key in signatures )
123            if( !signature_types[key] )
124                signatures[key] = signatures[key].replace( /\n/g, "<br>" );
125                 
126        RichTextEditor.signatures = signatures;
127        return signatures;
128
129}
130
131cRichTextEditor.prototype.getSignatureDefault = function() {
132         
133        if(RichTextEditor.signatures === false)
134            RichTextEditor.signatures = RichTextEditor.getSignaturesOptions();
135         
136        if(!RichTextEditor.signatures || 
137           !RichTextEditor.signatures[preferences.signature_default || ""])
138        {
139          preferences.use_signature = "0"; //Desabilita o uso da assinatura
140          return '';
141        }
142       
143        return unescape(RichTextEditor.signatures[preferences.signature_default]);
144
145}
146
147cRichTextEditor.prototype.createImage = function(){
148        if (preferences.auto_save_draft == 1)
149        {
150                        autosave_time = 200000;
151                        clearTimeout(openTab.autosave_timer[currentTab]);
152        }
153               
154        var form = document.getElementById("attachment_window");
155       
156        if (form == null){
157                form = document.createElement("DIV");
158                form.id  = "attachment_window";
159                form.style.visibility = "hidden";
160                form.style.position = "absolute";
161                form.style.background = "#eeeeee";
162                form.style.left = "0px";
163                form.style.top  = "0px";
164                form.style.width = "0px";
165                form.style.height = "0px";
166                document.body.appendChild(form);
167        }
168                var form_upload = Element('form_upload');
169                if (form_upload == null)
170                        form_upload = document.createElement("DIV");
171                form_upload.id = "form_upload";
172                form_upload.style.position = "absolute";
173                form_upload.style.top = "5px";
174                form_upload.style.left = "5px";
175                form_upload.name = get_lang("Upload File");
176                form_upload.style.width = "450px";
177                form_upload.style.height = "75px";
178                form_upload.innerHTML = get_lang('Select the desired image file')+':<br>'+
179                '<input name="image_at" maxlength="255" size="40" id="inputFile_img" type="file"><br>' +
180                '<input title="' + get_lang('Include') + '"  value="' + get_lang('Include') + '"' +
181                'type="button" onclick="RichTextEditor.addInputFile();">&nbsp;' +
182                '<input title="' + get_lang('Close') + '"  value="' + get_lang('Close') + '"' +
183                ' type="button" onclick="win.close()">';
184                form.appendChild(form_upload);
185               
186                this.showWindow(form);
187}
188cRichTextEditor.prototype.showWindow = function (div){
189
190                if(! div) {
191                        return;
192                }
193               
194                if(! this.emwindow[div.id]) {
195                        div.style.width  =  div.firstChild.style.width;
196                        div.style.height = div.firstChild.style.height;
197                        div.style.zIndex = "10000";                     
198                        var title = div.firstChild.name;
199                        var wHeight = div.offsetHeight + "px";
200                        var wWidth =  div.offsetWidth   + "px";
201                        div.style.width = div.offsetWidth - 5;
202
203                        win = new dJSWin({
204                                id: 'win_'+div.id,
205                                content_id: div.id,
206                                width: wWidth,
207                                height: wHeight,
208                                title_color: '#3978d6',
209                                bg_color: '#eee',
210                                title: title,
211                                title_text_color: 'white',
212                                button_x_img: '../phpgwapi/images/winclose.gif',
213                                border: true});
214                       
215                        this.emwindow[div.id] = win;
216                        win.draw();
217                }
218                else
219                        win = this.emwindow[div.id];
220                win.open();     
221}
222cRichTextEditor.prototype.addInputFile = function()
223{
224        //Begin: Verify if the image extension is allowed.
225        var imgExtensions = new Array("jpeg", "jpg", "gif", "png", "bmp", "xbm", "tiff", "pcx");
226        var inputFile = document.getElementById('inputFile_img');       
227        if(!inputFile.value) return false;
228        var fileExtension = inputFile.value.split(".");
229        fileExtension = fileExtension[(fileExtension.length-1)];
230        var deniedExtension = true;
231        for(var i=0; i<imgExtensions.length; i++) {
232                if(imgExtensions[i].toUpperCase() == fileExtension.toUpperCase()) {
233                        deniedExtension = false;
234                        break;
235                }
236        }
237        if(deniedExtension) {
238                alert(get_lang('File extension forbidden or invalid file') + '.');
239                return false;
240        }
241        // End: Verify image extension.
242        var id =  currentTab;
243        divFiles = document.getElementById("divFiles_"+id);
244        var countDivFiles = divFiles.childNodes.length + 1;
245
246        var divFiles = document.getElementById('divFiles_'+id);
247        inputFile.id = 'inputFile_'+id +"_"+countDivFiles;
248        inputFile.name = 'file_'+countDivFiles;
249        divFile = document.createElement('DIV');
250        divFile.appendChild(inputFile);
251        divFiles.appendChild(divFile);
252
253        var form_upload = document.getElementById('form_upload');
254        form_upload.parentNode.removeChild(form_upload);
255        win.close();
256
257        RichTextEditor.saveFlag = 0; // See if save function finished
258        var save_link = document.getElementById("save_message_options_"+id);
259        save_link.onclick = function () {};
260        this.newImageId = new Date().getTime();
261        CKEDITOR.instances['body_'+id].insertHtml('<img id="'+this.newImageId+'" src=""/>');
262        save_msg(id,true);
263}
264
265cRichTextEditor.prototype.execPosInstance = function(inst) {
266        var editor =  CKEDITOR.instances[inst];
267        var id = inst.replace('body_','');
268        editor.document.on('keydown', function(event)
269        {
270                away = false;
271                var save_link = Element("save_message_options_"+id);
272                save_link.onclick = function onclick() {openTab.toPreserve[id] = true;save_msg(id);} ;
273                $("#save_message_options_"+id).button({ disabled: false });
274        });
275       
276//Adicionando atalhos de preferencias 
277//TODO: Não esta pegando o numero (keycode)
278//        if (preferences.use_shortcuts == '1')
279//        {
280//            CKEDITOR.instances[inst].document.on('keyup', function(event){
281//                    if(event.keyCode == 27){                         
282//                            delete_border(id,'false');}  //Tecla delete fechar aba         
283//            });
284//        } 
285       
286        // IM Module Enabled
287        if( window.parent.loadscript && loadscript.autoStatusIM )
288        {
289                CKEDITOR.instances[inst].document.on('keydown', function(event){
290                        loadscript.autoStatusIM;
291                });             
292        }
293       
294        if (preferences.auto_save_draft == 1)
295        {
296                openTab.autosave_timer[id] = false;
297                var save_link = document.getElementById("save_message_options"+id);
298                CKEDITOR.instances[inst].document.on('keydown', function(event){
299                   if (openTab.autosave_timer[id])
300                                clearTimeout(openTab.autosave_timer[id]);
301                   openTab.autosave_timer[id] = setTimeout("save_msg("+id+")", autosave_time);
302                                       
303                }); 
304        }
305       
306        /*var rich_button = document.createElement("a");
307        //rich_button.className = "button small";
308        rich_button.name = "textplain_rt_checkbox_"+id;
309        rich_button.innerHTML = get_lang('Simple text mode')+" >>";
310        rich_button.href = "#";
311        rich_button.onclick = function (){
312                var check = $("#"+$(this).attr("name")).attr("checked");
313                $("#"+$(this).attr("name")).attr("checked", (!check ? true : false));
314                $("#"+$(this).attr("name")).trigger('click');
315                //RichTextEditor.setPlain($("#"+$(this).attr("name")).attr("checked"), id);
316        };
317        if($("#cke_top_body_"+id).find(".cke_toolbar:last"))
318        $("#cke_top_body_"+id).find(".cke_toolbar:last").append("<span class='button small'></span>");
319        $("#cke_top_body_"+id).find("span:last").append(rich_button);
320        $("#cke_top_body_"+id).attr("colSpan", "2");
321        $("#cke_contents_body_"+id).attr("colSpan", "2");
322        $("#cke_bottom_body_"+id).attr("colSpan", "2");*/
323        $(".cke_editor").css("white-space", "normal");
324       
325        RichTextEditor.editorReady = true;
326}
327cRichTextEditor.prototype.setPlain = function (active,id){
328      RichTextEditor.plain[id] = active;
329      if(active === true)
330      {
331            CKEDITOR.instances['body_'+id].destroy();
332            var height = document.body.scrollHeight;
333            height -= 330;
334            $('#body_'+id).height(height);
335            $('#body_'+id).keydown(function(event) {
336                away = false;
337                var save_link = Element("save_message_options_"+id);
338                save_link.onclick = function onclick() {openTab.toPreserve[id] = true;save_msg(id);} ;
339                                $("#save_message_options_"+id).button({ disabled: false });
340                //save_link.className = 'message_options';
341            });
342                        $("[name=textplain_rt_checkbox_"+id+"]").button({ disabled: false });
343      }   
344      else
345          RichTextEditor.active('body_'+id, id);
346}
347
348cRichTextEditor.prototype.getData = function (inst){ 
349    var id = inst.replace('body_','');
350   
351    if(RichTextEditor.plain[id] === true)
352        return $('#'+inst).val();
353    else
354        return CKEDITOR.instances[inst].getData();
355}
356cRichTextEditor.prototype.setData = function (id,data){
357   
358     if(this.plain[id] === true)
359        $('#'+id).val(data);
360     else
361        CKEDITOR.instances[id].setData(data)
362}
363cRichTextEditor.prototype.setInitData = function (id,data,reply,recursion){
364   
365    if(recursion === undefined) recursion = 1;
366    else recursion++;   
367   
368     if(this.plain[id] === true)
369     {
370                 if($('#'+id) !== undefined)
371                        $('#'+id).val(data);
372         else
373                          setTimeout(function() {RichTextEditor.setInitData(id,data,reply,recursion); }, 500);
374         } 
375     else
376     {
377       if( RichTextEditor.editorReady === true && CKEDITOR.instances['body_'+id] !== undefined )   
378       {
379           var editor =   CKEDITOR.instances['body_'+id];   
380           editor.insertHtml('');
381           var selection = editor.getSelection();
382           if(selection !== undefined && selection !== null) var selectionRanges = selection.getRanges();
383
384           var fontSize = '';
385           var fontFamily = '';
386           
387           if(typeof(preferences.font_size_editor) !== 'undefined')
388               fontSize = 'font-size:' + preferences.font_size_editor;
389               
390           if(fontSize != '')
391               fontFamily = ';'
392           
393           if(typeof(preferences.font_family_editor) !== 'undefined')
394               fontFamily += 'font-family:' + preferences.font_family_editor + ';';
395           
396           var divBr = '<div style="'+fontSize+fontFamily+'"><br type="_moz"></div>';
397         
398                    if(reply === undefined)
399                                editor.insertHtml(divBr+divBr+data);
400                        else if(reply == 'edit')
401                                editor.insertHtml(data);
402                        else
403                                editor.insertHtml(divBr+data);
404           
405           if(selection !== null) selection.selectRanges(selectionRanges);
406                   
407                   //Coloca o scroll do editor no inicio
408                   if (is_webkit){
409                                $('#cke_contents_body_'+id+'>iframe').scrollTo(':first');
410                   }
411          //Caso não for uma resposta votla o foco para o input to
412          if(reply === undefined)   
413                  setTimeout("$('#to_"+id+"').focus()",100);
414 
415       }
416       else if(recursion < 20)
417           setTimeout(function() {RichTextEditor.setInitData(id,data,reply,recursion); }, 500);
418     }
419}
420
421cRichTextEditor.prototype.destroy = function(id)
422{
423        //Remove Instancia do editor
424        if( CKEDITOR.instances[id] !== undefined )   
425             CKEDITOR.remove(CKEDITOR.instances[id]);
426}
427cRichTextEditor.prototype.active = function(id, just_id)
428{
429   
430   //Remove Instancia do editor caso ela exista
431    if( CKEDITOR.instances[id] !== undefined )   
432         CKEDITOR.remove(CKEDITOR.instances[id]);
433     
434    var height = document.body.scrollHeight;
435    height -= 425;
436     
437     $('#'+id).ckeditor(
438          function() {RichTextEditor.execPosInstance(id)},
439          {
440              toolbar:'mail',
441              height: height
442          });
443        $("[name=textplain_rt_checkbox_"+just_id+"]").button({ disabled: false });
444}
445cRichTextEditor.prototype.focus = function(id)
446{
447    if(RichTextEditor.plain[id]  === true)
448        $('#body_'+id).focus();
449    else
450        CKEDITOR.instances['body_'+id].focus();
451
452}
453//Função reseta o atributo contentEditable para resolver bug de cursor ao trocar abas
454cRichTextEditor.prototype.setEditable = function(id) {
455        if( CKEDITOR.instances['body_'+ id] === undefined ) return;   
456        var element = CKEDITOR.instances['body_'+ id].document.getBody();
457        element.removeAttribute('contentEditable');
458        element.setAttribute('contentEditable','true');
459}
460//Build the Object
461RichTextEditor = new cRichTextEditor();
Note: See TracBrowser for help on using the repository browser.