html:
...... ...... ......
trumbowyg.css
.trumbowyg-box,.editor{ clear:both;display:block;position:relative;border:1px solid #DDD;width:100%;min-height:300px;margin:17px auto}.trumbowyg-box .editor{ margin:0 auto;background:#FEFEFE}.trumbowyg-box.trumbowyg-fullscreen{ background:#FEFEFE}.trumbowyg-editor,.trumbowyg-textarea{ position:relative;padding:1% 2%;min-height:300px;width:96%;border-style:none;resize:none;outline:none}.trumbowyg-box-blur .trumbowyg-editor *{ color:transparent !important;text-shadow:0 0 7px #333}.trumbowyg-box-blur .trumbowyg-editor img{ filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=20);opacity:0.2}.trumbowyg-textarea{ position:relative;display:block;overflow:auto;border:none;white-space:normal}.trumbowyg-button-pane{ position:relative;width:100%;background:#ecf0f1;border-bottom:1px solid #d7e0e2;margin:0;padding:0;list-style-type:none;line-height:10px}.trumbowyg-button-pane li{ display:inline-block;text-align:center;overflow:hidden}.trumbowyg-button-pane li.trumbowyg-separator{ width:1px;background:#d7e0e2;margin:0 5px;height:35px}.trumbowyg-button-pane.trumbowyg-disable li:not(.trumbowyg-not-disable) button{ opacity:.2;cursor:default}.trumbowyg-button-pane.trumbowyg-disable li.trumbowyg-separator{ background:#e3e9eb}.trumbowyg-button-pane:not(.trumbowyg-disable) li button:hover,.trumbowyg-button-pane:not(.trumbowyg-disable) li button:focus,.trumbowyg-button-pane li button.trumbowyg-active,.trumbowyg-button-pane li.trumbowyg-not-disable button:hover,.trumbowyg-button-pane li.trumbowyg-not-disable button:focus{ outline:none}.trumbowyg-button-pane li .trumbowyg-open-dropdown:after{ display:block;content:" ";position:absolute;top:25px;right:3px;height:0;width:0;border:3px solid transparent;border-top-color:#555}.trumbowyg-button-pane .trumbowyg-buttons-right{ float:right;width:auto}.trumbowyg-button-pane .trumbowyg-buttons-right button{ float:left}.trumbowyg-dropdown{ width:200px;border:1px solid #ecf0f1;padding:5px 0;border-top:none;background:#FFF;margin-left:-1px;-moz-box-shadow:rgba(0,0,0,0.1) 0 2px 3px;-webkit-box-shadow:rgba(0,0,0,0.1) 0 2px 3px;box-shadow:rgba(0,0,0,0.1) 0 2px 3px}.trumbowyg-dropdown button{ display:block;width:100%;height:35px;line-height:35px;text-decoration:none;background:#FFF;padding:0 14px;color:#333;border:none;cursor:pointer;text-align:left;font-size:15px;-moz-transition:all 0.15s;-o-transition:all 0.15s;-webkit-transition:all 0.15s;transition:all 0.15s}.trumbowyg-dropdown button:hover,.trumbowyg-dropdown button:focus{ background:#ecf0f1}.trumbowyg-modal{ position:absolute;top:0;left:50%;margin-left:-260px;width:520px;height:290px;overflow:hidden}.trumbowyg-modal-box{ position:absolute;top:0;left:50%;margin-left:-250px;width:400px;padding: 10px 10px 35px 30px;z-index:1;background-color:#FFF;text-align:center;-moz-box-shadow:rgba(0,0,0,0.2) 0 2px 3px;-webkit-box-shadow:rgba(0,0,0,0.2) 0 2px 3px;box-shadow:rgba(0,0,0,0.2) 0 2px 3px}.trumbowyg-modal-box .trumbowyg-modal-title{ font-size:24px;font-weight:bold;margin:0 0 20px;padding:15px 0 13px;display:block;border-bottom:1px solid #EEE;color:#333;background:#fbfcfc}.trumbowyg-modal-box .trumbowyg-progress{ width:80%;background:#F00;height:3px;position:absolute;top:58px}.trumbowyg-modal-box .trumbowyg-progress .trumbowyg-progress-bar{ background:#2BC06A;height:100%;-moz-transition:width 0.15s linear;-o-transition:width 0.15s linear;-webkit-transition:width 0.15s linear;transition:width 0.15s linear}.trumbowyg-modal-box input,input[type=text]{ width:100%;}.trumbowyg-modal-box label{ display:block;position:relative;margin:15px 12px;height:27px;line-height:27px;overflow:hidden}.trumbowyg-modal-box label .trumbowyg-input-infos{ display:block;text-align:left;height:25px;line-height:25px;-moz-transition:all 0.15s;-o-transition:all 0.15s;-webkit-transition:all 0.15s;transition:all 0.15s}.trumbowyg-modal-box label .trumbowyg-input-infos span{ display:block;color:#859fa5;background-color:#fbfcfc;border:1px solid #DEDEDE;padding:0 2%;width:19.5%}.trumbowyg-modal-box label .trumbowyg-input-infos span.trumbowyg-msg-error{ color:#e74c3c}.trumbowyg-modal-box label.trumbowyg-input-error input,.trumbowyg-modal-box label.trumbowyg-input-error textarea{ border:1px solid #e74c3c}.trumbowyg-modal-box label.trumbowyg-input-error .trumbowyg-input-infos{ margin-top:-27px}.trumbowyg-modal-box label input{ position:absolute;top:0;right:20px;height:25px;line-height:25px;border:1px solid #DEDEDE;background:transparent;width:72%;padding:0 2%;margin:0 0 0 23%;-moz-transition:all 0.15s;-o-transition:all 0.15s;-webkit-transition:all 0.15s;transition:all 0.15s}.trumbowyg-modal-box label input:hover,.trumbowyg-modal-box label input:focus{ outline:none;border:1px solid #95a5a6}.trumbowyg-modal-box label input:focus{ background:rgba(230,230,255,0.1)}.trumbowyg-modal-box .error{ margin-top:25px;display:block;color:red}.trumbowyg-modal-box .trumbowyg-modal-button{ position:absolute;bottom:10px;right:0;text-decoration:none;color:#FFF;display:block;width:70px; height:35px;line-height:33px;margin:0 10px;background-color:#333;border:none;border-top:none;cursor:pointer;font-family:"Trebuchet MS", Helvetica, Verdana, sans-serif;-moz-transition:all 0.15s;-o-transition:all 0.15s;-webkit-transition:all 0.15s;transition:all 0.15s;margin-right: 100px;}.trumbowyg-modal-box .trumbowyg-modal-button.trumbowyg-modal-submit{ right:110px;background:#2bc06a}.trumbowyg-modal-box .trumbowyg-modal-button.trumbowyg-modal-submit:hover,.trumbowyg-modal-box .trumbowyg-modal-button.trumbowyg-modal-submit:focus{ background:#40d47e;outline:none}.trumbowyg-modal-box .trumbowyg-modal-button.trumbowyg-modal-submit:active{ background:#25a25a}.trumbowyg-modal-box .trumbowyg-modal-button.trumbowyg-modal-reset{ background:#b33528}.trumbowyg-modal-box .trumbowyg-modal-button.trumbowyg-modal-reset:hover,.trumbowyg-modal-box .trumbowyg-modal-button.trumbowyg-modal-reset:focus{ background:#d14233;outline:none}.trumbowyg-modal-box .trumbowyg-modal-button.trumbowyg-modal-reset:active{ background:#962d22}.trumbowyg-overlay{ position:absolute;background-color:rgba(255,255,255,0.5);width:100%;left:0;display:none}.trumbowyg-fullscreen.trumbowyg-box,.trumbowyg-fullscreen .editor{ border:none}.trumbowyg-fullscreen .trumbowyg-overlay{ height:100% !important}.trumbowyg-editor object,.trumbowyg-editor embed,.trumbowyg-editor video,.trumbowyg-editor img{ max-width:100%}.trumbowyg-editor video,.trumbowyg-editor img{ cursor:move}.trumbowyg-editor.trumbowyg-reset-css{ background:#FEFEFE !important;font-family:"Trebuchet MS", Helvetica, Verdana, sans-serif !important;font-size:14px !important;line-height:1.45em !important;white-space:normal !important;color:#333}.trumbowyg-editor.trumbowyg-reset-css a{ color:#15c !important;text-decoration:underline !important}.trumbowyg-editor.trumbowyg-reset-css div,.trumbowyg-editor.trumbowyg-reset-css p,.trumbowyg-editor.trumbowyg-reset-css ul,.trumbowyg-editor.trumbowyg-reset-css ol,.trumbowyg-editor.trumbowyg-reset-css blockquote{ box-shadow:none !important;background:none !important;margin:0 !important;margin-bottom:15px !important;line-height:1.4em !important;font-family:"Trebuchet MS", Helvetica, Verdana, sans-serif !important;font-size:14px !important;border:none}.trumbowyg-editor.trumbowyg-reset-css iframe,.trumbowyg-editor.trumbowyg-reset-css object,.trumbowyg-editor.trumbowyg-reset-css hr{ margin-bottom:15px !important}.trumbowyg-editor.trumbowyg-reset-css blockquote{ margin-left:32px !important;font-style:italic !important;color:#555}.trumbowyg-editor.trumbowyg-reset-css ul,.trumbowyg-editor.trumbowyg-reset-css ol{ padding-left:20px !important}.trumbowyg-editor.trumbowyg-reset-css ul ul,.trumbowyg-editor.trumbowyg-reset-css ol ol,.trumbowyg-editor.trumbowyg-reset-css ul ol,.trumbowyg-editor.trumbowyg-reset-css ol ul{ border:none;margin:2px !important;padding:0 !important;padding-left:24px !important}.trumbowyg-editor.trumbowyg-reset-css hr{ display:block;height:1px;border:none;border-top:1px solid #CCC}.trumbowyg-editor.trumbowyg-reset-css h1,.trumbowyg-editor.trumbowyg-reset-css h2,.trumbowyg-editor.trumbowyg-reset-css h3,.trumbowyg-editor.trumbowyg-reset-css h4{ color:#111;background:none;margin:0 !important;padding:0 !important;font-weight:bold}.trumbowyg-editor.trumbowyg-reset-css h1{ font-size:32px !important;line-height:38px !important;margin-bottom:20px !important}.trumbowyg-editor.trumbowyg-reset-css h2{ font-size:26px !important;line-height:34px !important;margin-bottom:15px !important}.trumbowyg-editor.trumbowyg-reset-css h3{ font-size:22px !important;line-height:28px !important;margin-bottom:7px !important}.trumbowyg-editor.trumbowyg-reset-css h4{ font-size:16px !important;line-height:22px !important;margin-bottom:7px !important}.trumbowyg-button-pane li button{ display:block;position:relative;text-indent:-9999px;width:35px;height:35px;overflow:hidden;background:transparent url('icons-sa75ce98b2b.png') no-repeat;border:none;cursor:pointer;-moz-transition:all 0.15s;-o-transition:all 0.15s;-webkit-transition:all 0.15s;transition:all 0.15s;transition:background-color .15s, background-image .15s, opacity .15s}.trumbowyg-button-pane li button.trumbowyg-viewHTML-button{ background-position:5px -545px}.trumbowyg-button-pane li button.trumbowyg-formatting-button{ background-position:5px -120px}.trumbowyg-button-pane li button.trumbowyg-bold-button,.trumbowyg-button-pane li button.trumbowyg-strong-button{ background-position:5px -45px}.trumbowyg-button-pane li button.trumbowyg-italic-button,.trumbowyg-button-pane li button.trumbowyg-em-button{ background-position:5px -270px}.trumbowyg-button-pane li button.trumbowyg-underline-button{ background-position:5px -470px}.trumbowyg-button-pane li button.trumbowyg-strikethrough-button,.trumbowyg-button-pane li button.trumbowyg-del-button{ background-position:5px -445px}.trumbowyg-button-pane li button.trumbowyg-link-button{ background-position:5px -345px}.trumbowyg-button-pane li button.trumbowyg-insertImage-button{ background-position:5px -245px}.trumbowyg-button-pane li button.trumbowyg-justifyLeft-button{ background-position:5px -320px}.trumbowyg-button-pane li button.trumbowyg-justifyCenter-button{ background-position:5px -70px}.trumbowyg-button-pane li button.trumbowyg-justifyRight-button{ background-position:5px -395px}.trumbowyg-button-pane li button.trumbowyg-justifyFull-button{ background-position:5px -295px}.trumbowyg-button-pane li button.trumbowyg-unorderedList-button{ background-position:5px -495px}.trumbowyg-button-pane li button.trumbowyg-orderedList-button{ background-position:5px -370px}.trumbowyg-button-pane li button.trumbowyg-horizontalRule-button{ background-position:5px -220px}.trumbowyg-button-pane li button.trumbowyg-fullscreen-button{ background-position:5px -170px}.trumbowyg-button-pane li button.trumbowyg-close-button{ background-position:5px -95px}.trumbowyg-fullscreen .trumbowyg-button-pane li button.trumbowyg-fullscreen-button{ background-position:5px -145px}.trumbowyg-button-pane li:first-child button{ margin-left:6px}.trumbowyg-button-pane li:last-child button{ margin-right:6px}.trumbowyg-fr .trumbowyg-button-pane li button.trumbowyg-bold-button,.trumbowyg-fr .trumbowyg-button-pane li button.trumbowyg-strong-button{ background-position:5px -195px}.trumbowyg-fr .trumbowyg-button-pane li button.trumbowyg-underline-button{ background-position:5px -420px}.trumbowyg-fr .trumbowyg-button-pane li button.trumbowyg-strikethrough-button,.trumbowyg-fr .trumbowyg-button-pane li button.trumbowyg-del-button{ background-position:5px -20px}@media only screen and (-webkit-min-device-pixel-ratio: 1.3), only screen and (min--moz-device-pixel-ratio: 1.3), only screen and (-o-min-device-pixel-ratio: 4 / 3), only screen and (min-device-pixel-ratio: 1.3), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx){ .trumbowyg-button-pane li button{background-size:72%;background-image:url('../images/icons-2x-s9034954e6d.png')}.trumbowyg-button-pane li button.trumbowyg-viewHTML-button{ background-position:5px -545px}.trumbowyg-button-pane li button.trumbowyg-formatting-button{ background-position:5px -120px}.trumbowyg-button-pane li button.trumbowyg-bold-button,.trumbowyg-button-pane li button.trumbowyg-strong-button{ background-position:5px -45px}.trumbowyg-button-pane li button.trumbowyg-italic-button,.trumbowyg-button-pane li button.trumbowyg-em-button{ background-position:5px -270px}.trumbowyg-button-pane li button.trumbowyg-underline-button{ background-position:5px -470px}.trumbowyg-button-pane li button.trumbowyg-strikethrough-button,.trumbowyg-button-pane li button.trumbowyg-del-button{ background-position:5px -445px}.trumbowyg-button-pane li button.trumbowyg-link-button{ background-position:5px -345px}.trumbowyg-button-pane li button.trumbowyg-insertImage-button{ background-position:5px -245px}.trumbowyg-button-pane li button.trumbowyg-justifyLeft-button{ background-position:5px -320px}.trumbowyg-button-pane li button.trumbowyg-justifyCenter-button{ background-position:5px -70px}.trumbowyg-button-pane li button.trumbowyg-justifyRight-button{ background-position:5px -395px}.trumbowyg-button-pane li button.trumbowyg-justifyFull-button{ background-position:5px -295px}.trumbowyg-button-pane li button.trumbowyg-unorderedList-button{ background-position:5px -495px}.trumbowyg-button-pane li button.trumbowyg-orderedList-button{ background-position:5px -370px}.trumbowyg-button-pane li button.trumbowyg-horizontalRule-button{ background-position:5px -220px}.trumbowyg-button-pane li button.trumbowyg-fullscreen-button{ background-position:5px -170px}.trumbowyg-button-pane li button.trumbowyg-close-button{ background-position:5px -95px}.trumbowyg-fullscreen .trumbowyg-button-pane li a.trumbowyg-fullscreen-button{ background-position:5px -145px}.trumbowyg-fr .trumbowyg-button-pane li button.trumbowyg-bold-button,.trumbowyg-fr .trumbowyg-button-pane li button.trumbowyg-strong-button{ background-position:5px -195px}.trumbowyg-fr .trumbowyg-button-pane li button.trumbowyg-underline-button{ background-position:5px -420px}.trumbowyg-fr .trumbowyg-button-pane li button.trumbowyg-strikethrough-button,.trumbowyg-fr .trumbowyg-button-pane li button.trumbowyg-del-button{ background-position:5px -20px}}html, body { margin: 0;padding: 0;}header { text-align: center;}#main { max-width: 960px;margin: 0 auto;}
trumbowyg.js
/* =========================================================== * trumbowyg.js v1.0 * Core code of Trumbowyg plugin * http://alex-d.github.com/Trumbowyg * =========================================================== * Author : Alexandre Demode (Alex-D) * Twitter : @AlexandreDemode * Website : alex-d.fr */$.trumbowyg = { langs: { en: { viewHTML: "View HTML", formatting: "Formatting", p: "Paragraph", blockquote: "Quote", code: "Code", header: "Header", bold: "Bold", italic: "Italic", strikethrough: "Stroke", underline: "Underline", strong: "Strong", em: "Emphasis", del: "Deleted", unorderedList: "Unordered list", orderedList: "Ordered list", insertImage: "Insert Image", insertVideo: "Insert Video", link: "Link", createLink: "Insert link", unlink: "Remove link", justifyLeft: "Align Left", justifyCenter: "Align Center", justifyRight: "Align Right", justifyFull: "Align Justify", horizontalRule: "Insert horizontal rule", fullscreen: "fullscreen", close: "Close", submit: "Confirm", reset: "Cancel", invalidUrl: "Invalid URL", required: "Required", description: "Description", title: "Title", text: "Text" } }, // User default options opts: {}, btnsGrps: { design: ['bold', 'italic', 'underline', 'strikethrough'], semantic: ['strong', 'em', 'del'], justify: ['justifyLeft', 'justifyCenter', 'justifyRight', 'justifyFull'], lists: ['unorderedList', 'orderedList'] }};(function($){ $.fn.trumbowyg = function(opts, params){ if($.isObject(opts) || opts == null){ return this.each(function(){ if(!$(this).data('trumbowyg')) $(this).data('trumbowyg', new Trumbowyg(this, opts)); }); } else if(this.length == 1){ try { var t = $(this).data('trumbowyg'); switch(opts){ // Modal box case 'openModal': return t.openModal(params.title, params.content); case 'closeModal': return t.closeModal(); case 'openModalInsert': return t.openModalInsert(params.title, params.fields, params.callback); // Selection case 'saveSelection': return t.saveSelection(); case 'getSelection': return t.selection; case 'getSelectedText': return t.selection+''; case 'restoreSelection': return t.restoreSelection(); // Destroy case 'destroy': return t.destroy(); // Empty case 'empty': return t.empty(); // Public options case 'lang': return t.lang; case 'duration': return t.o.duration; // HTML case 'html': return t.html(params); } } catch(e){} } return false; }; var Trumbowyg = function(editorElem, opts){ // jQuery object of the editor this.$e = $(editorElem); this.$creator = $(editorElem); // Extend with options opts = $.extend(true, {}, opts, $.trumbowyg.opts); // Localization management if(typeof opts.lang === 'undefined' || typeof $.trumbowyg.langs[opts.lang] === 'undefined') this.lang = $.trumbowyg.langs['en']; else this.lang = $.extend(true, {}, $.trumbowyg.langs['en'], $.trumbowyg.langs[opts.lang]); // Defaults Options this.o = $.extend(true, { lang: 'en', dir: 'ltr', duration: 200, // Duration of modal box animations mobile: false, tablet: true, closable: false, fullscreenable: true, fixedBtnPane: false, fixedFullWidth: false, semantic: false, resetCss: false, autogrow: false, prefix: 'trumbowyg-', convertLink: true, btns: ['viewHTML', '|', 'formatting', '|', $.trumbowyg.btnsGrps.design, '|', 'link', '|', 'insertImage', '|', $.trumbowyg.btnsGrps.justify, '|', $.trumbowyg.btnsGrps.lists, '|', 'horizontalRule'], btnsAdd: [], /** * When the button is associated to a empty object * func and title attributs are defined from the button key value * * For example * foo: {} * is equivalent to : * foo: { * func: 'foo', * title: this.lang.foo * } */ btnsDef: { viewHTML: { func: 'toggle' }, p: { func: 'formatBlock' }, blockquote: { func: 'formatBlock' }, h1: { func: 'formatBlock', title: this.lang.header + ' 1' }, h2: { func: 'formatBlock', title: this.lang.header + ' 2' }, h3: { func: 'formatBlock', title: this.lang.header + ' 3' }, h4: { func: 'formatBlock', title: this.lang.header + ' 4' }, bold: {}, italic: {}, underline: {}, strikethrough: {}, strong: { func: 'bold' }, em: { func: 'italic' }, del: { func: 'strikethrough' }, createLink: {}, unlink: {}, insertImage: {}, justifyLeft: {}, justifyCenter: {}, justifyRight: {}, justifyFull: {}, unorderedList: { func: 'insertUnorderedList' }, orderedList: { func: 'insertOrderedList' }, horizontalRule: { func: 'insertHorizontalRule' }, // Dropdowns formatting: { dropdown: ['p', 'blockquote', 'h1', 'h2', 'h3', 'h4'] }, link: { dropdown: ['createLink', 'unlink'] } } }, opts); if(this.o.semantic && !opts.btns) this.o.btns = [ 'viewHTML', '|', 'formatting', '|', $.trumbowyg.btnsGrps.semantic, '|', 'link', '|', 'insertImage', '|', $.trumbowyg.btnsGrps.justify, '|', $.trumbowyg.btnsGrps.lists, '|', 'horizontalRule' ]; else if(opts && opts.btns) this.o.btns = opts.btns; this.init(); } Trumbowyg.prototype = { init: function(){ this.height = this.$e.css('height'); if(this.isEnabled()){ this.buildEditor(true); return; } this.buildEditor(); this.buildBtnPane(); this.fixedBtnPaneEvents(); this.buildOverlay(); }, buildEditor: function(disable){ if(disable === true){ if(!this.$e.is('textarea')){ var textarea = this.buildTextarea().val(this.$e.val()); this.$e.hide().after(textarea); } return; } this.$box = $(' ', { 'class': this.o.prefix + 'box ' + this.o.prefix + this.o.lang + ' trumbowyg' }); this.isTextarea = true; if(this.$e.is('textarea')) this.$editor = $(' '); else { this.$editor = this.$e; this.$e = this.buildTextarea().val(this.$e.val()); this.isTextarea = false; } this.$e.hide() .addClass(this.o.prefix + 'textarea'); var html = ''; if(this.isTextarea){ html = this.$e.val(); this.$box.insertAfter(this.$e) .append(this.$editor) .append(this.$e); } else { html = this.$editor.html(); this.$box.insertAfter(this.$editor) .append(this.$e) .append(this.$editor); this.syncCode(); } this.$editor.addClass(this.o.prefix + 'editor') .attr('contenteditable', true) .attr('dir', this.o.dir) .html(html); if(this.o.resetCss) this.$editor.addClass(this.o.prefix + 'reset-css'); if(!this.o.autogrow){ $.each([this.$editor, this.$e], $.proxy(function(i, $el){ $el.css({ overflow: 'auto' }); }, this)); } if(this.o.semantic){ this.$editor.html( this.$editor.html() .replace("", "") .replace("&nsbp;", "") ); this.semanticCode(); } var that = this; this.$editor .on('dblclick', 'img', function(){ var $img = $(this); that.openModalInsert(that.lang.insertImage, { url: { label: 'URL', value: $img.attr('src'), required: true }, alt: { label: 'description', value: $img.attr('alt') } }, function(values){ $img.attr('src', values['url']); $img.attr('alt', values['alt']); }); return false; }) .on('keyup', function(e){ that.semanticCode(false, e.which === 13); }) .on('blur', function(){ that.syncCode(); }); }, // Build the Textarea which contain HTML generated code buildTextarea: function(){ return $('', { 'name': this.$e.attr('id'), 'height': this.height }); }, // Build button pane, use o.btns and o.btnsAdd options buildBtnPane: function(){ var t = this; if(t.o.btns === false) return; var pfx = t.o.prefix; t.$btnPane = $('
semanticCode: function(force, full){ this.syncCode(force); if(this.o.semantic){ this.semanticTag('b', 'strong'); this.semanticTag('i', 'em'); this.semanticTag('strike', 'del'); if(full){ // Wrap text nodes in p this.$editor.contents() .filter(function(){ // Only non-empty text nodes return this.nodeType === 3 && $.trim(this.nodeValue).length > 0; }).wrap('
').end() // Remove all br .filter("br").remove(); this.saveSelection(); this.semanticTag('div', 'p'); this.restoreSelection(); } this.$e.val(this.$editor.html()); } }, semanticTag: function(oldTag, newTag){ $(oldTag, this.$editor).each(function(){ $(this).replaceWith(function(){ return '<'+newTag+'>' + $(this).html() + ' '; }); }); }, // Function call when user click on « Insert Link » createLink: function(){ var that = this; this.saveSelection(); this.openModalInsert(this.lang.createLink, { url: { label: 'URL', value: 'http://', required: true }, title: { label: this.lang.title, value: this.selection }, text: { label: this.lang.text, value: this.selection } }, function(values){ that.execCommand('createLink', values['url']); var link = $(['a[href="', values['url'], '"]:not([title])'].join(''), that.$box); if($.trim(values['text']).length !== 0) link.text(values['text']); if($.trim(values['title']).length !== 0) link.attr('title', values['title']); return true; }); }, insertImage: function(){ //图片上传 var that = this; this.saveSelection(); this.openModalInsert(this.lang.insertImage, { url: { label: 'URL', value: '', required: true }, alt: { label: 'description', value: this.selection } }, function(values){ that.execCommand('insertImage', values['url']); $(['img[src="', values['url'], '"]:not([alt])'].join(''), that.$box).attr('alt', values['alt']); return true; }); }, /* * Call method of trumbowyg if exist * else try to call anonymous function * and finaly native execCommand */ execCommand: function(cmd, param){ if(cmd != 'dropdown') this.$editor.focus(); try { this[cmd](param); } catch(e){ try { cmd(param, this); } catch(e){ this.$editor.focus(); if(cmd == 'insertHorizontalRule') param = null; document.execCommand(cmd, false, param); } } this.syncCode(); }, formatBlock: function(param){ if($.browser.msie) param = '<' + param + '>'; document.execCommand('formatBlock', false, param); }, // Open a modal box openModal: function(title, content){ var pfx = this.o.prefix; // No open a modal box when exist other modal box if($('.' + pfx + 'modal-box', this.$box).size() > 0) return false; this.saveSelection(); this.showOverlay(); // Disable all btnPane btns this.$btnPane.addClass(pfx + 'disable'); $('.' + pfx + 'not-disable', this.$btnPane) .not('.' + pfx + 'buttons-right') .removeClass(pfx + 'not-disable') .addClass(pfx + 'not-disable-old'); // Build out of ModalBox, it's the mask for animations var $modal = $(' ', { 'class': pfx + 'modal ' + pfx + 'fixed-top' }).css({ top: (parseInt(this.$btnPane.css('height')) + 1) + 'px' }).appendTo(this.$box); // Click on overflay close modal by cancelling them this.$overlay.one('click', function(e){ e.preventDefault(); $modal.trigger(pfx + 'cancel'); }); $e = this.$editor; // Build the form $form = $('
trumbowyg.upload.js
/* =========================================================== * trumbowyg.upload.js v1.0 * Upload plugin for Trumbowyg * http://alex-d.github.com/Trumbowyg * =========================================================== * Author : Alexandre Demode (Alex-D) * Twitter : @AlexandreDemode * Website : alex-d.fr */(function($){ addXhrProgressEvent(); $.extend(true, $.trumbowyg, { upload: { serverPath: urlcore + '/file/upload/batch' }, opts: { btnsDef: { upload: { func: function(params, tbw){ var file, pfx = tbw.o.prefix; var $modal = tbw.openModalInsert( // Title tbw.lang['upload'], // Fields { file: { type: 'file', required: true }, alt: { label: 'description' } }, // Callback function(values, fields){ var data = new FormData(); data.append('files', file); if($('.' + pfx +'progress', $modal).length == 0) $('.' + pfx + 'modal-title', $modal) .after( $(' ', { 'class': pfx +'progress' }) .append( $(' ', { 'class': pfx +'progress-bar' }) ) ); $.ajax({ url: $.trumbowyg.upload.serverPath, type: 'POST', data: data, cache: false, dataType: 'json', processData: false, contentType: false, progressUpload: function(e){ $('.' + pfx + 'progress').html( ' '+ parseInt(e.loaded * 100 / e.total) + '%' ); }, success: function(data){ if (data.success == true) { for(var i in data.data){ tbw.execCommand('insertImage', data.data[i]); } setTimeout(function(){ tbw.closeModal(); }, 250); } else { tbw.addErrorOnModalField( $('input[type=file]', $modal), tbw.lang[data.message] ); } }, error: function(data){ tbw.addErrorOnModalField( $('input[type=file]', $modal), tbw.lang['uploadError'] ); } }); } ); $('input[type=file]').on('change', function(e){ file = e.target.files[0]; }); } } } } }); function addXhrProgressEvent(){ var originalXhr = $.ajaxSettings.xhr; $.ajaxSetup({ xhr: function() { var req = originalXhr(), that = this; if(req && typeof req.upload == "object" && that.progressUpload !== undefined) req.upload.addEventListener("progress", function(e){ that.progressUpload(e); }, false); return req; } }); }})(jQuery);
附件下载地址(包含图标和js):