Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 function emptyFontFaceDeclarations() | |
| 2 { | |
| 3 var stylesheet = document.styleSheets[0]; | |
| 4 var rules = stylesheet.cssRules; | |
| 5 var rulesLengthSnapshot = stylesheet.cssRules.length; | |
| 6 if (!rulesLengthSnapshot) | |
| 7 return; | |
| 8 for (var i = 0; i < rulesLengthSnapshot; i++) { | |
| 9 stylesheet.deleteRule(0); | |
| 10 } | |
| 11 } | |
| 12 | |
| 13 function makeFontFaceDeclaration(stretch, style, weight) | |
| 14 { | |
| 15 var fontFaceDeclaration = '@font-face { font-family: "CSSMatchingtest"; ' + | |
| 16 "font-stretch: " + stretch + ";" + | |
| 17 "font-style: " + style + ";" + | |
| 18 "font-weight: " + weight + ";" + | |
| 19 'src: url("' + | |
| 20 "resources/fonts/CSSMatchingTest_" + | |
| 21 stretch + "_" + style + "_" + weight + '.ttf");'; | |
| 22 return fontFaceDeclaration; | |
| 23 } | |
| 24 | |
| 25 function notifyInspectorFontsReady() { | |
| 26 var cssRules = document.styleSheets[0].cssRules; | |
| 27 var fontsAvailable = []; | |
| 28 for (var i = 0; i < cssRules.length; i++) { | |
| 29 urlmatch = /url\(.*fonts\/CSSMatchingTest_(.*).ttf\)/.exec( | |
| 30 cssRules[i].cssText); | |
| 31 fontsAvailable.push(urlmatch[1]); | |
| 32 } | |
| 33 evaluateInFrontend('window.onFontsLoaded(' + | |
| 34 JSON.stringify(fontsAvailable) + ");"); | |
| 35 } | |
| 36 | |
| 37 function updateAvailableFontFaceDeclarations(available) | |
| 38 { | |
| 39 emptyFontFaceDeclarations(); | |
| 40 for (stretch of available.stretches) | |
| 41 for (style of available.styles) | |
| 42 for (weight of available.weights) { | |
| 43 document.styleSheets[0].addRule( | |
| 44 makeFontFaceDeclaration(stretch, style, weight)); | |
| 45 } | |
| 46 | |
| 47 document.fonts.ready.then(window.notifyInspectorFontsReady); | |
| 48 } | |
| 49 | |
| 50 function test() | |
| 51 { | |
| 52 var documentNodeId; | |
| 53 var documentNodeSelector; | |
| 54 var allTestSelectors = []; | |
| 55 var testSelectors = []; | |
| 56 | |
| 57 var stretches = [ 'condensed', 'expanded' ]; | |
| 58 var styles = [ 'normal', 'italic' ]; | |
| 59 var weights = [ '100', '900' ]; | |
| 60 | |
| 61 var weightsHumanReadable = [ "Thin", "Black" ]; | |
| 62 | |
| 63 var fontSetVariations = []; | |
| 64 var currentFontSetVariation = {}; | |
| 65 | |
| 66 makeFontSetVariations(); | |
| 67 | |
| 68 function makeFontSetVariations() { | |
| 69 // For each of the three properties we have three choices: | |
| 70 // Restrict to the first value, to the second, or | |
| 71 // allow both. So we're iterating over those options | |
| 72 // for each dimension to generate the set of allowed | |
| 73 // options for each property. The fonts in the test | |
| 74 // page will later be generated from these possible | |
| 75 // choices / restrictions. | |
| 76 function choices(property) { | |
| 77 return [ property, [ property[0] ], [ property[1] ] ]; | |
| 78 } | |
| 79 | |
| 80 for (stretchChoice of choices(stretches)) { | |
| 81 for (styleChoice of choices(styles)) { | |
| 82 for (weightChoice of choices(weights)) { | |
| 83 var available = {}; | |
| 84 available.stretches = stretchChoice; | |
| 85 available.styles = styleChoice; | |
| 86 available.weights = weightChoice; | |
| 87 fontSetVariations.push(available); | |
| 88 } | |
| 89 } | |
| 90 } | |
| 91 } | |
| 92 | |
| 93 InspectorTest.requestDocumentNodeId(onDocumentNodeId); | |
| 94 | |
| 95 function onDocumentNodeId(nodeId) | |
| 96 { | |
| 97 documentNodeId = nodeId; | |
| 98 | |
| 99 InspectorTest.evaluateInInspectedPage( | |
| 100 'JSON.stringify(' + | |
| 101 'Array.prototype.map.call(' + | |
| 102 'document.querySelectorAll(".test *"),' + | |
| 103 'function(element) { return element.id } ));', | |
| 104 startTestingPage); | |
| 105 } | |
| 106 | |
| 107 function startTestingPage(result) | |
| 108 { | |
| 109 allTestSelectors = JSON.parse(result.result.result.value); | |
| 110 nextTest(); | |
| 111 } | |
| 112 | |
| 113 function nextTest() { | |
| 114 if (testSelectors.length) { | |
| 115 testNextPageElement(); | |
| 116 } else { | |
| 117 currentFontSetVariation = fontSetVariations.shift(); | |
| 118 if (currentFontSetVariation) { | |
| 119 testSelectors = allTestSelectors.slice(); | |
| 120 updateFontDeclarationsInPageForVariation( | |
| 121 currentFontSetVariation); | |
| 122 } else { | |
| 123 InspectorTest.completeTest(); | |
| 124 } | |
| 125 } | |
| 126 } | |
| 127 | |
| 128 function updateFontDeclarationsInPageForVariation(fontSetVariation) | |
| 129 { | |
| 130 window.testPageFontsReady = false; | |
| 131 InspectorTest.evaluateInInspectedPage( | |
| 132 'updateAvailableFontFaceDeclarations(' + | |
| 133 JSON.stringify(fontSetVariation) + | |
| 134 ');'); | |
| 135 // nextTest() is called once we receive the onFontsLoaded | |
| 136 // notification from the page. | |
| 137 } | |
| 138 | |
| 139 // Explicitly make this available on window scope so that testing | |
| 140 // can resume through a signal from the page once the fonts.ready | |
| 141 // promise resolves. | |
| 142 window.onFontsLoaded = function(loadedFonts) { | |
| 143 InspectorTest.log("Available fonts updated: " + | |
| 144 JSON.stringify(loadedFonts) + "\n"); | |
| 145 // fonts.ready event fires too early, used fonts for rendering | |
|
Kunihiko Sakamoto
2015/08/05 10:36:36
Hmm, fonts.ready resolves before the style change
| |
| 146 // have not been updated yet. Remove this wehn crbug.com/516680 | |
| 147 // is fixed. | |
| 148 // https://drafts.csswg.org/css-font-loading/#font-face-set-ready | |
| 149 setTimeout(nextTest, 100); | |
| 150 } | |
| 151 | |
| 152 function testNextPageElement(result) | |
| 153 { | |
| 154 var nextSelector = testSelectors.shift() | |
| 155 if (nextSelector) { | |
| 156 documentNodeSelector = "#" + nextSelector; | |
| 157 platformFontsForElementWithSelector(documentNodeSelector); | |
| 158 } | |
| 159 } | |
| 160 | |
| 161 function platformFontsForElementWithSelector(selector) | |
| 162 { | |
| 163 InspectorTest.requestNodeId(documentNodeId, selector, onNodeId); | |
| 164 | |
| 165 function onNodeId(nodeId) | |
| 166 { | |
| 167 InspectorTest.sendCommandOrDie("CSS.getPlatformFontsForNode", | |
| 168 { nodeId: nodeId }, | |
| 169 onGotComputedFonts); | |
| 170 } | |
| 171 | |
| 172 function onGotComputedFonts(response) | |
| 173 { | |
| 174 logResults(response); | |
| 175 nextTest(); | |
| 176 } | |
| 177 } | |
| 178 | |
| 179 function logResults(response) | |
| 180 { | |
| 181 InspectorTest.log(documentNodeSelector); | |
| 182 logPassFailResult( | |
| 183 documentNodeSelector, | |
| 184 response.fonts[0].familyName); | |
| 185 } | |
| 186 | |
| 187 function cssStyleMatchingExpectationForSelector(selector) { | |
| 188 var selectorStretchStyleWeight = selector.substr(1).split("_"); | |
| 189 var selectorStretch = selectorStretchStyleWeight[0].toLowerCase(); | |
| 190 var selectorStyle = selectorStretchStyleWeight[1].toLowerCase(); | |
| 191 var selectorWeight = selectorStretchStyleWeight[2]; | |
| 192 | |
| 193 var expectedProperties = {}; | |
| 194 if (currentFontSetVariation.stretches.indexOf(selectorStretch) > 0) { | |
| 195 expectedProperties.stretch = selectorStretch; | |
| 196 } else { | |
| 197 // If the requested property value is not availabe in the | |
| 198 // current font set, then it's restricted to only one value, | |
| 199 // which is the nearest match, and at index 0. | |
| 200 expectedProperties.stretch = currentFontSetVariation.stretches[0]; | |
| 201 } | |
| 202 | |
| 203 if (currentFontSetVariation.styles.indexOf(selectorStyle) > 0) { | |
| 204 expectedProperties.style = selectorStyle; | |
| 205 } else { | |
| 206 expectedProperties.style = currentFontSetVariation.styles[0]; | |
| 207 } | |
| 208 | |
| 209 if (currentFontSetVariation.weights.indexOf(selectorWeight) > 0) { | |
| 210 expectedProperties.weight = selectorWeight; | |
| 211 } else { | |
| 212 expectedProperties.weight = currentFontSetVariation.weights[0]; | |
| 213 } | |
| 214 | |
| 215 return expectedProperties; | |
| 216 } | |
| 217 | |
| 218 function logPassFailResult(selector, usedFontName) | |
| 219 { | |
| 220 var actualStretchStyleWeight = | |
| 221 /CSSMatchingTest (\w*) (\w*) (.*)/.exec(usedFontName); | |
| 222 var actualStretch, actualStyle, actualWeight; | |
| 223 if (actualStretchStyleWeight && actualStretchStyleWeight.length > 3) { | |
| 224 actualStretch = actualStretchStyleWeight[1].toLowerCase(); | |
| 225 actualStyle = actualStretchStyleWeight[2].toLowerCase(); | |
| 226 // Font names have human readable weight description, | |
| 227 // we need to convert. | |
| 228 actualWeight = weights [ | |
| 229 weightsHumanReadable.indexOf(actualStretchStyleWeight[3]) ]; | |
| 230 } else { | |
| 231 actualStretch = usedFontName; | |
| 232 actualStyle = ""; | |
| 233 actualWeight = ""; | |
| 234 } | |
| 235 | |
| 236 var expectedProperties = cssStyleMatchingExpectationForSelector( | |
| 237 selector); | |
| 238 | |
| 239 InspectorTest.log("Expected: " + | |
| 240 expectedProperties.stretch + " " + | |
| 241 expectedProperties.style + " " + | |
| 242 expectedProperties.weight); | |
| 243 InspectorTest.log("Actual: " + actualStretch + " " + | |
| 244 actualStyle + " " + | |
| 245 actualWeight); | |
| 246 | |
| 247 if (actualStretch != expectedProperties.stretch || | |
| 248 actualStyle != expectedProperties.style || | |
| 249 actualWeight != expectedProperties.weight) { | |
| 250 InspectorTest.log("FAIL\n"); | |
| 251 } else { | |
| 252 InspectorTest.log("PASS\n"); | |
| 253 } | |
| 254 } | |
| 255 }; | |
| 256 | |
| 257 window.addEventListener("DOMContentLoaded", function () { | |
| 258 runTest(); | |
| 259 }, false); | |
| OLD | NEW |