source: pro-violet-viettel/docs/Space/assets/js/uncompressed/ace-elements.js @ 290

Last change on this file since 290 was 290, checked in by lamdt, 11 years ago
File size: 27.9 KB
Line 
1if(! ('ace' in window) ) window['ace'] = {}
2jQuery(function() {
3        //at some places we try to use 'tap' event instead of 'click' if jquery mobile plugin is available
4        window['ace'].click_event = $.fn.tap ? "tap" : "click";
5});
6
7(function($ , undefined) {
8        var multiplible = 'multiple' in document.createElement('INPUT');
9        var hasFileList = 'FileList' in window;//file list enabled in modern browsers
10        var hasFileReader = 'FileReader' in window;
11
12        var Ace_File_Input = function(element , settings) {
13                var self = this;
14                this.settings = $.extend({}, $.fn.ace_file_input.defaults, settings);
15
16                this.$element = $(element);
17                this.element = element;
18                this.disabled = false;
19                this.can_reset = true;
20
21                this.$element.on('change.ace_inner_call', function(e , ace_inner_call){
22                        if(ace_inner_call === true) return;//this change event is called from above drop event
23                        return handle_on_change.call(self);
24                });
25               
26                this.$element.wrap('<div class="ace-file-input" />');
27               
28                this.apply_settings();
29        }
30        Ace_File_Input.error = {
31                'FILE_LOAD_FAILED' : 1,
32                'IMAGE_LOAD_FAILED' : 2,
33                'THUMBNAIL_FAILED' : 3
34        };
35
36
37        Ace_File_Input.prototype.apply_settings = function() {
38                var self = this;
39                var remove_btn = !!this.settings.icon_remove;
40
41                this.multi = this.$element.attr('multiple') && multiplible;
42                this.well_style = this.settings.style == 'well';
43
44                if(this.well_style) this.$element.parent().addClass('ace-file-multiple');
45                 else this.$element.parent().removeClass('ace-file-multiple');
46
47                this.$element.parent().find(':not(input[type=file])').remove();//remove all except our input, good for when changing settings
48                this.$element.after('<label class="file-label" data-title="'+this.settings.btn_choose+'"><span class="file-name" data-title="'+this.settings.no_file+'">'+(this.settings.no_icon ? '<i class="'+this.settings.no_icon+'"></i>' : '')+'</span></label>'+(remove_btn ? '<a class="remove" href="#"><i class="'+this.settings.icon_remove+'"></i></a>' : ''));
49                this.$label = this.$element.next();
50
51                this.$label.on('click', function(){//firefox mobile doesn't allow 'tap'!
52                        if(!this.disabled && !self.element.disabled && !self.$element.attr('readonly'))
53                                self.$element.click();
54                })
55
56                if(remove_btn) this.$label.next('a').on(ace.click_event, function(){
57                        if(! self.can_reset ) return false;
58                       
59                        var ret = true;
60                        if(self.settings.before_remove) ret = self.settings.before_remove.call(self.element);
61                        if(!ret) return false;
62                        return self.reset_input();
63                });
64
65
66                if(this.settings.droppable && hasFileList) {
67                        enable_drop_functionality.call(this);
68                }
69        }
70
71        Ace_File_Input.prototype.show_file_list = function($files) {
72                var files = typeof $files === "undefined" ? this.$element.data('ace_input_files') : $files;
73                if(!files || files.length == 0) return;
74
75                //////////////////////////////////////////////////////////////////
76
77                if(this.well_style) {
78                        this.$label.find('.file-name').remove();
79                        if(!this.settings.btn_change) this.$label.addClass('hide-placeholder');
80                }
81                this.$label.attr('data-title', this.settings.btn_change).addClass('selected');
82               
83                for (var i = 0; i < files.length; i++) {
84                        var filename = typeof files[i] === "string" ? files[i] : $.trim( files[i].name );
85                        var index = filename.lastIndexOf("\\") + 1;
86                        if(index == 0)index = filename.lastIndexOf("/") + 1;
87                        filename = filename.substr(index);
88                       
89                        var fileIcon = 'icon-file';
90                        if((/\.(jpe?g|png|gif|svg|bmp|tiff?)$/i).test(filename)) {
91                                fileIcon = 'icon-picture';
92                        }
93                        else if((/\.(mpe?g|flv|mov|avi|swf|mp4|mkv|webm|wmv|3gp)$/i).test(filename)) fileIcon = 'icon-film';
94                        else if((/\.(mp3|ogg|wav|wma|amr|aac)$/i).test(filename)) fileIcon = 'icon-music';
95
96
97                        if(!this.well_style) this.$label.find('.file-name').attr({'data-title':filename}).find('[class*="icon-"]').attr('class', fileIcon);
98                        else {
99                                this.$label.append('<span class="file-name" data-title="'+filename+'"><i class="'+fileIcon+'"></i></span>');
100                                var type = $.trim(files[i].type);
101                                var can_preview = hasFileReader && this.settings.thumbnail
102                                                &&
103                                                ( (type.length > 0 && type.match('image')) || (type.length == 0 && fileIcon == 'icon-picture') )//the second one is for Android's default browser which gives an empty text for file.type
104                                if(can_preview) {
105                                        var self = this;
106                                        $.when(preview_image.call(this, files[i])).fail(function(result){
107                                                //called on failure to load preview
108                                                if(self.settings.preview_error) self.settings.preview_error.call(self, filename, result.code);
109                                        });
110                                }
111                        }
112
113                }
114
115                return true;
116        }
117
118        Ace_File_Input.prototype.reset_input = function() {
119          this.$label.attr({'data-title':this.settings.btn_choose, 'class':'file-label'})
120                        .find('.file-name:first').attr({'data-title':this.settings.no_file , 'class':'file-name'})
121                        .find('[class*="icon-"]').attr('class', this.settings.no_icon)
122                        .prev('img').remove();
123                        if(!this.settings.no_icon) this.$label.find('[class*="icon-"]').remove();
124               
125                this.$label.find('.file-name').not(':first').remove();
126               
127                if(this.$element.data('ace_input_files')) {
128                        this.$element.removeData('ace_input_files');
129                        this.$element.removeData('ace_input_method');
130                }
131
132                this.reset_input_field();
133               
134                return false;
135        }
136
137        Ace_File_Input.prototype.reset_input_field = function() {
138                //http://stackoverflow.com/questions/1043957/clearing-input-type-file-using-jquery/13351234#13351234
139                this.$element.wrap('<form>').closest('form').get(0).reset();
140                this.$element.unwrap();
141        }
142       
143        Ace_File_Input.prototype.enable_reset = function(can_reset) {
144                this.can_reset = can_reset;
145        }
146
147        Ace_File_Input.prototype.disable = function() {
148                this.disabled = true;
149                this.$element.attr('disabled', 'disabled').addClass('disabled');
150        }
151        Ace_File_Input.prototype.enable = function() {
152                this.disabled = false;
153                this.$element.removeAttr('disabled').removeClass('disabled');
154        }
155       
156        Ace_File_Input.prototype.files = function() {
157                return $(this).data('ace_input_files') || null;
158        }
159        Ace_File_Input.prototype.method = function() {
160                return $(this).data('ace_input_method') || '';
161        }
162       
163        Ace_File_Input.prototype.update_settings = function(new_settings) {
164                this.settings = $.extend({}, this.settings, new_settings);
165                this.apply_settings();
166        }
167
168
169
170        var enable_drop_functionality = function() {
171                var self = this;
172                var dropbox = this.element.parentNode;         
173                $(dropbox).on('dragenter', function(e){
174                        e.preventDefault();
175                        e.stopPropagation();
176                }).on('dragover', function(e){
177                        e.preventDefault();
178                        e.stopPropagation();
179                }).on('drop', function(e){
180                        e.preventDefault();
181                        e.stopPropagation();
182
183                        var dt = e.originalEvent.dataTransfer;
184                        var files = dt.files;
185                        if(!self.multi && files.length > 1) {//single file upload, but dragged multiple files
186                                var tmpfiles = [];
187                                tmpfiles.push(files[0]);
188                                files = tmpfiles;//keep only first file
189                        }
190                       
191                        var ret = true;
192                        if(self.settings.before_change) ret = self.settings.before_change.call(self.element, files, true);//true means files have been dropped
193                        if(!ret || ret.length == 0) {
194                                return false;
195                        }
196                       
197                        //user can return a modified File Array as result
198                        if(ret instanceof Array || (hasFileList && ret instanceof FileList)) files = ret;
199                       
200                       
201                        self.$element.data('ace_input_files', files);//save files data to be used later by user
202                        self.$element.data('ace_input_method', 'drop');
203
204
205                        self.show_file_list(files);
206                       
207                       
208                        self.$element.triggerHandler('change' , [true]);//true means inner_call
209                        return true;
210                });
211        }
212       
213       
214        var handle_on_change = function() {
215                var ret = true;
216                if(this.settings.before_change) ret = this.settings.before_change.call(this.element, this.element.files || [this.element.value]/*make it an array*/, false);//false means files have been selected, not dropped
217                if(!ret || ret.length == 0) {
218                        if(!this.$element.data('ace_input_files')) this.reset_input_field();//if nothing selected before, reset because of the newly unacceptable (ret=false||length=0) selection
219                        return false;
220                }
221               
222
223                //user can return a modified File Array as result
224                var files = !hasFileList ? null ://for old IE, etc
225                                        ((ret instanceof Array || ret instanceof FileList) ? ret : this.element.files);
226                this.$element.data('ace_input_method', 'select');
227
228
229                if(files && files.length > 0) {//html5
230                        this.$element.data('ace_input_files', files);
231                }
232                else {
233                        var name = $.trim( this.element.value );
234                        if(name && name.length > 0) {
235                                files = []
236                                files.push(name);
237                                this.$element.data('ace_input_files', files);
238                        }
239                }
240
241                if(!files || files.length == 0) return false;
242                this.show_file_list(files);
243
244                return true;
245        }
246
247
248
249
250        var preview_image = function(file) {
251                var self = this;
252                var $span = self.$label.find('.file-name:last');//it should be out of onload, otherwise all onloads may target the same span because of delays
253               
254                var deferred = new $.Deferred
255                var reader = new FileReader();
256                reader.onload = function (e) {
257                        $span.prepend("<img class='middle' style='display:none;' />");
258                        var img = $span.find('img:last').get(0);
259
260                        $(img).one('load', function() {
261                                //if image loaded successfully
262                                var size = 50;
263                                if(self.settings.thumbnail == 'large') size = 150;
264                                else if(self.settings.thumbnail == 'fit') size = $span.width();
265                                $span.addClass(size > 50 ? 'large' : '');
266
267                                var thumb = get_thumbnail(img, size, file.type);
268                                if(thumb == null) {
269                                        //if making thumbnail fails
270                                        $(this).remove();
271                                        deferred.reject({code:Ace_File_Input.error['THUMBNAIL_FAILED']});
272                                        return;
273                                }
274
275                                var w = thumb.w, h = thumb.h;
276                                if(self.settings.thumbnail == 'small') {w=h=size;};
277                                $(img).css({'background-image':'url('+thumb.src+')' , width:w, height:h})                                                                       
278                                                .data('thumb', thumb.src)
279                                                .attr({src:'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWNgYGBgAAAABQABh6FO1AAAAABJRU5ErkJggg=='})
280                                                .show()
281
282                                ///////////////////
283                                deferred.resolve();
284                        }).one('error', function() {
285                                //for example when a file has image extenstion, but format is something else
286                                $span.find('img').remove();
287                                deferred.reject({code:Ace_File_Input.error['IMAGE_LOAD_FAILED']});
288                        });
289
290                        img.src = e.target.result;
291                }
292                reader.onerror = function (e) {
293                        deferred.reject({code:Ace_File_Input.error['FILE_LOAD_FAILED']});
294                }
295                reader.readAsDataURL(file);
296
297                return deferred.promise();
298        }
299
300        var get_thumbnail = function(img, size, type) {
301               
302                var w = img.width, h = img.height;
303                if(w > size || h > size) {
304                  if(w > h) {
305                        h = parseInt(size/w * h);
306                        w = size;
307                  } else {
308                        w = parseInt(size/h * w);
309                        h = size;
310                  }
311                }
312
313                var dataURL
314                try {
315                        var canvas = document.createElement('canvas');
316                        canvas.width = w; canvas.height = h;
317                        var context = canvas.getContext('2d');
318                        context.drawImage(img, 0, 0, img.width, img.height, 0, 0, w, h);
319                        dataURL = canvas.toDataURL(/*type == 'image/jpeg' ? type : 'image/png', 10*/)
320                } catch(e) {
321                        dataURL = null;
322                }
323
324                //there was only one image that failed in firefox completely randomly! so let's double check it
325                if(!( /^data\:image\/(png|jpe?g|gif);base64,[0-9A-Za-z\+\/\=]+$/.test(dataURL)) ) dataURL = null;
326                if(! dataURL) return null;
327
328                return {src: dataURL, w:w, h:h};
329        }
330
331
332
333        ///////////////////////////////////////////
334        $.fn.ace_file_input = function (option,value) {
335                var retval;
336
337                var $set = this.each(function () {
338                        var $this = $(this);
339                        var data = $this.data('ace_file_input');
340                        var options = typeof option === 'object' && option;
341
342                        if (!data) $this.data('ace_file_input', (data = new Ace_File_Input(this, options)));
343                        if (typeof option === 'string') retval = data[option](value);
344                });
345
346                return (retval === undefined) ? $set : retval;
347        };
348
349
350        $.fn.ace_file_input.defaults = {
351                style:false,
352                no_file:'No File ...',
353                no_icon:'icon-upload-alt',
354                btn_choose:'Choose',
355                btn_change:'Change',
356                icon_remove:'icon-remove',
357                droppable:false,
358                thumbnail:false,//large, fit, small
359               
360                //callbacks
361                before_change:null,
362                before_remove:null,
363                preview_error:null
364     }
365
366
367})(window.jQuery);
368
369
370
371
372
373
374
375
376(function($ , undefined) {
377        $.fn.ace_spinner = function(options) {
378               
379                //when min is negative, the input maxlength does not account for the extra minus sign
380                this.each(function() {
381                        var icon_up = options.icon_up || 'icon-chevron-up'
382                        var icon_down = options.icon_down || 'icon-chevron-down'
383                        var on_sides = options.on_sides || false
384                       
385                        var btn_up_class = options.btn_up_class || ''
386                        var btn_down_class = options.btn_down_class || ''
387               
388                        var max = options.max || 999
389                        max = (''+max).length
390                       
391                                $(this).addClass('spinner-input form-control').wrap('<div class="ace-spinner">')
392                                var $parent_div = $(this).closest('.ace-spinner').spinner(options).wrapInner("<div class='input-group'></div>")
393
394                                if(on_sides)
395                                {
396                                  $(this).before('<div class="spinner-buttons input-group-btn">\
397                                                        <button type="button" class="btn spinner-down btn-xs '+btn_down_class+'">\
398                                                                <i class="'+icon_down+'"></i>\
399                                                        </button>\
400                                                </div>')
401                                  .after('<div class="spinner-buttons input-group-btn">\
402                                                        <button type="button" class="btn spinner-up btn-xs '+btn_up_class+'">\
403                                                                <i class="'+icon_up+'"></i>\
404                                                        </button>\
405                                                </div>')
406                               
407                                        $parent_div.addClass('touch-spinner')
408                                        $parent_div.css('width' , (max * 20 + 40)+'px')
409                                }
410                                else {
411                                         $(this).after('<div class="spinner-buttons input-group-btn">\
412                                                        <button type="button" class="btn spinner-up btn-xs '+btn_up_class+'">\
413                                                                <i class="'+icon_up+'"></i>\
414                                                        </button>\
415                                                        <button type="button" class="btn spinner-down btn-xs '+btn_down_class+'">\
416                                                                <i class="'+icon_down+'"></i>\
417                                                        </button>\
418                                                </div>')
419
420                                        if("ontouchend" in document || options.touch_spinner) {
421                                                $parent_div.addClass('touch-spinner')
422                                                $parent_div.css('width' , (max * 20 + 40)+'px')
423                                        }
424                                        else {
425                                                $(this).next().addClass('btn-group-vertical');
426                                                $parent_div.css('width' , (max * 20 + 10)+'px')
427                                        }
428                                }
429                               
430                               
431
432                        $(this).on('mousewheel DOMMouseScroll', function(event){
433                                var delta = event.originalEvent.detail < 0 || event.originalEvent.wheelDelta > 0 ? 1 : -1
434                                $parent_div.spinner('step', delta > 0)//accepts true or false as second param
435                                $parent_div.spinner('triggerChangedEvent')
436                                return false
437                        });
438                        var that = $(this);
439                        $parent_div.on('changed', function(){
440                                that.trigger('change')//trigger the input's change event
441                        });
442                       
443                });
444               
445                return this;
446        }
447
448
449})(window.jQuery);
450
451
452
453
454
455
456(function($ , undefined) {
457        $.fn.ace_wizard = function(options) {
458               
459                this.each(function() {
460                        var $this = $(this);
461                        $this.wizard();
462
463                        var buttons = $this.siblings('.wizard-actions').eq(0);
464                        var $wizard = $this.data('wizard');
465                        $wizard.$prevBtn.remove();
466                        $wizard.$nextBtn.remove();
467                       
468                        $wizard.$prevBtn = buttons.find('.btn-prev').eq(0).on(ace.click_event,  function(){
469                                $this.wizard('previous');
470                        }).attr('disabled', 'disabled');
471                        $wizard.$nextBtn = buttons.find('.btn-next').eq(0).on(ace.click_event,  function(){
472                                $this.wizard('next');
473                        }).removeAttr('disabled');
474                        $wizard.nextText = $wizard.$nextBtn.text();
475                });
476               
477                return this;
478        }
479
480})(window.jQuery);
481
482
483
484
485
486(function($ , undefined) {
487        $.fn.ace_colorpicker = function(options) {
488               
489                var settings = $.extend( {
490                        pull_right:false,
491                        caret:true
492        }, options);
493               
494                this.each(function() {
495               
496                        var $that = $(this);
497                        var colors = '';
498                        var color = '';
499                        $(this).hide().find('option').each(function() {
500                                var $class = 'colorpick-btn';
501                                if(this.selected) {
502                                        $class += ' selected';
503                                        color = this.value;
504                                }
505                                colors += '<li><a class="'+$class+'" href="#" style="background-color:'+this.value+';" data-color="'+this.value+'"></a></li>';
506                        }).end().on('change.ace_inner_call', function(){
507                                        $(this).next().find('.btn-colorpicker').css('background-color', this.value);
508                        })
509                        .after('<div class="dropdown dropdown-colorpicker"><a data-toggle="dropdown" class="dropdown-toggle" href="#"><span class="btn-colorpicker" style="background-color:'+color+'"></span></a><ul class="dropdown-menu'+(settings.caret? ' dropdown-caret' : '')+(settings.pull_right ? ' pull-right' : '')+'">'+colors+'</ul></div>')
510                        .next().find('.dropdown-menu').on(ace.click_event, function(e) {
511                                var a = $(e.target);
512                                if(!a.is('.colorpick-btn')) return false;
513                                a.closest('ul').find('.selected').removeClass('selected');
514                                a.addClass('selected');
515                                var color = a.data('color');
516
517                                $that.val(color).change();
518
519                                e.preventDefault();
520                                return true;//if false, dropdown won't hide!
521                        });
522                       
523                       
524                });
525                return this;
526               
527        }       
528       
529       
530})(window.jQuery);
531
532
533
534
535
536
537
538
539
540
541
542
543(function($ , undefined) {
544        $.fn.ace_tree = function(options) {
545                var $options = {
546                        'open-icon' : 'icon-folder-open',
547                        'close-icon' : 'icon-folder-close',
548                        'selectable' : true,
549                        'selected-icon' : 'icon-ok',
550                        'unselected-icon' : 'tree-dot'
551                }
552               
553                $options = $.extend({}, $options, options)
554
555                this.each(function() {
556                        var $this = $(this);
557                        $this.html('<div class = "tree-folder" style="display:none;">\
558                                <div class="tree-folder-header">\
559                                        <i class="'+$options['close-icon']+'"></i>\
560                                        <div class="tree-folder-name"></div>\
561                                </div>\
562                                <div class="tree-folder-content"></div>\
563                                <div class="tree-loader" style="display:none"></div>\
564                        </div>\
565                        <div class="tree-item" style="display:none;">\
566                                '+($options['unselected-icon'] == null ? '' : '<i class="'+$options['unselected-icon']+'"></i>')+'\
567                                <div class="tree-item-name"></div>\
568                        </div>');
569                        $this.addClass($options['selectable'] == true ? 'tree-selectable' : 'tree-unselectable');
570                       
571                        $this.tree($options);
572                });
573
574                return this;
575        }
576
577
578})(window.jQuery);
579
580
581
582
583
584
585
586
587
588
589
590
591(function($ , undefined) {
592        $.fn.ace_wysiwyg = function($options , undefined) {
593                var options = $.extend( {
594                        speech_button:true,
595                        wysiwyg:{}
596        }, $options);
597
598                var color_values = [
599                        '#ac725e','#d06b64','#f83a22','#fa573c','#ff7537','#ffad46',
600                        '#42d692','#16a765','#7bd148','#b3dc6c','#fbe983','#fad165',
601                        '#92e1c0','#9fe1e7','#9fc6e7','#4986e7','#9a9cff','#b99aff',
602                        '#c2c2c2','#cabdbf','#cca6ac','#f691b2','#cd74e6','#a47ae2',
603                        '#444444'
604                ]
605
606                var button_defaults =
607                {
608                        'font' : {
609                                values:['Arial', 'Courier', 'Comic Sans MS', 'Helvetica', 'Open Sans', 'Tahoma', 'Verdana'],
610                                icon:'icon-font',
611                                title:'Font'
612                        },
613                        'fontSize' : {
614                                values:{5:'Huge', 3:'Normal', 1:'Small'},
615                                icon:'icon-text-height',
616                                title:'Font Size'
617                        },
618                        'bold' : {
619                                icon : 'icon-bold',
620                                title : 'Bold (Ctrl/Cmd+B)'
621                        },
622                        'italic' : {
623                                icon : 'icon-italic',
624                                title : 'Italic (Ctrl/Cmd+I)'
625                        },
626                        'strikethrough' : {
627                                icon : 'icon-strikethrough',
628                                title : 'Strikethrough'
629                        },
630                        'underline' : {
631                                icon : 'icon-underline',
632                                title : 'Underline'
633                        },
634                        'insertunorderedlist' : {
635                                icon : 'icon-list-ul',
636                                title : 'Bullet list'
637                        },
638                        'insertorderedlist' : {
639                                icon : 'icon-list-ol',
640                                title : 'Number list'
641                        },
642                        'outdent' : {
643                                icon : 'icon-indent-left',
644                                title : 'Reduce indent (Shift+Tab)'
645                        },
646                        'indent' : {
647                                icon : 'icon-indent-right',
648                                title : 'Indent (Tab)'
649                        },
650                        'justifyleft' : {
651                                icon : 'icon-align-left',
652                                title : 'Align Left (Ctrl/Cmd+L)'
653                        },
654                        'justifycenter' : {
655                                icon : 'icon-align-center',
656                                title : 'Center (Ctrl/Cmd+E)'
657                        },
658                        'justifyright' : {
659                                icon : 'icon-align-right',
660                                title : 'Align Right (Ctrl/Cmd+R)'
661                        },
662                        'justifyfull' : {
663                                icon : 'icon-align-justify',
664                                title : 'Justify (Ctrl/Cmd+J)'
665                        },
666                        'createLink' : {
667                                icon : 'icon-link',
668                                title : 'Hyperlink',
669                                button_text : 'Add',
670                                placeholder : 'URL',
671                                button_class : 'btn-primary'
672                        },
673                        'unlink' : {
674                                icon : 'icon-unlink',
675                                title : 'Remove Hyperlink'
676                        },
677                        'insertImage' : {
678                                icon : 'icon-picture',
679                                title : 'Insert picture',
680                                button_text : '<i class="icon-file"></i> Choose Image &hellip;',
681                                placeholder : 'Image URL',
682                                button_insert : 'Insert',
683                                button_class : 'btn-success',
684                                button_insert_class : 'btn-primary',
685                                choose_file: true //show the choose file button?
686                        },
687                        'foreColor' : {
688                                values : color_values,
689                                title : 'Change Color'
690                        },
691                        'backColor' : {
692                                values : color_values,
693                                title : 'Change Background Color'
694                        },
695                        'undo' : {
696                                icon : 'icon-undo',
697                                title : 'Undo (Ctrl/Cmd+Z)'
698                        },
699                        'redo' : {
700                                icon : 'icon-repeat',
701                                title : 'Redo (Ctrl/Cmd+Y)'
702                        },
703                        'viewSource' : {
704                                icon : 'icon-code',
705                                title : 'View Source'
706                        }
707                }
708               
709                var toolbar_buttons =
710                options.toolbar ||
711                [
712                        'font',
713                        null,
714                        'fontSize',
715                        null,
716                        'bold',
717                        'italic',
718                        'strikethrough',
719                        'underline',
720                        null,
721                        'insertunorderedlist',
722                        'insertorderedlist',
723                        'outdent',
724                        'indent',
725                        null,
726                        'justifyleft',
727                        'justifycenter',
728                        'justifyright',
729                        'justifyfull',
730                        null,
731                        'createLink',
732                        'unlink',
733                        null,
734                        'insertImage',
735                        null,
736                        'foreColor',
737                        null,
738                        'undo',
739                        'redo',
740                        null,
741                        'viewSource'
742                ]
743
744
745                this.each(function() {
746                        var toolbar = ' <div class="wysiwyg-toolbar btn-toolbar center"> <div class="btn-group"> ';
747
748                        for(var tb in toolbar_buttons) if(toolbar_buttons.hasOwnProperty(tb)) {
749                                var button = toolbar_buttons[tb];
750                                if(button === null){
751                                        toolbar += ' </div> <div class="btn-group"> ';
752                                        continue;
753                                }
754                               
755                                if(typeof button == "string" && button in button_defaults) {
756                                        button = button_defaults[button];
757                                        button.name = toolbar_buttons[tb];
758                                } else if(typeof button == "object" && button.name in button_defaults) {
759                                        button = $.extend(button_defaults[button.name] , button);
760                                }
761                                else continue;
762                               
763                                var className = "className" in button ? button.className : '';
764                                switch(button.name) {
765                                        case 'font':
766                                                toolbar += ' <a class="btn btn-sm '+className+' dropdown-toggle" data-toggle="dropdown" title="'+button.title+'"><i class="'+button.icon+'"></i><i class="icon-angle-down icon-on-right"></i></a> ';
767                                                toolbar += ' <ul class="dropdown-menu dropdown-light">';
768                                                for(var font in button.values)
769                                                        if(button.values.hasOwnProperty(font))
770                                                                toolbar += ' <li><a data-edit="fontName ' + button.values[font] +'" style="font-family:\''+ button.values[font]  +'\'">'+button.values[font]  + '</a></li> '
771                                                toolbar += ' </ul>';
772                                        break;
773
774                                        case 'fontSize':
775                                                toolbar += ' <a class="btn btn-sm '+className+' dropdown-toggle" data-toggle="dropdown" title="'+button.title+'"><i class="'+button.icon+'"></i>&nbsp;<i class="icon-angle-down icon-on-right"></i></a> ';
776                                                toolbar += ' <ul class="dropdown-menu dropdown-light"> ';
777                                                for(var size in button.values)
778                                                        if(button.values.hasOwnProperty(size))
779                                                                toolbar += ' <li><a data-edit="fontSize '+size+'"><font size="'+size+'">'+ button.values[size] +'</font></a></li> '
780                                                toolbar += ' </ul> ';
781                                        break;
782
783                                        case 'createLink':
784                                                toolbar += ' <div class="inline position-relative"> <a class="btn btn-sm '+className+' dropdown-toggle" data-toggle="dropdown" title="'+button.title+'"><i class="'+button.icon+'"></i></a> ';
785                                                toolbar += ' <div class="dropdown-menu dropdown-caret pull-right">\
786                                                        <div class="input-group">\
787                                                                <input class="form-control" placeholder="'+button.placeholder+'" type="text" data-edit="'+button.name+'" />\
788                                                                <span class="input-group-btn">\
789                                                                        <button class="btn btn-sm '+button.button_class+'" type="button">'+button.button_text+'</button>\
790                                                                </span>\
791                                                        </div>\
792                                                </div> </div>';
793                                        break;
794
795                                        case 'insertImage':
796                                                toolbar += ' <div class="inline position-relative"> <a class="btn btn-sm '+className+' dropdown-toggle" data-toggle="dropdown" title="'+button.title+'"><i class="'+button.icon+'"></i></a> ';
797                                                toolbar += ' <div class="dropdown-menu dropdown-caret pull-right">\
798                                                        <div class="input-group">\
799                                                                <input class="form-control" placeholder="'+button.placeholder+'" type="text" data-edit="'+button.name+'" />\
800                                                                <span class="input-group-btn">\
801                                                                        <button class="btn btn-sm '+button.button_insert_class+'" type="button">'+button.button_insert+'</button>\
802                                                                </span>\
803                                                        </div>';
804                                                        if( button.choose_file && 'FileReader' in window ) toolbar +=
805                                                         '<div class="space-2"></div>\
806                                                         <div class="center">\
807                                                                <button class="btn btn-sm '+button.button_class+' wysiwyg-choose-file" type="button">'+button.button_text+'</button>\
808                                                                <input type="file" data-edit="'+button.name+'" />\
809                                                          </div>'
810                                                toolbar += ' </div> </div>';
811                                        break;
812
813                                        case 'foreColor':
814                                        case 'backColor':
815                                                toolbar += ' <select class="hide wysiwyg_colorpicker" title="'+button.title+'"> ';
816                                                for(var color in button.values)
817                                                        toolbar += ' <option value="'+button.values[color]+'">'+button.values[color]+'</option> ';
818                                                toolbar += ' </select> ';
819                                                toolbar += ' <input style="display:none;" disabled class="hide" type="text" data-edit="'+button.name+'" /> ';
820                                        break;
821
822                                        case 'viewSource':
823                                                toolbar += ' <a class="btn btn-sm '+className+'" data-view="source" title="'+button.title+'"><i class="'+button.icon+'"></i></a> ';
824                                        break;
825                                        default:
826                                                toolbar += ' <a class="btn btn-sm '+className+'" data-edit="'+button.name+'" title="'+button.title+'"><i class="'+button.icon+'"></i></a> ';
827                                        break;
828                                }
829                        }
830                        toolbar += ' </div> </div> ';
831
832
833
834                        //if we have a function to decide where to put the toolbar, then call that
835                        if(options.toolbar_place) toolbar = options.toolbar_place.call(this, toolbar);
836                        //otherwise put it just before our DIV
837                        else toolbar = $(this).before(toolbar).prev();
838
839                        toolbar.find('a[title]').tooltip({animation:false, container:'body'});
840                        toolbar.find('.dropdown-menu input:not([type=file])').on(ace.click_event, function() {return false})
841                    .on('change', function() {$(this).closest('.dropdown-menu').siblings('.dropdown-toggle').dropdown('toggle')})
842                        .on('keydown', function (e) {if(e.which == 27) {this.value='';$(this).change()}});
843                        toolbar.find('input[type=file]').prev().on(ace.click_event, function (e) {
844                                $(this).next().click();
845                        });
846                        toolbar.find('.wysiwyg_colorpicker').each(function() {
847                                $(this).ace_colorpicker({pull_right:true}).change(function(){
848                                        $(this).nextAll('input').eq(0).val(this.value).change();
849                                }).next().find('.btn-colorpicker').tooltip({title: this.title, animation:false, container:'body'})
850                        });
851                       
852                        var speech_input;
853                        if (options.speech_button && 'onwebkitspeechchange' in (speech_input = document.createElement('input'))) {
854                                var editorOffset = $(this).offset();
855                                toolbar.append(speech_input);
856                                $(speech_input).attr({type:'text', 'data-edit':'inserttext','x-webkit-speech':''}).addClass('wysiwyg-speech-input')
857                                .css({'position':'absolute'}).offset({top: editorOffset.top, left: editorOffset.left+$(this).innerWidth()-35});
858                        } else speech_input = null
859                       
860                       
861                        //view source
862                        var self = $(this);
863                        var view_source = false;
864                        toolbar.find('a[data-view=source]').on('click', function(e){
865                                e.preventDefault();
866                               
867                                if(!view_source) {
868                                        $('<textarea />')
869                                        .css({'width':self.outerWidth(), 'height':self.outerHeight()})
870                                        .val(self.html())
871                                        .insertAfter(self)
872                                        self.hide();
873                                       
874                                        $(this).addClass('active');
875                                }
876                                else {
877                                        var textarea = self.next();
878                                        self.html(textarea.val()).show();
879                                        textarea.remove();
880                                       
881                                        $(this).removeClass('active');
882                                }
883                               
884                                view_source = !view_source;
885                        });
886
887
888                        var $options = $.extend({}, { activeToolbarClass: 'active' , toolbarSelector : toolbar }, options.wysiwyg || {})
889                        $(this).wysiwyg( $options );
890                });
891
892                return this;
893        }
894
895
896})(window.jQuery);
Note: See TracBrowser for help on using the repository browser.