@@ -75,7 +75,7 @@ var PR_keywords = new Object();
7575 var PERL_KEYWORDS = (
7676 "foreach require sub unless until use elsif BEGIN END" ) ;
7777 var SH_KEYWORDS = (
78- "if then do else fi end" ) ;
78+ "if then do done else fi end" ) ;
7979 var RUBY_KEYWORDS = (
8080 "if then elsif else end begin do rescue ensure while for class module " +
8181 "def yield raise until unless and or not when case super undef break " +
@@ -240,9 +240,85 @@ function PR_prefixMatch(chars, len, prefix) {
240240 return true ;
241241}
242242
243- /** used to convert html special characters embedded in XMP tags into html. */
243+ /** like textToHtml but escapes double quotes to be attribute safe. */
244+ function PR_attribToHtml ( str ) {
245+ return str . replace ( / & / g, '&' )
246+ . replace ( / < / g, '<' )
247+ . replace ( / > / g, '>' )
248+ . replace ( / " / g, '"' )
249+ . replace ( / \xa0 / , ' ' ) ;
250+ }
251+
252+ /** escapest html special characters to html. */
244253function PR_textToHtml ( str ) {
245- return str . replace ( / & / g, '&' ) . replace ( / < / g, '<' ) . replace ( / > / g, '>' ) ;
254+ return str . replace ( / & / g, '&' )
255+ . replace ( / < / g, '<' )
256+ . replace ( / > / g, '>' )
257+ . replace ( / \xa0 / g, ' ' ) ;
258+ }
259+
260+ /** is the given node's innerHTML normally unescaped? */
261+ function PR_isRawContent ( node ) {
262+ return 'XMP' == node . tagName ;
263+ }
264+
265+ var PR_innerHtmlWorks = null ;
266+ function PR_getInnerHtml ( node ) {
267+ // inner html is hopelessly broken in Safari 2.0.4 when the content is
268+ // an html description of well formed XML and the containing tag is a PRE
269+ // tag, so we detect that case and emulate innerHTML.
270+ if ( null == PR_innerHtmlWorks ) {
271+ var testNode = document . createElement ( 'PRE' ) ;
272+ testNode . appendChild (
273+ document . createTextNode ( '<!DOCTYPE foo PUBLIC "foo bar">\n<foo />' ) ) ;
274+ PR_innerHtmlWorks = ! / < / . test ( testNode . innerHTML ) ;
275+ }
276+
277+ if ( PR_innerHtmlWorks ) {
278+ var content = node . innerHTML ;
279+ // XMP tags contain unescaped entities so require special handling.
280+ if ( PR_isRawContent ( node ) ) {
281+ content = PR_textToHtml ( html ) ;
282+ }
283+ return content ;
284+ }
285+
286+ var out = [ ] ;
287+ for ( var child = node . firstChild ; child ; child = child . nextSibling ) {
288+ PR_normalizedHtml ( child , out ) ;
289+ }
290+ return out . join ( '' ) ;
291+ }
292+
293+ /**
294+ * walks the DOM returning a properly escaped version of innerHTML.
295+ */
296+ function PR_normalizedHtml ( node , out ) {
297+ switch ( node . nodeType ) {
298+ case 1 : // an element
299+ var name = node . tagName . toLowerCase ( ) ;
300+ out . push ( '\074' , name ) ;
301+ for ( var i = 0 ; i < node . attributes . length ; ++ i ) {
302+ var attr = node . attributes [ i ] ;
303+ if ( ! attr . specified ) { continue ; }
304+ out . push ( ' ' ) ;
305+ PR_normalizedHtml ( attr , out ) ;
306+ }
307+ out . push ( '>' ) ;
308+ for ( var child = node . firstChild ; child ; child = child . nextSibling ) {
309+ PR_normalizedHtml ( child , out ) ;
310+ }
311+ if ( node . firstChild || ! / ^ (?: b r | l i n k | i m g ) $ / . test ( name ) ) {
312+ out . push ( '<\/' , name , '>' ) ;
313+ }
314+ break ;
315+ case 2 : // an attribute
316+ out . push ( node . name . toLowerCase ( ) , '="' , PR_attribToHtml ( node . value ) , '"' ) ;
317+ break ;
318+ case 3 : case 4 : // text
319+ out . push ( PR_textToHtml ( node . nodeValue ) ) ;
320+ break ;
321+ }
246322}
247323
248324
@@ -1302,22 +1378,17 @@ function prettyPrint() {
13021378 }
13031379 }
13041380 if ( ! nested ) {
1305- // XMP tags contain unescaped entities so require special handling.
1306- var isRawContent = 'XMP' == cs . tagName ;
1307-
13081381 // fetch the content as a snippet of properly escaped HTML.
13091382 // Firefox adds newlines at the end.
1310- var content = cs . innerHTML . replace ( / (?: \r \n ? | \n ) $ / , '' ) ;
1383+ var content = PR_getInnerHtml ( cs ) ;
1384+ content = content . replace ( / (?: \r \n ? | \n ) $ / , '' ) ;
13111385 if ( ! content ) { continue ; }
1312- if ( isRawContent ) {
1313- content = PR_textToHtml ( content ) ;
1314- }
13151386
13161387 // do the pretty printing
13171388 var newContent = prettyPrintOne ( content ) ;
13181389
13191390 // push the prettified html back into the tag.
1320- if ( ! isRawContent ) {
1391+ if ( PR_isRawContent ( cs ) ) {
13211392 // just replace the old html with the new
13221393 cs . innerHTML = newContent ;
13231394 } else {
0 commit comments