Commit d1e95406 authored by anonym's avatar anonym
Browse files

Merge tag 'debian/1%78.9.0-1_deb10u1' into tails/buster

thunderbird Debian release 1:78.9.0-1~deb10u1
parents 3241e651 4a0bf275
......@@ -3,9 +3,9 @@
# Please do not edit.
[source."https://github.com/shravanrn/nix/"]
branch = "r0.13.1"
git = "https://github.com/shravanrn/nix/"
replace-with = "vendored-sources"
rev = "4af6c367603869a30fddb5ffb0aba2b9477ba92e"
[source."https://github.com/mozilla/rkv"]
git = "https://github.com/mozilla/rkv"
......
......@@ -898,9 +898,9 @@ dependencies = [
[[package]]
name = "cssparser"
version = "0.27.2"
version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "754b69d351cdc2d8ee09ae203db831e005560fc6030da058f86ad60c92a9cb0a"
checksum = "809d22aba9ffd53e9028f2d37261f1826ef613d0e96b1a5ddeefa97cde82bcca"
dependencies = [
"cssparser-macros",
"dtoa-short",
......@@ -3200,7 +3200,7 @@ dependencies = [
[[package]]
name = "nix"
version = "0.13.1"
source = "git+https://github.com/shravanrn/nix/?branch=r0.13.1#4af6c367603869a30fddb5ffb0aba2b9477ba92e"
source = "git+https://github.com/shravanrn/nix/?rev=4af6c367603869a30fddb5ffb0aba2b9477ba92e#4af6c367603869a30fddb5ffb0aba2b9477ba92e"
dependencies = [
"bitflags",
"cc",
......@@ -3717,9 +3717,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.5"
version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90cf5f418035b98e655e9cdb225047638296b862b42411c4e45bb88d700f7fc0"
checksum = "175c513d55719db99da20232b06cda8bab6b83ec2d04e3283edf0213c37c1a29"
dependencies = [
"unicode-xid",
]
......@@ -4647,9 +4647,9 @@ dependencies = [
[[package]]
name = "syn"
version = "1.0.5"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "66850e97125af79138385e9b88339cbcd037e3f28ceab8c5ad98e64f0f1f80bf"
checksum = "963f7d3cc59b59b9325165add223142bbf1df27655d07789f109896d353d8350"
dependencies = [
"proc-macro2",
"quote",
......@@ -4792,12 +4792,9 @@ checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c"
[[package]]
name = "thin-vec"
version = "0.1.0"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73fdf4b84c65a85168477b7fb6c498e0716bc9487fba24623389ea7f51708044"
dependencies = [
"libc",
]
checksum = "3a93c9ade36a827a69257925808463db46ffcf193442fad01eb9bdc1d31aed81"
[[package]]
name = "thiserror"
......
......@@ -68,8 +68,8 @@ panic = "abort"
libudev-sys = { path = "dom/webauthn/libudev-sys" }
packed_simd = { git = "https://github.com/hsivonen/packed_simd", rev="3541e3818fdc7c2a24f87e3459151a4ce955a67a" }
rlbox_lucet_sandbox = { git = "https://github.com/PLSysSec/rlbox_lucet_sandbox/", rev="d510da5999a744c563b0acd18056069d1698273f" }
nix = { git = "https://github.com/shravanrn/nix/", branch = "r0.13.1", rev="4af6c367603869a30fddb5ffb0aba2b9477ba92e" }
spirv_cross = { git = "https://github.com/kvark/spirv_cross", branch = "wgpu3", rev = "20191ad2f370afd6d247edcb9ff9da32d3bedb9c" }
nix = { git = "https://github.com/shravanrn/nix/", rev="4af6c367603869a30fddb5ffb0aba2b9477ba92e" }
spirv_cross = { git = "https://github.com/kvark/spirv_cross", branch = "wgpu3" }
# failure's backtrace feature might break our builds, see bug 1608157.
failure = { git = "https://github.com/badboy/failure", rev = "64af847bc5fdcb6d2438bec8a6030812a80519a5" }
failure_derive = { git = "https://github.com/badboy/failure", rev = "64af847bc5fdcb6d2438bec8a6030812a80519a5" }
......
......@@ -67,7 +67,20 @@ Accessible* TableCellAccessible::PrevColHeader() {
// Check whether the previous table cell has a cached value.
cachedHeader = cache.GetWeak(tableCell, &inCache);
if (inCache && cell->Role() != roles::COLUMNHEADER) {
if (
// We check the cache first because even though we might not use it,
// it's faster than the other conditions.
inCache &&
// Only use the cached value if:
// 1. cell is a table cell which is not a column header. In that case,
// cell is the previous header and cachedHeader is the one before that.
// We will return cell later.
cell->Role() != roles::COLUMNHEADER &&
// 2. cell starts in this column. If it starts in a previous column and
// extends into this one, its header will be for the starting column,
// which is wrong for this cell.
// ColExtent is faster than ColIdx, so check that first.
(tableCell->ColExtent() == 1 || tableCell->ColIdx() == colIdx)) {
if (!cachedHeader || !cachedHeader->IsDefunct()) {
// Cache it for this cell.
cache.Put(this, RefPtr<Accessible>(cachedHeader));
......
......@@ -220,16 +220,23 @@ AccessibleHandler::MaybeUpdateCachedData() {
return E_POINTER;
}
// Clean up the old data.
CleanupDynamicIA2Data(mCachedData.mDynamicData,
mCachedDynamicDataMarshaledByCom);
HRESULT hr =
mCachedData.mGeckoBackChannel->Refresh(&mCachedData.mDynamicData);
// While we're making the outgoing COM call below, an incoming COM call can
// be handled which calls ReadHandlerPayload or re-enters this function.
// Therefore, we mustn't update the cached data directly lest it be mutated
// elsewhere before the outgoing COM call returns and cause corruption or
// memory leaks. Instead, pass a temporary struct and update the cached data
// only after this call completes.
DynamicIA2Data newData;
HRESULT hr = mCachedData.mGeckoBackChannel->Refresh(&newData);
if (SUCCEEDED(hr)) {
// Clean up the old data.
CleanupDynamicIA2Data(mCachedData.mDynamicData,
mCachedDynamicDataMarshaledByCom);
mCachedData.mDynamicData = newData;
mCachedDynamicDataMarshaledByCom = true;
// We just updated the cache, so update this object's cache generation
// so we only update the cache again after the next change.
mCacheGen = gen;
mCachedDynamicDataMarshaledByCom = true;
}
return hr;
}
......
......@@ -426,6 +426,37 @@
testHeaderCells(headerInfoMap);
// ////////////////////////////////////////////////////////////////////////
// Ensure correct column headers after colspan in a previous row.
headerInfoMap = [
{
cell: "t11r1c1",
columnHeaderCells: [],
rowHeaderCells: [],
},
{
cell: "t11r1c2",
columnHeaderCells: [],
rowHeaderCells: [],
},
{
cell: "t11r2c1_2",
columnHeaderCells: ["t11r1c1"],
rowHeaderCells: [],
},
{
cell: "t11r3c1",
columnHeaderCells: ["t11r1c1"],
rowHeaderCells: [],
},
{
cell: "t11r3c2",
columnHeaderCells: ["t11r1c2"],
rowHeaderCells: [],
},
];
testHeaderCells(headerInfoMap);
SimpleTest.finish();
}
......@@ -707,5 +738,19 @@
<td headers="t10_males t10_todd t10_10km" id="t10_r3c4">50:35</td>
</tr>
</table>
<table id="table11">
<tr>
<th id="t11r1c1">a</th>
<th id="t11r1c2">b</th>
</tr>
<tr>
<td id="t11r2c1_2" colspan="2"></td>
</tr>
<tr>
<td id="t11r3c1">e</td>
<td id="t11r3c2">f</td>
</tr>
</table>
</body>
</html>
......@@ -9,6 +9,49 @@ var EXPORTED_SYMBOLS = ["DOMFullscreenParent"];
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
class DOMFullscreenParent extends JSWindowActorParent {
waitingForChildFullscreen = false;
updateFullscreenWindowReference(aWindow) {
if (aWindow.document.documentElement.hasAttribute("inDOMFullscreen")) {
this._fullscreenWindow = aWindow;
} else {
delete this._fullscreenWindow;
}
}
didDestroy() {
let window = this._fullscreenWindow;
if (!window) {
return;
}
if (this.waitingForChildFullscreen) {
// We were killed while waiting for our DOMFullscreenChild
// to transition to fullscreen so we abort the entire
// fullscreen transition to prevent getting stuck in a
// partial fullscreen state. We need to go through the
// document since window.Fullscreen could be undefined
// at this point.
//
// This could reject if we're not currently in fullscreen
// so just ignore rejection.
window.document.exitFullscreen().catch(() => {});
return;
}
// Need to resume Chrome UI if the window is still in fullscreen UI
// to avoid the window stays in fullscreen problem. (See Bug 1620341)
if (window.document.documentElement.hasAttribute("inDOMFullscreen")) {
if (window.FullScreen) {
window.FullScreen.cleanupDomFullscreen(this);
}
if (window.windowUtils) {
window.windowUtils.remoteFrameFullscreenReverted();
}
}
this.updateFullscreenWindowReference(window);
}
receiveMessage(aMessage) {
let topBrowsingContext = this.browsingContext.top;
let browser = topBrowsingContext.embedderElement;
......@@ -37,7 +80,9 @@ class DOMFullscreenParent extends JSWindowActorParent {
break;
}
case "DOMFullscreen:Entered": {
this.waitingForChildFullscreen = false;
window.FullScreen.enterDomFullscreen(browser, this);
this.updateFullscreenWindowReference(window);
break;
}
case "DOMFullscreen:Exit": {
......@@ -46,6 +91,7 @@ class DOMFullscreenParent extends JSWindowActorParent {
}
case "DOMFullscreen:Exited": {
window.FullScreen.cleanupDomFullscreen(this);
this.updateFullscreenWindowReference(window);
break;
}
case "DOMFullscreen:Painted": {
......@@ -83,6 +129,7 @@ class DOMFullscreenParent extends JSWindowActorParent {
TelemetryStopwatch.start("FULLSCREEN_CHANGE_MS");
window.FullScreen.enterDomFullscreen(browser, this);
this.updateFullscreenWindowReference(window);
break;
}
case "MozDOMFullscreen:Exited": {
......@@ -97,6 +144,7 @@ class DOMFullscreenParent extends JSWindowActorParent {
this.requestOrigin = this;
}
window.FullScreen.cleanupDomFullscreen(this);
this.updateFullscreenWindowReference(window);
this.removeListeners(window);
break;
}
......
......@@ -345,7 +345,9 @@ var FullScreen = {
},
exitDomFullScreen() {
document.exitFullscreen();
if (document.fullscreen) {
document.exitFullscreen();
}
},
handleEvent(event) {
......@@ -418,12 +420,27 @@ var FullScreen = {
// before the check is fine since we also check the activeness of
// the requesting document in content-side handling code.
if (this._isRemoteBrowser(aBrowser)) {
if (
!this._sendMessageToTheRightContent(aActor, "DOMFullscreen:Entered")
) {
let [targetActor, inProcessBC] = this._getNextMsgRecipientActor(aActor);
if (!targetActor) {
// If there is no appropriate actor to send the message we have
// no way to complete the transition and should abort by exiting
// fullscreen.
this._abortEnterFullscreen();
return;
}
targetActor.sendAsyncMessage("DOMFullscreen:Entered", {
remoteFrameBC: inProcessBC,
});
// Record that the actor is waiting for its child to enter
// fullscreen so that if it dies we can abort.
targetActor.waitingForChildFullscreen = true;
if (inProcessBC) {
// We aren't messaging the request origin yet, skip this time.
return;
}
}
// If we've received a fullscreen notification, we have to ensure that the
// element that's requesting fullscreen belongs to the browser that's currently
// active. If not, we exit fullscreen since the "full-screen document" isn't
......@@ -435,9 +452,7 @@ var FullScreen = {
// full-screen was made. Cancel full-screen.
Services.focus.activeWindow != window
) {
// This function is called synchronously in fullscreen change, so
// we have to avoid calling exitFullscreen synchronously here.
setTimeout(() => document.exitFullscreen(), 0);
this._abortEnterFullscreen();
return;
}
......@@ -451,7 +466,6 @@ var FullScreen = {
this._logWarningPermissionPromptFS("promptCanceled");
}
}
document.documentElement.setAttribute("inDOMFullscreen", true);
if (gFindBarInitialized) {
......@@ -486,9 +500,25 @@ var FullScreen = {
}
},
/**
* Clean up full screen, starting from the request origin's first ancestor
* frame that is OOP.
*
* If there are OOP ancestor frames, we notify the first of those and then bail to
* be called again in that process when it has dealt with the change. This is
* repeated until all ancestor processes have been updated. Once that has happened
* we remove our handlers and attributes and notify the request origin to complete
* the cleanup.
*/
cleanupDomFullscreen(aActor) {
if (!this._sendMessageToTheRightContent(aActor, "DOMFullscreen:CleanUp")) {
return;
let [target, inProcessBC] = this._getNextMsgRecipientActor(aActor);
if (target) {
target.sendAsyncMessage("DOMFullscreen:CleanUp", {
remoteFrameBC: inProcessBC,
});
if (inProcessBC) {
return;
}
}
PopupNotifications.panel.removeEventListener(
......@@ -506,30 +536,47 @@ var FullScreen = {
document.documentElement.removeAttribute("inDOMFullscreen");
},
_abortEnterFullscreen() {
// This function is called synchronously in fullscreen change, so
// we have to avoid calling exitFullscreen synchronously here.
setTimeout(() => document.exitFullscreen(), 0);
if (TelemetryStopwatch.running("FULLSCREEN_CHANGE_MS")) {
// Cancel the stopwatch for any fullscreen change to avoid
// errors if it is started again.
TelemetryStopwatch.cancel("FULLSCREEN_CHANGE_MS");
}
},
/**
* Search for the first ancestor of aActor that lives in a different process.
* If found, that ancestor is sent the message. Otherwise, the recipient should
* be the actor of the request origin.
* If found, that ancestor actor and the browsing context for its child which
* was in process are returned. Otherwise [request origin, null].
*
*
* @param {JSWindowActorParent} aActor
* The actor that called this function.
* @param {String} message
* Message to be sent.
*
* @return {boolean}
* Return true if the message is sent to the request source
* or false otherwise.
* @return {[JSWindowActorParent, BrowsingContext]}
* The parent actor which should be sent the next msg and the
* in process browsing context which is its child. Will be
* [null, null] if there is no OOP parent actor and request origin
* is unset. [null, null] is also returned if the intended actor or
* the calling actor has been destroyed.
*/
_sendMessageToTheRightContent(aActor, aMessage) {
_getNextMsgRecipientActor(aActor) {
if (aActor.hasBeenDestroyed()) {
// Just restore the chrome UI when the actor is dead.
return true;
return [null, null];
}
let childBC = aActor.browsingContext;
let parentBC = childBC.parent;
// Walk up the browsing context tree from aActor's browsing context
// to find the first ancestor browsing context that's in a different process.
while (parentBC) {
if (!childBC.currentWindowGlobal || !parentBC.currentWindowGlobal) {
break;
}
let childPid = childBC.currentWindowGlobal.osPid;
let parentPid = parentBC.currentWindowGlobal.osPid;
......@@ -541,22 +588,20 @@ var FullScreen = {
}
}
if (parentBC) {
let parentActor = parentBC.currentWindowGlobal.getActor("DOMFullscreen");
parentActor.sendAsyncMessage(aMessage, {
remoteFrameBC: childBC,
});
return false;
let target = null;
let inProcessBC = null;
if (parentBC && parentBC.currentWindowGlobal) {
target = parentBC.currentWindowGlobal.getActor("DOMFullscreen");
inProcessBC = childBC;
} else {
target = aActor.requestOrigin;
}
// All content frames living outside the process where
// the element requesting fullscreen lives should
// have entered or exited fullscreen at this point.
// So let's notify the process where the original request
// comes from.
aActor.requestOrigin.sendAsyncMessage(aMessage, {});
aActor.requestOrigin = null;
return true;
if (!target || target.hasBeenDestroyed()) {
return [null, null];
}
return [target, inProcessBC];
},
_isRemoteBrowser(aBrowser) {
......
......@@ -1090,7 +1090,7 @@ var PlacesMenuDNDHandler = {
/**
* This object handles the initialization and uninitialization of the bookmarks
* toolbar.
* toolbar. It also has helper functions for the managed bookmarks button.
*/
var PlacesToolbarHelper = {
get _viewElt() {
......@@ -1218,6 +1218,89 @@ var PlacesToolbarHelper = {
this.init();
}
},
async populateManagedBookmarks(popup) {
if (popup.hasChildNodes()) {
return;
}
// Show item's uri in the status bar when hovering, and clear on exit
popup.addEventListener("DOMMenuItemActive", function(event) {
XULBrowserWindow.setOverLink(event.target.link);
});
popup.addEventListener("DOMMenuItemInactive", function() {
XULBrowserWindow.setOverLink("");
});
let fragment = document.createDocumentFragment();
await this.addManagedBookmarks(
fragment,
Services.policies.getActivePolicies().ManagedBookmarks
);
popup.appendChild(fragment);
},
async addManagedBookmarks(menu, children) {
for (let i = 0; i < children.length; i++) {
let entry = children[i];
if (entry.children) {
// It's a folder.
let submenu = document.createXULElement("menu");
if (entry.name) {
submenu.setAttribute("label", entry.name);
} else {
submenu.setAttribute("data-l10n-id", "managed-bookmarks-subfolder");
}
submenu.setAttribute("container", "true");
submenu.setAttribute("class", "menu-iconic bookmark-item");
let submenupopup = document.createXULElement("menupopup");
submenu.appendChild(submenupopup);
menu.appendChild(submenu);
this.addManagedBookmarks(submenupopup, entry.children);
} else if (entry.name && entry.url) {
// It's bookmark.
let uri = Services.uriFixup.createFixupURI(
entry.url,
Ci.nsIURIFixup.FIXUP_FLAG_NONE
);
let menuitem = document.createXULElement("menuitem");
menuitem.setAttribute("label", entry.name);
menuitem.setAttribute("image", "page-icon:" + uri.spec);
menuitem.setAttribute(
"class",
"menuitem-iconic bookmark-item menuitem-with-favicon"
);
menuitem.link = uri.spec;
menu.appendChild(menuitem);
}
}
},
openManagedBookmark(event) {
openUILink(event.target.link, event, {
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
});
},
onDragStartManaged(event) {
if (!event.target.link) {
return;
}
let dt = event.dataTransfer;
let node = {};
node.type = 0;
node.title = event.target.label;
node.uri = event.target.link;
function addData(type, index) {
let wrapNode = PlacesUtils.wrapNode(node, type);
dt.mozSetDataAt(type, wrapNode, index);
}
addData(PlacesUtils.TYPE_X_MOZ_URL, 0);
addData(PlacesUtils.TYPE_UNICODE, 0);
addData(PlacesUtils.TYPE_HTML, 0);
},
};
/**
......
......@@ -89,6 +89,7 @@ XPCOMUtils.defineLazyModuleGetters(this, {
WebNavigationFrames: "resource://gre/modules/WebNavigationFrames.jsm",
fxAccounts: "resource://gre/modules/FxAccounts.jsm",
webrtcUI: "resource:///modules/webrtcUI.jsm",
WebsiteFilter: "resource:///modules/policies/WebsiteFilter.jsm",
ZoomUI: "resource:///modules/ZoomUI.jsm",
});
......@@ -2114,8 +2115,86 @@ var gBrowserInit = {
}
}
if (!Services.policies.isAllowed("hideShowMenuBar")) {
document.getElementById("toolbar-menubar").removeAttribute("toolbarname");
if (Services.policies.status === Services.policies.ACTIVE) {
if (!Services.policies.isAllowed("hideShowMenuBar")) {
document
.getElementById("toolbar-menubar")
.removeAttribute("toolbarname");
}
let policies = Services.policies.getActivePolicies();
if ("ManagedBookmarks" in policies) {
let managedBookmarks = policies.ManagedBookmarks;
let children = managedBookmarks.filter(
child => !("toplevel_name" in child)
);
if (children.length) {
let managedBookmarksButton = document.createXULElement(
"toolbarbutton"
);
managedBookmarksButton.setAttribute("id", "managed-bookmarks");
managedBookmarksButton.setAttribute("class", "bookmark-item");
let toplevel = managedBookmarks.find(
element => "toplevel_name" in element
);
if (toplevel) {
managedBookmarksButton.setAttribute(
"label",
toplevel.toplevel_name
);
} else {
managedBookmarksButton.setAttribute(
"data-l10n-id",
"managed-bookmarks"
);
}
managedBookmarksButton.setAttribute("context", "placesContext");
managedBookmarksButton.setAttribute("container", "true");
managedBookmarksButton.setAttribute("removable", "false");
managedBookmarksButton.setAttribute("type", "menu");
let managedBookmarksPopup = document.createXULElement("menupopup");
managedBookmarksPopup.setAttribute("id", "managed-bookmarks-popup");
managedBookmarksPopup.setAttribute(
"oncommand",
"