test_serializers_entities.js (2845B)
1 const encoders = { 2 xml: doc => { 3 let enc = Cu.createDocumentEncoder("text/xml"); 4 enc.init(doc, "text/xml", Ci.nsIDocumentEncoder.OutputLFLineBreak); 5 return enc; 6 }, 7 html: doc => { 8 let enc = Cu.createDocumentEncoder("text/html"); 9 enc.init(doc, "text/html", Ci.nsIDocumentEncoder.OutputLFLineBreak); 10 return enc; 11 }, 12 htmlBasic: doc => { 13 let enc = Cu.createDocumentEncoder("text/html"); 14 enc.init( 15 doc, 16 "text/html", 17 Ci.nsIDocumentEncoder.OutputEncodeBasicEntities | 18 Ci.nsIDocumentEncoder.OutputLFLineBreak 19 ); 20 return enc; 21 }, 22 xhtml: doc => { 23 let enc = Cu.createDocumentEncoder("application/xhtml+xml"); 24 enc.init( 25 doc, 26 "application/xhtml+xml", 27 Ci.nsIDocumentEncoder.OutputLFLineBreak 28 ); 29 return enc; 30 }, 31 }; 32 33 // Which characters should we encode as entities? It depends on the serializer. 34 const encodeAll = { html: true, htmlBasic: true, xhtml: true, xml: true }; 35 const encodeHTMLBasic = { 36 html: false, 37 htmlBasic: true, 38 xhtml: false, 39 xml: false, 40 }; 41 const encodeXML = { html: false, htmlBasic: false, xhtml: true, xml: true }; 42 const encodeNone = { html: false, htmlBasic: false, xhtml: false, xml: false }; 43 const encodingInfoMap = new Map([ 44 // Basic sanity chars '<', '>', '"', '&' get encoded in all cases. 45 ["<", encodeAll], 46 [">", encodeAll], 47 ["&", encodeAll], 48 // nbsp is only encoded with the HTML encoder when encoding basic entities. 49 ["\xA0", encodeHTMLBasic], 50 ]); 51 52 const encodingMap = new Map([ 53 ["<", "<"], 54 [">", ">"], 55 ["&", "&"], 56 // nbsp is only encoded with the HTML encoder when encoding basic entities. 57 ["\xA0", " "], 58 ]); 59 60 function encodingInfoForChar(c) { 61 var info = encodingInfoMap.get(c); 62 if (info) { 63 return info; 64 } 65 return encodeNone; 66 } 67 68 function encodingForChar(c, type) { 69 var info = encodingInfoForChar(c); 70 if (!info[type]) { 71 return c; 72 } 73 return encodingMap.get(c); 74 } 75 76 const doc = new DOMParser().parseFromString("<root></root>", "text/xml"); 77 const root = doc.documentElement; 78 for (let i = 0; i < 255; ++i) { 79 let el = doc.createElement("span"); 80 el.textContent = String.fromCharCode(i); 81 root.appendChild(el); 82 } 83 for (let type of ["xml", "xhtml", "htmlBasic", "html"]) { 84 let str = encoders[type](doc).encodeToString(); 85 const prefix = "<root><span>"; 86 const suffix = "</span></root>"; 87 Assert.ok(str.startsWith(prefix), `${type} serialization starts correctly`); 88 Assert.ok(str.endsWith(suffix), `${type} serialization ends correctly`); 89 str = str.substring(prefix.length, str.length - suffix.length); 90 let encodings = str.split("</span><span>"); 91 for (let i = 0; i < 255; ++i) { 92 let c = String.fromCharCode(i); 93 Assert.equal( 94 encodingForChar(c, type), 95 encodings[i], 96 `${type} encoding of char ${i} is correct` 97 ); 98 } 99 }