/
home2
/
cecillin
/
public_html
/
turnweb
/
public
/
framework
/
scripts
/
DHtexteditor
/
Upload File
HOME
/*! * DHtexteditor, based on (but not really compatible with): * jQuery TE 1.4.0 , http://jqueryte.com/ * Copyright (C) 2013, Fatih Koca (fattih@fattih.com), (http://jqueryte.com/about) * jQuery TE is provided under the MIT LICENSE. */ jQuery.fn.selectText = function(){ var doc = document; var element = this[0]; if (doc.body.createTextRange) { var range = document.body.createTextRange(); range.moveToElementText(element); range.select(); } else if (window.getSelection) { var selection = window.getSelection(); var range = document.createRange(); range.selectNodeContents(element); selection.removeAllRanges(); selection.addRange(range); } }; (function($){ $.fn.jqte = function(options) { // default text formats var formats = [["p","Normal"],["h1","Headline"],["h3","Subhead"],["h6","Note"], ["h5","Single-Space"]]; // default link-type names var linktypes = ["Web","Email"]; var vars = $.extend({ // options 'upload_url' : "/DHtexteditor/upload/", 'status' : true, 'css' : "jqte", 'title' : true, 'button' : "Ok", 'format' : true, 'formats' : formats, 'linktypes' : linktypes, 'u' : true, 'ol' : true, 'ul' : true, 'sub' : true, 'sup' : true, 'outdent' : true, 'indent' : true, 'strike' : true, 'link' : true, 'unlink' : true, 'remove' : false, 'rule' : true, 'source' : true, 'br' : false, 'p' : false, // events 'change' : "", 'focus' : "", 'blur' : "" }, options); // methods $.fn.jqteVal = function(value) { $(this).closest("."+vars.css).find("."+vars.css+"_editor").html(value); } // browser information is received var thisBrowser = navigator.userAgent.toLowerCase(); // if browser is ie and it version is 7 or even older, close title property if (/msie [1-7]./.test(thisBrowser)) vars.title = false; var buttons = []; // insertion function for parameters to toolbar function addButton(id,title,command,key,keylabel,tag,emphasis) { return buttons.push({id:id, title:title, command:command, key:key, keylabel:keylabel, tag:tag, emphasis:emphasis}); }; // add parameters for toolbar buttons // id title command key keylabel tag emphasis addButton('format', 'Fotmats', 'formats', '', '', '', false); addButton('b', 'Bold', 'Bold', 'B', 'B', ["b","strong"], true); addButton('i', 'Italic', 'Italic', 'I', 'I', ["i","em"], true); addButton('u', 'Underline', 'Underline', 'U', 'U', ["u"], true); addButton('ol', 'Ordered List', 'insertorderedlist', '', '.', ["ol"], true); addButton('ul', 'Unordered List', 'insertunorderedlist', '', ',', ["ul"], true); addButton('sub', 'Subscript', 'subscript', '(', 'down arrow', ["sub"], true); addButton('sup', 'Superscript', 'superscript', '&', 'up arrow', ["sup"], true); addButton('indent', 'Indent', 'indent', '\'', 'right arrow', ["blockquote"], true); addButton('outdent','Outdent', 'outdent', '%', 'left arrow', ["blockquote"], false); addButton('strike', 'Strike Through', 'strikeThrough', 'K', 'K', ["strike"], true); addButton('photo', 'Upload Photo', 'uploadphoto', '', '', '', true); addButton('link', 'Add Link', 'linkcreator', 'L', 'L', ["a"], true); addButton('unlink', 'Remove Link', 'unlink', '', '', ["a"], false); addButton('rule', 'Horizontal Rule', 'inserthorizontalrule', 'H', 'H', '', false); addButton('source', 'Source Code', 'displaysource', '', '', '', false); return this.each(function() { if (!$(this).data("jqte") || $(this).data("jqte")==null || $(this).data("jqte")=="undefined") { $(this).data("jqte",true); } else { $(this).data("jqte",false); } // is the status false of the editor if (!vars.status || !$(this).data("jqte")) { // if wanting the false status later if ($(this).closest("."+vars.css).length>0) { var editorValue = $(this).closest("."+vars.css).find("."+vars.css+"_editor").html(); var thisElementAttrs = ""; $($(this)[0].attributes).each(function() { if (this.nodeName!="style") thisElementAttrs = thisElementAttrs+" "+this.nodeName+'="'+this.nodeValue+'"'; }); var thisElementTag = $(this).is("[data-origin]") && $(this).attr("data-origin")!="" ? $(this).attr("data-origin") : "textarea"; var createValue = '>'+editorValue; // the contents of this element // if this element is input or option if (thisElementTag=="input" || thisElementTag=="option") { // encode special html characters editorValue = editorValue.replace(/"/g,'"').replace(/'/g,''').replace(/</g,'<').replace(/>/g,'>'); createValue = 'value="'+editorValue+'">'; // the value of this element } var thisClone = $(this).clone(); $(this).data("jqte",false).closest("."+vars.css).before(thisClone).remove(); thisClone.replaceWith('<'+ thisElementTag + thisElementAttrs + createValue + '</'+thisElementTag+'>'); } return; } // element will converted to the jqte editor var thisElement = $(this); // if starting with blank form, add P tags if (thisElement.html() == '') { thisElement.html('<p><br></p>'); } // tag name of the element var thisElementTag = $(this).prop('tagName').toLowerCase(); // tag name of origin $(this).attr("data-origin",thisElementTag); // contents of the element var thisElementVal = $(this).is("[value]") || thisElementTag == "textarea" ? $(this).val() : $(this).html(); // decode special html characters thisElementVal = thisElementVal.replace(/"/g,'"').replace(/'/g,"'").replace(/</g,'<').replace(/>/g,'>').replace(/&/g,'&'); // start jqte editor to after the element $(this).after('<div class="'+vars.css+'"></div>'); // jqte var jQTE = $(this).next('.'+vars.css); // insert toolbar in jqte editor jQTE.html('<div class="'+vars.css+"_toolbar"+'" role="toolbar" unselectable></div><div class="'+vars.css+'_linkform" style="display:none" role="dialog"></div><div class="'+vars.css+"_editor"+'"></div>' + ""); jQTE.after("<iframe id='jqte_iframe' name='jqte_iframe' src=''></iframe>"); jQTE.before("<div id='jqte_file_form_wrapper'><form id='jqte_file_form' enctype='multipart/form-data' method='POST' target='jqte_iframe' action='"+vars.upload_url+"'><input type='file' name='file' id='jqte_file'><input id='jqte_upload_submit' class='button bluebg' type='submit' name='submit' value='Upload'><button id='jqte_upload_cancel' class='button button'>Cancel</button></form></div>"); var toolbar = jQTE.find('.'+vars.css+"_toolbar"); // the toolbar variable var linkform = jQTE.find('.'+vars.css+"_linkform"); // the link-form-area in the toolbar variable var editor = jQTE.find('.'+vars.css+"_editor"); // the text-field of jqte editor var emphasize = vars.css+"_tool_depressed"; // highlight style of the toolbar buttons function stripInlineStyles() { $('blockquote').removeAttr('style'); $('p').removeAttr('style'); } var img_toolbar_html = "<div class='jqte_iedit'><a class='jqte_iedit_b1'></a><a class='jqte_iedit_b2'></a><a class='jqte_iedit_b3'></a><a class='jqte_iedit_b4'></a></div>"; var img_caption_html = "<div class='caption'>(click to add a caption)</div>"; function insert_image(element, img_url, img_width) { if (!element) return false; var img_class = "img2"; if (img_width >= 450) img_class = "img1"; element.before("<div class='"+img_class+"' contenteditable='false'>" + img_toolbar_html + "<img src='" + img_url + "'>" + img_caption_html + "</div>"); editor.trigger('change'); } function apply_img_style_click(style, element) { element.removeClass('img1 img2 img3').addClass('img'+style); editor.trigger('change'); } // Handle event where value of file selector is changed (e.g., upload automatically) $("#jqte_file").change(function() { if ($("#jqte_file").val()) $("#jqte_upload_submit").trigger('click'); }); // Handle form being submitted $("#jqte_file_form").submit(function() { // If the form is already processing, cancel now. if ($('#jqte_upload_submit').hasClass('button_processing')) { return false; } // If no file was selected, don't submit. if (!$("#jqte_file").val()) { show_file_upload_error("Please select a file to upload."); return false; } $('#jqte_upload_submit').addClass('button_processing').val('Uploading...'); }); // Process iframe file upload results $("#jqte_iframe").on('load', function() { $('#jqte_upload_submit').removeClass('button_processing').val('Upload'); $('#jqte_file_form_error').remove(); var result = jQuery.parseJSON( $(frames['jqte_iframe'].document).text() ); if (result.error) { show_file_upload_error(result.error); } else if (result.img) { insert_image( get_current_editor_node(), result.img, result.width ); $('#jqte_file_form_wrapper').fadeOut('fast', function() { $('#jqte_file').val(''); }); } }); // Handle file upload cancel click $('#jqte_upload_cancel').on('click', function() { $('#jqte_file_form_wrapper').fadeOut('fast', function() { $('#jqte_file').val(''); $('#jqte_file_form_error').remove(); }); return false; }); // Show file upload error function show_file_upload_error(message) { $('#jqte_file_form_error').remove(); $('#jqte_file_form_wrapper').fadeIn('fast'); $('#jqte_file').before("<div id='jqte_file_form_error'>"+message+"</div>"); } // Get selected node from editor or get first node in editor function get_current_editor_node() { var current_node = getSelectedNode(); // If the selected node is NOT in an editor... if ($(current_node).parents("."+vars.css+"_editor").length < 1) { var this_editor = jQTE.find("."+vars.css+"_editor"); var first_node = $(this_editor).children(":first"); // If there doesn't appear to be a first node in the editor, make one. if (first_node.length < 1) { var filler_node = $('<p><br></p>').appendTo(this_editor); return filler_node; } return first_node; } return current_node; } // Disable drop onto editor area (also prevents photos from being dragged around) editor.bind('dragover drop', function(event){ event.preventDefault(); return false; }); // Handle caption click editor.on('click', '.caption', function() { $(this).attr('contenteditable','true'); if ($(this).html() == '(click to add a caption)') $(this).selectText(); }); // Handle image mouseenter $('.jqte').on('mouseenter', '.img1, .img2, .img3', function() { // Add toolbars to images that do not have them (typically coming from the database) if ($(this).find(">:first-child").get(0).tagName == 'IMG') { $(this).prepend(img_toolbar_html); } // Add caption placeholders to images that don't have them if ($(this).find(">:last-child").get(0).tagName == 'IMG') { $(this).append(img_caption_html); } $(this).children('.jqte_iedit').fadeIn('fast'); }); // Handle image mouseleave $('.jqte').on('mouseleave', '.img1, .img2, .img3', function() { $(this).children('.jqte_iedit').fadeOut('fast'); }); // Handle image mouseenters that do NOT have .imgX div wrapper - and fix. $('.jqte').on('mouseenter', 'img', function() { fix_image_format($(this)); }); function fix_image_format(img) { var thisParent = $(img).parent(); if (!thisParent.hasClass('img1') && !thisParent.hasClass('img2') && !thisParent.hasClass('img3')) { // Remove styles and classes from this image $(img).removeAttr('style').removeClass().removeAttr('width').removeAttr('height'); if (thisParent.is('a')) { // If parent is a link tag $(img).unwrap(); // Remove parent <a> node (but keep img) thisParent = $(img).parent(); // Set new parent } if (thisParent.is('p')) { // If parent is a paragraph tag thisParent.before($(img)); // Move image to BEFORE the current paragraph } // Set default width var imgClass = 'img2'; if ($(img).width() >= 450) imgClass = 'img1'; $(img).wrap("<div class='"+imgClass+"'></div>"); // Wrap imgX div around img $(img).before(img_toolbar_html); // Add img toolbar div $(img).after(img_caption_html); // Add img caption div } } // Handle click for iedit buttons editor.on('click', '.jqte_iedit_b1', function() { apply_img_style_click(1, $(this).parent().parent() ); }); editor.on('click', '.jqte_iedit_b2', function() { apply_img_style_click(2, $(this).parent().parent() ); }); editor.on('click', '.jqte_iedit_b3', function() { apply_img_style_click(3, $(this).parent().parent() ); }); editor.on('click', '.jqte_iedit_b4', function() { $(event.target).parent().parent().remove(); editor.trigger('change'); }); // add to some tools in link form area linkform.append('<div class="'+vars.css+'_linktypeselect" unselectable></div><input class="'+vars.css+'_linkinput" type="text/css" value=""><div class="'+vars.css+'_linkbutton button_small" unselectable>'+vars.button+'</div> <div style="height:1px;float:none;clear:both"></div>'); var linktypeselect = linkform.find("."+vars.css+"_linktypeselect"); // the tool of link-type-selector var linkinput = linkform.find("."+vars.css+"_linkinput"); // the input of insertion link var linkbutton = linkform.find("."+vars.css+"_linkbutton"); // the button of insertion link // add to the link-type-selector sub tool parts linktypeselect.append('<div class="'+vars.css+'_linktypeview" unselectable></div><div class="'+vars.css+'_linktypes" role="menu" unselectable></div>'); var linktypes = linktypeselect.find("."+vars.css+"_linktypes"); // the select box of link types var linktypeview = linktypeselect.find("."+vars.css+"_linktypeview"); // the link type preview var setdatalink = vars.css+"-setlink"; // the selected text add to mark as "link will be added" // create to the source-area editor.after('<div class="'+vars.css+'_source '+vars.css+'_hiddenField"></div>'); var sourceField = jQTE.find("."+vars.css+"_source"); // the source-area variable // move the element to the source-area thisElement.appendTo(sourceField); // if the element isn't a textarea, convert this to textarea if (thisElementTag!="textarea") { // add all attributes of element to new textarea (type and value except) var thisElementAttrs = ""; $(thisElement[0].attributes).each(function(){ if (this.nodeName!="type" && this.nodeName!="value") thisElementAttrs = thisElementAttrs+" "+this.nodeName+'="'+this.nodeValue+'"'; }); // convert the element to textarea thisElement.replaceWith('<textarea '+thisElementAttrs+'>'+thisElementVal+'</textarea>'); // update to variable of thisElement thisElement = sourceField.find("textarea"); } // add feature editable to the text-field ve copy from the element's value to text-field editor.attr("contenteditable","true").html(thisElementVal); // Initially check all existing images for proper format jQTE.find('img').each(function() { fix_image_format($(this)); }); // Clean up pre-defined source html postToSource(); // Make toolbar buttons for (var n = 0; n < buttons.length; n++) { button = buttons[n]; if (button.title) { // create string for hotkey, if applicable var buttonHotkey = button.key.length>0 ? button.keylabel!=null && button.keylabel!="undefined" && button.keylabel!="" ? ' (Ctrl+'+button.keylabel+')' : '' : ''; // create button title (appending hotkey, if applicable) var buttonTitle = button.title!=null && button.title!="undefined" && button.title!="" ? button.title+buttonHotkey : ''; // add this button to the toolbar toolbar.append('<div class="'+vars.css+'_tool '+vars.css+'_tool_'+button.id+'" role="button" data-tool="'+n+'" unselectable><a class="'+vars.css+'_tool_icon" unselectable></a></div>'); // add the parameters to this button toolbar.find('.'+vars.css+'_tool[data-tool="'+n+'"]').data({tag: button.tag, command: button.command, emphasis: button.emphasis, title: buttonTitle}); // format-selector field if(button.id == 'format' && $.isArray(vars.formats)) { // selected text format var toolLabel = vars.formats[0][1].length>0 && vars.formats[0][1]!="undefined" ? vars.formats[0][1] : ""; toolbar.find("."+vars.css+'_tool_'+button.id).find("."+vars.css+"_tool_icon").replaceWith('<a class="'+vars.css+'_tool_label" unselectable><span class="'+vars.css+'_tool_text" unselectable>'+toolLabel+'</span><span class="'+vars.css+'_tool_icon" unselectable></span></a>'); toolbar.find("."+vars.css+'_tool_'+button.id).append('<div class="'+vars.css+'_formats" unselectable></div>'); toolbar.find("."+vars.css+"_formats").data("status",false); for(var f = 0; f < vars.formats.length; f++) { toolbar.find("."+vars.css+"_formats").append('<a '+vars.css+'-formatval="'+ vars.formats[f][0] +'" class="'+vars.css+'_format'+' '+vars.css+'_format_'+f+'" role="menuitem" unselectable>'+ vars.formats[f][1] +'</a>'); } toolbar.find("."+vars.css+"_formats").data("status",false); } } } // the default value of the link-type linktypes.data("linktype","0"); // add link types to link-type-selector for(var n = 0; n <= linktypes.length; n++) { linktypes.append('<a '+vars.css+'-linktype="'+n+'" unselectable>'+vars.linktypes[n]+'</a>'); linktypeview.html('<div class="'+vars.css+'_linktypearrow" unselectable></div><div class="'+vars.css+'_linktypetext">'+linktypes.find('a:eq('+linktypes.data("linktype")+')').text()+'</div>'); } // add the prefix of css according to browser var prefixCss = ""; if (/msie/.test(thisBrowser)) // ie prefixCss = '-ms-'; else if (/chrome/.test(thisBrowser) || /safari/.test(thisBrowser) || /yandex/.test(thisBrowser)) // webkit group (safari, chrome, yandex) prefixCss = '-webkit-'; else if (/mozilla/.test(thisBrowser)) // firefox prefixCss = '-moz-'; else if (/opera/.test(thisBrowser)) // opera prefixCss = '-o-'; else if (/konqueror/.test(thisBrowser)) // konqueror prefixCss = '-khtml-'; else prefixCss = ''; // make unselectable to unselectable attribute ones jQTE.find("[unselectable]") .css(prefixCss+"user-select","none") .addClass("unselectable") .attr("unselectable","on") .on("selectstart mousedown",false); // each button of the toolbar var toolbutton = toolbar.find("."+vars.css+"_tool"); // format menu var formatbar = toolbar.find("."+vars.css+"_formats"); // get the selected text as plain format function selectionGet() { // for webkit, mozilla, opera if (window.getSelection) return window.getSelection(); // for ie else if (document.selection && document.selection.createRange && document.selection.type != "None") return document.selection.createRange(); } // the function of changing to the selected text with "execCommand" method function selectionSet(addCommand,thirdParam) { var range, sel = selectionGet(); // for webkit, mozilla, opera if (window.getSelection) { if (sel.anchorNode && sel.getRangeAt) range = sel.getRangeAt(0); if (range) { sel.removeAllRanges(); sel.addRange(range); } if(!thisBrowser.match(/msie/)) document.execCommand('StyleWithCSS', false, false); document.execCommand(addCommand, false, thirdParam); } // for ie else if (document.selection && document.selection.createRange && document.selection.type != "None") { range = document.selection.createRange(); range.execCommand(addCommand, false, thirdParam); } // change styles to around tags affectStyleAround(false,false); } // the function of changing to the selected text with tags and tags's attributes function replaceSelection(tTag,tAttr,tVal) { // first, prevent to conflict of different jqte editors if (editor.not(":focus")) editor.focus(); // for webkit, mozilla, opera if (window.getSelection) { var selObj = selectionGet(), selRange, newElement, documentFragment; if (selObj.anchorNode && selObj.getRangeAt) { selRange = selObj.getRangeAt(0); // create to new element newElement = document.createElement(tTag); // add the attribute to the new element $(newElement).attr(tAttr,tVal); // extract to the selected text documentFragment = selRange.extractContents(); // add the contents to the new element newElement.appendChild(documentFragment); selRange.insertNode(newElement); selObj.removeAllRanges(); // if the attribute is "style", change styles to around tags if (tAttr=="style") affectStyleAround($(newElement),tVal); // for other attributes else affectStyleAround($(newElement),false); } } // for ie else if (document.selection && document.selection.createRange && document.selection.type != "None") { var range = document.selection.createRange(); var selectedText = range.htmlText; var newText = '<'+tTag+' '+tAttr+'="'+tVal+'">'+selectedText+'</'+tTag+'>'; document.selection.createRange().pasteHTML(newText); } } // the function of getting to the parent tag var getSelectedNode = function() { var node,selection; if (window.getSelection) { selection = getSelection(); node = selection.anchorNode; } if (!node && document.selection && document.selection.createRange && document.selection.type != "None") { selection = document.selection; var range = selection.getRangeAt ? selection.getRangeAt(0) : selection.createRange(); node = range.commonAncestorContainer ? range.commonAncestorContainer : range.parentElement ? range.parentElement() : range.item(0); } if (node) { return (node.nodeName == "#text" ? $(node.parentNode) : $(node)); } else return false; }; // the function of replacement styles to the around tags (parent and child) function affectStyleAround(element,style) { var selectedTag = getSelectedNode(); // the selected node selectedTag = selectedTag ? selectedTag : element; // (for replacement with execCommand) affect to child tags with parent tag's styles if (selectedTag && style==false) { // apply to the selected node with parent tag's styles if (selectedTag.parent().is("[style]")) selectedTag.attr("style",selectedTag.parent().attr("style")); // apply to child tags with parent tag's styles if (selectedTag.is("[style]")) selectedTag.find("*").attr("style",selectedTag.attr("style")); } // (for replacement with html changing method) else if (element && style && element.is("[style]")) { var styleKey = style.split(";"); // split the styles styleKey = styleKey[0].split(":") // get the key of first style feature // apply to child tags with parent tag's styles if (element.is("[style*="+styleKey[0]+"]")) element.find("*").css(styleKey[0],styleKey[1]); // select to the selected node again selectText(element); } } // the function of making selected to a element function selectText(element) { if (element) { var element = element[0]; if (document.body.createTextRange) { var range = document.body.createTextRange(); range.moveToElementText(element); range.select(); } else if (window.getSelection) { var selection = window.getSelection(); var range = document.createRange(); if (element != "undefined" && element != null) { range.selectNodeContents(element); selection.removeAllRanges(); selection.addRange(range); if ($(element).is(":empty")) { $(element).append(" "); selectText($(element)); } } } } } // the function of converting text to link function selected2link() { if (!toolbar.data("sourceOpened")) { var selectedTag = getSelectedNode(); // the selected node var thisHrefLink = "http://"; // default the input value of the link-form-field // display the link-form-field linkAreaSwitch(true); if (selectedTag) { var thisTagName = selectedTag.prop('tagName').toLowerCase(); // if tag name of the selected node is "a" and the selected node have "href" attribute if (thisTagName == "a" && selectedTag.is('[href]')) { thisHrefLink = selectedTag.attr('href'); selectedTag.attr(setdatalink,""); } else // if it doesn't have "a" tag name replaceSelection("a",setdatalink,""); } else { linkinput.val(thisHrefLink).focus(); } // the method of displaying-hiding to link-types linktypeselect.click(function(e) { if ($(e.target).hasClass(vars.css+"_linktypetext") || $(e.target).hasClass(vars.css+"_linktypearrow")) linktypeSwitch(true); }); // the method of selecting to link-types linktypes.find("a").click(function() { var thisLinkType = $(this).attr(vars.css+"-linktype"); linktypes.data("linktype",thisLinkType) linktypeview.find("."+vars.css+"_linktypetext").html(linktypes.find('a:eq('+linktypes.data("linktype")+')').text()); linkInputSet(thisHrefLink); linktypeSwitch(); }); linkInputSet(thisHrefLink); // the method of link-input linkinput // auto focus .focus() // update to value .val(thisHrefLink) // the event of key to enter in link-input .bind("keypress keyup",function(e) { if (e.keyCode==13) { linkRecord(jQTE.find("["+setdatalink+"]")); return false; } }); // the event of click link-button linkbutton.click(function() { linkRecord(jQTE.find("["+setdatalink+"]")); }); } else // hide the link-form-field linkAreaSwitch(false); } function linkRecord(thisSelection) { linkinput.focus(); // focus to link-input selectText(thisSelection); // select to the selected node // remove pre-link attribute (mark as "link will be added") of the selected node thisSelection.removeAttr(setdatalink); // if not selected to link-type of picture if (linktypes.data("linktype")!="2") { selectionSet("createlink",linkinput.val()); // insert link url of link-input to the selected node } linkAreaSwitch(); // hide the link-form-field editor.trigger("change"); // export contents of the text to the sources } // the function of switching link-form-field function linkAreaSwitch(status) { // remove all pre-link attribute (mark as "link will be added") clearSetElement("["+setdatalink+"]:not([href])"); jQTE.find("["+setdatalink+"][href]").removeAttr(setdatalink); if (status) { toolbar.data("linkOpened",true); linkform.show(); } else { toolbar.data("linkOpened",false); linkform.hide(); } linktypeSwitch(); } // the function of switching link-type-selector function linktypeSwitch(status) { if (status) { linktypes.show(); } else { linktypes.hide(); } } // the function of updating the link-input according to the link-type function linkInputSet(thisHrefLink) { var currentType = linktypes.data("linktype"); // if selected type of e-mail if (currentType=="1" && (linkinput.val()=="http://" || linkinput.is("[value^=http://]") || !linkinput.is("[value^=mailto]"))) linkinput.val("mailto:"); else if(currentType!="1" && !linkinput.is("[value^=http://]")) linkinput.val("http://"); else linkinput.val(thisHrefLink); } // the function of adding style to selected text function selected2style(styleCommand) { if(!toolbar.data("sourceOpened")) { // the event of click to style button styleField.find("a").unbind("click").click(function() { var styleValue = $(this).attr(vars.css + "-styleval"); // the property of style value to be added var prevStyles = refuseStyle(styleType); // affect styles to child tags (and extract to the new style attributes) // change to selected text replaceSelection("span","style",styleType+":"+styleValue+";"+prevStyles); $('.'+vars.css+'_title').remove(); // remove title bubbles editor.trigger("change"); // export contents of the text to the sources }); } else { linkAreaSwitch(false); } } // the function of removing all pre-link attribute (mark as "link will be added") function clearSetElement(elem) { jQTE.find(elem).each(function(){ $(this).before($(this).html()).remove(); }); } // the function of refusing some styles function refuseStyle(refStyle) { var selectedTag = getSelectedNode(); // the selected node // if the selected node has attribute of "style" and it has unwanted style if (selectedTag && selectedTag.is("[style]") && selectedTag.css(refStyle)!="") { var refValue = selectedTag.css(refStyle); // first get key of unwanted style selectedTag.css(refStyle,""); // clear unwanted style var cleanStyle = selectedTag.attr("style"); // cleaned style selectedTag.css(refStyle,refValue); // add unwanted style to the selected node again return cleanStyle; // print cleaned style } else return ""; } // the function of adding style to selected text function selected2format() { formatFieldSwitch(true); formatbar.find("a").click(function() { $("*",this).click(function(e) { e.preventDefault(); return false; }); formatLabelView($(this).text()); var formatValue = $(this).attr(vars.css + "-formatval"); // the type of format value selectionSet("formatBlock",'<'+formatValue+'>'); // convert to selected format formatFieldSwitch(false); }); } // the function of switching the style-field function formatFieldSwitch(status) { var thisStatus = status ? true : false; thisStatus = status && formatbar.data("status") ? true : false; if (thisStatus || !status) { formatbar.data("status",false).slideUp(200); } else { formatbar.data("status",true).slideDown(200); } } // change format label function formatLabelView(str) { var formatLabel = formatbar.closest("."+vars.css+"_tool").find("."+vars.css+"_tool_label").find("."+vars.css+"_tool_text"); if (str.length > 10) str = str.substr(0,7) + "..."; formatLabel.html(str); // change format label of button } // the function of insertion a specific form to texts function extractToText(strings) { var $htmlContent, $htmlPattern, $htmlReplace; // first remove to unnecessary gaps $htmlContent = strings.replace(/\n/gim,'').replace(/\r/gim,'').replace(/\t/gim,'').replace(/ /gim,' '); $htmlContent = $htmlContent.replace(/ contenteditable="(false|true)"/ig, ''); // remove contenteditable properties $htmlContent = $htmlContent.replace(/\(click to add a caption\)/i, ''); // remove placeholder caption $htmlContent = $htmlContent.replace(/<div class="caption"><\/div>/i, ''); // remove empty caption div $htmlPattern = [ /\<span(|\s+.*?)>(.*?)<\/span>/gim, // remove spans /\<font(|\s+.*?)>(.*?)<\/font>/gim, // remove <fonts> /<(\w*[^p])\s*[^\/>]*>\s*<\/\1>/gim, // remove empty or white-spaces tags (ignore paragraphs (<p>) and breaks (<br>)) /\<strong(|\s+.*?)>(.*?)\<\/strong>/gim, // convert strong to b /\<em(|\s+.*?)>(.*?)\<\/em>/gim // convert em to i ]; $htmlReplace = [ '$2', '$2', '', '<b$1>$2</b>', '<i$1>$2</i>' ]; for(c=0; c<4; c++) { // Repeat this loop 4 times, to be safe for(var i = 0; i < $htmlPattern.length; i++) { $htmlContent = $htmlContent.replace($htmlPattern[i], $htmlReplace[i]); } } // if break is false (<br>), convert <br> to <p> if(!vars.br) { $htmlPattern = [ /\<br>(.*?)/ig, /\<br\/>(.*?)/ig ]; $htmlReplace = [ '<p>$1</p>', '<p>$1</p>' ]; // create loop as the number of pattern (for breaks) for (var i = 0; i < $htmlPattern.length; i++) { $htmlContent = $htmlContent.replace($htmlPattern[i], $htmlReplace[i]); } } $htmlContent = $htmlContent.replace(/( style=")([^"]*?)"/ig, ''); return $htmlContent; } // the function of exporting contents of the text field to the source field (to be the standard in all browsers) function postToSource() { // Make a new DIV temporarily, remove any editing-only nodes, and copy text as HTML $('body').append("<div id='jqte_tmp' style='display: none; visibility: hidden;'></div>"); $('#jqte_tmp').html( editor.html() ); // Remove line breaks $('#jqte_tmp br').remove(); thisElement.val( extractToText( $('#jqte_tmp').html() ) ); $('#jqte_tmp').remove(); } // the function of exporting contents of the source field to the text field (to be the standard in all browsers) function postToEditor() { editor.html(extractToText(thisElement.val())); } // the function of getting parent (or super parent) tag name of the selected node function detectElement(tags){ var resultdetect=false, $node = getSelectedNode(), parentsTag; if ($node) { $.each(tags, function(i, val){ parentsTag = $node.prop('tagName').toLowerCase(); if (parentsTag == val) { resultdetect = true; } else { $node.parents().each(function(){ parentsTag = $(this).prop('tagName').toLowerCase(); if (parentsTag == val) resultdetect = true; }); } }); return resultdetect; } else return false; }; // the function of highlighting the toolbar buttons according to the cursor position in jqte editor function buttonEmphasize(e) { for (var n = 0; n < buttons.length; n++) { button = buttons[n]; if (button.id && button.emphasis && button.tag!='') { detectElement(button.tag) ? toolbar.find('.'+vars.css+'_tool_'+button.id).addClass(emphasize) : $('.'+vars.css+'_tool_'+button.id).removeClass(emphasize); } } // showing text format if (vars.format && $.isArray(vars.formats)) { var isFoundFormat = false; for (var f = 0; f < vars.formats.length; f++) { var thisFormat = []; thisFormat[0] = vars.formats[f][0]; if (vars.formats[f][0].length>0 && detectElement(thisFormat)) { formatLabelView(vars.formats[f][1]); isFoundFormat = true; break; } } if (!isFoundFormat) formatLabelView(vars.formats[0][1]); } // hide all style-fields formatFieldSwitch(false); } // the event of click to the toolbar buttons toolbutton .unbind("click") .click(function(e){ // if source button is clicked if ($(this).data('command')=='displaysource' && !toolbar.data("sourceOpened")) { // hide all the toolbar buttons (except the source button) toolbar.find("."+vars.css+"_tool").addClass(vars.css+"_hiddenField"); $(this).removeClass(vars.css+"_hiddenField"); // update to data of source displaying toolbar.data("sourceOpened",true); // equalize height of the text field with height of the source field //thisElement.css("height",editor.outerHeight()); sourceField.removeClass(vars.css+"_hiddenField"); editor.addClass(vars.css+"_hiddenField"); thisElement.focus(); linkAreaSwitch(false); // hide the link-form-field formatFieldSwitch(); // hide format field } else { // if source field is closed if (!toolbar.data("sourceOpened")) { // if insert-link-button is clicked if ($(this).data('command')=='linkcreator') { if (!toolbar.data("linkOpened")) { selected2link(); } else { linkAreaSwitch(false); // hide the link-form-field formatFieldSwitch(false); // hide format field } } else if ($(this).data('command')=='formats') { if ($(this).data('command')=='formats' && !$(e.target).hasClass(vars.css+"_format")) { selected2format(); } if (editor.not(":focus")) editor.focus(); } else if ($(this).data('command')=='uploadphoto') { $('#jqte_file').trigger('click'); } else { // first, prevent to conflict of different jqte editors if (editor.not(":focus")) editor.focus(); // apply command of clicked button to the selected text selectionSet($(this).data('command'),null); stripInlineStyles(); // hide all menu-fields formatFieldSwitch(false); linktypeSwitch(); // to highlight the toolbar buttons according to the cursor position in jqte editor $(this).data('emphasis')==true && !$(this).hasClass(emphasize) ? $(this).addClass(emphasize) : $(this).removeClass(emphasize); sourceField.addClass(vars.css+"_hiddenField"); editor.removeClass(vars.css+"_hiddenField"); } } // hide the source field and display the text field else { // update to data of source hiding toolbar.data("sourceOpened",false); // display all the toolbar buttons toolbar.find("."+vars.css+"_tool").removeClass(vars.css+"_hiddenField"); sourceField.addClass(vars.css+"_hiddenField"); editor.removeClass(vars.css+"_hiddenField"); } } // export contents of the text to the sources editor.trigger("change"); }) // the event of showing to the title bubble when mouse over of the toolbar buttons .hover(function(e){ if (vars.title && $(this).data("title")!="" && ( $(e.target).hasClass(vars.css+"_tool") || $(e.target).hasClass(vars.css+"_tool_icon") )) { $('.'+vars.css+'_title').remove(); // create the title bubble jQTE.append('<div class="'+vars.css+'_title"><div class="'+vars.css+'_titleArrow"><div class="'+vars.css+'_titleArrowIcon"></div></div><div class="'+vars.css+'_titleText">'+$(this).data("title")+'</div></div>'); var thisTitle = $('.'+vars.css+'_title:first'); var thisArrow = thisTitle.find('.'+vars.css+'_titleArrowIcon'); var thisPosition = $(this).position(); var thisAlignX = thisPosition.left + $(this).outerWidth() - (thisTitle.outerWidth()/2) - ($(this).outerWidth()/2); var thisAlignY = (thisPosition.top + $(this).outerHeight()); // show the title bubble and set to its position thisTitle.delay(1000).css({'top':thisAlignY, 'left':thisAlignX}).fadeIn(200); } },function(){ $('.'+vars.css+'_title').remove(); }); // prevent multiple calling postToSource() var editorChangeTimer = null; // the methods of the text fields editor // trigger change method of the text field when the text field modified .bind("keydown drop cut paste",function(e) { // export contents of the text to the sources if (!toolbar.data("sourceOpened")) { $(this).trigger("change"); } // hide the link-type-field linktypeSwitch(); // if the change method is added run the change method if ($.isFunction(vars.change)) vars.change(); }) .bind("change",function() { // If editor is totally empty, add a blank P tag here and move cursor to it. if (editor.html().length < 1) { editor.html('<p><br></p>'); selectText(editor.find("p")); } // Remove certain attributes editor.children().removeAttr('data-mce-style'); if (!toolbar.data("sourceOpened")) { clearTimeout(editorChangeTimer); editorChangeTimer = setTimeout(postToSource, 10); } }) // run to keyboard shortcuts .keydown(function(e) { // if ctrl key is clicked if (e.ctrlKey) { // check all toolbar buttons for(var n = 0; n < buttons.length; n++) { // if this settings of this button is activated (is it true) button = buttons[n]; // if the keyed button with ctrl is same of hotkey of this button if (button.id && e.keyCode == button.key.charCodeAt(0)) { if (button.command!='' && button.command!='linkcreator') { selectionSet(button.command,null); } else if(button.command=='linkcreator') { selected2link(); } stripInlineStyles(); return false; } } } }) // method of triggering to the highlight button .bind("mouseup keyup",buttonEmphasize) // the event of focus to the text field .focus(function() { // if the focus method is added run the focus method if($.isFunction(vars.focus)) vars.focus(); // add onfocus class jQTE.addClass(vars.css+"_focused"); // prevent focus problem on opera if(/opera/.test(thisBrowser)) { var range = document.createRange(); range.selectNodeContents(editor[0]); range.collapse(false); var selection = window.getSelection(); selection.removeAllRanges(); selection.addRange(range); } }) // the event of focus out from the text field .focusout(function() { // remove to highlights of all toolbar buttons toolbutton.removeClass(emphasize); // hide all menu-fields formatFieldSwitch(false); linktypeSwitch(); // if the blur method is added run the blur method if($.isFunction(vars.blur)) vars.blur(); // remove onfocus class jQTE.removeClass(vars.css+"_focused"); // show default text format if ($.isArray(vars.formats)) formatLabelView(vars.formats[0][1]); }); // the event of key in the source field thisElement //.bind("keydown keyup",function() { .bind("keydown",function() { // export contents of the source to the text field setTimeout(postToEditor,0); }) .focus(function() { // add onfocus class jQTE.addClass(vars.css+"_focused"); }) .focusout(function() { // remove onfocus class jQTE.removeClass(vars.css+"_focused"); }); }); }; })(jQuery);