test_font_family_parsing.html (10348B)
1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <meta charset=utf-8> 5 <title>Font family name parsing tests</title> 6 <link rel="author" title="John Daggett" href="mailto:jdaggett@mozilla.com"> 7 <link rel="help" href="http://www.w3.org/TR/css3-fonts/#font-family-prop" /> 8 <link rel="help" href="http://www.w3.org/TR/css3-fonts/#font-prop" /> 9 <meta name="assert" content="tests that valid font family names parse and invalid ones don't" /> 10 <script type="text/javascript" src="/resources/testharness.js"></script> 11 <script type="text/javascript" src="/resources/testharnessreport.js"></script> 12 <style type="text/css"> 13 </style> 14 </head> 15 <body> 16 <div id="log"></div> 17 <pre id="display"></pre> 18 <style type="text/css" id="testbox"></style> 19 20 <script type="text/javascript"> 21 22 function fontProp(n, size, s1, s2) { return (s1 ? s1 + " " : "") + (s2 ? s2 + " " : "") + size + " " + n; } 23 function font(n, size, s1, s2) { return "font: " + fontProp(n, size, s1, s2); } 24 25 // testrules 26 // namelist - font family list 27 // invalid - true if declarations won't parse in either font-family or font 28 // fontonly - only test with the 'font' property 29 // single - namelist includes only a single name (@font-face rules only allow a single name) 30 31 var testFontFamilyLists = [ 32 33 /* basic syntax */ 34 { namelist: "simple", single: true }, 35 { namelist: "'simple'", single: true }, 36 { namelist: '"simple"', single: true }, 37 { namelist: "-simple", single: true }, 38 { namelist: "_simple", single: true }, 39 { namelist: "quite simple", single: true }, 40 { namelist: "quite _simple", single: true }, 41 { namelist: "quite -simple", single: true }, 42 { namelist: "0simple", invalid: true, single: true }, 43 { namelist: "simple!", invalid: true, single: true }, 44 { namelist: "simple()", invalid: true, single: true }, 45 { namelist: "quite@simple", invalid: true, single: true }, 46 { namelist: "#simple", invalid: true, single: true }, 47 { namelist: "quite 0simple", invalid: true, single: true }, 48 { namelist: "納豆嫌い", single: true }, 49 { namelist: "納豆嫌い, ick, patooey" }, 50 { namelist: "ick, patooey, 納豆嫌い" }, 51 { namelist: "納豆嫌い, 納豆大嫌い" }, 52 { namelist: "納豆嫌い, 納豆大嫌い, 納豆本当に嫌い" }, 53 { namelist: "納豆嫌い, 納豆大嫌い, 納豆本当に嫌い, 納豆は好みではない" }, 54 { namelist: "arial, helvetica, sans-serif" }, 55 { namelist: "arial, helvetica, 'times' new roman, sans-serif", invalid: true }, 56 { namelist: "arial, helvetica, \"times\" new roman, sans-serif", invalid: true }, 57 58 { namelist: "arial, helvetica, \"\\\"times new roman\", sans-serif" }, 59 { namelist: "arial, helvetica, '\\\"times new roman', sans-serif" }, 60 { namelist: "arial, helvetica, times 'new' roman, sans-serif", invalid: true }, 61 { namelist: "arial, helvetica, times \"new\" roman, sans-serif", invalid: true }, 62 { namelist: "\"simple", single: true }, 63 { namelist: "\\\"simple", single: true }, 64 { namelist: "\"\\\"simple\"", single: true }, 65 { namelist: "İsimple", single: true }, 66 { namelist: "ßsimple", single: true }, 67 { namelist: "ẙsimple", single: true }, 68 69 /* escapes */ 70 { namelist: "\\s imple", single: true }, 71 { namelist: "\\073 imple", single: true }, 72 73 { namelist: "\\035 simple", single: true }, 74 { namelist: "sim\\035 ple", single: true }, 75 { namelist: "simple\\02cinitial", single: true }, 76 { namelist: "simple, \\02cinitial" }, 77 { namelist: "sim\\020 \\035 ple", single: true }, 78 { namelist: "sim\\020 5ple", single: true }, 79 { namelist: "\\@simple", single: true }, 80 { namelist: "\\@simple\\;", single: true }, 81 { namelist: "\\@font-face", single: true }, 82 { namelist: "\\@font-face\\;", single: true }, 83 { namelist: "\\031 \\036 px", single: true }, 84 { namelist: "\\031 \\036 px", single: true }, 85 { namelist: "\\1f4a9", single: true }, 86 { namelist: "\\01f4a9", single: true }, 87 { namelist: "\\0001f4a9", single: true }, 88 { namelist: "\\AbAb", single: true }, 89 90 /* keywords */ 91 { namelist: "italic", single: true }, 92 { namelist: "bold", single: true }, 93 { namelist: "bold italic", single: true }, 94 { namelist: "italic bold", single: true }, 95 { namelist: "larger", single: true }, 96 { namelist: "smaller", single: true }, 97 { namelist: "bolder", single: true }, 98 { namelist: "lighter", single: true }, 99 { namelist: "default", invalid: true, fontonly: true, single: true }, 100 { namelist: "initial", invalid: true, fontonly: true, single: true }, 101 { namelist: "inherit", invalid: true, fontonly: true, single: true }, 102 { namelist: "normal", single: true }, 103 { namelist: "default, simple", invalid: true }, 104 { namelist: "initial, simple", invalid: true }, 105 { namelist: "inherit, simple", invalid: true }, 106 { namelist: "normal, simple" }, 107 { namelist: "simple, default", invalid: true }, 108 { namelist: "simple, initial", invalid: true }, 109 { namelist: "simple, inherit", invalid: true }, 110 { namelist: "simple, default bongo" }, 111 { namelist: "simple, initial bongo" }, 112 { namelist: "simple, inherit bongo" }, 113 { namelist: "simple, bongo default" }, 114 { namelist: "simple, bongo initial" }, 115 { namelist: "simple, bongo inherit" }, 116 { namelist: "simple, normal" }, 117 { namelist: "simple default", single: true }, 118 { namelist: "simple initial", single: true }, 119 { namelist: "simple inherit", single: true }, 120 { namelist: "simple normal", single: true }, 121 { namelist: "default simple", single: true }, 122 { namelist: "initial simple", single: true }, 123 { namelist: "inherit simple", single: true }, 124 { namelist: "normal simple", single: true }, 125 { namelist: "caption", single: true }, // these are keywords for the 'font' property but only when in the first position 126 { namelist: "icon", single: true }, 127 { namelist: "menu", single: true }, 128 { namelist: "unset", invalid: true, fontonly: true, single: true }, 129 { namelist: "unset, simple", invalid: true }, 130 { namelist: "simple, unset", invalid: true }, 131 { namelist: "simple, unset bongo" }, 132 { namelist: "simple, bongo unset" }, 133 { namelist: "simple unset", single: true }, 134 { namelist: "unset simple", single: true } 135 136 ]; 137 138 var gTest = 0; 139 140 /* strip out just values */ 141 function extractDecl(rule) 142 { 143 var t = rule.replace(/[ \n]+/g, " "); 144 t = t.replace(/.*{[ \n]*/, ""); 145 t = t.replace(/[ \n]*}.*/, ""); 146 return t; 147 } 148 149 150 function testStyleRuleParse(decl, invalid) { 151 var sheet = document.styleSheets[1]; 152 var rule = ".test" + gTest++ + " { " + decl + "; }"; 153 154 while(sheet.cssRules.length > 0) { 155 sheet.deleteRule(0); 156 } 157 158 // shouldn't throw but improper handling of punctuation may cause some parsers to throw 159 try { 160 sheet.insertRule(rule, 0); 161 } catch (e) { 162 assert_unreached("unexpected error with " + decl + " ==> " + e.name); 163 } 164 165 assert_equals(sheet.cssRules.length, 1, 166 "strange number of rules (" + sheet.cssRules.length + ") with " + decl); 167 168 var s = extractDecl(sheet.cssRules[0].cssText); 169 170 if (invalid) { 171 assert_equals(s, "", "rule declaration shouldn't parse - " + rule + " ==> " + s); 172 } else { 173 assert_not_equals(s, "", "rule declaration should parse - " + rule); 174 175 // check that the serialization also parses 176 var r = ".test" + gTest++ + " { " + s + " }"; 177 while(sheet.cssRules.length > 0) { 178 sheet.deleteRule(0); 179 } 180 try { 181 sheet.insertRule(r, 0); 182 } catch (e) { 183 assert_unreached("exception occurred parsing serialized form of rule - " + rule + " ==> " + r + " " + e.name); 184 } 185 var s2 = extractDecl(sheet.cssRules[0].cssText); 186 assert_not_equals(s2, "", "serialized form of rule should also parse - " + rule + " ==> " + r); 187 } 188 } 189 190 var kDefaultFamilySetting = "onelittlepiggywenttomarket"; 191 192 function testFontFamilySetterParse(namelist, invalid) { 193 var el = document.getElementById("display"); 194 195 el.style.fontFamily = kDefaultFamilySetting; 196 var def = el.style.fontFamily; 197 el.style.fontFamily = namelist; 198 if (!invalid) { 199 assert_not_equals(el.style.fontFamily, def, "fontFamily setter should parse - " + namelist); 200 var parsed = el.style.fontFamily; 201 el.style.fontFamily = kDefaultFamilySetting; 202 el.style.fontFamily = parsed; 203 assert_equals(el.style.fontFamily, parsed, "fontFamily setter should parse serialized form to identical serialization - " + parsed + " ==> " + el.style.fontFamily); 204 } else { 205 assert_equals(el.style.fontFamily, def, "fontFamily setter shouldn't parse - " + namelist); 206 } 207 } 208 209 var kDefaultFontSetting = "16px onelittlepiggywenttomarket"; 210 211 function testFontSetterParse(n, size, s1, s2, invalid) { 212 var el = document.getElementById("display"); 213 214 el.style.font = kDefaultFontSetting; 215 var def = el.style.font; 216 var fp = fontProp(n, size, s1, s2); 217 el.style.font = fp; 218 if (!invalid) { 219 assert_not_equals(el.style.font, def, "font setter should parse - " + fp); 220 var parsed = el.style.font; 221 el.style.font = kDefaultFontSetting; 222 el.style.font = parsed; 223 assert_equals(el.style.font, parsed, "font setter should parse serialized form to identical serialization - " + parsed + " ==> " + el.style.font); 224 } else { 225 assert_equals(el.style.font, def, "font setter shouldn't parse - " + fp); 226 } 227 } 228 229 var testFontVariations = [ 230 { size: "16px" }, 231 { size: "900px" }, 232 { size: "900em" }, 233 { size: "35%" }, 234 { size: "7832.3%" }, 235 { size: "xx-large" }, 236 { size: "larger", s1: "lighter" }, 237 { size: "16px", s1: "italic" }, 238 { size: "16px", s1: "italic", s2: "bold" }, 239 { size: "smaller", s1: "normal" }, 240 { size: "16px", s1: "normal", s2: "normal" }, 241 { size: "16px", s1: "400", s2: "normal" }, 242 { size: "16px", s1: "bolder", s2: "oblique" } 243 ]; 244 245 function testFamilyNameParsing() { 246 var i; 247 for (i = 0; i < testFontFamilyLists.length; i++) { 248 var tst = testFontFamilyLists[i]; 249 var n = tst.namelist; 250 var t; 251 252 if (!tst.fontonly) { 253 t = "font-family: " + n; 254 test(function() { testStyleRuleParse(t, tst.invalid); }, t); 255 test(function() { testFontFamilySetterParse(n, tst.invalid); }, t + " (setter)"); 256 } 257 258 var v; 259 for (v = 0; v < testFontVariations.length; v++) { 260 var f = testFontVariations[v]; 261 t = font(n, f.size, f.s1, f.s2); 262 test(function() { testStyleRuleParse(t, tst.invalid); }, t); 263 test(function() { testFontSetterParse(n, f.size, f.s1, f.s2, tst.invalid); }, t + " (setter)"); 264 } 265 } 266 } 267 268 testFamilyNameParsing(); 269 270 </script> 271 </body> 272 </html>