@@ -53,7 +53,8 @@ function assertJasmineSuites() {
5353/*
5454 * tests about the contents of source (and lib) files:
5555 * - check for header comment
56- * - check that we don't have .classList
56+ * - check that we don't have any features that break in IE
57+ * - check that we don't use getComputedStyle unexpectedly
5758 */
5859function assertSrcContents ( ) {
5960 var licenseSrc = constants . licenseSrc ;
@@ -69,6 +70,8 @@ function assertSrcContents() {
6970 // Forbidden in IE in any context
7071 var IE_BLACK_LIST = [ 'classList' ] ;
7172
73+ var getComputedStyleCnt = 0 ;
74+
7275 glob ( combineGlobs ( [ srcGlob , libGlob ] ) , function ( err , files ) {
7376 files . forEach ( function ( file ) {
7477 var code = fs . readFileSync ( file , 'utf-8' ) ;
@@ -85,13 +88,21 @@ function assertSrcContents() {
8588 if ( source === 'Math.sign' ) {
8689 logs . push ( file + ' : contains Math.sign (IE failure)' ) ;
8790 }
91+ else if ( source === 'window.getComputedStyle' ) {
92+ getComputedStyleCnt ++ ;
93+ }
8894 else if ( IE_BLACK_LIST . indexOf ( lastPart ) !== - 1 ) {
8995 logs . push ( file + ' : contains .' + lastPart + ' (IE failure)' ) ;
9096 }
9197 else if ( IE_SVG_BLACK_LIST . indexOf ( lastPart ) !== - 1 ) {
9298 logs . push ( file + ' : contains .' + lastPart + ' (IE failure in SVG)' ) ;
9399 }
94100 }
101+ else if ( node . type === 'Identifier' && node . source ( ) === 'getComputedStyle' ) {
102+ if ( node . parent . source ( ) !== 'window.getComputedStyle' ) {
103+ logs . push ( file + ': getComputedStyle must be called as a `window` property.' ) ;
104+ }
105+ }
95106 } ) ;
96107
97108 var header = comments [ 0 ] ;
@@ -106,6 +117,34 @@ function assertSrcContents() {
106117 }
107118 } ) ;
108119
120+ /*
121+ * window.getComputedStyle calls are restricted, so we want to be
122+ * explicit about it whenever we add or remove these calls. This is
123+ * the reason d3.selection.style is forbidden as a getter.
124+ *
125+ * The rule is:
126+ * - You MAY NOT call getComputedStyle during rendering a plot, EXCEPT
127+ * in calculating autosize for the plot (which only makes sense if
128+ * the plot is displayed). Other uses of getComputedStyle while
129+ * rendering will fail, at least in Chrome, if the plot div is not
130+ * attached to the DOM.
131+ *
132+ * - You MAY call getComputedStyle during interactions (hover etc)
133+ * because at that point it's known that the plot is displayed.
134+ *
135+ * - You must use the explicit `window.getComputedStyle` rather than
136+ * the implicit global scope `getComputedStyle` for jsdom compat.
137+ *
138+ * - If you use conforms to these rules, you may update
139+ * KNOWN_GET_COMPUTED_STYLE_CALLS to count the new use.
140+ */
141+ var KNOWN_GET_COMPUTED_STYLE_CALLS = 5 ;
142+ if ( getComputedStyleCnt !== KNOWN_GET_COMPUTED_STYLE_CALLS ) {
143+ logs . push ( 'Expected ' + KNOWN_GET_COMPUTED_STYLE_CALLS +
144+ ' window.getComputedStyle calls, found ' + getComputedStyleCnt +
145+ '. See ' + __filename + ' for details how to proceed.' ) ;
146+ }
147+
109148 log ( 'correct headers and contents in lib/ and src/' , logs ) ;
110149 } ) ;
111150}
0 commit comments