Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
tails
thunderbird
Commits
406f9d79
Commit
406f9d79
authored
Feb 05, 2021
by
Carsten Schoenert
Browse files
New upstream version 78.7.1
parent
5cce2060
Changes
123
Hide whitespace changes
Inline
Side-by-side
comm/mail/app/profile/all-thunderbird.js
View file @
406f9d79
...
...
@@ -104,7 +104,7 @@ pref("datareporting.policy.firstRunURL", "https://www.mozilla.org/thunderbird/le
#
endif
// Base URL for web-based support pages.
pref
(
"
app.support.baseURL
"
,
"
https://support.thunderbird.net/%
LOCALE%/%APP%/%APPBUILDID
%/
"
);
pref
(
"
app.support.baseURL
"
,
"
https://support.thunderbird.net/%
APP%/%VERSION%/%OS%/%LOCALE
%/
"
);
// Base url for web-based feedback pages.
pref
(
"
app.feedback.baseURL
"
,
"
https://input.mozilla.org/%LOCALE%/feedback/%APP%/%VERSION%/
"
);
...
...
comm/mail/base/content/gloda-autocomplete-input.js
View file @
406f9d79
...
...
@@ -28,9 +28,6 @@ customElements.whenDefined("autocomplete-input").then(() => {
const
{
GlodaIMSearcher
}
=
ChromeUtils
.
import
(
"
resource:///modules/search_im.jsm
"
);
const
{
XPCOMUtils
}
=
ChromeUtils
.
import
(
"
resource://gre/modules/XPCOMUtils.jsm
"
);
/**
* The MozGlodaAutocompleteInput widget is used to display the autocomplete search bar.
...
...
@@ -80,17 +77,6 @@ customElements.whenDefined("autocomplete-input").then(() => {
super
.
connectedCallback
();
this
.
setAttribute
(
"
is
"
,
"
gloda-autocomplete-input
"
);
XPCOMUtils
.
defineLazyPreferenceGetter
(
this
,
"
glodaEnabled
"
,
"
mailnews.database.global.indexer.enabled
"
,
true
,
(
pref
,
oldVal
,
newVal
)
=>
{
this
.
toggleAttribute
(
"
hidden
"
,
!
newVal
);
}
);
this
.
glodaCompleter
=
null
;
// @implements {nsIObserver}
...
...
@@ -175,8 +161,6 @@ customElements.whenDefined("autocomplete-input").then(() => {
"
autocomplete-did-enter-text
"
);
this
.
toggleAttribute
(
"
hidden
"
,
!
this
.
glodaEnabled
);
// make sure we set our emptytext here from the get-go
if
(
this
.
hasAttribute
(
"
placeholder
"
))
{
this
.
placeholder
=
this
.
getAttribute
(
"
placeholder
"
);
...
...
comm/mail/base/content/mailWidgets.js
View file @
406f9d79
...
...
@@ -2137,12 +2137,13 @@
});
input
.
addEventListener
(
"
keyup
"
,
event
=>
{
// Trigger the onRecipientsChanged method for every letter typed
in
// order to properly update the "Send" button and trigger
the save as
// draft prompt even before the creation of any pill.
// Trigger the onRecipientsChanged method for every letter typed
or
//
deleted in
order to properly update the "Send" button and trigger
//
the save as
draft prompt even before the creation of any pill.
if
(
event
.
key
.
length
==
1
||
(
event
.
key
.
length
>
1
&&
/
[^
a-zA-Z0-9
]
/
.
test
(
event
.
key
))
(
event
.
key
.
length
>
1
&&
/
[^
a-zA-Z0-9
]
/
.
test
(
event
.
key
))
||
[
"
Backspace
"
,
"
Delete
"
].
includes
(
event
.
key
)
)
{
onRecipientsChanged
(
false
);
}
...
...
comm/mail/base/content/mainMailToolbox.inc.xhtml
View file @
406f9d79
...
...
@@ -325,7 +325,7 @@
title=
"&glodaSearch.title;"
align=
"center"
flex=
"1"
class=
"chromeclass-toolbar-additional"
>
class=
"
gloda-search-widget
chromeclass-toolbar-additional"
>
<image
class=
"search-icon"
/>
<html:input
is=
"gloda-autocomplete-input"
id=
"searchInput"
type=
"text"
...
...
comm/mail/base/content/msgMail3PaneWindow.js
View file @
406f9d79
...
...
@@ -682,6 +682,22 @@ function OnLoadMessenger() {
document
.
getElementById
(
"
multimessage
"
)
);
// Depending on the pref, hide/show the gloda toolbar search widgets.
XPCOMUtils
.
defineLazyPreferenceGetter
(
this
,
"
gGlodaEnabled
"
,
"
mailnews.database.global.indexer.enabled
"
,
true
,
(
pref
,
oldVal
,
newVal
)
=>
{
for
(
let
widget
of
document
.
querySelectorAll
(
"
.gloda-search-widget
"
))
{
widget
.
hidden
=
!
newVal
;
}
}
);
for
(
let
widget
of
document
.
querySelectorAll
(
"
.gloda-search-widget
"
))
{
widget
.
hidden
=
!
this
.
gGlodaEnabled
;
}
window
.
addEventListener
(
"
AppCommand
"
,
HandleAppCommandEvent
,
true
);
// Set up the appmenus. (This has to happen after the DOM has loaded.)
...
...
comm/mail/base/modules/ExtensionsUI.jsm
View file @
406f9d79
...
...
@@ -886,6 +886,30 @@ var ExtensionsUI = {
});
}
// Reject add-ons using the legacy API. We cannot use the general "ignore
// unknown APIs" policy, as add-ons using the Legacy API from TB68 will
// not do anything, confusing the user.
if (data.manifest.legacy) {
let subject = {
wrappedJSObject: {
browser,
originatingURI: null,
installs: [
{
addon: info.addon,
name: info.addon.name,
error: 0,
},
],
install: null,
cancel: null,
},
};
Services.obs.notifyObservers(subject, "addon-install-failed");
info.reject();
return;
}
this.showPermissionsPrompt(browser, strings, info.icon, histkey).then(
answer => {
if (answer) {
...
...
comm/mail/base/modules/ThemeVariableMap.jsm
View file @
406f9d79
...
...
@@ -248,6 +248,12 @@ const ThemeVariableMap = [
lwtProperty: "sidebar_border",
},
],
[
"--sidebar-highlight-border-color",
{
lwtProperty: "sidebar_highlight_border",
},
],
];
const ThemeContentPropertyList = [
...
...
comm/mail/components/activity/content/activity-widgets.js
View file @
406f9d79
...
...
@@ -611,7 +611,7 @@
<label crop="center" flex="1" class="displayText"></label>
<label class="dateTime"></label>
<button class="recover mini-button"
tooltiptext="&cmd.recover.label"
tooltiptext="&cmd.recover.label
;
"
cmd="cmd_recover"
ondblclick="event.stopPropagation();"
oncommand="activity.recoveryHandler.recover(activity);">
...
...
comm/mail/components/addrbook/test/browser/browser.ini
View file @
406f9d79
...
...
@@ -11,6 +11,7 @@ subsuite = thunderbird
tags
=
addrbook
[browser_cardDAV_init.js]
[browser_cardDAV_properties.js]
[browser_cardDAV_sync.js]
[browser_contact_tree.js]
[browser_directory_tree.js]
...
...
comm/mail/components/addrbook/test/browser/browser_cardDAV_properties.js
0 → 100644
View file @
406f9d79
/* 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/. */
/**
* Tests CardDAV properties dialog.
*/
const
{
CardDAVDirectory
}
=
ChromeUtils
.
import
(
"
resource:///modules/CardDAVDirectory.jsm
"
);
const
{
CardDAVServer
}
=
ChromeUtils
.
import
(
"
resource://testing-common/CardDAVServer.jsm
"
);
add_task
(
async
()
=>
{
const
INTERVAL_PREF
=
"
ldap_2.servers.props.carddav.syncinterval
"
;
const
TOKEN_PREF
=
"
ldap_2.servers.props.carddav.token
"
;
const
TOKEN_VALUE
=
"
http://mochi.test/sync/0
"
;
const
URL_PREF
=
"
ldap_2.servers.props.carddav.url
"
;
const
URL_VALUE
=
"
https://mochi.test/carddav/test
"
;
let
dirPrefId
=
MailServices
.
ab
.
newAddressBook
(
"
props
"
,
undefined
,
102
);
Assert
.
equal
(
dirPrefId
,
"
ldap_2.servers.props
"
);
Assert
.
equal
([...
MailServices
.
ab
.
directories
].
length
,
3
);
let
directory
=
MailServices
.
ab
.
getDirectoryFromId
(
dirPrefId
);
let
davDirectory
=
CardDAVDirectory
.
forFile
(
directory
.
fileName
);
registerCleanupFunction
(
async
()
=>
{
let
removePromise
=
promiseDirectoryRemoved
();
MailServices
.
ab
.
deleteAddressBook
(
directory
.
URI
);
await
removePromise
;
Assert
.
equal
(
davDirectory
.
_syncTimer
,
null
,
"
sync timer cleaned up
"
);
});
Assert
.
equal
(
directory
.
dirType
,
102
);
Services
.
prefs
.
setIntPref
(
INTERVAL_PREF
,
0
);
Services
.
prefs
.
setStringPref
(
TOKEN_PREF
,
TOKEN_VALUE
);
Services
.
prefs
.
setStringPref
(
URL_PREF
,
URL_VALUE
);
Assert
.
ok
(
davDirectory
);
Assert
.
equal
(
davDirectory
.
_serverURL
,
URL_VALUE
);
Assert
.
equal
(
davDirectory
.
_syncToken
,
TOKEN_VALUE
);
Assert
.
equal
(
davDirectory
.
_syncTimer
,
null
,
"
no sync scheduled
"
);
Assert
.
equal
(
davDirectory
.
readOnly
,
false
);
let
abWindow
=
await
openAddressBookWindow
();
let
abDocument
=
abWindow
.
document
;
registerCleanupFunction
(
async
()
=>
{
await
closeAddressBookWindow
();
Services
.
prefs
.
clearUserPref
(
"
mail.addr_book.view.startupURI
"
);
});
// This test becomes unreliable if we don't pause for a moment.
await
new
Promise
(
resolve
=>
abWindow
.
setTimeout
(
resolve
,
500
));
openDirectory
(
directory
);
Assert
.
equal
(
abWindow
.
gDirectoryTreeView
.
rowCount
,
4
);
Assert
.
equal
(
abWindow
.
gDirectoryTreeView
.
getIndexForId
(
directory
.
URI
),
2
);
Assert
.
equal
(
abWindow
.
gDirTree
.
currentIndex
,
2
);
let
menu
=
abDocument
.
getElementById
(
"
dirTreeContext
"
);
let
menuItem
=
abDocument
.
getElementById
(
"
dirTreeContext-properties
"
);
let
subtest
=
async
function
(
expectedValues
,
newValues
,
buttonAction
)
{
let
shownPromise
=
BrowserTestUtils
.
waitForEvent
(
menu
,
"
popupshown
"
);
mailTestUtils
.
treeClick
(
EventUtils
,
abWindow
,
abWindow
.
gDirTree
,
2
,
0
,
{
type
:
"
mousedown
"
,
button
:
2
,
});
mailTestUtils
.
treeClick
(
EventUtils
,
abWindow
,
abWindow
.
gDirTree
,
2
,
0
,
{
type
:
"
contextmenu
"
,
});
mailTestUtils
.
treeClick
(
EventUtils
,
abWindow
,
abWindow
.
gDirTree
,
2
,
0
,
{
type
:
"
mouseup
"
,
button
:
2
,
});
await
shownPromise
;
Assert
.
equal
(
abWindow
.
gDirTree
.
currentIndex
,
2
);
let
dialogPromise
=
BrowserTestUtils
.
promiseAlertDialog
(
undefined
,
"
chrome://messenger/content/addressbook/abCardDAVProperties.xhtml
"
,
async
dialogWindow
=>
{
let
dialogDocument
=
dialogWindow
.
document
;
let
nameInput
=
dialogDocument
.
getElementById
(
"
carddav-name
"
);
Assert
.
equal
(
nameInput
.
value
,
expectedValues
.
name
);
if
(
"
name
"
in
newValues
)
{
nameInput
.
value
=
newValues
.
name
;
}
let
urlInput
=
dialogDocument
.
getElementById
(
"
carddav-url
"
);
Assert
.
equal
(
urlInput
.
value
,
expectedValues
.
url
);
if
(
"
url
"
in
newValues
)
{
urlInput
.
value
=
newValues
.
url
;
}
let
refreshActiveInput
=
dialogDocument
.
getElementById
(
"
carddav-refreshActive
"
);
let
refreshIntervalInput
=
dialogDocument
.
getElementById
(
"
carddav-refreshInterval
"
);
Assert
.
equal
(
refreshActiveInput
.
checked
,
expectedValues
.
refreshActive
);
Assert
.
equal
(
refreshIntervalInput
.
disabled
,
!
expectedValues
.
refreshActive
);
if
(
"
refreshActive
"
in
newValues
&&
newValues
.
refreshActive
!=
expectedValues
.
refreshActive
)
{
EventUtils
.
synthesizeMouseAtCenter
(
refreshActiveInput
,
{},
dialogWindow
);
Assert
.
equal
(
refreshIntervalInput
.
disabled
,
!
newValues
.
refreshActive
);
}
Assert
.
equal
(
refreshIntervalInput
.
value
,
expectedValues
.
refreshInterval
);
if
(
"
refreshInterval
"
in
newValues
)
{
refreshIntervalInput
.
value
=
newValues
.
refreshInterval
;
}
let
readOnlyInput
=
dialogDocument
.
getElementById
(
"
carddav-readOnly
"
);
Assert
.
equal
(
readOnlyInput
.
checked
,
expectedValues
.
readOnly
);
if
(
"
readOnly
"
in
newValues
)
{
readOnlyInput
.
checked
=
newValues
.
readOnly
;
}
dialogDocument
.
querySelector
(
"
dialog
"
)
.
getButton
(
buttonAction
)
.
click
();
}
);
EventUtils
.
synthesizeMouseAtCenter
(
menuItem
,
{},
abWindow
);
await
dialogPromise
;
await
new
Promise
(
resolve
=>
abWindow
.
setTimeout
(
resolve
));
};
info
(
"
Open the dialog and cancel it. Nothing should change.
"
);
await
subtest
(
{
name
:
"
props
"
,
url
:
URL_VALUE
,
refreshActive
:
false
,
refreshInterval
:
30
,
readOnly
:
false
,
},
{},
"
cancel
"
);
Assert
.
equal
(
davDirectory
.
dirName
,
"
props
"
);
Assert
.
equal
(
davDirectory
.
_serverURL
,
URL_VALUE
);
Assert
.
equal
(
davDirectory
.
getIntValue
(
"
carddav.syncinterval
"
,
-
1
),
0
);
Assert
.
equal
(
davDirectory
.
_syncTimer
,
null
,
"
no sync scheduled
"
);
Assert
.
equal
(
davDirectory
.
readOnly
,
false
);
info
(
"
Open the dialog and accept it. Nothing should change.
"
);
await
subtest
(
{
name
:
"
props
"
,
url
:
URL_VALUE
,
refreshActive
:
false
,
refreshInterval
:
30
,
readOnly
:
false
,
},
{},
"
accept
"
);
Assert
.
equal
(
davDirectory
.
dirName
,
"
props
"
);
Assert
.
equal
(
davDirectory
.
_serverURL
,
URL_VALUE
);
Assert
.
equal
(
davDirectory
.
getIntValue
(
"
carddav.syncinterval
"
,
-
1
),
0
);
Assert
.
equal
(
davDirectory
.
_syncTimer
,
null
,
"
no sync scheduled
"
);
Assert
.
equal
(
davDirectory
.
readOnly
,
false
);
info
(
"
Open the dialog and change the values.
"
);
await
subtest
(
{
name
:
"
props
"
,
url
:
URL_VALUE
,
refreshActive
:
false
,
refreshInterval
:
30
,
readOnly
:
false
,
},
{
name
:
"
CardDAV Properties Test
"
,
refreshActive
:
true
,
refreshInterval
:
30
,
readOnly
:
true
,
},
"
accept
"
);
Assert
.
equal
(
davDirectory
.
dirName
,
"
CardDAV Properties Test
"
);
Assert
.
equal
(
davDirectory
.
_serverURL
,
URL_VALUE
);
Assert
.
equal
(
davDirectory
.
getIntValue
(
"
carddav.syncinterval
"
,
-
1
),
30
);
Assert
.
notEqual
(
davDirectory
.
_syncTimer
,
null
,
"
sync scheduled
"
);
let
currentSyncTimer
=
davDirectory
.
_syncTimer
;
Assert
.
equal
(
davDirectory
.
readOnly
,
true
);
info
(
"
Open the dialog and accept it. Nothing should change.
"
);
await
subtest
(
{
name
:
"
CardDAV Properties Test
"
,
url
:
URL_VALUE
,
refreshActive
:
true
,
refreshInterval
:
30
,
readOnly
:
true
,
},
{},
"
accept
"
);
Assert
.
equal
(
davDirectory
.
dirName
,
"
CardDAV Properties Test
"
);
Assert
.
equal
(
davDirectory
.
_serverURL
,
URL_VALUE
);
Assert
.
equal
(
davDirectory
.
getIntValue
(
"
carddav.syncinterval
"
,
-
1
),
30
);
Assert
.
equal
(
davDirectory
.
_syncTimer
,
currentSyncTimer
,
"
same sync scheduled
"
);
Assert
.
equal
(
davDirectory
.
readOnly
,
true
);
info
(
"
Open the dialog and change the interval.
"
);
await
subtest
(
{
name
:
"
CardDAV Properties Test
"
,
url
:
URL_VALUE
,
refreshActive
:
true
,
refreshInterval
:
30
,
readOnly
:
true
,
},
{
refreshInterval
:
60
},
"
accept
"
);
Assert
.
equal
(
davDirectory
.
dirName
,
"
CardDAV Properties Test
"
);
Assert
.
equal
(
davDirectory
.
_serverURL
,
URL_VALUE
);
Assert
.
equal
(
davDirectory
.
getIntValue
(
"
carddav.syncinterval
"
,
-
1
),
60
);
Assert
.
greater
(
davDirectory
.
_syncTimer
,
currentSyncTimer
,
"
new sync scheduled
"
);
Assert
.
equal
(
davDirectory
.
readOnly
,
true
);
});
comm/mail/components/compose/content/MsgComposeCommands.js
View file @
406f9d79
...
...
@@ -4036,7 +4036,9 @@ function ComposeLoad() {
attachmentBucketMarkEmptyBucket
();
updateAriaLabelsAndTooltipsOfAllAddressRows
();
for
(
let
input
of
document
.
querySelectorAll
(
"
.address-input
"
))
{
for
(
let
input
of
document
.
querySelectorAll
(
"
.address-input[recipienttype]
"
))
{
input
.
onBeforeHandleKeyDown
=
event
=>
addressInputOnBeforeHandleKeyDown
(
event
);
}
...
...
@@ -4896,7 +4898,7 @@ function updateSendLock() {
`input[is="autocomplete-input"][recipienttype]`
);
if
(
input
.
value
.
trim
()
&&
isValidAddress
(
input
.
value
.
trim
()))
{
if
(
input
?
.
value
.
trim
()
&&
isValidAddress
(
input
.
value
.
trim
()))
{
gSendLocked
=
false
;
break
;
}
...
...
@@ -4965,7 +4967,7 @@ function pillifyRecipients() {
);
// If we find a leftover string in the input field, create a pill. If the
// newly created pill is not a valid address, the sending will stop.
if
(
input
.
value
.
trim
())
{
if
(
input
?
.
value
.
trim
())
{
recipientAddPills
(
input
);
}
}
...
...
@@ -7481,9 +7483,16 @@ function fromKeyPress(event) {
row
.
querySelector
(
`input[is="autocomplete-input"][recipienttype]`
).
focus
();
}
/**
* Handle the keypress event of the subject line.
*
* @param {Event} event - The DOM Event.
*/
function
subjectKeyPress
(
event
)
{
gSubjectChanged
=
true
;
if
(
event
.
keyCode
==
KeyEvent
.
DOM_VK_RETURN
)
{
// Move the focus to the body only if the Enter key is pressed without any
// modifier, as that would mean the user wants to send the message.
if
(
event
.
key
==
"
Enter
"
&&
!
event
.
ctrlKey
&&
!
event
.
metaKey
)
{
SetMsgBodyFrameFocus
();
}
}
...
...
comm/mail/components/compose/content/addressingWidgetOverlay.js
View file @
406f9d79
...
...
@@ -562,6 +562,12 @@ function otherHeaderInputOnKeyDown(event) {
event
.
preventDefault
();
SetFocusOnNextAvailableElement
(
input
);
}
// macOS only variation to prevent the cursor from moving to the next
// element while sending.
if
(
event
.
metaKey
)
{
event
.
stopPropagation
();
}
break
;
case
"
Backspace
"
:
case
"
Delete
"
:
...
...
@@ -708,6 +714,14 @@ function addressInputOnBeforeHandleKeyDown(event) {
event
.
preventDefault
();
SetFocusOnNextAvailableElement
(
input
);
}
// macOS only variation necessary to send messages since autocomplete
// input fields prevent that by default.
if
(
event
.
metaKey
)
{
// Prevent the focus from moving to the next element.
event
.
stopPropagation
();
goDoCommand
(
"
cmd_sendWithCheck
"
);
}
break
;
case
"
Tab
"
:
...
...
comm/mail/components/extensions/jar.mn
View file @
406f9d79
...
...
@@ -33,6 +33,7 @@ messenger.jar:
content/messenger/parent/ext-messages.js (parent/ext-messages.js)
content/messenger/parent/ext-pkcs11.js (../../../../browser/components/extensions/parent/ext-pkcs11.js)
content/messenger/parent/ext-tabs.js (parent/ext-tabs.js)
content/messenger/parent/ext-theme.js (parent/ext-theme.js)
content/messenger/parent/ext-windows.js (parent/ext-windows.js)
content/messenger/schemas/accounts.json (schemas/accounts.json)
...
...
@@ -53,4 +54,8 @@ messenger.jar:
content/messenger/schemas/messages.json (schemas/messages.json)
content/messenger/schemas/pkcs11.json (../../../../browser/components/extensions/schemas/pkcs11.json)
content/messenger/schemas/tabs.json (schemas/tabs.json)
content/messenger/schemas/theme.json (schemas/theme.json)
content/messenger/schemas/windows.json (schemas/windows.json)
% override chrome://extensions/content/schemas/theme.json chrome://messenger/content/schemas/theme.json
% override chrome://extensions/content/parent/ext-theme.js chrome://messenger/content/parent/ext-theme.js
comm/mail/components/extensions/parent/ext-theme.js
0 → 100644
View file @
406f9d79
/* 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/. */
"
use strict
"
;
/* global windowTracker, EventManager, EventEmitter */
/* eslint-disable complexity */
var
{
Services
}
=
ChromeUtils
.
import
(
"
resource://gre/modules/Services.jsm
"
);
ChromeUtils
.
defineModuleGetter
(
this
,
"
LightweightThemeManager
"
,
"
resource://gre/modules/LightweightThemeManager.jsm
"
);
var
{
getWinUtils
}
=
ExtensionUtils
;
const
onUpdatedEmitter
=
new
EventEmitter
();
// Represents an empty theme for convenience of use
const
emptyTheme
=
{
details
:
{
colors
:
null
,
images
:
null
,
properties
:
null
},
};
let
defaultTheme
=
emptyTheme
;
// Map[windowId -> Theme instance]
let
windowOverrides
=
new
Map
();
/**
* Class representing either a global theme affecting all windows or an override on a specific window.
* Any extension updating the theme with a new global theme will replace the singleton defaultTheme.
*/
class
Theme
{
/**
* Creates a theme instance.
*
* @param {string} extension - Extension that created the theme.
* @param {Integer} windowId - The windowId where the theme is applied.
*/
constructor
({
extension
,
details
,
darkDetails
,
windowId
,
experiment
,
startupData
,
})
{
this
.
extension
=
extension
;
this
.
details
=
details
;
this
.
darkDetails
=
darkDetails
;
this
.
windowId
=
windowId
;
if
(
startupData
&&
startupData
.
lwtData
)
{
Object
.
assign
(
this
,
startupData
);
}
else
{
// TODO: Update this part after bug 1550090
this
.
lwtStyles
=
{};
this
.
lwtDarkStyles
=
null
;
if
(
darkDetails
)
{
this
.
lwtDarkStyles
=
{};
}
if
(
experiment
)
{
if
(
extension
.
experimentsAllowed
)
{
this
.
lwtStyles
.
experimental
=
{
colors
:
{},
images
:
{},