diff --git a/README.md b/README.md index 7c5f18c..1a1f0b7 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,7 @@ $('#some-element').editable({ lineBreaks : true, // Whether or not to convert \n to
(default true) toggleFontSize : true, // Whether or not it should be possible to change font size (default true), closeOnEnter : false, // Whether or not pressing the enter key should close the editor (default false) + closeOnEsc : true, // Whether or not pressing the escape key should close the editor (default false) event : 'click', // The event that triggers the editor (default dblclick) tinyMCE : false, // Integrate with tinyMCE by settings this option to true or an object containing your tinyMCE configuration emptyMessage : 'Please write something.', // HTML that will be added to the editable element in case it gets empty (default false) diff --git a/jquery.editable.js b/jquery.editable.js index 406b3db..62befd6 100644 --- a/jquery.editable.js +++ b/jquery.editable.js @@ -1,385 +1,226 @@ -/* -* jQuery plugin that makes elements editable -* -* @author Victor Jonsson (http://victorjonsson.se/) -* @website https://github.com/victorjonsson/jquery-editable/ -* @license GPLv2 http://www.gnu.org/licenses/gpl-2.0.html -* @version 1.3.6.dev -* @donations http://victorjonsson.se/donations/ -*/ -(function($, window) { - - 'use strict'; - - var $win = $(window), // Reference to window - - // Reference to textarea - $textArea = false, - - // Reference to currently edit element - $currentlyEdited = false, - - // Some constants - EVENT_ATTR = 'data-edit-event', - IS_EDITING_ATTR = 'data-is-editing', - EMPTY_ATTR = 'data-is-empty', - DBL_TAP_EVENT = 'dbltap', - SUPPORTS_TOUCH = 'ontouchend' in window, - TINYMCE_INSTALLED = 'tinyMCE' in window && typeof window.tinyMCE.init == 'function', - - // reference to old is function - oldjQueryIs = $.fn.is, - - /* - * Function responsible of triggering double tap event - */ - lastTap = 0, - tapper = function() { - var now = new Date().getTime(); - if( (now-lastTap) < 250 ) { - $(this).trigger(DBL_TAP_EVENT); - } - lastTap = now; - }, - - /** - * Event listener that largens font size - */ - keyHandler = function(e) { - if( e.keyCode == 13 && e.data.closeOnEnter ) { - $currentlyEdited.editable('close'); - } - else if( e.keyCode == 27 ) { - $textArea.val($currentlyEdited.attr('orig-text')); - $currentlyEdited.editable('close'); - } - else if( e.data.toggleFontSize && (e.metaKey && (e.keyCode == 38 || e.keyCode == 40)) ) { - var fontSize = parseInt($textArea.css('font-size'), 10); - fontSize += e.keyCode == 40 ? -1 : 1; - $textArea.css('font-size', fontSize+'px'); - return false; - } - }, - - /** - * Adjusts the height of the textarea to remove scroll - * @todo This way of doing it does not make the textarea smaller when the number of text lines gets smaller - */ - adjustTextAreaHeight = function() { - if( $textArea[0].scrollHeight !== parseInt($textArea.attr('data-scroll'), 10) ) { - $textArea.css('height', $textArea[0].scrollHeight +'px'); - $textArea.attr('data-scroll', $textArea[0].scrollHeight); - } - }, - - /** - * @param {jQuery} $el - * @param {String} newText - */ - resetElement = function($el, newText, emptyMessage) { - $el.removeAttr(IS_EDITING_ATTR); - - if (newText.length == 0 && emptyMessage) { - $el.html(emptyMessage); - $el.attr(EMPTY_ATTR, 'empty'); - } else { - $el.html( newText ); - $el.removeAttr(EMPTY_ATTR); - } - $textArea.remove(); - }, - - - /** - * Function creating editor - */ - elementEditor = function($el, opts) { - - if( $el.is(':editing') ) - return; - - $currentlyEdited = $el; - $el.attr(IS_EDITING_ATTR, '1'); - - if ($el.is(':empty')) { - $el.removeAttr(EMPTY_ATTR); - $el.html(''); - } - - var defaultText = $.trim( $el.html() ), - defaultFontSize = $el.css('font-size'), - elementHeight = $el.height(), - textareaStyle = 'width: 96%; padding:0; margin:0; border:0; background:none;'+ - 'font-family: '+$el.css('font-family')+'; font-size: '+$el.css('font-size')+';'+ - 'font-weight: '+$el.css('font-weight')+';'; - - $el.attr('orig-text', defaultText); - if( opts.lineBreaks ) { - defaultText = defaultText.replace(//g, '\n'); - } - - $textArea = $(''); - $el.text(''); - - if( navigator.userAgent.match(/webkit/i) !== null ) { - textareaStyle = document.defaultView.getComputedStyle($el.get(0), "").cssText; - } - - // The editor should always be static - textareaStyle += 'position: static'; - - /* - TINYMCE EDITOR - */ - if( opts.tinyMCE !== false ) { - var id = 'editable-area-'+(new Date().getTime()); - $textArea - .val(defaultText) - .appendTo($el) - .attr('id', id); - - if( typeof opts.tinyMCE != 'object' ) - opts.tinyMCE = {}; - - opts.tinyMCE.mode = 'exact'; - opts.tinyMCE.elements = id; - opts.tinyMCE.width = $el.innerWidth(); - opts.tinyMCE.height = $el.height() + 200; - opts.tinyMCE.theme_advanced_resize_vertical = true; - - opts.tinyMCE.setup = function (ed) { - ed.onInit.add(function(editor, evt) { - var editorWindow = editor.getWin(); - var hasPressedKey = false; - var editorBlur = function() { - - var newText = $(editor.getDoc()).find('body').html(); - if( $(newText).get(0).nodeName == $el.get(0).nodeName ) { - newText = $(newText).html(); - } - - // Update element and remove editor - resetElement($el, newText, opts.emptyMessage); - editor.remove(); - $textArea = false; - $win.unbind('click', editorBlur); - $currentlyEdited = false; - - // Run callback - if( typeof opts.callback == 'function' ) { - opts.callback({ - content : newText == defaultText || !hasPressedKey ? false : newText, - fontSize : false, - $el : $el - }); - } - }; - - // Blur editor when user clicks outside the editor - setTimeout(function() { - $win.bind('click', editorBlur); - }, 500); - - // Create a dummy textarea that will called upon when - // programmatically interacting with the editor - $textArea = $(''); - $textArea.bind('blur', editorBlur); - - editorWindow.onkeydown = function() { - hasPressedKey = true; - }; - - editorWindow.focus(); - }); - }; - - tinyMCE.init(opts.tinyMCE); - } - - /* - TEXTAREA EDITOR - */ - else { - - if( opts.toggleFontSize || opts.closeOnEnter ) { - $win.bind('keydown', opts, keyHandler); - } - $win.bind('keyup', adjustTextAreaHeight); - - $textArea - .val(defaultText) - .blur(function() { - - $currentlyEdited = false; - - // Get new text and font size - var newText = $.trim( $textArea.val() ), - newFontSize = $textArea.css('font-size'); - if( opts.lineBreaks ) { - newText = newText.replace(new RegExp('\n','g'), '
'); - } - - // Update element - resetElement($el, newText, opts.emptyMessage); - if( newFontSize != defaultFontSize ) { - $el.css('font-size', newFontSize); - } - - // remove textarea and size toggles - $win.unbind('keydown', keyHandler); - $win.unbind('keyup', adjustTextAreaHeight); - - // Run callback - if( typeof opts.callback == 'function' ) { - opts.callback({ - content : newText == defaultText ? false : newText, - fontSize : newFontSize == defaultFontSize ? false : newFontSize, - $el : $el - }); - } - }) - .attr('style', textareaStyle) - .appendTo($el) - .css({ - margin: 0, - padding: 0, - height : elementHeight +'px', - overflow : 'hidden' - }) - .css(opts.editorStyle) - .focus() - .get(0).select(); - - adjustTextAreaHeight(); - - } - - $el.trigger('edit', [$textArea]); - }, - - /** - * Event listener - */ - editEvent = function(event) { - - if( $currentlyEdited !== false && !$currentlyEdited.children("textarea").is(clickedElement)) { - // Not closing the currently open editor before opening a new - // editor makes things go crazy - $currentlyEdited.editable('close'); - elementEditor($(this), event.data); - } - else { - elementEditor($(this), event.data); - } - return false; - }; - - /** - * Jquery plugin that makes elments editable - * @param {Object|String} [opts] Either callback function or the string 'destroy' if wanting to remove the editor event - * @return {jQuery|Boolean} - */ - $.fn.editable = function(opts) { - - if(typeof opts == 'string') { - - if( this.is(':editable') ) { - - switch (opts) { - case 'open': - if( !this.is(':editing') ) { - this.trigger(this.attr(EVENT_ATTR)); - } - break; - case 'close': - if( this.is(':editing') ) { - $textArea.trigger('blur'); - } - break; - case 'destroy': - if( this.is(':editing') ) { - $textArea.trigger('blur'); - } - this.unbind(this.attr(EVENT_ATTR)); - this.removeAttr(EVENT_ATTR); - break; - default: - console.warn('Unknown command "'+opts+'" for jquery.editable'); - } - - } else { - console.error('Calling .editable() on an element that is not editable, call .editable() first'); - } - } - else { - - if( this.is(':editable') ) { - console.warn('Making an already editable element editable, call .editable("destroy") first'); - this.editable('destroy'); - } - - opts = $.extend({ - event : 'dblclick', - touch : true, - lineBreaks : true, - toggleFontSize : true, - closeOnEnter : false, - emptyMessage : false, - tinyMCE : false, - editorStyle : {} - }, opts); - - if( opts.tinyMCE !== false && !TINYMCE_INSTALLED ) { - console.warn('Trying to use tinyMCE as editor but id does not seem to be installed'); - opts.tinyMCE = false; - } - - if( SUPPORTS_TOUCH && opts.touch ) { - opts.event = DBL_TAP_EVENT; - this.unbind('touchend', tapper); - this.bind('touchend', tapper); - } - else { - opts.event += '.textEditor'; - } - - this.bind(opts.event, opts, editEvent); - this.attr(EVENT_ATTR, opts.event); - - // If it is empty to start with, apply the empty message - if (this.html().length == 0 && opts.emptyMessage) { - this.html(opts.emptyMessage); - this.attr(EMPTY_ATTR, 'empty'); - } else { - this.removeAttr(EMPTY_ATTR); - } - } - - return this; - }; - - /** - * Add :editable :editing to $.is() - * @param {Object} statement - * @return {*} - */ - $.fn.is = function(statement) { - if( typeof statement == 'string' && statement.indexOf(':') === 0) { - if( statement == ':editable' ) { - return this.attr(EVENT_ATTR) !== undefined; - } else if( statement == ':editing' ) { - return this.attr(IS_EDITING_ATTR) !== undefined; - } else if( statement == ':empty' ) { - return this.attr(EMPTY_ATTR) !== undefined; - } - } - return oldjQueryIs.apply(this, arguments); - }; - - // The latest element clicked - var clickedElement; - $(document).mousedown(function(e) { - clickedElement = $(e.target); - }); - -})(jQuery, window); +/* + * jQuery plugin that makes elements editable + * + * @author Victor Jonsson (http://victorjonsson.se/) + * @website https://github.com/victorjonsson/jquery-editable/ + * @license GPLv2 http://www.gnu.org/licenses/gpl-2.0.html + * @version 1.3.5 + * @donations http://victorjonsson.se/donations/ + */ (function ($, window) { + "use strict"; + var $win = $(window), + $textArea = false, + $currentlyEdited = false, + EVENT_ATTR = "data-edit-event", + IS_EDITING_ATTR = "data-is-editing", + EMPTY_ATTR = "data-is-empty", + DBL_TAP_EVENT = "dbltap", + SUPPORTS_TOUCH = "ontouchend" in window, + TINYMCE_INSTALLED = "tinyMCE" in window && typeof window.tinyMCE.init == "function", + oldjQueryIs = $.fn.is, + lastTap = 0, + tapper = function () { + var now = new Date().getTime(); + if (now - lastTap < 250) { + $(this).trigger(DBL_TAP_EVENT); + } + lastTap = now; + }, + keyHandler = function (e) { + if ((e.keyCode == 13 && e.data.closeOnEnter) || (e.keyCode == 27 && e.data.closeOnEsc)) { + $currentlyEdited.editable("close"); + } else if (e.data.toggleFontSize && e.metaKey && (e.keyCode == 38 || e.keyCode == 40)) { + var fontSize = parseInt($textArea.css("font-size"), 10); + fontSize += e.keyCode == 40 ? -1 : 1; + $textArea.css("font-size", fontSize + "px"); + return false; + } + }, + adjustTextAreaHeight = function () { + if ($textArea[0].scrollHeight !== parseInt($textArea.attr("data-scroll"), 10)) { + $textArea.css("height", $textArea[0].scrollHeight + "px"); + $textArea.attr("data-scroll", $textArea[0].scrollHeight); + } + }, + resetElement = function ($el, newText, emptyMessage) { + $el.removeAttr(IS_EDITING_ATTR); + if (newText.length == 0 && emptyMessage) { + $el.html(emptyMessage); + $el.attr(EMPTY_ATTR, "empty"); + } else { + $el.html(newText); + $el.removeAttr(EMPTY_ATTR); + } + $textArea.remove(); + }, + elementEditor = function ($el, opts) { + if ($el.is(":editing")) return; + $currentlyEdited = $el; + $el.attr(IS_EDITING_ATTR, "1"); + if ($el.is(":empty")) { + $el.removeAttr(EMPTY_ATTR); + $el.html(""); + } + var defaultText = $.trim($el.html()), + defaultFontSize = $el.css("font-size"), + elementHeight = $el.height(), + textareaStyle = "width: 96%; padding:0; margin:0; border:0; background:none;" + "font-family: " + $el.css("font-family") + "; font-size: " + $el.css("font-size") + ";" + "font-weight: " + $el.css("font-weight") + ";"; + if (opts.lineBreaks) { + defaultText = defaultText.replace(//g, "\n"); + } + $textArea = $(""); + $el.text(""); + if (navigator.userAgent.match(/webkit/i) !== null) { + textareaStyle = document.defaultView.getComputedStyle($el.get(0), "").cssText; + } + textareaStyle += "position: static"; + if (opts.tinyMCE !== false) { + var id = "editable-area-" + new Date().getTime(); + $textArea.val(defaultText).appendTo($el).attr("id", id); + if (typeof opts.tinyMCE != "object") opts.tinyMCE = {}; + opts.tinyMCE.mode = "exact"; + opts.tinyMCE.elements = id; + opts.tinyMCE.width = $el.innerWidth(); + opts.tinyMCE.height = $el.height() + 200; + opts.tinyMCE.theme_advanced_resize_vertical = true; + opts.tinyMCE.setup = function (ed) { + ed.onInit.add(function (editor, evt) { + var editorWindow = editor.getWin(); + var hasPressedKey = false; + var editorBlur = function () { + var newText = $(editor.getDoc()).find("body").html(); + if ($(newText).get(0).nodeName == $el.get(0).nodeName) { + newText = $(newText).html(); + } + resetElement($el, newText, opts.emptyMessage); + editor.remove(); + $textArea = false; + $win.unbind("click", editorBlur); + $currentlyEdited = false; + if (typeof opts.callback == "function") { + opts.callback({ content: newText == defaultText || !hasPressedKey ? false : newText, fontSize: false, $el: $el }); + } + }; + setTimeout(function () { + $win.bind("click", editorBlur); + }, 500); + $textArea = $(""); + $textArea.bind("blur", editorBlur); + editorWindow.onkeydown = function () { + hasPressedKey = true; + }; + editorWindow.focus(); + }); + }; + tinyMCE.init(opts.tinyMCE); + } else { + if (opts.toggleFontSize || opts.closeOnEnter) { + $win.bind("keydown", opts, keyHandler); + } + $win.bind("keyup", adjustTextAreaHeight); + $textArea + .val(defaultText) + .blur(function () { + $currentlyEdited = false; + var newText = $.trim($textArea.val()), + newFontSize = $textArea.css("font-size"); + if (opts.lineBreaks) { + newText = newText.replace(new RegExp("\n", "g"), "
"); + } + resetElement($el, newText, opts.emptyMessage); + if (newFontSize != defaultFontSize) { + $el.css("font-size", newFontSize); + } + $win.unbind("keydown", keyHandler); + $win.unbind("keyup", adjustTextAreaHeight); + if (typeof opts.callback == "function") { + opts.callback({ content: newText == defaultText ? false : newText, fontSize: newFontSize == defaultFontSize ? false : newFontSize, $el: $el }); + } + }) + .attr("style", textareaStyle) + .appendTo($el) + .css({ margin: 0, padding: 0, height: elementHeight + "px", overflow: "hidden" }) + .focus() + .get(0) + .select(); + adjustTextAreaHeight(); + } + $el.trigger("edit", [$textArea]); + }, + editEvent = function (event) { + if ($currentlyEdited !== false) { + $currentlyEdited.editable("close"); + elementEditor($(this), event.data); + } else { + elementEditor($(this), event.data); + } + return false; + }; + $.fn.editable = function (opts) { + if (typeof opts == "string") { + if (this.is(":editable")) { + switch (opts) { + case "open": + if (!this.is(":editing")) { + this.trigger(this.attr(EVENT_ATTR)); + } + break; + case "close": + if (this.is(":editing")) { + $textArea.trigger("blur"); + } + break; + case "destroy": + if (this.is(":editing")) { + $textArea.trigger("blur"); + } + this.unbind(this.attr(EVENT_ATTR)); + this.removeAttr(EVENT_ATTR); + break; + default: + console.warn('Unknown command "' + opts + '" for jquery.editable'); + } + } else { + console.error("Calling .editable() on an element that is not editable, call .editable() first"); + } + } else { + if (this.is(":editable")) { + console.warn('Making an already editable element editable, call .editable("destroy") first'); + this.editable("destroy"); + } + opts = $.extend({ event: "dblclick", touch: true, lineBreaks: true, toggleFontSize: true, closeOnEnter: false, closeOnEsc: true, emptyMessage: false, tinyMCE: false }, opts); + if (opts.tinyMCE !== false && !TINYMCE_INSTALLED) { + console.warn("Trying to use tinyMCE as editor but id does not seem to be installed"); + opts.tinyMCE = false; + } + if (SUPPORTS_TOUCH && opts.touch) { + opts.event = DBL_TAP_EVENT; + this.unbind("touchend", tapper); + this.bind("touchend", tapper); + } else { + opts.event += ".textEditor"; + } + this.bind(opts.event, opts, editEvent); + this.attr(EVENT_ATTR, opts.event); + if (this.html().length == 0 && opts.emptyMessage) { + this.html(opts.emptyMessage); + this.attr(EMPTY_ATTR, "empty"); + } else { + this.removeAttr(EMPTY_ATTR); + } + } + return this; + }; + $.fn.is = function (statement) { + if (typeof statement == "string" && statement.indexOf(":") === 0) { + if (statement == ":editable") { + return this.attr(EVENT_ATTR) !== undefined; + } else if (statement == ":editing") { + return this.attr(IS_EDITING_ATTR) !== undefined; + } else if (statement == ":empty") { + return this.attr(EMPTY_ATTR) !== undefined; + } + } + return oldjQueryIs.apply(this, arguments); + }; +})(jQuery, window); diff --git a/jquery.editable.min.js b/jquery.editable.min.js index 71eb9d7..7202fe1 100644 --- a/jquery.editable.min.js +++ b/jquery.editable.min.js @@ -1,9 +1,9 @@ -/* -* jQuery plugin that makes elements editable -* -* @author Victor Jonsson (http://victorjonsson.se/) -* @website https://github.com/victorjonsson/jquery-editable/ -* @license GPLv2 http://www.gnu.org/licenses/gpl-2.0.html -* @version 1.3.5 -* @donations http://victorjonsson.se/donations/ -*/(function($,window){"use strict";var $win=$(window),$textArea=false,$currentlyEdited=false,EVENT_ATTR="data-edit-event",IS_EDITING_ATTR="data-is-editing",EMPTY_ATTR="data-is-empty",DBL_TAP_EVENT="dbltap",SUPPORTS_TOUCH="ontouchend"in window,TINYMCE_INSTALLED="tinyMCE"in window&&typeof window.tinyMCE.init=="function",oldjQueryIs=$.fn.is,lastTap=0,tapper=function(){var now=(new Date).getTime();if(now-lastTap<250){$(this).trigger(DBL_TAP_EVENT)}lastTap=now},keyHandler=function(e){if(e.keyCode==13&&e.data.closeOnEnter){$currentlyEdited.editable("close")}else if(e.data.toggleFontSize&&e.metaKey&&(e.keyCode==38||e.keyCode==40)){var fontSize=parseInt($textArea.css("font-size"),10);fontSize+=e.keyCode==40?-1:1;$textArea.css("font-size",fontSize+"px");return false}},adjustTextAreaHeight=function(){if($textArea[0].scrollHeight!==parseInt($textArea.attr("data-scroll"),10)){$textArea.css("height",$textArea[0].scrollHeight+"px");$textArea.attr("data-scroll",$textArea[0].scrollHeight)}},resetElement=function($el,newText,emptyMessage){$el.removeAttr(IS_EDITING_ATTR);if(newText.length==0&&emptyMessage){$el.html(emptyMessage);$el.attr(EMPTY_ATTR,"empty")}else{$el.html(newText);$el.removeAttr(EMPTY_ATTR)}$textArea.remove()},elementEditor=function($el,opts){if($el.is(":editing"))return;$currentlyEdited=$el;$el.attr(IS_EDITING_ATTR,"1");if($el.is(":empty")){$el.removeAttr(EMPTY_ATTR);$el.html("")}var defaultText=$.trim($el.html()),defaultFontSize=$el.css("font-size"),elementHeight=$el.height(),textareaStyle="width: 96%; padding:0; margin:0; border:0; background:none;"+"font-family: "+$el.css("font-family")+"; font-size: "+$el.css("font-size")+";"+"font-weight: "+$el.css("font-weight")+";";if(opts.lineBreaks){defaultText=defaultText.replace(//g,"\n")}$textArea=$("");$el.text("");if(navigator.userAgent.match(/webkit/i)!==null){textareaStyle=document.defaultView.getComputedStyle($el.get(0),"").cssText}textareaStyle+="position: static";if(opts.tinyMCE!==false){var id="editable-area-"+(new Date).getTime();$textArea.val(defaultText).appendTo($el).attr("id",id);if(typeof opts.tinyMCE!="object")opts.tinyMCE={};opts.tinyMCE.mode="exact";opts.tinyMCE.elements=id;opts.tinyMCE.width=$el.innerWidth();opts.tinyMCE.height=$el.height()+200;opts.tinyMCE.theme_advanced_resize_vertical=true;opts.tinyMCE.setup=function(ed){ed.onInit.add(function(editor,evt){var editorWindow=editor.getWin();var hasPressedKey=false;var editorBlur=function(){var newText=$(editor.getDoc()).find("body").html();if($(newText).get(0).nodeName==$el.get(0).nodeName){newText=$(newText).html()}resetElement($el,newText,opts.emptyMessage);editor.remove();$textArea=false;$win.unbind("click",editorBlur);$currentlyEdited=false;if(typeof opts.callback=="function"){opts.callback({content:newText==defaultText||!hasPressedKey?false:newText,fontSize:false,$el:$el})}};setTimeout(function(){$win.bind("click",editorBlur)},500);$textArea=$("");$textArea.bind("blur",editorBlur);editorWindow.onkeydown=function(){hasPressedKey=true};editorWindow.focus()})};tinyMCE.init(opts.tinyMCE)}else{if(opts.toggleFontSize||opts.closeOnEnter){$win.bind("keydown",opts,keyHandler)}$win.bind("keyup",adjustTextAreaHeight);$textArea.val(defaultText).blur(function(){$currentlyEdited=false;var newText=$.trim($textArea.val()),newFontSize=$textArea.css("font-size");if(opts.lineBreaks){newText=newText.replace(new RegExp("\n","g"),"
")}resetElement($el,newText,opts.emptyMessage);if(newFontSize!=defaultFontSize){$el.css("font-size",newFontSize)}$win.unbind("keydown",keyHandler);$win.unbind("keyup",adjustTextAreaHeight);if(typeof opts.callback=="function"){opts.callback({content:newText==defaultText?false:newText,fontSize:newFontSize==defaultFontSize?false:newFontSize,$el:$el})}}).attr("style",textareaStyle).appendTo($el).css({margin:0,padding:0,height:elementHeight+"px",overflow:"hidden"}).focus().get(0).select();adjustTextAreaHeight()}$el.trigger("edit",[$textArea])},editEvent=function(event){if($currentlyEdited!==false){$currentlyEdited.editable("close");elementEditor($(this),event.data)}else{elementEditor($(this),event.data)}return false};$.fn.editable=function(opts){if(typeof opts=="string"){if(this.is(":editable")){switch(opts){case"open":if(!this.is(":editing")){this.trigger(this.attr(EVENT_ATTR))}break;case"close":if(this.is(":editing")){$textArea.trigger("blur")}break;case"destroy":if(this.is(":editing")){$textArea.trigger("blur")}this.unbind(this.attr(EVENT_ATTR));this.removeAttr(EVENT_ATTR);break;default:console.warn('Unknown command "'+opts+'" for jquery.editable')}}else{console.error("Calling .editable() on an element that is not editable, call .editable() first")}}else{if(this.is(":editable")){console.warn('Making an already editable element editable, call .editable("destroy") first');this.editable("destroy")}opts=$.extend({event:"dblclick",touch:true,lineBreaks:true,toggleFontSize:true,closeOnEnter:false,emptyMessage:false,tinyMCE:false},opts);if(opts.tinyMCE!==false&&!TINYMCE_INSTALLED){console.warn("Trying to use tinyMCE as editor but id does not seem to be installed");opts.tinyMCE=false}if(SUPPORTS_TOUCH&&opts.touch){opts.event=DBL_TAP_EVENT;this.unbind("touchend",tapper);this.bind("touchend",tapper)}else{opts.event+=".textEditor"}this.bind(opts.event,opts,editEvent);this.attr(EVENT_ATTR,opts.event);if(this.html().length==0&&opts.emptyMessage){this.html(opts.emptyMessage);this.attr(EMPTY_ATTR,"empty")}else{this.removeAttr(EMPTY_ATTR)}}return this};$.fn.is=function(statement){if(typeof statement=="string"&&statement.indexOf(":")===0){if(statement==":editable"){return this.attr(EVENT_ATTR)!==undefined}else if(statement==":editing"){return this.attr(IS_EDITING_ATTR)!==undefined}else if(statement==":empty"){return this.attr(EMPTY_ATTR)!==undefined}}return oldjQueryIs.apply(this,arguments)}})(jQuery,window); +/* + * jQuery plugin that makes elements editable + * + * @author Victor Jonsson (http://victorjonsson.se/) + * @website https://github.com/victorjonsson/jquery-editable/ + * @license GPLv2 http://www.gnu.org/licenses/gpl-2.0.html + * @version 1.3.5 + * @donations http://victorjonsson.se/donations/ + */!function(l,t){"use strict";function e(){var t=(new Date).getTime();t-p<250&&l(this).trigger(o),p=t}function a(t){if(13==t.keyCode&&t.data.closeOnEnter||27==t.keyCode&&t.data.closeOnEsc)f.editable("close");else if(t.data.toggleFontSize&&t.metaKey&&(38==t.keyCode||40==t.keyCode)){var e=parseInt(g.css("font-size"),10);return e+=40==t.keyCode?-1:1,g.css("font-size",e+"px"),!1}}function d(){g[0].scrollHeight!==parseInt(g.attr("data-scroll"),10)&&(g.css("height",g[0].scrollHeight+"px"),g.attr("data-scroll",g[0].scrollHeight))}function c(t,e,i){t.removeAttr(u),0==e.length&&i?(t.html(i),t.attr(y,"empty")):(t.html(e),t.removeAttr(y)),g.remove()}function i(s,o){var r,i,t,e,n;s.is(":editing")||((f=s).attr(u,"1"),s.is(":empty")&&(s.removeAttr(y),s.html("")),r=l.trim(s.html()),i=s.css("font-size"),t=s.height(),e="width: 96%; padding:0; margin:0; border:0; background:none;font-family: "+s.css("font-family")+"; font-size: "+s.css("font-size")+";font-weight: "+s.css("font-weight")+";",o.lineBreaks&&(r=r.replace(//g,"\n")),g=l(""),s.text(""),null!==navigator.userAgent.match(/webkit/i)&&(e=document.defaultView.getComputedStyle(s.get(0),"").cssText),e+="position: static",!1!==o.tinyMCE?(n="editable-area-"+(new Date).getTime(),g.val(r).appendTo(s).attr("id",n),"object"!=typeof o.tinyMCE&&(o.tinyMCE={}),o.tinyMCE.mode="exact",o.tinyMCE.elements=n,o.tinyMCE.width=s.innerWidth(),o.tinyMCE.height=s.height()+200,o.tinyMCE.theme_advanced_resize_vertical=!0,o.tinyMCE.setup=function(t){t.onInit.add(function(e,t){var i=e.getWin(),n=!1,a=function(){var t=l(e.getDoc()).find("body").html();l(t).get(0).nodeName==s.get(0).nodeName&&(t=l(t).html()),c(s,t,o.emptyMessage),e.remove(),g=!1,h.unbind("click",a),f=!1,"function"==typeof o.callback&&o.callback({content:!(t==r||!n)&&t,fontSize:!1,$el:s})};setTimeout(function(){h.bind("click",a)},500),(g=l("")).bind("blur",a),i.onkeydown=function(){n=!0},i.focus()})},tinyMCE.init(o.tinyMCE)):((o.toggleFontSize||o.closeOnEnter)&&h.bind("keydown",o,a),h.bind("keyup",d),g.val(r).blur(function(){f=!1;var t=l.trim(g.val()),e=g.css("font-size");o.lineBreaks&&(t=t.replace(new RegExp("\n","g"),"
")),c(s,t,o.emptyMessage),e!=i&&s.css("font-size",e),h.unbind("keydown",a),h.unbind("keyup",d),"function"==typeof o.callback&&o.callback({content:t!=r&&t,fontSize:e!=i&&e,$el:s})}).attr("style",e).appendTo(s).css({margin:0,padding:0,height:t+"px",overflow:"hidden"}).focus().get(0).select(),d()),s.trigger("edit",[g]))}function n(t){return!1!==f&&f.editable("close"),i(l(this),t.data),!1}var h=l(t),g=!1,f=!1,s="data-edit-event",u="data-is-editing",y="data-is-empty",o="dbltap",r="ontouchend"in t,b="tinyMCE"in t&&"function"==typeof t.tinyMCE.init,m=l.fn.is,p=0;l.fn.editable=function(t){if("string"==typeof t)if(this.is(":editable"))switch(t){case"open":this.is(":editing")||this.trigger(this.attr(s));break;case"close":this.is(":editing")&&g.trigger("blur");break;case"destroy":this.is(":editing")&&g.trigger("blur"),this.unbind(this.attr(s)),this.removeAttr(s);break;default:console.warn('Unknown command "'+t+'" for jquery.editable')}else console.error("Calling .editable() on an element that is not editable, call .editable() first");else this.is(":editable")&&(console.warn('Making an already editable element editable, call .editable("destroy") first'),this.editable("destroy")),!1===(t=l.extend({event:"dblclick",touch:!0,lineBreaks:!0,toggleFontSize:!0,closeOnEnter:!1,closeOnEsc:!0,emptyMessage:!1,tinyMCE:!1},t)).tinyMCE||b||(console.warn("Trying to use tinyMCE as editor but id does not seem to be installed"),t.tinyMCE=!1),r&&t.touch?(t.event=o,this.unbind("touchend",e),this.bind("touchend",e)):t.event+=".textEditor",this.bind(t.event,t,n),this.attr(s,t.event),0==this.html().length&&t.emptyMessage?(this.html(t.emptyMessage),this.attr(y,"empty")):this.removeAttr(y);return this},l.fn.is=function(t){if("string"==typeof t&&0===t.indexOf(":")){if(":editable"==t)return void 0!==this.attr(s);if(":editing"==t)return void 0!==this.attr(u);if(":empty"==t)return void 0!==this.attr(y)}return m.apply(this,arguments)}}(jQuery,window); \ No newline at end of file