test_navigator_language.html (7102B)
1 <!DOCTYPE HTML> 2 <html> 3 <!-- 4 https://bugzilla.mozilla.org/show_bug.cgi?id=889335 5 --> 6 <head> 7 <meta charset="utf-8"> 8 <title>Test for NavigatorLanguage</title> 9 <script src="/tests/SimpleTest/SimpleTest.js"></script> 10 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> 11 </head> 12 <body> 13 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=889335">Mozilla Bug 889335</a> 14 <p id="display"></p> 15 <div id="content" style="display: none"> 16 </div> 17 <pre id="test"> 18 </pre> 19 <script type="application/javascript"> 20 "use strict"; 21 22 SimpleTest.waitForExplicitFinish(); 23 24 /** Test for NavigatorLanguage */ 25 var actualLanguageChangesFromHandler = 0; 26 var actualLanguageChangesFromAVL = 0; 27 var expectedLanguageChanges = 0; 28 var emptyLocale = SpecialPowers.Services.locale.webExposedLocales[0]; 29 30 var testValues = [ 31 { accept_languages: 'foo', language: 'foo', languages: ['foo'] }, 32 { accept_languages: '', language: emptyLocale, languages: [emptyLocale] }, 33 { accept_languages: 'foo,bar', language: 'foo', languages: [ 'foo', 'bar' ] }, 34 { accept_languages: ' foo , bar ', language: 'foo', languages: [ 'foo', 'bar' ] }, 35 { accept_languages: ' foo ; bar ', language: 'foo ; bar', languages: [ 'foo ; bar' ] }, 36 { accept_languages: '_foo_', language: '_foo_', languages: ['_foo_'] }, 37 { accept_languages: 'en_', language: 'en-', languages: ['en-'] }, 38 { accept_languages: 'en__', language: 'en-_', languages: ['en-_'] }, 39 { accept_languages: 'en_US, fr_FR', language: 'en-US', languages: ['en-US', 'fr-FR'] }, 40 { accept_languages: 'en_US_CA', language: 'en-US_CA', languages: ['en-US_CA'] }, 41 { accept_languages: 'en_us-ca', language: 'en-US-CA', languages: ['en-US-CA'] }, 42 { accept_languages: 'en_us-cal, en_us-c', language: 'en-US-cal', languages: ['en-US-cal', 'en-US-c'] }, 43 ]; 44 45 var currentTestIdx = 0; 46 var tests = []; 47 function nextTest() { 48 currentTestIdx++; 49 if (currentTestIdx >= tests.length) { 50 SimpleTest.finish(); 51 return; 52 } 53 54 tests[currentTestIdx](); 55 } 56 57 // Check that the API is there. 58 tests.push(function testAPIPresence() { 59 ok('language' in window.navigator); 60 ok('languages' in window.navigator); 61 ok('onlanguagechange' in window); 62 63 nextTest(); 64 }); 65 66 // Check that calling navigator.languages return the same array, unless there 67 // was a change. 68 tests.push(function testArrayCached() { 69 var previous = navigator.languages; 70 is(navigator.languages, navigator.languages, "navigator.languages is cached"); 71 is(navigator.languages, previous, "navigator.languages is cached"); 72 73 window.onlanguagechange = function() { 74 isnot(navigator.languages, previous, "navigator.languages cached value was updated"); 75 window.onlanguagechange = null; 76 77 nextTest(); 78 } 79 80 setTimeout(function() { 81 SpecialPowers.pushPrefEnv({"set": [['intl.accept_languages', 'testArrayCached']]}); 82 }, 0); 83 }); 84 85 // Test that event handler inside the <body> works as expected and that the 86 // event has the expected properties. 87 tests.push(function testEventProperties() { 88 document.body.setAttribute('onlanguagechange', 89 "document.body.removeAttribute('onlanguagechange');" + 90 "is(event.cancelable, false); is(event.bubbles, false);" + 91 "nextTest();"); 92 93 setTimeout(function() { 94 SpecialPowers.pushPrefEnv({"set": [['intl.accept_languages', 'testEventProperties']]}, function() {}); 95 }, 0); 96 }); 97 98 // Check that the returned values such as the behavior when the underlying 99 // languages change. 100 tests.push(function testBasicBehaviour() { 101 function checkIfDoneAndProceed() { 102 if (actualLanguageChangesFromHandler == actualLanguageChangesFromAVL) { 103 if (genEvents.next().done) { 104 window.onlanguagechange = null; 105 window.removeEventListener('languagechange', languageChangeAVL); 106 nextTest(); 107 } 108 } 109 } 110 window.onlanguagechange = function() { 111 actualLanguageChangesFromHandler++; 112 checkIfDoneAndProceed(); 113 } 114 function languageChangeAVL() { 115 actualLanguageChangesFromAVL++; 116 checkIfDoneAndProceed(); 117 } 118 window.addEventListener('languagechange', languageChangeAVL); 119 120 function* testEvents() { 121 for (var i = 0; i < testValues.length; ++i) { 122 var data = testValues[i]; 123 setTimeout(function(d) { 124 SpecialPowers.pushPrefEnv({"set": [['intl.accept_languages', d.accept_languages]]}); 125 }, 0, data); 126 expectedLanguageChanges++; 127 yield undefined; 128 129 is(actualLanguageChangesFromAVL, expectedLanguageChanges); 130 is(actualLanguageChangesFromHandler, expectedLanguageChanges); 131 132 is(navigator.language, data.language); 133 is(navigator.languages.length, data.languages.length); 134 if (navigator.languages.length) { 135 is(navigator.languages[0], navigator.language) 136 } 137 for (var j = 0; j < navigator.languages.length; ++j) { 138 is(navigator.languages[j], data.languages[j]); 139 } 140 } 141 } 142 143 var genEvents = testEvents(); 144 genEvents.next(); 145 }); 146 147 // Check that the languagechange event isn't sent twice if the preference 148 // is set to the same value. 149 tests.push(function testOnlyFireIfRealChange() { 150 function* changeLanguage() { 151 setTimeout(function() { 152 SpecialPowers.pushPrefEnv({"set": [['intl.accept_languages', 'fr-CA']]}); 153 }); 154 yield undefined; 155 156 setTimeout(function() { 157 // Twice the same change, should fire only one event. 158 SpecialPowers.pushPrefEnv({"set": [['intl.accept_languages', 'fr-CA']]}); 159 setTimeout(function() { 160 // A real change to tell the test it should now count how many changes were 161 // received until now. 162 SpecialPowers.pushPrefEnv({"set": [['intl.accept_languages', 'fr-FR']]}); 163 }); 164 }); 165 yield undefined; 166 } 167 168 var genChanges = changeLanguage(); 169 170 var doubleEventCount = 0; 171 window.onlanguagechange = function() { 172 if (navigator.language == 'fr-FR') { 173 is(1, doubleEventCount); 174 window.onlanguagechange = null; 175 nextTest(); 176 return; 177 } 178 179 if (navigator.language == 'fr-CA') { 180 doubleEventCount++; 181 } 182 genChanges.next(); 183 } 184 185 genChanges.next(); 186 }); 187 188 // Check that there is no crash when a change happen after a window listening 189 // to them is killed. 190 tests.push(function testThatAddingAnEventDoesNotHaveSideEffects() { 191 var frame = document.createElement('iframe'); 192 frame.srcdoc = '<script>window.onlanguagechange=function(){}<\/script>'; 193 document.body.appendChild(frame); 194 195 frame.contentWindow.onload = function() { 196 document.body.removeChild(frame); 197 frame = null; 198 199 SpecialPowers.exactGC(function() { 200 // This should not crash. 201 SpecialPowers.pushPrefEnv({"set": [['intl.accept_languages', 'en-GB']]}, nextTest); 202 }); 203 } 204 }); 205 206 // There is one test using document.body. 207 addLoadEvent(function() { 208 tests[0](); 209 }); 210 211 </script> 212 </body> 213 </html>