webpack-bootstrap-ui-kit/src/thirdparty/jQuery-TE_v.1.4.0/uncompressed/jquery-te-1.4.0.js

1347 lines
45 KiB
JavaScript
Raw Normal View History

2019-12-02 16:33:28 +01:00
/*!
*
* 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,'&#34;').replace(/'/g,'&#39;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
// 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(/&#34;/g,'"').replace(/&#39;/g,"'").replace(/&lt;/g,'<').replace(/&gt;/g,'>').replace(/&amp;/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>');
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('<div class="'+vars.css+'_linktypeselect" unselectable></div><input class="'+vars.css+'_linkinput" type="text/css" value=""><div class="'+vars.css+'_linkbutton" 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);
// 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('<div class="'+vars.css+'_tool '+vars.css+'_tool_'+buttons[n].cls+'" 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 : 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('<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_'+buttons[n].cls)
.append('<div class="'+vars.css+'_formats" unselectable></div>');
// add font-sizes to font-size-selector
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);
}
// font-size-selector field
else if(buttons[n].name=="fsize" && $.isArray(vars.fsizes))
{
toolbar.find("."+vars.css+'_tool_'+buttons[n].cls)
.append('<div class="'+vars.css+'_fontsizes" unselectable></div>');
// add font-sizes to font-size-selector
for(var f = 0; f < vars.fsizes.length; f++)
{
toolbar.find("."+vars.css+"_fontsizes").append('<a '+vars.css+'-styleval="'+ vars.fsizes[f] +'" class="'+vars.css+'_fontsize'+'" style="font-size:'+ vars.fsizes[f] + vars.funit+'" role="menuitem" unselectable>Abcdefgh...</a>');
}
}
// color-selector field
else if(buttons[n].name=="color" && $.isArray(colors))
{
toolbar.find("."+vars.css+'_tool_'+buttons[n].cls)
.append('<div class="'+vars.css+'_cpalette" unselectable></div>');
// 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('<a '+vars.css+'-styleval="'+ colors[c] +'" class="'+vars.css+'_color'+'" style="background-color: rgb('+ colors[c] +')" role="gridcell" unselectable></a>');
else
toolbar.find("."+vars.css+"_cpalette").append('<div class="'+vars.css+"_colorSeperator"+'"></div>');
}
}
}
}
// 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('<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 = '';
// the feature of placeholder
if(vars.placeholder && vars.placeholder!="")
{
jQTE.prepend('<div class="'+vars.css+'_placeholder" unselectable><div class="'+vars.css+'_placeholder_text">'+vars.placeholder+'</div></div>');
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("&nbsp;");
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,"");
}
// 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://" || 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"))
{
// 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ı
// 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(/&nbsp;/gim,' ');
$htmlPattern = [
/\<span(|\s+.*?)><span(|\s+.*?)>(.*?)<\/span><\/span>/gim, // trim nested spans
/<(\w*[^p])\s*[^\/>]*>\s*<\/\1>/gim, // remove empty or white-spaces tags (ignore paragraphs (<p>) and breaks (<br>))
/\<div(|\s+.*?)>(.*?)\<\/div>/gim, // convert div to p
/\<strong(|\s+.*?)>(.*?)\<\/strong>/gim, // convert strong to b
/\<em(|\s+.*?)>(.*?)\<\/em>/gim // convert em to i
];
$htmlReplace = [
'<span$2>$3</span>',
'',
'<p$1>$2</p>',
'<b$1>$2</b>',
'<i$1>$2</i>'
];
// 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 (<p>), convert <p> to <br>
if(!vars.p)
$htmlContent = $htmlContent.replace(/\<p(|\s+.*?)>(.*?)\<\/p>/ig, '<br/>$2');
// 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]);
}
}
// if paragraph and break is false (<p> && <br>), convert <p> to <div>
if(!vars.p && !vars.br)
$htmlContent = $htmlContent.replace(/\<p>(.*?)\<\/p>/ig, '<div>$1</div>');
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('<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() + 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);