Backed out changeset 2f74f8f2ed19 (bug 1689816) for causing reftest failures on skip-ink-multiline-position.html.
This commit is contained in:
@@ -75,6 +75,7 @@
|
|||||||
#include "mozilla/Services.h"
|
#include "mozilla/Services.h"
|
||||||
#include "mozilla/StaticPrefs_accessibility.h"
|
#include "mozilla/StaticPrefs_accessibility.h"
|
||||||
#include "mozilla/SVGGeometryFrame.h"
|
#include "mozilla/SVGGeometryFrame.h"
|
||||||
|
#include "nsDeckFrame.h"
|
||||||
|
|
||||||
#include "XULAlertAccessible.h"
|
#include "XULAlertAccessible.h"
|
||||||
#include "XULComboboxAccessible.h"
|
#include "XULComboboxAccessible.h"
|
||||||
@@ -442,20 +443,63 @@ LocalAccessible* nsAccessibilityService::GetRootDocumentAccessible(
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsAccessibilityService::NotifyOfTabPanelVisibilityChange(
|
void nsAccessibilityService::DeckPanelSwitched(PresShell* aPresShell,
|
||||||
PresShell* aPresShell, Element* aPanel, bool aNowVisible) {
|
nsIContent* aDeckNode,
|
||||||
MOZ_ASSERT(aPanel->GetParent()->IsXULElement(nsGkAtoms::tabpanels));
|
nsIFrame* aPrevBoxFrame,
|
||||||
|
nsIFrame* aCurrentBoxFrame) {
|
||||||
DocAccessible* document = GetDocAccessible(aPresShell);
|
DocAccessible* document = GetDocAccessible(aPresShell);
|
||||||
if (!document) {
|
if (!document) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// A deck with a LocalAccessible is a tabpanels element.
|
||||||
|
const bool isTabPanels = document->HasAccessible(aDeckNode);
|
||||||
|
MOZ_ASSERT(!isTabPanels || aDeckNode->IsXULElement(nsGkAtoms::tabpanels),
|
||||||
|
"A deck with a LocalAccessible should be a tabpanels element");
|
||||||
|
|
||||||
if (LocalAccessible* acc = document->GetAccessible(aPanel)) {
|
if (aPrevBoxFrame) {
|
||||||
|
nsIContent* panelNode = aPrevBoxFrame->GetContent();
|
||||||
|
#ifdef A11Y_LOG
|
||||||
|
if (logging::IsEnabled(logging::eTree)) {
|
||||||
|
logging::MsgBegin("TREE", "deck panel unselected");
|
||||||
|
logging::Node("container", panelNode);
|
||||||
|
logging::Node("content", aDeckNode);
|
||||||
|
logging::MsgEnd();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (isTabPanels) {
|
||||||
|
// Tabpanels are accessible even when not selected.
|
||||||
|
if (LocalAccessible* acc = document->GetAccessible(panelNode)) {
|
||||||
RefPtr<AccEvent> event =
|
RefPtr<AccEvent> event =
|
||||||
new AccStateChangeEvent(acc, states::OFFSCREEN, aNowVisible);
|
new AccStateChangeEvent(acc, states::OFFSCREEN, true);
|
||||||
document->FireDelayedEvent(event);
|
document->FireDelayedEvent(event);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
document->ContentRemoved(panelNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aCurrentBoxFrame) {
|
||||||
|
nsIContent* panelNode = aCurrentBoxFrame->GetContent();
|
||||||
|
#ifdef A11Y_LOG
|
||||||
|
if (logging::IsEnabled(logging::eTree)) {
|
||||||
|
logging::MsgBegin("TREE", "deck panel selected");
|
||||||
|
logging::Node("container", panelNode);
|
||||||
|
logging::Node("content", aDeckNode);
|
||||||
|
logging::MsgEnd();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (isTabPanels) {
|
||||||
|
// Tabpanels are accessible even when not selected, so we don't have to
|
||||||
|
// insert a LocalAccessible.
|
||||||
|
if (LocalAccessible* acc = document->GetAccessible(panelNode)) {
|
||||||
|
RefPtr<AccEvent> event =
|
||||||
|
new AccStateChangeEvent(acc, states::OFFSCREEN, false);
|
||||||
|
document->FireDelayedEvent(event);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
document->ContentInserted(panelNode, panelNode->GetNextSibling());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsAccessibilityService::ContentRangeInserted(PresShell* aPresShell,
|
void nsAccessibilityService::ContentRangeInserted(PresShell* aPresShell,
|
||||||
@@ -1084,6 +1128,16 @@ LocalAccessible* nsAccessibilityService::CreateAccessible(
|
|||||||
|
|
||||||
// XUL accessibles.
|
// XUL accessibles.
|
||||||
if (!newAcc && content->IsXULElement()) {
|
if (!newAcc && content->IsXULElement()) {
|
||||||
|
// No accessible for not selected deck panel and its children.
|
||||||
|
if (!aContext->IsXULTabpanels()) {
|
||||||
|
nsDeckFrame* deckFrame = do_QueryFrame(frame->GetParent());
|
||||||
|
if (deckFrame && deckFrame->GetSelectedBox() != frame) {
|
||||||
|
if (aIsSubtreeHidden) *aIsSubtreeHidden = true;
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (content->IsXULElement(nsGkAtoms::panel)) {
|
if (content->IsXULElement(nsGkAtoms::panel)) {
|
||||||
// We filter here instead of in the XUL map because
|
// We filter here instead of in the XUL map because
|
||||||
// if we filter there and return null, we still end up
|
// if we filter there and return null, we still end up
|
||||||
|
|||||||
@@ -153,6 +153,13 @@ class nsAccessibilityService final : public mozilla::a11y::DocManager,
|
|||||||
void GetStringRelationType(uint32_t aRelationType, nsAString& aString);
|
void GetStringRelationType(uint32_t aRelationType, nsAString& aString);
|
||||||
|
|
||||||
// nsAccesibilityService
|
// nsAccesibilityService
|
||||||
|
/**
|
||||||
|
* Notification used to update the accessible tree when deck panel is
|
||||||
|
* switched.
|
||||||
|
*/
|
||||||
|
void DeckPanelSwitched(mozilla::PresShell* aPresShell, nsIContent* aDeckNode,
|
||||||
|
nsIFrame* aPrevBoxFrame, nsIFrame* aCurrentBoxFrame);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notification used to update the accessible tree when new content is
|
* Notification used to update the accessible tree when new content is
|
||||||
* inserted.
|
* inserted.
|
||||||
@@ -233,10 +240,6 @@ class nsAccessibilityService final : public mozilla::a11y::DocManager,
|
|||||||
void NotifyOfComputedStyleChange(mozilla::PresShell* aPresShell,
|
void NotifyOfComputedStyleChange(mozilla::PresShell* aPresShell,
|
||||||
nsIContent* aContent);
|
nsIContent* aContent);
|
||||||
|
|
||||||
void NotifyOfTabPanelVisibilityChange(mozilla::PresShell* aPresShell,
|
|
||||||
mozilla::dom::Element* aPanel,
|
|
||||||
bool aVisible);
|
|
||||||
|
|
||||||
void NotifyOfResolutionChange(mozilla::PresShell* aPresShell,
|
void NotifyOfResolutionChange(mozilla::PresShell* aPresShell,
|
||||||
float aResolution);
|
float aResolution);
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#include "nsAccCache.h"
|
#include "nsAccCache.h"
|
||||||
#include "nsAccessiblePivot.h"
|
#include "nsAccessiblePivot.h"
|
||||||
#include "nsAccUtils.h"
|
#include "nsAccUtils.h"
|
||||||
|
#include "nsDeckFrame.h"
|
||||||
#include "nsEventShell.h"
|
#include "nsEventShell.h"
|
||||||
#include "nsLayoutUtils.h"
|
#include "nsLayoutUtils.h"
|
||||||
#include "nsTextEquivUtils.h"
|
#include "nsTextEquivUtils.h"
|
||||||
@@ -1051,6 +1052,21 @@ LocalAccessible* DocAccessible::GetAccessibleOrContainer(
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if node is in an unselected deck panel
|
||||||
|
if (aNoContainerIfPruned && currNode->IsXULElement()) {
|
||||||
|
if (nsIFrame* frame = currNode->AsContent()->GetPrimaryFrame()) {
|
||||||
|
nsDeckFrame* deckFrame = do_QueryFrame(frame->GetParent());
|
||||||
|
if (deckFrame && deckFrame->GetSelectedBox() != frame) {
|
||||||
|
// If deck is not a <tabpanels>, return null
|
||||||
|
nsIContent* parentFrameContent = deckFrame->GetContent();
|
||||||
|
if (!parentFrameContent ||
|
||||||
|
!parentFrameContent->IsXULElement(nsGkAtoms::tabpanels)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check if node is in zero-sized map
|
// Check if node is in zero-sized map
|
||||||
if (aNoContainerIfPruned && currNode->IsHTMLElement(nsGkAtoms::map)) {
|
if (aNoContainerIfPruned && currNode->IsHTMLElement(nsGkAtoms::map)) {
|
||||||
if (nsIFrame* frame = currNode->AsContent()->GetPrimaryFrame()) {
|
if (nsIFrame* frame = currNode->AsContent()->GetPrimaryFrame()) {
|
||||||
|
|||||||
@@ -50,6 +50,7 @@
|
|||||||
#include "nsIContent.h"
|
#include "nsIContent.h"
|
||||||
#include "nsIFormControl.h"
|
#include "nsIFormControl.h"
|
||||||
|
|
||||||
|
#include "nsDeckFrame.h"
|
||||||
#include "nsLayoutUtils.h"
|
#include "nsLayoutUtils.h"
|
||||||
#include "nsPresContext.h"
|
#include "nsPresContext.h"
|
||||||
#include "nsIFrame.h"
|
#include "nsIFrame.h"
|
||||||
@@ -69,7 +70,6 @@
|
|||||||
#include "nsArrayUtils.h"
|
#include "nsArrayUtils.h"
|
||||||
#include "nsWhitespaceTokenizer.h"
|
#include "nsWhitespaceTokenizer.h"
|
||||||
#include "nsAttrName.h"
|
#include "nsAttrName.h"
|
||||||
#include "nsContainerFrame.h"
|
|
||||||
|
|
||||||
#include "mozilla/Assertions.h"
|
#include "mozilla/Assertions.h"
|
||||||
#include "mozilla/BasicEvents.h"
|
#include "mozilla/BasicEvents.h"
|
||||||
@@ -324,16 +324,22 @@ uint64_t LocalAccessible::VisibilityState() const {
|
|||||||
return states::INVISIBLE;
|
return states::INVISIBLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nsLayoutUtils::IsPopup(curFrame)) {
|
if (nsLayoutUtils::IsPopup(curFrame)) return 0;
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (curFrame->StyleUIReset()->mMozSubtreeHiddenOnlyVisually) {
|
// Offscreen state for background tab content and invisible for not selected
|
||||||
// Offscreen state for background tab content.
|
// deck panel.
|
||||||
|
nsIFrame* parentFrame = curFrame->GetParent();
|
||||||
|
nsDeckFrame* deckFrame = do_QueryFrame(parentFrame);
|
||||||
|
if (deckFrame && deckFrame->GetSelectedBox() != curFrame) {
|
||||||
|
if (deckFrame->GetContent()->IsXULElement(nsGkAtoms::tabpanels)) {
|
||||||
return states::OFFSCREEN;
|
return states::OFFSCREEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIFrame* parentFrame = curFrame->GetParent();
|
MOZ_ASSERT_UNREACHABLE(
|
||||||
|
"Children of not selected deck panel are not accessible.");
|
||||||
|
return states::INVISIBLE;
|
||||||
|
}
|
||||||
|
|
||||||
// If contained by scrollable frame then check that at least 12 pixels
|
// If contained by scrollable frame then check that at least 12 pixels
|
||||||
// around the object is visible, otherwise the object is offscreen.
|
// around the object is visible, otherwise the object is offscreen.
|
||||||
nsIScrollableFrame* scrollableFrame = do_QueryFrame(parentFrame);
|
nsIScrollableFrame* scrollableFrame = do_QueryFrame(parentFrame);
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include "XULTabAccessible.h"
|
#include "XULTabAccessible.h"
|
||||||
#include "HTMLFormControlAccessible.h"
|
#include "HTMLFormControlAccessible.h"
|
||||||
|
|
||||||
|
#include "nsDeckFrame.h"
|
||||||
#include "nsObjCExceptions.h"
|
#include "nsObjCExceptions.h"
|
||||||
|
|
||||||
using namespace mozilla::a11y;
|
using namespace mozilla::a11y;
|
||||||
@@ -125,17 +126,26 @@ enum CheckboxValue {
|
|||||||
@implementation mozPaneAccessible
|
@implementation mozPaneAccessible
|
||||||
|
|
||||||
- (NSArray*)moxChildren {
|
- (NSArray*)moxChildren {
|
||||||
// By default, all tab panels are exposed in the a11y tree
|
if (!mGeckoAccessible->AsLocal()) return nil;
|
||||||
// even if the tab they represent isn't the active tab. To
|
|
||||||
// prevent VoiceOver from navigating background tab content,
|
nsDeckFrame* deckFrame =
|
||||||
// only expose the tab panel that is currently on screen.
|
do_QueryFrame(mGeckoAccessible->AsLocal()->GetFrame());
|
||||||
for (mozAccessible* child in [super moxChildren]) {
|
nsIFrame* selectedFrame = deckFrame ? deckFrame->GetSelectedBox() : nullptr;
|
||||||
if (!([child state] & states::OFFSCREEN)) {
|
|
||||||
return [NSArray arrayWithObject:GetObjectOrRepresentedView(child)];
|
LocalAccessible* selectedAcc = nullptr;
|
||||||
|
if (selectedFrame) {
|
||||||
|
nsINode* node = selectedFrame->GetContent();
|
||||||
|
selectedAcc = mGeckoAccessible->AsLocal()->Document()->GetAccessible(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (selectedAcc) {
|
||||||
|
mozAccessible* curNative = GetNativeFromGeckoAccessible(selectedAcc);
|
||||||
|
if (curNative)
|
||||||
|
return
|
||||||
|
[NSArray arrayWithObjects:GetObjectOrRepresentedView(curNative), nil];
|
||||||
}
|
}
|
||||||
MOZ_ASSERT_UNREACHABLE("We have no on screen tab content?");
|
|
||||||
return @[];
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
// CSS display
|
// CSS display
|
||||||
testCSSAttrs("display_mozbox");
|
testCSSAttrs("display_mozbox");
|
||||||
testCSSAttrs("display_mozinlinebox");
|
testCSSAttrs("display_mozinlinebox");
|
||||||
|
testCSSAttrs("display_mozdeck");
|
||||||
testCSSAttrs("display_mozpopup");
|
testCSSAttrs("display_mozpopup");
|
||||||
|
|
||||||
SimpleTest.finish();
|
SimpleTest.finish();
|
||||||
@@ -49,6 +50,7 @@
|
|||||||
|
|
||||||
<vbox id="display_mozbox" style="display: -moz-box;" role="img"/>
|
<vbox id="display_mozbox" style="display: -moz-box;" role="img"/>
|
||||||
<vbox id="display_mozinlinebox" style="display: -moz-inline-box;" role="img"/>
|
<vbox id="display_mozinlinebox" style="display: -moz-inline-box;" role="img"/>
|
||||||
|
<vbox id="display_mozdeck" style="display: -moz-deck;" role="img"/>
|
||||||
<vbox id="display_mozpopup" style="display: -moz-popup;" role="img"/>
|
<vbox id="display_mozpopup" style="display: -moz-popup;" role="img"/>
|
||||||
|
|
||||||
</hbox>
|
</hbox>
|
||||||
|
|||||||
@@ -2171,23 +2171,23 @@ var gBrowserInit = {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (gBrowser.selectedBrowser.isRemoteBrowser) {
|
||||||
// If the initial browser is remote, in order to optimize for first paint,
|
// If the initial browser is remote, in order to optimize for first paint,
|
||||||
// we'll defer switching focus to that browser until it has painted.
|
// we'll defer switching focus to that browser until it has painted.
|
||||||
// Otherwise use a regular promise to guarantee that mutationobserver
|
this._firstContentWindowPaintDeferred.promise.then(() => {
|
||||||
// microtasks that could affect focusability have run.
|
// If focus didn't move while we were waiting for first paint, we're okay
|
||||||
let promise = gBrowser.selectedBrowser.isRemoteBrowser
|
// to move to the browser.
|
||||||
? this._firstContentWindowPaintDeferred.promise
|
|
||||||
: Promise.resolve();
|
|
||||||
|
|
||||||
promise.then(() => {
|
|
||||||
// If focus didn't move while we were waiting, we're okay to move to
|
|
||||||
// the browser.
|
|
||||||
if (
|
if (
|
||||||
document.commandDispatcher.focusedElement == initiallyFocusedElement
|
document.commandDispatcher.focusedElement == initiallyFocusedElement
|
||||||
) {
|
) {
|
||||||
gBrowser.selectedBrowser.focus();
|
gBrowser.selectedBrowser.focus();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
// If the initial browser is not remote, we can focus the browser
|
||||||
|
// immediately with no paint performance impact.
|
||||||
|
gBrowser.selectedBrowser.focus();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Delay removing the attribute using requestAnimationFrame to avoid
|
// Delay removing the attribute using requestAnimationFrame to avoid
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ add_task(async function() {
|
|||||||
Assert.equal(
|
Assert.equal(
|
||||||
win.document.activeElement,
|
win.document.activeElement,
|
||||||
expectedActiveElement,
|
expectedActiveElement,
|
||||||
`${uri}: the active element is expected: ${win.document.activeElement?.nodeName}`
|
uri + ": the active element is expected"
|
||||||
);
|
);
|
||||||
Assert.equal(win.gURLBar.value, "", uri + ": urlbar is empty");
|
Assert.equal(win.gURLBar.value, "", uri + ": urlbar is empty");
|
||||||
Assert.ok(win.gURLBar.placeholder, uri + ": placeholder text is present");
|
Assert.ok(win.gURLBar.placeholder, uri + ": placeholder text is present");
|
||||||
|
|||||||
@@ -254,7 +254,11 @@ add_task(async function() {
|
|||||||
|
|
||||||
// The widget is still fetching tabs, as we've neutered everything that
|
// The widget is still fetching tabs, as we've neutered everything that
|
||||||
// provides them
|
// provides them
|
||||||
is(deck.selectedIndex, DECKINDEX_FETCHING, "first deck entry is visible");
|
is(
|
||||||
|
deck.selectedIndex,
|
||||||
|
"" + DECKINDEX_FETCHING,
|
||||||
|
"first deck entry is visible"
|
||||||
|
);
|
||||||
|
|
||||||
// Tell the widget there are tabs available, but with zero clients.
|
// Tell the widget there are tabs available, but with zero clients.
|
||||||
mockedInternal.getTabClients = () => {
|
mockedInternal.getTabClients = () => {
|
||||||
@@ -265,7 +269,7 @@ add_task(async function() {
|
|||||||
// The UI should be showing the "no clients" pane.
|
// The UI should be showing the "no clients" pane.
|
||||||
is(
|
is(
|
||||||
deck.selectedIndex,
|
deck.selectedIndex,
|
||||||
DECKINDEX_NOCLIENTS,
|
"" + DECKINDEX_NOCLIENTS,
|
||||||
"no-clients deck entry is visible"
|
"no-clients deck entry is visible"
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -316,7 +320,11 @@ add_task(async function() {
|
|||||||
await updateTabsPanel();
|
await updateTabsPanel();
|
||||||
|
|
||||||
// The UI should be showing tabs!
|
// The UI should be showing tabs!
|
||||||
is(deck.selectedIndex, DECKINDEX_TABS, "no-clients deck entry is visible");
|
is(
|
||||||
|
deck.selectedIndex,
|
||||||
|
"" + DECKINDEX_TABS,
|
||||||
|
"no-clients deck entry is visible"
|
||||||
|
);
|
||||||
let tabList = document.getElementById("PanelUI-remotetabs-tabslist");
|
let tabList = document.getElementById("PanelUI-remotetabs-tabslist");
|
||||||
let node = tabList.firstElementChild;
|
let node = tabList.firstElementChild;
|
||||||
// First entry should be the client with the most-recent tab.
|
// First entry should be the client with the most-recent tab.
|
||||||
@@ -459,7 +467,7 @@ add_task(async function() {
|
|||||||
let subpanel = document.getElementById("PanelUI-remotetabs-main");
|
let subpanel = document.getElementById("PanelUI-remotetabs-main");
|
||||||
ok(!subpanel.hidden, "main pane is visible");
|
ok(!subpanel.hidden, "main pane is visible");
|
||||||
let deck = document.getElementById("PanelUI-remotetabs-deck");
|
let deck = document.getElementById("PanelUI-remotetabs-deck");
|
||||||
is(deck.selectedIndex, DECKINDEX_TABS, "we should be showing tabs");
|
is(deck.selectedIndex, "" + DECKINDEX_TABS, "we should be showing tabs");
|
||||||
|
|
||||||
function checkTabsPage(tabsShownCount, showMoreLabel) {
|
function checkTabsPage(tabsShownCount, showMoreLabel) {
|
||||||
let tabList = document.getElementById("PanelUI-remotetabs-tabslist");
|
let tabList = document.getElementById("PanelUI-remotetabs-tabslist");
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ add_task(async function() {
|
|||||||
);
|
);
|
||||||
is(
|
is(
|
||||||
weavePrefsDeck.selectedIndex,
|
weavePrefsDeck.selectedIndex,
|
||||||
0,
|
"0",
|
||||||
"Should select the #noFxaAccount child node"
|
"Should select the #noFxaAccount child node"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ add_task(async function test_infobar() {
|
|||||||
let notif = showTranslationUI("fr");
|
let notif = showTranslationUI("fr");
|
||||||
is(
|
is(
|
||||||
notif.state,
|
notif.state,
|
||||||
Translation.STATE_OFFER,
|
"" + Translation.STATE_OFFER,
|
||||||
"the infobar is offering translation"
|
"the infobar is offering translation"
|
||||||
);
|
);
|
||||||
is(
|
is(
|
||||||
@@ -117,7 +117,7 @@ add_task(async function test_infobar() {
|
|||||||
notif._getAnonElt("translate").click();
|
notif._getAnonElt("translate").click();
|
||||||
is(
|
is(
|
||||||
notif.state,
|
notif.state,
|
||||||
Translation.STATE_TRANSLATING,
|
"" + Translation.STATE_TRANSLATING,
|
||||||
"the infobar is in the translating state"
|
"the infobar is in the translating state"
|
||||||
);
|
);
|
||||||
ok(
|
ok(
|
||||||
@@ -134,14 +134,14 @@ add_task(async function test_infobar() {
|
|||||||
|
|
||||||
info("Make the translation fail and check we are in the error state.");
|
info("Make the translation fail and check we are in the error state.");
|
||||||
notif.translation.failTranslation();
|
notif.translation.failTranslation();
|
||||||
is(notif.state, Translation.STATE_ERROR, "infobar in the error state");
|
is(notif.state, "" + Translation.STATE_ERROR, "infobar in the error state");
|
||||||
checkURLBarIcon();
|
checkURLBarIcon();
|
||||||
|
|
||||||
info("Click the try again button");
|
info("Click the try again button");
|
||||||
notif._getAnonElt("tryAgain").click();
|
notif._getAnonElt("tryAgain").click();
|
||||||
is(
|
is(
|
||||||
notif.state,
|
notif.state,
|
||||||
Translation.STATE_TRANSLATING,
|
"" + Translation.STATE_TRANSLATING,
|
||||||
"infobar in the translating state"
|
"infobar in the translating state"
|
||||||
);
|
);
|
||||||
ok(
|
ok(
|
||||||
@@ -162,7 +162,7 @@ add_task(async function test_infobar() {
|
|||||||
notif.translation.finishTranslation();
|
notif.translation.finishTranslation();
|
||||||
is(
|
is(
|
||||||
notif.state,
|
notif.state,
|
||||||
Translation.STATE_TRANSLATED,
|
"" + Translation.STATE_TRANSLATED,
|
||||||
"infobar in the translated state"
|
"infobar in the translated state"
|
||||||
);
|
);
|
||||||
checkURLBarIcon(true);
|
checkURLBarIcon(true);
|
||||||
@@ -207,7 +207,7 @@ add_task(async function test_infobar() {
|
|||||||
from.doCommand();
|
from.doCommand();
|
||||||
is(
|
is(
|
||||||
notif.state,
|
notif.state,
|
||||||
Translation.STATE_TRANSLATING,
|
"" + Translation.STATE_TRANSLATING,
|
||||||
"infobar in the translating state"
|
"infobar in the translating state"
|
||||||
);
|
);
|
||||||
ok(
|
ok(
|
||||||
@@ -232,7 +232,7 @@ add_task(async function test_infobar() {
|
|||||||
to.doCommand();
|
to.doCommand();
|
||||||
is(
|
is(
|
||||||
notif.state,
|
notif.state,
|
||||||
Translation.STATE_TRANSLATING,
|
"" + Translation.STATE_TRANSLATING,
|
||||||
"infobar in the translating state"
|
"infobar in the translating state"
|
||||||
);
|
);
|
||||||
ok(
|
ok(
|
||||||
@@ -254,7 +254,7 @@ add_task(async function test_infobar() {
|
|||||||
notif = showTranslationUI("fr");
|
notif = showTranslationUI("fr");
|
||||||
is(
|
is(
|
||||||
notif.state,
|
notif.state,
|
||||||
Translation.STATE_OFFER,
|
"" + Translation.STATE_OFFER,
|
||||||
"the infobar is offering translation"
|
"the infobar is offering translation"
|
||||||
);
|
);
|
||||||
is(
|
is(
|
||||||
@@ -267,7 +267,7 @@ add_task(async function test_infobar() {
|
|||||||
notif._getAnonElt("translate").click();
|
notif._getAnonElt("translate").click();
|
||||||
is(
|
is(
|
||||||
notif.state,
|
notif.state,
|
||||||
Translation.STATE_TRANSLATING,
|
"" + Translation.STATE_TRANSLATING,
|
||||||
"the infobar is in the translating state"
|
"the infobar is in the translating state"
|
||||||
);
|
);
|
||||||
ok(
|
ok(
|
||||||
@@ -332,7 +332,7 @@ add_task(async function test_infobar_using_page() {
|
|||||||
let notif = notificationBox.getNotificationWithValue("translation");
|
let notif = notificationBox.getNotificationWithValue("translation");
|
||||||
is(
|
is(
|
||||||
notif.state,
|
notif.state,
|
||||||
Translation.STATE_OFFER,
|
"" + Translation.STATE_OFFER,
|
||||||
"the infobar is offering translation"
|
"the infobar is offering translation"
|
||||||
);
|
);
|
||||||
is(
|
is(
|
||||||
|
|||||||
@@ -468,7 +468,7 @@ class AsyncTabSwitcher {
|
|||||||
let index = Array.prototype.indexOf.call(tabpanels.children, showPanel);
|
let index = Array.prototype.indexOf.call(tabpanels.children, showPanel);
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
this.log(`Switch to tab ${index} - ${this.tinfo(showTab)}`);
|
this.log(`Switch to tab ${index} - ${this.tinfo(showTab)}`);
|
||||||
tabpanels.updateSelectedIndex(index);
|
tabpanels.setAttribute("selectedIndex", index);
|
||||||
if (showTab === this.requestedTab) {
|
if (showTab === this.requestedTab) {
|
||||||
if (requestedTabState == this.STATE_LOADED) {
|
if (requestedTabState == this.STATE_LOADED) {
|
||||||
// The new tab will be made visible in the next paint, record the expected
|
// The new tab will be made visible in the next paint, record the expected
|
||||||
|
|||||||
@@ -397,11 +397,9 @@ moz-input-box > menupopup .context-menu-add-engine > .menu-iconic-left {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#tabbrowser-tabs {
|
#tabbrowser-tabs {
|
||||||
/* overriding tabbox.css */
|
|
||||||
-moz-box-align: stretch;
|
-moz-box-align: stretch;
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
position: static;
|
position: static;
|
||||||
z-index: auto;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Bookmark drag and drop styles */
|
/* Bookmark drag and drop styles */
|
||||||
|
|||||||
@@ -113,7 +113,6 @@ exports.ANIMATION_TYPE_FOR_LONGHANDS = [
|
|||||||
"object-fit",
|
"object-fit",
|
||||||
"-moz-orient",
|
"-moz-orient",
|
||||||
"-moz-osx-font-smoothing",
|
"-moz-osx-font-smoothing",
|
||||||
"-moz-subtree-hidden-only-visually",
|
|
||||||
"outline-style",
|
"outline-style",
|
||||||
"overflow-anchor",
|
"overflow-anchor",
|
||||||
"overflow-block",
|
"overflow-block",
|
||||||
|
|||||||
@@ -10,14 +10,18 @@
|
|||||||
#include "Layers.h"
|
#include "Layers.h"
|
||||||
#include "mozilla/dom/BrowserChild.h"
|
#include "mozilla/dom/BrowserChild.h"
|
||||||
#include "mozilla/dom/Document.h"
|
#include "mozilla/dom/Document.h"
|
||||||
|
#include "mozilla/gfx/gfxVars.h"
|
||||||
#include "mozilla/gfx/Point.h"
|
#include "mozilla/gfx/Point.h"
|
||||||
|
#include "mozilla/layers/APZCCallbackHelper.h"
|
||||||
#include "mozilla/layers/APZPublicUtils.h"
|
#include "mozilla/layers/APZPublicUtils.h"
|
||||||
#include "mozilla/layers/CompositorBridgeChild.h"
|
#include "mozilla/layers/CompositorBridgeChild.h"
|
||||||
#include "mozilla/layers/LayersMessageUtils.h"
|
#include "mozilla/layers/LayersMessageUtils.h"
|
||||||
#include "mozilla/layers/PAPZ.h"
|
#include "mozilla/layers/PAPZ.h"
|
||||||
|
#include "mozilla/layers/RepaintRequest.h"
|
||||||
#include "mozilla/PresShell.h"
|
#include "mozilla/PresShell.h"
|
||||||
#include "mozilla/StaticPrefs_layers.h"
|
#include "mozilla/StaticPrefs_layers.h"
|
||||||
#include "mozilla/StaticPrefs_layout.h"
|
#include "mozilla/StaticPrefs_layout.h"
|
||||||
|
#include "nsDeckFrame.h"
|
||||||
#include "nsIScrollableFrame.h"
|
#include "nsIScrollableFrame.h"
|
||||||
#include "nsLayoutUtils.h"
|
#include "nsLayoutUtils.h"
|
||||||
#include "nsPlaceholderFrame.h"
|
#include "nsPlaceholderFrame.h"
|
||||||
@@ -29,9 +33,13 @@
|
|||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
|
using gfx::gfxVars;
|
||||||
using gfx::IntSize;
|
using gfx::IntSize;
|
||||||
|
|
||||||
|
using layers::APZCCallbackHelper;
|
||||||
using layers::FrameMetrics;
|
using layers::FrameMetrics;
|
||||||
|
using layers::LayerManager;
|
||||||
|
using layers::RepaintRequest;
|
||||||
using layers::ScrollableLayerGuid;
|
using layers::ScrollableLayerGuid;
|
||||||
|
|
||||||
typedef ScrollableLayerGuid::ViewID ViewID;
|
typedef ScrollableLayerGuid::ViewID ViewID;
|
||||||
@@ -797,11 +805,12 @@ bool DisplayPortUtils::CalculateAndSetDisplayPortMargins(
|
|||||||
aRepaintMode);
|
aRepaintMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DisplayPortUtils::MaybeCreateDisplayPort(
|
bool DisplayPortUtils::MaybeCreateDisplayPort(nsDisplayListBuilder* aBuilder,
|
||||||
nsDisplayListBuilder* aBuilder, nsIFrame* aScrollFrame,
|
nsIFrame* aScrollFrame,
|
||||||
nsIScrollableFrame* aScrollFrameAsScrollable, RepaintMode aRepaintMode) {
|
RepaintMode aRepaintMode) {
|
||||||
nsIContent* content = aScrollFrame->GetContent();
|
nsIContent* content = aScrollFrame->GetContent();
|
||||||
if (!content) {
|
nsIScrollableFrame* scrollableFrame = do_QueryFrame(aScrollFrame);
|
||||||
|
if (!content || !scrollableFrame) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -814,7 +823,7 @@ bool DisplayPortUtils::MaybeCreateDisplayPort(
|
|||||||
if (aBuilder->IsPaintingToWindow() &&
|
if (aBuilder->IsPaintingToWindow() &&
|
||||||
nsLayoutUtils::AsyncPanZoomEnabled(aScrollFrame) &&
|
nsLayoutUtils::AsyncPanZoomEnabled(aScrollFrame) &&
|
||||||
!aBuilder->HaveScrollableDisplayPort() &&
|
!aBuilder->HaveScrollableDisplayPort() &&
|
||||||
aScrollFrameAsScrollable->WantAsyncScroll()) {
|
scrollableFrame->WantAsyncScroll()) {
|
||||||
// If we don't already have a displayport, calculate and set one.
|
// If we don't already have a displayport, calculate and set one.
|
||||||
if (!haveDisplayPort) {
|
if (!haveDisplayPort) {
|
||||||
// We only use the viewId for logging purposes, but create it
|
// We only use the viewId for logging purposes, but create it
|
||||||
@@ -826,7 +835,7 @@ bool DisplayPortUtils::MaybeCreateDisplayPort(
|
|||||||
sDisplayportLog, LogLevel::Debug,
|
sDisplayportLog, LogLevel::Debug,
|
||||||
("Setting DP on first-encountered scrollId=%" PRIu64 "\n", viewId));
|
("Setting DP on first-encountered scrollId=%" PRIu64 "\n", viewId));
|
||||||
|
|
||||||
CalculateAndSetDisplayPortMargins(aScrollFrameAsScrollable, aRepaintMode);
|
CalculateAndSetDisplayPortMargins(scrollableFrame, aRepaintMode);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
haveDisplayPort = HasNonMinimalDisplayPort(content);
|
haveDisplayPort = HasNonMinimalDisplayPort(content);
|
||||||
MOZ_ASSERT(haveDisplayPort,
|
MOZ_ASSERT(haveDisplayPort,
|
||||||
@@ -875,8 +884,10 @@ bool DisplayPortUtils::MaybeCreateDisplayPortInFirstScrollFrameEncountered(
|
|||||||
aFrame->GetContent()->GetID() == nsGkAtoms::tabbrowser_arrowscrollbox) {
|
aFrame->GetContent()->GetID() == nsGkAtoms::tabbrowser_arrowscrollbox) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (nsIScrollableFrame* sf = do_QueryFrame(aFrame)) {
|
|
||||||
if (MaybeCreateDisplayPort(aBuilder, aFrame, sf, RepaintMode::Repaint)) {
|
nsIScrollableFrame* sf = do_QueryFrame(aFrame);
|
||||||
|
if (sf) {
|
||||||
|
if (MaybeCreateDisplayPort(aBuilder, aFrame, RepaintMode::Repaint)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -890,21 +901,28 @@ bool DisplayPortUtils::MaybeCreateDisplayPortInFirstScrollFrameEncountered(
|
|||||||
if (aFrame->IsSubDocumentFrame()) {
|
if (aFrame->IsSubDocumentFrame()) {
|
||||||
PresShell* presShell = static_cast<nsSubDocumentFrame*>(aFrame)
|
PresShell* presShell = static_cast<nsSubDocumentFrame*>(aFrame)
|
||||||
->GetSubdocumentPresShellForPainting(0);
|
->GetSubdocumentPresShellForPainting(0);
|
||||||
if (nsIFrame* root = presShell ? presShell->GetRootFrame() : nullptr) {
|
nsIFrame* root = presShell ? presShell->GetRootFrame() : nullptr;
|
||||||
|
if (root) {
|
||||||
if (MaybeCreateDisplayPortInFirstScrollFrameEncountered(root, aBuilder)) {
|
if (MaybeCreateDisplayPortInFirstScrollFrameEncountered(root, aBuilder)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (aFrame->StyleUIReset()->mMozSubtreeHiddenOnlyVisually) {
|
if (aFrame->IsDeckFrame()) {
|
||||||
// Only descend the visible card of deck / tabpanels
|
// only descend the visible card of a decks
|
||||||
return false;
|
nsIFrame* child = static_cast<nsDeckFrame*>(aFrame)->GetSelectedBox();
|
||||||
|
if (child) {
|
||||||
|
return MaybeCreateDisplayPortInFirstScrollFrameEncountered(child,
|
||||||
|
aBuilder);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (nsIFrame* child : aFrame->PrincipalChildList()) {
|
for (nsIFrame* child : aFrame->PrincipalChildList()) {
|
||||||
if (MaybeCreateDisplayPortInFirstScrollFrameEncountered(child, aBuilder)) {
|
if (MaybeCreateDisplayPortInFirstScrollFrameEncountered(child, aBuilder)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -278,9 +278,9 @@ class DisplayPortUtils {
|
|||||||
* Returns true if there is a displayport on an async scrollable scrollframe
|
* Returns true if there is a displayport on an async scrollable scrollframe
|
||||||
* after this call, either because one was just added or it already existed.
|
* after this call, either because one was just added or it already existed.
|
||||||
*/
|
*/
|
||||||
static bool MaybeCreateDisplayPort(
|
static bool MaybeCreateDisplayPort(nsDisplayListBuilder* aBuilder,
|
||||||
nsDisplayListBuilder* aBuilder, nsIFrame* aScrollFrame,
|
nsIFrame* aScrollFrame,
|
||||||
nsIScrollableFrame* aScrollFrameAsScrollable, RepaintMode aRepaintMode);
|
RepaintMode aRepaintMode);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets a zero margin display port on all proper ancestors of aFrame that
|
* Sets a zero margin display port on all proper ancestors of aFrame that
|
||||||
|
|||||||
@@ -3961,24 +3961,38 @@ void PresShell::ClearMouseCaptureOnView(nsView* aView) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PresShell::ClearMouseCapture() {
|
void PresShell::ClearMouseCapture() {
|
||||||
|
nsIContent* capturingContent = GetCapturingContent();
|
||||||
|
if (!capturingContent) {
|
||||||
|
AllowMouseCapture(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ReleaseCapturingContent();
|
ReleaseCapturingContent();
|
||||||
AllowMouseCapture(false);
|
AllowMouseCapture(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PresShell::ClearMouseCapture(nsIFrame* aFrame) {
|
void PresShell::ClearMouseCapture(nsIFrame* aFrame) {
|
||||||
MOZ_ASSERT(aFrame);
|
MOZ_ASSERT(
|
||||||
|
aFrame && aFrame->GetParent() &&
|
||||||
|
aFrame->GetParent()->Type() == LayoutFrameType::Deck,
|
||||||
|
"This function should only be called with a child frame of <deck>");
|
||||||
|
|
||||||
nsIContent* capturingContent = GetCapturingContent();
|
nsIContent* capturingContent = GetCapturingContent();
|
||||||
if (!capturingContent) {
|
if (!capturingContent) {
|
||||||
|
AllowMouseCapture(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIFrame* capturingFrame = capturingContent->GetPrimaryFrame();
|
nsIFrame* capturingFrame = capturingContent->GetPrimaryFrame();
|
||||||
const bool shouldClear =
|
if (!capturingFrame) {
|
||||||
!capturingFrame ||
|
ReleaseCapturingContent();
|
||||||
nsLayoutUtils::IsAncestorFrameCrossDocInProcess(aFrame, capturingFrame);
|
AllowMouseCapture(false);
|
||||||
if (shouldClear) {
|
return;
|
||||||
ClearMouseCapture();
|
}
|
||||||
|
|
||||||
|
if (nsLayoutUtils::IsAncestorFrameCrossDocInProcess(aFrame, capturingFrame)) {
|
||||||
|
ReleaseCapturingContent();
|
||||||
|
AllowMouseCapture(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -205,22 +205,13 @@ class PresShell final : public nsStubDocumentObserver,
|
|||||||
|
|
||||||
static void ClearMouseCaptureOnView(nsView* aView);
|
static void ClearMouseCaptureOnView(nsView* aView);
|
||||||
|
|
||||||
// Clear the capture content if it exists in this process.
|
|
||||||
static void ClearMouseCapture();
|
|
||||||
|
|
||||||
// If a frame in the subtree rooted at aFrame is capturing the mouse then
|
// If a frame in the subtree rooted at aFrame is capturing the mouse then
|
||||||
// clears that capture.
|
// clears that capture.
|
||||||
//
|
|
||||||
// NOTE(emilio): This is needed only so that mouse events captured by a remote
|
|
||||||
// frame don't remain being captured by the frame while hidden, see
|
|
||||||
// dom/events/test/browser_mouse_enterleave_switch_tab.js, which is the only
|
|
||||||
// test that meaningfully exercises this code path.
|
|
||||||
//
|
|
||||||
// We could consider maybe removing this, since the capturing content gets
|
|
||||||
// reset on mouse/pointerdown? Or maybe exposing an API so that the front-end
|
|
||||||
// does this.
|
|
||||||
static void ClearMouseCapture(nsIFrame* aFrame);
|
static void ClearMouseCapture(nsIFrame* aFrame);
|
||||||
|
|
||||||
|
// Clear the capture content if it exists in this process.
|
||||||
|
static void ClearMouseCapture();
|
||||||
|
|
||||||
#ifdef ACCESSIBILITY
|
#ifdef ACCESSIBILITY
|
||||||
/**
|
/**
|
||||||
* Return the document accessible for this PresShell if there is one.
|
* Return the document accessible for this PresShell if there is one.
|
||||||
|
|||||||
@@ -2624,7 +2624,7 @@ MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(ServoPostTraversalFlags)
|
|||||||
// flags for kids.
|
// flags for kids.
|
||||||
static ServoPostTraversalFlags SendA11yNotifications(
|
static ServoPostTraversalFlags SendA11yNotifications(
|
||||||
nsPresContext* aPresContext, Element* aElement,
|
nsPresContext* aPresContext, Element* aElement,
|
||||||
const ComputedStyle& aOldStyle, const ComputedStyle& aNewStyle,
|
ComputedStyle* aOldComputedStyle, ComputedStyle* aNewComputedStyle,
|
||||||
ServoPostTraversalFlags aFlags) {
|
ServoPostTraversalFlags aFlags) {
|
||||||
using Flags = ServoPostTraversalFlags;
|
using Flags = ServoPostTraversalFlags;
|
||||||
MOZ_ASSERT(!(aFlags & Flags::SkipA11yNotifications) ||
|
MOZ_ASSERT(!(aFlags & Flags::SkipA11yNotifications) ||
|
||||||
@@ -2638,24 +2638,13 @@ static ServoPostTraversalFlags SendA11yNotifications(
|
|||||||
// enabled. Just skip everything.
|
// enabled. Just skip everything.
|
||||||
return Flags::Empty;
|
return Flags::Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aNewStyle.StyleUIReset()->mMozSubtreeHiddenOnlyVisually !=
|
|
||||||
aOldStyle.StyleUIReset()->mMozSubtreeHiddenOnlyVisually) {
|
|
||||||
if (aElement->GetParent() &&
|
|
||||||
aElement->GetParent()->IsXULElement(nsGkAtoms::tabpanels)) {
|
|
||||||
accService->NotifyOfTabPanelVisibilityChange(
|
|
||||||
aPresContext->PresShell(), aElement,
|
|
||||||
aNewStyle.StyleUIReset()->mMozSubtreeHiddenOnlyVisually);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aFlags & Flags::SkipA11yNotifications) {
|
if (aFlags & Flags::SkipA11yNotifications) {
|
||||||
// Propagate the skipping flag to descendants.
|
// Propogate the skipping flag to descendants.
|
||||||
return Flags::SkipA11yNotifications;
|
return Flags::SkipA11yNotifications;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool needsNotify = false;
|
bool needsNotify = false;
|
||||||
bool isVisible = aNewStyle.StyleVisibility()->IsVisible();
|
bool isVisible = aNewComputedStyle->StyleVisibility()->IsVisible();
|
||||||
if (aFlags & Flags::SendA11yNotificationsIfShown) {
|
if (aFlags & Flags::SendA11yNotificationsIfShown) {
|
||||||
if (!isVisible) {
|
if (!isVisible) {
|
||||||
// Propagate the sending-if-shown flag to descendants.
|
// Propagate the sending-if-shown flag to descendants.
|
||||||
@@ -2668,7 +2657,7 @@ static ServoPostTraversalFlags SendA11yNotifications(
|
|||||||
} else {
|
} else {
|
||||||
// If we shouldn't skip in any case, we need to check whether our
|
// If we shouldn't skip in any case, we need to check whether our
|
||||||
// own visibility has changed.
|
// own visibility has changed.
|
||||||
bool wasVisible = aOldStyle.StyleVisibility()->IsVisible();
|
bool wasVisible = aOldComputedStyle->StyleVisibility()->IsVisible();
|
||||||
needsNotify = wasVisible != isVisible;
|
needsNotify = wasVisible != isVisible;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2898,9 +2887,9 @@ bool RestyleManager::ProcessPostTraversal(Element* aElement,
|
|||||||
AddLayerChangesForAnimation(styleFrame, primaryFrame, aElement, changeHint,
|
AddLayerChangesForAnimation(styleFrame, primaryFrame, aElement, changeHint,
|
||||||
aRestyleState.ChangeList());
|
aRestyleState.ChangeList());
|
||||||
|
|
||||||
childrenFlags |= SendA11yNotifications(mPresContext, aElement,
|
childrenFlags |=
|
||||||
*oldOrDisplayContentsStyle,
|
SendA11yNotifications(mPresContext, aElement, oldOrDisplayContentsStyle,
|
||||||
*upToDateStyle, aFlags);
|
upToDateStyle, aFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool traverseElementChildren =
|
const bool traverseElementChildren =
|
||||||
|
|||||||
10
layout/base/crashtests/344300-2.html
Normal file
10
layout/base/crashtests/344300-2.html
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<html><body>
|
||||||
|
<object style="display:-moz-deck;">
|
||||||
|
<noscript>
|
||||||
|
</noscript>
|
||||||
|
</object>
|
||||||
|
</body></html>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -58,13 +58,16 @@ window.location.reload();
|
|||||||
<s style=" display: -moz-box; position: absolute; direction: ltr;">
|
<s style=" display: -moz-box; position: absolute; direction: ltr;">
|
||||||
<q style=" display: table; direction: ltr;">
|
<q style=" display: table; direction: ltr;">
|
||||||
<bdo style=" display: block;">mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m
|
<bdo style=" display: block;">mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m
|
||||||
|
<q style=" display: -moz-deck; position: absolute; direction: rtl;">mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m
|
||||||
|
</q>
|
||||||
</bdo>
|
</bdo>
|
||||||
</q>
|
</q>
|
||||||
</s>
|
</s>
|
||||||
<map style=" display: inline-table; position: fixed; direction: ltr;">
|
<map style=" display: inline-table; position: fixed; direction: ltr;">
|
||||||
<q style=" display: table; direction: ltr;">
|
<q style=" display: table; direction: ltr;">
|
||||||
<bdo style=" display: block;">
|
<bdo style=" display: block;">
|
||||||
mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m
|
<q style=" display: -moz-deck; position: absolute; direction: rtl;">mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m
|
||||||
|
</q>mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m
|
||||||
<q style=" display: inline; direction: ltr;">mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m
|
<q style=" display: inline; direction: ltr;">mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m
|
||||||
</q>
|
</q>
|
||||||
</bdo>
|
</bdo>
|
||||||
@@ -363,6 +366,7 @@ mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m
|
|||||||
</q>
|
</q>
|
||||||
</q>
|
</q>
|
||||||
</q>
|
</q>
|
||||||
|
<listing style=" display: -moz-deck; direction: ltr;">
|
||||||
<p style=" display: block; position: fixed; direction: ltr;">
|
<p style=" display: block; position: fixed; direction: ltr;">
|
||||||
<q style=" display: table-header-group; ">
|
<q style=" display: table-header-group; ">
|
||||||
<q style=" display: table-cell; ">
|
<q style=" display: table-cell; ">
|
||||||
@@ -401,6 +405,7 @@ mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m
|
|||||||
</q>
|
</q>
|
||||||
</q>
|
</q>
|
||||||
</p>
|
</p>
|
||||||
|
</listing>
|
||||||
<q style=" display: table-header-group; ">
|
<q style=" display: table-header-group; ">
|
||||||
<q style=" display: table-cell; ">
|
<q style=" display: table-cell; ">
|
||||||
<q style=" display: table; direction: ltr;">
|
<q style=" display: table; direction: ltr;">
|
||||||
@@ -651,7 +656,7 @@ mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m
|
|||||||
</map>
|
</map>
|
||||||
<ol style="display: inline-block;direction: ltr;">
|
<ol style="display: inline-block;direction: ltr;">
|
||||||
<p style="display: inherit;position: fixed;direction: ltr;">
|
<p style="display: inherit;position: fixed;direction: ltr;">
|
||||||
<body style="display: position: absolute;direction: ltr;">mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m
|
<body style="display: -moz-deck;position: absolute;direction: ltr;">mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m
|
||||||
</ol>mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m
|
</ol>mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m
|
||||||
</html>mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m
|
</html>mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m
|
||||||
</map>mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m
|
</map>mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m mm m
|
||||||
|
|||||||
4
layout/base/crashtests/570038-1.html
Normal file
4
layout/base/crashtests/570038-1.html
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<body><div style="display: -moz-deck;"><div style="overflow: auto; border: 4294967296px solid blue;">M</div></div></body>
|
||||||
|
</html>
|
||||||
@@ -105,6 +105,7 @@ load 343540-1.html
|
|||||||
load 344057-1.xhtml
|
load 344057-1.xhtml
|
||||||
load 344064-1.html
|
load 344064-1.html
|
||||||
load 344300-1.html
|
load 344300-1.html
|
||||||
|
load 344300-2.html
|
||||||
load chrome://reftest/content/crashtests/layout/base/crashtests/344340-1.xhtml
|
load chrome://reftest/content/crashtests/layout/base/crashtests/344340-1.xhtml
|
||||||
load 347898-1.html
|
load 347898-1.html
|
||||||
load 348126-1.html
|
load 348126-1.html
|
||||||
@@ -315,6 +316,7 @@ load 543648-1.html
|
|||||||
load 560447-1.html
|
load 560447-1.html
|
||||||
load 564063-1.html
|
load 564063-1.html
|
||||||
load 569018-1.html
|
load 569018-1.html
|
||||||
|
load chrome://reftest/content/crashtests/layout/base/crashtests/570038-1.html
|
||||||
load chrome://reftest/content/crashtests/layout/base/crashtests/572003.xhtml
|
load chrome://reftest/content/crashtests/layout/base/crashtests/572003.xhtml
|
||||||
load 572582-1.xhtml
|
load 572582-1.xhtml
|
||||||
load 576649-1.html
|
load 576649-1.html
|
||||||
|
|||||||
@@ -215,6 +215,8 @@ nsContainerFrame* NS_NewRootBoxFrame(PresShell* aPresShell,
|
|||||||
nsContainerFrame* NS_NewDocElementBoxFrame(PresShell* aPresShell,
|
nsContainerFrame* NS_NewDocElementBoxFrame(PresShell* aPresShell,
|
||||||
ComputedStyle* aStyle);
|
ComputedStyle* aStyle);
|
||||||
|
|
||||||
|
nsIFrame* NS_NewDeckFrame(PresShell* aPresShell, ComputedStyle* aStyle);
|
||||||
|
|
||||||
nsIFrame* NS_NewLeafBoxFrame(PresShell* aPresShell, ComputedStyle* aStyle);
|
nsIFrame* NS_NewLeafBoxFrame(PresShell* aPresShell, ComputedStyle* aStyle);
|
||||||
|
|
||||||
nsIFrame* NS_NewRangeFrame(PresShell* aPresShell, ComputedStyle* aStyle);
|
nsIFrame* NS_NewRangeFrame(PresShell* aPresShell, ComputedStyle* aStyle);
|
||||||
@@ -4547,6 +4549,11 @@ nsCSSFrameConstructor::FindDisplayData(const nsStyleDisplay& aDisplay,
|
|||||||
FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeRuby));
|
FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeRuby));
|
||||||
return &data;
|
return &data;
|
||||||
}
|
}
|
||||||
|
case StyleDisplayInside::MozDeck: {
|
||||||
|
static constexpr FrameConstructionData data =
|
||||||
|
SIMPLE_XUL_FCDATA(NS_NewDeckFrame);
|
||||||
|
return &data;
|
||||||
|
}
|
||||||
case StyleDisplayInside::MozPopup: {
|
case StyleDisplayInside::MozPopup: {
|
||||||
static constexpr FrameConstructionData data(
|
static constexpr FrameConstructionData data(
|
||||||
NS_NewMenuPopupFrame, FCDATA_DISALLOW_OUT_OF_FLOW | FCDATA_IS_POPUP |
|
NS_NewMenuPopupFrame, FCDATA_DISALLOW_OUT_OF_FLOW | FCDATA_IS_POPUP |
|
||||||
|
|||||||
@@ -117,6 +117,7 @@
|
|||||||
#include "nsCSSPseudoElements.h"
|
#include "nsCSSPseudoElements.h"
|
||||||
#include "nsCSSRendering.h"
|
#include "nsCSSRendering.h"
|
||||||
#include "nsTHashMap.h"
|
#include "nsTHashMap.h"
|
||||||
|
#include "nsDeckFrame.h"
|
||||||
#include "nsDisplayList.h"
|
#include "nsDisplayList.h"
|
||||||
#include "nsFlexContainerFrame.h"
|
#include "nsFlexContainerFrame.h"
|
||||||
#include "nsFontInflationData.h"
|
#include "nsFontInflationData.h"
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
#include "nsRepeatService.h"
|
#include "nsRepeatService.h"
|
||||||
#include "nsFloatManager.h"
|
#include "nsFloatManager.h"
|
||||||
#include "nsSprocketLayout.h"
|
#include "nsSprocketLayout.h"
|
||||||
|
#include "nsStackLayout.h"
|
||||||
#include "nsTextControlFrame.h"
|
#include "nsTextControlFrame.h"
|
||||||
#include "txMozillaXSLTProcessor.h"
|
#include "txMozillaXSLTProcessor.h"
|
||||||
#include "nsTreeSanitizer.h"
|
#include "nsTreeSanitizer.h"
|
||||||
@@ -328,6 +329,7 @@ void nsLayoutStatics::Shutdown() {
|
|||||||
nsColorNames::ReleaseTable();
|
nsColorNames::ReleaseTable();
|
||||||
nsCSSProps::ReleaseTable();
|
nsCSSProps::ReleaseTable();
|
||||||
nsRepeatService::Shutdown();
|
nsRepeatService::Shutdown();
|
||||||
|
nsStackLayout::Shutdown();
|
||||||
|
|
||||||
nsXULContentUtils::Finish();
|
nsXULContentUtils::Finish();
|
||||||
nsXULPrototypeCache::ReleaseGlobals();
|
nsXULPrototypeCache::ReleaseGlobals();
|
||||||
|
|||||||
16
layout/forms/crashtests/378413-1.xhtml
Normal file
16
layout/forms/crashtests/378413-1.xhtml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<body style="direction: rtl;">
|
||||||
|
|
||||||
|
<form style="display: -moz-deck; width: 1em;">
|
||||||
|
<fieldset>
|
||||||
|
<legend>Your name</legend>
|
||||||
|
<input type="text" name="name" size="20"/>
|
||||||
|
</fieldset>
|
||||||
|
<fieldset>
|
||||||
|
<legend>Your E-mail address</legend>
|
||||||
|
<input type="text" name="email" size="25"/>
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -20,6 +20,7 @@ load 370703-1.html
|
|||||||
load 370940-1.html
|
load 370940-1.html
|
||||||
load 370967.html
|
load 370967.html
|
||||||
load 378369.html
|
load 378369.html
|
||||||
|
load 378413-1.xhtml
|
||||||
load 380116-1.xhtml
|
load 380116-1.xhtml
|
||||||
load 382610-1.html
|
load 382610-1.html
|
||||||
load 383887-1.html
|
load 383887-1.html
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ FRAME_CLASSES = [
|
|||||||
Frame("nsComboboxDisplayFrame", "ComboboxDisplay", NOT_LEAF),
|
Frame("nsComboboxDisplayFrame", "ComboboxDisplay", NOT_LEAF),
|
||||||
Frame("nsContinuingTextFrame", "Text", LEAF),
|
Frame("nsContinuingTextFrame", "Text", LEAF),
|
||||||
Frame("nsDateTimeControlFrame", "DateTimeControl", NOT_LEAF),
|
Frame("nsDateTimeControlFrame", "DateTimeControl", NOT_LEAF),
|
||||||
|
Frame("nsDeckFrame", "Deck", NOT_LEAF),
|
||||||
Frame("nsDocElementBoxFrame", "DocElementBox", NOT_LEAF),
|
Frame("nsDocElementBoxFrame", "DocElementBox", NOT_LEAF),
|
||||||
Frame("nsFieldSetFrame", "FieldSet", NOT_LEAF),
|
Frame("nsFieldSetFrame", "FieldSet", NOT_LEAF),
|
||||||
Frame("nsFileControlFrame", "Block", LEAF),
|
Frame("nsFileControlFrame", "Block", LEAF),
|
||||||
|
|||||||
14
layout/generic/crashtests/370866-1.xhtml
Normal file
14
layout/generic/crashtests/370866-1.xhtml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<table style="display: -moz-deck;"><tbody><tr><td>
|
||||||
|
<span style="position: relative;"><marquee><marquee><span style="position: absolute;">X</span></marquee></marquee></span>
|
||||||
|
</td></tr></tbody></table>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
17
layout/generic/crashtests/381786-1.html
Normal file
17
layout/generic/crashtests/381786-1.html
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div style="display:-moz-deck">
|
||||||
|
<div>
|
||||||
|
<span style="float: right; width: 0;">x</span>
|
||||||
|
</div>
|
||||||
|
<div style="position: relative;">
|
||||||
|
<span style="float: right;">
|
||||||
|
<span style="position: absolute;">y</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
16
layout/generic/crashtests/862947-1.html
Normal file
16
layout/generic/crashtests/862947-1.html
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<style>
|
||||||
|
|
||||||
|
div { display: flex; }
|
||||||
|
div:after { display: -moz-deck; content: counter(b); }
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div></div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -87,6 +87,7 @@ load 370174-2.html
|
|||||||
load 370174-3.html
|
load 370174-3.html
|
||||||
load 370699-1.html
|
load 370699-1.html
|
||||||
load 370794-1.html
|
load 370794-1.html
|
||||||
|
load 370866-1.xhtml
|
||||||
load 370884-1.xhtml
|
load 370884-1.xhtml
|
||||||
load 371348-1.xhtml
|
load 371348-1.xhtml
|
||||||
load 371561-1.html
|
load 371561-1.html
|
||||||
@@ -103,6 +104,7 @@ load 379217-2.xhtml
|
|||||||
load 379917-1.xhtml
|
load 379917-1.xhtml
|
||||||
load 380012-1.html
|
load 380012-1.html
|
||||||
load 381152-1.html
|
load 381152-1.html
|
||||||
|
load 381786-1.html
|
||||||
load 382129-1.xhtml
|
load 382129-1.xhtml
|
||||||
load 382131-1.html
|
load 382131-1.html
|
||||||
load 382199-1.html
|
load 382199-1.html
|
||||||
@@ -534,6 +536,7 @@ asserts(8-46) load 850931.html # nested multicols, inner multicol has column-wid
|
|||||||
load 851396-1.html
|
load 851396-1.html
|
||||||
load 854263-1.html
|
load 854263-1.html
|
||||||
load 862185.html
|
load 862185.html
|
||||||
|
load 862947-1.html
|
||||||
load 863935.html
|
load 863935.html
|
||||||
load 866547-1.html
|
load 866547-1.html
|
||||||
needs-focus pref(accessibility.browsewithcaret,true) load 868906.html
|
needs-focus pref(accessibility.browsewithcaret,true) load 868906.html
|
||||||
|
|||||||
@@ -100,6 +100,7 @@
|
|||||||
#include "nsBlockFrame.h"
|
#include "nsBlockFrame.h"
|
||||||
#include "nsDisplayList.h"
|
#include "nsDisplayList.h"
|
||||||
#include "nsChangeHint.h"
|
#include "nsChangeHint.h"
|
||||||
|
#include "nsDeckFrame.h"
|
||||||
#include "nsSubDocumentFrame.h"
|
#include "nsSubDocumentFrame.h"
|
||||||
#include "RetainedDisplayListBuilder.h"
|
#include "RetainedDisplayListBuilder.h"
|
||||||
|
|
||||||
@@ -374,19 +375,17 @@ bool nsIFrame::IsVisibleConsideringAncestors(uint32_t aFlags) const {
|
|||||||
const nsIFrame* frame = this;
|
const nsIFrame* frame = this;
|
||||||
while (frame) {
|
while (frame) {
|
||||||
nsView* view = frame->GetView();
|
nsView* view = frame->GetView();
|
||||||
if (view && view->GetVisibility() == nsViewVisibility_kHide) {
|
if (view && view->GetVisibility() == nsViewVisibility_kHide) return false;
|
||||||
return false;
|
|
||||||
|
if (this != frame && frame->HidesContent()) return false;
|
||||||
|
|
||||||
|
nsIFrame* parent = frame->GetParent();
|
||||||
|
nsDeckFrame* deck = do_QueryFrame(parent);
|
||||||
|
if (deck) {
|
||||||
|
if (deck->GetSelectedBox() != frame) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frame->StyleUIReset()->mMozSubtreeHiddenOnlyVisually) {
|
if (parent) {
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this != frame && frame->HidesContent()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nsIFrame* parent = frame->GetParent()) {
|
|
||||||
frame = parent;
|
frame = parent;
|
||||||
} else {
|
} else {
|
||||||
parent = nsLayoutUtils::GetCrossDocParentFrameInProcess(frame);
|
parent = nsLayoutUtils::GetCrossDocParentFrameInProcess(frame);
|
||||||
@@ -1287,10 +1286,6 @@ void nsIFrame::DidSetComputedStyle(ComputedStyle* aOldComputedStyle) {
|
|||||||
scrollableFrame->PostPendingResnap();
|
scrollableFrame->PostPendingResnap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (StyleUIReset()->mMozSubtreeHiddenOnlyVisually &&
|
|
||||||
!aOldComputedStyle->StyleUIReset()->mMozSubtreeHiddenOnlyVisually) {
|
|
||||||
PresShell::ClearMouseCapture(this);
|
|
||||||
}
|
|
||||||
} else { // !aOldComputedStyle
|
} else { // !aOldComputedStyle
|
||||||
handleStickyChange = disp->mPosition == StylePositionProperty::Sticky;
|
handleStickyChange = disp->mPosition == StylePositionProperty::Sticky;
|
||||||
}
|
}
|
||||||
@@ -3988,21 +3983,22 @@ static bool ShouldSkipFrame(nsDisplayListBuilder* aBuilder,
|
|||||||
if (aBuilder->IsBackgroundOnly()) {
|
if (aBuilder->IsBackgroundOnly()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aBuilder->IsForGenerateGlyphMask() &&
|
if (aBuilder->IsForGenerateGlyphMask() &&
|
||||||
(!aFrame->IsTextFrame() && aFrame->IsLeaf())) {
|
(!aFrame->IsTextFrame() && aFrame->IsLeaf())) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The placeholder frame should have the same content as the OOF frame.
|
// The placeholder frame should have the same content as the OOF frame.
|
||||||
if (aBuilder->GetSelectedFramesOnly() &&
|
if (aBuilder->GetSelectedFramesOnly() &&
|
||||||
(aFrame->IsLeaf() && !aFrame->IsSelected())) {
|
(aFrame->IsLeaf() && !aFrame->IsSelected())) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const nsFrameState skipFlags =
|
static const nsFrameState skipFlags =
|
||||||
(NS_FRAME_TOO_DEEP_IN_FRAME_TREE | NS_FRAME_IS_NONDISPLAY);
|
(NS_FRAME_TOO_DEEP_IN_FRAME_TREE | NS_FRAME_IS_NONDISPLAY);
|
||||||
if (aFrame->HasAnyStateBits(skipFlags)) {
|
|
||||||
return true;
|
return aFrame->HasAnyStateBits(skipFlags);
|
||||||
}
|
|
||||||
return aFrame->StyleUIReset()->mMozSubtreeHiddenOnlyVisually;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
|
void nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
|
||||||
|
|||||||
8
layout/reftests/bugs/411367-3-ref.html
Normal file
8
layout/reftests/bugs/411367-3-ref.html
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div style="display: -moz-deck;" id="s">x</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
8
layout/reftests/bugs/411367-3.html
Normal file
8
layout/reftests/bugs/411367-3.html
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
</head>
|
||||||
|
<body onload="document.getElementById('s').firstChild.data = 'x';">
|
||||||
|
<div style="display: -moz-deck;" id="s"> </div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -926,6 +926,7 @@ fuzzy-if(winWidget,0-123,0-1900) fuzzy-if(swgl,0-1,0-39) == 409659-1d.html 40965
|
|||||||
== 410621-1.html 410621-1-ref.html
|
== 410621-1.html 410621-1-ref.html
|
||||||
== 411059-1.html 411059-1-ref.html
|
== 411059-1.html 411059-1-ref.html
|
||||||
fuzzy-if(winWidget,46-129,652-770) == 411334-1.xml 411334-1-ref.xml
|
fuzzy-if(winWidget,46-129,652-770) == 411334-1.xml 411334-1-ref.xml
|
||||||
|
== 411367-3.html 411367-3-ref.html
|
||||||
== 411585-1.html 411585-1-ref.html
|
== 411585-1.html 411585-1-ref.html
|
||||||
== 411585-2.html 411585-2-ref.html
|
== 411585-2.html 411585-2-ref.html
|
||||||
fails == 411585-3.html 411585-3-ref.html # bug 426909
|
fails == 411585-3.html 411585-3-ref.html # bug 426909
|
||||||
|
|||||||
@@ -607,7 +607,6 @@ cbindgen-types = [
|
|||||||
{ gecko = "StyleFontStyle", servo = "crate::values::computed::font::FontStyle" },
|
{ gecko = "StyleFontStyle", servo = "crate::values::computed::font::FontStyle" },
|
||||||
{ gecko = "StyleFontWeight", servo = "crate::values::computed::font::FontWeight" },
|
{ gecko = "StyleFontWeight", servo = "crate::values::computed::font::FontWeight" },
|
||||||
{ gecko = "StyleFontStretch", servo = "crate::values::computed::font::FontStretch" },
|
{ gecko = "StyleFontStretch", servo = "crate::values::computed::font::FontStretch" },
|
||||||
{ gecko = "StyleBoolInteger", servo = "crate::values::computed::BoolInteger" },
|
|
||||||
]
|
]
|
||||||
|
|
||||||
mapped-generic-types = [
|
mapped-generic-types = [
|
||||||
|
|||||||
@@ -91,6 +91,8 @@ enum class StyleDisplay : uint16_t {
|
|||||||
StyleDisplayFrom(StyleDisplayOutside::Block, StyleDisplayInside::MozBox),
|
StyleDisplayFrom(StyleDisplayOutside::Block, StyleDisplayInside::MozBox),
|
||||||
MozInlineBox =
|
MozInlineBox =
|
||||||
StyleDisplayFrom(StyleDisplayOutside::Inline, StyleDisplayInside::MozBox),
|
StyleDisplayFrom(StyleDisplayOutside::Inline, StyleDisplayInside::MozBox),
|
||||||
|
MozDeck =
|
||||||
|
StyleDisplayFrom(StyleDisplayOutside::XUL, StyleDisplayInside::MozDeck),
|
||||||
MozPopup =
|
MozPopup =
|
||||||
StyleDisplayFrom(StyleDisplayOutside::XUL, StyleDisplayInside::MozPopup),
|
StyleDisplayFrom(StyleDisplayOutside::XUL, StyleDisplayInside::MozPopup),
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3213,8 +3213,7 @@ nsChangeHint nsStyleUI::CalcDifference(const nsStyleUI& aNewData) const {
|
|||||||
nsStyleUIReset::nsStyleUIReset(const Document& aDocument)
|
nsStyleUIReset::nsStyleUIReset(const Document& aDocument)
|
||||||
: mUserSelect(StyleUserSelect::Auto),
|
: mUserSelect(StyleUserSelect::Auto),
|
||||||
mScrollbarWidth(StyleScrollbarWidth::Auto),
|
mScrollbarWidth(StyleScrollbarWidth::Auto),
|
||||||
mMozForceBrokenImageIcon(false),
|
mMozForceBrokenImageIcon(0),
|
||||||
mMozSubtreeHiddenOnlyVisually(false),
|
|
||||||
mIMEMode(StyleImeMode::Auto),
|
mIMEMode(StyleImeMode::Auto),
|
||||||
mWindowDragging(StyleWindowDragging::Default),
|
mWindowDragging(StyleWindowDragging::Default),
|
||||||
mWindowShadow(StyleWindowShadow::Default),
|
mWindowShadow(StyleWindowShadow::Default),
|
||||||
@@ -3251,7 +3250,6 @@ nsStyleUIReset::nsStyleUIReset(const nsStyleUIReset& aSource)
|
|||||||
: mUserSelect(aSource.mUserSelect),
|
: mUserSelect(aSource.mUserSelect),
|
||||||
mScrollbarWidth(aSource.mScrollbarWidth),
|
mScrollbarWidth(aSource.mScrollbarWidth),
|
||||||
mMozForceBrokenImageIcon(aSource.mMozForceBrokenImageIcon),
|
mMozForceBrokenImageIcon(aSource.mMozForceBrokenImageIcon),
|
||||||
mMozSubtreeHiddenOnlyVisually(aSource.mMozSubtreeHiddenOnlyVisually),
|
|
||||||
mIMEMode(aSource.mIMEMode),
|
mIMEMode(aSource.mIMEMode),
|
||||||
mWindowDragging(aSource.mWindowDragging),
|
mWindowDragging(aSource.mWindowDragging),
|
||||||
mWindowShadow(aSource.mWindowShadow),
|
mWindowShadow(aSource.mWindowShadow),
|
||||||
@@ -3289,9 +3287,6 @@ nsChangeHint nsStyleUIReset::CalcDifference(
|
|||||||
if (mMozForceBrokenImageIcon != aNewData.mMozForceBrokenImageIcon) {
|
if (mMozForceBrokenImageIcon != aNewData.mMozForceBrokenImageIcon) {
|
||||||
hint |= nsChangeHint_ReconstructFrame;
|
hint |= nsChangeHint_ReconstructFrame;
|
||||||
}
|
}
|
||||||
if (mMozSubtreeHiddenOnlyVisually != aNewData.mMozSubtreeHiddenOnlyVisually) {
|
|
||||||
hint |= nsChangeHint_RepaintFrame;
|
|
||||||
}
|
|
||||||
if (mScrollbarWidth != aNewData.mScrollbarWidth) {
|
if (mScrollbarWidth != aNewData.mScrollbarWidth) {
|
||||||
// For scrollbar-width change, we need some special handling similar
|
// For scrollbar-width change, we need some special handling similar
|
||||||
// to overflow properties. Specifically, we may need to reconstruct
|
// to overflow properties. Specifically, we may need to reconstruct
|
||||||
|
|||||||
@@ -1863,8 +1863,7 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleUIReset {
|
|||||||
return mAnimations[aIndex % mAnimationTimelineCount].GetTimeline();
|
return mAnimations[aIndex % mAnimationTimelineCount].GetTimeline();
|
||||||
}
|
}
|
||||||
|
|
||||||
mozilla::StyleBoolInteger mMozForceBrokenImageIcon;
|
uint8_t mMozForceBrokenImageIcon; // (0 if not forcing, otherwise forcing)
|
||||||
mozilla::StyleBoolInteger mMozSubtreeHiddenOnlyVisually;
|
|
||||||
mozilla::StyleImeMode mIMEMode;
|
mozilla::StyleImeMode mIMEMode;
|
||||||
mozilla::StyleWindowDragging mWindowDragging;
|
mozilla::StyleWindowDragging mWindowDragging;
|
||||||
mozilla::StyleWindowShadow mWindowShadow;
|
mozilla::StyleWindowShadow mWindowShadow;
|
||||||
|
|||||||
@@ -104,7 +104,6 @@ const char* gInaccessibleProperties[] = {
|
|||||||
"-moz-min-font-size-ratio", // parsed by UA sheets only
|
"-moz-min-font-size-ratio", // parsed by UA sheets only
|
||||||
"-moz-box-layout", // chrome-only internal properties
|
"-moz-box-layout", // chrome-only internal properties
|
||||||
"-moz-font-smoothing-background-color", // chrome-only internal properties
|
"-moz-font-smoothing-background-color", // chrome-only internal properties
|
||||||
"-moz-subtree-hidden-only-visually", // chrome-only internal properties
|
|
||||||
"-moz-window-input-region-margin", // chrome-only internal properties
|
"-moz-window-input-region-margin", // chrome-only internal properties
|
||||||
"-moz-window-opacity", // chrome-only internal properties
|
"-moz-window-opacity", // chrome-only internal properties
|
||||||
"-moz-window-transform", // chrome-only internal properties
|
"-moz-window-transform", // chrome-only internal properties
|
||||||
|
|||||||
@@ -134,6 +134,8 @@ skip-if = true # Bug 701060
|
|||||||
[test_bug418986-2.html]
|
[test_bug418986-2.html]
|
||||||
[test_bug437915.html]
|
[test_bug437915.html]
|
||||||
[test_bug450191.html]
|
[test_bug450191.html]
|
||||||
|
[test_bug453896_deck.html]
|
||||||
|
support-files = bug453896_iframe.html
|
||||||
[test_bug470769.html]
|
[test_bug470769.html]
|
||||||
[test_bug499655.html]
|
[test_bug499655.html]
|
||||||
[test_bug499655.xhtml]
|
[test_bug499655.xhtml]
|
||||||
|
|||||||
42
layout/style/test/test_bug453896_deck.html
Normal file
42
layout/style/test/test_bug453896_deck.html
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<!--
|
||||||
|
https://bugzilla.mozilla.org/show_bug.cgi?id=453896
|
||||||
|
-->
|
||||||
|
<head>
|
||||||
|
<title>Test for Bug 453896</title>
|
||||||
|
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||||
|
</head>
|
||||||
|
<body onload="run()">
|
||||||
|
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=453896">Mozilla Bug 453896</a>
|
||||||
|
<div id="display">
|
||||||
|
|
||||||
|
<div style="display:-moz-deck; height: 300px; width: 300px;">
|
||||||
|
<iframe src="about:blank"></iframe>
|
||||||
|
<iframe id="subdoc" src="bug453896_iframe.html"></iframe>
|
||||||
|
<iframe src="about:blank"></iframe>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<pre id="test">
|
||||||
|
<script class="testbody" type="text/javascript">
|
||||||
|
|
||||||
|
/** Test for Bug 453896 **/
|
||||||
|
|
||||||
|
function run()
|
||||||
|
{
|
||||||
|
var iframe = document.getElementById("subdoc");
|
||||||
|
var subdoc = iframe.contentDocument;
|
||||||
|
var subwin = iframe.contentWindow;
|
||||||
|
|
||||||
|
subwin.run(window);
|
||||||
|
SimpleTest.finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</pre>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
@@ -19,6 +19,7 @@ const NON_CONTENT_ACCESSIBLE_VALUES = {
|
|||||||
"-moz-autofill-background",
|
"-moz-autofill-background",
|
||||||
],
|
],
|
||||||
"display": [
|
"display": [
|
||||||
|
"-moz-deck",
|
||||||
"-moz-popup",
|
"-moz-popup",
|
||||||
"-moz-box",
|
"-moz-box",
|
||||||
"-moz-inline-box",
|
"-moz-inline-box",
|
||||||
|
|||||||
6
layout/xul/crashtests/290743.html
Normal file
6
layout/xul/crashtests/290743.html
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<html>
|
||||||
|
<head><title>Testcase bug 290743 - This display:-moz-deck testcase freezes Mozilla</title></head>
|
||||||
|
<body style="display:-moz-deck;">
|
||||||
|
<input type="radio"><input type="radio">
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
12
layout/xul/crashtests/311457-1.html
Normal file
12
layout/xul/crashtests/311457-1.html
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<html><head>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div style="display: -moz-deck"><div style="display: -moz-popup"></div></div>
|
||||||
|
|
||||||
|
<div style="position: relative">Y</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
5
layout/xul/crashtests/374102-1.xhtml
Normal file
5
layout/xul/crashtests/374102-1.xhtml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||||
|
<tabpanels>
|
||||||
|
<treechildren style="display: -moz-deck;"/>
|
||||||
|
</tabpanels>
|
||||||
|
</window>
|
||||||
31
layout/xul/crashtests/399013.xhtml
Normal file
31
layout/xul/crashtests/399013.xhtml
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||||
|
<menulist id="b" style="display: -moz-box;">
|
||||||
|
<panel id="c" style=" position: absolute;">
|
||||||
|
<popup onunderflow="document.getElementById('c').removeAttribute('style')"/>
|
||||||
|
</panel>
|
||||||
|
<menupopup id="a" style="display: -moz-box;">
|
||||||
|
<menulist/>
|
||||||
|
</menupopup>
|
||||||
|
<panel style="display: -moz-deck;" onoverflow="document.getElementById('b').removeAttribute('style')">
|
||||||
|
<popup style="display: -moz-deck;"/>
|
||||||
|
</panel>
|
||||||
|
</menulist>
|
||||||
|
|
||||||
|
<script id="script" xmlns="http://www.w3.org/1999/xhtml"><![CDATA[
|
||||||
|
function doe() {
|
||||||
|
document.getElementById('c').removeAttribute('style');
|
||||||
|
document.documentElement.clientHeight;
|
||||||
|
document.getElementById('b').removeAttribute('style');
|
||||||
|
document.getElementById('a').setAttribute('selected', 'true');
|
||||||
|
document.getElementById('a').setAttribute('style', 'position: fixed;');
|
||||||
|
document.documentElement.clientHeight;
|
||||||
|
document.getElementById('a').removeAttribute('style');
|
||||||
|
}
|
||||||
|
|
||||||
|
function doe2() {
|
||||||
|
window.location.reload();
|
||||||
|
}
|
||||||
|
setTimeout(doe2, 200);
|
||||||
|
setTimeout(doe,100);
|
||||||
|
]]></script>
|
||||||
|
</window>
|
||||||
@@ -5,10 +5,12 @@ load chrome://reftest/content/crashtests/layout/xul/crashtests/151826-1.xhtml
|
|||||||
load chrome://reftest/content/crashtests/layout/xul/crashtests/168724-1.xhtml
|
load chrome://reftest/content/crashtests/layout/xul/crashtests/168724-1.xhtml
|
||||||
load chrome://reftest/content/crashtests/layout/xul/crashtests/189814-1.xhtml
|
load chrome://reftest/content/crashtests/layout/xul/crashtests/189814-1.xhtml
|
||||||
skip-if(Android) load chrome://reftest/content/crashtests/layout/xul/crashtests/289410-1.xhtml
|
skip-if(Android) load chrome://reftest/content/crashtests/layout/xul/crashtests/289410-1.xhtml
|
||||||
|
load 290743.html
|
||||||
load chrome://reftest/content/crashtests/layout/xul/crashtests/291702-1.xhtml
|
load chrome://reftest/content/crashtests/layout/xul/crashtests/291702-1.xhtml
|
||||||
load chrome://reftest/content/crashtests/layout/xul/crashtests/291702-2.xhtml
|
load chrome://reftest/content/crashtests/layout/xul/crashtests/291702-2.xhtml
|
||||||
load chrome://reftest/content/crashtests/layout/xul/crashtests/291702-3.xhtml
|
load chrome://reftest/content/crashtests/layout/xul/crashtests/291702-3.xhtml
|
||||||
load chrome://reftest/content/crashtests/layout/xul/crashtests/294371-1.xhtml
|
load chrome://reftest/content/crashtests/layout/xul/crashtests/294371-1.xhtml
|
||||||
|
load 311457-1.html
|
||||||
load chrome://reftest/content/crashtests/layout/xul/crashtests/322786-1.xhtml
|
load chrome://reftest/content/crashtests/layout/xul/crashtests/322786-1.xhtml
|
||||||
skip-if(Android) load chrome://reftest/content/crashtests/layout/xul/crashtests/325377.xhtml
|
skip-if(Android) load chrome://reftest/content/crashtests/layout/xul/crashtests/325377.xhtml
|
||||||
skip-if(Android) load chrome://reftest/content/crashtests/layout/xul/crashtests/326879-1.xhtml
|
skip-if(Android) load chrome://reftest/content/crashtests/layout/xul/crashtests/326879-1.xhtml
|
||||||
@@ -22,6 +24,7 @@ load chrome://reftest/content/crashtests/layout/xul/crashtests/366112-1.xhtml
|
|||||||
skip-if(Android) load chrome://reftest/content/crashtests/layout/xul/crashtests/366203-1.xhtml
|
skip-if(Android) load chrome://reftest/content/crashtests/layout/xul/crashtests/366203-1.xhtml
|
||||||
load 367185-1.xhtml
|
load 367185-1.xhtml
|
||||||
load 369942-1.xhtml
|
load 369942-1.xhtml
|
||||||
|
skip-if(Android) load chrome://reftest/content/crashtests/layout/xul/crashtests/374102-1.xhtml
|
||||||
load 376137-1.html
|
load 376137-1.html
|
||||||
load 376137-2.html
|
load 376137-2.html
|
||||||
load 377592-1.svg
|
load 377592-1.svg
|
||||||
@@ -36,6 +39,7 @@ load 384871-1.html
|
|||||||
load chrome://reftest/content/crashtests/layout/xul/crashtests/386642.xhtml
|
load chrome://reftest/content/crashtests/layout/xul/crashtests/386642.xhtml
|
||||||
load chrome://reftest/content/crashtests/layout/xul/crashtests/387080-1.xhtml
|
load chrome://reftest/content/crashtests/layout/xul/crashtests/387080-1.xhtml
|
||||||
load 391974-1.html
|
load 391974-1.html
|
||||||
|
skip-if(Android) load chrome://reftest/content/crashtests/layout/xul/crashtests/399013.xhtml
|
||||||
load 402912-1.xhtml
|
load 402912-1.xhtml
|
||||||
load 404192.xhtml
|
load 404192.xhtml
|
||||||
load chrome://reftest/content/crashtests/layout/xul/crashtests/408904-1.xhtml
|
load chrome://reftest/content/crashtests/layout/xul/crashtests/408904-1.xhtml
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ UNIFIED_SOURCES += [
|
|||||||
"nsBoxFrame.cpp",
|
"nsBoxFrame.cpp",
|
||||||
"nsBoxLayout.cpp",
|
"nsBoxLayout.cpp",
|
||||||
"nsBoxLayoutState.cpp",
|
"nsBoxLayoutState.cpp",
|
||||||
|
"nsDeckFrame.cpp",
|
||||||
"nsDocElementBoxFrame.cpp",
|
"nsDocElementBoxFrame.cpp",
|
||||||
"nsImageBoxFrame.cpp",
|
"nsImageBoxFrame.cpp",
|
||||||
"nsLeafBoxFrame.cpp",
|
"nsLeafBoxFrame.cpp",
|
||||||
@@ -38,6 +39,7 @@ UNIFIED_SOURCES += [
|
|||||||
"nsSliderFrame.cpp",
|
"nsSliderFrame.cpp",
|
||||||
"nsSplitterFrame.cpp",
|
"nsSplitterFrame.cpp",
|
||||||
"nsSprocketLayout.cpp",
|
"nsSprocketLayout.cpp",
|
||||||
|
"nsStackLayout.cpp",
|
||||||
"nsTextBoxFrame.cpp",
|
"nsTextBoxFrame.cpp",
|
||||||
"nsXULPopupManager.cpp",
|
"nsXULPopupManager.cpp",
|
||||||
"nsXULTooltipListener.cpp",
|
"nsXULTooltipListener.cpp",
|
||||||
|
|||||||
@@ -308,7 +308,8 @@ nsresult nsIFrame::SyncXULLayout(nsBoxLayoutState& aBoxLayoutState) {
|
|||||||
nsresult nsIFrame::XULRedraw(nsBoxLayoutState& aState) {
|
nsresult nsIFrame::XULRedraw(nsBoxLayoutState& aState) {
|
||||||
if (aState.PaintingDisabled()) return NS_OK;
|
if (aState.PaintingDisabled()) return NS_OK;
|
||||||
|
|
||||||
// Unclear whether we could get away with just InvalidateFrame().
|
// nsStackLayout, at least, expects us to repaint descendants even
|
||||||
|
// if a damage rect is provided
|
||||||
InvalidateFrameSubtree();
|
InvalidateFrameSubtree();
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|||||||
283
layout/xul/nsDeckFrame.cpp
Normal file
283
layout/xul/nsDeckFrame.cpp
Normal file
@@ -0,0 +1,283 @@
|
|||||||
|
/* -*- 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/. */
|
||||||
|
|
||||||
|
//
|
||||||
|
// Eric Vaughan
|
||||||
|
// Netscape Communications
|
||||||
|
//
|
||||||
|
// See documentation in associated header file
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "nsDeckFrame.h"
|
||||||
|
#include "mozilla/ComputedStyle.h"
|
||||||
|
#include "mozilla/PresShell.h"
|
||||||
|
#include "nsLayoutUtils.h"
|
||||||
|
#include "nsPresContext.h"
|
||||||
|
#include "nsIContent.h"
|
||||||
|
#include "nsCOMPtr.h"
|
||||||
|
#include "nsNameSpaceManager.h"
|
||||||
|
#include "nsGkAtoms.h"
|
||||||
|
#include "nsHTMLParts.h"
|
||||||
|
#include "nsCSSRendering.h"
|
||||||
|
#include "nsViewManager.h"
|
||||||
|
#include "nsBoxLayoutState.h"
|
||||||
|
#include "nsStackLayout.h"
|
||||||
|
#include "nsDisplayList.h"
|
||||||
|
#include "nsContainerFrame.h"
|
||||||
|
#include "nsContentUtils.h"
|
||||||
|
#include "nsXULPopupManager.h"
|
||||||
|
#include "nsImageBoxFrame.h"
|
||||||
|
#include "nsImageFrame.h"
|
||||||
|
|
||||||
|
#ifdef ACCESSIBILITY
|
||||||
|
# include "nsAccessibilityService.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
using namespace mozilla;
|
||||||
|
|
||||||
|
nsIFrame* NS_NewDeckFrame(PresShell* aPresShell, ComputedStyle* aStyle) {
|
||||||
|
return new (aPresShell) nsDeckFrame(aStyle, aPresShell->GetPresContext());
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMPL_FRAMEARENA_HELPERS(nsDeckFrame)
|
||||||
|
|
||||||
|
NS_QUERYFRAME_HEAD(nsDeckFrame)
|
||||||
|
NS_QUERYFRAME_ENTRY(nsDeckFrame)
|
||||||
|
NS_QUERYFRAME_TAIL_INHERITING(nsBoxFrame)
|
||||||
|
|
||||||
|
nsDeckFrame::nsDeckFrame(ComputedStyle* aStyle, nsPresContext* aPresContext)
|
||||||
|
: nsBoxFrame(aStyle, aPresContext, kClassID) {
|
||||||
|
nsCOMPtr<nsBoxLayout> layout;
|
||||||
|
NS_NewStackLayout(layout);
|
||||||
|
SetXULLayoutManager(layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult nsDeckFrame::AttributeChanged(int32_t aNameSpaceID, nsAtom* aAttribute,
|
||||||
|
int32_t aModType) {
|
||||||
|
nsresult rv =
|
||||||
|
nsBoxFrame::AttributeChanged(aNameSpaceID, aAttribute, aModType);
|
||||||
|
|
||||||
|
// if the index changed hide the old element and make the new element visible
|
||||||
|
if (aAttribute == nsGkAtoms::selectedIndex) {
|
||||||
|
IndexChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nsDeckFrame::Init(nsIContent* aContent, nsContainerFrame* aParent,
|
||||||
|
nsIFrame* aPrevInFlow) {
|
||||||
|
nsBoxFrame::Init(aContent, aParent, aPrevInFlow);
|
||||||
|
|
||||||
|
mIndex = GetSelectedIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
void nsDeckFrame::ShowBox(nsIFrame* aBox) { Animate(aBox, true); }
|
||||||
|
|
||||||
|
void nsDeckFrame::HideBox(nsIFrame* aBox) {
|
||||||
|
PresShell::ClearMouseCapture(aBox);
|
||||||
|
Animate(aBox, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nsDeckFrame::IndexChanged() {
|
||||||
|
// did the index change?
|
||||||
|
int32_t index = GetSelectedIndex();
|
||||||
|
|
||||||
|
if (index == mIndex) return;
|
||||||
|
|
||||||
|
// redraw
|
||||||
|
InvalidateFrame();
|
||||||
|
|
||||||
|
// hide the currently showing box
|
||||||
|
nsIFrame* currentBox = GetSelectedBox();
|
||||||
|
if (currentBox) // only hide if it exists
|
||||||
|
HideBox(currentBox);
|
||||||
|
|
||||||
|
mSelectedBoxCache = nullptr;
|
||||||
|
|
||||||
|
mIndex = index;
|
||||||
|
|
||||||
|
ShowBox(GetSelectedBox());
|
||||||
|
|
||||||
|
#ifdef ACCESSIBILITY
|
||||||
|
nsAccessibilityService* accService = GetAccService();
|
||||||
|
if (accService) {
|
||||||
|
accService->DeckPanelSwitched(PresContext()->GetPresShell(), mContent,
|
||||||
|
currentBox, GetSelectedBox());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Force any popups that might be anchored on elements within hidden
|
||||||
|
// box to update.
|
||||||
|
nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
|
||||||
|
if (pm && currentBox) {
|
||||||
|
pm->UpdatePopupPositions(currentBox->PresContext()->RefreshDriver());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t nsDeckFrame::GetSelectedIndex() {
|
||||||
|
// default index is 0
|
||||||
|
int32_t index = 0;
|
||||||
|
|
||||||
|
// get the index attribute
|
||||||
|
nsAutoString value;
|
||||||
|
if (mContent->AsElement()->GetAttr(kNameSpaceID_None,
|
||||||
|
nsGkAtoms::selectedIndex, value)) {
|
||||||
|
nsresult error;
|
||||||
|
|
||||||
|
// convert it to an integer
|
||||||
|
index = value.ToInteger(&error);
|
||||||
|
}
|
||||||
|
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsIFrame* nsDeckFrame::GetSelectedBox() {
|
||||||
|
if (!mSelectedBoxCache && mIndex >= 0) {
|
||||||
|
mSelectedBoxCache = (mIndex >= 0) ? mFrames.FrameAt(mIndex) : nullptr;
|
||||||
|
}
|
||||||
|
return mSelectedBoxCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nsDeckFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||||
|
const nsDisplayListSet& aLists) {
|
||||||
|
// if a tab is hidden all its children are too.
|
||||||
|
if (StyleVisibility()->mVisible == StyleVisibility::Hidden) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
nsBoxFrame::BuildDisplayList(aBuilder, aLists);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nsDeckFrame::RemoveFrame(ChildListID aListID, nsIFrame* aOldFrame) {
|
||||||
|
nsIFrame* currentFrame = GetSelectedBox();
|
||||||
|
if (aOldFrame == currentFrame) {
|
||||||
|
mSelectedBoxCache = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentFrame && aOldFrame && currentFrame != aOldFrame) {
|
||||||
|
// If the frame we're removing is at an index that's less
|
||||||
|
// than mIndex, that means we're going to be shifting indexes
|
||||||
|
// by 1.
|
||||||
|
//
|
||||||
|
// We attempt to keep the same child displayed by automatically
|
||||||
|
// updating our internal notion of the current index.
|
||||||
|
int32_t removedIndex = mFrames.IndexOf(aOldFrame);
|
||||||
|
MOZ_ASSERT(removedIndex >= 0,
|
||||||
|
"A deck child was removed that was not in mFrames.");
|
||||||
|
if (removedIndex < mIndex) {
|
||||||
|
// This shouldn't invalidate our cache, but be really paranoid, it's not
|
||||||
|
// that important to keep our cache here.
|
||||||
|
mSelectedBoxCache = nullptr;
|
||||||
|
|
||||||
|
mIndex--;
|
||||||
|
// This is going to cause us to handle the index change in IndexedChanged,
|
||||||
|
// but since the new index will match mIndex, it's essentially a noop.
|
||||||
|
nsContentUtils::AddScriptRunner(new nsSetAttrRunnable(
|
||||||
|
mContent->AsElement(), nsGkAtoms::selectedIndex, mIndex));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nsBoxFrame::RemoveFrame(aListID, aOldFrame);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nsDeckFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder,
|
||||||
|
const nsDisplayListSet& aLists) {
|
||||||
|
// only paint the selected box
|
||||||
|
nsIFrame* box = GetSelectedBox();
|
||||||
|
if (!box) return;
|
||||||
|
|
||||||
|
// Putting the child in the background list. This is a little weird but
|
||||||
|
// it matches what we were doing before.
|
||||||
|
nsDisplayListSet set(aLists, aLists.BlockBorderBackgrounds());
|
||||||
|
BuildDisplayListForChild(aBuilder, box, set);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nsDeckFrame::Animate(nsIFrame* aParentBox, bool start) {
|
||||||
|
if (!aParentBox) return;
|
||||||
|
|
||||||
|
nsImageBoxFrame* imgBoxFrame = do_QueryFrame(aParentBox);
|
||||||
|
nsImageFrame* imgFrame = do_QueryFrame(aParentBox);
|
||||||
|
|
||||||
|
if (imgBoxFrame) {
|
||||||
|
if (start)
|
||||||
|
imgBoxFrame->RestartAnimation();
|
||||||
|
else
|
||||||
|
imgBoxFrame->StopAnimation();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (imgFrame) {
|
||||||
|
if (start)
|
||||||
|
imgFrame->RestartAnimation();
|
||||||
|
else
|
||||||
|
imgFrame->StopAnimation();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& childList : aParentBox->ChildLists()) {
|
||||||
|
for (nsIFrame* child : childList.mList) {
|
||||||
|
Animate(child, start);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDeckFrame::DoXULLayout(nsBoxLayoutState& aState) {
|
||||||
|
// Make sure we tweak the state so it does not resize our children.
|
||||||
|
// We will do that.
|
||||||
|
ReflowChildFlags oldFlags = aState.LayoutFlags();
|
||||||
|
aState.SetLayoutFlags(ReflowChildFlags::NoSizeView);
|
||||||
|
|
||||||
|
// do a normal layout
|
||||||
|
nsresult rv = nsBoxFrame::DoXULLayout(aState);
|
||||||
|
|
||||||
|
// <deck> and <tabpanels> other than our browser's tab shouldn't have any
|
||||||
|
// <browser> or <iframe> to avoid running into troubles with Fission.
|
||||||
|
MOZ_ASSERT(
|
||||||
|
(mContent->IsXULElement(nsGkAtoms::tabpanels) &&
|
||||||
|
mContent->AsElement()->AttrValueIs(kNameSpaceID_None, nsGkAtoms::id,
|
||||||
|
#ifdef MOZ_THUNDERBIRD
|
||||||
|
u"tabpanelcontainer"_ns,
|
||||||
|
#else
|
||||||
|
u"tabbrowser-tabpanels"_ns,
|
||||||
|
#endif
|
||||||
|
eCaseMatters)) ||
|
||||||
|
!HasPossiblyRemoteContents());
|
||||||
|
|
||||||
|
// run though each child. Hide all but the selected one
|
||||||
|
nsIFrame* box = nsIFrame::GetChildXULBox(this);
|
||||||
|
|
||||||
|
nscoord count = 0;
|
||||||
|
while (box) {
|
||||||
|
// make collapsed children not show up
|
||||||
|
if (count != mIndex) {
|
||||||
|
HideBox(box);
|
||||||
|
} else {
|
||||||
|
ShowBox(box);
|
||||||
|
}
|
||||||
|
box = GetNextXULBox(box);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
aState.SetLayoutFlags(oldFlags);
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool nsDeckFrame::HasPossiblyRemoteContents() const {
|
||||||
|
auto hasRemoteOrMayChangeRemoteNessAttribute =
|
||||||
|
[](dom::Element& aElement) -> bool {
|
||||||
|
return (aElement.AttrValueIs(kNameSpaceID_None, nsGkAtoms::remote,
|
||||||
|
nsGkAtoms::_true, eCaseMatters) ||
|
||||||
|
aElement.HasAttribute(u"maychangeremoteness"_ns));
|
||||||
|
};
|
||||||
|
|
||||||
|
for (nsIContent* node = mContent; node; node = node->GetNextNode(mContent)) {
|
||||||
|
if ((node->IsXULElement(nsGkAtoms::browser) ||
|
||||||
|
node->IsHTMLElement(nsGkAtoms::iframe)) &&
|
||||||
|
hasRemoteOrMayChangeRemoteNessAttribute(*(node->AsElement()))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
78
layout/xul/nsDeckFrame.h
Normal file
78
layout/xul/nsDeckFrame.h
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
/* -*- 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/. */
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
Eric D Vaughan
|
||||||
|
A frame that can have multiple children. Only one child may be displayed at
|
||||||
|
one time. So the can be flipped though like a deck of cards.
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifndef nsDeckFrame_h___
|
||||||
|
#define nsDeckFrame_h___
|
||||||
|
|
||||||
|
#include "mozilla/Attributes.h"
|
||||||
|
#include "nsBoxFrame.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
class PresShell;
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
|
class nsDeckFrame final : public nsBoxFrame {
|
||||||
|
public:
|
||||||
|
NS_DECL_QUERYFRAME
|
||||||
|
NS_DECL_FRAMEARENA_HELPERS(nsDeckFrame)
|
||||||
|
|
||||||
|
friend nsIFrame* NS_NewDeckFrame(mozilla::PresShell* aPresShell,
|
||||||
|
ComputedStyle* aStyle);
|
||||||
|
|
||||||
|
virtual nsresult AttributeChanged(int32_t aNameSpaceID, nsAtom* aAttribute,
|
||||||
|
int32_t aModType) override;
|
||||||
|
|
||||||
|
NS_IMETHOD DoXULLayout(nsBoxLayoutState& aState) override;
|
||||||
|
|
||||||
|
virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||||
|
const nsDisplayListSet& aLists) override;
|
||||||
|
|
||||||
|
virtual void RemoveFrame(ChildListID aListID, nsIFrame* aOldFrame) override;
|
||||||
|
|
||||||
|
virtual void BuildDisplayListForChildren(
|
||||||
|
nsDisplayListBuilder* aBuilder, const nsDisplayListSet& aLists) override;
|
||||||
|
|
||||||
|
virtual void Init(nsIContent* aContent, nsContainerFrame* aParent,
|
||||||
|
nsIFrame* aPrevInFlow) override;
|
||||||
|
|
||||||
|
#ifdef DEBUG_FRAME_DUMP
|
||||||
|
virtual nsresult GetFrameName(nsAString& aResult) const override {
|
||||||
|
return MakeFrameName(u"Deck"_ns, aResult);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
explicit nsDeckFrame(ComputedStyle* aStyle, nsPresContext* aPresContext);
|
||||||
|
|
||||||
|
nsIFrame* GetSelectedBox();
|
||||||
|
|
||||||
|
// Returns whether this frame has any <browser> or <iframe> elements.
|
||||||
|
// Note that this function traverses down all descendants so this function
|
||||||
|
// should be used only in debug builds.
|
||||||
|
bool HasPossiblyRemoteContents() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void IndexChanged();
|
||||||
|
int32_t GetSelectedIndex();
|
||||||
|
void HideBox(nsIFrame* aBox);
|
||||||
|
void ShowBox(nsIFrame* aBox);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int32_t mIndex = 0;
|
||||||
|
nsIFrame* mSelectedBoxCache = nullptr;
|
||||||
|
|
||||||
|
void Animate(nsIFrame*, bool);
|
||||||
|
|
||||||
|
}; // class nsDeckFrame
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -15,6 +15,7 @@
|
|||||||
#include "nsStyleConsts.h"
|
#include "nsStyleConsts.h"
|
||||||
#include "nsGkAtoms.h"
|
#include "nsGkAtoms.h"
|
||||||
#include "nsBoxFrame.h"
|
#include "nsBoxFrame.h"
|
||||||
|
#include "nsStackLayout.h"
|
||||||
#include "nsIAnonymousContentCreator.h"
|
#include "nsIAnonymousContentCreator.h"
|
||||||
#include "nsNodeInfoManager.h"
|
#include "nsNodeInfoManager.h"
|
||||||
#include "nsContentCreatorFunctions.h"
|
#include "nsContentCreatorFunctions.h"
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include "nsGkAtoms.h"
|
#include "nsGkAtoms.h"
|
||||||
#include "nsBoxFrame.h"
|
#include "nsBoxFrame.h"
|
||||||
#include "nsDisplayList.h"
|
#include "nsDisplayList.h"
|
||||||
|
#include "nsStackLayout.h"
|
||||||
#include "nsIPopupContainer.h"
|
#include "nsIPopupContainer.h"
|
||||||
#include "nsIContent.h"
|
#include "nsIContent.h"
|
||||||
#include "nsFrameManager.h"
|
#include "nsFrameManager.h"
|
||||||
|
|||||||
209
layout/xul/nsStackLayout.cpp
Normal file
209
layout/xul/nsStackLayout.cpp
Normal file
@@ -0,0 +1,209 @@
|
|||||||
|
/* -*- 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/. */
|
||||||
|
|
||||||
|
//
|
||||||
|
// Eric Vaughan
|
||||||
|
// Netscape Communications
|
||||||
|
//
|
||||||
|
// See documentation in associated header file
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "nsStackLayout.h"
|
||||||
|
#include "nsCOMPtr.h"
|
||||||
|
#include "nsBoxLayoutState.h"
|
||||||
|
#include "nsBoxFrame.h"
|
||||||
|
#include "nsGkAtoms.h"
|
||||||
|
#include "nsIContent.h"
|
||||||
|
#include "nsNameSpaceManager.h"
|
||||||
|
|
||||||
|
using namespace mozilla;
|
||||||
|
|
||||||
|
nsBoxLayout* nsStackLayout::gInstance = nullptr;
|
||||||
|
|
||||||
|
nsresult NS_NewStackLayout(nsCOMPtr<nsBoxLayout>& aNewLayout) {
|
||||||
|
if (!nsStackLayout::gInstance) {
|
||||||
|
nsStackLayout::gInstance = new nsStackLayout();
|
||||||
|
NS_IF_ADDREF(nsStackLayout::gInstance);
|
||||||
|
}
|
||||||
|
// we have not instance variables so just return our static one.
|
||||||
|
aNewLayout = nsStackLayout::gInstance;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*static*/
|
||||||
|
void nsStackLayout::Shutdown() { NS_IF_RELEASE(gInstance); }
|
||||||
|
|
||||||
|
nsStackLayout::nsStackLayout() = default;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sizing: we are as wide as the widest child
|
||||||
|
* we are tall as the tallest child.
|
||||||
|
*/
|
||||||
|
|
||||||
|
nsSize nsStackLayout::GetXULPrefSize(nsIFrame* aBox, nsBoxLayoutState& aState) {
|
||||||
|
nsSize prefSize(0, 0);
|
||||||
|
|
||||||
|
nsIFrame* child = nsIFrame::GetChildXULBox(aBox);
|
||||||
|
while (child) {
|
||||||
|
nsSize pref = child->GetXULPrefSize(aState);
|
||||||
|
|
||||||
|
AddXULMargin(child, pref);
|
||||||
|
|
||||||
|
if (pref.width > prefSize.width) {
|
||||||
|
prefSize.width = pref.width;
|
||||||
|
}
|
||||||
|
if (pref.height > prefSize.height) {
|
||||||
|
prefSize.height = pref.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
child = nsIFrame::GetNextXULBox(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
AddXULBorderAndPadding(aBox, prefSize);
|
||||||
|
|
||||||
|
return prefSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsSize nsStackLayout::GetXULMinSize(nsIFrame* aBox, nsBoxLayoutState& aState) {
|
||||||
|
nsSize minSize(0, 0);
|
||||||
|
|
||||||
|
nsIFrame* child = nsIFrame::GetChildXULBox(aBox);
|
||||||
|
while (child) {
|
||||||
|
nsSize min = child->GetXULMinSize(aState);
|
||||||
|
|
||||||
|
AddXULMargin(child, min);
|
||||||
|
|
||||||
|
if (min.width > minSize.width) {
|
||||||
|
minSize.width = min.width;
|
||||||
|
}
|
||||||
|
if (min.height > minSize.height) {
|
||||||
|
minSize.height = min.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
child = nsIFrame::GetNextXULBox(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
AddXULBorderAndPadding(aBox, minSize);
|
||||||
|
|
||||||
|
return minSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsSize nsStackLayout::GetXULMaxSize(nsIFrame* aBox, nsBoxLayoutState& aState) {
|
||||||
|
nsSize maxSize(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
|
||||||
|
|
||||||
|
nsIFrame* child = nsIFrame::GetChildXULBox(aBox);
|
||||||
|
while (child) {
|
||||||
|
nsSize min = child->GetXULMinSize(aState);
|
||||||
|
nsSize max = child->GetXULMaxSize(aState);
|
||||||
|
|
||||||
|
max = nsIFrame::XULBoundsCheckMinMax(min, max);
|
||||||
|
|
||||||
|
AddXULMargin(child, max);
|
||||||
|
|
||||||
|
if (max.width < maxSize.width) {
|
||||||
|
maxSize.width = max.width;
|
||||||
|
}
|
||||||
|
if (max.height < maxSize.height) {
|
||||||
|
maxSize.height = max.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
child = nsIFrame::GetNextXULBox(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
AddXULBorderAndPadding(aBox, maxSize);
|
||||||
|
|
||||||
|
return maxSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
nscoord nsStackLayout::GetAscent(nsIFrame* aBox, nsBoxLayoutState& aState) {
|
||||||
|
nscoord vAscent = 0;
|
||||||
|
|
||||||
|
nsIFrame* child = nsIFrame::GetChildXULBox(aBox);
|
||||||
|
while (child) {
|
||||||
|
nscoord ascent = child->GetXULBoxAscent(aState);
|
||||||
|
nsMargin margin;
|
||||||
|
child->GetXULMargin(margin);
|
||||||
|
ascent += margin.top;
|
||||||
|
if (ascent > vAscent) vAscent = ascent;
|
||||||
|
|
||||||
|
child = nsIFrame::GetNextXULBox(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
return vAscent;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsStackLayout::XULLayout(nsIFrame* aBox, nsBoxLayoutState& aState) {
|
||||||
|
nsRect clientRect;
|
||||||
|
aBox->GetXULClientRect(clientRect);
|
||||||
|
|
||||||
|
bool grow;
|
||||||
|
|
||||||
|
do {
|
||||||
|
nsIFrame* child = nsIFrame::GetChildXULBox(aBox);
|
||||||
|
grow = false;
|
||||||
|
|
||||||
|
while (child) {
|
||||||
|
nsMargin margin;
|
||||||
|
child->GetXULMargin(margin);
|
||||||
|
nsRect childRect(clientRect);
|
||||||
|
childRect.Deflate(margin);
|
||||||
|
|
||||||
|
if (childRect.width < 0) childRect.width = 0;
|
||||||
|
|
||||||
|
if (childRect.height < 0) childRect.height = 0;
|
||||||
|
|
||||||
|
nsRect oldRect(child->GetRect());
|
||||||
|
bool sizeChanged = !oldRect.IsEqualEdges(childRect);
|
||||||
|
|
||||||
|
// only lay out dirty children or children whose sizes have changed
|
||||||
|
if (sizeChanged || child->IsSubtreeDirty()) {
|
||||||
|
// add in the child's margin
|
||||||
|
nsMargin margin;
|
||||||
|
child->GetXULMargin(margin);
|
||||||
|
|
||||||
|
// Now place the child.
|
||||||
|
child->SetXULBounds(aState, childRect);
|
||||||
|
|
||||||
|
// Flow the child.
|
||||||
|
child->XULLayout(aState);
|
||||||
|
|
||||||
|
// Get the child's new rect.
|
||||||
|
childRect = child->GetRect();
|
||||||
|
childRect.Inflate(margin);
|
||||||
|
|
||||||
|
// Did the child push back on us and get bigger?
|
||||||
|
if (childRect.width > clientRect.width) {
|
||||||
|
clientRect.width = childRect.width;
|
||||||
|
grow = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (childRect.height > clientRect.height) {
|
||||||
|
clientRect.height = childRect.height;
|
||||||
|
grow = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
child = nsIFrame::GetNextXULBox(child);
|
||||||
|
}
|
||||||
|
} while (grow);
|
||||||
|
|
||||||
|
// if some HTML inside us got bigger we need to force ourselves to
|
||||||
|
// get bigger
|
||||||
|
nsRect bounds(aBox->GetRect());
|
||||||
|
nsMargin bp;
|
||||||
|
aBox->GetXULBorderAndPadding(bp);
|
||||||
|
clientRect.Inflate(bp);
|
||||||
|
|
||||||
|
if (clientRect.width > bounds.width || clientRect.height > bounds.height) {
|
||||||
|
if (clientRect.width > bounds.width) bounds.width = clientRect.width;
|
||||||
|
if (clientRect.height > bounds.height) bounds.height = clientRect.height;
|
||||||
|
|
||||||
|
aBox->SetXULBounds(aState, bounds);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
48
layout/xul/nsStackLayout.h
Normal file
48
layout/xul/nsStackLayout.h
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
/* -*- 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/. */
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
Eric D Vaughan
|
||||||
|
A frame that can have multiple children. Only one child may be displayed at
|
||||||
|
one time. So the can be flipped though like a deck of cards.
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifndef nsStackLayout_h___
|
||||||
|
#define nsStackLayout_h___
|
||||||
|
|
||||||
|
#include "mozilla/Attributes.h"
|
||||||
|
#include "nsBoxLayout.h"
|
||||||
|
#include "nsCOMPtr.h"
|
||||||
|
#include "nsCoord.h"
|
||||||
|
|
||||||
|
nsresult NS_NewStackLayout(nsCOMPtr<nsBoxLayout>& aNewLayout);
|
||||||
|
|
||||||
|
class nsStackLayout : public nsBoxLayout {
|
||||||
|
public:
|
||||||
|
friend nsresult NS_NewStackLayout(nsCOMPtr<nsBoxLayout>& aNewLayout);
|
||||||
|
static void Shutdown();
|
||||||
|
|
||||||
|
nsStackLayout();
|
||||||
|
|
||||||
|
NS_IMETHOD XULLayout(nsIFrame* aBox, nsBoxLayoutState& aState) override;
|
||||||
|
|
||||||
|
virtual nsSize GetXULPrefSize(nsIFrame* aBox,
|
||||||
|
nsBoxLayoutState& aBoxLayoutState) override;
|
||||||
|
virtual nsSize GetXULMinSize(nsIFrame* aBox,
|
||||||
|
nsBoxLayoutState& aBoxLayoutState) override;
|
||||||
|
virtual nsSize GetXULMaxSize(nsIFrame* aBox,
|
||||||
|
nsBoxLayoutState& aBoxLayoutState) override;
|
||||||
|
virtual nscoord GetAscent(nsIFrame* aBox,
|
||||||
|
nsBoxLayoutState& aBoxLayoutState) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static nsBoxLayout* gInstance;
|
||||||
|
|
||||||
|
}; // class nsStackLayout
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -487,7 +487,7 @@ class Longhand(Property):
|
|||||||
"LineBreak",
|
"LineBreak",
|
||||||
"LineClamp",
|
"LineClamp",
|
||||||
"MasonryAutoFlow",
|
"MasonryAutoFlow",
|
||||||
"BoolInteger",
|
"MozForceBrokenImageIcon",
|
||||||
"text::MozControlCharacterVisibility",
|
"text::MozControlCharacterVisibility",
|
||||||
"MathDepth",
|
"MathDepth",
|
||||||
"MozScriptMinSize",
|
"MozScriptMinSize",
|
||||||
|
|||||||
@@ -108,23 +108,11 @@ ${helpers.predefined_type(
|
|||||||
enabled_in="chrome",
|
enabled_in="chrome",
|
||||||
)}
|
)}
|
||||||
|
|
||||||
// Hack to allow chrome to hide stuff only visually (without hiding it from
|
|
||||||
// a11y).
|
|
||||||
${helpers.predefined_type(
|
|
||||||
"-moz-subtree-hidden-only-visually",
|
|
||||||
"BoolInteger",
|
|
||||||
"computed::BoolInteger::zero()",
|
|
||||||
engines="gecko",
|
|
||||||
animation_value_type="discrete",
|
|
||||||
spec="None (Nonstandard internal property)",
|
|
||||||
enabled_in="chrome",
|
|
||||||
)}
|
|
||||||
|
|
||||||
// TODO(emilio): Probably also should be hidden from content.
|
// TODO(emilio): Probably also should be hidden from content.
|
||||||
${helpers.predefined_type(
|
${helpers.predefined_type(
|
||||||
"-moz-force-broken-image-icon",
|
"-moz-force-broken-image-icon",
|
||||||
"BoolInteger",
|
"MozForceBrokenImageIcon",
|
||||||
"computed::BoolInteger::zero()",
|
"computed::MozForceBrokenImageIcon::false_value()",
|
||||||
engines="gecko",
|
engines="gecko",
|
||||||
animation_value_type="discrete",
|
animation_value_type="discrete",
|
||||||
spec="None (Nonstandard Firefox-only property)",
|
spec="None (Nonstandard Firefox-only property)",
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ pub use self::transform::{Rotate, Scale, Transform, TransformOperation};
|
|||||||
pub use self::transform::{TransformOrigin, TransformStyle, Translate};
|
pub use self::transform::{TransformOrigin, TransformStyle, Translate};
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
pub use self::ui::CursorImage;
|
pub use self::ui::CursorImage;
|
||||||
pub use self::ui::{Cursor, BoolInteger, UserSelect};
|
pub use self::ui::{Cursor, MozForceBrokenImageIcon, UserSelect};
|
||||||
pub use super::specified::TextTransform;
|
pub use super::specified::TextTransform;
|
||||||
pub use super::specified::ViewportVariant;
|
pub use super::specified::ViewportVariant;
|
||||||
pub use super::specified::{BorderStyle, TextDecorationLine};
|
pub use super::specified::{BorderStyle, TextDecorationLine};
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use crate::values::computed::Number;
|
|||||||
use crate::values::generics::ui as generics;
|
use crate::values::generics::ui as generics;
|
||||||
|
|
||||||
pub use crate::values::specified::ui::CursorKind;
|
pub use crate::values::specified::ui::CursorKind;
|
||||||
pub use crate::values::specified::ui::{BoolInteger, UserSelect};
|
pub use crate::values::specified::ui::{MozForceBrokenImageIcon, UserSelect};
|
||||||
|
|
||||||
/// A computed value for the `cursor` property.
|
/// A computed value for the `cursor` property.
|
||||||
pub type Cursor = generics::GenericCursor<CursorImage>;
|
pub type Cursor = generics::GenericCursor<CursorImage>;
|
||||||
|
|||||||
@@ -101,6 +101,8 @@ pub enum DisplayInside {
|
|||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
MozBox,
|
MozBox,
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
|
MozDeck,
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
MozPopup,
|
MozPopup,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,6 +216,8 @@ impl Display {
|
|||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
pub const MozInlineBox: Self = Self::new(DisplayOutside::Inline, DisplayInside::MozBox);
|
pub const MozInlineBox: Self = Self::new(DisplayOutside::Inline, DisplayInside::MozBox);
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
|
pub const MozDeck: Self = Self::new(DisplayOutside::XUL, DisplayInside::MozDeck);
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
pub const MozPopup: Self = Self::new(DisplayOutside::XUL, DisplayInside::MozPopup);
|
pub const MozPopup: Self = Self::new(DisplayOutside::XUL, DisplayInside::MozPopup);
|
||||||
|
|
||||||
/// Make a raw display value from <display-outside> and <display-inside> values.
|
/// Make a raw display value from <display-outside> and <display-inside> values.
|
||||||
@@ -594,6 +598,8 @@ impl Parse for Display {
|
|||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
"-moz-inline-box" if moz_display_values_enabled(context) => Display::MozInlineBox,
|
"-moz-inline-box" if moz_display_values_enabled(context) => Display::MozInlineBox,
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
|
"-moz-deck" if moz_display_values_enabled(context) => Display::MozDeck,
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
"-moz-popup" if moz_display_values_enabled(context) => Display::MozPopup,
|
"-moz-popup" if moz_display_values_enabled(context) => Display::MozPopup,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ pub use self::transform::{Rotate, Scale, Transform};
|
|||||||
pub use self::transform::{TransformOrigin, TransformStyle, Translate};
|
pub use self::transform::{TransformOrigin, TransformStyle, Translate};
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
pub use self::ui::CursorImage;
|
pub use self::ui::CursorImage;
|
||||||
pub use self::ui::{Cursor, BoolInteger, UserSelect};
|
pub use self::ui::{Cursor, MozForceBrokenImageIcon, UserSelect};
|
||||||
pub use super::generics::grid::GridTemplateComponent as GenericGridTemplateComponent;
|
pub use super::generics::grid::GridTemplateComponent as GenericGridTemplateComponent;
|
||||||
|
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
|
|||||||
@@ -88,32 +88,31 @@ impl SpecifiedValueInfo for CursorImage {
|
|||||||
ToResolvedValue,
|
ToResolvedValue,
|
||||||
ToShmem,
|
ToShmem,
|
||||||
)]
|
)]
|
||||||
#[repr(transparent)]
|
pub struct MozForceBrokenImageIcon(pub bool);
|
||||||
pub struct BoolInteger(pub bool);
|
|
||||||
|
|
||||||
impl BoolInteger {
|
impl MozForceBrokenImageIcon {
|
||||||
/// Returns 0
|
/// Return initial value of -moz-force-broken-image-icon which is false.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn zero() -> Self {
|
pub fn false_value() -> MozForceBrokenImageIcon {
|
||||||
Self(false)
|
MozForceBrokenImageIcon(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Parse for BoolInteger {
|
impl Parse for MozForceBrokenImageIcon {
|
||||||
fn parse<'i, 't>(
|
fn parse<'i, 't>(
|
||||||
_context: &ParserContext,
|
_context: &ParserContext,
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<MozForceBrokenImageIcon, ParseError<'i>> {
|
||||||
// We intentionally don't support calc values here.
|
// We intentionally don't support calc values here.
|
||||||
match input.expect_integer()? {
|
match input.expect_integer()? {
|
||||||
0 => Ok(Self(false)),
|
0 => Ok(MozForceBrokenImageIcon(false)),
|
||||||
1 => Ok(Self(true)),
|
1 => Ok(MozForceBrokenImageIcon(true)),
|
||||||
_ => Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)),
|
_ => Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToCss for BoolInteger {
|
impl ToCss for MozForceBrokenImageIcon {
|
||||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
||||||
where
|
where
|
||||||
W: Write,
|
W: Write,
|
||||||
@@ -122,6 +121,22 @@ impl ToCss for BoolInteger {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<u8> for MozForceBrokenImageIcon {
|
||||||
|
fn from(bits: u8) -> MozForceBrokenImageIcon {
|
||||||
|
MozForceBrokenImageIcon(bits == 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<MozForceBrokenImageIcon> for u8 {
|
||||||
|
fn from(v: MozForceBrokenImageIcon) -> u8 {
|
||||||
|
if v.0 {
|
||||||
|
1
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A specified value for `scrollbar-color` property
|
/// A specified value for `scrollbar-color` property
|
||||||
pub type ScrollbarColor = generics::ScrollbarColor<Color>;
|
pub type ScrollbarColor = generics::ScrollbarColor<Color>;
|
||||||
|
|
||||||
|
|||||||
@@ -79,7 +79,6 @@ include = [
|
|||||||
"BreakBetween",
|
"BreakBetween",
|
||||||
"BreakWithin",
|
"BreakWithin",
|
||||||
"BorderStyle",
|
"BorderStyle",
|
||||||
"BoolInteger",
|
|
||||||
"OutlineStyle",
|
"OutlineStyle",
|
||||||
"CaptionSide",
|
"CaptionSide",
|
||||||
"FontSizeAdjust",
|
"FontSizeAdjust",
|
||||||
|
|||||||
@@ -113,7 +113,7 @@
|
|||||||
ok(deck instanceof MozXULElement, "instance of MozXULElement");
|
ok(deck instanceof MozXULElement, "instance of MozXULElement");
|
||||||
ok(XULElement.isInstance(deck), "instance of XULElement");
|
ok(XULElement.isInstance(deck), "instance of XULElement");
|
||||||
is(deck.id, "foo", "attribute set");
|
is(deck.id, "foo", "attribute set");
|
||||||
is(deck.selectedIndex, 0, "Custom Element is property attached");
|
is(deck.selectedIndex, "0", "Custom Element is property attached");
|
||||||
deck.remove();
|
deck.remove();
|
||||||
|
|
||||||
info("Checking that whitespace text is removed but non-whitespace text isn't");
|
info("Checking that whitespace text is removed but non-whitespace text isn't");
|
||||||
|
|||||||
@@ -5,13 +5,14 @@
|
|||||||
XUL Widget Test for deck
|
XUL Widget Test for deck
|
||||||
-->
|
-->
|
||||||
<window title="Deck Test"
|
<window title="Deck Test"
|
||||||
|
onload="setTimeout(run_tests, 0);"
|
||||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||||
<script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
<script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||||
<script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
|
<script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
|
||||||
|
|
||||||
<deck id="deck1" style="padding-top: 5px; padding-bottom: 12px;">
|
<deck id="deck1" style="padding-top: 5px; padding-bottom: 12px;">
|
||||||
<button id="d1b1" label="Button One"/>
|
<button id="d1b1" label="Button One"/>
|
||||||
<button id="d1b2" label="Button Two is larger" style="height: 80px; margin: 1px;"/>
|
<button id="d1b2" label="Button Two is larger" height="80" style="margin: 1px;"/>
|
||||||
</deck>
|
</deck>
|
||||||
<deck id="deck2" selectedIndex="1">
|
<deck id="deck2" selectedIndex="1">
|
||||||
<button id="d2b1" label="Button One"/>
|
<button id="d2b1" label="Button One"/>
|
||||||
@@ -43,15 +44,19 @@
|
|||||||
|
|
||||||
<!-- test code goes here -->
|
<!-- test code goes here -->
|
||||||
<script type="application/javascript"><![CDATA[
|
<script type="application/javascript"><![CDATA[
|
||||||
add_task(async function run_tests() {
|
|
||||||
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
|
||||||
|
function run_tests() {
|
||||||
test_deck();
|
test_deck();
|
||||||
await test_deck_child_removal();
|
test_deck_child_removal();
|
||||||
});
|
SimpleTest.finish();
|
||||||
|
}
|
||||||
|
|
||||||
function test_deck()
|
function test_deck()
|
||||||
{
|
{
|
||||||
var deck = $("deck1");
|
var deck = $("deck1");
|
||||||
is(deck.selectedIndex, 0, "deck one selectedIndex");
|
ok(deck.selectedIndex === '0', "deck one selectedIndex");
|
||||||
// this size is the button height, 80, plus the button padding of 1px on each side,
|
// this size is the button height, 80, plus the button padding of 1px on each side,
|
||||||
// plus the deck's 5px top padding and the 12px bottom padding.
|
// plus the deck's 5px top padding and the 12px bottom padding.
|
||||||
var rect = deck.getBoundingClientRect();
|
var rect = deck.getBoundingClientRect();
|
||||||
@@ -61,52 +66,47 @@ function test_deck()
|
|||||||
// change the selected page of the deck and ensure that the mouse click goes
|
// change the selected page of the deck and ensure that the mouse click goes
|
||||||
// to the button on that page
|
// to the button on that page
|
||||||
deck.selectedIndex = 1;
|
deck.selectedIndex = 1;
|
||||||
is(deck.selectedIndex, 1, "deck one selectedIndex after change");
|
ok(deck.selectedIndex === '1', "deck one selectedIndex after change");
|
||||||
synthesizeMouseExpectEvent(deck, 9, 9, { }, $("d1b2"), "click", "mouse on deck one after change");
|
synthesizeMouseExpectEvent(deck, 9, 9, { }, $("d1b2"), "click", "mouse on deck one after change");
|
||||||
|
|
||||||
deck = $("deck2");
|
deck = $("deck2");
|
||||||
is(deck.selectedIndex, 1, "deck two selectedIndex");
|
ok(deck.selectedIndex === '1', "deck two selectedIndex");
|
||||||
synthesizeMouseExpectEvent(deck, 9, 9, { }, $("d2b2"), "click", "mouse on deck two");
|
synthesizeMouseExpectEvent(deck, 9, 9, { }, $("d2b2"), "click", "mouse on deck two");
|
||||||
}
|
}
|
||||||
|
|
||||||
async function test_deck_child_removal()
|
function test_deck_child_removal()
|
||||||
{
|
{
|
||||||
// Start with a simple case where we have two child nodes in a deck, with
|
// Start with a simple case where we have two child nodes in a deck, with
|
||||||
// the second child (index 1) selected. Removing the first node should
|
// the second child (index 1) selected. Removing the first node should
|
||||||
// automatically set the selectedIndex at 0.
|
// automatically set the selectedIndex at 0.
|
||||||
let deck = $("deck3");
|
let deck = $("deck3");
|
||||||
let child = $("d3b1");
|
let child = $("d3b1");
|
||||||
is(deck.selectedIndex, 1, "Should have the deck element at index 1 selected");
|
is(deck.selectedIndex, "1", "Should have the deck element at index 1 selected");
|
||||||
|
|
||||||
// Remove the child at the 0th index. The deck should automatically
|
// Remove the child at the 0th index. The deck should automatically
|
||||||
// set the selectedIndex to "0".
|
// set the selectedIndex to "0".
|
||||||
child.remove();
|
child.remove();
|
||||||
|
is(deck.selectedIndex, "0", "Should have the deck element at index 0 selected");
|
||||||
await Promise.resolve();
|
|
||||||
|
|
||||||
is(deck.selectedIndex, 0, "Should have the deck element at index 0 selected");
|
|
||||||
|
|
||||||
// Now scale it up by using a deck with 7 child nodes, and remove the
|
// Now scale it up by using a deck with 7 child nodes, and remove the
|
||||||
// first three, making sure that the selectedIndex is decremented
|
// first three, making sure that the selectedIndex is decremented
|
||||||
// each time.
|
// each time.
|
||||||
deck = $("deck4");
|
deck = $("deck4");
|
||||||
let expectedIndex = 5;
|
let expectedIndex = 5;
|
||||||
is(deck.selectedIndex, expectedIndex,
|
is(deck.selectedIndex, String(expectedIndex),
|
||||||
"Should have the deck element at index " + expectedIndex + " selected");
|
"Should have the deck element at index " + expectedIndex + " selected");
|
||||||
|
|
||||||
for (let i = 0; i < 3; ++i) {
|
for (let i = 0; i < 3; ++i) {
|
||||||
deck.firstChild.remove();
|
deck.firstChild.remove();
|
||||||
expectedIndex--;
|
expectedIndex--;
|
||||||
await Promise.resolve();
|
is(deck.selectedIndex, String(expectedIndex),
|
||||||
is(deck.selectedIndex, expectedIndex,
|
|
||||||
"Should have the deck element at index " + expectedIndex + " selected");
|
"Should have the deck element at index " + expectedIndex + " selected");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that removing the currently selected node doesn't change
|
// Check that removing the currently selected node doesn't change
|
||||||
// behaviour.
|
// behaviour.
|
||||||
deck.childNodes[expectedIndex].remove();
|
deck.childNodes[expectedIndex].remove();
|
||||||
await Promise.resolve();
|
is(deck.selectedIndex, String(expectedIndex),
|
||||||
is(deck.selectedIndex, expectedIndex,
|
|
||||||
"The selectedIndex should not change when removing the node " +
|
"The selectedIndex should not change when removing the node " +
|
||||||
"at the selected index.");
|
"at the selected index.");
|
||||||
|
|
||||||
@@ -114,16 +114,14 @@ async function test_deck_child_removal()
|
|||||||
// nodes at indexes greater than the selected node.
|
// nodes at indexes greater than the selected node.
|
||||||
deck = $("deck5");
|
deck = $("deck5");
|
||||||
expectedIndex = 2;
|
expectedIndex = 2;
|
||||||
await Promise.resolve();
|
is(deck.selectedIndex, String(expectedIndex),
|
||||||
is(deck.selectedIndex, expectedIndex,
|
|
||||||
"Should have the deck element at index " + expectedIndex + " selected");
|
"Should have the deck element at index " + expectedIndex + " selected");
|
||||||
|
|
||||||
// And then remove all of the nodes, starting from last to first, making
|
// And then remove all of the nodes, starting from last to first, making
|
||||||
// sure that the selectedIndex does not change.
|
// sure that the selectedIndex does not change.
|
||||||
while (deck.lastChild) {
|
while (deck.lastChild) {
|
||||||
deck.lastChild.remove();
|
deck.lastChild.remove();
|
||||||
await Promise.resolve();
|
is(deck.selectedIndex, String(expectedIndex),
|
||||||
is(deck.selectedIndex, expectedIndex,
|
|
||||||
"Should have the deck element at index " + expectedIndex + " selected");
|
"Should have the deck element at index " + expectedIndex + " selected");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,40 @@
|
|||||||
// This is loaded into chrome windows with the subscript loader. Wrap in
|
// This is loaded into chrome windows with the subscript loader. Wrap in
|
||||||
// a block to prevent accidentally leaking globals onto `window`.
|
// a block to prevent accidentally leaking globals onto `window`.
|
||||||
{
|
{
|
||||||
|
class MozDeck extends MozXULElement {
|
||||||
|
set selectedIndex(val) {
|
||||||
|
if (this.selectedIndex == val) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.setAttribute("selectedIndex", val);
|
||||||
|
var event = document.createEvent("Events");
|
||||||
|
event.initEvent("select", true, true);
|
||||||
|
this.dispatchEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
get selectedIndex() {
|
||||||
|
return this.getAttribute("selectedIndex") || "0";
|
||||||
|
}
|
||||||
|
|
||||||
|
set selectedPanel(val) {
|
||||||
|
var selectedIndex = -1;
|
||||||
|
for (
|
||||||
|
var panel = val;
|
||||||
|
panel != null;
|
||||||
|
panel = panel.previousElementSibling
|
||||||
|
) {
|
||||||
|
++selectedIndex;
|
||||||
|
}
|
||||||
|
this.selectedIndex = selectedIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
get selectedPanel() {
|
||||||
|
return this.children[this.selectedIndex];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
customElements.define("deck", MozDeck);
|
||||||
|
|
||||||
class MozDropmarker extends MozXULElement {
|
class MozDropmarker extends MozXULElement {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
|||||||
@@ -158,107 +158,14 @@
|
|||||||
|
|
||||||
customElements.define("tabbox", MozTabbox);
|
customElements.define("tabbox", MozTabbox);
|
||||||
|
|
||||||
class MozDeck extends MozXULElement {
|
class MozTabpanels extends MozXULElement {
|
||||||
get isAsync() {
|
|
||||||
return this.getAttribute("async") == "true";
|
|
||||||
}
|
|
||||||
|
|
||||||
connectedCallback() {
|
connectedCallback() {
|
||||||
if (this.delayConnectedCallback()) {
|
if (this.delayConnectedCallback()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this._selectedPanel = null;
|
|
||||||
this._inAsyncOperation = false;
|
|
||||||
|
|
||||||
let selectCurrentIndex = () => {
|
|
||||||
// Try to select the new node if any.
|
|
||||||
let index = this.selectedIndex;
|
|
||||||
let oldPanel = this._selectedPanel;
|
|
||||||
this._selectedPanel = this.children.item(index) || null;
|
|
||||||
this.updateSelectedIndex(index, oldPanel);
|
|
||||||
};
|
|
||||||
|
|
||||||
this._mutationObserver = new MutationObserver(records => {
|
|
||||||
let anyRemovals = records.some(record => !!record.removedNodes.length);
|
|
||||||
if (anyRemovals) {
|
|
||||||
// Try to keep the current selected panel in-place first.
|
|
||||||
let index = Array.from(this.children).indexOf(this._selectedPanel);
|
|
||||||
if (index != -1) {
|
|
||||||
// Try to keep the same node selected.
|
|
||||||
this.setAttribute("selectedIndex", index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Select the current index if needed in case mutations have made that
|
|
||||||
// available where it wasn't before.
|
|
||||||
if (!this._inAsyncOperation) {
|
|
||||||
selectCurrentIndex();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this._mutationObserver.observe(this, {
|
|
||||||
childList: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
selectCurrentIndex();
|
|
||||||
}
|
|
||||||
|
|
||||||
disconnectedCallback() {
|
|
||||||
this._mutationObserver?.disconnect();
|
|
||||||
this._mutationObserver = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
updateSelectedIndex(
|
|
||||||
val,
|
|
||||||
oldPanel = this.querySelector(":scope > .deck-selected")
|
|
||||||
) {
|
|
||||||
this._inAsyncOperation = false;
|
|
||||||
if (oldPanel != this._selectedPanel) {
|
|
||||||
oldPanel?.classList.remove("deck-selected");
|
|
||||||
this._selectedPanel?.classList.add("deck-selected");
|
|
||||||
}
|
|
||||||
this.setAttribute("selectedIndex", val);
|
|
||||||
}
|
|
||||||
|
|
||||||
set selectedIndex(val) {
|
|
||||||
if (val < 0 || val >= this.children.length) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let oldPanel = this._selectedPanel;
|
|
||||||
this._selectedPanel = this.children[val];
|
|
||||||
|
|
||||||
this._inAsyncOperation = this.isAsync;
|
|
||||||
if (!this._inAsyncOperation) {
|
|
||||||
this.updateSelectedIndex(val, oldPanel);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._selectedPanel != oldPanel) {
|
|
||||||
let event = document.createEvent("Events");
|
|
||||||
event.initEvent("select", true, true);
|
|
||||||
this.dispatchEvent(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
get selectedIndex() {
|
|
||||||
let indexStr = this.getAttribute("selectedIndex");
|
|
||||||
return indexStr ? parseInt(indexStr) : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
set selectedPanel(val) {
|
|
||||||
this.selectedIndex = Array.from(this.children).indexOf(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
get selectedPanel() {
|
|
||||||
return this._selectedPanel;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
customElements.define("deck", MozDeck);
|
|
||||||
|
|
||||||
class MozTabpanels extends MozDeck {
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this._tabbox = null;
|
this._tabbox = null;
|
||||||
|
this._selectedPanel = this.children.item(this.selectedIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
get tabbox() {
|
get tabbox() {
|
||||||
@@ -279,6 +186,46 @@
|
|||||||
return (this._tabbox = parent);
|
return (this._tabbox = parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set selectedIndex(val) {
|
||||||
|
if (val < 0 || val >= this.children.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let panel = this._selectedPanel;
|
||||||
|
this._selectedPanel = this.children[val];
|
||||||
|
|
||||||
|
if (this.getAttribute("async") != "true") {
|
||||||
|
this.setAttribute("selectedIndex", val);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._selectedPanel != panel) {
|
||||||
|
let event = document.createEvent("Events");
|
||||||
|
event.initEvent("select", true, true);
|
||||||
|
this.dispatchEvent(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get selectedIndex() {
|
||||||
|
let indexStr = this.getAttribute("selectedIndex");
|
||||||
|
return indexStr ? parseInt(indexStr) : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
set selectedPanel(val) {
|
||||||
|
let selectedIndex = -1;
|
||||||
|
for (
|
||||||
|
let panel = val;
|
||||||
|
panel != null;
|
||||||
|
panel = panel.previousElementSibling
|
||||||
|
) {
|
||||||
|
++selectedIndex;
|
||||||
|
}
|
||||||
|
this.selectedIndex = selectedIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
get selectedPanel() {
|
||||||
|
return this._selectedPanel;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nsIDOMXULRelatedElement
|
* nsIDOMXULRelatedElement
|
||||||
*/
|
*/
|
||||||
@@ -580,9 +527,7 @@
|
|||||||
|
|
||||||
set selectedIndex(val) {
|
set selectedIndex(val) {
|
||||||
var tab = this.getItemAtIndex(val);
|
var tab = this.getItemAtIndex(val);
|
||||||
if (!tab) {
|
if (tab) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (let otherTab of this.allTabs) {
|
for (let otherTab of this.allTabs) {
|
||||||
if (otherTab != tab && otherTab.selected) {
|
if (otherTab != tab && otherTab.selected) {
|
||||||
otherTab._selected = false;
|
otherTab._selected = false;
|
||||||
@@ -601,6 +546,7 @@
|
|||||||
this.tabbox.tabpanels.selectedPanel = linkedPanel;
|
this.tabbox.tabpanels.selectedPanel = linkedPanel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
get selectedIndex() {
|
get selectedIndex() {
|
||||||
const tabs = this.allTabs;
|
const tabs = this.allTabs;
|
||||||
|
|||||||
@@ -448,34 +448,18 @@ treechildren::-moz-tree-cell(ltr) {
|
|||||||
direction: ltr !important;
|
direction: ltr !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/********** deck, tabpanels & stack *********/
|
/********** deck & stack *********/
|
||||||
|
|
||||||
tabpanels > *|*:not(:-moz-native-anonymous) {
|
deck {
|
||||||
/* tabpanels is special: we want to avoid displaying them, but we still want
|
display: -moz-deck;
|
||||||
* the hidden children to be accessible */
|
|
||||||
-moz-subtree-hidden-only-visually: 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
deck > *|*:not(:-moz-native-anonymous) {
|
|
||||||
visibility: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
tabpanels > .deck-selected,
|
|
||||||
deck > .deck-selected {
|
|
||||||
-moz-subtree-hidden-only-visually: 0;
|
|
||||||
visibility: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
tabpanels,
|
|
||||||
deck,
|
|
||||||
stack {
|
stack {
|
||||||
display: grid;
|
display: grid;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We shouldn't style native anonymous children like scrollbars or what not. */
|
/* We shouldn't style native anonymous children like scrollbars or what not */
|
||||||
tabpanels > *|*:not(:-moz-native-anonymous),
|
|
||||||
deck > *|*:not(:-moz-native-anonymous),
|
|
||||||
stack > *|*:not(:-moz-native-anonymous) {
|
stack > *|*:not(:-moz-native-anonymous) {
|
||||||
grid-area: 1 / 1;
|
grid-area: 1 / 1;
|
||||||
z-index: 0;
|
z-index: 0;
|
||||||
@@ -505,6 +489,10 @@ tab {
|
|||||||
-moz-box-pack: center;
|
-moz-box-pack: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tabpanels {
|
||||||
|
display: -moz-deck;
|
||||||
|
}
|
||||||
|
|
||||||
/********** tooltip *********/
|
/********** tooltip *********/
|
||||||
|
|
||||||
tooltip[titletip="true"] {
|
tooltip[titletip="true"] {
|
||||||
|
|||||||
@@ -26,9 +26,6 @@ tabs {
|
|||||||
padding: 0 10px;
|
padding: 0 10px;
|
||||||
margin-bottom: -12px;
|
margin-bottom: -12px;
|
||||||
position: relative;
|
position: relative;
|
||||||
/* Needs to sort on top of the tabbox, which is a grid container (and thus
|
|
||||||
* causes pseudo stacking contexts to be created) */
|
|
||||||
z-index: 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tab {
|
tab {
|
||||||
|
|||||||
Reference in New Issue
Block a user