@@ -138,47 +138,57 @@ index 040c7b124dec6bb254563bbe74fe50012cb077a3..b4e6b8132786af70e8ad0dce88b67c28
138
138
const transportProvider = {
139
139
setListener(upgradeListener) {
140
140
diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp
141
- index 514a4f2890a20558afe0d9c1aec697612fc8e873..44b48f306cb6c67264edbb2eaa49c890b657c675 100644
141
+ index 514a4f2890a20558afe0d9c1aec697612fc8e873..4be480a4ec0e397c6c9a1d695a1faf381af414d1 100644
142
142
--- a/docshell/base/nsDocShell.cpp
143
143
+++ b/docshell/base/nsDocShell.cpp
144
- @@ -15,6 +15,12 @@
144
+ @@ -15,6 +15,14 @@
145
145
# include <unistd.h> // for getpid()
146
146
#endif
147
147
148
148
+ #if JS_HAS_INTL_API && !MOZ_SYSTEM_ICU
149
149
+ # include "unicode/locid.h"
150
+ + # include "unicode/timezone.h"
151
+ + # include "unicode/unistr.h"
150
152
+ #endif /* JS_HAS_INTL_API && !MOZ_SYSTEM_ICU */
151
153
+
152
154
+ #include "js/LocaleSensitive.h"
153
155
+
154
156
#include "mozilla/ArrayUtils.h"
155
157
#include "mozilla/Attributes.h"
156
158
#include "mozilla/AutoRestore.h"
157
- @@ -53,6 +59 ,7 @@
159
+ @@ -53,6 +61 ,7 @@
158
160
#include "mozilla/dom/ContentFrameMessageManager.h"
159
161
#include "mozilla/dom/DocGroup.h"
160
162
#include "mozilla/dom/Element.h"
161
163
+ #include "mozilla/dom/Geolocation.h"
162
164
#include "mozilla/dom/HTMLAnchorElement.h"
163
165
#include "mozilla/dom/PerformanceNavigation.h"
164
166
#include "mozilla/dom/PermissionMessageUtils.h"
165
- @@ -71,6 +78 ,7 @@
167
+ @@ -71,6 +80 ,7 @@
166
168
#include "mozilla/dom/nsCSPContext.h"
167
169
#include "mozilla/dom/LoadURIOptionsBinding.h"
168
170
#include "mozilla/dom/JSWindowActorChild.h"
169
171
+ #include "mozilla/dom/WorkerCommon.h"
170
172
171
173
#include "mozilla/net/DocumentChannel.h"
172
174
#include "mozilla/net/DocumentChannelChild.h"
173
- @@ -96,6 +104 ,7 @@
175
+ @@ -96,6 +106 ,7 @@
174
176
#include "nsIDocShellTreeItem.h"
175
177
#include "nsIDocShellTreeOwner.h"
176
178
#include "mozilla/dom/Document.h"
177
179
+ #include "mozilla/dom/Element.h"
178
180
#include "nsIDocumentLoaderFactory.h"
179
181
#include "nsIDOMWindow.h"
180
182
#include "nsIEditingSession.h"
181
- @@ -350,6 +359,9 @@ nsDocShell::nsDocShell(BrowsingContext* aBrowsingContext,
183
+ @@ -183,6 +194,7 @@
184
+ #include "nsGlobalWindow.h"
185
+ #include "nsISearchService.h"
186
+ #include "nsJSEnvironment.h"
187
+ + #include "nsJSUtils.h"
188
+ #include "nsNetCID.h"
189
+ #include "nsNetUtil.h"
190
+ #include "nsObjectLoadingContent.h"
191
+ @@ -350,6 +362,9 @@ nsDocShell::nsDocShell(BrowsingContext* aBrowsingContext,
182
192
mUseErrorPages(false),
183
193
mObserveErrorPages(true),
184
194
mCSSErrorReportingEnabled(false),
@@ -188,15 +198,15 @@ index 514a4f2890a20558afe0d9c1aec697612fc8e873..44b48f306cb6c67264edbb2eaa49c890
188
198
mAllowAuth(mItemType == typeContent),
189
199
mAllowKeywordFixup(false),
190
200
mIsOffScreenBrowser(false),
191
- @@ -1219,6 +1231 ,7 @@ bool nsDocShell::SetCurrentURI(nsIURI* aURI, nsIRequest* aRequest,
201
+ @@ -1219,6 +1234 ,7 @@ bool nsDocShell::SetCurrentURI(nsIURI* aURI, nsIRequest* aRequest,
192
202
isSubFrame = mLSHE->GetIsSubFrame();
193
203
}
194
204
195
205
+ FireOnFrameLocationChange(this, aRequest, aURI, aLocationFlags);
196
206
if (!isSubFrame && !isRoot) {
197
207
/*
198
208
* We don't want to send OnLocationChange notifications when
199
- @@ -3340,6 +3353,131 @@ nsDocShell::GetMessageManager(ContentFrameMessageManager** aMessageManager) {
209
+ @@ -3340,6 +3356,162 @@ nsDocShell::GetMessageManager(ContentFrameMessageManager** aMessageManager) {
200
210
return NS_OK;
201
211
}
202
212
@@ -262,6 +272,37 @@ index 514a4f2890a20558afe0d9c1aec697612fc8e873..44b48f306cb6c67264edbb2eaa49c890
262
272
+ }
263
273
+
264
274
+ NS_IMETHODIMP
275
+ + nsDocShell::OverrideTimezone(const nsAString& aTimezoneOverride, bool* aSuccess) {
276
+ + NS_ENSURE_ARG(aSuccess);
277
+ +
278
+ + // Validate timezone id.
279
+ + UniquePtr<icu::TimeZone> timezone(icu::TimeZone::createTimeZone(
280
+ + icu::UnicodeString(NS_LossyConvertUTF16toASCII(aTimezoneOverride).get(), -1, US_INV)));
281
+ + if (!timezone || *timezone == icu::TimeZone::getUnknown()) {
282
+ + fprintf(stderr, "Invalid timezone id: %s\n", NS_LossyConvertUTF16toASCII(aTimezoneOverride).get());
283
+ + *aSuccess = false;
284
+ + return NS_OK;
285
+ + }
286
+ +
287
+ + // The env variable is read by js::DateTimeInfo::internalResyncICUDefaultTimeZone()
288
+ + auto setTimeZoneEnv = [](const char* value) {
289
+ + #if defined(_WIN32)
290
+ + return _putenv_s("TZ", value) == 0;
291
+ + #else
292
+ + return setenv("TZ", value, true) == 0;
293
+ + #endif /* _WIN32 */
294
+ + };
295
+ +
296
+ + *aSuccess = setTimeZoneEnv(NS_LossyConvertUTF16toASCII(aTimezoneOverride).get());
297
+ + if (*aSuccess) {
298
+ + nsJSUtils::ResetTimeZone();
299
+ + } else {
300
+ + fprintf(stderr, "Failed to change timezone to '%s'\n", NS_LossyConvertUTF16toASCII(aTimezoneOverride).get());
301
+ + }
302
+ + return NS_OK;
303
+ + }
304
+ +
305
+ + NS_IMETHODIMP
265
306
+ nsDocShell::GetFileInputInterceptionEnabled(bool* aEnabled) {
266
307
+ MOZ_ASSERT(aEnabled);
267
308
+ *aEnabled = GetRootDocShell()->mFileInputInterceptionEnabled;
@@ -328,7 +369,7 @@ index 514a4f2890a20558afe0d9c1aec697612fc8e873..44b48f306cb6c67264edbb2eaa49c890
328
369
NS_IMETHODIMP
329
370
nsDocShell::GetIsNavigating(bool* aOut) {
330
371
*aOut = mIsNavigating;
331
- @@ -12137,6 +12275 ,9 @@ class OnLinkClickEvent : public Runnable {
372
+ @@ -12137,6 +12309 ,9 @@ class OnLinkClickEvent : public Runnable {
332
373
mNoOpenerImplied, nullptr, nullptr,
333
374
mIsUserTriggered, mTriggeringPrincipal, mCsp);
334
375
}
@@ -338,7 +379,7 @@ index 514a4f2890a20558afe0d9c1aec697612fc8e873..44b48f306cb6c67264edbb2eaa49c890
338
379
return NS_OK;
339
380
}
340
381
341
- @@ -12226,6 +12367 ,9 @@ nsresult nsDocShell::OnLinkClick(
382
+ @@ -12226,6 +12401 ,9 @@ nsresult nsDocShell::OnLinkClick(
342
383
this, aContent, aURI, target, aFileName, aPostDataStream,
343
384
aHeadersDataStream, noOpenerImplied, aIsUserTriggered, aIsTrusted,
344
385
aTriggeringPrincipal, aCsp);
@@ -405,7 +446,7 @@ index cc88045201371eb2195a28c60fcd3b6d940e8b72..7fad3529cc7a22b0b2aa8d8cb5ebbb58
405
446
bool mAllowKeywordFixup : 1;
406
447
bool mIsOffScreenBrowser : 1;
407
448
diff --git a/docshell/base/nsIDocShell.idl b/docshell/base/nsIDocShell.idl
408
- index ee89208c3ada6da09ecda6147e1a372ee0562810..83a70dd59a22abd391f9b2db99837e3e5851db31 100644
449
+ index ee89208c3ada6da09ecda6147e1a372ee0562810..ce8d31365b5190ac2c974100a6ec6408c53681d5 100644
409
450
--- a/docshell/base/nsIDocShell.idl
410
451
+++ b/docshell/base/nsIDocShell.idl
411
452
@@ -44,6 +44,7 @@ interface nsIURI;
@@ -416,7 +457,7 @@ index ee89208c3ada6da09ecda6147e1a372ee0562810..83a70dd59a22abd391f9b2db99837e3e
416
457
interface nsIDocShellLoadInfo;
417
458
interface nsIEditor;
418
459
interface nsIEditingSession;
419
- @@ -1129,4 +1130,19 @@ interface nsIDocShell : nsIDocShellTreeItem
460
+ @@ -1129,4 +1130,21 @@ interface nsIDocShell : nsIDocShellTreeItem
420
461
* @see nsISHEntry synchronizeLayoutHistoryState().
421
462
*/
422
463
void synchronizeLayoutHistoryState();
@@ -427,6 +468,8 @@ index ee89208c3ada6da09ecda6147e1a372ee0562810..83a70dd59a22abd391f9b2db99837e3e
427
468
+
428
469
+ attribute AString languageOverride;
429
470
+
471
+ + boolean overrideTimezone(in AString timezoneId);
472
+ +
430
473
+ cenum OnlineOverride: 8 {
431
474
+ ONLINE_OVERRIDE_NONE = 0,
432
475
+ ONLINE_OVERRIDE_ONLINE = 1,
@@ -1953,10 +1996,10 @@ index 0000000000000000000000000000000000000000..ba34976ad05e7f5f1a99777f76ac08b1
1953
1996
+ this.SimpleChannel = SimpleChannel;
1954
1997
diff --git a/juggler/TargetRegistry.js b/juggler/TargetRegistry.js
1955
1998
new file mode 100644
1956
- index 0000000000000000000000000000000000000000..98d00f70a61787e31c5ae58310fd86312f3d0dcf
1999
+ index 0000000000000000000000000000000000000000..dcf03385589acc29c7fe0f02f912d40ab7efb76f
1957
2000
--- /dev/null
1958
2001
+++ b/juggler/TargetRegistry.js
1959
- @@ -0,0 +1,471 @@
2002
+ @@ -0,0 +1,479 @@
1960
2003
+ const {EventEmitter} = ChromeUtils.import('resource://gre/modules/EventEmitter.jsm');
1961
2004
+ const {Helper} = ChromeUtils.import('chrome://juggler/content/Helper.js');
1962
2005
+ const {SimpleChannel} = ChromeUtils.import('chrome://juggler/content/SimpleChannel.js');
@@ -2048,6 +2091,10 @@ index 0000000000000000000000000000000000000000..98d00f70a61787e31c5ae58310fd8631
2048
2091
+ this._mainWindow.gBrowser.selectedTab = tab;
2049
2092
+ const target = this._tabToTarget.get(tab);
2050
2093
+ await target._contentReadyPromise;
2094
+ + if (browserContext.options.timezoneId) {
2095
+ + if (await target.hasFailedToOverrideTimezone())
2096
+ + throw new Error('Failed to override timezone');
2097
+ + }
2051
2098
+ return target.id();
2052
2099
+ }
2053
2100
+
@@ -2249,6 +2296,10 @@ index 0000000000000000000000000000000000000000..98d00f70a61787e31c5ae58310fd8631
2249
2296
+ await this._channel.connect('').send('setOnlineOverride', override).catch(e => void e);
2250
2297
+ }
2251
2298
+
2299
+ + async hasFailedToOverrideTimezone() {
2300
+ + return await this._channel.connect('').send('hasFailedToOverrideTimezone').catch(e => true);
2301
+ + }
2302
+ +
2252
2303
+ dispose() {
2253
2304
+ this._disposed = true;
2254
2305
+ if (this._browserContext)
@@ -4840,10 +4891,10 @@ index 0000000000000000000000000000000000000000..3a386425d3796d0a6786dea193b3402d
4840
4891
+
4841
4892
diff --git a/juggler/content/main.js b/juggler/content/main.js
4842
4893
new file mode 100644
4843
- index 0000000000000000000000000000000000000000..b1f66264a97a0ca24fe29fb8a04e3ea2f5ec9eeb
4894
+ index 0000000000000000000000000000000000000000..1864328a47107621309c9b3726bb84535b780c2f
4844
4895
--- /dev/null
4845
4896
+++ b/juggler/content/main.js
4846
- @@ -0,0 +1,146 @@
4897
+ @@ -0,0 +1,153 @@
4847
4898
+ const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
4848
4899
+ const {Helper} = ChromeUtils.import('chrome://juggler/content/Helper.js');
4849
4900
+ const {FrameTree} = ChromeUtils.import('chrome://juggler/content/content/FrameTree.js');
@@ -4908,8 +4959,11 @@ index 0000000000000000000000000000000000000000..b1f66264a97a0ca24fe29fb8a04e3ea2
4908
4959
+ response = { sessionIds: [], browserContextOptions: {}, waitForInitialNavigation: false };
4909
4960
+
4910
4961
+ const { sessionIds, browserContextOptions, waitForInitialNavigation } = response;
4911
- + const { userAgent, bypassCSP, javaScriptDisabled, viewport, scriptsToEvaluateOnNewDocument, bindings, locale, geolocation, onlineOverride } = browserContextOptions;
4962
+ + const { userAgent, bypassCSP, javaScriptDisabled, viewport, scriptsToEvaluateOnNewDocument, bindings, locale, timezoneId, geolocation, onlineOverride } = browserContextOptions;
4912
4963
+
4964
+ + let failedToOverrideTimezone = false;
4965
+ + if (timezoneId)
4966
+ + failedToOverrideTimezone = !docShell.overrideTimezone(timezoneId);
4913
4967
+ if (userAgent !== undefined)
4914
4968
+ docShell.browsingContext.customUserAgent = userAgent;
4915
4969
+ if (bypassCSP !== undefined)
@@ -4970,6 +5024,10 @@ index 0000000000000000000000000000000000000000..b1f66264a97a0ca24fe29fb8a04e3ea2
4970
5024
+ // noop, just a rountrip.
4971
5025
+ },
4972
5026
+
5027
+ + hasFailedToOverrideTimezone() {
5028
+ + return failedToOverrideTimezone;
5029
+ + },
5030
+ +
4973
5031
+ dispose() {
4974
5032
+ },
4975
5033
+ });
@@ -6075,10 +6133,10 @@ index 0000000000000000000000000000000000000000..78b6601b91d0b7fcda61114e6846aa07
6075
6133
+ this.EXPORTED_SYMBOLS = ['t', 'checkScheme'];
6076
6134
diff --git a/juggler/protocol/Protocol.js b/juggler/protocol/Protocol.js
6077
6135
new file mode 100644
6078
- index 0000000000000000000000000000000000000000..67df4d5592d66e0db3c7c120ad12f9b360b9c45d
6136
+ index 0000000000000000000000000000000000000000..4028ed2f4c87e869da15103e936f85e887d769a1
6079
6137
--- /dev/null
6080
6138
+++ b/juggler/protocol/Protocol.js
6081
- @@ -0,0 +1,778 @@
6139
+ @@ -0,0 +1,779 @@
6082
6140
+ const {t, checkScheme} = ChromeUtils.import('chrome://juggler/content/protocol/PrimitiveTypes.js');
6083
6141
+
6084
6142
+ // Protocol-specific types.
@@ -6294,6 +6352,7 @@ index 0000000000000000000000000000000000000000..67df4d5592d66e0db3c7c120ad12f9b3
6294
6352
+ javaScriptDisabled: t.Optional(t.Boolean),
6295
6353
+ viewport: t.Optional(pageTypes.Viewport),
6296
6354
+ locale: t.Optional(t.String),
6355
+ + timezoneId: t.Optional(t.String),
6297
6356
+ },
6298
6357
+ returns: {
6299
6358
+ browserContextId: t.String,
0 commit comments