You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

508 lines
16 KiB

  1. /*
  2. * HTML Parser By John Resig (ejohn.org)
  3. * Original code by Erik Arvidsson, Mozilla Public License
  4. * http://erik.eae.net/simplehtmlparser/simplehtmlparser.js
  5. * @license GPL 3 or later (http://www.gnu.org/licenses/gpl.html)
  6. */
  7. var HTMLParser;
  8. var HTMLParserInstalled=true;
  9. var HTMLParser_Elements = new Array();
  10. (function(){
  11. // Regular Expressions for parsing tags and attributes
  12. var startTag = /^<(\w+)((?:\s+[\w-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/,
  13. endTag = /^<\/(\w+)[^>]*>/,
  14. attr = /([\w-]+)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g;
  15. // Empty Elements - HTML 4.01
  16. var empty = makeMap("br,col,hr,img");
  17. // HTMLParser_Elements['empty'] = empty;
  18. // Block Elements - HTML 4.01
  19. var block = makeMap("blockquote,center,del,div,dl,dt,hr,iframe,ins,li,ol,p,pre,table,tbody,td,tfoot,th,thead,tr,ul");
  20. // HTMLParser_Elements['block'] = block;
  21. // Inline Elements - HTML 4.01
  22. var inline = makeMap("a,abbr,acronym,b,big,br,cite,code,del,em,font,h1,h2,h3,h4,h5,h6,i,img,ins,kbd,q,s,samp,small,span,strike,strong,sub,sup,tt,u,var");
  23. // Elements that you can, intentionally, leave open
  24. // (and which close themselves)
  25. var closeSelf = makeMap("colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr");
  26. // Attributes that have their values filled in disabled="disabled"
  27. var fillAttrs = makeMap("checked,disabled,ismap,noresize,nowrap,readonly,selected");
  28. // Special Elements (can contain anything)
  29. var special = makeMap("script,style");
  30. //define ('BROKEN_IMAGE', DOKU_URL . 'lib/plugins/ckgedit/fckeditor/userfiles/blink.jpg?nolink&33x34');
  31. var broken_image ='http://' + location.host + DOKU_BASE + '/lib/plugins/ckgedit/fckeditor/userfiles/blink.jpg?nolink&33x34';
  32. HTMLParser = this.HTMLParser = function( html, handler ) {
  33. var index, chars, match, stack = [], last = html;
  34. html = html.replace(/(<img.*?src="data:image\/\w+;base64,\s*)(.*?)(\/>)/gm,
  35. function(match, p1, p2) {
  36. var skip = false;
  37. if(p1.match(/msword/) ) {
  38. skip = true;
  39. match = match.replace(/msword/,"");
  40. }
  41. if(p2.length > 2500000 && !skip ) {
  42. jQuery('#dw__editform').append('<input type="hidden" id="broken_image" name="broken_image" value="' + p2.length +'" />');
  43. return '{{' + broken_image + '}}';
  44. }
  45. return match;
  46. });
  47. html = html.replace(/~~OPEN_HTML_BLOCK~~/gm , '~~START_HTML_BLOCK~~') ;
  48. html = html.replace(/~~END_HTML_BLOCK~~/gm , '~~CLOSE_HTML_BLOCK~~') ;
  49. if(html.match(/~~START_HTML_BLOCK~~/gm) ){ //adopted [\s\S] from Goyvaerts, Reg. Exp. Cookbook (O'Reilly)
  50. if(!JSINFO['htmlok']) {
  51. html = html.replace(/~~START_HTML_BLOCK~~|~~CLOSE_HTML_BLOCK~~/gm,"");
  52. }
  53. html = html.replace(/(<p>)*\s*~~START_HTML_BLOCK~~\s*(<\/p>)*([\s\S]+)~~CLOSE_HTML_BLOCK~~\s*(<\/p>)*/gm, function(match,p,p1,text,p2) {
  54. text = text.replace(/<\/?div.*?>/gm,"");
  55. text = text.replace(/<code>/gm,"");
  56. text = text.replace(/<\/code>/gm,"");
  57. text = text.replace(/</gm,"&lt;");
  58. text = text.replace(/<\//gm,"&gt;");
  59. return "~~START_HTML_BLOCK~~\n\n" + text + "\n\n~~CLOSE_HTML_BLOCK~~\n\n";
  60. });
  61. }
  62. /* remove dwfck note superscripts from inside links */
  63. html = html.replace(/(<sup\s+class=\"dwfcknote fckgL\d+\"\>fckgL\d+\s*\<\/sup\>)\<\/a\>/gm, function(match,sup,a) {
  64. return( '</a>' +sup);
  65. }
  66. );
  67. /* remove html5 attributes */
  68. var pos = html.indexOf('data-');
  69. if(pos != -1) {
  70. html = html.replace(/(<\w+)([^>]+)>/gm,function(match,tag,atts){
  71. atts = atts.replace(/data-[\w\-]+\s*=\s*(\"|\')\w+(\"|\')/,"");
  72. //alert(atts);
  73. return tag + atts+ '>';
  74. });
  75. }
  76. stack.last = function(){
  77. return this[ this.length - 1 ];
  78. };
  79. while ( html ) {
  80. chars = true;
  81. // Make sure we're not in a script or style element
  82. if ( !stack.last() || !special[ stack.last() ] ) {
  83. // Comment
  84. if ( html.indexOf("<!--") == 0 ) {
  85. index = html.indexOf("-->");
  86. if ( index >= 0 ) {
  87. if ( handler.comment )
  88. handler.comment( html.substring( 4, index ) );
  89. html = html.substring( index + 3 );
  90. chars = false;
  91. }
  92. // end tag
  93. } else if ( html.indexOf("</") == 0 ) {
  94. match = html.match( endTag );
  95. if ( match ) {
  96. html = html.substring( match[0].length );
  97. match[0].replace( endTag, parseEndTag );
  98. chars = false;
  99. }
  100. // start tag
  101. } else if ( html.indexOf("<") == 0 ) {
  102. match = html.match( startTag );
  103. if ( match ) {
  104. html = html.substring( match[0].length );
  105. match[0].replace( startTag, parseStartTag );
  106. chars = false;
  107. }
  108. }
  109. if ( chars ) {
  110. index = html.indexOf("<");
  111. var text = index < 0 ? html : html.substring( 0, index );
  112. html = index < 0 ? "" : html.substring( index );
  113. if ( handler.chars )
  114. handler.chars( text );
  115. }
  116. } else {
  117. html = html.replace(new RegExp("(.*)<\/" + stack.last() + "[^>]*>"), function(all, text){
  118. text = text.replace(/<!--(.*?)-->/g, "$1")
  119. .replace(/<!\[CDATA\[(.*?)]]>/g, "$1");
  120. if ( handler.chars )
  121. handler.chars( text );
  122. return "";
  123. });
  124. parseEndTag( "", stack.last() );
  125. }
  126. if ( html == last )
  127. throw "Parse Error: " + html;
  128. last = html;
  129. }
  130. // Clean up any remaining tags
  131. parseEndTag();
  132. function parseStartTag( tag, tagName, rest, unary ) {
  133. if ( block[ tagName ] ) {
  134. while ( stack.last() && inline[ stack.last() ] ) {
  135. parseEndTag( "", stack.last() );
  136. }
  137. }
  138. if ( closeSelf[ tagName ] && stack.last() == tagName ) {
  139. parseEndTag( "", tagName );
  140. }
  141. unary = empty[ tagName ] || !!unary;
  142. if ( !unary )
  143. stack.push( tagName );
  144. if ( handler.start ) {
  145. var attrs = [];
  146. rest.replace(attr, function(match, name) {
  147. var value = arguments[2] ? arguments[2] :
  148. arguments[3] ? arguments[3] :
  149. arguments[4] ? arguments[4] :
  150. fillAttrs[name] ? name : "";
  151. attrs.push({
  152. name: name,
  153. value: value,
  154. escaped: value.replace(/(^|[^\\])"/g, '$1\\\"') //"
  155. });
  156. });
  157. if ( handler.start )
  158. handler.start( tagName, attrs, unary );
  159. }
  160. }
  161. function parseEndTag( tag, tagName ) {
  162. // If no tag name is provided, clean shop
  163. if ( !tagName )
  164. var pos = 0;
  165. // Find the closest opened tag of the same type
  166. else
  167. for ( var pos = stack.length - 1; pos >= 0; pos-- )
  168. if ( stack[ pos ] == tagName )
  169. break;
  170. if ( pos >= 0 ) {
  171. // Close all the open elements, up the stack
  172. for ( var i = stack.length - 1; i >= pos; i-- )
  173. if ( handler.end )
  174. handler.end( stack[ i ] );
  175. // Remove the open elements from the stack
  176. stack.length = pos;
  177. }
  178. }
  179. };
  180. function makeMap(str){
  181. var obj = {}, items = str.split(",");
  182. for ( var i = 0; i < items.length; i++ )
  183. obj[ items[i] ] = true;
  184. return obj;
  185. }
  186. })();
  187. function HTMLParser_test_result(results) {
  188. var test_str = "";
  189. for ( i=0; i < results.length; i++) {
  190. var character = results.charAt(i);
  191. if(results.charCodeAt(i) == 10)
  192. character ='\\n';
  193. if(results.charCodeAt(i) == 32)
  194. character ='SP';
  195. var entry = character + ' ';
  196. test_str += entry;
  197. if(results.charCodeAt(i) == 10) {
  198. test_str += "\n";
  199. }
  200. }
  201. if(!confirm(test_str)) return false;
  202. return true;
  203. }
  204. function hide_backup_msg() {
  205. document.getElementById("backup_msg").style.display="none";
  206. return false;
  207. }
  208. function show_backup_msg(msg) {
  209. document.getElementById("backup_msg").style.display="block";
  210. document.getElementById("backup_msg_area").innerHTML = "Backed up to: " + msg;
  211. return false;
  212. }
  213. // legacy functions
  214. function remove_draft(){
  215. }
  216. function dwedit_draft_delete() {
  217. }
  218. // legacy functions end
  219. function setEdHeight(h) {
  220. h = parseInt(h);
  221. document.cookie = 'ckgEdht=' + h +';expires=0;path=' +JSINFO['doku_base'] + ';SameSite=Lax;';
  222. }
  223. /* enable disable image paste */
  224. function ckgd_setImgPaste(which) {
  225. var state = JSINFO['ckgEdPaste'] ? JSINFO['ckgEdPaste'] : "";
  226. if(state == 'on') {
  227. which = 'off'
  228. }
  229. else which = 'on';
  230. JSINFO['ckgEdPaste'] = which;
  231. document.cookie = 'ckgEdPaste=' + which +';expires="Thu, 18 Dec 2575 12:00:00 UTC";path=' +JSINFO['doku_base'];
  232. alert(LANG.plugins.ckgedit.ckg_paste_restart + ' ' + LANG.plugins.ckgedit[which]);
  233. }
  234. function ckg_RawImgMsg() {
  235. return LANG.plugins.ckgedit.broken_image_1 + "\n" + LANG.plugins.ckgedit.broken_image_2 ;
  236. }
  237. function GetE(e) {
  238. return document.getElementById(e);
  239. }
  240. var dokuBase = location.host + DOKU_BASE;
  241. if(window.getSelection != undefined) {
  242. var doku_ckg_getSelection = window.getSelection;
  243. window.getSelection = function(ta) {
  244. if(!ta) ta = GetE("wiki__text");
  245. return doku_ckg_getSelection(ta);
  246. };
  247. }
  248. function ckgedit_seteditor_priority(m,client,dw_val_obj) {
  249. var which = {'Y': 'Dokuwiki', 'N': 'CKEditor'};
  250. if (typeof m === "undefined") { // Safari
  251. if(dw_val_obj[0].checked) {
  252. m= dw_val_obj[0].value;
  253. }
  254. else if(dw_val_obj[1].checked) {
  255. m = dw_val_obj[1].value;
  256. }
  257. }
  258. var params = "dw_val=" + m; params += '&call=cked_selector'; params += "&dwp_client=" + client;
  259. jQuery.post( DOKU_BASE + 'lib/exe/ajax.php', params,
  260. function (data) {
  261. if(data == 'done') {
  262. if(!m)
  263. alert(LANG.plugins.ckgedit.dwp_not_sel);
  264. else
  265. alert(LANG.plugins.ckgedit.dwp_updated + which[m]);
  266. }
  267. else {
  268. alert(LANG.plugins.ckgedit.dwp_save_err + data);
  269. }
  270. },
  271. 'html'
  272. );
  273. }
  274. /* gets both size and filetime: "size||filetime" */
  275. function ckged_get_unlink_size(id) {
  276. var params = 'call=cked_deletedsize'; params += "&cked_delid=" + id;
  277. jQuery.post( DOKU_BASE + 'lib/exe/ajax.php', params,
  278. function (data) {
  279. if(data) {
  280. JSINFO['ckg_del_sz'] = data;
  281. //console.log(data);
  282. }
  283. else {
  284. // alert(LANG.plugins.ckgedit.dwp_save_err + data);
  285. }
  286. },
  287. 'html'
  288. );
  289. }
  290. function ckged_setmedia(id,del, refresh_cb) {
  291. var params = 'call=cked_upload'; params += "&ckedupl_id=" + id;
  292. if(del) params += "&ckedupl_del=D&delsize="+JSINFO['ckg_del_sz'];
  293. jQuery.post( DOKU_BASE + 'lib/exe/ajax.php', params,
  294. function (data) {
  295. if(data) {
  296. if(refresh_cb) {
  297. refresh_cb.postMessage(JSINFO['doku_url'], JSINFO['doku_url']);
  298. }
  299. // console.log(data);
  300. }
  301. else {
  302. // alert(LANG.plugins.ckgedit.dwp_save_err + data);
  303. }
  304. },
  305. 'html'
  306. );
  307. }
  308. jQuery(function() {
  309. if(JSINFO['hide_captcha_error'] =='hide') {
  310. jQuery("div.error").hide();
  311. }
  312. });
  313. jQuery(function() {
  314. jQuery( "#editor_height" ).keydown(function(event) {
  315. if ( event.which == 13 ) {
  316. event.preventDefault();
  317. }
  318. });
  319. $dokuWiki = jQuery('.dokuwiki');
  320. jQuery('.editbutton_table button').click(function() {
  321. var f = this.form;
  322. jQuery('<input />').attr('type','hidden').attr('name','mode').attr('value','dwiki').appendTo(jQuery(f));
  323. jQuery('<input />').attr('type','hidden').attr('name','fck_preview_mode').attr('value','nil').appendTo(jQuery(f));
  324. });
  325. if(typeof(JSINFO['dbl_click_auth'] !== 'undefined') && JSINFO['dbl_click_auth'] == "") return;
  326. if(!JSINFO['ckg_dbl_click']) return;
  327. /**
  328. * If one or more edit section buttons exist?
  329. * This makes sure this feature is enabled only on the edit page and for users with page edit rights.
  330. */
  331. if (jQuery('.editbutton_section', $dokuWiki).length > 0) {
  332. // register double click event for all headings and section divs
  333. jQuery('[class^="sectionedit"], div[class^="level"]', $dokuWiki).dblclick(function(){
  334. // find the closest edit button form to the element double clicked (downwards) and submit the form
  335. var f = jQuery(this).nextAll('.editbutton_section:eq(0)').children('form:eq(0)');
  336. //alert(jQuery(f).hasClass('button'));
  337. jQuery('<input />').attr('type','hidden').attr('name','mode').attr('value','dwiki').appendTo(jQuery(f));
  338. jQuery('<input />').attr('type','hidden').attr('name','fck_preview_mode').attr('value','nil').appendTo(jQuery(f));
  339. f.submit();
  340. })
  341. }
  342. if(JSINFO['ckg_template'].match(/bootstrap/) && jQuery('div.editButtons').length>0) {
  343. // var n=jQuery('div.editButtons input').length;
  344. jQuery( "div.editButtons input").each(function( index ) {
  345. if(jQuery(this).hasClass('btn-success')) {
  346. jQuery(this).removeClass('btn-success')
  347. }
  348. if(jQuery(this).hasClass('btn-danger')) {
  349. jQuery(this).removeClass('btn-danger');
  350. }
  351. });
  352. }
  353. });
  354. function ckg_edit_mediaman_insert(edid, id, opts, dw_align) {
  355. var link, width, s, align;
  356. //parse option string
  357. var options = opts.substring(1).split('&');
  358. //get width and link options
  359. link = 'detail';
  360. for (var i in options) {
  361. var opt = options[i];
  362. if (typeof opt !== 'string') {
  363. continue;
  364. }
  365. if (opt.match(/^\d+$/)) {
  366. width = opt;
  367. } else if (opt.match(/^\w+$/)) {
  368. link = opt;
  369. }
  370. }
  371. //get alignment option
  372. switch (dw_align) {
  373. case '2':
  374. align = 'medialeft';
  375. break;
  376. case '3':
  377. align = 'mediacenter';
  378. break;
  379. case '4':
  380. align = 'mediaright';
  381. break;
  382. default:
  383. align = '';
  384. break;
  385. }
  386. var funcNum = CKEDITOR.instances.wiki__text._.filebrowserFn;
  387. var fileUrl = DOKU_BASE + 'lib/exe/fetch.php?media=' + id;
  388. CKEDITOR.tools.callFunction(funcNum, fileUrl, function() {
  389. var dialog = this.getDialog();
  390. if ( dialog.getName() == "image" ) {
  391. if (align != null) {
  392. dialog.getContentElement("info", "cmbAlign").setValue(align);
  393. }
  394. if (link != null) {
  395. dialog.getContentElement("info", "cmbLinkType").setValue(link);
  396. }
  397. if (width != null) {
  398. dialog.getContentElement("info", "txtWidth").setValue(width);
  399. dialog.dontResetSize = true;
  400. }
  401. }
  402. });
  403. }
  404. function ckg_edit_mediaman_insertlink(edid, id, opts, dw_align) {
  405. var funcNum = CKEDITOR.instances.wiki__text._.filebrowserFn;
  406. CKEDITOR.tools.callFunction(funcNum, id, function() {
  407. var dialog = this.getDialog();
  408. if (dialog.getName() == "link") {
  409. dialog.getContentElement('info', 'media').setValue(id);
  410. }
  411. });
  412. }
  413. function getCookie(name) {
  414. var re = new RegExp(name + "=([^;]+)");
  415. var value = re.exec(document.cookie);
  416. return (value != null) ? decodeURIComponent(value[1]) : null;
  417. }
  418. function ckg_admininfo(t){
  419. if(t.innerHTML == LANG.plugins.ckgedit.stylesheet_cinfo)
  420. t.innerHTML = LANG.plugins.ckgedit.stylesheet_oinfo;
  421. else t.innerHTML = LANG.plugins.ckgedit.stylesheet_cinfo;
  422. }
  423. /* DOKUWIKI:include_once locktimer.js */