funchat/themes/austria/js/wysibb/jquery.wysibb.js

3026 lines
No EOL
98 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*! WysiBB v1.5.1 2014-03-26
Author: Vadim Dobroskok
*/
if (typeof (WBBLANG)=="undefined") {WBBLANG = {};}
WBBLANG['en'] = CURLANG = {
bold: "Bold",
italic: "Italic",
underline: "Underline",
strike: "Strike",
link: "Link",
img: "Insert image",
sup: "Superscript",
sub: "Subscript",
justifyleft: "Align left",
justifycenter: "Align center",
justifyright: "Align right",
table: "Insert table",
bullist: "• Unordered list",
numlist: "1. Ordered list",
quote: "Quote",
offtop: "Offtop",
code: "Code",
spoiler: "Spoiler",
fontcolor: "Font color",
fontsize: "Font size",
fontfamily: "Font family",
fs_verysmall: "Very small",
fs_small: "Small",
fs_normal: "Normal",
fs_big: "Big",
fs_verybig: "Very big",
smilebox: "Insert emoticon",
video: "Insert YouTube",
removeFormat:"Remove Format",
modal_link_title: "Insert link",
modal_link_text: "Display text",
modal_link_url: "URL",
modal_email_text: "Display email",
modal_email_url: "Email",
modal_link_tab1: "Insert URL",
modal_img_title: "Insert image",
modal_img_tab1: "Insert URL",
modal_img_tab2: "Upload image",
modal_imgsrc_text: "Enter image URL",
modal_img_btn: "Choose file",
add_attach: "Add Attachment",
modal_video_text: "Enter the URL of the video",
close: "Close",
save: "Save",
cancel: "Cancel",
remove: "Delete",
validation_err: "The entered data is invalid",
error_onupload: "Error during file upload",
fileupload_text1: "Drop file here",
fileupload_text2: "or",
loading: "Loading",
auto: "Auto",
views: "Views",
downloads: "Downloads",
//smiles
sm1: "Smile",
sm2: "Laughter",
sm3: "Wink",
sm4: "Thank you",
sm5: "Scold",
sm6: "Shock",
sm7: "Angry",
sm8: "Pain",
sm9: "Sick"
};
wbbdebug=true;
(function($) {
'use strict';
$.wysibb = function(txtArea,settings) {
$(txtArea).data("wbb",this);
if (settings && settings.deflang && typeof(WBBLANG[settings.deflang])!="undefined") {CURLANG = WBBLANG[settings.deflang];}
if (settings && settings.lang && typeof(WBBLANG[settings.lang])!="undefined") {CURLANG = WBBLANG[settings.lang];}
this.txtArea=txtArea;
this.$txtArea=$(txtArea);
var id = this.$txtArea.attr("id") || this.setUID(this.txtArea);
this.options = {
bbmode: false,
onlyBBmode: false,
themeName: "default",
bodyClass: "",
lang: "ru",
tabInsert: true,
// toolbar: false,
//img upload config
imgupload: false,
img_uploadurl: "/iupload.php",
img_maxwidth: 800,
img_maxheight: 800,
hotkeys: true,
showHotkeys: true,
autoresize: true,
resize_maxheight: 800,
loadPageStyles: true,
traceTextarea: true,
// direction: "ltr",
smileConversion: true,
//END img upload config
buttons: "bold,italic,underline,strike,sup,sub,|,img,video,link,|,bullist,numlist,|,fontcolor,fontsize,fontfamily,|,justifyleft,justifycenter,justifyright,|,quote,code,table,removeFormat",
allButtons: {
bold : {
title: CURLANG.bold,
buttonHTML: '<span class="fonticon ve-tlb-bold1">\uE018</span>',
excmd: 'bold',
hotkey: 'ctrl+b',
transform : {
'<b>{SELTEXT}</b>':"[b]{SELTEXT}[/b]",
'<strong>{SELTEXT}</strong>':"[b]{SELTEXT}[/b]"
}
},
italic : {
title: CURLANG.italic,
buttonHTML: '<span class="fonticon ve-tlb-italic1">\uE001</span>',
excmd: 'italic',
hotkey: 'ctrl+i',
transform : {
'<i>{SELTEXT}</i>':"[i]{SELTEXT}[/i]",
'<em>{SELTEXT}</em>':"[i]{SELTEXT}[/i]"
}
},
underline : {
title: CURLANG.underline,
buttonHTML: '<span class="fonticon ve-tlb-underline1">\uE002</span>',
excmd: 'underline',
hotkey: 'ctrl+u',
transform : {
'<u>{SELTEXT}</u>':"[u]{SELTEXT}[/u]"
}
},
strike : {
title: CURLANG.strike,
buttonHTML: '<span class="fonticon fi-stroke1 ve-tlb-strike1">\uE003</span>',
excmd: 'strikeThrough',
transform : {
'<strike>{SELTEXT}</strike>':"[s]{SELTEXT}[/s]",
'<s>{SELTEXT}</s>':"[s]{SELTEXT}[/s]"
}
},
sup : {
title: CURLANG.sup,
buttonHTML: '<span class="fonticon ve-tlb-sup1">\uE005</span>',
excmd: 'superscript',
transform : {
'<sup>{SELTEXT}</sup>':"[sup]{SELTEXT}[/sup]"
}
},
sub : {
title: CURLANG.sub,
buttonHTML: '<span class="fonticon ve-tlb-sub1">\uE004</span>',
excmd: 'subscript',
transform : {
'<sub>{SELTEXT}</sub>':"[sub]{SELTEXT}[/sub]"
}
},
link : {
title: CURLANG.link,
buttonHTML: '<span class="fonticon ve-tlb-link1">\uE007</span>',
hotkey: 'ctrl+shift+2',
modal: {
title: CURLANG.modal_link_title,
width: "500px",
tabs: [
{
input: [
{param: "SELTEXT",title:CURLANG.modal_link_text, type: "div"},
{param: "URL",title:CURLANG.modal_link_url,validation: '^http(s)?://'}
]
}
]
},
transform : {
'<a href="{URL}">{SELTEXT}</a>':"[url={URL}]{SELTEXT}[/url]",
'<a href="{URL}">{URL}</a>':"[url]{URL}[/url]"
}
},
img : {
title: CURLANG.img,
buttonHTML: '<span class="fonticon ve-tlb-img1">\uE006</span>',
hotkey: 'ctrl+shift+1',
addWrap: true,
modal: {
title: CURLANG.modal_img_title,
width: "600px",
tabs: [
{
title: CURLANG.modal_img_tab1,
input: [
{param: "SRC",title:CURLANG.modal_imgsrc_text,validation: '^http(s)?://.*?\.(jpg|png|gif|jpeg)$'}
]
}
],
onLoad: this.imgLoadModal
},
transform : {
'<img src="{SRC}" />':"[img]{SRC}[/img]",
'<img src="{SRC}" width="{WIDTH}" height="{HEIGHT}"/>':"[img width={WIDTH},height={HEIGHT}]{SRC}[/img]"
}
},
bullist : {
title: CURLANG.bullist,
buttonHTML: '<span class="fonticon ve-tlb-list1">\uE009</span>',
excmd: 'insertUnorderedList',
transform : {
'<ul>{SELTEXT}</ul>':"[list]{SELTEXT}[/list]",
'<li>{SELTEXT}</li>':"[*]{SELTEXT}[/*]"
}
},
numlist : {
title: CURLANG.numlist,
buttonHTML: '<span class="fonticon ve-tlb-numlist1">\uE00a</span>',
excmd: 'insertOrderedList',
transform : {
'<ol>{SELTEXT}</ol>':"[list=1]{SELTEXT}[/list]",
'<li>{SELTEXT}</li>':"[*]{SELTEXT}[/*]"
}
},
quote : {
title: CURLANG.quote,
buttonHTML: '<span class="fonticon ve-tlb-quote1">\uE00c</span>',
hotkey: 'ctrl+shift+3',
//subInsert: true,
transform : {
'<blockquote>{SELTEXT}</blockquote>':"[quote]{SELTEXT}[/quote]"
}
},
code : {
title: CURLANG.code,
buttonText: '[code]',
/* buttonHTML: '<span class="fonticon">\uE00d</span>', */
hotkey: 'ctrl+shift+4',
onlyClearText: true,
transform : {
'<code>{SELTEXT}</code>':"[code]{SELTEXT}[/code]"
}
},
offtop : {
title: CURLANG.offtop,
buttonText: 'offtop',
transform : {
'<span style="font-size:10px;color:#ccc">{SELTEXT}</span>':"[offtop]{SELTEXT}[/offtop]"
}
},
fontcolor: {
type: "colorpicker",
title: CURLANG.fontcolor,
excmd: "foreColor",
valueBBname: "color",
subInsert: true,
colors: "#000000,#444444,#666666,#999999,#b6b6b6,#cccccc,#d8d8d8,#efefef,#f4f4f4,#ffffff,-, \
#ff0000,#980000,#ff7700,#ffff00,#00ff00,#00ffff,#1e84cc,#0000ff,#9900ff,#ff00ff,-, \
#f4cccc,#dbb0a7,#fce5cd,#fff2cc,#d9ead3,#d0e0e3,#c9daf8,#cfe2f3,#d9d2e9,#ead1dc, \
#ea9999,#dd7e6b,#f9cb9c,#ffe599,#b6d7a8,#a2c4c9,#a4c2f4,#9fc5e8,#b4a7d6,#d5a6bd, \
#e06666,#cc4125,#f6b26b,#ffd966,#93c47d,#76a5af,#6d9eeb,#6fa8dc,#8e7cc3,#c27ba0, \
#cc0000,#a61c00,#e69138,#f1c232,#6aa84f,#45818e,#3c78d8,#3d85c6,#674ea7,#a64d79, \
#900000,#85200C,#B45F06,#BF9000,#38761D,#134F5C,#1155Cc,#0B5394,#351C75,#741B47, \
#660000,#5B0F00,#783F04,#7F6000,#274E13,#0C343D,#1C4587,#073763,#20124D,#4C1130",
transform: {
'<font color="{COLOR}">{SELTEXT}</font>':'[color={COLOR}]{SELTEXT}[/color]'
}
},
table: {
type: "table",
title: CURLANG.table,
cols: 10,
rows: 10,
cellwidth: 20,
transform: {
'<td>{SELTEXT}</td>': '[td]{SELTEXT}[/td]',
'<tr>{SELTEXT}</tr>': '[tr]{SELTEXT}[/tr]',
'<table class="wbb-table">{SELTEXT}</table>': '[table]{SELTEXT}[/table]'
},
skipRules: true
},
fontsize: {
type: 'select',
title: CURLANG.fontsize,
options: "fs_verysmall,fs_small,fs_normal,fs_big,fs_verybig"
},
fontfamily: {
type: 'select',
title: CURLANG.fontfamily,
excmd: 'fontName',
valueBBname: "font",
options: [
{title: "Arial",exvalue: "Arial"},
{title: "Comic Sans MS",exvalue: "Comic Sans MS"},
{title: "Courier New",exvalue: "Courier New"},
{title: "Georgia",exvalue: "Georgia"},
{title: "Lucida Sans Unicode",exvalue: "Lucida Sans Unicode"},
{title: "Tahoma",exvalue: "Tahoma"},
{title: "Times New Roman",exvalue: "Times New Roman"},
{title: "Trebuchet MS",exvalue: "Trebuchet MS"},
{title: "Verdana",exvalue: "Verdana"}
],
transform: {
'<font face="{FONT}">{SELTEXT}</font>':'[font={FONT}]{SELTEXT}[/font]'
}
},
smilebox: {
type: 'smilebox',
title: CURLANG.smilebox,
buttonHTML: '<span class="fonticon ve-tlb-smilebox1">\uE00b</span>'
},
justifyleft: {
title: CURLANG.justifyleft,
buttonHTML: '<span class="fonticon ve-tlb-textleft1">\uE015</span>',
groupkey: 'align',
transform: {
'<p style="text-align:left">{SELTEXT}</p>': '[left]{SELTEXT}[/left]'
}
},
justifyright: {
title: CURLANG.justifyright,
buttonHTML: '<span class="fonticon ve-tlb-textright1">\uE016</span>',
groupkey: 'align',
transform: {
'<p style="text-align:right">{SELTEXT}</p>': '[right]{SELTEXT}[/right]'
}
},
justifycenter: {
title: CURLANG.justifycenter,
buttonHTML: '<span class="fonticon ve-tlb-textcenter1">\uE014</span>',
groupkey: 'align',
transform: {
'<p style="text-align:center">{SELTEXT}</p>': '[center]{SELTEXT}[/center]'
}
},
video: {
title: CURLANG.video,
buttonHTML: '<span class="fonticon ve-tlb-video1">\uE008</span>',
modal: {
title: CURLANG.video,
width: "600px",
tabs: [
{
title: CURLANG.video,
input: [
{param: "SRC",title:CURLANG.modal_video_text}
]
}
],
onSubmit: function(cmd,opt,queryState) {
var url = this.$modal.find('input[name="SRC"]').val();
if (url) {
url = url.replace(/^\s+/,"").replace(/\s+$/,"");
}
var a;
if (url.indexOf("youtu.be")!=-1) {
a = url.match(/^http[s]*:\/\/youtu\.be\/([a-z0-9_-]+)/i);
}else{
a = url.match(/^http[s]*:\/\/www\.youtube\.com\/watch\?.*?v=([a-z0-9_-]+)/i);
}
if (a && a.length==2) {
var code = a[1];
this.insertAtCursor(this.getCodeByCommand(cmd,{src:code}));
}
this.closeModal();
this.updateUI();
return false;
}
},
transform: {
'<iframe src="http://www.youtube.com/embed/{SRC}" width="640" height="480" frameborder="0"></iframe>':'[video]{SRC}[/video]'
}
},
//select options
fs_verysmall: {
title: CURLANG.fs_verysmall,
buttonText: "fs1",
excmd: 'fontSize',
exvalue: "1",
transform: {
'<font size="1">{SELTEXT}</font>':'[size=50]{SELTEXT}[/size]'
}
},
fs_small: {
title: CURLANG.fs_small,
buttonText: "fs2",
excmd: 'fontSize',
exvalue: "2",
transform: {
'<font size="2">{SELTEXT}</font>':'[size=85]{SELTEXT}[/size]'
}
},
fs_normal: {
title: CURLANG.fs_normal,
buttonText: "fs3",
excmd: 'fontSize',
exvalue: "3",
transform: {
'<font size="3">{SELTEXT}</font>':'[size=100]{SELTEXT}[/size]'
}
},
fs_big: {
title: CURLANG.fs_big,
buttonText: "fs4",
excmd: 'fontSize',
exvalue: "4",
transform: {
'<font size="4">{SELTEXT}</font>':'[size=150]{SELTEXT}[/size]'
}
},
fs_verybig: {
title: CURLANG.fs_verybig,
buttonText: "fs5",
excmd: 'fontSize',
exvalue: "6",
transform: {
'<font size="6">{SELTEXT}</font>':'[size=200]{SELTEXT}[/size]'
}
},
removeformat: {
title: CURLANG.removeFormat,
buttonHTML: '<span class="fonticon ve-tlb-removeformat1">\uE00f</span>',
excmd: "removeFormat"
}
},
systr: {
'<br/>':"\n",
'<span class="wbbtab">{SELTEXT}</span>': ' {SELTEXT}'
},
customRules: {
td: [["[td]{SELTEXT}[/td]",{seltext: {rgx:false,attr:false,sel:false}}]],
tr: [["[tr]{SELTEXT}[/tr]",{seltext: {rgx:false,attr:false,sel:false}}]],
table: [["[table]{SELTEXT}[/table]",{seltext: {rgx:false,attr:false,sel:false}}]]
//blockquote: [[" {SELTEXT}",{seltext: {rgx:false,attr:false,sel:false}}]]
},
smileList: [
//{title:CURLANG.sm1, img: '<img src="{themePrefix}{themeName}/img/smiles/sm1.png" class="sm">', bbcode:":)"},
],
attrWrap: ['src','color','href'] //use becouse FF and IE change values for this attr, modify [attr] to _[attr]
}
//FIX for Opera. Wait while iframe loaded
this.inited=this.options.onlyBBmode;
//init css prefix, if not set
if (!this.options.themePrefix) {
$('link').each($.proxy(function(idx, el) {
var sriptMatch = $(el).get(0).href.match(/(.*\/)(.*)\/wbbtheme\.css.*$/);
if (sriptMatch !== null) {
this.options.themeName = sriptMatch[2];
this.options.themePrefix = sriptMatch[1];
}
},this));
}
//check for preset
if (typeof(WBBPRESET)!="undefined") {
if (WBBPRESET.allButtons) {
//clear transform
$.each(WBBPRESET.allButtons,$.proxy(function(k,v) {
if (v.transform && this.options.allButtons[k]) {
delete this.options.allButtons[k].transform;
}
},this));
}
$.extend(true,this.options,WBBPRESET);
}
if (settings && settings.allButtons) {
$.each(settings.allButtons,$.proxy(function(k,v) {
if (v.transform && this.options.allButtons[k]) {
delete this.options.allButtons[k].transform;
}
},this));
}
$.extend(true,this.options,settings);
this.init();
}
$.wysibb.prototype = {
lastid : 1,
init: function() {
$.log("Init",this);
//check for mobile
this.isMobile = function(a) {(/android|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|meego.+mobile|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(a))}(navigator.userAgent||navigator.vendor||window.opera);
//use bbmode on mobile devices
//this.isMobile = true; //TEMP
if (this.options.onlyBBmode===true) {this.options.bbmode=true;}
//create array of controls, for queryState
this.controllers = [];
//convert button string to array
this.options.buttons = this.options.buttons.toLowerCase();
this.options.buttons = this.options.buttons.split(",");
//init system transforms
this.options.allButtons["_systr"] = {};
this.options.allButtons["_systr"]["transform"]= this.options.systr;
this.smileFind();
this.initTransforms();
this.build();
this.initModal();
if (this.options.hotkeys===true && !this.isMobile) {
this.initHotkeys();
}
//sort smiles
if (this.options.smileList && this.options.smileList.length>0) {
this.options.smileList.sort(function(a,b) {
return (b.bbcode.length-a.bbcode.length);
})
}
this.$txtArea.parents("form").bind("submit",$.proxy(function() {
this.sync();
return true;
},this));
//phpbb2
this.$txtArea.parents("form").find("input[id*='preview'],input[id*='submit'],input[class*='preview'],input[class*='submit'],input[name*='preview'],input[name*='submit']").bind("mousedown",$.proxy(function() {
this.sync();
setTimeout($.proxy(function() {
if (this.options.bbmode===false) {
this.$txtArea.removeAttr("wbbsync").val("");
}
},this),1000);
},this));
//end phpbb2
if (this.options.initCallback) {
this.options.initCallback.call(this);
}
$.log(this);
},
initTransforms: function() {
$.log("Create rules for transform HTML=>BB");
var o = this.options;
//need to check for active buttons
if (!o.rules) {o.rules={};}
if (!o.groups) {o.groups={};} //use for groupkey, For example: justifyleft,justifyright,justifycenter. It is must replace each other.
var btnlist = o.buttons.slice();
//add system transform
btnlist.push("_systr");
for (var bidx=0; bidx<btnlist.length; bidx++) {
var ob = o.allButtons[btnlist[bidx]];
if (!ob ) {continue;}
ob.en=true;
//check for simplebbcode
if (ob.simplebbcode && $.isArray(ob.simplebbcode) && ob.simplebbcode.length==2) {
ob.bbcode = ob.html = ob.simplebbcode[0]+"{SELTEXT}"+ob.simplebbcode[1];
if (ob.transform) delete ob.transform;
if (ob.modal) delete ob.modal;
}
//add transforms to option list
if (ob.type=="select" && typeof(ob.options)=="string") {
var olist = ob.options.split(",");
$.each(olist,function(i,op) {
if ($.inArray(op,btnlist)==-1) {
btnlist.push(op);
}
});
}
if (ob.transform && ob.skipRules!==true) {
var obtr = $.extend({},ob.transform);
/* if (ob.addWrap) {
//addWrap
$.log("needWrap");
for (var bhtml in obtr) {
var bbcode = ob.transform[bhtml];
var newhtml = '<span wbb="'+btnlist[bidx]+'">'+bhtml+'</span>';
obtr[newhtml] = bbcode;
}
} */
for (var bhtml in obtr) {
var orightml = bhtml;
var bbcode = obtr[bhtml];
//create root selector for isContain bbmode
if (!ob.bbSelector) {ob.bbSelector=[];}
if ($.inArray(bbcode,ob.bbSelector)==-1) {
ob.bbSelector.push(bbcode);
}
if (this.options.onlyBBmode===false) {
//wrap attributes
bhtml = this.wrapAttrs(bhtml);
var $bel = $(document.createElement('DIV')).append($(this.elFromString(bhtml,document)));
var rootSelector = this.filterByNode($bel.children());
//check if current rootSelector is exist, create unique selector for each transform (1.2.2)
if (rootSelector=="div" || typeof(o.rules[rootSelector])!="undefined") {
//create unique selector
$.log("create unique selector: "+rootSelector);
this.setUID($bel.children());
rootSelector = this.filterByNode($bel.children());
$.log("New rootSelector: "+rootSelector);
//replace transform with unique selector
var nhtml2 = $bel.html();
nhtml2 = this.unwrapAttrs(nhtml2);
var obhtml = this.unwrapAttrs(bhtml);
ob.transform[nhtml2]=bbcode;
delete ob.transform[obhtml];
bhtml=nhtml2;
orightml = nhtml2;
}
//create root selector for isContain
if (!ob.excmd) {
if (!ob.rootSelector) {ob.rootSelector=[];}
ob.rootSelector.push(rootSelector);
}
//check for rules on this rootSeletor
if (typeof(o.rules[rootSelector])=="undefined") {
o.rules[rootSelector]=[];
}
var crules={};
if (bhtml.match(/\{\S+?\}/)) {
$bel.find('*').each($.proxy(function(idx,el) {
//check attributes
var attributes = this.getAttributeList(el);
$.each(attributes,$.proxy(function(i, item) {
var attr = $(el).attr(item);
if (item.substr(0,1)=='_') {
item = item.substr(1);
}
var r = attr.match(/\{\S+?\}/g);
if (r) {
for (var a=0; a<r.length; a++) {
var rname = r[a].substr(1,r[a].length-2);
rname = rname.replace(this.getValidationRGX(rname),"");
var p = this.relFilterByNode(el,rootSelector);
var regRepl = (attr!=r[a]) ? this.getRegexpReplace(attr,r[a]):false;
crules[rname.toLowerCase()]={sel:(p) ? $.trim(p):false,attr:item,rgx:regRepl}
}
}
},this));
//check for text
var sl=[];
if (!$(el).is("iframe")) {
$(el).contents().filter(function() {return this.nodeType===3}).each($.proxy(function(i,rel) {
var txt = rel.textContent || rel.data;
if (typeof(txt)=="undefined") {return true;}
var r = txt.match(/\{\S+?\}/g)
if (r) {
for (var a=0; a<r.length; a++) {
var rname = r[a].substr(1,r[a].length-2);
rname = rname.replace(this.getValidationRGX(rname),"");
var p = this.relFilterByNode(el,rootSelector);
var regRepl = (txt!=r[a]) ? this.getRegexpReplace(txt,r[a]):false;
var sel = (p) ? $.trim(p):false;
if ($.inArray(sel,sl)>-1 || $(rel).parent().contents().size()>1) {
//has dublicate and not one children, need wrap
var nel = $("<span>").html("{"+rname+"}");
this.setUID(nel,"wbb");
var start = (txt.indexOf(rname)+rname.length)+1;
var after_txt = txt.substr(start,txt.length-start);
//create wrap element
rel.data = txt.substr(0,txt.indexOf(rname)-1);
$(rel).after(this.elFromString(after_txt,document)).after(nel);
sel=((sel) ? sel+" ":"")+this.filterByNode(nel);
regRepl=false;
}
crules[rname.toLowerCase()]={sel:sel,attr:false,rgx:regRepl}
sl[sl.length]=sel;
}
}
},this));
}
sl=null;
},this));
var nbhtml = $bel.html();
//UnWrap attributes
nbhtml = this.unwrapAttrs(nbhtml);
if (orightml!=nbhtml) {
//if we modify html, replace it
delete ob.transform[orightml];
ob.transform[nbhtml]=bbcode;
bhtml=nbhtml;
}
}
o.rules[rootSelector].push([bbcode,crules]);
//check for onlyClearText
if (ob.onlyClearText===true) {
if (!this.cleartext) {this.cleartext={};}
this.cleartext[rootSelector]=btnlist[bidx];
}
//check for groupkey
if (ob.groupkey) {
if (!o.groups[ob.groupkey]) {o.groups[ob.groupkey]=[]}
o.groups[ob.groupkey].push(rootSelector);
}
}
}
//sort rootSelector
if (ob.rootSelector) {
this.sortArray(ob.rootSelector,-1);
}
var htmll = $.map(ob.transform,function(bb,html) {return html}).sort(function(a,b) {
return ((b[0] || "").length-(a[0] || "").length)
});
ob.bbcode = ob.transform[htmll[0]];
ob.html = htmll[0];
}
};
this.options.btnlist=btnlist; //use for transforms, becouse select elements not present in buttons
//add custom rules, for table,tr,td and other
$.extend(o.rules,this.options.customRules);
//smile rules
o.srules={};
if (this.options.smileList) {
$.each(o.smileList,$.proxy(function(i,sm) {
var $sm = $(this.strf(sm.img,o));
var f = this.filterByNode($sm);
o.srules[f]=[sm.bbcode,sm.img];
},this));
}
//sort transforms by bbcode length desc
for (var rootsel in o.rules) {
this.options.rules[rootsel].sort(function(a,b) {
return (b[0].length-a[0].length)
});
}
//create rootsel list
this.rsellist = [];
for (var rootsel in this.options.rules) {
this.rsellist.push(rootsel);
}
this.sortArray(this.rsellist,-1);
},
//BUILD
build: function() {
$.log("Build editor");
//this.$editor = $('<div class="wysibb">');
this.$editor = $('<div>').addClass("wysibb");
if (this.isMobile) {
this.$editor.addClass("wysibb-mobile");
}
//set direction if defined
if (this.options.direction) {this.$editor.css("direction",this.options.direction)}
this.$editor.insertAfter(this.txtArea).append(this.txtArea);
this.startHeight = this.$txtArea.outerHeight();
this.$txtArea.addClass("wysibb-texarea");
this.buildToolbar();
//Build iframe if needed
this.$txtArea.wrap('<div class="wysibb-text">');
if (this.options.onlyBBmode===false) {
var height = this.options.minheight || this.$txtArea.outerHeight();
var maxheight = this.options.resize_maxheight;
var mheight = (this.options.autoresize===true) ? this.options.resize_maxheight:height;
this.$body = $(this.strf('<div class="wysibb-text-editor" style="max-height:{maxheight}px;min-height:{height}px"></div>',{maxheight:mheight,height:height})).insertAfter(this.$txtArea);
this.body = this.$body[0];
this.$txtArea.hide();
if (height>32) {
this.$toolbar.css("max-height",height);
}
$.log("WysiBB loaded");
this.$body.addClass("wysibb-body").addClass(this.options.bodyClass);
//set direction if defined
if (this.options.direction) {this.$body.css("direction",this.options.direction)}
if ('contentEditable' in this.body) {
this.body.contentEditable=true;
try{
//fix for mfirefox
//document.execCommand('enableObjectResizing', false, 'false'); //disable image resizing
document.execCommand('StyleWithCSS', false, false);
//document.designMode = "on";
this.$body.append("<span></span>");
}catch(e) {}
}else{
//use onlybbmode
this.options.onlyBBmode=this.options.bbmode=true;
}
//check for exist content in textarea
if (this.txtArea.value.length>0) {
this.txtAreaInitContent();
}
//clear html on paste from external editors
this.$body.bind('keydown', $.proxy(function(e) {
if ((e.which == 86 && (e.ctrlKey==true || e.metaKey==true)) || (e.which == 45 && (e.shiftKey==true || e.metaKey==true))) {
if (!this.$pasteBlock) {
this.saveRange();
this.$pasteBlock = $(this.elFromString('<div style="opacity:0;" contenteditable="true">\uFEFF</div>'));
this.$pasteBlock.appendTo(this.body);
//if (!$.support.search?type=2) {this.$pasteBlock.focus();} //IE 7,8 FIX
setTimeout($.proxy(function() {
this.clearPaste(this.$pasteBlock);
var rdata = '<span>'+this.$pasteBlock.html()+'</span>';
this.$body.attr("contentEditable","true");
this.$pasteBlock.blur().remove();
this.body.focus();
if (this.cleartext) {
$.log("Check if paste to clearText Block");
if (this.isInClearTextBlock()) {
rdata = this.toBB(rdata).replace(/\n/g,"<br/>").replace(/\s{3}/g,'<span class="wbbtab"></span>');
}
}
rdata = rdata.replace(/\t/g,'<span class="wbbtab"></span>');
this.selectRange(this.lastRange);
this.insertAtCursor(rdata,false);
this.lastRange=false;
this.$pasteBlock=false;
}
,this), 1);
this.selectNode(this.$pasteBlock[0]);
}
return true;
}
},this));
//insert BR on press enter
this.$body.bind('keydown',$.proxy(function(e) {
if (e.which == 13) {
var isLi = this.isContain(this.getSelectNode(),'li');
if (!isLi) {
if (e.preventDefault) {e.preventDefault();}
this.checkForLastBR(this.getSelectNode());
this.insertAtCursor('<br/>',false);
}
}
},this));
//tabInsert
if (this.options.tabInsert===true) {
this.$body.bind('keydown', $.proxy(this.pressTab,this));
}
//add event listeners
this.$body.bind('mouseup keyup',$.proxy(this.updateUI,this));
this.$body.bind('mousedown',$.proxy(function(e) {this.clearLastRange();this.checkForLastBR(e.target)},this));
//trace Textarea
if (this.options.traceTextarea===true) {
$(document).bind("mousedown",$.proxy(this.traceTextareaEvent,this));
this.$txtArea.val("");
}
//attach hotkeys
if (this.options.hotkeys===true) {
this.$body.bind('keydown',$.proxy(this.presskey,this));
}
//smileConversion
if (this.options.smileConversion===true) {
this.$body.bind('keyup',$.proxy(this.smileConversion,this));
}
this.inited=true;
//create resize lines
if (this.options.autoresize===true) {
this.$bresize = $(this.elFromString('<div class="bottom-resize-line"></div>')).appendTo(this.$editor)
.wdrag({
scope:this,
axisY: true,
height: height
});
}
this.imgListeners();
}
//this.$editor.append('<span class="powered">Powered by <a href="http://www.wysibb.com" target="_blank">WysiBB<a/></span>');
//add event listeners to textarea
this.$txtArea.bind('mouseup keyup',$.proxy(function() {
clearTimeout(this.uitimer);
this.uitimer = setTimeout($.proxy(this.updateUI,this),100);
},this));
//attach hotkeys
if (this.options.hotkeys===true) {
$(document).bind('keydown',$.proxy(this.presskey,this));
}
},
buildToolbar: function() {
if (this.options.toolbar === false) {return false;}
//this.$toolbar = $('<div class="wysibb-toolbar">').prependTo(this.$editor);
this.$toolbar = $('<div>').addClass("wysibb-toolbar").prependTo(this.$editor);
var $btnContainer;
$.each(this.options.buttons,$.proxy(function(i,bn) {
var opt = this.options.allButtons[bn];
if (i==0 || bn=="|" || bn=="-") {
if (bn=="-") {
this.$toolbar.append("<div>");
}
$btnContainer = $('<div class="wysibb-toolbar-container">').appendTo(this.$toolbar);
}
if (opt) {
if (opt.type=="colorpicker") {
this.buildColorpicker($btnContainer,bn,opt);
}else if (opt.type=="table") {
this.buildTablepicker($btnContainer,bn,opt);
}else if (opt.type=="select") {
this.buildSelect($btnContainer,bn,opt);
}else if (opt.type=="smilebox") {
this.buildSmilebox($btnContainer,bn,opt);
}else{
this.buildButton($btnContainer,bn,opt);
}
}
},this));
//fix for hide tooltip on quick mouse over
this.$toolbar.find(".btn-tooltip").hover(function () {$(this).parent().css("overflow","hidden")},function() {$(this).parent().css("overflow","visible")});
//build bbcode switch button
//var $bbsw = $('<div class="wysibb-toolbar-container modeSwitch"><div class="wysibb-toolbar-btn" unselectable="on"><span class="btn-inner ve-tlb-bbcode" unselectable="on"></span></div></div>').appendTo(this.$toolbar);
var $bbsw = $(document.createElement('div')).addClass("wysibb-toolbar-container modeSwitch").html('<div class="wysibb-toolbar-btn mswitch" unselectable="on"><span class="btn-inner modesw" unselectable="on">[bbcode]</span></div>').appendTo(this.$toolbar);
if (this.options.bbmode==true) {$bbsw.children(".wysibb-toolbar-btn").addClass("on");}
if (this.options.onlyBBmode===false) {
$bbsw.children(".wysibb-toolbar-btn").click($.proxy(function(e) {
$(e.currentTarget).toggleClass("on");
this.modeSwitch();
},this));
}
},
buildButton: function(container,bn,opt) {
if (typeof(container)!="object") {
container = this.$toolbar;
}
var btnHTML = (opt.buttonHTML) ? $(this.strf(opt.buttonHTML,this.options)).addClass("btn-inner") : this.strf('<span class="btn-inner btn-text">{text}</span>',{text:opt.buttonText.replace(/</g,"&lt;")});
var hotkey = (this.options.hotkeys===true && this.options.showHotkeys===true && opt.hotkey) ? (' <span class="tthotkey">['+opt.hotkey+']</span>'):""
var $btn = $('<div class="wysibb-toolbar-btn wbb-'+bn+'">').appendTo(container).append(btnHTML).append(this.strf('<span class="btn-tooltip">{title}<ins/>{hotkey}</span>',{title:opt.title,hotkey:hotkey}));
//attach events
this.controllers.push($btn);
$btn.bind('queryState',$.proxy(function(e) {
(this.queryState(bn)) ? $(e.currentTarget).addClass("on"):$(e.currentTarget).removeClass("on");
},this));
$btn.mousedown($.proxy(function(e) {
e.preventDefault();
this.execCommand(bn,opt.exvalue || false);
$(e.currentTarget).trigger('queryState');
},this));
},
buildColorpicker: function(container,bn,opt) {
var $btn = $('<div class="wysibb-toolbar-btn wbb-dropdown wbb-cp">').appendTo(container).append('<div class="ve-tlb-colorpick"><span class="fonticon">\uE010</span><span class="cp-line"></span></div><ins class="fonticon ar">\uE011</ins>').append(this.strf('<span class="btn-tooltip">{title}<ins/></span>',{title:opt.title}));
var $cpline = $btn.find(".cp-line");
var $dropblock = $('<div class="wbb-list">').appendTo($btn);
$dropblock.append('<div class="nc">'+CURLANG.auto+'</div>');
var colorlist = (opt.colors) ? opt.colors.split(","):[];
for (var j=0; j<colorlist.length; j++) {
colorlist[j] = $.trim(colorlist[j]);
if (colorlist[j]=="-") {
//insert padding
$dropblock.append('<span class="pl"></span>');
}else{
$dropblock.append(this.strf('<div class="sc" style="background:{color}" title="{color}"></div>',{color:colorlist[j]}));
}
}
var basecolor = $(document.body).css("color");
//attach events
this.controllers.push($btn);
$btn.bind('queryState',$.proxy(function(e) {
//queryState
$cpline.css("background-color",basecolor);
var r = this.queryState(bn,true);
if (r) {
$cpline.css("background-color",(this.options.bbmode) ? r.color:r);
$btn.find(".ve-tlb-colorpick span.fonticon").css("color",(this.options.bbmode) ? r.color:r);
}
},this));
$btn.mousedown($.proxy(function(e) {
e.preventDefault();
this.dropdownclick(".wbb-cp",".wbb-list",e);
},this));
$btn.find(".sc").mousedown($.proxy(function(e) {
e.preventDefault();
this.selectLastRange();
var c = $(e.currentTarget).attr("title");
this.execCommand(bn,c);
$btn.trigger('queryState');
},this));
$btn.find(".nc").mousedown($.proxy(function(e) {
e.preventDefault();
this.selectLastRange();
this.execCommand(bn,basecolor);
$btn.trigger('queryState');
},this));
$btn.mousedown(function(e) {
if (e.preventDefault) e.preventDefault();
});
},
buildTablepicker: function(container,bn,opt) {
var $btn = $('<div class="wysibb-toolbar-btn wbb-dropdown wbb-tbl">').appendTo(container).append('<span class="btn-inner fonticon ve-tlb-table1">\uE00e</span><ins class="fonticon ar">\uE011</ins>').append(this.strf('<span class="btn-tooltip">{title}<ins/></span>',{title:opt.title}));
var $listblock = $('<div class="wbb-list">').appendTo($btn);
var $dropblock = $('<div>').css({"position":"relative","box-sizing":"border-box"}).appendTo($listblock);
var rows = opt.rows || 10;
var cols = opt.cols || 10;
var allcount = rows*cols;
$dropblock.css("height",(rows*opt.cellwidth+2)+"px");
for (var j=1; j<=cols; j++) {
for (var h=1; h<=rows; h++) {
//var html = this.strf('<div class="tbl-sel" style="width:{width}px;height:{height}px;z-index:{zindex}" title="{row},{col}"></div>',{width: (j*opt.cellwidth),height: (h*opt.cellwidth),zindex: --allcount,row:h,col:j});
var html = '<div class="tbl-sel" style="width:'+(j*100/cols)+'%;height:'+(h*100/rows)+'%;z-index:'+(--allcount)+'" title="'+h+','+j+'"></div>';
$dropblock.append(html);
}
}
//this.debug("Attach event on: tbl-sel");
$btn.find(".tbl-sel").mousedown($.proxy(function(e) {
e.preventDefault();
var t = $(e.currentTarget).attr("title");
var rc = t.split(",");
var code = (this.options.bbmode) ? '[table]':'<table class="wbb-table" cellspacing="5" cellpadding="0">';
for (var i=1; i<=rc[0]; i++) {
code += (this.options.bbmode) ? ' [tr]\n':'<tr>';
for (var j=1; j<=rc[1]; j++) {
code += (this.options.bbmode) ? ' [td][/td]\n':'<td>\uFEFF</td>';
}
code += (this.options.bbmode) ? '[/tr]\n':'</tr>';
}
code += (this.options.bbmode) ? '[/table]':'</table>';
this.insertAtCursor(code);
},this));
//this.debug("END Attach event on: tbl-sel");
$btn.mousedown($.proxy(function(e) {
e.preventDefault();
this.dropdownclick(".wbb-tbl",".wbb-list",e);
},this));
},
buildSelect: function(container,bn,opt) {
var $btn = $('<div class="wysibb-toolbar-btn wbb-select wbb-'+bn+'">').appendTo(container).append(this.strf('<span class="val">{title}</span><ins class="fonticon sar">\uE012</ins>',opt)).append(this.strf('<span class="btn-tooltip">{title}<ins/></span>',{title:opt.title}));
var $sblock = $('<div class="wbb-list">').appendTo($btn);
var $sval = $btn.find("span.val");
var olist = ($.isArray(opt.options)) ? opt.options:opt.options.split(",");
var $selectbox = (this.isMobile) ? $("<select>").addClass("wbb-selectbox"):"";
for (var i=0; i<olist.length; i++) {
var oname = olist[i];
if (typeof(oname)=="string") {
var option = this.options.allButtons[oname];
if (option) {
//$.log("create: "+oname);
if (option.html) {
$('<span>').addClass("option").attr("oid",oname).attr("cmdvalue",option.exvalue).appendTo($sblock).append(this.strf(option.html,{seltext:option.title}));
}else{
$sblock.append(this.strf('<span class="option" oid="'+oname+'" cmdvalue="'+option.exvalue+'">{title}</span>',option));
}
//SelectBox for mobile devices
if (this.isMobile) {
$selectbox.append($('<option>').attr("oid",oname).attr("cmdvalue",option.exvalue).append(option.title));
}
}
}else{
//build option list from array
var params = {
seltext: oname.title
}
params[opt.valueBBname]=oname.exvalue;
$('<span>').addClass("option").attr("oid",bn).attr("cmdvalue",oname.exvalue).appendTo($sblock).append(this.strf(opt.html,params));
if (this.isMobile) {$selectbox.append($('<option>').attr("oid",bn).attr("cmdvalue",oname.exvalue).append(oname.exvalue))}
}
}
//$sblock.append($selectbox);
if (this.isMobile) {
$selectbox.appendTo(container);
this.controllers.push($selectbox);
$selectbox.bind('queryState',$.proxy(function(e) {
//queryState
$selectbox.find("option").each($.proxy(function(i,el){
var $el = $(el);
var r = this.queryState($el.attr("oid"),true);
var cmdvalue = $el.attr("cmdvalue");
if ((cmdvalue && r==$el.attr("cmdvalue")) || (!cmdvalue && r)) {
$el.prop("selected",true);
return false;
}
},this));
},this));
$selectbox.change($.proxy(function(e) {
e.preventDefault();
var $o = $(e.currentTarget).find(":selected");
var oid = $o.attr("oid");
var cmdvalue = $o.attr("cmdvalue");
var opt = this.options.allButtons[oid];
this.execCommand(oid,opt.exvalue || cmdvalue || false);
$(e.currentTarget).trigger('queryState');
},this));
}
this.controllers.push($btn);
$btn.bind('queryState',$.proxy(function(e) {
//queryState
$sval.text(opt.title);
$btn.find(".option.selected").removeClass("selected");
$btn.find(".option").each($.proxy(function(i,el){
var $el = $(el);
var r = this.queryState($el.attr("oid"),true);
var cmdvalue = $el.attr("cmdvalue");
if ((cmdvalue && r==$el.attr("cmdvalue")) || (!cmdvalue && r)) {
$sval.text($el.text());
$el.addClass("selected");
return false;
}
},this));
},this));
$btn.mousedown($.proxy(function(e) {
e.preventDefault();
this.dropdownclick(".wbb-select",".wbb-list",e);
},this));
$btn.find(".option").mousedown($.proxy(function(e) {
e.preventDefault();
var oid = $(e.currentTarget).attr("oid");
var cmdvalue = $(e.currentTarget).attr("cmdvalue");
var opt = this.options.allButtons[oid];
this.execCommand(oid,opt.exvalue || cmdvalue || false);
$(e.currentTarget).trigger('queryState');
},this));
},
buildSmilebox: function(container,bn,opt) {
if (this.options.smileList && this.options.smileList.length>0) {
var $btnHTML = $(this.strf(opt.buttonHTML,opt)).addClass("btn-inner");
var $btn = $('<div class="wysibb-toolbar-btn wbb-smilebox wbb-'+bn+'">').appendTo(container).append($btnHTML).append(this.strf('<span class="btn-tooltip">{title}<ins/></span>',{title:opt.title}));
var $sblock = $('<div class="wbb-list">').appendTo($btn);
if ($.isArray(this.options.smileList)) {
$.each(this.options.smileList,$.proxy(function(i,sm){
$('<span>').addClass("smile").appendTo($sblock).append($(this.strf(sm.img,this.options)).attr("title",sm.title));
},this));
}
$btn.mousedown($.proxy(function(e) {
e.preventDefault();
this.dropdownclick(".wbb-smilebox",".wbb-list",e);
},this));
$btn.find('.smile').mousedown($.proxy(function(e) {
e.preventDefault();
//this.selectLastRange();
this.insertAtCursor((this.options.bbmode) ? this.toBB($(e.currentTarget).html()):$($(e.currentTarget).html()));
},this))
}
},
updateUI: function(e) {
if (!e || ((e.which>=8 && e.which<=46) || e.which>90 || e.type=="mouseup")) {
$.each(this.controllers,$.proxy(function(i,$btn) {
$btn.trigger('queryState');
},this));
}
//check for onlyClearText
this.disNonActiveButtons();
},
initModal: function() {
this.$modal=$("#wbbmodal");
if (this.$modal.size()==0) {
$.log("Init modal");
this.$modal = $('<div>').attr("id","wbbmodal").prependTo(document.body)
.html('<div class="wbbm"><div class="wbbm-title"><span class="wbbm-title-text"></span><span class="wbbclose" title="'+CURLANG.close+'">×</span></div><div class="wbbm-content"></div><div class="wbbm-bottom"><button id="wbbm-submit" class="wbb-button">'+CURLANG.save+'</button><button id="wbbm-cancel" class="wbb-cancel-button">'+CURLANG.cancel+'</button><button id="wbbm-remove" class="wbb-remove-button">'+CURLANG.remove+'</button></div></div>').hide();
this.$modal.find('#wbbm-cancel,.wbbclose').click($.proxy(this.closeModal,this));
this.$modal.bind('click',$.proxy(function(e) {
if ($(e.target).parents(".wbbm").size()==0) {
this.closeModal();
}
},this));
$(document).bind("keydown",$.proxy(this.escModal,this)); //ESC key close modal
}
},
initHotkeys: function() {
$.log("initHotkeys");
this.hotkeys=[];
var klist = "0123456789 abcdefghijklmnopqrstuvwxyz";
$.each(this.options.allButtons,$.proxy(function(cmd,opt) {
if (opt.hotkey) {
var keys = opt.hotkey.split("+");
if (keys && keys.length>=2) {
var metasum=0;
var key = keys.pop();
$.each(keys,function(i,k) {
switch($.trim(k.toLowerCase())) {
case "ctrl": {metasum+=1;break;}
case "shift": {metasum+=4;break;}
case "alt": {metasum+=7;break;}
}
})
//$.log("metasum: "+metasum+" key: "+key+" code: "+(klist.indexOf(key)+48));
if (metasum>0) {
if (!this.hotkeys["m"+metasum]) {this.hotkeys["m"+metasum]=[];}
this.hotkeys["m"+metasum]["k"+(klist.indexOf(key)+48)]=cmd;
}
}
}
},this))
},
presskey: function(e) {
if (e.ctrlKey==true || e.shiftKey==true || e.altKey==true) {
var metasum = ((e.ctrlKey==true) ? 1:0)+((e.shiftKey==true) ? 4:0)+((e.altKey==true) ? 7:0);
if (this.hotkeys["m"+metasum] && this.hotkeys["m"+metasum]["k"+e.which]) {
this.execCommand(this.hotkeys["m"+metasum]["k"+e.which],false);
e.preventDefault();
return false;
}
}
},
//COgdfMMAND FUNCTIONS
execCommand: function(command,value) {
$.log("execCommand: "+command);
var opt = this.options.allButtons[command];
if (opt.en!==true) {return false;}
var queryState = this.queryState(command,value);
//check for onlyClearText
var skipcmd = this.isInClearTextBlock();
if (skipcmd && skipcmd!=command) {return;}
if (opt.excmd) {
//use NativeCommand
if (this.options.bbmode) {
$.log("Native command in bbmode: "+command);
if (queryState && opt.subInsert!=true) {
//remove bbcode
this.wbbRemoveCallback(command,value);
}else{
//insert bbcode
var v = {};
if (opt.valueBBname && value) {
v[opt.valueBBname]=value;
}
this.insertAtCursor(this.getBBCodeByCommand(command,v));
}
}else{
this.execNativeCommand(opt.excmd,value || false);
}
}else if (!opt.cmd) {
//wbbCommand
//this.wbbExecCommand(command,value,queryState,$.proxy(this.wbbInsertCallback,this),$.proxy(this.wbbRemoveCallback,this));
this.wbbExecCommand.call(this,command,value,queryState);
}else{
//user custom command
opt.cmd.call(this,command,value,queryState);
}
this.updateUI();
},
queryState: function(command,withvalue) {
var opt = this.options.allButtons[command];
if (opt.en!==true) {return false;}
//if (opt.subInsert===true && opt.type!="colorpicker") {return false;}
if (this.options.bbmode) {
//bbmode
if (opt.bbSelector) {
for (var i=0; i<opt.bbSelector.length; i++) {
var b = this.isBBContain(opt.bbSelector[i]);
if (b) {
return this.getParams(b,opt.bbSelector[i],b[1]);
}
}
}
return false;
}else{
if (opt.excmd) {
//native command
if (withvalue) {
try {
//Firefox fix
var v = (document.queryCommandValue(opt.excmd)+"").replace(/\'/g,"");
if (opt.excmd=="foreColor") {
v = this.rgbToHex(v);
}
//return (v==value);
return v;
}catch(e) {return false;}
}else{
try { //Firefox fix, exception while get queryState for UnorderedList
if ((opt.excmd=="bold" || opt.excmd=="italic" || opt.excmd=="underline" || opt.excmd=="strikeThrough") && $(this.getSelectNode()).is("img")) { //Fix, when img selected
return false;
}else if (opt.excmd=="underline" && $(this.getSelectNode()).closest("a").size()>0) { //fix, when link select
return false;
}
return document.queryCommandState(opt.excmd);
}catch(e) {return false;}
}
}else{
//custom command
if ($.isArray(opt.rootSelector)) {
for (var i=0; i<opt.rootSelector.length; i++) {
var n = this.isContain(this.getSelectNode(),opt.rootSelector[i]);
if (n) {
return this.getParams(n,opt.rootSelector[i]);
}
}
}
return false;
}
}
},
wbbExecCommand: function(command,value,queryState) { //default command for custom bbcodes
$.log("wbbExecCommand");
var opt = this.options.allButtons[command];
if (opt) {
if (opt.modal) {
if ($.isFunction(opt.modal)) {
//custom modal function
//opt.modal(command,opt.modal,queryState,new clbk(this));
opt.modal.call(this,command,opt.modal,queryState);
}else{
this.showModal.call(this,command,opt.modal,queryState);
}
}else{
if (queryState && opt.subInsert!=true) {
//remove formatting
//removeCallback(command,value);
this.wbbRemoveCallback(command);
}else{
//insert format
if (opt.groupkey) {
var groupsel = this.options.groups[opt.groupkey];
if (groupsel) {
var snode = this.getSelectNode();
$.each(groupsel,$.proxy(function(i,sel) {
var is = this.isContain(snode,sel);
if (is) {
var $sp = $('<span>').html(is.innerHTML)
var id = this.setUID($sp);
$(is).replaceWith($sp);
this.selectNode(this.$editor.find("#"+id)[0]);
return false;
}
},this));
}
}
this.wbbInsertCallback(command,value)
}
}
}
},
wbbInsertCallback: function(command,paramobj) {
if (typeof(paramobj)!="object") {paramobj={}};
$.log("wbbInsertCallback: "+command);
var data = this.getCodeByCommand(command,paramobj);
this.insertAtCursor(data);
if (this.seltextID && data.indexOf(this.seltextID)!=-1) {
var snode = this.$body.find("#"+this.seltextID)[0];
this.selectNode(snode);
$(snode).removeAttr("id");
this.seltextID=false;
}
},
wbbRemoveCallback: function(command,clear) {
$.log("wbbRemoveCallback: "+command);
var opt = this.options.allButtons[command];
if (this.options.bbmode) {
//bbmode
//REMOVE BBCODE
var pos = this.getCursorPosBB();
var stextnum=0;
$.each(opt.bbSelector,$.proxy(function(i,bbcode) {
var stext = bbcode.match(/\{[\s\S]+?\}/g);
$.each(stext,function(n,s) {
if (s.toLowerCase()=="{seltext}") {stextnum=n;return false}
});
var a = this.isBBContain(bbcode);
if (a) {
this.txtArea.value = this.txtArea.value.substr(0,a[1])+this.txtArea.value.substr(a[1],this.txtArea.value.length-a[1]).replace(a[0][0],(clear===true) ? '':a[0][stextnum+1]);
this.setCursorPosBB(a[1]);
return false;
}
},this));
}else{
var node = this.getSelectNode();
$.each(opt.rootSelector,$.proxy(function(i,s) {
//$.log("RS: "+s);
var root = this.isContain(node,s);
if (!root) {return true;}
var $root = $(root);
var cs = this.options.rules[s][0][1];
if ($root.is("span[wbb]") || !$root.is("span,font")) { //remove only blocks
if (clear===true || (!cs || !cs["seltext"])) {
this.setCursorByEl($root);
$root.remove();
}else{
if (cs && cs["seltext"] && cs["seltext"]["sel"]) {
var htmldata = $root.find(cs["seltext"]["sel"]).html();
if (opt.onlyClearText===true) {
htmldata = this.getHTML(htmldata,true,true);
htmldata = htmldata.replace(/\&#123;/g,"{").replace(/\&#125;/g,"}");
}
$root.replaceWith(htmldata);
}else{
var htmldata = $root.html();
if (opt.onlyClearText===true) {
htmldata = this.getHTML(htmldata,true);
htmldata = htmldata.replace(/\&lt;/g,"<").replace(/\&gt;/g,">").replace(/\&#123;/g,"{").replace(/\&#125;/g,"}");
}
$root.replaceWith(htmldata);
}
}
return false;
}else{
//span,font - extract select content from this span,font
var rng = this.getRange();
var shtml = this.getSelectText();
var rnode = this.getSelectNode();
if (shtml=="") {
shtml="\uFEFF";
}else{
shtml = this.clearFromSubInsert(shtml,command);
}
var ins = this.elFromString(shtml);
var before_rng = (window.getSelection) ? rng.cloneRange():this.body.createTextRange();
var after_rng = (window.getSelection) ? rng.cloneRange():this.body.createTextRange();
if (window.getSelection) {
this.insertAtCursor('<span id="wbbdivide"></span>');
var div = $root.find('span#wbbdivide').get(0);
before_rng.setStart(root.firstChild,0);
before_rng.setEndBefore(div);
after_rng.setStartAfter(div);
after_rng.setEndAfter(root.lastChild);
}else{
before_rng.moveToElementText(root);
after_rng.moveToElementText(root);
before_rng.setEndPoint('EndToStart',rng);
after_rng.setEndPoint('StartToEnd',rng);
}
var bf = this.getSelectText(false,before_rng);
var af = this.getSelectText(false,after_rng);
if (af!="") {
var $af = $root.clone().html(af);
$root.after($af);
}
if (clear!==true) $root.after(ins); //insert select html
if (window.getSelection) {
$root.html(bf);
if (clear!==true) this.selectNode(ins);
}else{
$root.replaceWith(bf);
}
return false;
}
},this));
}
},
execNativeCommand: function(cmd,param) {
//$.log("execNativeCommand: '"+cmd+"' : "+param);
this.body.focus(); //set focus to frame body
if (cmd=="insertHTML" && !window.getSelection) { //IE does't support insertHTML
var r = (this.lastRange) ? this.lastRange:document.selection.createRange(); //IE 7,8 range lost fix
r.pasteHTML(param);
var txt = $('<div>').html(param).text(); //for ie selection inside block
var brsp = txt.indexOf("\uFEFF");
if (brsp>-1) {
r.moveStart('character',(-1)*(txt.length-brsp));
r.select();
}
this.lastRange=false;
}else if (cmd=="insertHTML") { //fix webkit bug with insertHTML
var sel = this.getSelection();
var e = this.elFromString(param);
var rng = (this.lastRange) ? this.lastRange:this.getRange();
rng.deleteContents();
rng.insertNode(e);
rng.collapse(false);
sel.removeAllRanges();
sel.addRange(rng);
}else{
if (typeof param == "undefined") {param=false;}
if (this.lastRange) {
$.log("Last range select");
this.selectLastRange()
}
document.execCommand(cmd, false, param);
}
},
getCodeByCommand: function(command,paramobj) {
return (this.options.bbmode) ? this.getBBCodeByCommand(command,paramobj):this.getHTMLByCommand(command,paramobj);
},
getBBCodeByCommand: function(command,params) {
if (!this.options.allButtons[command]) {return "";}
if (typeof(params)=="undefined") {params={};}
params = this.keysToLower(params);
if (!params["seltext"]) {
//get selected text
params["seltext"] = this.getSelectText(true);
}
var bbcode = this.options.allButtons[command].bbcode;
//bbcode = this.strf(bbcode,params);
bbcode = bbcode.replace(/\{(.*?)(\[.*?\])*\}/g,function(str,p,vrgx) {
if (vrgx) {
var vrgxp;
if (vrgx) {
vrgxp = new RegExp(vrgx+"+","i");
}
if (typeof(params[p.toLowerCase()])!="undefined" && params[p.toLowerCase()].toString().match(vrgxp)===null) {
//not valid value
return "";
}
}
return (typeof(params[p.toLowerCase()])=="undefined") ? "":params[p.toLowerCase()];
});
//insert first with max params
var rbbcode=null,maxpcount=0;
if (this.options.allButtons[command].transform) {
var tr=[];
$.each(this.options.allButtons[command].transform,function(html,bb) {
tr.push(bb);
});
tr=this.sortArray(tr,-1);
$.each(tr,function(i,v) {
var valid=true,pcount=0,pname={};;
v = v.replace(/\{(.*?)(\[.*?\])*\}/g,function(str,p,vrgx) {
var vrgxp;
p = p.toLowerCase();
if (vrgx) {
vrgxp = new RegExp(vrgx+"+","i");
}
if (typeof(params[p.toLowerCase()])=="undefined" || (vrgx && params[p.toLowerCase()].toString().match(vrgxp)===null)) {valid=false;};
if (typeof(params[p])!="undefined" && !pname[p]) {pname[p]=1;pcount++;}
return (typeof(params[p.toLowerCase()])=="undefined") ? "":params[p.toLowerCase()];
});
if (valid && (pcount>maxpcount)) {rbbcode = v;maxpcount=pcount;}
});
}
return rbbcode || bbcode;
},
getHTMLByCommand: function(command,params) {
if (!this.options.allButtons[command]) {return "";}
params = this.keysToLower(params);
if (typeof(params)=="undefined") {params={};}
if (!params["seltext"]) {
//get selected text
params["seltext"] = this.getSelectText(false);
//$.log("seltext: '"+params["seltext"]+"'");
if (params["seltext"]=="") {params["seltext"]="\uFEFF";}
else{
//clear selection from current command tags
params["seltext"] = this.clearFromSubInsert(params["seltext"],command);
//toBB if params onlyClearText=true
if (this.options.allButtons[command].onlyClearText===true) {
params["seltext"] = this.toBB(params["seltext"]).replace(/\</g,"&lt;").replace(/\n/g,"<br/>").replace(/\s{3}/g,'<span class="wbbtab"></span>');
}
}
}
var postsel="";
this.seltextID = "wbbid_"+(++this.lastid);
if (command!="link" && command!="img") {
params["seltext"] = '<span id="'+this.seltextID+'">'+params["seltext"]+'</span>'; //use for select seltext
}else{
postsel = '<span id="'+this.seltextID+'">\uFEFF</span>'
}
var html = this.options.allButtons[command].html;
html = html.replace(/\{(.*?)(\[.*?\])*\}/g,function(str,p,vrgx) {
if (vrgx) {
var vrgxp = new RegExp(vrgx+"+","i");
if (typeof(params[p.toLowerCase()])!="undefined" && params[p.toLowerCase()].toString().match(vrgxp)===null) {
//not valid value
return "";
}
}
return (typeof(params[p.toLowerCase()])=="undefined") ? "":params[p.toLowerCase()];
});
//insert first with max params
var rhtml=null,maxpcount=0;
if (this.options.allButtons[command].transform) {
var tr=[];
$.each(this.options.allButtons[command].transform,function(html,bb) {
tr.push(html);
});
tr=this.sortArray(tr,-1);
$.each(tr,function(i,v) {
var valid=true, pcount=0,pname={};
v = v.replace(/\{(.*?)(\[.*?\])*\}/g,function(str,p,vrgx) {
var vrgxp;
p = p.toLowerCase();
if (vrgx) {
vrgxp = new RegExp(vrgx+"+","i");
}
if (typeof(params[p])=="undefined" || (vrgx && params[p].toString().match(vrgxp)===null)) {valid=false;};
if (typeof(params[p])!="undefined" && !pname[p]) {pname[p]=1;pcount++;}
return (typeof(params[p])=="undefined") ? "":params[p];
});
if (valid && (pcount>maxpcount)) {rhtml = v;maxpcount=pcount;}
});
}
return (rhtml || html)+postsel;
},
//SELECTION FUNCTIONS
getSelection: function() {
if (window.getSelection) {
return window.getSelection();
}else if (document.selection) {
return (this.options.bbmode) ? document.selection.createRange():document.selection.createRange();
}
},
getSelectText: function(fromTxtArea,range) {
if (fromTxtArea) {
//return select text from textarea
this.txtArea.focus();
if('selectionStart' in this.txtArea) {
var l = this.txtArea.selectionEnd - this.txtArea.selectionStart;
return this.txtArea.value.substr(this.txtArea.selectionStart, l);
}else{
//IE
var r = document.selection.createRange();
return r.text;
}
}else{
//return select html from body
this.body.focus();
if (!range) {range=this.getRange()};
if (window.getSelection) {
//w3c
if (range) {
return $('<div>').append(range.cloneContents()).html();
}
}else{
//ie
return range.htmlText;
}
}
return "";
},
getRange: function() {
if (window.getSelection) {
var sel = this.getSelection();
if (sel.getRangeAt && sel.rangeCount>0) {
return sel.getRangeAt(0);
}else if (sel.anchorNode) {
var range = (this.options.bbmode) ? document.createRange() : document.createRange();
range.setStart (sel.anchorNode, sel.anchorOffset);
range.setEnd (sel.focusNode, sel.focusOffset);
return range;
}
}else{
return (this.options.bbmode===true) ? document.selection.createRange():document.selection.createRange();
}
},
insertAtCursor: function(code,forceBBMode) {
if (typeof(code)!="string") {code = $("<div>").append(code).html();}
if ((this.options.bbmode && typeof(forceBBMode)=="undefined") || forceBBMode===true) {
var clbb = code.replace(/.*(\[\/\S+?\])$/,"$1");
var p = this.getCursorPosBB()+((code.indexOf(clbb)!=-1 && code.match(/\[.*\]/)) ? code.indexOf(clbb):code.length);
if (document.selection) {
//IE
this.txtArea.focus();
this.getSelection().text=code;
}else if (this.txtArea.selectionStart || this.txtArea.selectionStart == '0') {
this.txtArea.value = this.txtArea.value.substring(0, this.txtArea.selectionStart) + code + this.txtArea.value.substring(this.txtArea.selectionEnd, this.txtArea.value.length);
}
if (p<0) {p=0;}
this.setCursorPosBB(p);
}else{
this.execNativeCommand("insertHTML",code);
var node = this.getSelectNode();
if (!$(node).closest("table,tr,td")) {
this.splitPrevNext(node);
}
}
},
getSelectNode: function(rng) {
this.body.focus();
if (!rng) {rng=this.getRange();}
if (!rng) {return this.$body;}
//return (window.getSelection) ? rng.commonAncestorContainer:rng.parentElement();
var sn = (window.getSelection) ? rng.commonAncestorContainer:rng.parentElement();
if ($(sn).is(".imgWrap")) {sn = $(sn).children("img")[0];}
return sn;
},
getCursorPosBB: function() {
var pos=0;
if ('selectionStart' in this.txtArea) {
pos = this.txtArea.selectionStart;
}else{
this.txtArea.focus();
var r = this.getRange();
var rt = document.body.createTextRange();
rt.moveToElementText(this.txtArea);
rt.setEndPoint('EndToStart',r);
pos = rt.text.length;
}
return pos;
},
setCursorPosBB: function(pos) {
if (this.options.bbmode) {
if (window.getSelection) {
this.txtArea.selectionStart=pos;
this.txtArea.selectionEnd=pos;
}else{
var range = this.txtArea.createTextRange();
range.collapse(true);
range.move('character', pos);
range.select();
}
}
},
selectNode: function(node,rng) {
if (!rng) {rng = this.getRange();}
if (!rng) {return;}
if (window.getSelection) {
var sel = this.getSelection();
rng.selectNodeContents(node)
sel.removeAllRanges();
sel.addRange(rng);
}else{
rng.moveToElementText(node);
rng.select();
}
},
selectRange: function(rng) {
if (rng) {
if (!window.getSelection) {
rng.select();
}else{
var sel = this.getSelection();
sel.removeAllRanges();
sel.addRange(rng);
}
}
},
cloneRange: function(rng) {
if (rng) {
if (!window.getSelection) {
return rng.duplicate();
}else{
return rng.cloneRange();
}
}
},
getRangeClone: function() {
return this.cloneRange(this.getRange());
},
saveRange: function() {
this.setBodyFocus();
//this.lastRange=(this.options.bbmode) ? this.getCursorPosBB():this.getRangeClone();
this.lastRange=this.getRangeClone();
},
selectLastRange: function() {
if (this.lastRange) {
this.body.focus();
this.selectRange(this.lastRange);
this.lastRange=false;
}
},
setBodyFocus: function() {
$.log("Set focus to WysiBB editor");
if (this.options.bbmode) {
if (!this.$txtArea.is(":focus")) {
this.$txtArea.focus();
}
}else{
if (!this.$body.is(":focus")) {
this.$body.focus();
}
}
},
clearLastRange: function() {
this.lastRange=false;
},
//TRANSFORM FUNCTIONS
filterByNode: function(node) {
var $n = $(node);
var tagName = $n.get(0).tagName.toLowerCase();
var filter=tagName;
var attributes = this.getAttributeList($n.get(0));
$.each(attributes, $.proxy(function(i, item) {
var v = $n.attr(item);
/* $.log("v: "+v);
if ($.inArray(item,this.options.attrWrap)!=-1) {
item = '_'+item;
} */
//$.log(item);
if (item.substr(0,1)=="_") {item=item.substr(1,item.length)}
if (v && !v.match(/\{.*?\}/)) {
//$.log("I1: "+item);
if (item=="style") {
var v = $n.attr(item);
var va = v.split(";");
$.each(va,function(i,f) {
if (f && f.length>0) {
filter+='['+item+'*="'+$.trim(f)+'"]';
}
});
}else{
filter+='['+item+'="'+v+'"]';
}
}else if (v && item=="style") {
//$.log("I2: "+item);
var vf = v.substr(0,v.indexOf("{"));
if (vf && vf!="") {
var v = v.substr(0,v.indexOf("{"));
var va = v.split(";");
$.each(va,function(i,f) {
filter+='['+item+'*="'+f+'"]';
});
//filter+='['+item+'*="'+v.substr(0,v.indexOf("{"))+'"]';
}
}else{ //1.2.2
//$.log("I3: "+item);
filter+='['+item+']';
}
},this));
//index
var idx = $n.parent().children(filter).index($n);
if (idx>0) {
filter+=":eq("+$n.index()+")";
}
return filter;
},
relFilterByNode: function(node,stop) {
var p="";
$.each(this.options.attrWrap,function(i,a) {
stop = stop.replace('['+a,'[_'+a);
});
while (node && node.tagName!="BODY" && !$(node).is(stop)) {
p=this.filterByNode(node)+" "+p;
if (node) {node = node.parentNode;}
}
return p;
},
getRegexpReplace: function(str,validname) {
str = str.replace(/(\(|\)|\[|\]|\.|\*|\?|\:|\\)/g,"\\$1")
.replace(/\s+/g,"\\s+")
.replace(validname.replace(/(\(|\)|\[|\]|\.|\*|\?|\:|\\)/g,"\\$1"),"(.+)")
.replace(/\{\S+?\}/g,".*");
return (str);
},
getBBCode: function() {
if (!this.options.rules) {return this.$txtArea.val();}
if (this.options.bbmode) {return this.$txtArea.val();}
this.clearEmpty();
this.removeLastBodyBR();
return this.toBB(this.$body.html());
},
toBB: function(data) {
if (!data) {return "";};
var $e = (typeof(data)=="string") ? $('<span>').html(data):$(data);
//remove last BR
$e.find("div,blockquote,p").each(function() {
if (this.nodeType!=3 && this.lastChild && this.lastChild.tagName=="BR") {
$(this.lastChild).remove();
}
})
if ($e.is("div,blockquote,p") && $e[0].nodeType!=3 && $e[0].lastChild && $e[0].lastChild.tagName=="BR") {
$($e[0].lastChild).remove();
}
//END remove last BR
//Remove BR
$e.find("ul > br, table > br, tr > br").remove();
//IE
var outbb="";
//transform smiles
$.each(this.options.srules,$.proxy(function(s,bb) {
$e.find(s).replaceWith(bb[0]);
},this));
$e.contents().each($.proxy(function(i,el) {
var $el = $(el);
if (el.nodeType===3) {
outbb+=el.data.replace(/\n+/,"").replace(/\t/g," ");
}else{
//process html tag
var rpl,processed=false;
//for (var rootsel in this.options.rules) {
for (var j=0; j<this.rsellist.length; j++) {
var rootsel = this.rsellist[j];
if ($el && $el.is(rootsel)) {
//it is root sel
var rlist = this.options.rules[rootsel];
for (var i=0; i<rlist.length; i++) {
var bbcode = rlist[i][0];
var crules = rlist[i][1];
var skip=false,keepElement=false,keepAttr=false;
if (!$el.is("br")) {
bbcode = bbcode.replace(/\n/g,"<br>");
}
bbcode = bbcode.replace(/\{(.*?)(\[.*?\])*\}/g,$.proxy(function(str,s,vrgx) {
var c = crules[s.toLowerCase()];
//if (typeof(c)=="undefined") {$.log("Param: {"+s+"} not found in HTML representation.");skip=true;return s;}
if (typeof(c)=="undefined") {$.log("Param: {"+s+"} not found in HTML representation.");skip=true;}
var $cel = (c.sel) ? $(el).find(c.sel):$(el);
if (c.attr && !$cel.attr(c.attr)) {skip=true;return s;} //skip if needed attribute not present, maybe other bbcode
var cont = (c.attr) ? $cel.attr(c.attr):$cel.html();
if (typeof(cont)=="undefined" || cont==null) {skip=true;return s;}
var regexp = c.rgx;
//style fix
if (regexp && c.attr=="style" && regexp.substr(regexp.length-1,1)!=";") {
regexp+=";";
}
if (c.attr=="style" && cont && cont.substr(cont.length-1,1)!=";") {cont+=";"}
//prepare regexp
var rgx = (regexp) ? new RegExp(regexp,""):false;
if (rgx) {
if (cont.match(rgx)) {
var m = cont.match(rgx);
if (m && m.length==2) {
cont=m[1];
}
}else{
cont="";
}
}
//if it is style attr, then keep tag alive, remove this style
if (c.attr && skip===false) {
if (c.attr=="style") {
keepElement=true;
var nstyle="";
var r = c.rgx.replace(/^\.\*\?/,"").replace(/\.\*$/,"").replace(/;$/,"");
$($cel.attr("style").split(";")).each(function(idx,style) {
if (style && style!="") {
if (!style.match(r)) {
nstyle+=style+";";
}
}
});
if (nstyle=="") {
$cel.removeAttr("style");
}else{
$cel.attr("style",nstyle);
}
}else if (c.rgx===false){
keepElement=true;
keepAttr=true;
$cel.removeAttr(c.attr);
}
}
if ($el.is('table,tr,td,font')) {keepElement=true;}
return cont || "";
},this));
if (skip) {continue;}
if ($el.is("img,br,hr")) {
//replace element
outbb+=bbcode;
$el=null;
break;
}else{
if (keepElement && !$el.attr("notkeep")) {
if ($el.is("table,tr,td")) {
bbcode = this.fixTableTransform(bbcode);
outbb+=this.toBB($('<span>').html(bbcode));
$el=null;
}else{
$el.empty().html('<span>'+bbcode+'</span>');
}
}else{
if ($el.is("iframe")) {
outbb+=bbcode;
}else{
$el.empty().html(bbcode);
outbb+=this.toBB($el);
$el=null;
}
break;
}
}
}
}
}
if (!$el || $el.is("iframe,img")) {return true;}
outbb+=this.toBB($el);
}
},this));
outbb.replace(/\uFEFF/g,"");
return outbb;
},
getHTML: function(bbdata,init,skiplt) {
if (!this.options.bbmode && !init) {return this.$body.html()}
if (!skiplt) {bbdata = bbdata.replace(/</g,"&lt;").replace(/\{/g,"&#123;").replace(/\}/g,"&#125;");}
bbdata = bbdata.replace(/\[code\]([\s\S]*?)\[\/code\]/g,function(s) {
s = s.substr("[code]".length,s.length-"[code]".length-"[/code]".length).replace(/\[/g,"&#91;").replace(/\]/g,"&#93;");
return "[code]"+s+"[/code]";
});
$.each(this.options.btnlist,$.proxy(function(i,b){
if (b!="|" && b!="-") {
var find=true;
if (!this.options.allButtons[b] || !this.options.allButtons[b].transform) {
return true;
}
$.each(this.options.allButtons[b].transform,$.proxy(function(html,bb) {
html = html.replace(/\n/g,""); //IE 7,8 FIX
var a=[];
bb = bb.replace(/(\(|\)|\[|\]|\.|\*|\?|\:|\\|\\)/g,"\\$1");
//.replace(/\s/g,"\\s");
bb = bb.replace(/\{(.*?)(\\\[.*?\\\])*\}/gi,$.proxy(function(str,s,vrgx) {
a.push(s);
if (vrgx) {
//has validation regexp
vrgx = vrgx.replace(/\\/g,"");
return "("+vrgx+"*?)";
}
return "([\\s\\S]*?)";
},this));
var n=0,am;
while ((am = (new RegExp(bb,"mgi")).exec(bbdata)) != null) {
if (am) {
var r={};
$.each(a,$.proxy(function(i,k) {
r[k]=am[i+1];
},this));
var nhtml = html;
nhtml = nhtml.replace(/\{(.*?)(\[.*?\])\}/g,"{$1}");
nhtml = this.strf(nhtml,r);
bbdata = bbdata.replace(am[0],nhtml);
}
}
},this));
}
},this));
//transform system codes
$.each(this.options.systr,function(html,bb) {
bb = bb.replace(/(\(|\)|\[|\]|\.|\*|\?|\:|\\|\\)/g,"\\$1")
.replace(" ","\\s");
bbdata = bbdata.replace(new RegExp(bb,"g"),html);
});
var $wrap = $(this.elFromString("<div>"+bbdata+"</div>"));
//transform smiles
/* $wrap.contents().filter(function() {return this.nodeType==3}).each($.proxy(smilerpl,this)).end().find("*").contents().filter(function() {return this.nodeType==3}).each($.proxy(smilerpl,this));
function smilerpl(i,el) {
var ndata = el.data;
$.each(this.options.smileList,$.proxy(function(i,row) {
var fidx = ndata.indexOf(row.bbcode);
if (fidx!=-1) {
var afternode_txt = ndata.substring(fidx+row.bbcode.length,ndata.length);
var afternode = document.createTextNode(afternode_txt);
el.data = ndata = el.data.substr(0,fidx);
$(el).after(afternode).after(this.strf(row.img,this.options));
}
},this));
} */
this.getHTMLSmiles($wrap);
//$wrap.contents().filter(function() {return this.nodeType==3}).each($.proxy(this,smileRPL,this));
return $wrap.html();
},
getHTMLSmiles: function(rel) {
$(rel).contents().filter(function() {return this.nodeType==3}).each($.proxy(this.smileRPL,this));
},
smileRPL: function(i,el) {
var ndata = el.data;
$.each(this.options.smileList,$.proxy(function(i,row) {
var fidx = ndata.indexOf(row.bbcode);
if (fidx!=-1) {
var afternode_txt = ndata.substring(fidx+row.bbcode.length,ndata.length);
var afternode = document.createTextNode(afternode_txt);
el.data = ndata = el.data.substr(0,fidx);
$(el).after(afternode).after(this.strf(row.img,this.options));
this.getHTMLSmiles(el.parentNode);
return false;
}
this.getHTMLSmiles(el);
},this));
},
//UTILS
setUID: function(el,attr) {
var id = "wbbid_"+(++this.lastid);
if (el) {
$(el).attr(attr || "id",id);
}
return id;
},
keysToLower: function(o) {
$.each(o,function(k,v) {
if (k!=k.toLowerCase()) {
delete o[k];
o[k.toLowerCase()]=v;
}
});
return o;
},
strf: function(str,data) {
data = this.keysToLower($.extend({},data));
return str.replace(/\{([\w\.]*)\}/g, function (str, key) {key = key.toLowerCase();var keys = key.split("."), value = data[keys.shift().toLowerCase()];$.each(keys, function () { value = value[this]; }); return (value === null || value === undefined) ? "" : value;});
},
elFromString: function(str) {
if (str.indexOf("<")!=-1 && str.indexOf(">")!=-1) {
//create tag
var wr = document.createElement("SPAN");
$(wr).html(str);
this.setUID(wr,"wbb");
return ($(wr).contents().size()>1) ? wr:wr.firstChild;
}else{
//create text node
return document.createTextNode(str);
}
},
isContain: function(node,sel) {
while (node && !$(node).hasClass("wysibb")) {
if ($(node).is(sel)) {return node};
if (node) {node = node.parentNode;}
else{return null;}
}
},
isBBContain: function(bbcode) {
var pos=this.getCursorPosBB();
var b = this.prepareRGX(bbcode);
var bbrgx = new RegExp(b,"g");
var a;
var lastindex=0;
while ((a=bbrgx.exec(this.txtArea.value))!=null) {
var p = this.txtArea.value.indexOf(a[0],lastindex);
if (pos>p && pos<(p+a[0].length)) {
return [a,p];
}
lastindex=p+1;
}
},
prepareRGX: function(r) {
return r.replace(/(\[|\]|\)|\(|\.|\*|\?|\:|\||\\)/g,"\\$1").replace(/\{.*?\}/g,"([\\s\\S]*?)");
//return r.replace(/([^a-z0-9)/ig,"\\$1").replace(/\{.*?\}/g,"([\\s\\S]*?)");
},
checkForLastBR: function(node) {
if (!node) {$node = this.body;}
if (node.nodeType==3) {node=node.parentNode;}
var $node = $(node);
if ($node.is("span[id*='wbbid']")) {$node = $node.parent();}
if (this.options.bbmode===false && $node.is('div,blockquote,code') && $node.contents().size()>0) {
var l = $node[0].lastChild;
if (!l || (l && l.tagName!="BR")) {$node.append("<br/>");}
}
if (this.$body.contents().size()>0 && this.body.lastChild.tagName!="BR") {
this.$body.append('<br/>');
}
},
getAttributeList: function(el) {
var a=[];
$.each(el.attributes,function(i,attr) {
if (attr.specified) {
a.push(attr.name);
}
});
return a;
},
clearFromSubInsert: function(html,cmd) {
if (this.options.allButtons[cmd] && this.options.allButtons[cmd].rootSelector) {
var $wr = $('<div>').html(html);
$.each(this.options.allButtons[cmd].rootSelector,$.proxy(function(i,s) {
var seltext=false;
if (typeof(this.options.rules[s][0][1]["seltext"])!="undefined") {
seltext = this.options.rules[s][0][1]["seltext"]["sel"];
}
var res=true;
$wr.find("*").each(function() { //work with find("*") and "is", becouse in ie7-8 find is case sensitive
if ($(this).is(s)) {
if (seltext && seltext["sel"]) {
$(this).replaceWith($(this).find(seltext["sel"].toLowerCase()).html());
}else{
$(this).replaceWith($(this).html());
}
res=false;
}
});
return res;
},this));
return $wr.html();
}
return html;
},
splitPrevNext: function(node) {
if (node.nodeType==3) {node = node.parentNode};
var f = this.filterByNode(node).replace(/\:eq.*$/g,"");
if ($(node.nextSibling).is(f)) {
$(node).append($(node.nextSibling).html());
$(node.nextSibling).remove();
}
if ($(node.previousSibling).is(f)) {
$(node).prepend($(node.previousSibling).html());
$(node.previousSibling).remove();
}
},
modeSwitch: function() {
if (this.options.bbmode) {
//to HTML
this.$body.html(this.getHTML(this.$txtArea.val()));
this.$txtArea.hide().removeAttr("wbbsync").val("");
this.$body.css("min-height",this.$txtArea.height()).show().focus();
}else{
//to bbcode
this.$txtArea.val(this.getBBCode()).css("min-height",this.$body.height());
this.$body.hide();
this.$txtArea.show().focus();
}
this.options.bbmode=!this.options.bbmode;
},
clearEmpty: function () {
this.$body.children().filter(emptyFilter).remove();
function emptyFilter() {
if (!$(this).is("span,font,a,b,i,u,s")) {
//clear empty only for span,font
return false;
}
if (!$(this).hasClass("wbbtab") && $.trim($(this).html()).length==0) {
return true;
}else if ($(this).children().size()>0) {
$(this).children().filter(emptyFilter).remove();
if ($(this).html().length==0 && this.tagName!="BODY") {
return true;
}
}
}
},
dropdownclick: function(bsel,tsel,e) {
//this.body.focus();
var $btn = $(e.currentTarget).closest(bsel);
if ($btn.hasClass("dis")) {return;}
if ($btn.attr("wbbshow")) {
//hide dropdown
$btn.removeAttr("wbbshow");
$(document).unbind("mousedown",this.dropdownhandler);
if (document) {
$(document).unbind("mousedown",this.dropdownhandler);
}
this.lastRange=false;
}else{
this.saveRange();
this.$editor.find("*[wbbshow]").each(function(i,el) {
$(el).removeClass("on").find($(el).attr("wbbshow")).hide().end().removeAttr("wbbshow");
})
$btn.attr("wbbshow",tsel);
$(document.body).bind("mousedown",$.proxy(function(evt) {this.dropdownhandler($btn,bsel,tsel,evt)},this));
if (this.$body) {
this.$body.bind("mousedown",$.proxy(function(evt) {this.dropdownhandler($btn,bsel,tsel,evt)},this));
}
}
$btn.find(tsel).toggle();
$btn.toggleClass("on");
},
dropdownhandler: function($btn,bsel,tsel,e) {
if ($(e.target).parents(bsel).size()==0) {
$btn.removeClass("on").find(tsel).hide();
$(document).unbind('mousedown',this.dropdownhandler);
if (this.$body) {
this.$body.unbind('mousedown',this.dropdownhandler);
}
}
},
rgbToHex: function(rgb) {
if (rgb.substr(0, 1)=='#') {return rgb;}
//if (rgb.indexOf("rgb")==-1) {return rgb;}
if (rgb.indexOf("rgb")==-1) {
//IE
var color=parseInt(rgb);
color = ((color & 0x0000ff) << 16) | (color & 0x00ff00) | ((color & 0xff0000) >>> 16);
return '#'+color.toString(16);
}
var digits = /(.*?)rgb\((\d+),\s*(\d+),\s*(\d+)\)/.exec(rgb);
return "#"+this.dec2hex(parseInt(digits[2]))+this.dec2hex(parseInt(digits[3]))+this.dec2hex(parseInt(digits[4]));
},
dec2hex: function(d) {
if(d>15) {
return d.toString(16);
}else{
return "0"+d.toString(16);
}
},
sync: function() {
if (this.options.bbmode) {
this.$body.html(this.getHTML(this.txtArea.value,true));
}else{
this.$txtArea.attr("wbbsync",1).val(this.getBBCode());
}
},
clearPaste: function(el) {
var $block = $(el);
//NEW
$.each(this.options.rules,$.proxy(function(s,ar) {
var $sf = $block.find(s).attr("wbbkeep",1);
if ($sf.size()>0) {
var s2 = ar[0][1];
$.each(s2,function(i,v) {
if (v.sel) {
$sf.find(v.sel).attr("wbbkeep",1);
}
});
}
},this));
$block.find("*[wbbkeep!='1']").each($.proxy(function(i,el) {
var $this = $(el);
if ($this.is('div,p') && ($this.children().size()==0 || el.lastChild.tagName!="BR")) {
$this.after("<br/>");
}
},this));
$block.find("*[wbbkeep]").removeAttr("wbbkeep").removeAttr("style");
$.log($block.html());
//$.log("BBCODE: "+this.toBB($block.clone(true)));
$block.html(this.getHTML(this.toBB($block),true));
$.log($block.html());
//OLD
/* $.each(this.options.rules,$.proxy(function(s,bb) {
$block.find(s).attr("wbbkeep",1);
},this));
//replace div and p without last br to html()+br
$block.find("*[wbbkeep!='1']").each($.proxy(function(i,el) {
var $this = $(el);
if ($this.is('div,p') && ($this.children().size()==0 || el.lastChild.tagName!="BR")) {
$this.after("<br/>").after($this.contents()).remove();
}else{
$this.after($this.contents()).remove();
}
},this));
$block.find("*[wbbkeep]").removeAttr("wbbkeep").removeAttr("style"); */
},
sortArray: function(ar,asc) {
ar.sort(function(a,b) {
return (a.length-b.length)*(asc || 1);
});
return ar;
},
smileFind: function() {
if (this.options.smilefind) {
var $smlist = $(this.options.smilefind).find('img[alt]');
if ($smlist.size()>0) {
this.options.smileList=[];
$smlist.each($.proxy(function(i,el) {
var $el=$(el);
this.options.smileList.push({title:$el.attr("title"),bbcode:$el.attr("alt"),img:$el.removeAttr("alt").removeAttr("title")[0].outerHTML});
},this));
}
}
},
destroy: function() {
this.$editor.replaceWith(this.$txtArea);
this.$txtArea.removeClass("wysibb-texarea").show();
this.$modal.remove();
this.$txtArea.data("wbb",null);
},
pressTab: function(e) {
if (e && e.which == 9) {
//insert tab
if (e.preventDefault) {e.preventDefault();}
if (this.options.bbmode) {
this.insertAtCursor(' ',false);
}else{
this.insertAtCursor('<span class="wbbtab">\uFEFF</span>',false);
//this.execNativeCommand("indent",false);
}
}
},
removeLastBodyBR: function() {
if (this.body.lastChild && this.body.lastChild.nodeType!=3 && this.body.lastChild.tagName=="BR") {
this.body.removeChild(this.body.lastChild);
this.removeLastBodyBR();
}
},
traceTextareaEvent: function(e) {
if ($(e.target).closest("div.wysibb").size()==0) {
if ($(document.activeElement).is("div.wysibb-body")) {
this.saveRange();
}
setTimeout($.proxy(function() {
var data = this.$txtArea.val();
if (this.options.bbmode===false && data!="" && $(e.target).closest("div.wysibb").size()==0 && !this.$txtArea.attr("wbbsync")) {
this.selectLastRange();
this.insertAtCursor(this.getHTML(data,true));
this.$txtArea.val("");
}
if ($(document.activeElement).is("div.wysibb-body")) {
this.lastRange=false;
}
},this),100);
}
},
txtAreaInitContent: function() {
//$.log(this.txtArea.value);
this.$body.html(this.getHTML(this.txtArea.value,true));
},
getValidationRGX: function(s) {
if (s.match(/\[\S+\]/)) {
return s.replace(/.*(\\*\[\S+\]).*/,"$1");
}
return "";
},
smileConversion: function() {
if (this.options.smileList && this.options.smileList.length>0) {
var snode = this.getSelectNode();
if (snode.nodeType==3) {
var ndata = snode.data;
if (ndata.length>=2 && !this.isInClearTextBlock(snode) && $(snode).parents("a").size()==0) {
$.each(this.options.srules,$.proxy(function(i,sar) {
var smbb = sar[0];
var fidx = ndata.indexOf(smbb);
if (fidx!=-1) {
var afternode_txt = ndata.substring(fidx+smbb.length,ndata.length);
var afternode = document.createTextNode(afternode_txt);
var afternode_cursor = document.createElement("SPAN");
snode.data = snode.data.substr(0,fidx);
$(snode).after(afternode).after(afternode_cursor).after(this.strf(sar[1],this.options));
this.selectNode(afternode_cursor);
return false;
}
},this));
}
}
}
},
isInClearTextBlock: function() {
if (this.cleartext) {
var find=false;
$.each(this.cleartext,$.proxy(function(sel,command) {
if (this.queryState(command)) {
find=command;
return false;
}
},this))
return find;
}
return false;
},
wrapAttrs: function(html) {
$.each(this.options.attrWrap,function(i,a) {
html = html.replace(a+'="','_'+a+'="');
});
return html;
},
unwrapAttrs: function(html) {
$.each(this.options.attrWrap,function(i,a) {
html = html.replace('_'+a+'="',a+'="');
});
return html;
},
disNonActiveButtons: function() {
if (this.isInClearTextBlock()) {
this.$toolbar.find(".wysibb-toolbar-btn:not(.on,.mswitch)").addClass("dis");
}else{
this.$toolbar.find(".wysibb-toolbar-btn.dis").removeClass("dis");
}
},
setCursorByEl: function(el) {
var sl = document.createTextNode("\uFEFF");
$(el).after(sl);
this.selectNode(sl);
},
//img listeners
imgListeners: function() {
$(document).on("mousedown",$.proxy(this.imgEventHandler,this));
},
imgEventHandler: function(e) {
var $e = $(e.target);
if (this.hasWrapedImage && ($e.closest(".wbb-img,#wbbmodal").size()==0 || $e.hasClass("wbb-cancel-button"))) {
this.$body.find(".imgWrap ").each(function() {
$.log("Removed imgWrap block");
$(this).replaceWith($(this).find("img"));
})
this.hasWrapedImage = false;
this.updateUI();
}
if ($e.is("img") && $e.closest(".wysibb-body").size()>0) {
$e.wrap("<span class='imgWrap'></span>");
this.hasWrapedImage = $e;
this.$body.focus();
this.selectNode($e.parent()[0]);
}
},
//MODAL WINDOW
showModal: function(cmd,opt,queryState) {
$.log("showModal: "+cmd);
this.saveRange();
var $cont = this.$modal.find(".wbbm-content").html("");
var $wbbm = this.$modal.find(".wbbm").removeClass("hastabs");
this.$modal.find("span.wbbm-title-text").html(opt.title);
if (opt.tabs && opt.tabs.length>1) {
//has tabs, create
$wbbm.addClass("hastabs");
var $ul = $('<div class="wbbm-tablist">').appendTo($cont).append("<ul>").children("ul");
$.each(opt.tabs,$.proxy(function(i,row) {
if (i==0) {row['on']="on"}
$ul.append(this.strf('<li class="{on}" onClick="$(this).parent().find(\'.on\').removeClass(\'on\');$(this).addClass(\'on\');$(this).parents(\'.wbbm-content\').find(\'.tab-cont\').hide();$(this).parents(\'.wbbm-content\').find(\'.tab'+i+'\').show()">{title}</li>',row));
},this))
}
if (opt.width) {
$wbbm.css("width",opt.width);
}
var $cnt = $('<div class="wbbm-cont">').appendTo($cont);
if (queryState) {
$wbbm.find('#wbbm-remove').show();
}else{
$wbbm.find('#wbbm-remove').hide();
}
$.each(opt.tabs,$.proxy(function(i,r) {
var $c = $('<div>').addClass("tab-cont tab"+i).attr("tid",i).appendTo($cnt);
if (i>0) {$c.hide();}
if (r.html) {
$c.html(this.strf(r.html,this.options));
}else{
$.each(r.input,$.proxy(function(j,inp) {
inp["value"]=queryState[inp.param.toLowerCase()];
if (inp.param.toLowerCase()=="seltext" && (!inp["value"] || inp["value"]=="")) {
inp["value"] = this.getSelectText(this.options.bbmode);
}
if (inp["value"] && inp["value"].indexOf("<span id='wbbid")==0 && $(inp["value"]).is("span[id*='wbbid']")) {
inp["value"] = $(inp["value"]).html();
}
if (inp.type && inp.type=="div") {
//div input, support wysiwyg input
$c.append(this.strf('<div class="wbbm-inp-row"><label>{title}</label><div class="inp-text div-modal-text" contenteditable="true" name="{param}">{value}</div></div>',inp));
}else{
//default input
$c.append(this.strf('<div class="wbbm-inp-row"><label>{title}</label><input class="inp-text modal-text" type="text" name="{param}" value="{value}"/></div>',inp));
}
},this));
}
},this));
//this.lastRange=this.getRange();
if ($.isFunction(opt.onLoad)) {
opt.onLoad.call(this,cmd,opt,queryState);
}
$wbbm.find('#wbbm-submit').click($.proxy(function() {
if ($.isFunction(opt.onSubmit)) { //custom submit function, if return false, then don't process our function
var r = opt.onSubmit.call(this,cmd,opt,queryState);
if (r===false) {return;}
}
var params={};
var valid=true;
this.$modal.find(".wbbm-inperr").remove();
this.$modal.find(".wbbm-brdred").removeClass("wbbm-brdred");
//$.each(this.$modal.find(".tab-cont:visible input"),$.proxy(function(i,el) {
$.each(this.$modal.find(".tab-cont:visible .inp-text"),$.proxy(function(i,el) {
var tid = $(el).parents(".tab-cont").attr("tid");
var pname = $(el).attr("name").toLowerCase();
var pval="";
if ($(el).is("input,textrea,select")) {
pval = $(el).val();
}else{
pval = $(el).html();
}
var validation = opt.tabs[tid]["input"][i]["validation"];
if (typeof(validation)!="undefined") {
if (!pval.match(new RegExp(validation,"i"))) {
valid=false;
$(el).after('<span class="wbbm-inperr">'+CURLANG.validation_err+'</span>').addClass("wbbm-brdred");
}
}
params[pname]=pval;
},this));
if (valid) {
$.log("Last range: "+this.lastRange);
this.selectLastRange();
//insert callback
if (queryState) {
this.wbbRemoveCallback(cmd,true);
}
this.wbbInsertCallback(cmd,params);
//END insert callback
this.closeModal();
this.updateUI();
}
},this));
$wbbm.find('#wbbm-remove').click($.proxy(function() {
//clbk.remove();
this.selectLastRange();
this.wbbRemoveCallback(cmd); //remove callback
this.closeModal();
this.updateUI();
},this));
$(document.body).css("overflow","hidden"); //lock the screen, remove scroll on body
if ($("body").height() > $(window).height()) { //if body has scroll, add padding-right 18px
$(document.body).css("padding-right","18px");
}
this.$modal.show();
//if (window.getSelection)
if (this.isMobile) {
$wbbm.css("margin-top","10px");
}else{
$wbbm.css("margin-top",($(window).height()-$wbbm.outerHeight())/3+"px");
}
//setTimeout($.proxy(function() {this.$modal.find("input:visible")[0].focus()},this),10);
setTimeout($.proxy(function() {this.$modal.find(".inp-text:visible")[0].focus()},this),10);
},
escModal: function(e) {
if (e.which==27) {this.closeModal();}
},
closeModal: function() {
$(document.body).css("overflow","auto").css("padding-right","0").unbind("keyup",this.escModal); //ESC key close modal;
this.$modal.find('#wbbm-submit,#wbbm-remove').unbind('click');
this.$modal.hide();
this.lastRange=false;
return this;
},
getParams: function(src,s,offset) {
var params={};
if (this.options.bbmode) {
//bbmode
var stext = s.match(/\{[\s\S]+?\}/g);
s = this.prepareRGX(s);
var rgx = new RegExp(s,"g");
var val = this.txtArea.value;
if (offset>0) {
val = val.substr(offset,val.length-offset);
}
var a = rgx.exec(val);
if (a) {
$.each(stext,function(i,n) {
params[n.replace(/\{|\}/g,"").replace(/"/g,"'").toLowerCase()] = a[i+1];
});
}
}else{
var rules = this.options.rules[s][0][1];
$.each(rules,$.proxy(function(k,v) {
var value="";
var $v = (v.sel!==false) ? value=$(src).find(v.sel):$(src);
if (v.attr!==false) {
value=$v.attr(v.attr);
}else{
value=$v.html();
}
if (value) {
if (v.rgx!==false) {
var m = value.match(new RegExp(v.rgx));
if (m && m.length==2) {
value = m[1];
}
}
params[k]=value.replace(/"/g,"'");
}
},this))
}
return params;
},
//imgUploader
imgLoadModal: function() {
$.log("imgLoadModal");
if (this.options.imgupload===true) {
this.$modal.find("#imguploader").dragfileupload({
url: this.strf(this.options.img_uploadurl,this.options),
extraParams: {
maxwidth: this.options.img_maxwidth,
maxheight: this.options.img_maxheight
},
themePrefix: this.options.themePrefix,
themeName: this.options.themeName,
success: $.proxy(function(data) {
this.$txtArea.insertImage(data.image_link,data.thumb_link);
this.closeModal();
this.updateUI();
},this)
});
this.$modal.find("#fileupl").bind("change",function() {
$("#fupform").submit();
});
this.$modal.find("#fupform").bind("submit",$.proxy(function(e) {
$(e.target).parents("#imguploader").hide().after('<div class="loader"><img src="'+this.options.themePrefix+'/'+this.options.themeName+'/img/loader.gif" /><br/><span>'+CURLANG.loading+'</span></div>').parent().css("text-align","center");
},this))
}else{
this.$modal.find(".hastabs").removeClass("hastabs");
this.$modal.find("#imguploader").parents(".tab-cont").remove();
this.$modal.find(".wbbm-tablist").remove();
}
},
imgSubmitModal: function() {
$.log("imgSubmitModal");
},
//DEBUG
printObjectInIE: function(obj) {
try{
$.log(JSON.stringify(obj));
}catch(e) {}
},
checkFilter: function(node,filter) {
$.log("node: "+$(node).get(0).outerHTML+" filter: "+filter+" res: "+$(node).is(filter.toLowerCase()));
},
debug: function(msg) {
if (this.options.debug===true) {
var time = (new Date()).getTime();
if (typeof(console)!="undefined") {
console.log((time-this.startTime)+" ms: "+msg);
}else{
$("#exlog").append('<p>'+(time-this.startTime)+" ms: "+msg+'</p>');
}
this.startTime=time;
}
},
//Browser fixes
isChrome: function() {
return (window.chrome) ? true:false;
},
fixTableTransform: function(html) {
if (!html) {return "";}
if ($.inArray("table",this.options.buttons)==-1) {
return html.replace(/\<(\/*?(table|tr|td|tbody))[^>]*\>/ig,"");
}else{
return html.replace(/\<(\/*?(table|tr|td))[^>]*\>/ig,"[$1]".toLowerCase()).replace(/\<\/*tbody[^>]*\>/ig,"");
}
}
}
$.log = function(msg) {
if (typeof(wbbdebug)!="undefined" && wbbdebug===true) {
if (typeof(console)!="undefined") {
console.log(msg);
}else{
$("#exlog").append('<p>'+msg+'</p>');
}
}
}
$.fn.wysibb = function(settings) {
return this.each(function() {
var data = $(this).data("wbb");
if (!data) {
new $.wysibb(this, settings);
}
});
}
$.fn.wdrag = function(opt) {
if (!opt.scope) {opt.scope=this;}
var start={x:0,y:0, height: 0};
var drag;
opt.scope.drag_mousedown = function(e) {
e.preventDefault();
start = {
x: e.pageX,
y: e.pageY,
height: opt.height,
sheight: opt.scope.$body.height()
}
drag=true;
$(document).bind("mousemove",$.proxy(opt.scope.drag_mousemove,this));
$(this).addClass("drag");
};
opt.scope.drag_mouseup = function(e) {
if (drag===true) {
e.preventDefault();
$(document).unbind("mousemove",opt.scope.drag_mousemove);
$(this).removeClass("drag");
drag=false;
}
};
opt.scope.drag_mousemove = function(e) {
e.preventDefault();
var axisX=0,axisY=0;
if (opt.axisX) {
axisX = e.pageX-start.x;
}
if (opt.axisY) {
axisY = e.pageY-start.y;
}
if (axisY!=0) {
var nheight = start.sheight+axisY;
if (nheight>start.height && nheight<=opt.scope.options.resize_maxheight) {
if (opt.scope.options.bbmode==true) {
opt.scope.$txtArea.css((opt.scope.options.autoresize===true) ? "min-height":"height",nheight+"px");
}else{
opt.scope.$body.css((opt.scope.options.autoresize===true) ? "min-height":"height",nheight+"px");
}
}
}
};
$(this).bind("mousedown",opt.scope.drag_mousedown);
$(document).bind("mouseup",$.proxy(opt.scope.drag_mouseup,this));
},
//API
$.fn.getDoc = function() {
return this.data('wbb').doc;
}
$.fn.getSelectText = function(fromTextArea) {
return this.data('wbb').getSelectText(fromTextArea);
}
$.fn.bbcode = function(data) {
if (typeof(data)!="undefined") {
if (this.data('wbb').options.bbmode) {
this.data('wbb').$txtArea.val(data);
}else{
this.data('wbb').$body.html(this.data("wbb").getHTML(data));
}
return this;
}else{
return this.data('wbb').getBBCode();
}
}
$.fn.htmlcode = function(data) {
if (!this.data('wbb').options.onlyBBMode && this.data('wbb').inited===true) {
if (typeof(data)!="undefined") {
this.data('wbb').$body.html(data);
return this;
}else{
return this.data('wbb').getHTML(this.data('wbb').$txtArea.val());
}
}
}
$.fn.getBBCode = function() {
return this.data('wbb').getBBCode();
}
$.fn.getHTML = function() {
var wbb = this.data('wbb');
return wbb.getHTML(wbb.$txtArea.val());
}
$.fn.getHTMLByCommand = function(command,params) {
return this.data("wbb").getHTMLByCommand(command,params);
}
$.fn.getBBCodeByCommand = function(command,params) {
return this.data("wbb").getBBCodeByCommand(command,params);
}
$.fn.insertAtCursor = function(data,forceBBMode) {
this.data("wbb").insertAtCursor(data,forceBBMode);
return this.data("wbb");
}
$.fn.execCommand = function(command,value) {
this.data("wbb").execCommand(command,value);
return this.data("wbb");
}
$.fn.insertImage = function(imgurl,thumburl) {
var editor = this.data("wbb");
var code = (thumburl) ? editor.getCodeByCommand('link',{url:imgurl,seltext: editor.getCodeByCommand('img',{src:thumburl})}): editor.getCodeByCommand('img',{src:imgurl});
this.insertAtCursor(code);
return editor;
}
$.fn.sync = function() {
this.data("wbb").sync();
return this.data("wbb");
}
$.fn.destroy = function() {
this.data("wbb").destroy();
}
$.fn.queryState = function(command) {
return this.data("wbb").queryState(command);
}
})(jQuery);
//Drag&Drop file uploader
(function($) {
'use strict';
$.fn.dragfileupload = function(options) {
return this.each(function() {
var upl = new FileUpload(this, options);
upl.init();
});
};
function FileUpload(e, options) {
this.$block=$(e);
this.opt = $.extend({
url: false,
success: false,
extraParams: false,
fileParam: 'img',
validation: '\.(jpg|png|gif|jpeg)$',
t1: CURLANG.fileupload_text1,
t2: CURLANG.fileupload_text2
},options);
}
FileUpload.prototype = {
init: function() {
if (window.FormData != null) {
this.$block.addClass("drag");
this.$block.prepend('<div class="p2">'+this.opt.t2+'</div>');
this.$block.prepend('<div class="p">'+this.opt.t1+'</div>');
this.$block.bind('dragover', function() {$(this).addClass('dragover');return false;});
this.$block.bind('dragleave', function() {$(this).removeClass('dragover');return false;});
//upload progress
var uploadProgress = $.proxy(function(e) {
var p = parseInt(e.loaded/e.total*100, 10);
this.$loader.children("span").text(CURLANG.loading+': '+ p+'%');
}, this);
var xhr = jQuery.ajaxSettings.xhr();
if (xhr.upload) {
xhr.upload.addEventListener('progress', uploadProgress, false);
}
this.$block[0].ondrop = $.proxy(function(e) {
e.preventDefault();
this.$block.removeClass('dragover');
var ufile = e.dataTransfer.files[0];
if (this.opt.validation && !ufile.name.match(new RegExp(this.opt.validation))) {
this.error(CURLANG.validation_err);
return false;
}
var fData = new FormData();
fData.append(this.opt.fileParam, ufile);
if (this.opt.extraParams) { //check for extraParams to upload
$.each(this.opt.extraParams,function(k,v) {
fData.append(k, v);
});
}
this.$loader = $('<div class="loader"><img src="'+this.opt.themePrefix+'/'+this.opt.themeName+'/img/loader.gif" /><br/><span>'+CURLANG.loading+'</span></div>');
this.$block.html(this.$loader);
$.ajax({
type: 'POST',
url: this.opt.url,
data: fData,
processData: false,
contentType: false,
xhr: function() {return xhr},
dataType: 'json',
success: $.proxy(function(data) {
if (data && data.status==1) {
this.opt.success(data);
}else{
this.error(data.msg || CURLANG.error_onupload);
}
},this),
error: $.proxy(function (xhr, txt, thr) {this.error(CURLANG.error_onupload)},this)
});
},this);
}
},
error: function(msg) {
this.$block.find(".upl-error").remove().end().append('<span class="upl-error">'+msg+'</span>').addClass("wbbm-brdred");
}
}
})(jQuery);