diff --git a/devices.php b/devices.php
index 806adb6b1..15c4f43b8 100644
--- a/devices.php
+++ b/devices.php
@@ -1053,7 +1053,7 @@ function buildCustomAttributes($template, $device) {
-
+
diff --git a/scripts/jquery-te-1.4.0.js b/scripts/jquery-te-1.4.0.js
new file mode 100644
index 000000000..43fde0e07
--- /dev/null
+++ b/scripts/jquery-te-1.4.0.js
@@ -0,0 +1,1318 @@
+/*!
+ *
+ * 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.
+ *
+*/
+
+(function($){
+ $.fn.jqte = function(options){
+
+ // default titles of buttons
+ var varsTitle = [
+ {title:"Text Format"},
+ {title:"Font Size"},
+ {title:"Color"},
+ {title:"Bold",hotkey:"B"},
+ {title:"Italic",hotkey:"I"},
+ {title:"Underline",hotkey:"U"},
+ {title:"Ordered List",hotkey:"."},
+ {title:"Unordered List",hotkey:","},
+ {title:"Subscript",hotkey:"down arrow"},
+ {title:"Superscript",hotkey:"up arrow"},
+ {title:"Outdent",hotkey:"left arrow"},
+ {title:"Indent",hotkey:"right arrow"},
+ {title:"Justify Left"},
+ {title:"Justify Center"},
+ {title:"Justify Right"},
+ {title:"Strike Through",hotkey:"K"},
+ {title:"Add Link",hotkey:"L"},
+ {title:"Remove Link"},
+ {title:"Cleaner Style",hotkey:"Delete"},
+ {title:"Horizontal Rule",hotkey:"H"},
+ {title:"Source"}
+ ];
+
+ // default text formats
+ var formats = [["p","Normal"],["h1","Header 1"],["h2","Header 2"],["h3","Header 3"],["h4","Header 4"],["h5","Header 5"],["h6","Header 6"],["pre","Preformatted"]];
+
+ // default font sizes
+ var fsizes = ["10","12","16","18","20","24","28"];
+
+ // default rgb values of colors
+ var colors = [
+ "0,0,0","68,68,68","102,102,102","153,153,153","204,204,204","238,238,238","243,243,243","255,255,255",
+ null,
+ "255,0,0","255,153,0","255,255,0","0,255,0","0,255,255","0,0,255","153,0,255","255,0,255",
+ null,
+ "244,204,204","252,229,205","255,242,204","217,234,211","208,224,227","207,226,243","217,210,233","234,209,220",
+ "234,153,153","249,203,156","255,229,153","182,215,168","162,196,201","159,197,232","180,167,214","213,166,189",
+ "224,102,102","246,178,107","255,217,102","147,196,125","118,165,175","111,168,220","142,124,195","194,123,160",
+ "204,0,0","230,145,56","241,194,50","106,168,79","69,129,142","61,133,198","103,78,167","166,77,121",
+ "153,0,0","180,95,6","191,144,0","56,118,29","19,79,92","11,83,148","53,28,117","116,27,71",
+ "102,0,0","120,63,4","127,96,0","39,78,19","12,52,61","7,55,99","32,18,77","76,17,48"
+ ];
+
+ // default link-type names
+ var linktypes = ["Web Address","E-mail Address","Picture URL"];
+
+ var vars = $.extend({
+ // options
+ 'status' : true,
+ 'css' : "jqte",
+ 'title' : true,
+ 'titletext' : varsTitle,
+ 'button' : "OK",
+ 'format' : true,
+ 'formats' : formats,
+ 'fsize' : true,
+ 'fsizes' : fsizes,
+ 'funit' : "px",
+ 'color' : true,
+ 'linktypes' : linktypes,
+ 'b' : true,
+ 'i' : true,
+ 'u' : true,
+ 'ol' : true,
+ 'ul' : true,
+ 'sub' : true,
+ 'sup' : true,
+ 'outdent' : true,
+ 'indent' : true,
+ 'left' : true,
+ 'center' : true,
+ 'right' : true,
+ 'strike' : true,
+ 'link' : true,
+ 'unlink' : true,
+ 'remove' : true,
+ 'rule' : true,
+ 'source' : true,
+ 'placeholder' : false,
+ 'br' : true,
+ 'p' : true,
+
+ // 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 addParams(name,command,key,tag,emphasis)
+ {
+ var thisCssNo = buttons.length+1;
+ return buttons.push({name:name, cls:thisCssNo, command:command, key:key, tag:tag, emphasis:emphasis});
+ };
+
+ // add parameters for toolbar buttons
+ addParams('format','formats','','',false); // text format button --> no hotkey
+ addParams('fsize','fSize','','',false); // font size button --> no hotkey
+ addParams('color','colors','','',false); // text color button --> no hotkey
+ addParams('b','Bold','B',["b","strong"],true); // bold --> ctrl + b
+ addParams('i','Italic','I',["i","em"],true); // italic --> ctrl + i
+ addParams('u','Underline','U',["u"],true); // underline --> ctrl + u
+ addParams('ol','insertorderedlist','¾',["ol"],true); // ordered list --> ctrl + .(dot)
+ addParams('ul','insertunorderedlist','¼',["ul"],true); // unordered list --> ctrl + ,(comma)
+ addParams('sub','subscript','(',["sub"],true); // sub script --> ctrl + down arrow
+ addParams('sup','superscript','&',["sup"],true); // super script --> ctrl + up arrow
+ addParams('outdent','outdent','%',["blockquote"],false); // outdent --> ctrl + left arrow
+ addParams('indent','indent','\'',["blockquote"],true); // indent --> ctrl + right arrow
+ addParams('left','justifyLeft','','',false); // justify Left --> no hotkey
+ addParams('center','justifyCenter','','',false); // justify center --> no hotkey
+ addParams('right','justifyRight','','',false); // justify right --> no hotkey
+ addParams('strike','strikeThrough','K',["strike"],true); // strike through --> ctrl + K
+ addParams('link','linkcreator','L',["a"],true); // insertion link --> ctrl + L
+ addParams('unlink','unlink','',["a"],false); // remove link --> ctrl + N
+ addParams('remove','removeformat','.','',false); // remove all styles --> ctrl + delete
+ addParams('rule','inserthorizontalrule','H',["hr"],false); // insertion horizontal rule --> ctrl + H
+ addParams('source','displaysource','','',false); // feature of displaying source
+
+ 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();
+
+ // add all attributes of element
+ 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";
+
+ // the contents of this element
+ var createValue = '>'+editorValue;
+
+ // if this element is input or option
+ if(thisElementTag=="input" || thisElementTag=="option")
+ {
+ // encode special html characters
+ editorValue = editorValue.replace(/"/g,'"').replace(/'/g,''').replace(//g,'>');
+
+ // the value of this element
+ createValue = 'value="'+editorValue+'">';
+ }
+
+ 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);
+
+ // 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('
');
+
+ // jqte
+ var jQTE = $(this).next('.'+vars.css);
+
+ // insert toolbar in jqte editor
+ jQTE.html('');
+
+ 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
+
+ // add to some tools in link form area
+ linkform.append('
'+vars.button+'
');
+
+ 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('');
+
+ 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('');
+
+ 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('');
+
+ // 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);
+
+ // insertion the toolbar button
+ for(var n = 0; n < buttons.length; n++)
+ {
+ // if setting of this button is activated (is it true?)
+ if(vars[buttons[n].name])
+ {
+ // if it have a title, add to this button
+ var buttonHotkey = buttons[n].key.length>0 ? vars.titletext[n].hotkey!=null && vars.titletext[n].hotkey!="undefined" && vars.titletext[n].hotkey!="" ? ' (Ctrl+'+vars.titletext[n].hotkey+')' : '' : '';
+ var buttonTitle = vars.titletext[n].title!=null && vars.titletext[n].title!="undefined" && vars.titletext[n].title!="" ? vars.titletext[n].title+buttonHotkey : '';
+
+ // add this button to the toolbar
+ toolbar.append('
');
+
+ // add the parameters to this button
+ toolbar.find('.'+vars.css+'_tool[data-tool='+n+']').data({tag : buttons[n].tag, command : buttons[n].command, emphasis : buttons[n].emphasis, title : buttonTitle});
+
+ // format-selector field
+ if(buttons[n].name=="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_'+buttons[n].cls).find("."+vars.css+"_tool_icon").replaceWith(''+toolLabel+'');
+
+ toolbar.find("."+vars.css+'_tool_'+buttons[n].cls)
+ .append('');
+
+ // add font-sizes to font-size-selector
+ for(var f = 0; f < vars.formats.length; f++)
+ {
+ toolbar.find("."+vars.css+"_formats").append(''+ vars.formats[f][1] +'');
+ }
+
+ toolbar.find("."+vars.css+"_formats").data("status",false);
+ }
+
+ // font-size-selector field
+ else if(buttons[n].name=="fsize" && $.isArray(vars.fsizes))
+ {
+ toolbar.find("."+vars.css+'_tool_'+buttons[n].cls)
+ .append('');
+
+ // add font-sizes to font-size-selector
+ for(var f = 0; f < vars.fsizes.length; f++)
+ {
+ toolbar.find("."+vars.css+"_fontsizes").append('Abcdefgh...');
+ }
+ }
+
+ // color-selector field
+ else if(buttons[n].name=="color" && $.isArray(colors))
+ {
+ toolbar.find("."+vars.css+'_tool_'+buttons[n].cls)
+ .append('');
+
+ // create color palette to color-selector field
+ for(var c = 0; c < colors.length; c++)
+ {
+ if(colors[c]!=null)
+ toolbar.find("."+vars.css+"_cpalette").append('');
+ else
+ toolbar.find("."+vars.css+"_cpalette").append('');
+ }
+ }
+ }
+ }
+
+ // the default value of the link-type
+ linktypes.data("linktype","0");
+
+ // add link types to link-type-selector
+ for(var n = 0; n < 3; n++)
+ {
+ linktypes.append(''+vars.linktypes[n]+'');
+
+ linktypeview.html('
');
+
+ var placeHolder = jQTE.find("."+vars.css+"_placeholder");
+
+ placeHolder.click(function(){
+ editor.focus();
+ });
+ }
+
+ // 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");
+
+ // font-size filed
+ var fsizebar = toolbar.find("."+vars.css+"_fontsizes");
+
+ // color palette
+ var cpalette = toolbar.find("."+vars.css+"_cpalette");
+
+ // 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(linkinput.val());
+ selectText($(element));
+ }
+ }
+ }
+ }
+ }
+
+ // the function of converting text to link
+ function selected2link(){
+ if(!toolbar.data("sourceOpened")){
+ var selectedTag = getSelectedNode(); // the selected node
+ var thisHrefLink = "https://"; // 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,"");
+ // if it don't have "a" tag name
+ }else{
+ 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){
+ // focus to link-input
+ linkinput.focus();
+
+ // select to the selected node
+ selectText(thisSelection);
+
+ // 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
+ // if selected to link-type of picture
+ }else{
+ selectionSet("insertImage",linkinput.val()); // insert image url of link-input to the selected node
+
+ // the method of all pictures in the editor
+ editor.find("img").each(function(){
+ var emptyPrevLinks = $(this).prev("a");
+ var emptyNextLinks = $(this).next("a");
+
+ // if "a" tags of the front and rear of the picture is empty, remove
+ if(emptyPrevLinks.length>0 && emptyPrevLinks.html()==""){
+ emptyPrevLinks.remove();
+ }else if(emptyNextLinks.length>0 && emptyNextLinks.html()==""){
+ emptyNextLinks.remove();
+ }
+ });
+ }
+
+ // hide the link-form-field
+ linkAreaSwitch();
+
+ // export contents of the text to the sources
+ editor.trigger("change");
+ }
+
+ // 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://" || RegExp("^(https?://|mailto)").test(linkinput.val()))){
+ linkinput.val("mailto:");
+ }else if(currentType!="1" && !RegExp("^https?://").test(linkinput.val())){
+ linkinput.val("http://");
+ }else{
+ linkinput.val(thisHrefLink);
+ }
+ }
+
+ // the function of adding style to selected text
+ function selected2style(styleCommand)
+ {
+ if(!toolbar.data("sourceOpened"))
+ {
+
+ // if selected to changing the font-size value
+ if(styleCommand=="fSize")
+ styleField = fsizebar;
+
+ // if selected to changing the text-color value
+ else if(styleCommand=="colors")
+ styleField = cpalette;
+
+ // display the style-field
+ styleFieldSwitch(styleField,true);
+
+ // 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
+
+ // if selected to changing the font-size value
+ if(styleCommand=="fSize")
+ {
+ styleType = "font-size";
+ styleValue = styleValue + vars.funit; // combine the value with size unit
+ }
+ // if selected to changing the text-color value
+ else if(styleCommand=="colors")
+ {
+ styleType = "color";
+ styleValue = "rgb("+styleValue + ")"; // combine color value with rgb
+ }
+
+ 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);
+
+ // hide all style-fields
+ styleFieldSwitch("",false);
+
+ // remove title bubbles
+ $('.'+vars.css+'_title').remove();
+
+ // export contents of the text to the sources
+ editor.trigger("change");
+ });
+
+ }
+ else
+ // hide the style-field
+ styleFieldSwitch(styleField,false);
+
+ // hide the link-form-field
+ linkAreaSwitch(false);
+ }
+
+ // the function of switching the style-field
+ function styleFieldSwitch(styleField,status)
+ {
+ var mainData="", // the style data of the actual wanted
+ allData = [{"d":"fsizeOpened","f":fsizebar},{"d":"cpallOpened","f":cpalette}]; // all style datas
+
+ // if the style data of the actual wanted isn't empty
+ if(styleField!="")
+ {
+ // return to all datas and find the main data
+ for(var si=0; si < allData.length; si++)
+ {
+ if(styleField==allData[si]["f"])
+ mainData = allData[si];
+ }
+ }
+ // display the style-field
+ if(status)
+ {
+ toolbar.data(mainData["d"],true); // stil seçme alanının açıldığını belirten parametre yaz
+ mainData["f"].slideDown(100); // stil seçme alanını aç
+
+ // return to all datas and close the fields of external datas
+ for(var si=0; si < allData.length; si++)
+ {
+ if(mainData["d"]!=allData[si]["d"])
+ {
+ toolbar.data(allData[si]["d"],false);
+ allData[si]["f"].slideUp(100);
+ }
+ }
+ }
+ // hide all style-fields
+ else
+ {
+ // return to all datas and close all style fields
+ for(var si=0; si < allData.length; si++)
+ {
+ toolbar.data(allData[si]["d"],false);
+ allData[si]["f"].slideUp(100);
+ }
+ }
+ }
+
+ // 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 have attribute of "style" and it have 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
+
+ // convert to selected format
+ selectionSet("formatBlock",'<'+formatValue+'>');
+
+ 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) + "...";
+
+ // change format label of button
+ formatLabel.html(str);
+ }
+
+ // 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,' ');
+
+ $htmlPattern = [
+ /\(.*?)<\/span><\/span>/gim, // trim nested spans
+ /<(\w*[^p])\s*[^\/>]*>\s*<\/\1>/gim, // remove empty or white-spaces tags (ignore paragraphs (
) and breaks ( ))
+ /\
(.*?)\<\/div>/gim, // convert div to p
+ /\(.*?)\<\/strong>/gim, // convert strong to b
+ /\(.*?)\<\/em>/gim // convert em to i
+ ];
+
+ $htmlReplace = [
+ '$3',
+ '',
+ '
$2
',
+ '$2',
+ '$2'
+ ];
+
+ // repeat the cleaning process 5 times
+ for(c=0; c<5; c++)
+ {
+ // create loop as the number of pattern
+ for(var i = 0; i < $htmlPattern.length; i++)
+ {
+ $htmlContent = $htmlContent.replace($htmlPattern[i], $htmlReplace[i]);
+ }
+ }
+
+ // if paragraph is false (
), convert
to
+ if(!vars.p)
+ $htmlContent = $htmlContent.replace(/\
(.*?)\<\/p>/ig, ' $2');
+
+ // if break is false ( ), convert to
'
+ ];
+
+ // create loop as the number of pattern (for breaks)
+ for (var i = 0; i < $htmlPattern.length; i++) {
+ $htmlContent = $htmlContent.replace($htmlPattern[i], $htmlReplace[i]);
+ }
+ }
+
+ // if paragraph and break is false (
');
+
+ return $htmlContent;
+ }
+
+ // the function of exporting contents of the text field to the source field (to be the standard in all browsers)
+ function postToSource()
+ {
+ // clear unnecessary tags when editor view empty
+ var sourceStrings = editor.text()=="" && editor.html().length<12 ? "" : editor.html();
+
+ thisElement.val(extractToText(sourceStrings));
+ }
+
+ // 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++)
+ {
+ if(vars[buttons[n].name] && buttons[n].emphasis && buttons[n].tag!='')
+ detectElement(buttons[n].tag) ? toolbar.find('.'+vars.css+'_tool_'+buttons[n].cls).addClass(emphasize) : $('.'+vars.css+'_tool_'+buttons[n].cls).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
+ styleFieldSwitch("",false);
+ 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();
+
+ // hide the link-form-field
+ linkAreaSwitch(false);
+
+ // hide all style-fields
+ styleFieldSwitch("",false);
+
+ // hide format field
+ formatFieldSwitch();
+
+ // hide placeholder
+ if(vars.placeholder && vars.placeholder!="")
+ placeHolder.hide();
+ }
+ // if other buttons is clicked
+ 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
+ {
+ // hide the link-form-field
+ linkAreaSwitch(false);
+
+ // hide format field
+ formatFieldSwitch(false);
+ }
+ }
+
+ // if the format button is clicked
+ else if($(this).data('command')=='formats')
+ {
+ if($(this).data('command')=='formats' && !$(e.target).hasClass(vars.css+"_format"))
+ selected2format();
+
+ // hide all style-fields
+ styleFieldSwitch("",false);
+
+ if(editor.not(":focus"))
+ editor.focus();
+ }
+
+ // if the style buttons are clicked
+ else if($(this).data('command')=='fSize' || $(this).data('command')=='colors')
+ {
+ if(
+ ($(this).data('command')=='fSize' && !$(e.target).hasClass(vars.css+"_fontsize")) || // the font-size button
+ ($(this).data('command')=='colors' && !$(e.target).hasClass(vars.css+"_color")) // the color button
+ )
+ selected2style($(this).data('command'));
+
+ // hide format field
+ formatFieldSwitch(false);
+
+ if(editor.not(":focus"))
+ editor.focus();
+ }
+
+ // if other buttons is clicked
+ 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);
+
+ // hide all menu-fields
+ styleFieldSwitch("",false);
+ 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");
+ }
+
+ if(vars.placeholder && vars.placeholder!="")
+ editor.html()!="" ? placeHolder.hide() : placeHolder.show();
+ }
+
+ // 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('
'+$(this).data("title")+'
');
+
+ 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() + 5);
+
+ // show the title bubble and set to its position
+ thisTitle.delay(400).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("keypress keyup keydown drop cut copy paste DOMCharacterDataModified DOMSubtreeModified",function()
+ {
+ // 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();
+
+ // the feature of placeholder
+ if(vars.placeholder && vars.placeholder!="")
+ $(this).text()!="" ? placeHolder.hide() : placeHolder.show();
+ })
+ .bind("change",function()
+ {
+ 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)
+ // if the keyed button with ctrl is same of hotkey of this button
+ if(vars[buttons[n].name] && e.keyCode == buttons[n].key.charCodeAt(0))
+ {
+ if(buttons[n].command!='' && buttons[n].command!='linkcreator')
+ selectionSet(buttons[n].command,null);
+
+ else if(buttons[n].command=='linkcreator')
+ selected2link();
+
+ 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
+ styleFieldSwitch("",false);
+ 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()
+ {
+ // export contents of the source to the text field
+ setTimeout(postToEditor,0);
+
+ // auto extension for the source field
+ $(this).height($(this)[0].scrollHeight);
+
+ // if the source field is empty, shorten to the source field
+ if($(this).val()=="")
+ $(this).height(0);
+ })
+ .focus(function()
+ {
+ // add onfocus class
+ jQTE.addClass(vars.css+"_focused");
+ })
+ .focusout(function()
+ {
+ // remove onfocus class
+ jQTE.removeClass(vars.css+"_focused");
+ });
+ });
+ };
+})(jQuery);