/*! WysiBB - WYSIWYG BBCode editor - v1.3.0 - 2012-11-28 * http://www.wysibb.com * Copyright (c) 2012 Vadim Dobroskok; Licensed MIT, GPL */ if (typeof (WBBLANG) == "undefined") { WBBLANG = {}; } WBBLANG['ru'] = CURLANG = { bold:"Полужирный", italic:"Курсив", underline:"Подчеркнутый", strike:"Зачеркнутый", link:"Ссылка", img:"Изображение", sup:"Надстрочный текст", sub:"Подстрочный текст", justifyleft:"Текст по левому краю", justifycenter:"Текст по центру", justifyright:"Текст по правому краю", table:"Вставить таблицу", bullist:"Обычный список", numlist:"Нумерованный список", quote:"Цитата", offtop:"Оффтоп", code:"Код", spoiler:"Сворачиваемый текст", fontcolor:"Цвет текста", fontsize:"Размер текста", fontfamily:"Шрифт текста", fs_verysmall:"Очень маленький", fs_small:"Маленький", fs_normal:"Нормальный", fs_big:"Большой", fs_verybig:"Очень большой", smilebox:"Вставить смайл", video:"Вставить видео", removeFormat:"Удалить форматирование", modal_link_title:"Вставить ссылку", modal_link_text:"Отображаемый текст", modal_link_url:"URL ссылки", modal_link_target:"Открывать в новом окне", modal_email_text:"Отображаемый эл.адрес", modal_email_url:"Email", modal_link_tab1:"Вставить URL", modal_img_title:"Вставить изображение", modal_img_tab1:"Ввести URL", modal_img_tab2:"Загрузить файл", modal_imgsrc_text:"Введите адрес изображения", modal_img_btn:"Выберите файл для загрузки", add_attach:"Добавить вложение", modal_video_text:"Введите URL видео", close:"Закрыть", save:"Сохранить", cancel:"Отмена", remove:"Удалить", validation_err:"Введенные данные некорректны", error_onupload:"Ошибка во время загрузки файла или такое расширение файла не поддерживается", fileupload_text1:"Перетащите файл сюда", fileupload_text2:"или", loading:"Загрузка", auto:"Авто", views:"Просмотров", downloads:"Скачиваний", //smiles sm1:"Улыбка", sm2:"Смех", sm3:"Подмигивание", sm4:"Спасибо, класс", sm5:"Ругаю", sm6:"Шок", sm7:"Злой", sm8:"Огорчение", sm9:"Тошнит" }; var 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:true, 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,smilebox,|,fontcolor,fontsize,fontfamily,|,justifyleft,justifycenter,justifyright,|,quote,code,offtop,table,removeFormat", allButtons:{ bold:{ title:CURLANG.bold, buttonHTML:'\uE000', excmd:'bold', hotkey:'ctrl+b', transform:{ '{SELTEXT}':"[b]{SELTEXT}[/b]", '{SELTEXT}':"[b]{SELTEXT}[/b]" } }, italic:{ title:CURLANG.italic, buttonHTML:'\uE001', excmd:'italic', hotkey:'ctrl+i', transform:{ '{SELTEXT}':"[i]{SELTEXT}[/i]", '{SELTEXT}':"[i]{SELTEXT}[/i]" } }, underline:{ title:CURLANG.underline, buttonHTML:'\uE002', excmd:'underline', hotkey:'ctrl+u', transform:{ '{SELTEXT}':"[u]{SELTEXT}[/u]" } }, strike:{ title:CURLANG.strike, buttonHTML:'\uE003', excmd:'strikeThrough', transform:{ '{SELTEXT}':"[s]{SELTEXT}[/s]", '{SELTEXT}':"[s]{SELTEXT}[/s]" } }, sup:{ title:CURLANG.sup, buttonHTML:'\uE005', excmd:'superscript', transform:{ '{SELTEXT}':"[sup]{SELTEXT}[/sup]" } }, sub:{ title:CURLANG.sub, buttonHTML:'\uE004', excmd:'subscript', transform:{ '{SELTEXT}':"[sub]{SELTEXT}[/sub]" } }, link:{ title:CURLANG.link, buttonHTML:'\uE007', 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:{ '{SELTEXT}':"[url={URL}]{SELTEXT}[/url]" } }, img:{ title:CURLANG.img, buttonHTML:'\uE006', hotkey:'ctrl+shift+1', 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)$'} ] }/*, { title:CURLANG.modal_img_tab2, html:'
' }*/ ], onLoad:this.imgLoadModal }, transform:{ '':"[img]{SRC}[/img]", '':"[img width={WIDTH},height={HEIGHT}]{SRC}[/img]" } }, bullist:{ title:CURLANG.bullist, buttonHTML:'\uE009', excmd:'insertUnorderedList', transform:{ '':"[list]{SELTEXT}[/list]", '
  • {SELTEXT}
  • ':"[*]{SELTEXT}[/*]" } }, numlist:{ title:CURLANG.numlist, buttonHTML:'\uE00a', excmd:'insertOrderedList', transform:{ '
      {SELTEXT}
    ':"[list=1]{SELTEXT}[/list]", '
  • {SELTEXT}
  • ':"[*]{SELTEXT}[/*]" } }, quote:{ title:CURLANG.quote, buttonHTML:'\uE00c', hotkey:'ctrl+shift+3', //subInsert: true, transform:{ '
    {SELTEXT}
    ':"[quote]{SELTEXT}[/quote]" } }, code:{ title:CURLANG.code, buttonText:'[code]', /* buttonHTML: '\uE00d', */ hotkey:'ctrl+shift+4', onlyClearText:true, transform:{ '
    Код:
    {SELTEXT}
    ':"[code]{SELTEXT}[/code]" } }, offtop:{ title:CURLANG.offtop, buttonText:'offtop', transform:{ '{SELTEXT}':"[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:{ '{SELTEXT}':'[color={COLOR}]{SELTEXT}[/color]' } }, table:{ type:"table", title:CURLANG.table, cols:10, rows:10, cellwidth:15, transform:{ '{SELTEXT}':'[td]{SELTEXT}[/td]', '{SELTEXT}':'[tr]{SELTEXT}[/tr]', '{SELTEXT}
    ':'[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:{ '{SELTEXT}':'[font={FONT}]{SELTEXT}[/font]' } }, smilebox:{ type:'smilebox', title:CURLANG.smilebox, buttonHTML:'\uE00b' }, justifyleft:{ title:CURLANG.justifyleft, buttonHTML:'\uE015', groupkey:'align', transform:{ '

    {SELTEXT}

    ':'[left]{SELTEXT}[/left]' } }, justifyright:{ title:CURLANG.justifyright, buttonHTML:'\uE016', groupkey:'align', transform:{ '

    {SELTEXT}

    ':'[right]{SELTEXT}[/right]' } }, justifycenter:{ title:CURLANG.justifycenter, buttonHTML:'\uE014', groupkey:'align', transform:{ '

    {SELTEXT}

    ':'[center]{SELTEXT}[/center]' } }, video:{ title:CURLANG.video, buttonHTML:'\uE008', 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(); var a; if (url.indexOf("youtu.be") != -1) { a = url.match(/^http:\/\/youtu\.be\/([a-z0-9_]+)/i); } else { a = url.match(/^http:\/\/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:{ '':'[video]{SRC}[/video]' } }, //select options fs_verysmall:{ title:CURLANG.fs_verysmall, buttonText:"fs1", excmd:'fontSize', exvalue:"1", transform:{ '{SELTEXT}':'[size=50]{SELTEXT}[/size]' } }, fs_small:{ title:CURLANG.fs_small, buttonText:"fs2", excmd:'fontSize', exvalue:"2", transform:{ '{SELTEXT}':'[size=85]{SELTEXT}[/size]' } }, fs_normal:{ title:CURLANG.fs_normal, buttonText:"fs3", excmd:'fontSize', exvalue:"3", transform:{ '{SELTEXT}':'[size=100]{SELTEXT}[/size]' } }, fs_big:{ title:CURLANG.fs_big, buttonText:"fs4", excmd:'fontSize', exvalue:"4", transform:{ '{SELTEXT}':'[size=150]{SELTEXT}[/size]' } }, fs_verybig:{ title:CURLANG.fs_verybig, buttonText:"fs5", excmd:'fontSize', exvalue:"6", transform:{ '{SELTEXT}':'[size=200]{SELTEXT}[/size]' } }, removeformat:{ title:CURLANG.removeFormat, buttonHTML:'\uE00f', excmd:"removeFormat" } }, systr:{ '
    ':"\n", '{SELTEXT}':' {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:'', bbcode:":)"}, {title:CURLANG.sm8, img:'', bbcode:":("}, {title:CURLANG.sm1, img:'', bbcode:":D"}, {title:CURLANG.sm3, img:'', bbcode:";)"}, {title:CURLANG.sm4, img:'', bbcode:":up:"}, {title:CURLANG.sm5, img:'', bbcode:":down:"}, {title:CURLANG.sm6, img:'', bbcode:":shock:"}, {title:CURLANG.sm7, img:'', bbcode:":angry:"}, {title:CURLANG.sm9, img:'', bbcode:":sick:"} ], 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 if (this.isMobile) { this.onlyBBmode = this.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; //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); for (var bhtml in obtr) { var orightml = bhtml; var bbcode = ob.transform[bhtml]; //wrap attributes $.each(o.attrWrap, function (i, a) { bhtml = bhtml.replace(a + '="', '_' + a + '="'); }); 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()); //replace transform with unique selector var nhtml2 = $bel.html(); ob.transform[nhtml2] = bbcode; delete ob.transform[bhtml]; bhtml = nhtml2; } //create root selector for isContain if (!ob.excmd) { if (!ob.rootSelector) { ob.rootSelector = []; } ob.rootSelector.push(rootSelector); } if (!ob.bbSelector) { ob.bbSelector = []; } if ($.inArray(bbcode, ob.bbSelector) == -1) { ob.bbSelector.push(bbcode); } //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 = $("").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 $.each(o.attrWrap, function (i, a) { nbhtml = nbhtml.replace('_' + a + '="', a + '="'); }); 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); } } 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 = $('
    '); this.$editor = $('
    ').addClass("wysibb"); //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('
    '); 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('
    ', {maxheight:mheight, height:height})).insertAfter(this.$txtArea); this.body = this.$body[0]; this.$txtArea.hide(); $.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(""); } 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.lastRange = this.getRangeClone(); this.$pasteBlock = $(this.elFromString('
    \uFEFF
    ')); this.$pasteBlock.appendTo(this.body); if ($.browser.msie) { this.$pasteBlock.focus(); } //IE 7,8 FIX setTimeout($.proxy(function () { this.clearPaste(this.$pasteBlock); var rdata = '' + this.$pasteBlock.html() + ''; this.$body.attr("contentEditable", "true"); this.$pasteBlock.blur().remove(); this.body.focus(); if (this.cleartext) { if (this.isInClearTextBlock()) { rdata = this.toBB(rdata).replace(/\n/g, "
    ").replace(/\s{3}/g, ''); } } rdata = rdata.replace(/\t/g, ''); 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('
    ', 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.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('
    ')).appendTo(this.$editor) .wdrag({ scope:this, axisY:true, height:height }); } } //add event listeners to textarea this.$txtArea.bind('mouseup keyup', $.proxy(this.updateUI, 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 = $('
    ').prependTo(this.$editor); this.$toolbar = $('
    ').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("
    "); } $btnContainer = $('
    ').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 = $('
    ').appendTo(this.$toolbar); var $bbsw = $(document.createElement('div')).addClass("wysibb-toolbar-container modeSwitch").html('
    [BBcode]
    ').appendTo(this.$toolbar); $bbsw.children(".wysibb-toolbar-btn").click($.proxy(function (e) { $(e.currentTarget).toggleClass("on"); this.modeSwitch(); }, this)); if ($.browser.msie) { this.$toolbar.find("*").attr("unselectable", "on"); } //fix for ie8 and lower }, 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('{text}', {text:opt.buttonText.replace(/[' + opt.hotkey + ']') : "" var $btn = $('
    ').appendTo(container).append(btnHTML).append(this.strf('{title}{hotkey}', {title:opt.title, hotkey:hotkey})); //if ($.browser.msie) {$btn.attr("unselectable","on").find("*").attr("unselectable","on");} //fix for ie8 and lower //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) { if (e.preventDefault) e.preventDefault(); this.execCommand(bn, opt.exvalue || false); $(e.currentTarget).trigger('queryState'); }, this)); }, buildColorpicker:function (container, bn, opt) { var $btn = $('
    ').appendTo(container).append('
    \uE010
    \uE011').append(this.strf('{title}', {title:opt.title})); var $cpline = $btn.find(".cp-line"); //if ($.browser.msie) {$btn.attr("unselectable","on").find("*").attr("unselectable","on");} //fix for ie8 and lower var $dropblock = $('
    ').appendTo($btn); $dropblock.append('
    ' + CURLANG.auto + '
    '); 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(''); } else { $dropblock.append(this.strf('
    ', {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("fontcolor", 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("fontcolor", c); $btn.trigger('queryState'); }, this)); $btn.find(".nc").mousedown($.proxy(function (e) { e.preventDefault(); this.selectLastRange(); this.execCommand("fontcolor", basecolor); $btn.trigger('queryState'); }, this)); $btn.mousedown(function (e) { if (e.preventDefault) e.preventDefault(); }); }, buildTablepicker:function (container, bn, opt) { var $btn = $('
    ').appendTo(container).append('\uE00e\uE011').append(this.strf('{title}', {title:opt.title})); //if ($.browser.msie) {$btn.attr("unselectable","on").find("*").attr("unselectable","on");} //fix for ie8 and lower var $dropblock = $('
    ').appendTo($btn); var rows = opt.rows || 10; var cols = opt.cols || 10; var allcount = rows * cols; $dropblock.css("width", (cols * opt.cellwidth + 2) + "px").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('
    ',{width: (j*opt.cellwidth),height: (h*opt.cellwidth),zindex: --allcount,row:h,col:j}); var html = '
    '; $dropblock.append(html); } } //this.debug("Attach event on: tbl-sel"); $btn.find(".tbl-sel").mousedown($.proxy(function (e) { e.preventDefault(); this.selectLastRange(); var t = $(e.currentTarget).attr("title"); var rc = t.split(","); var code = (this.options.bbmode) ? '[table]' : ''; for (var i = 1; i <= rc[0]; i++) { code += (this.options.bbmode) ? ' [tr]\n' : ''; for (var j = 1; j <= rc[1]; j++) { code += (this.options.bbmode) ? ' [td][/td]\n' : ''; } code += (this.options.bbmode) ? '[/tr]\n' : ''; } code += (this.options.bbmode) ? '[/table]' : '
    \uFEFF
    '; 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 = $('
    ').appendTo(container).append(this.strf('{title}\uE012', opt)).append(this.strf('{title}', {title:opt.title})); var $sblock = $('
    ').appendTo($btn); var $sval = $btn.find("span.val"); //if ($.browser.msie) {$btn.attr("unselectable","on").find("*").attr("unselectable","on");} //fix for ie8 and lower var olist = ($.isArray(opt.options)) ? opt.options : opt.options.split(","); //$.log(this.printObjectInIE(olist)); 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) { $('').addClass("option").attr("oid", oname).attr("cmdvalue", option.exvalue).appendTo($sblock).append(this.strf(option.html, {seltext:option.title})); } else { $sblock.append(this.strf('{title}', option)); } } } else { //build option list from array var params = { seltext:oname.title } params[opt.valueBBname] = oname.exvalue; $('').addClass("option").attr("oid", bn).attr("cmdvalue", oname.exvalue).appendTo($sblock).append(this.strf(opt.html, params)); } } 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(); //this.selectRange(this.lastRange); 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.lastRange=false; //if (this.lastRange) this.lastRange=false; //IE 7 FIX }, 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 = $('
    ').appendTo(container).append($btnHTML).append(this.strf('{title}', {title:opt.title})); var $sblock = $('
    ').appendTo($btn); if ($.isArray(this.options.smileList)) { $.each(this.options.smileList, $.proxy(function (i, sm) { $('').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) : $($(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 if (this.isInClearTextBlock()) { this.$toolbar.find(".wysibb-toolbar-btn:not(.on,.mswitch)").addClass("dis"); } else { this.$toolbar.find(".wysibb-toolbar-btn.dis").removeClass("dis"); } }, initModal:function () { this.$modal = $("#wbbmodal"); if (this.$modal.size() == 0) { $.log("Init modal"); this.$modal = $('
    ').attr("id", "wbbmodal").prependTo(document.body) .html('
    ?
    ').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; } } }, //COMMAND 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 return document.queryCommandState(opt.excmd); } catch (e) { return false; } } } else { //custom command 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 = $('').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) { this.selectNode(this.$body.find("#" + this.seltextID)[0]); 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) { var root = this.isContain(node, s); 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) { $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(/\{/g, "{").replace(/\}/g, "}"); } $root.replaceWith(htmldata); } else { var htmldata = $root.html(); if (opt.onlyClearText === true) { htmldata = this.getHTML(htmldata, true); htmldata = htmldata.replace(/\</g, "<").replace(/\{/g, "{").replace(/\}/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(); $.log("selHTML: " + shtml); 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(''); 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 = $('
    ').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.selectRange(this.lastRange); this.lastRange = false; } 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; 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; v = v.replace(/\{(.*?)(\[.*?\])*\}/g, function (str, p, vrgx) { var vrgxp; if (vrgx) { vrgxp = new RegExp(vrgx + "+", "i"); } if (typeof(params[p.toLowerCase()]) == "undefined" || (vrgx && params[p.toLowerCase()].toString().match(vrgxp) === null)) { valid = false; } ; return (typeof(params[p.toLowerCase()]) == "undefined") ? "" : params[p.toLowerCase()]; }); if (valid) { rbbcode = v; return false; } }); 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(/\").replace(/\s{3}/g, ''); } } } var postsel = ""; this.seltextID = "wbbid_" + (++this.lastid); if (command != "link" && command != "img") { params["seltext"] = '' + params["seltext"] + ''; //use for select seltext } else { postsel = '\uFEFF' } 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; 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; v = v.replace(/\{(.*?)(\[.*?\])*\}/g, function (str, p, vrgx) { var vrgxp; if (vrgx) { vrgxp = new RegExp(vrgx + "+", "i"); } if (typeof(params[p.toLowerCase()]) == "undefined" || (vrgx && params[p.toLowerCase()].toString().match(vrgxp) === null)) { valid = false; } ; return (typeof(params[p.toLowerCase()]) == "undefined") ? "" : params[p.toLowerCase()]; }); if (valid) { rhtml = v; return false; } }); 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 $('
    ').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 = $("
    ").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); 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(); }, 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.lastRange = this.getRangeClone(); }, selectLastRange:function () { if (this.lastRange) { this.selectRange(this.lastRange); 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 ""; } ; //.replace(/\[/g,"[").replace(/\]/g,"]") var $e = (typeof(data) == "string") ? $('').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, " "); //outbb+=el.data.replace(/\t/g," "); /* }else if (el.tagName=="BR") { outbb+="\n"; */ } 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, "
    "); } 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") || $el.attr("notkeep")) { //replace element outbb += bbcode; $el = null; break; } else { if (keepElement) { if ($.browser.msie) { $el.empty().append($('').html(bbcode)); } else { $el.empty().html('' + bbcode + ''); } } 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)); return outbb; }, getHTML:function (bbdata, init, skiplt) { if (!this.options.bbmode && !init) { return this.$body.html() } if (!skiplt) { bbdata = bbdata.replace(/" + bbdata + "
    ")); //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("
    "); } } if (this.$body.contents().size() > 0 && this.body.lastChild.tagName != "BR") { this.$body.append('
    '); } }, getAttributeList:function (el) { var a = []; $.each(el.attributes, function (i, attr) { if (attr.specified) { a.push(attr.name); } }); return a; }, clearFromSubInsert:function (html, cmd) { var $wr = $('
    ').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(); }, 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")) { //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(); //if (!window.getSeletion && $.browser.msie) this.lastRange=this.getRange(); //IE 7 FIX 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); //clear paste //$.log("clearPaste"); //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("
    "); } }, this)); $block.find("*[wbbkeep]").removeAttr("wbbkeep").removeAttr("style"); $.log($block.html()); $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("
    ").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('\uFEFF', 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 ($(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 () { 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 (snode) { if (this.cleartext && this.options.bbmode === false) { if (!snode) { snode = this.getSelectNode(); } var find = false; $.each(this.cleartext, $.proxy(function (sel, command) { if (this.isContain(snode, sel)) { find = command; return false; } }, this)) return find; } return false; }, //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 = $('
    ').appendTo($cont).append("
      ").children("ul"); $.each(opt.tabs, $.proxy(function (i, row) { if (i == 0) { row['on'] = "on" } $ul.append(this.strf('
    • {title}
    • ', row)); }, this)) } if (opt.width) { $wbbm.css("width", opt.width); } var $cnt = $('
      ').appendTo($cont); if (queryState) { $wbbm.find('#wbbm-remove').show(); } else { $wbbm.find('#wbbm-remove').hide(); } $.each(opt.tabs, $.proxy(function (i, r) { var $c = $('
      ').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("
      {value}
      ', inp)); } else { //default input $c.append(this.strf('
      ', 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")) { 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('' + CURLANG.validation_err + '').addClass("wbbm-brdred"); } } params[pname] = pval; }, this)); if (valid) { //if (this.lastRange) this.selectRange(this.lastRange); this.selectLastRange(); //clbk.insert(params); //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 ($(document.body).height()>$(window).height()) { //if body has scroll, add padding-right 20px $(document.body).css("padding-right","20px"); } */ this.$modal.show(); //if (window.getSelection) $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 = ""; if (v.attr !== false) { value = $(src).attr(v.attr); } else if (v.sel !== false) { value = $(src).find(v.sel).html(); } else { value = $(src).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) }); if ($.browser.msie) { //ie not posting form by security reason, show default file upload $.log("IE not posting form by security reason, show default file upload"); this.$modal.find("#nicebtn").hide(); this.$modal.find("#fileupl").css("opacity", 1); } this.$modal.find("#fileupl").bind("change", function () { $("#fupform").submit(); }); this.$modal.find("#fupform").bind("submit", $.proxy(function (e) { $(e.target).parents("#imguploader").hide().after('

      ' + CURLANG.loading + '
      ').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('

      ' + (time - this.startTime) + " ms: " + msg + '

      '); } this.startTime = time; } } } $.log = function (msg) { if (typeof(wbbdebug) != "undefined" && wbbdebug === true) { if (typeof(console) != "undefined") { //console.log(msg); } else { $("#exlog").append('

      ' + msg + '

      '); } } } $.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('
      ' + this.opt.t2 + '
      '); this.$block.prepend('
      ' + this.opt.t1 + '
      '); 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 = $('

      ' + CURLANG.loading + '
      '); 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('' + msg + '').addClass("wbbm-brdred"); } } })(jQuery);