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