Merge mozilla-inbound to mozilla-central. a=merge

This commit is contained in:
Andreea Pavel 2018-11-06 19:05:52 +02:00
Родитель 7d7be1afe1 2f80da43fe
Коммит d401f28d4e
67 изменённых файлов: 835 добавлений и 432 удалений

Двоичные данные
config/external/icu/data/icudt63l.dat поставляемый

Двоичный файл не отображается.

Просмотреть файл

@ -8,24 +8,23 @@
.notificationbox .notificationInner {
display: flex;
flex-direction: row;
}
.notificationbox .details {
flex-grow: 1;
display: flex;
flex-direction: row;
align-items: center;
}
.notificationbox .notification-button {
text-align: right;
.notificationInner .messageText {
flex: 1;
width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.notificationbox .messageText {
flex-grow: 1;
.notificationInner .messageImage,
.notificationbox .notificationButton,
.notificationbox .messageCloseButton {
flex: none;
}
.notificationbox .details:dir(rtl)
.notificationbox .notificationInner:dir(rtl) {
flex-direction: row-reverse;
}
@ -50,7 +49,6 @@
}
.notificationbox .messageImage {
display: inline-block;
background-size: 16px;
width: 16px;
height: 16px;

Просмотреть файл

@ -202,7 +202,7 @@ class NotificationBox extends Component {
return (
button({
key: props.label,
className: "notification-button",
className: "notificationButton",
accesskey: props.accesskey,
onClick: onClick},
props.label
@ -220,17 +220,20 @@ class NotificationBox extends Component {
className: "notification",
"data-key": notification.value,
"data-type": notification.type},
div({className: "notificationInner"},
div({className: "details"},
div({
className: "messageImage",
"data-type": notification.type}),
span({className: "messageText"},
notification.label
),
notification.buttons.map(props =>
this.renderButton(props, notification)
)
div(
{className: "notificationInner"},
div({
className: "messageImage",
"data-type": notification.type,
}),
span({
className: "messageText",
title: notification.label,
},
notification.label
),
notification.buttons.map(props =>
this.renderButton(props, notification)
),
div({
className: "messageCloseButton",

Просмотреть файл

@ -54,7 +54,7 @@ window.onload = async function () {
);
let buttonNodes = notificationNode.querySelectorAll(
".notification-button");
".notificationButton");
is(buttonNodes.length, 2, "There must be two buttons");

Просмотреть файл

@ -654,6 +654,14 @@ a.learn-more-link.webconsole-learn-more-link {
color: currentColor;
}
/* Special casing warning and error string colors so they are legible */
.theme-dark .message.error .objectBox-string,
.theme-light .message.error .objectBox-string,
.theme-dark .message.warn .objectBox-string,
.theme-light .message.warn .objectBox-string {
color: var(--error-color);
}
/* Special casing dark-theme error and warning ObjectInspector colors */
.theme-dark .webconsole-output-wrapper .message.error .tree.object-inspector .object-label,
.theme-dark .webconsole-output-wrapper .message.error .tree.object-inspector .object-label *,

Просмотреть файл

@ -141,6 +141,7 @@ add_task(async function() {
add_task(async function() {
info("Test UA widgets when showUserAgentShadowRoots is true");
await SpecialPowers.pushPrefEnv({"set": [
["dom.ua_widget.enabled", true],
["devtools.inspector.showUserAgentShadowRoots", true],
]});
@ -160,6 +161,7 @@ add_task(async function() {
add_task(async function() {
info("Test UA widgets when showUserAgentShadowRoots is false");
await SpecialPowers.pushPrefEnv({"set": [
["dom.ua_widget.enabled", true],
["devtools.inspector.showUserAgentShadowRoots", false],
]});

Просмотреть файл

@ -45,3 +45,6 @@ DEPRECATED_OPERATION(DOMAttrModifiedEvent)
DEPRECATED_OPERATION(MozBoxOrInlineBoxDisplay)
DEPRECATED_OPERATION(DOMQuadBoundsAttr)
DEPRECATED_OPERATION(CreateImageBitmapCanvasRenderingContext2D)
DEPRECATED_OPERATION(MozRequestFullScreenDeprecatedPrefix)
DEPRECATED_OPERATION(MozfullscreenchangeDeprecatedPrefix)
DEPRECATED_OPERATION(MozfullscreenerrorDeprecatedPrefix)

82
dom/fetch/EmptyBody.cpp Normal file
Просмотреть файл

@ -0,0 +1,82 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "EmptyBody.h"
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTING_ADDREF(EmptyBody)
NS_IMPL_CYCLE_COLLECTING_RELEASE(EmptyBody)
NS_IMPL_CYCLE_COLLECTION_CLASS(EmptyBody)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(EmptyBody)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mOwner)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mAbortSignalImpl)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFetchStreamReader)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(EmptyBody)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOwner)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAbortSignalImpl)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFetchStreamReader)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(EmptyBody)
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(EmptyBody)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
EmptyBody::EmptyBody(nsIGlobalObject* aGlobal,
mozilla::ipc::PrincipalInfo* aPrincipalInfo,
AbortSignalImpl* aAbortSignalImpl,
already_AddRefed<nsIInputStream> aBodyStream)
: FetchBody<EmptyBody>(aGlobal)
, mPrincipalInfo(aPrincipalInfo)
, mAbortSignalImpl(aAbortSignalImpl)
, mBodyStream(std::move(aBodyStream))
{}
EmptyBody::~EmptyBody() = default;
/* static */ already_AddRefed<EmptyBody>
EmptyBody::Create(nsIGlobalObject* aGlobal,
mozilla::ipc::PrincipalInfo* aPrincipalInfo,
AbortSignalImpl* aAbortSignalImpl,
const nsACString& aMimeType,
ErrorResult& aRv)
{
nsCOMPtr<nsIInputStream> bodyStream;
aRv = NS_NewCStringInputStream(getter_AddRefs(bodyStream), EmptyCString());
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
RefPtr<EmptyBody> emptyBody = new EmptyBody(aGlobal, aPrincipalInfo,
aAbortSignalImpl,
bodyStream.forget());
emptyBody->OverrideMimeType(aMimeType);
return emptyBody.forget();
}
void
EmptyBody::GetBody(nsIInputStream** aStream, int64_t* aBodyLength)
{
MOZ_ASSERT(aStream);
if (aBodyLength) {
*aBodyLength = 0;
}
nsCOMPtr<nsIInputStream> bodyStream = mBodyStream;
bodyStream.forget(aStream);
}
} // dom namespace
} // mozilla namespace

89
dom/fetch/EmptyBody.h Normal file
Просмотреть файл

@ -0,0 +1,89 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_EmptyBody_h
#define mozilla_dom_EmptyBody_h
#include "nsISupportsImpl.h"
#include "mozilla/dom/Fetch.h"
namespace mozilla {
namespace ipc {
class PrincipalInfo;
} // namespace ipc
namespace dom {
class EmptyBody final : public nsISupports
, public FetchBody<EmptyBody>
{
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(EmptyBody)
public:
static already_AddRefed<EmptyBody>
Create(nsIGlobalObject* aGlobal,
mozilla::ipc::PrincipalInfo* aPrincipalInfo,
AbortSignalImpl* aAbortSignalImpl,
const nsACString& aMimeType,
ErrorResult& aRv);
nsIGlobalObject*
GetParentObject() const
{
return mOwner;
}
AbortSignalImpl*
GetSignalImpl() const override
{
return mAbortSignalImpl;
}
const UniquePtr<mozilla::ipc::PrincipalInfo>&
GetPrincipalInfo() const
{
return mPrincipalInfo;
}
void
GetBody(nsIInputStream** aStream, int64_t* aBodyLength = nullptr);
using FetchBody::BodyBlobURISpec;
const nsACString&
BodyBlobURISpec() const
{
return EmptyCString();
}
using FetchBody::BodyLocalPath;
const nsAString&
BodyLocalPath() const
{
return EmptyString();
}
private:
EmptyBody(nsIGlobalObject* aGlobal,
mozilla::ipc::PrincipalInfo* aPrincipalInfo,
AbortSignalImpl* aAbortSignalImpl,
already_AddRefed<nsIInputStream> mBodyStream);
~EmptyBody();
UniquePtr<mozilla::ipc::PrincipalInfo> mPrincipalInfo;
RefPtr<AbortSignalImpl> mAbortSignalImpl;
nsCOMPtr<nsIInputStream> mBodyStream;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_EmptyBody_h

Просмотреть файл

@ -40,6 +40,7 @@
#include "mozilla/Telemetry.h"
#include "BodyExtractor.h"
#include "EmptyBody.h"
#include "FetchObserver.h"
#include "InternalRequest.h"
#include "InternalResponse.h"
@ -1242,6 +1243,29 @@ FetchBody<Derived>::ConsumeBody(JSContext* aCx, FetchConsumeType aType,
return nullptr;
}
// Null bodies are a special-case in the fetch spec. The Body mix-in can only
// be "disturbed" or "locked" if its associated "body" is non-null.
// Additionally, the Body min-in's "consume body" algorithm explicitly creates
// a fresh empty ReadableStream object in step 2. This means that `bodyUsed`
// will never return true for a null body.
//
// To this end, we create a fresh (empty) body every time a request is made
// and consume its body here, without marking this FetchBody consumed via
// SetBodyUsed.
nsCOMPtr<nsIInputStream> bodyStream;
DerivedClass()->GetBody(getter_AddRefs(bodyStream));
if (!bodyStream) {
RefPtr<EmptyBody> emptyBody =
EmptyBody::Create(DerivedClass()->GetParentObject(),
DerivedClass()->GetPrincipalInfo().get(),
signalImpl, mMimeType, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
return emptyBody->ConsumeBody(aCx, aType, aRv);
}
SetBodyUsed(aCx, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
@ -1251,7 +1275,7 @@ FetchBody<Derived>::ConsumeBody(JSContext* aCx, FetchConsumeType aType,
RefPtr<Promise> promise =
FetchBodyConsumer<Derived>::Create(global, mMainThreadEventTarget, this,
signalImpl, aType, aRv);
bodyStream, signalImpl, aType, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
@ -1269,6 +1293,11 @@ already_AddRefed<Promise>
FetchBody<Response>::ConsumeBody(JSContext* aCx, FetchConsumeType aType,
ErrorResult& aRv);
template
already_AddRefed<Promise>
FetchBody<EmptyBody>::ConsumeBody(JSContext* aCx, FetchConsumeType aType,
ErrorResult& aRv);
template <class Derived>
void
FetchBody<Derived>::SetMimeType()
@ -1297,6 +1326,13 @@ template
void
FetchBody<Response>::SetMimeType();
template <class Derived>
void
FetchBody<Derived>::OverrideMimeType(const nsACString& aMimeType)
{
mMimeType = aMimeType;
}
template <class Derived>
const nsACString&
FetchBody<Derived>::BodyBlobURISpec() const
@ -1312,6 +1348,10 @@ template
const nsACString&
FetchBody<Response>::BodyBlobURISpec() const;
template
const nsACString&
FetchBody<EmptyBody>::BodyBlobURISpec() const;
template <class Derived>
const nsAString&
FetchBody<Derived>::BodyLocalPath() const
@ -1327,6 +1367,10 @@ template
const nsAString&
FetchBody<Response>::BodyLocalPath() const;
template
const nsAString&
FetchBody<EmptyBody>::BodyLocalPath() const;
template <class Derived>
void
FetchBody<Derived>::SetReadableStreamBody(JSContext* aCx, JSObject* aBody)

Просмотреть файл

@ -267,6 +267,9 @@ public:
void
Abort() override;
already_AddRefed<Promise>
ConsumeBody(JSContext* aCx, FetchConsumeType aType, ErrorResult& aRv);
protected:
nsCOMPtr<nsIGlobalObject> mOwner;
@ -288,6 +291,9 @@ protected:
void
SetMimeType();
void
OverrideMimeType(const nsACString& aMimeType);
void
SetReadableStreamBody(JSContext* aCx, JSObject* aBody);
@ -298,9 +304,6 @@ private:
return static_cast<Derived*>(const_cast<FetchBody*>(this));
}
already_AddRefed<Promise>
ConsumeBody(JSContext* aCx, FetchConsumeType aType, ErrorResult& aRv);
void
LockStream(JSContext* aCx, JS::HandleObject aStream, ErrorResult& aRv);

Просмотреть файл

@ -323,22 +323,15 @@ template <class Derived>
FetchBodyConsumer<Derived>::Create(nsIGlobalObject* aGlobal,
nsIEventTarget* aMainThreadEventTarget,
FetchBody<Derived>* aBody,
nsIInputStream* aBodyStream,
AbortSignalImpl* aSignalImpl,
FetchConsumeType aType,
ErrorResult& aRv)
{
MOZ_ASSERT(aBody);
MOZ_ASSERT(aBodyStream);
MOZ_ASSERT(aMainThreadEventTarget);
nsCOMPtr<nsIInputStream> bodyStream;
aBody->DerivedClass()->GetBody(getter_AddRefs(bodyStream));
if (!bodyStream) {
aRv = NS_NewCStringInputStream(getter_AddRefs(bodyStream), EmptyCString());
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
}
RefPtr<Promise> promise = Promise::Create(aGlobal, aRv);
if (aRv.Failed()) {
return nullptr;
@ -346,7 +339,7 @@ FetchBodyConsumer<Derived>::Create(nsIGlobalObject* aGlobal,
RefPtr<FetchBodyConsumer<Derived>> consumer =
new FetchBodyConsumer<Derived>(aMainThreadEventTarget, aGlobal,
aBody, bodyStream, promise,
aBody, aBodyStream, promise,
aType);
RefPtr<ThreadSafeWorkerRef> workerRef;

Просмотреть файл

@ -39,6 +39,7 @@ public:
Create(nsIGlobalObject* aGlobal,
nsIEventTarget* aMainThreadEventTarget,
FetchBody<Derived>* aBody,
nsIInputStream* aBodyStream,
AbortSignalImpl* aSignalImpl,
FetchConsumeType aType,
ErrorResult& aRv);

Просмотреть файл

@ -27,6 +27,7 @@ EXPORTS.mozilla.dom += [
UNIFIED_SOURCES += [
'BodyExtractor.cpp',
'ChannelInfo.cpp',
'EmptyBody.cpp',
'Fetch.cpp',
'FetchConsumer.cpp',
'FetchDriver.cpp',

Просмотреть файл

@ -355,3 +355,9 @@ DOMQuadBoundsAttrWarning=DOMQuad.bounds is deprecated in favor of DOMQuad.getBou
UnsupportedEntryTypesIgnored=Ignoring unsupported entryTypes: %S.
# LOCALIZATION NOTE (CreateImageBitmapCanvasRenderingContext2DWarning): Do not translate CanvasRenderingContext2D and createImageBitmap.
CreateImageBitmapCanvasRenderingContext2DWarning=Use of CanvasRenderingContext2D in createImageBitmap is deprecated.
# LOCALIZATION NOTE (MozRequestFullScreenDeprecatedPrefixWarning): Do not translate mozRequestFullScreen.
MozRequestFullScreenDeprecatedPrefixWarning=mozRequestFullScreen() is deprecated.
# LOCALIZATION NOTE (MozfullscreenchangeDeprecatedPrefixWarning): Do not translate onmozfullscreenchange.
MozfullscreenchangeDeprecatedPrefixWarning=onmozfullscreenchange is deprecated.
# LOCALIZATION NOTE (MozfullscreenerrorDeprecatedPrefixWarning): Do not translate onmozfullscreenerror.
MozfullscreenerrorDeprecatedPrefixWarning=onmozfullscreenerror is deprecated.

Просмотреть файл

@ -263,7 +263,7 @@ Element implements GeometryUtils;
partial interface Element {
[Throws, Func="nsDocument::IsUnprefixedFullscreenEnabled", NeedsCallerType]
Promise<void> requestFullscreen();
[Throws, BinaryName="requestFullscreen", NeedsCallerType]
[Throws, BinaryName="requestFullscreen", NeedsCallerType, Deprecated="MozRequestFullScreenDeprecatedPrefix"]
Promise<void> mozRequestFullScreen();
// Events handlers

Просмотреть файл

@ -118,7 +118,9 @@ interface GlobalEventHandlers {
// Mozilla-specific handlers. Unprefixed handlers live in
// Document rather than here.
[Deprecated="MozfullscreenchangeDeprecatedPrefix"]
attribute EventHandler onmozfullscreenchange;
[Deprecated="MozfullscreenerrorDeprecatedPrefix"]
attribute EventHandler onmozfullscreenerror;
// CSS-Animation and CSS-Transition handlers.

Просмотреть файл

@ -222,7 +222,7 @@ ChannelFromScriptURL(nsIPrincipal* principal,
nullptr, // aCallbacks
aLoadFlags,
ios);
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_SECURITY_ERR);
} else {
// We must have a loadGroup with a load context for the principal to
// traverse the channel correctly.
@ -262,7 +262,7 @@ ChannelFromScriptURL(nsIPrincipal* principal,
ios);
}
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_SECURITY_ERR);
if (cspEventListener) {
nsCOMPtr<nsILoadInfo> loadInfo = channel->GetLoadInfo();

5
intl/tzdata/GIT-INFO Normal file
Просмотреть файл

@ -0,0 +1,5 @@
commit 6a8e28db3cbff837570f93881e6e4f7ff4d5fb25
Author: Yoshito Umaoka <yoshito_umaoka@us.ibm.com>
Date: Tue Oct 30 08:52:31 2018 -0400
ICU-20245: tzdata2018g updates. Also added tzdata2018f release files missed previously.

Просмотреть файл

@ -1,10 +0,0 @@
Path: 44
URL: https://ssl.icu-project.org/repos/icu/data/trunk/tzdata/icunew/2018e/44
Relative URL: ^/data/trunk/tzdata/icunew/2018e/44
Repository Root: https://ssl.icu-project.org/repos/icu
Repository UUID: 251d0590-4201-4cf1-90de-194747b24ca1
Node Kind: directory
Last Changed Author: yoshito
Last Changed Rev: 41324
Last Changed Date: 2018-05-04 22:02:44 +0000 (Fri, 04 May 2018)

1
intl/tzdata/VERSION Normal file
Просмотреть файл

@ -0,0 +1 @@
2018g

Двоичные данные
intl/tzdata/source/be/metaZones.res

Двоичный файл не отображается.

Двоичные данные
intl/tzdata/source/be/windowsZones.res

Двоичный файл не отображается.

Двоичные данные
intl/tzdata/source/be/zoneinfo64.res

Двоичный файл не отображается.

Двоичные данные
intl/tzdata/source/ee/metaZones.res

Двоичный файл не отображается.

Двоичные данные
intl/tzdata/source/ee/windowsZones.res

Двоичный файл не отображается.

Двоичные данные
intl/tzdata/source/ee/zoneinfo64.res

Двоичный файл не отображается.

Двоичные данные
intl/tzdata/source/le/metaZones.res

Двоичный файл не отображается.

Двоичные данные
intl/tzdata/source/le/windowsZones.res

Двоичный файл не отображается.

Двоичные данные
intl/tzdata/source/le/zoneinfo64.res

Двоичный файл не отображается.

Просмотреть файл

@ -813,6 +813,11 @@ metaZones:table(nofallback){
{
"Europe_Western",
"1985-12-31 23:00",
"2018-10-26 23:00",
}
{
"Europe_Central",
"2018-10-26 23:00",
"9999-12-31 23:59",
}
}
@ -862,6 +867,11 @@ metaZones:table(nofallback){
{
"Europe_Western",
"1976-04-14 01:00",
"2018-10-26 23:00",
}
{
"Europe_Central",
"2018-10-26 23:00",
"9999-12-31 23:59",
}
}
@ -2559,7 +2569,7 @@ metaZones:table(nofallback){
{
"Casey",
"2016-10-21 16:00",
"2016-03-10 17:00",
"2018-03-10 17:00",
}
{
"Australia_Western",
@ -3132,11 +3142,11 @@ metaZones:table(nofallback){
{
"Pyongyang",
"2015-08-14 15:00",
"2018-05-05 08:30",
"2018-05-04 15:00",
}
{
"Korea",
"2018-05-05 08:30",
"2018-05-04 15:00",
"9999-12-31 23:59",
}
}
@ -3992,6 +4002,11 @@ metaZones:table(nofallback){
{
"Moscow",
"1992-03-28 22:00",
"2018-10-27 23:00",
}
{
"Volgograd",
"2018-10-27 23:00",
"9999-12-31 23:59",
}
}

Просмотреть файл

@ -287,7 +287,7 @@ windowsZones:table(nofallback){
}
"GTB Standard Time"{
001{"Europe/Bucharest"}
CY{"Asia/Nicosia"}
CY{"Asia/Famagusta Asia/Nicosia"}
GR{"Europe/Athens"}
RO{"Europe/Bucharest"}
}
@ -580,6 +580,10 @@ windowsZones:table(nofallback){
001{"Pacific/Apia"}
WS{"Pacific/Apia"}
}
"Sao Tome Standard Time"{
001{"Africa/Sao_Tome"}
ST{"Africa/Sao_Tome"}
}
"Saratov Standard Time"{
001{"Europe/Saratov"}
RU{"Europe/Saratov"}
@ -654,7 +658,6 @@ windowsZones:table(nofallback){
}
"Turkey Standard Time"{
001{"Europe/Istanbul"}
CY{"Asia/Famagusta"}
TR{"Europe/Istanbul"}
}
"Turks And Caicos Standard Time"{
@ -746,7 +749,6 @@ windowsZones:table(nofallback){
GQ{"Africa/Malabo"}
NE{"Africa/Niamey"}
NG{"Africa/Lagos"}
ST{"Africa/Sao_Tome"}
TD{"Africa/Ndjamena"}
TN{"Africa/Tunis"}
ZZ{"Etc/GMT-1"}

Просмотреть файл

@ -3,17 +3,17 @@
// License & terms of use: http://www.unicode.org/copyright.html#License
//---------------------------------------------------------
// Build tool: tz2icu
// Build date: Fri May 4 16:06:17 2018
// Build date: Tue Oct 30 03:17:32 2018
// tz database: ftp://ftp.iana.org/tz/
// tz version: 2018e
// ICU version: 61.1
// tz version: 2018g
// ICU version: 63.1
//---------------------------------------------------------
// >> !!! >> THIS IS A MACHINE-GENERATED FILE << !!! <<
// >> !!! >>> DO NOT EDIT <<< !!! <<
//---------------------------------------------------------
zoneinfo64:table(nofallback) {
TZVersion { "2018e" }
TZVersion { "2018g" }
Zones:array {
/* ACT */ :int { 354 } //Z#0
/* AET */ :int { 366 } //Z#1
@ -59,13 +59,9 @@ zoneinfo64:table(nofallback) {
links:intvector { 3, 18, 400 }
} //Z#18
/* Africa/Casablanca */ :table {
trans:intvector { -1773012580, -956361600, -950490000, -942019200, -761187600, -617241600, -605149200, -81432000, -71110800, 141264000, 147222000, 199756800, 207702000, 231292800, 244249200, 265507200, 271033200, 448243200, 504918000, 1212278400, 1220223600, 1243814400, 1250809200, 1272758400, 1281222000, 1301788800, 1312066800, 1335664800, 1342749600, 1345428000, 1348970400, 1367114400, 1373162400, 1376100000, 1382839200, 1396144800, 1403920800, 1406944800, 1414288800, 1427594400, 1434247200, 1437271200, 1445738400, 1459044000, 1465092000, 1468116000, 1477792800, 1490493600, 1495332000, 1498960800, 1509242400, 1521943200, 1526176800, 1529200800, 1540692000, 1553997600, 1557021600, 1560045600, 1572141600, 1585447200, 1587261600, 1590285600, 1603591200, 1616896800, 1618106400, 1621130400, 1635645600, 1651975200, 1667095200, 1682215200, 1698544800, 1713060000, 1729994400, 1743904800, 1761444000, 1774749600, 1792893600, 1806199200, 1824948000, 1837648800, 1856397600, 1869098400, 1887847200, 1901152800, 1919296800, 1932602400, 1950746400, 1964052000, 1982800800, 1995501600, 2014250400, 2026951200, 2045700000, 2058400800, 2077149600, 2090455200, 2107994400, 2121904800, 2138234400 }
transPost32:intvector { 0, -2141612896, 0, -2122864096 }
trans:intvector { -1773012580, -956361600, -950490000, -942019200, -761187600, -617241600, -605149200, -81432000, -71110800, 141264000, 147222000, 199756800, 207702000, 231292800, 244249200, 265507200, 271033200, 448243200, 504918000, 1212278400, 1220223600, 1243814400, 1250809200, 1272758400, 1281222000, 1301788800, 1312066800, 1335664800, 1342749600, 1345428000, 1348970400, 1367114400, 1373162400, 1376100000, 1382839200, 1396144800, 1403920800, 1406944800, 1414288800, 1427594400, 1434247200, 1437271200, 1445738400, 1459044000, 1465092000, 1468116000, 1477792800, 1490493600, 1495332000, 1498960800, 1509242400, 1521943200, 1526176800, 1529200800, 1540594800 }
typeOffsets:intvector { -1820, 0, 0, 0, 0, 3600, 3600, 0 }
typeMap:bin { "0102010201020102010201020102010201030102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201" }
finalRule { "Morocco" }
finalRaw:int { 0 }
finalYear:int { 2039 }
typeMap:bin { "01020102010201020102010201020102010301020102010201020102010201020102010201020102010201020102010201020102010203" }
} //Z#19
/* Africa/Ceuta */ :table {
transPre32:intvector { -1, 2117514496 }
@ -82,13 +78,9 @@ zoneinfo64:table(nofallback) {
/* Africa/Djibouti */ :int { 48 } //Z#24
/* Africa/Douala */ :int { 36 } //Z#25
/* Africa/El_Aaiun */ :table {
trans:intvector { -1136070432, 198291600, 199756800, 207702000, 231292800, 244249200, 265507200, 271033200, 1212278400, 1220223600, 1243814400, 1250809200, 1272758400, 1281222000, 1301788800, 1312066800, 1335664800, 1342749600, 1345428000, 1348970400, 1367114400, 1373162400, 1376100000, 1382839200, 1396144800, 1403920800, 1406944800, 1414288800, 1427594400, 1434247200, 1437271200, 1445738400, 1459044000, 1465092000, 1468116000, 1477792800, 1490493600, 1495332000, 1498960800, 1509242400, 1521943200, 1526176800, 1529200800, 1540692000, 1553997600, 1557021600, 1560045600, 1572141600, 1585447200, 1587261600, 1590285600, 1603591200, 1616896800, 1618106400, 1621130400, 1635645600, 1651975200, 1667095200, 1682215200, 1698544800, 1713060000, 1729994400, 1743904800, 1761444000, 1774749600, 1792893600, 1806199200, 1824948000, 1837648800, 1856397600, 1869098400, 1887847200, 1901152800, 1919296800, 1932602400, 1950746400, 1964052000, 1982800800, 1995501600, 2014250400, 2026951200, 2045700000, 2058400800, 2077149600, 2090455200, 2107994400, 2121904800, 2138234400 }
transPost32:intvector { 0, -2141612896, 0, -2122864096 }
typeOffsets:intvector { -3168, 0, -3600, 0, 0, 0, 0, 3600 }
typeMap:bin { "010203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302030203020302" }
finalRule { "Morocco" }
finalRaw:int { 0 }
finalYear:int { 2039 }
trans:intvector { -1136070432, 198291600, 199756800, 207702000, 231292800, 244249200, 265507200, 271033200, 1212278400, 1220223600, 1243814400, 1250809200, 1272758400, 1281222000, 1301788800, 1312066800, 1335664800, 1342749600, 1345428000, 1348970400, 1367114400, 1373162400, 1376100000, 1382839200, 1396144800, 1403920800, 1406944800, 1414288800, 1427594400, 1434247200, 1437271200, 1445738400, 1459044000, 1465092000, 1468116000, 1477792800, 1490493600, 1495332000, 1498960800, 1509242400, 1521943200, 1526176800, 1529200800, 1540594800 }
typeOffsets:intvector { -3168, 0, -3600, 0, 0, 0, 0, 3600, 3600, 0 }
typeMap:bin { "0102030203020302030203020302030203020302030203020302030203020302030203020302030203020304" }
} //Z#26
/* Africa/Freetown */ :int { 5 } //Z#27
/* Africa/Gaborone */ :int { 43 } //Z#28
@ -1030,12 +1022,12 @@ zoneinfo64:table(nofallback) {
typeMap:bin { "010201020102010201020102010201020102010201020102010201020103" }
} //Z#199
/* America/Santiago */ :table {
trans:intvector { -1892661434, -1688410800, -1619205434, -1593806400, -1335986234, -1317585600, -1304362800, -1286049600, -1272826800, -1254513600, -1241290800, -1222977600, -1209754800, -1191355200, -1178132400, -870552000, -865278000, -740520000, -736376400, -718056000, -713649600, -36619200, -23922000, -3355200, 7527600, 24465600, 37767600, 55915200, 69217200, 87969600, 100666800, 118209600, 132116400, 150868800, 163566000, 182318400, 195620400, 213768000, 227070000, 245217600, 258519600, 277272000, 289969200, 308721600, 321418800, 340171200, 353473200, 371620800, 384922800, 403070400, 416372400, 434520000, 447822000, 466574400, 479271600, 498024000, 510721200, 529473600, 545194800, 560923200, 574225200, 592372800, 605674800, 624427200, 637124400, 653457600, 668574000, 687326400, 700628400, 718776000, 732078000, 750225600, 763527600, 781675200, 794977200, 813729600, 826426800, 845179200, 859690800, 876628800, 889930800, 906868800, 923194800, 939528000, 952830000, 971582400, 984279600, 1003032000, 1015729200, 1034481600, 1047178800, 1065931200, 1079233200, 1097380800, 1110682800, 1128830400, 1142132400, 1160884800, 1173582000, 1192334400, 1206846000, 1223784000, 1237086000, 1255233600, 1270350000, 1286683200, 1304823600, 1313899200, 1335668400, 1346558400, 1367118000, 1378612800, 1398567600, 1410062400, 1463281200, 1471147200 }
trans:intvector { -1892661434, -1688410800, -1619205434, -1593806400, -1335986234, -1317585600, -1304362800, -1286049600, -1272826800, -1254513600, -1241290800, -1222977600, -1209754800, -1191355200, -1178132400, -870552000, -865278000, -740520000, -736376400, -718056000, -713649600, -36619200, -23922000, -3355200, 7527600, 24465600, 37767600, 55915200, 69217200, 87969600, 100666800, 118209600, 132116400, 150868800, 163566000, 182318400, 195620400, 213768000, 227070000, 245217600, 258519600, 277272000, 289969200, 308721600, 321418800, 340171200, 353473200, 371620800, 384922800, 403070400, 416372400, 434520000, 447822000, 466574400, 479271600, 498024000, 510721200, 529473600, 545194800, 560923200, 574225200, 592372800, 605674800, 624427200, 637124400, 653457600, 668574000, 687326400, 700628400, 718776000, 732078000, 750225600, 763527600, 781675200, 794977200, 813729600, 826426800, 845179200, 859690800, 876628800, 889930800, 906868800, 923194800, 939528000, 952830000, 971582400, 984279600, 1003032000, 1015729200, 1034481600, 1047178800, 1065931200, 1079233200, 1097380800, 1110682800, 1128830400, 1142132400, 1160884800, 1173582000, 1192334400, 1206846000, 1223784000, 1237086000, 1255233600, 1270350000, 1286683200, 1304823600, 1313899200, 1335668400, 1346558400, 1367118000, 1378612800, 1398567600, 1410062400, 1463281200, 1471147200, 1494730800, 1502596800, 1526180400, 1534046400, 1554606000, 1567915200 }
typeOffsets:intvector { -16966, 0, -18000, 0, -18000, 3600, -14400, 0, -14400, 3600 }
typeMap:bin { "0100030002010201020102010201030103040301030403040304030403040304030403040304030403040304030403040304030403040304030403040304030403040304030403040304030403040304030403040304030403040304030403040304030403040304030403040304030403040304" }
typeMap:bin { "0100030002010201020102010201030103040301030403040304030403040304030403040304030403040304030403040304030403040304030403040304030403040304030403040304030403040304030403040304030403040304030403040304030403040304030403040304030403040304030403040304" }
finalRule { "Chile" }
finalRaw:int { -14400 }
finalYear:int { 2017 }
finalYear:int { 2020 }
links:intvector { 200, 392 }
} //Z#200
/* America/Santo_Domingo */ :table {
@ -1498,9 +1490,9 @@ zoneinfo64:table(nofallback) {
/* Asia/Kuwait */ :int { 308 } //Z#290
/* Asia/Macao */ :int { 292 } //Z#291
/* Asia/Macau */ :table {
trans:intvector { -1830412800, -277360200, -257405400, -245910600, -225955800, -214473600, -194506200, -182406600, -163056600, -150969600, -131619600, -117088200, -101367000, -85638600, -69312600, -53584200, -37863000, -22134600, -6413400, 9315000, 25036200, 40764600, 56485800, 72201600, 87922800, 103651200, 119977200, 135705600, 151439400, 167167800, 182889000, 198617400, 214338600, 230067000, 245788200, 261504000, 277225200, 292953600, 309279600, 325008000, 340729200 }
typeOffsets:intvector { 27260, 0, 28800, 0, 28800, 3600 }
typeMap:bin { "0102010201020102010201020102010201020102010201020102010201020102010201020102010201" }
trans:intvector { -2056692850, -884509200, -873280800, -855918000, -841744800, -828529200, -765363600, -747046800, -733827600, -716461200, -697021200, -683715600, -667990800, -654771600, -636627600, -623322000, -605178000, -591872400, -573642000, -559818000, -541674000, -528368400, -510224400, -498128400, -478774800, -466678800, -446720400, -435229200, -415258200, -403158600, -383808600, -371709000, -352359000, -340259400, -320909400, -308809800, -288855000, -277360200, -257405400, -245910600, -225955800, -213856200, -194506200, -182406600, -163056600, -148537800, -132820200, -117088200, -101370600, -85638600, -69312600, -53584200, -37863000, -22134600, -6413400, 9315000, 25036200, 40764600, 56485800, 72214200, 88540200, 104268600, 119989800, 126041400, 151439400, 167167800, 182889000, 198617400, 214338600, 295385400, 309292200 }
typeOffsets:intvector { 27250, 0, 28800, 0, 28800, 3600, 32400, 0, 32400, 3600 }
typeMap:bin { "0103040304030102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201020102010201" }
links:intvector { 291, 292 }
} //Z#292
/* Asia/Magadan */ :table {
@ -1557,7 +1549,7 @@ zoneinfo64:table(nofallback) {
typeMap:bin { "02040203020301" }
} //Z#303
/* Asia/Pyongyang */ :table {
trans:intvector { -1948782180, -1830414600, 1439564400, 1525447800 }
trans:intvector { -1948782180, -1830414600, 1439564400, 1525446000 }
typeOffsets:intvector { 30180, 0, 30600, 0, 32400, 0 }
typeMap:bin { "01020102" }
} //Z#304
@ -1598,9 +1590,9 @@ zoneinfo64:table(nofallback) {
} //Z#312
/* Asia/Shanghai */ :table {
transPre32:intvector { -1, 2117485353 }
trans:intvector { -933494400, -923130000, -908784000, -891594000, 515520000, 527007600, 545155200, 558457200, 576604800, 589906800, 608659200, 621961200, 640108800, 653410800, 671558400, 684860400 }
trans:intvector { -933667200, -922093200, -908870400, -888829200, -881049600, -767869200, -745833600, -733827600, -716889600, -699613200, -683884800, -670669200, -652348800, -650019600, 515527200, 527014800, 545162400, 558464400, 577216800, 589914000, 608666400, 621968400, 640116000, 653418000, 671565600, 684867600 }
typeOffsets:intvector { 29143, 0, 28800, 0, 28800, 3600 }
typeMap:bin { "0102010201020102010201020102010201" }
typeMap:bin { "010201020102010201020102010201020102010201020102010201" }
links:intvector { 258, 259, 269, 313, 382, 546 }
} //Z#313
/* Asia/Singapore */ :table {
@ -1650,7 +1642,7 @@ zoneinfo64:table(nofallback) {
} //Z#322
/* Asia/Tokyo */ :table {
transPre32:intvector { -1, 1707254896 }
trans:intvector { -683802000, -672314400, -654771600, -640864800, -620298000, -609415200, -588848400, -577965600 }
trans:intvector { -683802000, -672310800, -654771600, -640861200, -620298000, -609411600, -588848400, -577962000 }
typeOffsets:intvector { 33539, 0, 32400, 0, 32400, 3600 }
typeMap:bin { "010201020102010201" }
links:intvector { 323, 527, 529 }
@ -2406,9 +2398,9 @@ zoneinfo64:table(nofallback) {
finalYear:int { 2004 }
} //Z#495
/* Europe/Volgograd */ :table {
trans:intvector { -1577761060, -1247540400, 354916800, 370724400, 386452800, 402260400, 417988800, 433796400, 449611200, 465343200, 481068000, 496792800, 512517600, 528242400, 543967200, 559692000, 575416800, 591145200, 606870000, 622594800, 638319600, 654649200, 670374000, 701820000, 717548400, 733273200, 748998000, 764722800, 780447600, 796172400, 811897200, 828226800, 846370800, 859676400, 877820400, 891126000, 909270000, 922575600, 941324400, 954025200, 972774000, 985474800, 1004223600, 1017529200, 1035673200, 1048978800, 1067122800, 1080428400, 1099177200, 1111878000, 1130626800, 1143327600, 1162076400, 1174777200, 1193526000, 1206831600, 1224975600, 1238281200, 1256425200, 1269730800, 1288479600, 1301180400, 1414274400 }
trans:intvector { -1577761060, -1247540400, 354916800, 370724400, 386452800, 402260400, 417988800, 433796400, 449611200, 465343200, 481068000, 496792800, 512517600, 528242400, 543967200, 559692000, 575416800, 591145200, 606870000, 622594800, 638319600, 654649200, 670374000, 701820000, 717548400, 733273200, 748998000, 764722800, 780447600, 796172400, 811897200, 828226800, 846370800, 859676400, 877820400, 891126000, 909270000, 922575600, 941324400, 954025200, 972774000, 985474800, 1004223600, 1017529200, 1035673200, 1048978800, 1067122800, 1080428400, 1099177200, 1111878000, 1130626800, 1143327600, 1162076400, 1174777200, 1193526000, 1206831600, 1224975600, 1238281200, 1256425200, 1269730800, 1288479600, 1301180400, 1414274400, 1540681200 }
typeOffsets:intvector { 10660, 0, 10800, 0, 10800, 3600, 14400, 0, 14400, 3600 }
typeMap:bin { "010304030403040304030403040304030201020102010302010201020102010201020102010201020102010201020102010201020102010201020102010301" }
typeMap:bin { "01030403040304030403040304030403020102010201030201020102010201020102010201020102010201020102010201020102010201020102010201030103" }
} //Z#496
/* Europe/Warsaw */ :table {
trans:intvector { -1717032240, -1693706400, -1680483600, -1663455600, -1650150000, -1632006000, -1618700400, -1600473600, -1587168000, -1501725600, -931734000, -857257200, -844556400, -828226800, -812502000, -796608000, -778726800, -762660000, -748486800, -733273200, -715215600, -701910000, -684975600, -670460400, -654130800, -639010800, -397094400, -386812800, -371088000, -355363200, -334195200, -323308800, -307584000, -291859200, -271296000, -260409600, -239846400, -228960000, -208396800, -197510400, -176342400, -166060800, 228873600, 243993600, 260323200, 276048000, 291772800, 307497600, 323827200, 338947200, 354672000, 370396800, 386121600, 401846400, 417571200, 433296000, 449020800, 465350400, 481075200, 496800000, 512524800, 528249600, 543974400, 559699200, 575427600, 591152400, 606877200, 622602000, 638326800, 654656400, 670381200, 686106000, 701830800, 717555600, 733280400, 749005200, 764730000, 780454800, 796179600, 811904400, 828234000, 846378000 }
@ -2590,12 +2582,12 @@ zoneinfo64:table(nofallback) {
links:intvector { 554, 589, 592 }
} //Z#554
/* Pacific/Easter */ :table {
trans:intvector { -1178124152, -36619200, -23922000, -3355200, 7527600, 24465600, 37767600, 55915200, 69217200, 87969600, 100666800, 118209600, 132116400, 150868800, 163566000, 182318400, 195620400, 213768000, 227070000, 245217600, 258519600, 277272000, 289969200, 308721600, 321418800, 340171200, 353473200, 371620800, 384922800, 403070400, 416372400, 434520000, 447822000, 466574400, 479271600, 498024000, 510721200, 529473600, 545194800, 560923200, 574225200, 592372800, 605674800, 624427200, 637124400, 653457600, 668574000, 687326400, 700628400, 718776000, 732078000, 750225600, 763527600, 781675200, 794977200, 813729600, 826426800, 845179200, 859690800, 876628800, 889930800, 906868800, 923194800, 939528000, 952830000, 971582400, 984279600, 1003032000, 1015729200, 1034481600, 1047178800, 1065931200, 1079233200, 1097380800, 1110682800, 1128830400, 1142132400, 1160884800, 1173582000, 1192334400, 1206846000, 1223784000, 1237086000, 1255233600, 1270350000, 1286683200, 1304823600, 1313899200, 1335668400, 1346558400, 1367118000, 1378612800, 1398567600, 1410062400, 1463281200, 1471147200 }
trans:intvector { -1178124152, -36619200, -23922000, -3355200, 7527600, 24465600, 37767600, 55915200, 69217200, 87969600, 100666800, 118209600, 132116400, 150868800, 163566000, 182318400, 195620400, 213768000, 227070000, 245217600, 258519600, 277272000, 289969200, 308721600, 321418800, 340171200, 353473200, 371620800, 384922800, 403070400, 416372400, 434520000, 447822000, 466574400, 479271600, 498024000, 510721200, 529473600, 545194800, 560923200, 574225200, 592372800, 605674800, 624427200, 637124400, 653457600, 668574000, 687326400, 700628400, 718776000, 732078000, 750225600, 763527600, 781675200, 794977200, 813729600, 826426800, 845179200, 859690800, 876628800, 889930800, 906868800, 923194800, 939528000, 952830000, 971582400, 984279600, 1003032000, 1015729200, 1034481600, 1047178800, 1065931200, 1079233200, 1097380800, 1110682800, 1128830400, 1142132400, 1160884800, 1173582000, 1192334400, 1206846000, 1223784000, 1237086000, 1255233600, 1270350000, 1286683200, 1304823600, 1313899200, 1335668400, 1346558400, 1367118000, 1378612800, 1398567600, 1410062400, 1463281200, 1471147200, 1494730800, 1502596800, 1526180400, 1534046400, 1554606000, 1567915200 }
typeOffsets:intvector { -26248, 0, -25200, 0, -25200, 3600, -21600, 0, -21600, 3600 }
typeMap:bin { "010201020102010201020102010201020102010201020102010201020304030403040304030403040304030403040304030403040304030403040304030403040304030403040304030403040304030403040304030403040304030403040304" }
typeMap:bin { "010201020102010201020102010201020102010201020102010201020304030403040304030403040304030403040304030403040304030403040304030403040304030403040304030403040304030403040304030403040304030403040304030403040304" }
finalRule { "Chile" }
finalRaw:int { -21600 }
finalYear:int { 2017 }
finalYear:int { 2020 }
links:intvector { 393, 555 }
} //Z#555
/* Pacific/Efate */ :table {
@ -3100,7 +3092,7 @@ zoneinfo64:table(nofallback) {
8, -30, -1, 9900, 1, 3, 1, -1, 9900, 1, 3600
} //_#7
Chile:intvector {
7, 9, -1, 14400, 2, 4, 9, -1, 10800, 2, 3600
8, 2, -1, 14400, 2, 3, 2, -1, 10800, 2, 3600
} //_#8
Cuba:intvector {
2, 8, -1, 0, 1, 10, 1, -1, 0, 1, 3600
@ -3115,7 +3107,7 @@ zoneinfo64:table(nofallback) {
9, -31, -1, 3600, 2, 2, -31, -1, 3600, 2, -3600
} //_#12
Fiji:intvector {
10, 1, -1, 7200, 0, 0, 14, -1, 10800, 0, 3600
10, 1, -1, 7200, 0, 0, 13, -1, 10800, 0, 3600
} //_#13
Haiti:intvector {
2, 8, -1, 7200, 0, 10, 1, -1, 7200, 0, 3600
@ -3138,39 +3130,36 @@ zoneinfo64:table(nofallback) {
Moldova:intvector {
2, -31, -1, 7200, 0, 9, -31, -1, 10800, 0, 3600
} //_#20
Morocco:intvector {
2, -31, -1, 7200, 0, 9, -31, -1, 10800, 0, 3600
} //_#21
NZ:intvector {
8, -30, -1, 7200, 1, 3, 1, -1, 7200, 1, 3600
} //_#22
} //_#21
Palestine:intvector {
2, 22, -7, 3600, 0, 9, -31, -7, 3600, 0, 3600
} //_#23
} //_#22
Para:intvector {
9, 1, -1, 0, 0, 2, 22, -1, 0, 0, 3600
} //_#24
} //_#23
Syria:intvector {
2, -31, -6, 0, 0, 9, -31, -6, 0, 0, 3600
} //_#25
} //_#24
SystemV:intvector {
3, -30, -1, 7200, 0, 9, -31, -1, 7200, 0, 3600
} //_#26
} //_#25
Thule:intvector {
2, 8, -1, 7200, 0, 10, 1, -1, 7200, 0, 3600
} //_#27
} //_#26
Troll:intvector {
2, -31, -1, 3600, 2, 9, -31, -1, 3600, 2, 7200
} //_#28
} //_#27
US:intvector {
2, 8, -1, 7200, 0, 10, 1, -1, 7200, 0, 3600
} //_#29
} //_#28
WS:intvector {
8, -30, -1, 10800, 0, 3, 1, -1, 14400, 0, 3600
} //_#30
} //_#29
Zion:intvector {
2, 23, -6, 7200, 0, 9, -31, -1, 7200, 0, 3600
} //_#31
} //_#30
}
Regions:array {
"AU", //Z#0 ACT

Просмотреть файл

@ -8,11 +8,11 @@ set -e
# Usage: update-tzdata.sh <tzdata version>
# E.g., for tzdata2016f: update-tzdata.sh 2016f
# Ensure that $Date$ in the checked-out svn files expands timezone-agnostically,
# Ensure that $Date$ in the checked-out git files expands timezone-agnostically,
# so that this script's behavior is consistent when run from any time zone.
export TZ=UTC
# Also ensure SVN-INFO is consistently English.
# Also ensure GIT-INFO is consistently English.
export LANG=en_US.UTF-8
export LANGUAGE=en_US
export LC_ALL=en_US.UTF-8
@ -21,7 +21,7 @@ export LC_ALL=en_US.UTF-8
icu_pkg=
# Force updates even when current tzdata is newer than the requested version.
force=false
# Dry run, doesn't run 'svn export' and 'icupkg'.
# Dry run, doesn't run 'git clone' and 'icupkg'.
dry=false
# Compare ICU and local tzdata versions (used by update-icu.sh).
check_version=false
@ -51,11 +51,11 @@ icudata_dir=`dirname "$0"`/../config/external/icu/data
icu_dir=`dirname "$0"`/icu
tzdata_dir=`dirname "$0"`/tzdata
tzdata_files="${tzdata_dir}"/files.txt
tzdata_url=https://ssl.icu-project.org/repos/icu/data/trunk/tzdata/icunew/${tzdata_version}/44/
tzdata_url=https://github.com/unicode-org/icu-data.git
icu_tzdata_version=`grep --only-matching --perl-regexp --regexp="tz version:\s+\K.*$" "${icu_dir}"/source/data/misc/zoneinfo64.txt`
local_tzdata_version=
if [ -f "${tzdata_dir}"/SVN-INFO ]; then
local_tzdata_version=`grep --only-matching --perl-regexp --regexp="^URL: .*tzdata/icunew/\K[0-9a-z]+" "${tzdata_dir}"/SVN-INFO`
if [ -f "${tzdata_dir}"/VERSION ]; then
local_tzdata_version=`grep --only-matching --perl-regexp --regexp="^\K[0-9a-z]+" "${tzdata_dir}"/VERSION`
fi
# Check ICU and current local tzdata versions.
@ -120,20 +120,21 @@ else
echo "INFO: ICU data file (big endian) not found, skipping..."
fi
# Retrieve tzdata from svn.
# Retrieve tzdata from git.
if [ $dry = false ]; then
echo "INFO: Downloading tzdata${tzdata_version}"
# Remove intl/tzdata/source, then replace it with a clean export.
rm -r "${tzdata_dir}"/source
svn export "${tzdata_url}" "${tzdata_dir}"/source
fi
git clone --depth 1 "${tzdata_url}" "${tzdata_dir}"/source
git -C "${tzdata_dir}"/source filter-branch --prune-empty --subdirectory-filter tzdata/icunew/${tzdata_version}/44 HEAD
# Record `svn info`, eliding the line that changes every time the entire ICU
# tzdata repository (not just the path within it we care about) receives a
# commit.
if [ $dry = false ]; then
svn info "${tzdata_url}" | grep --invert-match '^Revision: [[:digit:]]\+$' > "${tzdata_dir}"/SVN-INFO
# Record `git log` and the tzdata version.
git -C "${tzdata_dir}"/source log -1 > "${tzdata_dir}"/GIT-INFO
echo "${tzdata_version}" > "${tzdata_dir}"/VERSION
# Remove the .git directory.
rm -rf "${tzdata_dir}"/source/.git
fi
# Update ICU data.
@ -163,11 +164,11 @@ if [ $dry = false ]; then
update_icu_data "be" "${icudata_file_be}"
fi
hg addremove "${tzdata_dir}/source" "${tzdata_dir}/SVN-INFO" "${icudata_file_le}"
hg addremove "${tzdata_dir}/source" "${tzdata_dir}/GIT-INFO" "${tzdata_dir}/VERSION" "${icudata_file_le}"
if [ -n "${icudata_file_be}" ]; then
hg addremove "${icudata_file_be}"
fi
echo "INFO: Successfully updated tzdata!"
echo "INFO: Please run js/src/builtin/make_intl_data.py to update additional time zone files for SpiderMonkey."
echo "INFO: Please run js/src/builtin/intl/make_intl_data.py to update additional time zone files for SpiderMonkey."
fi

Просмотреть файл

@ -1,5 +1,5 @@
// Generated by make_intl_data.py. DO NOT EDIT.
// tzdata version = 2018e
// tzdata version = 2018g
#ifndef builtin_intl_TimeZoneDataGenerated_h
#define builtin_intl_TimeZoneDataGenerated_h
@ -104,6 +104,8 @@ const char* const legacyICUTimeZones[] = {
"Canada/East-Saskatchewan",
"EAT",
"ECT",
"Eire--ICU",
"Europe/Bratislava--ICU",
"IET",
"IST",
"JST",
@ -116,6 +118,9 @@ const char* const legacyICUTimeZones[] = {
"PST",
"SST",
"VST",
"Africa/Windhoek--ICU",
"Europe/Dublin--ICU",
"Europe/Prague--ICU",
"SystemV/AST4",
"SystemV/AST4ADT",
"SystemV/CST6",

Просмотреть файл

@ -1,7 +1,7 @@
// |reftest| skip-if(!this.hasOwnProperty("Intl"))
// Generated by make_intl_data.py. DO NOT EDIT.
// tzdata version = 2018e
// tzdata version = 2018g
const tzMapper = [
x => x,

Просмотреть файл

@ -1,7 +1,7 @@
// |reftest| skip-if(!this.hasOwnProperty("Intl"))
// Generated by make_intl_data.py. DO NOT EDIT.
// tzdata version = 2018e
// tzdata version = 2018g
const tzMapper = [
x => x,

Просмотреть файл

@ -1,7 +1,7 @@
// |reftest| skip-if(!this.hasOwnProperty("Intl"))
// Generated by make_intl_data.py. DO NOT EDIT.
// tzdata version = 2018e
// tzdata version = 2018g
const tzMapper = [
x => x,

Просмотреть файл

@ -1,7 +1,7 @@
// |reftest| skip-if(!this.hasOwnProperty("Intl"))
// Generated by make_intl_data.py. DO NOT EDIT.
// tzdata version = 2018e
// tzdata version = 2018g
const tzMapper = [
x => x,

Просмотреть файл

@ -28,18 +28,15 @@ class GeckoViewContentChild extends GeckoViewChildModule {
Utils: "resource://gre/modules/sessionstore/Utils.jsm",
});
this.messageManager.addMessageListener("GeckoView:SaveState",
this);
this.messageManager.addMessageListener("GeckoView:RestoreState",
this);
this.messageManager.addMessageListener("GeckoView:DOMFullscreenEntered",
this);
this.messageManager.addMessageListener("GeckoView:DOMFullscreenExited",
this);
this.messageManager.addMessageListener("GeckoView:ZoomToInput",
this);
this.messageManager.addMessageListener("GeckoView:SetActive",
this);
this.messageManager.addMessageListener("GeckoView:RestoreState", this);
this.messageManager.addMessageListener("GeckoView:SaveState", this);
this.messageManager.addMessageListener("GeckoView:SetActive", this);
this.messageManager.addMessageListener("GeckoView:UpdateInitData", this);
this.messageManager.addMessageListener("GeckoView:ZoomToInput", this);
const options = {
mozSystemGroup: true,
@ -245,6 +242,12 @@ class GeckoViewContentChild extends GeckoViewChildModule {
content.windowUtils.mediaSuspend = aMsg.data.active ? Ci.nsISuspendedTypes.NONE_SUSPENDED : Ci.nsISuspendedTypes.SUSPENDED_PAUSE;
}
break;
case "GeckoView:UpdateInitData":
// Provide a hook for native code to detect a transfer.
Services.obs.notifyObservers(
docShell, "geckoview-content-global-transferred");
break;
}
}

Просмотреть файл

@ -194,6 +194,9 @@ var ModuleManager = {
module.enabled = initData.modules[name];
}
}
// Notify child of the transfer.
this._browser.messageManager.sendAsyncMessage(aEvent);
break;
}

Просмотреть файл

@ -7,9 +7,11 @@ package org.mozilla.geckoview.test
import org.mozilla.geckoview.GeckoSession
import org.mozilla.geckoview.GeckoSessionSettings
import org.mozilla.geckoview.GeckoView
import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.AssertCalled
import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.ClosedSessionAtStart
import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.NullDelegate
import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.ReuseSession
import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.WithDevToolsAPI
import org.mozilla.geckoview.test.util.Callbacks
import org.mozilla.geckoview.test.util.UiThreadUtils
@ -258,6 +260,46 @@ class SessionLifecycleTest : BaseSessionTest() {
onLocationCount, equalTo(1))
}
@WithDevToolsAPI
@Test fun readFromParcel_focusedInput() {
// When an input is focused, make sure SessionTextInput is still active after transferring.
mainSession.loadTestPath(INPUTS_PATH)
mainSession.waitForPageStop()
mainSession.evaluateJS("$('#input').focus()")
mainSession.waitUntilCalled(object : Callbacks.TextInputDelegate {
@AssertCalled(count = 1)
override fun restartInput(session: GeckoSession, reason: Int) {
assertThat("Reason should be correct",
reason, equalTo(GeckoSession.TextInputDelegate.RESTART_REASON_FOCUS))
}
})
val newSession = sessionRule.createClosedSession()
mainSession.toParcel { parcel ->
newSession.readFromParcel(parcel)
}
// We generate an extra focus event during transfer.
newSession.waitUntilCalled(object : Callbacks.TextInputDelegate {
@AssertCalled(count = 1)
override fun restartInput(session: GeckoSession, reason: Int) {
assertThat("Reason should be correct",
reason, equalTo(GeckoSession.TextInputDelegate.RESTART_REASON_FOCUS))
}
})
newSession.evaluateJS("$('#input').blur()")
newSession.waitUntilCalled(object : Callbacks.TextInputDelegate {
@AssertCalled(count = 1)
override fun restartInput(session: GeckoSession, reason: Int) {
// We generate an extra focus event during transfer.
assertThat("Reason should be correct",
reason, equalTo(GeckoSession.TextInputDelegate.RESTART_REASON_BLUR))
}
})
}
private fun testRestoreInstanceState(fromSession: GeckoSession?,
ontoSession: GeckoSession?) =
GeckoView(InstrumentationRegistry.getTargetContext()).apply {

Просмотреть файл

@ -4,10 +4,15 @@
package org.mozilla.gecko;
import org.mozilla.gecko.IGeckoEditableParent;
import android.view.KeyEvent;
// Interface for GeckoEditable calls from parent to child
interface IGeckoEditableChild {
// Transfer this child to a new parent.
void transferParent(in IGeckoEditableParent parent);
// Process a key event.
void onKeyEvent(int action, int keyCode, int scanCode, int metaState,
int keyPressMetaState, long time, int domPrintableKeyValue,

Просмотреть файл

@ -11,12 +11,15 @@ import org.mozilla.gecko.IGeckoEditableChild;
// Interface for GeckoEditable calls from child to parent
interface IGeckoEditableParent {
// Set the default child to forward events to, when there is no focused child.
void setDefaultChild(IGeckoEditableChild child);
// Notify an IME event of a type defined in GeckoEditableListener.
void notifyIME(IGeckoEditableChild child, int type);
// Notify a change in editor state or type.
void notifyIMEContext(int state, String typeHint, String modeHint, String actionHint,
int flags);
void notifyIMEContext(IBinder token, int state, String typeHint, String modeHint,
String actionHint, int flags);
// Notify a change in editor selection.
void onSelectionChange(IBinder token, int start, int end);

Просмотреть файл

@ -4,8 +4,8 @@
package org.mozilla.gecko.process;
import org.mozilla.gecko.IGeckoEditableParent;
import org.mozilla.gecko.IGeckoEditableChild;
interface IProcessManager {
IGeckoEditableParent getEditableParent(long contentId, long tabId);
void getEditableParent(in IGeckoEditableChild child, long contentId, long tabId);
}

Просмотреть файл

@ -12,6 +12,7 @@ import org.mozilla.gecko.util.ThreadUtils;
import android.graphics.RectF;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.KeyEvent;
@ -29,6 +30,11 @@ public final class GeckoEditableChild extends JNIObject implements IGeckoEditabl
private static final int NOTIFY_IME_TO_CANCEL_COMPOSITION = 9;
private final class RemoteChild extends IGeckoEditableChild.Stub {
@Override // IGeckoEditableChild
public void transferParent(final IGeckoEditableParent editableParent) {
GeckoEditableChild.this.transferParent(editableParent);
}
@Override // IGeckoEditableChild
public void onKeyEvent(int action, int keyCode, int scanCode, int metaState,
int keyPressMetaState, long time, int domPrintableKeyValue,
@ -70,25 +76,49 @@ public final class GeckoEditableChild extends JNIObject implements IGeckoEditabl
}
}
private final IGeckoEditableParent mEditableParent;
private final IGeckoEditableChild mEditableChild;
private final boolean mIsDefault;
private IGeckoEditableParent mEditableParent;
private int mCurrentTextLength; // Used by Gecko thread
@WrapForJNI(calledFrom = "gecko")
public GeckoEditableChild(final IGeckoEditableParent editableParent) {
mEditableParent = editableParent;
private GeckoEditableChild(@Nullable final IGeckoEditableParent editableParent,
final boolean isDefault) {
mIsDefault = isDefault;
final IBinder binder = editableParent.asBinder();
if (binder.queryLocalInterface(IGeckoEditableParent.class.getName()) != null) {
if (editableParent != null &&
editableParent.asBinder().queryLocalInterface(
IGeckoEditableParent.class.getName()) != null) {
// IGeckoEditableParent is local; i.e. we're in the main process.
mEditableChild = this;
} else {
// IGeckoEditableParent is remote; i.e. we're in a content process.
mEditableChild = new RemoteChild();
}
if (editableParent != null) {
setParent(editableParent);
}
}
@WrapForJNI(calledFrom = "gecko")
private void setParent(final IGeckoEditableParent editableParent) {
mEditableParent = editableParent;
if (mIsDefault) {
// Tell the parent we're the default child.
try {
editableParent.setDefaultChild(mEditableChild);
} catch (final RemoteException e) {
Log.e(LOGTAG, "Failed to set default child", e);
}
}
}
@WrapForJNI(dispatchTo = "proxy") @Override // IGeckoEditableChild
public native void transferParent(IGeckoEditableParent editableParent);
@WrapForJNI(dispatchTo = "proxy") @Override // IGeckoEditableChild
public native void onKeyEvent(int action, int keyCode, int scanCode, int metaState,
int keyPressMetaState, long time, int domPrintableKeyValue,
@ -123,10 +153,22 @@ public final class GeckoEditableChild extends JNIObject implements IGeckoEditabl
throw new UnsupportedOperationException();
}
@WrapForJNI(calledFrom = "gecko")
private boolean hasEditableParent() {
if (mEditableParent != null) {
return true;
}
Log.w(LOGTAG, "No editable parent");
return false;
}
@Override // IInterface
public IBinder asBinder() {
// Return the GeckoEditableParent's binder as our binder for comparison purposes.
return mEditableParent.asBinder();
// Return the GeckoEditableParent's binder as fallback for comparison purposes.
return mEditableChild != this
? mEditableChild.asBinder()
: hasEditableParent()
? mEditableParent.asBinder() : null;
}
@WrapForJNI(calledFrom = "gecko")
@ -135,6 +177,9 @@ public final class GeckoEditableChild extends JNIObject implements IGeckoEditabl
ThreadUtils.assertOnGeckoThread();
Log.d(LOGTAG, "notifyIME(" + type + ")");
}
if (!hasEditableParent()) {
return;
}
if (type == NOTIFY_IME_TO_CANCEL_COMPOSITION) {
// Composition should have been canceled on the parent side through text
// update notifications. We cannot verify that here because we don't
@ -161,9 +206,13 @@ public final class GeckoEditableChild extends JNIObject implements IGeckoEditabl
typeHint + "\", \"" + modeHint + "\", \"" + actionHint +
"\", 0x" + Integer.toHexString(flags) + ")");
}
if (!hasEditableParent()) {
return;
}
try {
mEditableParent.notifyIMEContext(state, typeHint, modeHint, actionHint, flags);
mEditableParent.notifyIMEContext(mEditableChild.asBinder(), state, typeHint,
modeHint, actionHint, flags);
} catch (final RemoteException e) {
Log.e(LOGTAG, "Remote call failed", e);
}
@ -175,6 +224,9 @@ public final class GeckoEditableChild extends JNIObject implements IGeckoEditabl
ThreadUtils.assertOnGeckoThread();
Log.d(LOGTAG, "onSelectionChange(" + start + ", " + end + ")");
}
if (!hasEditableParent()) {
return;
}
final int currentLength = mCurrentTextLength;
if (start < 0 || start > currentLength || end < 0 || end > currentLength) {
@ -195,6 +247,9 @@ public final class GeckoEditableChild extends JNIObject implements IGeckoEditabl
Log.d(LOGTAG, "onTextChange(" + text + ", " + start + ", " +
unboundedOldEnd + ", " + unboundedNewEnd + ")");
}
if (!hasEditableParent()) {
return;
}
if (start < 0 || start > unboundedOldEnd) {
Log.e(LOGTAG, "invalid text notification range: " +
@ -231,6 +286,9 @@ public final class GeckoEditableChild extends JNIObject implements IGeckoEditabl
.append("repeatCount=").append(event.getRepeatCount()).append(")");
Log.d(LOGTAG, sb.toString());
}
if (!hasEditableParent()) {
return;
}
try {
mEditableParent.onDefaultKeyEvent(mEditableChild.asBinder(), event);
@ -246,6 +304,9 @@ public final class GeckoEditableChild extends JNIObject implements IGeckoEditabl
ThreadUtils.assertOnGeckoThread();
Log.d(LOGTAG, "updateCompositionRects(rects.length = " + rects.length + ")");
}
if (!hasEditableParent()) {
return;
}
try {
mEditableParent.updateCompositionRects(mEditableChild.asBinder(), rects);

Просмотреть файл

@ -6,6 +6,7 @@ package org.mozilla.gecko.process;
import org.mozilla.gecko.GeckoAppShell;
import org.mozilla.gecko.GeckoThread;
import org.mozilla.gecko.IGeckoEditableChild;
import org.mozilla.gecko.IGeckoEditableParent;
import org.mozilla.gecko.annotation.WrapForJNI;
import org.mozilla.gecko.util.ThreadUtils;
@ -31,13 +32,24 @@ public final class GeckoProcessManager extends IProcessManager.Stub {
return INSTANCE;
}
@WrapForJNI(stubName = "GetEditableParent")
private static native IGeckoEditableParent nativeGetEditableParent(long contentId,
long tabId);
@WrapForJNI(calledFrom = "gecko")
private static void setEditableChildParent(final IGeckoEditableChild child,
final IGeckoEditableParent parent) {
try {
child.transferParent(parent);
} catch (final RemoteException e) {
Log.e(LOGTAG, "Cannot set parent", e);
}
}
@WrapForJNI(stubName = "GetEditableParent", dispatchTo = "gecko")
private static native void nativeGetEditableParent(IGeckoEditableChild child,
long contentId, long tabId);
@Override // IProcessManager
public IGeckoEditableParent getEditableParent(final long contentId, final long tabId) {
return nativeGetEditableParent(contentId, tabId);
public void getEditableParent(final IGeckoEditableChild child,
final long contentId, final long tabId) {
nativeGetEditableParent(child, contentId, tabId);
}
private static final class ChildConnection implements ServiceConnection,

Просмотреть файл

@ -7,6 +7,7 @@ package org.mozilla.gecko.process;
import org.mozilla.gecko.annotation.WrapForJNI;
import org.mozilla.gecko.GeckoAppShell;
import org.mozilla.gecko.IGeckoEditableChild;
import org.mozilla.gecko.IGeckoEditableParent;
import org.mozilla.gecko.mozglue.GeckoLoader;
import org.mozilla.gecko.GeckoThread;
@ -28,13 +29,13 @@ public class GeckoServiceChildProcess extends Service {
private static IProcessManager sProcessManager;
@WrapForJNI(calledFrom = "gecko")
private static IGeckoEditableParent getEditableParent(final long contentId,
final long tabId) {
private static void getEditableParent(final IGeckoEditableChild child,
final long contentId,
final long tabId) {
try {
return sProcessManager.getEditableParent(contentId, tabId);
sProcessManager.getEditableParent(child, contentId, tabId);
} catch (final RemoteException e) {
Log.e(LOGTAG, "Cannot get editable", e);
return null;
}
}

Просмотреть файл

@ -105,6 +105,9 @@ import android.view.inputmethod.EditorInfo;
private int mIMEFlags; // Used by IC thread.
private boolean mIgnoreSelectionChange; // Used by Gecko thread
private int mLastTextChangeStart = -1; // Used by Gecko thread
private int mLastTextChangeEnd = -1; // Used by Gecko thread
private boolean mLastTextChangeReplacedSelection; // Used by Gecko thread
// Prevent showSoftInput and hideSoftInput from being called multiple times in a row,
// including reentrant calls on some devices. Used by UI/IC thread.
@ -658,10 +661,10 @@ import android.view.inputmethod.EditorInfo;
mIcRunHandler = mIcPostHandler = ThreadUtils.getUiHandler();
}
public void setDefaultEditableChild(final IGeckoEditableChild child) {
@Override // IGeckoEditableParent
public void setDefaultChild(final IGeckoEditableChild child) {
if (DEBUG) {
// Called by SessionTextInput.
ThreadUtils.assertOnUiThread();
// On Gecko or binder thread.
Log.d(LOGTAG, "setDefaultEditableChild " + child);
}
mDefaultChild = child;
@ -1126,6 +1129,45 @@ import android.view.inputmethod.EditorInfo;
getConstantName(Action.class, "TYPE_", action.mType) + ")");
}
switch (action.mType) {
case Action.TYPE_REPLACE_TEXT: {
final Spanned currentText = mText.getCurrentText();
final int actionNewEnd = action.mStart + action.mSequence.length();
if (mLastTextChangeStart < 0 || mLastTextChangeEnd > currentText.length() ||
action.mStart < mLastTextChangeStart || actionNewEnd > mLastTextChangeEnd) {
// Replace-text action doesn't match our text change.
break;
}
int indexInText = TextUtils.indexOf(currentText, action.mSequence,
action.mStart, mLastTextChangeEnd);
if (indexInText < 0 && action.mStart != mLastTextChangeStart) {
final String changedText = TextUtils.substring(
currentText, mLastTextChangeStart, actionNewEnd);
indexInText = changedText.lastIndexOf(action.mSequence.toString());
if (indexInText >= 0) {
indexInText += mLastTextChangeStart;
}
}
if (indexInText < 0) {
// Replace-text action doesn't match our current text.
break;
}
// Replace-text action matches our current text; copy the new spans to the
// current text.
mText.currentReplace(indexInText,
indexInText + action.mSequence.length(),
action.mSequence);
// The text change is caused by the replace-text event. If the text change
// replaced the previous selection, we need to rely on Gecko for an updated
// selection, so don't ignore selection change. However, if the text change
// did not replace the previous selection, we can ignore the Gecko selection
// in favor of the Java selection.
mIgnoreSelectionChange = !mLastTextChangeReplacedSelection;
break;
}
case Action.TYPE_SET_SPAN:
final int len = mText.getCurrentText().length();
if (action.mStart > len || action.mEnd > len ||
@ -1292,7 +1334,7 @@ import android.view.inputmethod.EditorInfo;
}
@Override // IGeckoEditableParent
public void notifyIMEContext(final int state, final String typeHint,
public void notifyIMEContext(final IBinder token, final int state, final String typeHint,
final String modeHint, final String actionHint,
final int flags) {
// On Gecko or binder thread.
@ -1304,9 +1346,14 @@ import android.view.inputmethod.EditorInfo;
"\", 0x" + Integer.toHexString(flags) + ")");
}
// Don't check token for notifyIMEContext, because the calls all come
// from the parent process.
ThreadUtils.assertOnGeckoThread();
// Regular notifyIMEContext calls all come from the parent process (with the default child),
// so always allow calls from there. We can get additional notifyIMEContext calls during
// a session transfer; calls in those cases can come from child processes, and we must
// perform a token check in that situation.
if (token != mDefaultChild.asBinder() &&
!binderCheckToken(token, /* allowNull */ false)) {
return;
}
mIcPostHandler.post(new Runnable() {
@Override
@ -1574,6 +1621,12 @@ import android.view.inputmethod.EditorInfo;
mText.currentSetSelection(start, end);
}
// We receive selection change notification after receiving replies for pending
// events, so we can reset text change bounds at this point.
mLastTextChangeStart = -1;
mLastTextChangeEnd = -1;
mLastTextChangeReplacedSelection = false;
mIcPostHandler.post(new Runnable() {
@Override
public void run() {
@ -1605,7 +1658,6 @@ import android.view.inputmethod.EditorInfo;
final int currentLength = mText.getCurrentText().length();
final int oldEnd = unboundedOldEnd > currentLength ? currentLength : unboundedOldEnd;
final int newEnd = start + text.length();
final Action action = mActions.peek();
if (start == 0 && unboundedOldEnd > currentLength) {
// | oldEnd > currentLength | signals entire text is cleared (e.g. for
@ -1617,96 +1669,42 @@ import android.view.inputmethod.EditorInfo;
// Don't ignore the next selection change because we are re-syncing with Gecko
mIgnoreSelectionChange = false;
} else if (action != null &&
action.mType == Action.TYPE_REPLACE_TEXT &&
start <= action.mStart &&
oldEnd >= action.mEnd &&
newEnd >= action.mStart + action.mSequence.length()) {
mLastTextChangeStart = -1;
mLastTextChangeEnd = -1;
mLastTextChangeReplacedSelection = false;
// Try to preserve both old spans and new spans in action.mSequence.
// indexInText is where we can find waction.mSequence within the passed in text.
final int startWithinText = action.mStart - start;
int indexInText = TextUtils.indexOf(text, action.mSequence, startWithinText);
if (indexInText < 0 && startWithinText >= action.mSequence.length()) {
indexInText = text.toString().lastIndexOf(action.mSequence.toString(),
startWithinText);
}
} else if (!geckoIsSameText(start, oldEnd, text)) {
final Spanned currentText = mText.getCurrentText();
final int selStart = Selection.getSelectionStart(currentText);
final int selEnd = Selection.getSelectionEnd(currentText);
if (indexInText < 0) {
// Text was changed from under us. We are forced to discard any new spans.
mText.currentReplace(start, oldEnd, text);
// True if the selection was in the middle of the replaced text; in that case
// we don't know where to place the selection after replacement, and must rely
// on the Gecko selection.
mLastTextChangeReplacedSelection |=
(selStart >= start && selStart <= oldEnd) ||
(selEnd >= start && selEnd <= oldEnd);
// Don't ignore the next selection change because we are forced to re-sync
// with Gecko here.
mIgnoreSelectionChange = false;
} else if (indexInText == 0 && text.length() == action.mSequence.length() &&
oldEnd - start == action.mEnd - action.mStart) {
// The new change exactly matches our saved change, so do a direct replace.
mText.currentReplace(start, oldEnd, action.mSequence);
// Ignore the next selection change because the selection change is a
// side-effect of the replace-text event we sent.
mIgnoreSelectionChange = true;
} else {
// The sequence is embedded within the changed text, so we have to perform
// replacement in parts. First replace part of text before the sequence.
mText.currentReplace(start, action.mStart, text.subSequence(0, indexInText));
// Then replace part of the text after the sequence.
final int actionStart = indexInText + start;
final int delta = actionStart - action.mStart;
final int actionEnd = delta + action.mEnd;
final Spanned currentText = mText.getCurrentText();
final boolean resetSelStart = Selection.getSelectionStart(currentText) == actionEnd;
final boolean resetSelEnd = Selection.getSelectionEnd(currentText) == actionEnd;
mText.currentReplace(actionEnd, delta + oldEnd, text.subSequence(
indexInText + action.mSequence.length(), text.length()));
// The replacement above may have shifted our selection, if the selection
// was at the start of the replacement range. If so, we need to reset
// our selection to the previous position.
if (resetSelStart || resetSelEnd) {
mText.currentSetSelection(
resetSelStart ? actionEnd : Selection.getSelectionStart(currentText),
resetSelEnd ? actionEnd : Selection.getSelectionEnd(currentText));
}
// Finally replace the sequence itself to preserve new spans.
mText.currentReplace(actionStart, actionEnd, action.mSequence);
// If one of the Java selection ends is not at the end of the replaced
// text, we want to preserve that selection, so we ignore the Gecko
// selection change notification. On the other hand, if the Java selection
// is normal, we want to try syncing the Java selection to the Gecko
// selection, because this text change could have changed the Gecko
// selection to elsewhere; so in that case, don't ignore the Gecko
// selection change notification.
mIgnoreSelectionChange = !resetSelStart || !resetSelEnd;
}
} else if (geckoIsSameText(start, oldEnd, text)) {
// Nothing to do because the text is the same. This could happen when
// the composition is updated for example, in which case we want to keep the
// Java selection.
mIgnoreSelectionChange = mIgnoreSelectionChange || (action != null &&
(action.mType == Action.TYPE_REPLACE_TEXT ||
action.mType == Action.TYPE_SET_SPAN ||
action.mType == Action.TYPE_REMOVE_SPAN));
return;
} else {
// Gecko side initiated the text change. Replace in two steps to properly
// clear composing spans that span the whole range.
mText.currentReplace(start, oldEnd, "");
mText.currentReplace(start, start, text);
// Don't ignore the next selection change because we are forced to re-sync
// with Gecko here.
mIgnoreSelectionChange = false;
mLastTextChangeStart = start;
mLastTextChangeEnd = newEnd;
} else {
// Nothing to do because the text is the same. This could happen when
// the composition is updated for example, in which case we want to keep the
// Java selection.
final Action action = mActions.peek();
mIgnoreSelectionChange = mIgnoreSelectionChange || (action != null &&
(action.mType == Action.TYPE_REPLACE_TEXT ||
action.mType == Action.TYPE_SET_SPAN ||
action.mType == Action.TYPE_REMOVE_SPAN));
mLastTextChangeStart = start;
mLastTextChangeEnd = newEnd;
}
// onTextChange is always followed by onSelectionChange, so we let
@ -1785,7 +1783,7 @@ import android.view.inputmethod.EditorInfo;
} else if (chr == '\n') {
return "\u21b2";
}
return String.format("%04x", (int) chr);
return String.format("\\u%04x", (int) chr);
}
static StringBuilder debugAppend(StringBuilder sb, Object obj) {

Просмотреть файл

@ -730,8 +730,7 @@ public class GeckoSession extends LayerSession
GeckoBundle initData);
@WrapForJNI(dispatchTo = "proxy")
public native void attachEditable(IGeckoEditableParent parent,
GeckoEditableChild child);
public native void attachEditable(IGeckoEditableParent parent);
@WrapForJNI(dispatchTo = "proxy")
public native void attachAccessibility(SessionAccessibility.NativeProvider sessionAccessibility);

Просмотреть файл

@ -275,7 +275,6 @@ public final class SessionTextInput {
private final GeckoSession mSession;
private final NativeQueue mQueue;
private final GeckoEditable mEditable;
private final GeckoEditableChild mEditableChild;
private InputConnectionClient mInputConnection;
private GeckoSession.TextInputDelegate mDelegate;
// Auto-fill nodes.
@ -289,8 +288,6 @@ public final class SessionTextInput {
mSession = session;
mQueue = queue;
mEditable = new GeckoEditable(session);
mEditableChild = new GeckoEditableChild(mEditable);
mEditable.setDefaultEditableChild(mEditableChild);
session.getEventDispatcher().registerUiThreadListener(
new BundleEventListener() {
@ -314,11 +311,10 @@ public final class SessionTextInput {
/* package */ void onWindowChanged(final GeckoSession.Window window) {
if (mQueue.isReady()) {
window.attachEditable(mEditable, mEditableChild);
window.attachEditable(mEditable);
} else {
mQueue.queueUntilReady(window, "attachEditable",
IGeckoEditableParent.class, mEditable,
GeckoEditableChild.class, mEditableChild);
IGeckoEditableParent.class, mEditable);
}
}

Просмотреть файл

@ -372,6 +372,17 @@ public class testInputConnection extends JavascriptBridgeTest {
ic.deleteSurroundingText(1, 0);
assertTextAndSelectionAt("Can clear text", ic, "", 0);
// Bug 1490391 - Committing then setting composition can result in duplicates.
ic.commitText("far", 1);
ic.setComposingText("bar", 1);
assertTextAndSelectionAt("Can commit then set composition", ic, "farbar", 6);
ic.setComposingText("baz", 1);
assertTextAndSelectionAt("Composition still exists after setting", ic, "farbaz", 6);
ic.finishComposingText();
ic.deleteSurroundingText(6, 0);
assertTextAndSelectionAt("Can clear text", ic, "", 0);
// Make sure we don't leave behind stale events for the following test.
processGeckoEvents();
processInputConnectionEvents();

Просмотреть файл

@ -29,7 +29,7 @@ web-platform-tests:
linux.*/debug: 18
macosx64.*/opt: 8
macosx64/debug: 16
windows10-64-ccov/debug: 15
windows10.*/debug: 18
macosx64-ccov/debug: 24
default: 12
max-run-time:

Просмотреть файл

@ -1,32 +1,4 @@
[request-consume-empty.html]
max-asserts: 2
[Consume request's body as text]
expected: FAIL
[Consume request's body as blob]
expected: FAIL
[Consume request's body as arrayBuffer]
expected: FAIL
[Consume request's body as json]
expected: FAIL
[Consume request's body as formData]
expected: FAIL
[Consume empty FormData request body as text]
expected: FAIL
[Consume request's body as json (error case)]
expected: FAIL
[Consume request's body as formData with correct multipart type (error case)]
expected: FAIL
[Consume request's body as formData with correct urlencoded type]
expected: FAIL
[Consume request's body as formData without correct type (error case)]
expected: FAIL

Просмотреть файл

@ -1,7 +1,4 @@
[request-disturbed.html]
[Request without body cannot be disturbed]
expected: FAIL
[Request's body: initial state]
expected: FAIL

Просмотреть файл

@ -1,32 +1,3 @@
[response-consume-empty.html]
max-asserts: 2
[Consume response's body as text]
expected: FAIL
[Consume response's body as blob]
expected: FAIL
[Consume response's body as arrayBuffer]
expected: FAIL
[Consume response's body as json]
expected: FAIL
[Consume response's body as formData]
expected: FAIL
[Consume empty FormData response body as text]
expected: FAIL
[Consume response's body as json (error case)]
expected: FAIL
[Consume response's body as formData with correct multipart type (error case)]
expected: FAIL
[Consume response's body as formData with correct urlencoded type]
expected: FAIL
[Consume response's body as formData without correct type (error case)]
expected: FAIL

Просмотреть файл

@ -1,4 +1,6 @@
[area-coords.html]
max-asserts: 102
[COMMA: "2,2,10,10" (rect)]
expected: FAIL

Просмотреть файл

@ -1,4 +0,0 @@
[cache-add.https.html]
[Cache.add with request with null body (not consumed)]
expected: FAIL

Просмотреть файл

@ -1,4 +0,0 @@
[cache-add.https.html]
[Cache.add with request with null body (not consumed)]
expected: FAIL

Просмотреть файл

@ -1,4 +0,0 @@
[cache-add.https.html]
[Cache.add with request with null body (not consumed)]
expected: FAIL

Просмотреть файл

@ -1,4 +0,0 @@
[same-origin.html]
[unsupported_scheme]
expected: FAIL

Просмотреть файл

@ -1,4 +0,0 @@
[same-origin.html]
[unsupported_scheme]
expected: FAIL

Просмотреть файл

@ -16,6 +16,7 @@
#include "mozilla/TextComposition.h"
#include "mozilla/TextEventDispatcherListener.h"
#include "mozilla/TextEvents.h"
#include "mozilla/dom/TabChild.h"
#include <android/api-level.h>
#include <android/input.h>
@ -585,18 +586,19 @@ GeckoEditableSupport::GetComposition() const
return widget ? IMEStateManager::GetTextCompositionFor(widget) : nullptr;
}
void
bool
GeckoEditableSupport::RemoveComposition(RemoveCompositionFlag aFlag)
{
if (!mDispatcher || !mDispatcher->IsComposing()) {
return;
return false;
}
nsEventStatus status = nsEventStatus_eIgnore;
NS_ENSURE_SUCCESS_VOID(BeginInputTransaction(mDispatcher));
NS_ENSURE_SUCCESS(BeginInputTransaction(mDispatcher), false);
mDispatcher->CommitComposition(
status, aFlag == CANCEL_IME_COMPOSITION ? &EmptyString() : nullptr);
return true;
}
void
@ -903,16 +905,18 @@ GeckoEditableSupport::FlushIMEChanges(FlushChangesFlag aFlags)
}
}
while (mIMEDelaySynchronizeReply && mIMEActiveSynchronizeCount) {
mIMEActiveSynchronizeCount--;
mEditable->NotifyIME(EditableListener::NOTIFY_IME_REPLY_EVENT);
}
mIMEDelaySynchronizeReply = false;
mIMEActiveSynchronizeCount = 0;
if (mIMESelectionChanged) {
mIMESelectionChanged = false;
mEditable->OnSelectionChange(selStart, selEnd);
flushOnException();
}
while (mIMEActiveReplaceTextCount) {
mIMEActiveReplaceTextCount--;
OnImeSynchronize();
}
}
void
@ -961,6 +965,12 @@ GeckoEditableSupport::UpdateCompositionRects()
void
GeckoEditableSupport::OnImeSynchronize()
{
if (mIMEDelaySynchronizeReply) {
// If we are waiting for other events to reply,
// queue this reply as well.
mIMEActiveSynchronizeCount++;
return;
}
if (!mIMEMaskEventsCount) {
FlushIMEChanges();
}
@ -971,13 +981,11 @@ void
GeckoEditableSupport::OnImeReplaceText(int32_t aStart, int32_t aEnd,
jni::String::Param aText)
{
mIMEActiveReplaceTextCount++;
if (!DoReplaceText(aStart, aEnd, aText)) {
// We did not process the event, so reply to it now.
mIMEActiveReplaceTextCount--;
OnImeSynchronize();
if (DoReplaceText(aStart, aEnd, aText)) {
mIMEDelaySynchronizeReply = true;
}
OnImeSynchronize();
}
bool
@ -1010,6 +1018,7 @@ GeckoEditableSupport::DoReplaceText(int32_t aStart, int32_t aEnd,
nsString string(aText->ToString());
const bool composing = !mIMERanges->IsEmpty();
nsEventStatus status = nsEventStatus_eIgnore;
bool textChanged = composing;
if (!mIMEKeyEvents.IsEmpty() ||
!composition || !mDispatcher->IsComposing() ||
@ -1019,7 +1028,7 @@ GeckoEditableSupport::DoReplaceText(int32_t aStart, int32_t aEnd,
// Only start a new composition if we have key events,
// if we don't have an existing composition, or
// the replaced text does not match our composition.
RemoveComposition();
textChanged |= RemoveComposition();
{
// Use text selection to set target position(s) for
@ -1061,6 +1070,7 @@ GeckoEditableSupport::DoReplaceText(int32_t aStart, int32_t aEnd,
if (!mDispatcher || widget->Destroyed()) {
return false;
}
textChanged = true;
}
} else if (composition->String().Equals(string)) {
/* If the new text is the same as the existing composition text,
@ -1070,7 +1080,10 @@ GeckoEditableSupport::DoReplaceText(int32_t aStart, int32_t aEnd,
IMETextChange dummyChange;
dummyChange.mStart = aStart;
dummyChange.mOldEnd = dummyChange.mNewEnd = aEnd;
PostFlushIMEChanges();
mIMESelectionChanged = true;
AddIMETextChange(dummyChange);
textChanged = true;
}
if (sDispatchKeyEventsInCompositionForAnyApps ||
@ -1088,6 +1101,7 @@ GeckoEditableSupport::DoReplaceText(int32_t aStart, int32_t aEnd,
mIMERanges->Clear();
} else if (!string.IsEmpty() || mDispatcher->IsComposing()) {
mDispatcher->CommitComposition(status, &string);
textChanged = true;
}
if (!mDispatcher || widget->Destroyed()) {
return false;
@ -1098,7 +1112,7 @@ GeckoEditableSupport::DoReplaceText(int32_t aStart, int32_t aEnd,
SendIMEDummyKeyEvent(widget, eKeyUp);
// Widget may be destroyed after dispatching the above event.
}
return true;
return textChanged;
}
void
@ -1131,28 +1145,38 @@ GeckoEditableSupport::OnImeAddCompositionRange(
void
GeckoEditableSupport::OnImeUpdateComposition(int32_t aStart, int32_t aEnd,
int32_t aFlags)
{
if (DoUpdateComposition(aStart, aEnd, aFlags)) {
mIMEDelaySynchronizeReply = true;
}
}
bool
GeckoEditableSupport::DoUpdateComposition(int32_t aStart, int32_t aEnd,
int32_t aFlags)
{
if (mIMEMaskEventsCount > 0) {
// Not focused.
return;
return false;
}
nsCOMPtr<nsIWidget> widget = GetWidget();
nsEventStatus status = nsEventStatus_eIgnore;
NS_ENSURE_TRUE_VOID(mDispatcher && widget);
NS_ENSURE_TRUE(mDispatcher && widget, false);
const bool keepCurrent = !!(aFlags &
java::GeckoEditableChild::FLAG_KEEP_CURRENT_COMPOSITION);
bool compositionChanged = false;
// A composition with no ranges means we want to set the selection.
if (mIMERanges->IsEmpty()) {
if (keepCurrent && mDispatcher->IsComposing()) {
// Don't set selection if we want to keep current composition.
return;
return false;
}
MOZ_ASSERT(aStart >= 0 && aEnd >= 0);
RemoveComposition();
compositionChanged = RemoveComposition();
WidgetSelectionEvent selEvent(true, eSetSelection, widget);
selEvent.mOffset = std::min(aStart, aEnd);
@ -1160,7 +1184,7 @@ GeckoEditableSupport::OnImeUpdateComposition(int32_t aStart, int32_t aEnd,
selEvent.mReversed = aStart > aEnd;
selEvent.mExpandToClusterBoundary = false;
widget->DispatchEvent(&selEvent, status);
return;
return compositionChanged;
}
/**
@ -1181,12 +1205,13 @@ GeckoEditableSupport::OnImeUpdateComposition(int32_t aStart, int32_t aEnd,
if (keepCurrent) {
// Don't start a new composition if we want to keep the current one.
mIMERanges->Clear();
return;
return false;
}
// Only start new composition if we don't have an existing one,
// or if the existing composition doesn't match the new one.
RemoveComposition();
compositionChanged = true;
{
WidgetSelectionEvent event(true, eSetSelection, widget);
@ -1218,11 +1243,12 @@ GeckoEditableSupport::OnImeUpdateComposition(int32_t aStart, int32_t aEnd,
if (NS_WARN_IF(NS_FAILED(BeginInputTransaction(mDispatcher)))) {
mIMERanges->Clear();
return;
return false;
}
mDispatcher->SetPendingComposition(string, mIMERanges);
mDispatcher->FlushPendingComposition(status);
mIMERanges->Clear();
return compositionChanged;
}
void
@ -1330,7 +1356,8 @@ GeckoEditableSupport::NotifyIME(TextEventDispatcher* aTextEventDispatcher,
RefPtr<GeckoEditableSupport> self(this);
nsAppShell::PostEvent([this, self] {
if (!mIMEFocusCount) {
mIMEActiveReplaceTextCount = 0;
mIMEDelaySynchronizeReply = false;
mIMEActiveSynchronizeCount = 0;
mEditable->NotifyIME(EditableListener::NOTIFY_IME_OF_BLUR);
OnRemovedFrom(mDispatcher);
}
@ -1383,7 +1410,7 @@ GeckoEditableSupport::OnRemovedFrom(TextEventDispatcher* aTextEventDispatcher)
{
mDispatcher = nullptr;
if (mIsRemote) {
if (mIsRemote && mEditable->HasEditableParent()) {
// When we're remote, detach every time.
OnDetach(NS_NewRunnableFunction("GeckoEditableSupport::OnRemovedFrom",
[editable = java::GeckoEditableChild::GlobalRef(mEditable)] {
@ -1425,27 +1452,34 @@ GeckoEditableSupport::SetInputContext(const InputContext& aContext,
return;
}
const bool inPrivateBrowsing = mInputContext.mInPrivateBrowsing;
// Post an event to keep calls in order relative to NotifyIME.
nsAppShell::PostEvent([this, self = RefPtr<GeckoEditableSupport>(this),
context = mInputContext, action = aAction] {
nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget || widget->Destroyed()) {
return;
}
NotifyIMEContext(context, action);
});
}
void
GeckoEditableSupport::NotifyIMEContext(const InputContext& aContext,
const InputContextAction& aAction)
{
const bool inPrivateBrowsing = aContext.mInPrivateBrowsing;
const bool isUserAction =
aAction.IsHandlingUserInput() || aContext.mHasHandledUserInput;
const int32_t flags =
(inPrivateBrowsing ? EditableListener::IME_FLAG_PRIVATE_BROWSING : 0) |
(isUserAction ? EditableListener::IME_FLAG_USER_ACTION : 0);
// Post an event to keep calls in order relative to NotifyIME.
nsAppShell::PostEvent([this, self = RefPtr<GeckoEditableSupport>(this),
flags, context = mInputContext] {
nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget || widget->Destroyed()) {
return;
}
mEditable->NotifyIMEContext(context.mIMEState.mEnabled,
context.mHTMLInputType,
context.mHTMLInputInputmode,
context.mActionHint,
flags);
});
mEditable->NotifyIMEContext(aContext.mIMEState.mEnabled,
aContext.mHTMLInputType,
aContext.mHTMLInputInputmode,
aContext.mActionHint,
flags);
}
InputContext
@ -1456,5 +1490,89 @@ GeckoEditableSupport::GetInputContext()
return context;
}
void
GeckoEditableSupport::TransferParent(jni::Object::Param aEditableParent)
{
mEditable->SetParent(aEditableParent);
// If we are already focused, make sure the new parent has our token
// and focus information, so it can accept additional calls from us.
if (mIMEFocusCount > 0) {
mEditable->NotifyIME(EditableListener::NOTIFY_IME_OF_TOKEN);
NotifyIMEContext(mInputContext, InputContextAction());
mEditable->NotifyIME(EditableListener::NOTIFY_IME_OF_FOCUS);
}
if (mIsRemote && !mDispatcher) {
// Detach now if we were only attached temporarily.
OnRemovedFrom(/* dispatcher */ nullptr);
}
}
void
GeckoEditableSupport::SetOnTabChild(dom::TabChild* aTabChild)
{
MOZ_ASSERT(!XRE_IsParentProcess());
NS_ENSURE_TRUE_VOID(aTabChild);
const dom::ContentChild* const contentChild =
dom::ContentChild::GetSingleton();
RefPtr<widget::PuppetWidget> widget(aTabChild->WebWidget());
NS_ENSURE_TRUE_VOID(contentChild && widget);
// Get the content/tab ID in order to get the correct
// IGeckoEditableParent object, which GeckoEditableChild uses to
// communicate with the parent process.
const uint64_t contentId = contentChild->GetID();
const uint64_t tabId = aTabChild->GetTabId();
NS_ENSURE_TRUE_VOID(contentId && tabId);
RefPtr<widget::TextEventDispatcherListener> listener =
widget->GetNativeTextEventDispatcherListener();
if (!listener || listener.get() ==
static_cast<widget::TextEventDispatcherListener*>(widget)) {
// We need to set a new listener.
const auto editableChild = java::GeckoEditableChild::New(
/* parent */ nullptr, /* default */ false);
RefPtr<widget::GeckoEditableSupport> editableSupport =
new widget::GeckoEditableSupport(editableChild);
// Tell PuppetWidget to use our listener for IME operations.
widget->SetNativeTextEventDispatcherListener(editableSupport);
// Temporarily attach so we can receive the initial editable parent.
AttachNative(editableChild, editableSupport);
editableSupport->mEditableAttached = true;
// Connect the new child to a parent that corresponds to the TabChild.
java::GeckoServiceChildProcess::GetEditableParent(
editableChild, contentId, tabId);
return;
}
// We need to update the existing listener to use the new parent.
// We expect the existing TextEventDispatcherListener to be a
// GeckoEditableSupport object, so we perform a sanity check to make
// sure, by comparing their respective vtable pointers.
const RefPtr<widget::GeckoEditableSupport> dummy =
new widget::GeckoEditableSupport(/* child */ nullptr);
NS_ENSURE_TRUE_VOID(*reinterpret_cast<const uintptr_t*>(listener.get()) ==
*reinterpret_cast<const uintptr_t*>(dummy.get()));
const auto support =
static_cast<widget::GeckoEditableSupport*>(listener.get());
if (!support->mEditableAttached) {
// Temporarily attach so we can receive the initial editable parent.
AttachNative(support->GetJavaEditable(), support);
support->mEditableAttached = true;
}
// Transfer to a new parent that corresponds to the TabChild.
java::GeckoServiceChildProcess::GetEditableParent(
support->GetJavaEditable(), contentId, tabId);
}
} // namespace widget
} // namespace mozilla

Просмотреть файл

@ -21,6 +21,10 @@ namespace mozilla {
class TextComposition;
namespace dom {
class TabChild;
}
namespace widget {
class GeckoEditableSupport final
@ -92,7 +96,8 @@ class GeckoEditableSupport final
RefPtr<TextRangeArray> mIMERanges;
int32_t mIMEMaskEventsCount; // Mask events when > 0.
int32_t mIMEFocusCount; // We are focused when > 0.
int32_t mIMEActiveReplaceTextCount; // We still need to reply when > 0.
bool mIMEDelaySynchronizeReply; // We reply asynchronously when true.
int32_t mIMEActiveSynchronizeCount; // The number of replies being delayed.
bool mIMESelectionChanged;
bool mIMETextChangedDuringFlush;
bool mIMEMonitorCursor;
@ -118,7 +123,7 @@ class GeckoEditableSupport final
virtual ~GeckoEditableSupport() {}
RefPtr<TextComposition> GetComposition() const;
void RemoveComposition(
bool RemoveComposition(
RemoveCompositionFlag aFlag = COMMIT_IME_COMPOSITION);
void SendIMEDummyKeyEvent(nsIWidget* aWidget, EventMessage msg);
void AddIMETextChange(const IMETextChange& aChange);
@ -128,6 +133,9 @@ class GeckoEditableSupport final
void AsyncNotifyIME(int32_t aNotification);
void UpdateCompositionRects();
bool DoReplaceText(int32_t aStart, int32_t aEnd, jni::String::Param aText);
bool DoUpdateComposition(int32_t aStart, int32_t aEnd, int32_t aFlags);
void NotifyIMEContext(const InputContext& aContext,
const InputContextAction& aAction);
public:
template<typename Functor>
@ -162,6 +170,8 @@ public:
std::move(aCall)));
}
static void SetOnTabChild(dom::TabChild* aTabChild);
// Constructor for main process GeckoEditableChild.
GeckoEditableSupport(nsWindow::NativePtr<GeckoEditableSupport>* aPtr,
nsWindow* aWindow,
@ -173,7 +183,8 @@ public:
, mIMERanges(new TextRangeArray())
, mIMEMaskEventsCount(1) // Mask IME events since there's no focus yet
, mIMEFocusCount(0)
, mIMEActiveReplaceTextCount(0)
, mIMEDelaySynchronizeReply(false)
, mIMEActiveSynchronizeCount(0)
, mIMESelectionChanged(false)
, mIMETextChangedDuringFlush(false)
, mIMEMonitorCursor(false)
@ -225,6 +236,9 @@ public:
});
}
// Transfer to a new parent.
void TransferParent(jni::Object::Param aEditableParent);
// Handle an Android KeyEvent.
void OnKeyEvent(int32_t aAction, int32_t aKeyCode, int32_t aScanCode,
int32_t aMetaState, int32_t aKeyPressMetaState,

Просмотреть файл

@ -42,18 +42,16 @@ class GeckoProcessManager final
}
public:
static jni::Object::LocalRef
GetEditableParent(int64_t aContentId, int64_t aTabId)
static void
GetEditableParent(jni::Object::Param aEditableChild,
int64_t aContentId, int64_t aTabId)
{
// On binder thread.
jni::Object::GlobalRef ret;
nsAppShell::SyncRunEvent([aContentId, aTabId, &ret] {
nsCOMPtr<nsIWidget> widget = GetWidget(aContentId, aTabId);
if (widget) {
ret = static_cast<nsWindow*>(widget.get())->GetEditableParent();
}
});
return ret;
nsCOMPtr<nsIWidget> widget = GetWidget(aContentId, aTabId);
if (widget && widget->GetNativeData(NS_NATIVE_WIDGET) == widget) {
java::GeckoProcessManager::SetEditableChildParent(
aEditableChild,
static_cast<nsWindow*>(widget.get())->GetEditableParent());
}
}
};

Просмотреть файл

@ -22,7 +22,6 @@
#include "nsIDOMWakeLockListener.h"
#include "nsIPowerManagerService.h"
#include "nsISpeculativeConnect.h"
#include "nsITabChild.h"
#include "nsIURIFixup.h"
#include "nsCategoryManagerUtils.h"
#include "nsCDefaultURIFixup.h"
@ -553,6 +552,7 @@ nsAppShell::Init()
obsServ->AddObserver(this, "chrome-document-loaded", false);
} else {
obsServ->AddObserver(this, "content-document-global-created", false);
obsServ->AddObserver(this, "geckoview-content-global-transferred", false);
}
}
@ -678,38 +678,15 @@ nsAppShell::Observe(nsISupports* aSubject,
nsPIDOMWindowOuter::From(domWindow));
NS_ENSURE_TRUE(domWidget, NS_OK);
dom::ContentChild* contentChild = dom::ContentChild::GetSingleton();
dom::TabChild* tabChild = domWidget->GetOwningTabChild();
RefPtr<widget::PuppetWidget> widget(tabChild->WebWidget());
NS_ENSURE_TRUE(contentChild && tabChild && widget, NS_OK);
widget::GeckoEditableSupport::SetOnTabChild(
domWidget->GetOwningTabChild());
widget::TextEventDispatcherListener* listener =
widget->GetNativeTextEventDispatcherListener();
if (listener && listener !=
static_cast<widget::TextEventDispatcherListener*>(widget)) {
// We already set a listener before.
return NS_OK;
}
// Get the content/tab ID in order to get the correct
// IGeckoEditableParent object, which GeckoEditableChild uses to
// communicate with the parent process.
const uint64_t contentId = contentChild->GetID();
const uint64_t tabId = tabChild->GetTabId();
NS_ENSURE_TRUE(contentId && tabId, NS_OK);
auto editableParent = java::GeckoServiceChildProcess::GetEditableParent(
contentId, tabId);
NS_ENSURE_TRUE(editableParent, NS_OK);
auto editableChild = java::GeckoEditableChild::New(editableParent);
NS_ENSURE_TRUE(editableChild, NS_OK);
RefPtr<widget::GeckoEditableSupport> editableSupport =
new widget::GeckoEditableSupport(editableChild);
// Tell PuppetWidget to use our listener for IME operations.
widget->SetNativeTextEventDispatcherListener(editableSupport);
} else if (!strcmp(aTopic, "geckoview-content-global-transferred")) {
// We're transferring to a new GeckoEditableParent, so notify the
// existing GeckoEditableChild instance associated with the docshell.
nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(aSubject);
widget::GeckoEditableSupport::SetOnTabChild(
dom::TabChild::GetFrom(docShell));
}
if (removeObserver) {

Просмотреть файл

@ -361,8 +361,7 @@ public:
jni::Object::Param aInitData);
void AttachEditable(const GeckoSession::Window::LocalRef& inst,
jni::Object::Param aEditableParent,
jni::Object::Param aEditableChild);
jni::Object::Param aEditableParent);
void AttachAccessibility(const GeckoSession::Window::LocalRef& inst,
jni::Object::Param aSessionAccessibility);
@ -1362,18 +1361,16 @@ nsWindow::GeckoViewSupport::Transfer(const GeckoSession::Window::LocalRef& inst,
void
nsWindow::GeckoViewSupport::AttachEditable(const GeckoSession::Window::LocalRef& inst,
jni::Object::Param aEditableParent,
jni::Object::Param aEditableChild)
jni::Object::Param aEditableParent)
{
java::GeckoEditableChild::LocalRef editableChild(inst.Env());
editableChild = java::GeckoEditableChild::Ref::From(aEditableChild);
if (window.mEditableSupport) {
window.mEditableSupport.Detach(
window.mEditableSupport->GetJavaEditable());
if (!window.mEditableSupport) {
auto editableChild = java::GeckoEditableChild::New(aEditableParent,
/* default */ true);
window.mEditableSupport.Attach(editableChild, &window, editableChild);
} else {
window.mEditableSupport->TransferParent(aEditableParent);
}
window.mEditableSupport.Attach(editableChild, &window, editableChild);
window.mEditableParent = aEditableParent;
}