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