r111374 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r111373‎ | r111374 | r111375 >
Date:14:49, 13 February 2012
Author:krinkle
Status:ok
Tags:
Comment:
[WebFonts tests] Refactor / fix breakage

* attr() / css() problem (r109144)
-- Basically undoes r109144, which changed usage of css() to attr().
-- attr() returns the attribute value, whereas the style property (via css()) returns the actually used/applied style in the DOM. The latter should be tested, because attr() will always return what it was given, so it will never appear to fail even when it doesn't work.
-- It turns out that in Chrome, creating an element and setting some style properties, will not instantly update and/or create a "style" attribute with the cssText. Triggering the browser to index the element (by accessing innerHTML) fixes this for Chrome. This is a work-around that only applies to the unit test and is fine. It does not affect production, since in production these elements would be pre-existing at least one function call ahead of time (usually even from the server response).

* <body> attribute restoration (r109230)
-- Code was storing and setting the <body lang> attribute, and then supposedly restored it later by doing ``$body.attr( 'lang', bodyLang );``. However, since attr() does both retrieval and setting of attributes, if the second arguments is undefined, it will return the current value instead of setting it to 'undefined'.
-- The reason <body lang> value was undefined, is because MediaWiki stores it on <html>, not on the <body>.
-- Fixed code by getting/setting the lang-attribute from <html> instead, and added an undefined-check to be future proof.

