bbcode.js 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765
  1. /*
  2. [Discuz!] (C)2001-2099 Comsenz Inc.
  3. This is NOT a freeware, use is subject to license terms
  4. $Id: bbcode.js 36359 2017-01-20 05:06:45Z nemohou $
  5. */
  6. var re, DISCUZCODE = [];
  7. DISCUZCODE['num'] = '-1';
  8. DISCUZCODE['html'] = [];
  9. EXTRAFUNC['bbcode2html'] = [];
  10. EXTRAFUNC['html2bbcode'] = [];
  11. function addslashes(str) {
  12. return preg_replace(['\\\\', '\\\'', '\\\/', '\\\(', '\\\)', '\\\[', '\\\]', '\\\{', '\\\}', '\\\^', '\\\$', '\\\?', '\\\.', '\\\*', '\\\+', '\\\|'], ['\\\\', '\\\'', '\\/', '\\(', '\\)', '\\[', '\\]', '\\{', '\\}', '\\^', '\\$', '\\?', '\\.', '\\*', '\\+', '\\|'], str);
  13. }
  14. function atag(aoptions, text) {
  15. if(trim(text) == '') {
  16. return '';
  17. }
  18. var pend = parsestyle(aoptions, '', '');
  19. href = getoptionvalue('href', aoptions);
  20. if(href.substr(0, 11) == 'javascript:') {
  21. return trim(recursion('a', text, 'atag'));
  22. }
  23. return pend['prepend'] + '[url=' + href + ']' + trim(recursion('a', text, 'atag')) + '[/url]' + pend['append'];
  24. }
  25. function bbcode2html(str) {
  26. if(str == '') {
  27. return '';
  28. }
  29. if(typeof(parsetype) == 'undefined') {
  30. parsetype = 0;
  31. }
  32. if(!fetchCheckbox('bbcodeoff') && allowbbcode && parsetype != 1) {
  33. str = str.replace(/\[code\]([\s\S]+?)\[\/code\]/ig, function($1, $2) {return parsecode($2);});
  34. }
  35. if(fetchCheckbox('allowimgurl')) {
  36. str = str.replace(/([^>=\]"'\/]|^)((((https?|ftp):\/\/)|www\.)([\w\-]+\.)*[\w\-\u4e00-\u9fa5]+\.([\.a-zA-Z0-9]+|\u4E2D\u56FD|\u7F51\u7EDC|\u516C\u53F8)((\?|\/|:)+[\w\.\/=\?%\-&~`@':+!]*)+\.(jpg|gif|png|bmp))/ig, '$1[img]$2[/img]');
  37. }
  38. if(!allowhtml || !fetchCheckbox('htmlon')) {
  39. str = str.replace(/</g, '&lt;');
  40. str = str.replace(/>/g, '&gt;');
  41. if(!fetchCheckbox('parseurloff')) {
  42. str = parseurl(str, 'html', false);
  43. }
  44. }
  45. for(i in EXTRAFUNC['bbcode2html']) {
  46. EXTRASTR = str;
  47. try {
  48. eval('str = ' + EXTRAFUNC['bbcode2html'][i] + '()');
  49. } catch(e) {}
  50. }
  51. if(!fetchCheckbox('smileyoff') && allowsmilies) {
  52. if(typeof smilies_type == 'object') {
  53. for(var typeid in smilies_array) {
  54. for(var page in smilies_array[typeid]) {
  55. for(var i in smilies_array[typeid][page]) {
  56. re = new RegExp(preg_quote(smilies_array[typeid][page][i][1]), "g");
  57. str = str.replace(re, '<img src="' + STATICURL + 'image/smiley/' + smilies_type['_' + typeid][1] + '/' + smilies_array[typeid][page][i][2] + '" border="0" smilieid="' + smilies_array[typeid][page][i][0] + '" alt="' + smilies_array[typeid][page][i][1] + '" />');
  58. }
  59. }
  60. }
  61. }
  62. }
  63. if(!fetchCheckbox('bbcodeoff') && allowbbcode) {
  64. str = clearcode(str);
  65. str = str.replace(/\[url\]\s*((https?|ftp|gopher|news|telnet|rtsp|mms|callto|bctp|thunder|qqdl|synacast){1}:\/\/|www\.)([^\[\"']+?)\s*\[\/url\]/ig, function($1, $2, $3, $4) {return cuturl($2 + $4);});
  66. str = str.replace(/\[url=((https?|ftp|gopher|news|telnet|rtsp|mms|callto|bctp|thunder|qqdl|synacast){1}:\/\/|www\.|mailto:)?([^\r\n\[\"']+?)\]([\s\S]+?)\[\/url\]/ig, '<a href="$1$3" target="_blank">$4</a>');
  67. str = str.replace(/\[email\](.[^\\=[]*)\[\/email\]/ig, '<a href="mailto:$1">$1</a>');
  68. str = str.replace(/\[email=(.[^\\=[]*)\](.*?)\[\/email\]/ig, '<a href="mailto:$1" target="_blank">$2</a>');
  69. str = str.replace(/\[postbg\]\s*([^\[\<\r\n;'\"\?\(\)]+?)\s*\[\/postbg\]/ig, function($1, $2) {
  70. addCSS = '';
  71. if(in_array($2, postimg_type["postbg"])) {
  72. addCSS = '<style type="text/css" name="editorpostbg">body{background-image:url("'+STATICURL+'image/postbg/'+$2+'");}</style>';
  73. }
  74. return addCSS;
  75. });
  76. str = str.replace(/\[color=([\w#\(\),\s]+?)\]/ig, '<font color="$1">');
  77. str = str.replace(/\[backcolor=([\w#\(\),\s]+?)\]/ig, '<font style="background-color:$1">');
  78. str = str.replace(/\[size=(\d+?)\]/ig, '<font size="$1">');
  79. str = str.replace(/\[size=(\d+(\.\d+)?(px|pt)+?)\]/ig, '<font style="font-size: $1">');
  80. str = str.replace(/\[font=([^\[\<\=]+?)\]/ig, '<font face="$1">');
  81. str = str.replace(/\[align=([^\[\<\=]+?)\]/ig, '<div align="$1">');
  82. str = str.replace(/\[p=(\d{1,2}|null), (\d{1,2}|null), (left|center|right)\]/ig, '<p style="line-height: $1px; text-indent: $2em; text-align: $3;">');
  83. str = str.replace(/\[float=left\]/ig, '<br style="clear: both"><span style="float: left; margin-right: 5px;">');
  84. str = str.replace(/\[float=right\]/ig, '<br style="clear: both"><span style="float: right; margin-left: 5px;">');
  85. if(parsetype != 1) {
  86. str = str.replace(/\[quote]([\s\S]*?)\[\/quote\]\s?\s?/ig, '<div class="quote"><blockquote>$1</blockquote></div>\n');
  87. }
  88. re = /\[table(?:=(\d{1,4}%?)(?:,([\(\)%,#\w ]+))?)?\]\s*([\s\S]+?)\s*\[\/table\]/ig;
  89. for (i = 0; i < 4; i++) {
  90. str = str.replace(re, function($1, $2, $3, $4) {return parsetable($2, $3, $4);});
  91. }
  92. str = preg_replace([
  93. '\\\[\\\/color\\\]', '\\\[\\\/backcolor\\\]', '\\\[\\\/size\\\]', '\\\[\\\/font\\\]', '\\\[\\\/align\\\]', '\\\[\\\/p\\\]', '\\\[b\\\]', '\\\[\\\/b\\\]',
  94. '\\\[i\\\]', '\\\[\\\/i\\\]', '\\\[u\\\]', '\\\[\\\/u\\\]', '\\\[s\\\]', '\\\[\\\/s\\\]', '\\\[hr\\\]', '\\\[list\\\]', '\\\[list=1\\\]', '\\\[list=a\\\]',
  95. '\\\[list=A\\\]', '\\s?\\\[\\\*\\\]', '\\\[\\\/list\\\]', '\\\[indent\\\]', '\\\[\\\/indent\\\]', '\\\[\\\/float\\\]'
  96. ], [
  97. '</font>', '</font>', '</font>', '</font>', '</div>', '</p>', '<b>', '</b>', '<i>',
  98. '</i>', '<u>', '</u>', '<strike>', '</strike>', '<hr class="l" />', '<ul>', '<ul type=1 class="litype_1">', '<ul type=a class="litype_2">',
  99. '<ul type=A class="litype_3">', '<li>', '</ul>', '<blockquote>', '</blockquote>', '</span>'
  100. ], str, 'g');
  101. }
  102. if(!fetchCheckbox('bbcodeoff')) {
  103. if(allowimgcode) {
  104. str = str.replace(/\[img\]\s*([^\[\"\<\r\n]+?)\s*\[\/img\]/ig, '<img src="$1" border="0" alt="" style="max-width:400px" />');
  105. str = str.replace(/\[attachimg\](\d+)\[\/attachimg\]/ig, function ($1, $2) {
  106. if(!$('image_' + $2)) {
  107. return '';
  108. }
  109. width = $('image_' + $2).getAttribute('cwidth');
  110. if(!width) {
  111. re = /cwidth=(["']?)(\d+)(\1)/i;
  112. var matches = re.exec($('image_' + $2).outerHTML);
  113. if(matches != null) {
  114. width = matches[2];
  115. }
  116. }
  117. return '<img src="' + $('image_' + $2).src + '" border="0" aid="attachimg_' + $2 + '" width="' + width + '" alt="" />';
  118. });
  119. str = str.replace(/\[img=(\d{1,4})[x|\,](\d{1,4})\]\s*([^\[\"\<\r\n]+?)\s*\[\/img\]/ig, function ($1, $2, $3, $4) {return '<img' + ($2 > 0 ? ' width="' + $2 + '"' : '') + ($3 > 0 ? ' _height="' + $3 + '"' : '') + ' src="' + $4 + '" border="0" alt="" />'});
  120. } else {
  121. str = str.replace(/\[img\]\s*([^\[\"\<\r\n]+?)\s*\[\/img\]/ig, '<a href="$1" target="_blank">$1</a>');
  122. str = str.replace(/\[img=(\d{1,4})[x|\,](\d{1,4})\]\s*([^\[\"\<\r\n]+?)\s*\[\/img\]/ig, '<a href="$3" target="_blank">$3</a>');
  123. }
  124. }
  125. for(var i = 0; i <= DISCUZCODE['num']; i++) {
  126. str = str.replace("[\tDISCUZ_CODE_" + i + "\t]", DISCUZCODE['html'][i]);
  127. }
  128. if(!allowhtml || !fetchCheckbox('htmlon')) {
  129. str = str.replace(/(^|>)([^<]+)(?=<|$)/ig, function($1, $2, $3) {
  130. return $2 + preg_replace(['\t', ' ', ' ', '(\r\n|\n|\r)'], ['&nbsp; &nbsp; &nbsp; &nbsp; ', '&nbsp; &nbsp;', '&nbsp;&nbsp;', '<br />'], $3);
  131. });
  132. } else {
  133. str = str.replace(/<script[^\>]*?>([^\x00]*?)<\/script>/ig, '');
  134. }
  135. return str;
  136. }
  137. function clearcode(str) {
  138. str= str.replace(/\[url\]\[\/url\]/ig, '', str);
  139. str= str.replace(/\[url=((https?|ftp|gopher|news|telnet|rtsp|mms|callto|bctp|thunder|qqdl|synacast){1}:\/\/|www\.|mailto:)?([^\s\[\"']+?)\]\[\/url\]/ig, '', str);
  140. str= str.replace(/\[email\]\[\/email\]/ig, '', str);
  141. str= str.replace(/\[email=(.[^\[]*)\]\[\/email\]/ig, '', str);
  142. str= str.replace(/\[color=([^\[\<]+?)\]\[\/color\]/ig, '', str);
  143. str= str.replace(/\[size=(\d+?)\]\[\/size\]/ig, '', str);
  144. str= str.replace(/\[size=(\d+(\.\d+)?(px|pt)+?)\]\[\/size\]/ig, '', str);
  145. str= str.replace(/\[font=([^\[\<]+?)\]\[\/font\]/ig, '', str);
  146. str= str.replace(/\[align=([^\[\<]+?)\]\[\/align\]/ig, '', str);
  147. str= str.replace(/\[p=(\d{1,2}), (\d{1,2}), (left|center|right)\]\[\/p\]/ig, '', str);
  148. str= str.replace(/\[float=([^\[\<]+?)\]\[\/float\]/ig, '', str);
  149. str= str.replace(/\[quote\]\[\/quote\]/ig, '', str);
  150. str= str.replace(/\[code\]\[\/code\]/ig, '', str);
  151. str= str.replace(/\[table\]\[\/table\]/ig, '', str);
  152. str= str.replace(/\[free\]\[\/free\]/ig, '', str);
  153. str= str.replace(/\[b\]\[\/b]/ig, '', str);
  154. str= str.replace(/\[u\]\[\/u]/ig, '', str);
  155. str= str.replace(/\[i\]\[\/i]/ig, '', str);
  156. str= str.replace(/\[s\]\[\/s]/ig, '', str);
  157. return str;
  158. }
  159. function cuturl(url) {
  160. var length = 65;
  161. var urllink = '<a href="' + (url.toLowerCase().substr(0, 4) == 'www.' ? 'http://' + url : url) + '" target="_blank">';
  162. if(url.length > length) {
  163. url = url.substr(0, parseInt(length * 0.5)) + ' ... ' + url.substr(url.length - parseInt(length * 0.3));
  164. }
  165. urllink += url + '</a>';
  166. return urllink;
  167. }
  168. function dstag(options, text, tagname) {
  169. if(trim(text) == '') {
  170. return '\n';
  171. }
  172. var pend = parsestyle(options, '', '');
  173. var prepend = pend['prepend'];
  174. var append = pend['append'];
  175. if(in_array(tagname, ['div', 'p'])) {
  176. align = getoptionvalue('align', options);
  177. if(in_array(align, ['left', 'center', 'right'])) {
  178. prepend = '[align=' + align + ']' + prepend;
  179. append += '[/align]';
  180. } else {
  181. append += '\n';
  182. }
  183. }
  184. return prepend + recursion(tagname, text, 'dstag') + append;
  185. }
  186. function ptag(options, text, tagname) {
  187. if(trim(text) == '') {
  188. return '\n';
  189. }
  190. if(trim(options) == '') {
  191. return text + '\n';
  192. }
  193. var lineHeight = null;
  194. var textIndent = null;
  195. var align, re, matches;
  196. re = /line-height\s?:\s?(\d{1,3})px/i;
  197. matches = re.exec(options);
  198. if(matches != null) {
  199. lineHeight = matches[1];
  200. }
  201. re = /text-indent\s?:\s?(\d{1,3})em/i;
  202. matches = re.exec(options);
  203. if(matches != null) {
  204. textIndent = matches[1];
  205. }
  206. re = /text-align\s?:\s?(left|center|right)/i;
  207. matches = re.exec(options);
  208. if(matches != null) {
  209. align = matches[1];
  210. } else {
  211. align = getoptionvalue('align', options);
  212. }
  213. align = in_array(align, ['left', 'center', 'right']) ? align : 'left';
  214. style = getoptionvalue('style', options);
  215. style = preg_replace(['line-height\\\s?:\\\s?(\\\d{1,3})px', 'text-indent\\\s?:\\\s?(\\\d{1,3})em', 'text-align\\\s?:\\\s?(left|center|right)'], '', style);
  216. if(lineHeight === null && textIndent === null) {
  217. return '[align=' + align + ']' + (style ? '<span style="' + style + '">' : '') + text + (style ? '</span>' : '') + '[/align]';
  218. } else {
  219. return '[p=' + lineHeight + ', ' + textIndent + ', ' + align + ']' + (style ? '<span style="' + style + '">' : '') + text + (style ? '</span>' : '') + '[/p]';
  220. }
  221. }
  222. function fetchCheckbox(cbn) {
  223. return $(cbn) && $(cbn).checked == true ? 1 : 0;
  224. }
  225. function fetchoptionvalue(option, text) {
  226. if((position = strpos(text, option)) !== false) {
  227. delimiter = position + option.length;
  228. if(text.charAt(delimiter) == '"') {
  229. delimchar = '"';
  230. } else if(text.charAt(delimiter) == '\'') {
  231. delimchar = '\'';
  232. } else {
  233. delimchar = ' ';
  234. }
  235. delimloc = strpos(text, delimchar, delimiter + 1);
  236. if(delimloc === false) {
  237. delimloc = text.length;
  238. } else if(delimchar == '"' || delimchar == '\'') {
  239. delimiter++;
  240. }
  241. return trim(text.substr(delimiter, delimloc - delimiter));
  242. } else {
  243. return '';
  244. }
  245. }
  246. function fonttag(fontoptions, text) {
  247. var prepend = '';
  248. var append = '';
  249. var tags = new Array();
  250. tags = {'font' : 'face=', 'size' : 'size=', 'color' : 'color='};
  251. for(bbcode in tags) {
  252. optionvalue = fetchoptionvalue(tags[bbcode], fontoptions);
  253. if(optionvalue) {
  254. prepend += '[' + bbcode + '=' + optionvalue + ']';
  255. append = '[/' + bbcode + ']' + append;
  256. }
  257. }
  258. var pend = parsestyle(fontoptions, prepend, append);
  259. return pend['prepend'] + recursion('font', text, 'fonttag') + pend['append'];
  260. }
  261. function getoptionvalue(option, text) {
  262. re = new RegExp(option + "(\s+?)?\=(\s+?)?[\"']?(.+?)([\"']|$|>)", "ig");
  263. var matches = re.exec(text);
  264. if(matches != null) {
  265. return trim(matches[3]);
  266. }
  267. return '';
  268. }
  269. function html2bbcode(str) {
  270. if((allowhtml && fetchCheckbox('htmlon')) || trim(str) == '') {
  271. for(i in EXTRAFUNC['html2bbcode']) {
  272. EXTRASTR = str;
  273. try {
  274. eval('str = ' + EXTRAFUNC['html2bbcode'][i] + '()');
  275. } catch(e) {}
  276. }
  277. str = str.replace(/<img[^>]+smilieid=(["']?)(\d+)(\1)[^>]*>/ig, function($1, $2, $3) {return smileycode($3);});
  278. str = str.replace(/<img([^>]*aid=[^>]*)>/ig, function($1, $2) {return imgtag($2);});
  279. return str;
  280. }
  281. str = str.replace(/<div\sclass=["']?blockcode["']?>[\s\S]*?<blockquote>([\s\S]+?)<\/blockquote>[\s\S]*?<\/div>/ig, function($1, $2) {return codetag($2);});
  282. if(!fetchCheckbox('bbcodeoff') && allowbbcode) {
  283. var postbg = '';
  284. str = str.replace(/<style[^>]+name="editorpostbg"[^>]*>body{background-image:url\("([^\[\<\r\n;'\"\?\(\)]+?)"\);}<\/style>/ig, function($1, $4) {
  285. $4 = $4.replace(STATICURL+'image/postbg/', '');
  286. return '[postbg]'+$4+'[/postbg]';
  287. });
  288. str = str.replace(/\[postbg\]\s*([^\[\<\r\n;'\"\?\(\)]+?)\s*\[\/postbg\]/ig, function($1, $2) {
  289. postbg = $2;
  290. return '';
  291. });
  292. if(postbg) {
  293. str = '[postbg]'+postbg+'[/postbg]' + str;
  294. }
  295. }
  296. str = preg_replace(['<style.*?>[\\\s\\\S]*?<\/style>', '<script.*?>[\\\s\\\S]*?<\/script>', '<noscript.*?>[\\\s\\\S]*?<\/noscript>', '<select.*?>[\s\S]*?<\/select>', '<object.*?>[\s\S]*?<\/object>', '<!--[\\\s\\\S]*?-->', ' on[a-zA-Z]{3,16}\\\s?=\\\s?"[\\\s\\\S]*?"'], '', str);
  297. str= str.replace(/(\r\n|\n|\r)/ig, '');
  298. str= str.replace(/&((#(32|127|160|173))|shy|nbsp);/ig, ' ');
  299. if(fetchCheckbox('allowimgurl')) {
  300. str = str.replace(/([^>=\]"'\/]|^)((((https?|ftp):\/\/)|www\.)([\w\-]+\.)*[\w\-\u4e00-\u9fa5]+\.([\.a-zA-Z0-9]+|\u4E2D\u56FD|\u7F51\u7EDC|\u516C\u53F8)((\?|\/|:)+[\w\.\/=\?%\-&~`@':+!]*)+\.(jpg|gif|png|bmp))/ig, '$1[img]$2[/img]');
  301. }
  302. if(!fetchCheckbox('parseurloff')) {
  303. str = parseurl(str, 'bbcode', false);
  304. }
  305. for(i in EXTRAFUNC['html2bbcode']) {
  306. EXTRASTR = str;
  307. try {
  308. eval('str = ' + EXTRAFUNC['html2bbcode'][i] + '()');
  309. } catch(e) {}
  310. }
  311. str = str.replace(/<br\s+?style=(["']?)clear: both;?(\1)[^\>]*>/ig, '');
  312. str = str.replace(/<br[^\>]*>/ig, "\n");
  313. if(!fetchCheckbox('bbcodeoff') && allowbbcode) {
  314. str = preg_replace([
  315. '<table[^>]*float:\\\s*(left|right)[^>]*><tbody><tr><td>\\\s*([\\\s\\\S]+?)\\\s*<\/td><\/tr></tbody><\/table>',
  316. '<table([^>]*(width|background|background-color|backcolor)[^>]*)>',
  317. '<table[^>]*>',
  318. '<tr[^>]*(?:background|background-color|backcolor)[:=]\\\s*(["\']?)([\(\)\\\s%,#\\\w]+)(\\1)[^>]*>',
  319. '<tr[^>]*>',
  320. '(<t[dh]([^>]*(left|center|right)[^>]*)>)\\\s*([\\\s\\\S]+?)\\\s*(<\/t[dh]>)',
  321. '<t[dh]([^>]*(width|colspan|rowspan)[^>]*)>',
  322. '<t[dh][^>]*>',
  323. '<\/t[dh]>',
  324. '<\/tr>',
  325. '<\/table>',
  326. '<h\\\d[^>]*>',
  327. '<\/h\\\d>'
  328. ], [
  329. function($1, $2, $3) {return '[float=' + $2 + ']' + $3 + '[/float]';},
  330. function($1, $2) {return tabletag($2);},
  331. '[table]\n',
  332. function($1, $2, $3) {return '[tr=' + $3 + ']';},
  333. '[tr]',
  334. function($1, $2, $3, $4, $5, $6) {return $2 + '[align=' + $4 + ']' + $5 + '[/align]' + $6},
  335. function($1, $2) {return tdtag($2);},
  336. '[td]',
  337. '[/td]',
  338. '[/tr]\n',
  339. '[/table]',
  340. '[b]',
  341. '[/b]'
  342. ], str);
  343. str = str.replace(/<h([0-9]+)[^>]*>([\s\S]*?)<\/h\1>/ig, function($1, $2, $3) {return "[size=" + (7 - $2) + "]" + $3 + "[/size]\n\n";});
  344. str = str.replace(/<hr[^>]*>/ig, "[hr]");
  345. str = str.replace(/<img[^>]+smilieid=(["']?)(\d+)(\1)[^>]*>/ig, function($1, $2, $3) {return smileycode($3);});
  346. str = str.replace(/<img([^>]*src[^>]*)>/ig, function($1, $2) {return imgtag($2);});
  347. str = str.replace(/<a\s+?name=(["']?)(.+?)(\1)[\s\S]*?>([\s\S]*?)<\/a>/ig, '$4');
  348. str = str.replace(/<div[^>]*quote[^>]*><blockquote>([\s\S]*?)<\/blockquote><\/div>([\s\S]*?)(<br[^>]*>)?/ig, "[quote]$1[/quote]");
  349. str = str.replace(/<div[^>]*blockcode[^>]*><blockquote>([\s\S]*?)<\/blockquote><\/div>([\s\S]*?)(<br[^>]*>)?/ig, "[code]$1[/code]");
  350. str = recursion('b', str, 'simpletag', 'b');
  351. str = recursion('strong', str, 'simpletag', 'b');
  352. str = recursion('i', str, 'simpletag', 'i');
  353. str = recursion('em', str, 'simpletag', 'i');
  354. str = recursion('u', str, 'simpletag', 'u');
  355. str = recursion('strike', str, 'simpletag', 's');
  356. str = recursion('a', str, 'atag');
  357. str = recursion('font', str, 'fonttag');
  358. str = recursion('blockquote', str, 'simpletag', 'indent');
  359. str = recursion('ol', str, 'listtag');
  360. str = recursion('ul', str, 'listtag');
  361. str = recursion('div', str, 'dstag');
  362. str = recursion('p', str, 'ptag');
  363. str = recursion('span', str, 'fonttag');
  364. }
  365. str = str.replace(/<[\/\!]*?[^<>]*?>/ig, '');
  366. for(var i = 0; i <= DISCUZCODE['num']; i++) {
  367. str = str.replace("[\tDISCUZ_CODE_" + i + "\t]", DISCUZCODE['html'][i]);
  368. }
  369. str = clearcode(str);
  370. return preg_replace(['&nbsp;', '&lt;', '&gt;', '&amp;'], [' ', '<', '>', '&'], str);
  371. }
  372. function tablesimple(s, table, str) {
  373. if(strpos(str, '[tr=') || strpos(str, '[td=')) {
  374. return s;
  375. } else {
  376. return '[table=' + table + ']\n' + preg_replace(['\\\[tr\\\]', '\\\[\\\/td\\\]\\\s?\\\[td\\\]', '\\\[\\\/tr\\\]\s?', '\\\[td\\\]', '\\\[\\\/td\\\]', '\\\[\\\/td\\\]\\\[\\\/tr\\\]'], ['', '|', '', '', '', '', ''], str) + '[/table]';
  377. }
  378. }
  379. function imgtag(attributes) {
  380. var width = '';
  381. var height = '';
  382. re = /src=(["']?)([\s\S]*?)(\1)/i;
  383. var matches = re.exec(attributes);
  384. if(matches != null) {
  385. var src = matches[2];
  386. } else {
  387. return '';
  388. }
  389. re = /(max-)?width\s?:\s?(\d{1,4})(px)?/i;
  390. var matches = re.exec(attributes);
  391. if(matches != null && !matches[1]) {
  392. width = matches[2];
  393. }
  394. re = /height\s?:\s?(\d{1,4})(px)?/i;
  395. var matches = re.exec(attributes);
  396. if(matches != null) {
  397. height = matches[1];
  398. }
  399. if(!width) {
  400. re = /width=(["']?)(\d+)(\1)/i;
  401. var matches = re.exec(attributes);
  402. if(matches != null) {
  403. width = matches[2];
  404. }
  405. }
  406. if(!height) {
  407. re = /height=(["']?)(\d+)(\1)/i;
  408. var matches = re.exec(attributes);
  409. if(matches != null) {
  410. height = matches[2];
  411. }
  412. }
  413. re = /aid=(["']?)attachimg_(\d+)(\1)/i;
  414. var matches = re.exec(attributes);
  415. if(matches != null) {
  416. return '[attachimg]' + matches[2] + '[/attachimg]';
  417. }
  418. width = width > 0 ? width : 0;
  419. height = height > 0 ? height : 0;
  420. return width > 0 || height > 0 ?
  421. '[img=' + width + ',' + height + ']' + src + '[/img]' :
  422. '[img]' + src + '[/img]';
  423. }
  424. function listtag(listoptions, text, tagname) {
  425. text = text.replace(/<li>(([\s\S](?!<\/li))*?)(?=<\/?ol|<\/?ul|<li|\[list|\[\/list)/ig, '<li>$1</li>') + (BROWSER.opera ? '</li>' : '');
  426. text = recursion('li', text, 'litag');
  427. var opentag = '[list]';
  428. var listtype = fetchoptionvalue('type=', listoptions);
  429. listtype = listtype != '' ? listtype : (tagname == 'ol' ? '1' : '');
  430. if(in_array(listtype, ['1', 'a', 'A'])) {
  431. opentag = '[list=' + listtype + ']';
  432. }
  433. return text ? opentag + '\n' + recursion(tagname, text, 'listtag') + '[/list]' : '';
  434. }
  435. function litag(listoptions, text) {
  436. return '[*]' + text.replace(/(\s+)$/g, '') + '\n';
  437. }
  438. function parsecode(text) {
  439. DISCUZCODE['num']++;
  440. DISCUZCODE['html'][DISCUZCODE['num']] = '<div class="blockcode"><blockquote>' + htmlspecialchars(text) + '</blockquote></div>';
  441. return "[\tDISCUZ_CODE_" + DISCUZCODE['num'] + "\t]";
  442. }
  443. function parsestyle(tagoptions, prepend, append) {
  444. var searchlist = [
  445. ['align', true, 'text-align:\\s*(left|center|right);?', 1],
  446. ['float', true, 'float:\\s*(left|right);?', 1],
  447. ['color', true, '(^|[;\\s])color:\\s*([^;]+);?', 2],
  448. ['backcolor', true, '(^|[;\\s])background-color:\\s*([^;]+);?', 2],
  449. ['font', true, 'font-family:\\s*([^;]+);?', 1],
  450. ['size', true, 'font-size:\\s*(\\d+(\\.\\d+)?(px|pt|in|cm|mm|pc|em|ex|%|));?', 1],
  451. ['size', true, 'font-size:\\s*(x\\-small|small|medium|large|x\\-large|xx\\-large|\\-webkit\\-xxx\\-large);?', 1, 'size'],
  452. ['b', false, 'font-weight:\\s*(bold);?'],
  453. ['i', false, 'font-style:\\s*(italic);?'],
  454. ['u', false, 'text-decoration:\\s*(underline);?'],
  455. ['s', false, 'text-decoration:\\s*(line-through);?']
  456. ];
  457. var sizealias = {'x-small':1,'small':2,'medium':3,'large':4,'x-large':5,'xx-large':6,'-webkit-xxx-large':7};
  458. var style = getoptionvalue('style', tagoptions);
  459. re = /^(?:\s|)color:\s*rgb\((\d+),\s*(\d+),\s*(\d+)\)(;?)/i;
  460. style = style.replace(re, function($1, $2, $3, $4, $5) {return("color:#" + parseInt($2).toString(16) + parseInt($3).toString(16) + parseInt($4).toString(16) + $5);});
  461. var len = searchlist.length;
  462. for(var i = 0; i < len; i++) {
  463. searchlist[i][4] = !searchlist[i][4] ? '' : searchlist[i][4];
  464. re = new RegExp(searchlist[i][2], "ig");
  465. match = re.exec(style);
  466. if(match != null) {
  467. opnvalue = match[searchlist[i][3]];
  468. if(searchlist[i][4] == 'size') {
  469. opnvalue = sizealias[opnvalue];
  470. }
  471. prepend += '[' + searchlist[i][0] + (searchlist[i][1] == true ? '=' + opnvalue + ']' : ']');
  472. append = '[/' + searchlist[i][0] + ']' + append;
  473. }
  474. }
  475. return {'prepend' : prepend, 'append' : append};
  476. }
  477. function parsetable(width, bgcolor, str) {
  478. if(isUndefined(width)) {
  479. var width = '';
  480. } else {
  481. try {
  482. width = width.substr(width.length - 1, width.length) == '%' ? (width.substr(0, width.length - 1) <= 98 ? width : '98%') : (width <= 560 ? width : '98%');
  483. } catch(e) { width = ''; }
  484. }
  485. if(isUndefined(str)) {
  486. return;
  487. }
  488. if(strpos(str, '[/tr]') === false && strpos(str, '[/td]') === false) {
  489. var rows = str.split('\n');
  490. var s = '';
  491. for(i = 0;i < rows.length;i++) {
  492. s += '<tr><td>' + preg_replace(['\r', '\\\\\\\|', '\\\|', '\\\\n'], ['', '&#124;', '</td><td>', '\n'], rows[i]) + '</td></tr>';
  493. }
  494. str = s;
  495. simple = ' simpletable';
  496. } else {
  497. simple = '';
  498. str = str.replace(/\[tr(?:=([\(\)\s%,#\w]+))?\]\s*\[td(?:=(\d{1,4}%?))?\]/ig, function($1, $2, $3) {
  499. return '<tr' + ($2 ? ' style="background-color: ' + $2 + '"' : '') + '><td' + ($3 ? ' width="' + $3 + '"' : '') + '>';
  500. });
  501. str = str.replace(/\[tr(?:=([\(\)\s%,#\w]+))?\]\s*\[td(?:=(\d{1,2}),(\d{1,2})(?:,(\d{1,4}%?))?)?\]/ig, function($1, $2, $3, $4, $5) {
  502. return '<tr' + ($2 ? ' style="background-color: ' + $2 + '"' : '') + '><td' + ($3 ? ' colspan="' + $3 + '"' : '') + ($4 ? ' rowspan="' + $4 + '"' : '') + ($5 ? ' width="' + $5 + '"' : '') + '>';
  503. });
  504. str = str.replace(/\[\/td\]\s*\[td(?:=(\d{1,4}%?))?\]/ig, function($1, $2) {
  505. return '</td><td' + ($2 ? ' width="' + $2 + '"' : '') + '>';
  506. });
  507. str = str.replace(/\[\/td\]\s*\[td(?:=(\d{1,2}),(\d{1,2})(?:,(\d{1,4}%?))?)?\]/ig, function($1, $2, $3, $4) {
  508. return '</td><td' + ($2 ? ' colspan="' + $2 + '"' : '') + ($3 ? ' rowspan="' + $3 + '"' : '') + ($4 ? ' width="' + $4 + '"' : '') + '>';
  509. });
  510. str = str.replace(/\[\/td\]\s*\[\/tr\]\s*/ig, '</td></tr>');
  511. str = str.replace(/<td> <\/td>/ig, '<td>&nbsp;</td>');
  512. }
  513. return '<table ' + (width == '' ? '' : 'width="' + width + '" ') + 'class="t_table"' + (isUndefined(bgcolor) ? '' : ' style="background-color: ' + bgcolor + '"') + simple +'>' + str + '</table>';
  514. }
  515. function preg_quote(str) {
  516. return (str+'').replace(/([\\\.\+\*\?\[\^\]\$\(\)\{\}\=\!<>\|\:])/g, "\\$1");
  517. }
  518. function recursion(tagname, text, dofunction, extraargs) {
  519. if(extraargs == null) {
  520. extraargs = '';
  521. }
  522. tagname = tagname.toLowerCase();
  523. var open_tag = '<' + tagname;
  524. var open_tag_len = open_tag.length;
  525. var close_tag = '</' + tagname + '>';
  526. var close_tag_len = close_tag.length;
  527. var beginsearchpos = 0;
  528. do {
  529. var textlower = text.toLowerCase();
  530. var tagbegin = textlower.indexOf(open_tag, beginsearchpos);
  531. if(tagbegin == -1) {
  532. break;
  533. }
  534. var strlen = text.length;
  535. var inquote = '';
  536. var found = false;
  537. var tagnameend = false;
  538. var optionend = 0;
  539. var t_char = '';
  540. for(optionend = tagbegin; optionend <= strlen; optionend++) {
  541. t_char = text.charAt(optionend);
  542. if((t_char == '"' || t_char == "'") && inquote == '') {
  543. inquote = t_char;
  544. } else if((t_char == '"' || t_char == "'") && inquote == t_char) {
  545. inquote = '';
  546. } else if(t_char == '>' && !inquote) {
  547. found = true;
  548. break;
  549. } else if((t_char == '=' || t_char == ' ') && !tagnameend) {
  550. tagnameend = optionend;
  551. }
  552. }
  553. if(!found) {
  554. break;
  555. }
  556. if(!tagnameend) {
  557. tagnameend = optionend;
  558. }
  559. var offset = optionend - (tagbegin + open_tag_len);
  560. var tagoptions = text.substr(tagbegin + open_tag_len, offset);
  561. var acttagname = textlower.substr(tagbegin * 1 + 1, tagnameend - tagbegin - 1);
  562. if(acttagname != tagname) {
  563. beginsearchpos = optionend;
  564. continue;
  565. }
  566. var tagend = textlower.indexOf(close_tag, optionend);
  567. if(tagend == -1) {
  568. break;
  569. }
  570. var nestedopenpos = textlower.indexOf(open_tag, optionend);
  571. while(nestedopenpos != -1 && tagend != -1) {
  572. if(nestedopenpos > tagend) {
  573. break;
  574. }
  575. tagend = textlower.indexOf(close_tag, tagend + close_tag_len);
  576. nestedopenpos = textlower.indexOf(open_tag, nestedopenpos + open_tag_len);
  577. }
  578. if(tagend == -1) {
  579. beginsearchpos = optionend;
  580. continue;
  581. }
  582. var localbegin = optionend + 1;
  583. var localtext = eval(dofunction)(tagoptions, text.substr(localbegin, tagend - localbegin), tagname, extraargs);
  584. text = text.substring(0, tagbegin) + localtext + text.substring(tagend + close_tag_len);
  585. beginsearchpos = tagbegin + localtext.length;
  586. } while(tagbegin != -1);
  587. return text;
  588. }
  589. function simpletag(options, text, tagname, parseto) {
  590. if(trim(text) == '') {
  591. return '';
  592. }
  593. text = recursion(tagname, text, 'simpletag', parseto);
  594. return '[' + parseto + ']' + text + '[/' + parseto + ']';
  595. }
  596. function smileycode(smileyid) {
  597. if(typeof smilies_type != 'object') return;
  598. for(var typeid in smilies_array) {
  599. for(var page in smilies_array[typeid]) {
  600. for(var i in smilies_array[typeid][page]) {
  601. if(smilies_array[typeid][page][i][0] == smileyid) {
  602. return smilies_array[typeid][page][i][1];
  603. break;
  604. }
  605. }
  606. }
  607. }
  608. }
  609. function strpos(haystack, needle, _offset) {
  610. if(isUndefined(_offset)) {
  611. _offset = 0;
  612. }
  613. var _index = haystack.toLowerCase().indexOf(needle.toLowerCase(), _offset);
  614. return _index == -1 ? false : _index;
  615. }
  616. function tabletag(attributes) {
  617. var width = '';
  618. re = /width=(["']?)(\d{1,4}%?)(\1)/i;
  619. var matches = re.exec(attributes);
  620. if(matches != null) {
  621. width = matches[2].substr(matches[2].length - 1, matches[2].length) == '%' ?
  622. (matches[2].substr(0, matches[2].length - 1) <= 98 ? matches[2] : '98%') :
  623. (matches[2] <= 560 ? matches[2] : '98%');
  624. } else {
  625. re = /width\s?:\s?(\d{1,4})([px|%])/i;
  626. var matches = re.exec(attributes);
  627. if(matches != null) {
  628. width = matches[2] == '%' ? (matches[1] <= 98 ? matches[1] + '%' : '98%') : (matches[1] <= 560 ? matches[1] : '98%');
  629. }
  630. }
  631. var bgcolor = '';
  632. re = /(?:background|background-color|bgcolor)[:=]\s*(["']?)((rgb\(\d{1,3}%?,\s*\d{1,3}%?,\s*\d{1,3}%?\))|(#[0-9a-fA-F]{3,6})|([a-zA-Z]{1,20}))(\1)/i;
  633. var matches = re.exec(attributes);
  634. if(matches != null) {
  635. bgcolor = matches[2];
  636. width = width ? width : '98%';
  637. }
  638. return bgcolor ? '[table=' + width + ',' + bgcolor + ']\n' : (width ? '[table=' + width + ']\n' : '[table]\n');
  639. }
  640. function tdtag(attributes) {
  641. var colspan = 1;
  642. var rowspan = 1;
  643. var width = '';
  644. re = /colspan=(["']?)(\d{1,2})(\1)/i;
  645. var matches = re.exec(attributes);
  646. if(matches != null) {
  647. colspan = matches[2];
  648. }
  649. re = /rowspan=(["']?)(\d{1,2})(\1)/i;
  650. var matches = re.exec(attributes);
  651. if(matches != null) {
  652. rowspan = matches[2];
  653. }
  654. re = /width=(["']?)(\d{1,4}%?)(\1)/i;
  655. var matches = re.exec(attributes);
  656. if(matches != null) {
  657. width = matches[2];
  658. }
  659. return in_array(width, ['', '0', '100%']) ?
  660. (colspan == 1 && rowspan == 1 ? '[td]' : '[td=' + colspan + ',' + rowspan + ']') :
  661. (colspan == 1 && rowspan == 1 ? '[td=' + width + ']' : '[td=' + colspan + ',' + rowspan + ',' + width + ']');
  662. }
  663. if(typeof jsloaded == 'function') {
  664. jsloaded('bbcode');
  665. }