* <select> test failure (r#)
-- The unit test was failing on <select> before the switch to attr(), even after the above fix the <select> test was still failing. This is actually not a bug anywhere in WebFonts, but something browsers don't allow/support.
-- Removed 'select' selector from tests and from production code
Modified paths:
  • /trunk/extensions/WebFonts/resources/ext.webfonts.js (modified) (history)
  • /trunk/extensions/WebFonts/tests/qunit/ext.webfonts.tests.js (modified) (history)

Diff [purge]

Index: trunk/extensions/WebFonts/tests/qunit/ext.webfonts.tests.js
@@ -25,7 +25,7 @@
2626 continue;
2727 }
2828 cssText = lastStyleSheet.cssRules[0].cssText;
29 - if ( cssText.indexOf( '@font-face' ) >= 0 && cssText.indexOf( fontFamilyName ) >= 0 ) {
 29+ if ( cssText.indexOf( '@font-face' ) !== -1 && cssText.indexOf( fontFamilyName ) !== -1 ) {
3030 return true;
3131 }
3232 }
@@ -44,8 +44,7 @@
4545
4646 // Remove the quotes from font names
4747 for ( fontIndex = 0; fontIndex < fontList.length; ++fontIndex ) {
48 - fontList[fontIndex] = fontList[fontIndex].replace( /^["']/, '' );
49 - fontList[fontIndex] = fontList[fontIndex].replace( /["']$/, '' );
 48+ fontList[fontIndex] = fontList[fontIndex].replace( /^["']/, '' ).replace( /["']$/, '' );
5049 }
5150
5251 return fontList;
@@ -65,63 +64,66 @@
6665 } );
6766
6867 test( '-- Application of a web font to the page and its removal', function() {
 68+ // @fixme TODO: test that the right thing was written to the log
 69+
6970 if ( !mw.webfonts.isBrowserSupported ) {
7071 return;
7172 }
7273
73 - expect( 18 );
 74+ expect( 15 );
7475
7576 var invalidFont = 'NonExistingFont';
7677 strictEqual( mw.webfonts.set( invalidFont ), undefined, 'A non-existent font is not initialized' );
77 - // TODO: test that the right thing was written to the log
7878
79 - var $body = $( 'body' );
80 - var bodyLang = $body.attr( 'lang' );
 79+ var $doc = $( 'html' );
 80+ var docLang = $doc.attr( 'lang' );
8181 var oldConfig = {
82 - fontFamily: $body.css( 'font-family' ),
83 - fontSize: $body.css( 'font-size' )
 82+ fontFamily: $doc.css( 'font-family' ),
 83+ fontSize: $doc.css( 'font-size' )
8484 };
85 - var teluguFont = mw.webfonts.config.languages.te[0];
86 - $body.attr( 'lang', 'te' );
 85+ var fontName = mw.webfonts.config.languages.my[2];
 86+ $doc.attr( 'lang', 'my' );
8787
 88+ var $body = $( 'body' );
8889 var $inputElement = $( '<input value="input content"/>' );
89 - var $selectElement = $( '<select><option value="foobar">Foobar</option></select>' );
9090 var $textareaElement = $( '<textarea>textarea content</textarea>' );
91 - $( '#qunit-fixture' ).append( $inputElement, $selectElement, $textareaElement );
 91+ $( '#qunit-fixture' ).append( $inputElement, $textareaElement );
9292
93 - assertTrue( mw.webfonts.set( teluguFont ), 'Attempted to load a Telugu font for the whole page' );
 93+ assertTrue( mw.webfonts.set( fontName ), 'Attempted to load a Telugu font for the whole page' );
9494 var fallbackFonts = 'Helvetica, Arial, sans-serif';
9595 deepEqual( oldConfig, mw.webfonts.oldconfig, 'Previous body css was saved properly' );
9696
9797 // Font application
98 - var expectedFontFamilyValue = fontFamilyList( "'" + teluguFont + "', " + fallbackFonts );
 98+ var expectedFontFamilyValue = fontFamilyList( "'" + fontName + "', " + fallbackFonts );
9999 deepEqual( fontFamilyList( $body.css( 'font-family' ) ),
100100 expectedFontFamilyValue, 'The web font was applied to font-family of body' );
101101 deepEqual( fontFamilyList( $inputElement.css( 'font-family' ) ),
102102 expectedFontFamilyValue, 'The web font was applied to font-family of input' );
103 - deepEqual( fontFamilyList( $selectElement.css( 'font-family' ) ),
104 - expectedFontFamilyValue, 'The web font was applied to font-family of select' );
105103 deepEqual( fontFamilyList( $textareaElement.css( 'font-family' ) ),
106104 expectedFontFamilyValue, 'The web font was applied to font-family of textarea' );
107105
108106 // Cookie set
109 - equals( $.cookie( 'webfonts-font' ), teluguFont, 'Correct cookie for the font was set' );
 107+ equals( $.cookie( 'webfonts-font' ), fontName, 'Correct cookie for the font was set' );
110108
111109 // Reset everything
112110 strictEqual( mw.webfonts.set( false ), undefined, 'Reset body after testing font application' );
113 - equals( $body.css( 'font-family' ), oldConfig.fontFamily, 'Previous font-family for body was restored' );
114 - equals( $body.css( 'font-size' ), oldConfig.fontSize, 'Previous font-size for body was restored' );
 111+ equals( $doc.css( 'font-family' ), oldConfig.fontFamily, 'Previous font-family for body was restored' );
 112+ equals( $doc.css( 'font-size' ), oldConfig.fontSize, 'Previous font-size for body was restored' );
115113 equals( $inputElement.css( 'font-family' ), oldConfig.fontFamily, 'Previous font-family for body was restored' );
116114 equals( $inputElement.css( 'font-size' ), oldConfig.fontSize, 'Previous font-size for body was restored' );
117 - equals( $selectElement.css( 'font-family' ), oldConfig.fontFamily, 'Previous font-family for the select element was restored' );
118 - equals( $selectElement.css( 'font-size' ), oldConfig.fontSize, 'Previous font-size for the select element restored' );
119115 equals( $textareaElement.css( 'font-family' ), oldConfig.fontFamily, 'Previous font-family for the textarea element was restored' );
120116 equals( $textareaElement.css( 'font-size' ), oldConfig.fontSize, 'Previous font-size for the textarea element was restored' );
121117
122118 // Cookie set
123119 equals( $.cookie( 'webfonts-font' ), 'none', 'The cookie was removed' );
124120
125 - $body.attr( 'lang', bodyLang );
 121+ // docLang could be undefined, in which case jQuery will treat
 122+ // the invocation as a getter instead of a setter.
 123+ if ( docLang !== undefined ) {
 124+ $doc.attr( 'lang', docLang );
 125+ } else {
 126+ $doc.removeAttr( 'lang' );
 127+ }
126128 } );
127129
128130 test( '-- Dynamic font loading', function() {
@@ -185,33 +187,48 @@
186188 return;
187189 }
188190
189 - expect( 11 );
 191+ expect( 8 );
190192
 193+ // Save
 194+ var oldFonts = mw.webfonts.fonts;
191195 mw.webfonts.fonts = [];
192196
193 - var $testElement = $( '<p>Some content</p>' );
194 - $( '#qunit-fixture' ).append( $testElement );
 197+ var $qunitFixture = $( '#qunit-fixture' );
 198+ var $latinTest = $( '<p>Some content</p>' );
 199+ var $invalidTest = $( '<p>Some content</p>' );
 200+ var $malayalamTest = $( '<p>Some content</p>' );
195201
196202 var latinWebFont = 'RufScript';
197203 var fallbackFonts = 'Helvetica, Arial, sans-serif';
198 - $testElement.attr( 'style', 'font-family: ' + latinWebFont + ', ' + fallbackFonts );
 204+ var invalidFont = 'NonExistingFont';
 205+ var malayalamFont = mw.webfonts.config.languages.ml[0];
 206+
 207+ $latinTest.css( 'font-family', latinWebFont + ', ' + fallbackFonts );
 208+ $invalidTest.css( 'font-family', invalidFont + ', ' + fallbackFonts );
 209+ $malayalamTest.css( 'font-family', invalidFont + ', ' + malayalamFont + ', ' + fallbackFonts );
 210+ $qunitFixture.append( $latinTest, $invalidTest, $malayalamTest );
 211+
 212+ // Trigger a re-render for Chrome,
 213+ // which otherwise will not synchronize css property into a string for style="" attribute
 214+ // We don't actually use innerHTML anywhere, just triggering it will fix Chrome.
 215+ $qunitFixture.prop('innerHTML');
 216+
199217 assertTrue( $.inArray( latinWebFont, mw.webfonts.fonts ) === -1, 'Latin font not loaded yet' );
200 - ok( mw.webfonts.loadFontsForFontFamilyStyle(), 'Loaded fonts from font-family' );
201 - assertTrue( $.inArray( latinWebFont, mw.webfonts.fonts ) >= 0, 'Latin font loaded' );
202 - assertTrue( isFontFaceLoaded( latinWebFont ), 'New css rule added to the document for Latin' );
 218+ assertTrue( $.inArray( malayalamFont, mw.webfonts.fonts ) === -1, 'Fallback font not loaded yet' );
203219
204 - var invalidFont = 'NonExistingFont';
205 - $testElement.attr( 'style', 'font-family: ' + invalidFont + ', ' + fallbackFonts );
206 - ok( mw.webfonts.loadFontsForFontFamilyStyle(), 'Attempted to load non-existing fonts specified in font-family' );
207 - assertTrue( $.inArray( invalidFont, mw.webfonts.fonts ) === -1, 'Font not loaded since it is not existing, including fallback fonts' );
208 - assertFalse( isFontFaceLoaded( invalidFont ), 'No new css rule added to the document since the font does not exist' );
 220+ mw.webfonts.loadFontsForFontFamilyStyle();
209221
210 - var malayalamFont = mw.webfonts.config.languages.ml[0];
211 - $testElement.attr( 'style', 'font-family: ' + invalidFont + ', ' + malayalamFont + ', ' + fallbackFonts );
212 - assertTrue( $.inArray( malayalamFont, mw.webfonts.fonts ) === -1, 'Fallback font not loaded yet' );
213 - ok( mw.webfonts.loadFontsForFontFamilyStyle(), 'Loading fonts from font-family' );
214 - assertTrue( $.inArray( malayalamFont, mw.webfonts.fonts ) >= 0, 'A fallback font was loaded' );
215 - assertTrue( isFontFaceLoaded( malayalamFont ), 'New css rule added to the document for fallback font' );
 222+ assertTrue( $.inArray( latinWebFont, mw.webfonts.fonts ) !== -1, 'Latin font loaded' );
 223+ assertTrue( isFontFaceLoaded( latinWebFont ), 'Latin font css rule added to the document' );
 224+
 225+ assertTrue( $.inArray( invalidFont, mw.webfonts.fonts ) === -1, 'NonExistingFont not loaded since it is not existing, including fallback fonts' );
 226+ assertFalse( isFontFaceLoaded( invalidFont ), 'NonExistingFont css rule not added to the document' );
 227+
 228+ assertTrue( $.inArray( malayalamFont, mw.webfonts.fonts ) !== -1, 'Fallback font loaded' );
 229+ assertTrue( isFontFaceLoaded( malayalamFont ), 'Fallback font css rule added to the document' );
 230+
 231+ // Restore
 232+ mw.webfonts.fonts = oldFonts;
216233 } );
217234
218235 test( '-- Build the menu', function() {
Index: trunk/extensions/WebFonts/resources/ext.webfonts.js
@@ -39,8 +39,10 @@
4040 }
4141
4242 // Set the web font and the fallback fonts.
43 - // font-family of <input>, <select> and <textarea> must be changed explicitly.
44 - $( 'body, input, select, textarea' ).css(
 43+ // font-family of <input> and <textarea> must be changed explicitly.
 44+ // @fixme TODO: Figure out a way to set font styling on <select> elements.
 45+ // (if done, also add to reset() and to unit test).
 46+ $( 'body, input, textarea' ).css(
4547 'font-family', '"' + font + '", Helvetica, Arial, sans-serif'
4648 );
4749
@@ -62,7 +64,7 @@
6365 * Reset the font with old configuration
6466 */
6567 reset: function() {
66 - $( 'body, input, select, textarea' ).css( {
 68+ $( 'body, input, textarea' ).css( {
6769 fontFamily: mw.webfonts.oldconfig.fontFamily,
6870 fontSize: mw.webfonts.oldconfig.fontSize
6971 });
@@ -250,13 +252,13 @@
251253 * Scan the page for tags with lang attr and load the default font
252254 * for that language if available.
253255 */
254 - loadFontsForLangAttr: function() {
 256+ loadFontsForLangAttr: function () {
255257 var languages = mw.webfonts.config.languages;
256258 var requested = [mw.config.get( 'wgUserVariant' ), mw.config.get( 'wgContentLanguage' ),
257259 mw.config.get( 'wgUserLanguage' ), mw.config.get( 'wgPageContentLanguage' )];
258260 var fontFamily = false;
259261 // Find elements with the lang attribute.
260 - $( 'body' ).find( '*[lang]' ).each( function( i, el ) {
 262+ $( 'body' ).find( '*[lang]' ).each( function ( i, el ) {
261263 // If the lang attribute value is same as one of
262264 // contentLang,useLang, variant, no need to do this.
263265 if( $.inArray( el.lang , requested ) === -1 ) {
@@ -275,12 +277,12 @@
276278 * Scan the page for tags with font-family style declarations
277279 * If that font is available, embed it.
278280 */
279 - loadFontsForFontFamilyStyle: function() {
 281+ loadFontsForFontFamilyStyle: function () {
280282 // If there are tags with font-family style definition, get a list of fonts to be loaded
281 - $( 'body' ).find( '*[style]' ).each( function( i, el ) {
282 - if( el.style.fontFamily ) {
 283+ $( 'body' ).find( '[style]' ).each( function ( i, el ) {
 284+ if ( el.style.fontFamily ) {
283285 var fontFamilyItems = el.style.fontFamily.split( ',' );
284 - $.each( fontFamilyItems, function( i, fontFamily ) {
 286+ $.each( fontFamilyItems, function ( i, fontFamily ) {
285287 // Remove the ' characters if any.
286288 fontFamily = $.trim( fontFamily.replace( /'/g, '' ) );
287289 mw.webfonts.addFont( fontFamily );

Sign-offs

UserFlagDate
Nikerabbitinspected15:31, 13 February 2012

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r109144Modify directly the style attr, .css didn't work - more tests passing now...nikerabbit13:51, 17 January 2012
r109230Started writing tests for applying web fonts to body (set( font )). Changed l...amire8022:09, 17 January 2012

Status & tagging log