mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-12 21:05:36 +00:00
Merge mozilla-central to mozilla-inbound. r=merge a=merge CLOSED TREE
This commit is contained in:
commit
0792c2eee8
@ -25,8 +25,6 @@
|
||||
|
||||
ok(!isAccessible("statusbarpanel"),
|
||||
"statusbarpanel shouldn't be accessible.");
|
||||
testRole("statusbarpanel-iconic", ROLE_PUSHBUTTON);
|
||||
testRole("statusbarpanel-iconic-text", ROLE_PUSHBUTTON);
|
||||
testRole("statusbar", ROLE_STATUSBAR);
|
||||
|
||||
SimpleTest.finish();
|
||||
@ -57,8 +55,6 @@
|
||||
<image id="image-onclick" src="../moz.png" onclick=""/>
|
||||
|
||||
<statusbarpanel id="statusbarpanel"></statusbarpanel>
|
||||
<statusbarpanel id="statusbarpanel-iconic" class="statusbarpanel-iconic"></statusbarpanel>
|
||||
<statusbarpanel id="statusbarpanel-iconic-text" class="statusbarpanel-iconic-text"></statusbarpanel>
|
||||
<statusbar id="statusbar"></statusbar>
|
||||
|
||||
</hbox>
|
||||
|
@ -247,24 +247,26 @@ var BrowserPageActions = {
|
||||
let popupSet = document.getElementById("mainPopupSet");
|
||||
popupSet.appendChild(panelNode);
|
||||
panelNode.addEventListener("popuphidden", () => {
|
||||
if (iframeNode) {
|
||||
action.onIframeHidden(iframeNode, panelNode);
|
||||
}
|
||||
panelNode.remove();
|
||||
}, { once: true });
|
||||
|
||||
if (iframeNode) {
|
||||
panelNode.addEventListener("popupshown", () => {
|
||||
action.onIframeShown(iframeNode, panelNode);
|
||||
panelNode.addEventListener("popupshowing", () => {
|
||||
action.onIframeShowing(iframeNode, panelNode);
|
||||
}, { once: true });
|
||||
panelNode.addEventListener("popuphiding", () => {
|
||||
action.onIframeHiding(iframeNode, panelNode);
|
||||
}, { once: true });
|
||||
panelNode.addEventListener("popuphidden", () => {
|
||||
action.onIframeHidden(iframeNode, panelNode);
|
||||
}, { once: true });
|
||||
}
|
||||
|
||||
if (panelViewNode) {
|
||||
action.subview.onPlaced(panelViewNode);
|
||||
action.subview.onShowing(panelViewNode);
|
||||
panelNode.addEventListener("popupshowing", () => {
|
||||
action.subview.onShowing(panelViewNode);
|
||||
}, { once: true });
|
||||
}
|
||||
|
||||
return panelNode;
|
||||
@ -956,14 +958,11 @@ BrowserPageActions.sendToDevice = {
|
||||
}
|
||||
},
|
||||
|
||||
onShowingInPanel(buttonNode) {
|
||||
onLocationChange() {
|
||||
let action = PageActions.actionForID("sendToDevice");
|
||||
let browser = gBrowser.selectedBrowser;
|
||||
let url = browser.currentURI.spec;
|
||||
if (gSync.isSendableURI(url)) {
|
||||
buttonNode.removeAttribute("disabled");
|
||||
} else {
|
||||
buttonNode.setAttribute("disabled", "true");
|
||||
}
|
||||
action.setDisabled(!gSync.isSendableURI(url), window);
|
||||
},
|
||||
|
||||
onShowingSubview(panelViewNode) {
|
||||
@ -1008,7 +1007,7 @@ BrowserPageActions.sendToDevice = {
|
||||
bodyNode.setAttribute("state", "notready");
|
||||
// Force a background Sync
|
||||
Services.tm.dispatchToMainThread(async () => {
|
||||
await Weave.Service.sync([]); // [] = clients engine only
|
||||
await Weave.Service.sync({why: "pageactions", engines: []}); // [] = clients engine only
|
||||
// There's no way Sync is still syncing at this point, but we check
|
||||
// anyway to avoid infinite looping.
|
||||
if (!window.closed && !gSync.syncConfiguredAndLoading) {
|
||||
|
@ -5695,6 +5695,7 @@ var gUIDensity = {
|
||||
}
|
||||
|
||||
TabsInTitlebar.updateAppearance(true);
|
||||
gBrowser.tabContainer.uiDensityChanged();
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -6823,6 +6823,14 @@
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<method name="uiDensityChanged">
|
||||
<body><![CDATA[
|
||||
this._positionPinnedTabs();
|
||||
this._updateCloseButtons();
|
||||
this._handleTabSelect(true);
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<field name="_lastNumPinned">0</field>
|
||||
<field name="_pinnedTabsLayoutCache">null</field>
|
||||
<method name="_positionPinnedTabs">
|
||||
@ -6835,9 +6843,12 @@
|
||||
this.setAttribute("positionpinnedtabs", "true");
|
||||
|
||||
let layoutData = this._pinnedTabsLayoutCache;
|
||||
if (!layoutData) {
|
||||
let uiDensity = document.documentElement.getAttribute("uidensity");
|
||||
if (!layoutData ||
|
||||
layoutData.uiDensity != uiDensity) {
|
||||
let arrowScrollbox = this.arrowScrollbox;
|
||||
layoutData = this._pinnedTabsLayoutCache = {
|
||||
uiDensity,
|
||||
pinnedTabWidth: this.childNodes[0].getBoundingClientRect().width,
|
||||
scrollButtonWidth: arrowScrollbox._scrollButtonDown.getBoundingClientRect().width
|
||||
};
|
||||
|
@ -174,34 +174,27 @@ add_task(async function copyURLFromURLBar() {
|
||||
});
|
||||
|
||||
add_task(async function sendToDevice_nonSendable() {
|
||||
// Open a tab that's not sendable. An about: page like about:home is
|
||||
// convenient.
|
||||
await BrowserTestUtils.withNewTab("about:home", async () => {
|
||||
// ... but the page actions should be hidden on about:home, including the
|
||||
// main button. (It's not easy to load a page that's both actionable and
|
||||
// not sendable.) So first check that that's the case, and then unhide the
|
||||
// main button so that this test can continue.
|
||||
Assert.equal(
|
||||
window.getComputedStyle(BrowserPageActions.mainButtonNode).display,
|
||||
"none",
|
||||
"Main button should be hidden on about:home"
|
||||
);
|
||||
BrowserPageActions.mainButtonNode.style.display = "-moz-box";
|
||||
// Open a tab that's not sendable but where the page action buttons still
|
||||
// appear. about:about is convenient.
|
||||
await BrowserTestUtils.withNewTab("about:about", async () => {
|
||||
await promiseSyncReady();
|
||||
// Open the panel. Send to Device should be disabled.
|
||||
await promisePageActionPanelOpen();
|
||||
Assert.equal(BrowserPageActions.mainButtonNode.getAttribute("open"),
|
||||
"true", "Main button has 'open' attribute");
|
||||
let sendToDeviceButton =
|
||||
document.getElementById("pageAction-panel-sendToDevice");
|
||||
Assert.ok(sendToDeviceButton.disabled);
|
||||
Assert.equal(BrowserPageActions.mainButtonNode.getAttribute("open"), "true",
|
||||
"Main button has 'open' attribute");
|
||||
let panelButton =
|
||||
BrowserPageActions.panelButtonNodeForActionID("sendToDevice");
|
||||
Assert.equal(panelButton.disabled, true,
|
||||
"The panel button should be disabled");
|
||||
let hiddenPromise = promisePageActionPanelHidden();
|
||||
BrowserPageActions.panelNode.hidePopup();
|
||||
await hiddenPromise;
|
||||
Assert.ok(!BrowserPageActions.mainButtonNode.hasAttribute("open"),
|
||||
"Main button no longer has 'open' attribute");
|
||||
// Remove the `display` style set above.
|
||||
BrowserPageActions.mainButtonNode.style.removeProperty("display");
|
||||
"Main button no longer has 'open' attribute");
|
||||
// The urlbar button shouldn't exist.
|
||||
let urlbarButton =
|
||||
BrowserPageActions.urlbarButtonNodeForActionID("sendToDevice");
|
||||
Assert.equal(urlbarButton, null, "The urlbar button shouldn't exist");
|
||||
});
|
||||
});
|
||||
|
||||
@ -550,7 +543,9 @@ add_task(async function sendToDevice_inUrlbar() {
|
||||
let urlbarButton = document.getElementById(
|
||||
BrowserPageActions.urlbarButtonNodeIDForActionID(action.id)
|
||||
);
|
||||
Assert.ok(!urlbarButton.disabled);
|
||||
Assert.notEqual(urlbarButton, null, "The urlbar button should exist");
|
||||
Assert.ok(!urlbarButton.disabled,
|
||||
"The urlbar button should not be disabled");
|
||||
let panelPromise =
|
||||
promisePanelShown(BrowserPageActions._activatedActionPanelID);
|
||||
EventUtils.synthesizeMouseAtCenter(urlbarButton, {});
|
||||
|
2
browser/extensions/pocket/bootstrap.js
vendored
2
browser/extensions/pocket/bootstrap.js
vendored
@ -139,7 +139,7 @@ var PocketPageAction = {
|
||||
onPlacedInPanel(panelNode, urlbarNode) {
|
||||
PocketOverlay.onWindowOpened(panelNode.ownerGlobal);
|
||||
},
|
||||
onIframeShown(iframe, panel) {
|
||||
onIframeShowing(iframe, panel) {
|
||||
Pocket.onShownInPhotonPageActionPanel(panel, iframe);
|
||||
|
||||
let doc = panel.ownerDocument;
|
||||
|
@ -525,9 +525,9 @@ this.PageActions = {
|
||||
* onIframeHidden(iframeNode, parentPanelNode)
|
||||
* * iframeNode: The iframe.
|
||||
* * parentPanelNode: The panel node in which the iframe is shown.
|
||||
* @param onIframeShown (function, optional)
|
||||
* Called when the action's iframe is shown to the user:
|
||||
* onIframeShown(iframeNode, parentPanelNode)
|
||||
* @param onIframeShowing (function, optional)
|
||||
* Called when the action's iframe is showing to the user:
|
||||
* onIframeShowing(iframeNode, parentPanelNode)
|
||||
* * iframeNode: The iframe.
|
||||
* * parentPanelNode: The panel node in which the iframe is shown.
|
||||
* @param onLocationChange (function, optional)
|
||||
@ -584,7 +584,7 @@ function Action(options) {
|
||||
onCommand: false,
|
||||
onIframeHiding: false,
|
||||
onIframeHidden: false,
|
||||
onIframeShown: false,
|
||||
onIframeShowing: false,
|
||||
onLocationChange: false,
|
||||
onPlacedInPanel: false,
|
||||
onPlacedInUrlbar: false,
|
||||
@ -901,16 +901,16 @@ Action.prototype = {
|
||||
},
|
||||
|
||||
/**
|
||||
* Call this when the action's iframe is shown.
|
||||
* Call this when the action's iframe is showing.
|
||||
*
|
||||
* @param iframeNode (DOM node, required)
|
||||
* The iframe that's being shown.
|
||||
* @param parentPanelNode (DOM node, required)
|
||||
* The panel in which the iframe is shown.
|
||||
*/
|
||||
onIframeShown(iframeNode, parentPanelNode) {
|
||||
if (this._onIframeShown) {
|
||||
this._onIframeShown(iframeNode, parentPanelNode);
|
||||
onIframeShowing(iframeNode, parentPanelNode) {
|
||||
if (this._onIframeShowing) {
|
||||
this._onIframeShowing(iframeNode, parentPanelNode);
|
||||
}
|
||||
},
|
||||
|
||||
@ -1229,8 +1229,8 @@ var gBuiltInActions = [
|
||||
onPlacedInPanel(buttonNode) {
|
||||
browserPageActions(buttonNode).sendToDevice.onPlacedInPanel(buttonNode);
|
||||
},
|
||||
onShowingInPanel(buttonNode) {
|
||||
browserPageActions(buttonNode).sendToDevice.onShowingInPanel(buttonNode);
|
||||
onLocationChange(browserWindow) {
|
||||
browserPageActions(browserWindow).sendToDevice.onLocationChange();
|
||||
},
|
||||
subview: {
|
||||
buttons: [
|
||||
|
@ -455,7 +455,7 @@ add_task(async function withIframe() {
|
||||
let onCommandCallCount = 0;
|
||||
let onPlacedInPanelCallCount = 0;
|
||||
let onPlacedInUrlbarCallCount = 0;
|
||||
let onIframeShownCount = 0;
|
||||
let onIframeShowingCount = 0;
|
||||
|
||||
let panelButtonID = BrowserPageActions.panelButtonNodeIDForActionID(id);
|
||||
let urlbarButtonID = BrowserPageActions.urlbarButtonNodeIDForActionID(id);
|
||||
@ -469,8 +469,8 @@ add_task(async function withIframe() {
|
||||
onCommand(event, buttonNode) {
|
||||
onCommandCallCount++;
|
||||
},
|
||||
onIframeShown(iframeNode, panelNode) {
|
||||
onIframeShownCount++;
|
||||
onIframeShowing(iframeNode, panelNode) {
|
||||
onIframeShowingCount++;
|
||||
Assert.ok(iframeNode, "iframeNode should be non-null: " + iframeNode);
|
||||
Assert.equal(iframeNode.localName, "iframe", "iframe localName");
|
||||
Assert.ok(panelNode, "panelNode should be non-null: " + panelNode);
|
||||
@ -496,8 +496,8 @@ add_task(async function withIframe() {
|
||||
"onPlacedInPanelCallCount should be inc'ed");
|
||||
Assert.equal(onPlacedInUrlbarCallCount, 1,
|
||||
"onPlacedInUrlbarCallCount should be inc'ed");
|
||||
Assert.equal(onIframeShownCount, 0,
|
||||
"onIframeShownCount should remain 0");
|
||||
Assert.equal(onIframeShowingCount, 0,
|
||||
"onIframeShowingCount should remain 0");
|
||||
Assert.equal(onCommandCallCount, 0,
|
||||
"onCommandCallCount should remain 0");
|
||||
|
||||
@ -519,11 +519,11 @@ add_task(async function withIframe() {
|
||||
|
||||
// Open the panel, click the action's button.
|
||||
await promisePageActionPanelOpen();
|
||||
Assert.equal(onIframeShownCount, 0, "onIframeShownCount should remain 0");
|
||||
Assert.equal(onIframeShowingCount, 0, "onIframeShowingCount should remain 0");
|
||||
EventUtils.synthesizeMouseAtCenter(panelButtonNode, {});
|
||||
await promisePanelShown(BrowserPageActions._activatedActionPanelID);
|
||||
Assert.equal(onCommandCallCount, 0, "onCommandCallCount should remain 0");
|
||||
Assert.equal(onIframeShownCount, 1, "onIframeShownCount should be inc'ed");
|
||||
Assert.equal(onIframeShowingCount, 1, "onIframeShowingCount should be inc'ed");
|
||||
|
||||
// The activated-action panel should have opened, anchored to the action's
|
||||
// urlbar button.
|
||||
@ -538,7 +538,7 @@ add_task(async function withIframe() {
|
||||
EventUtils.synthesizeMouseAtCenter(urlbarButtonNode, {});
|
||||
await promisePanelShown(BrowserPageActions._activatedActionPanelID);
|
||||
Assert.equal(onCommandCallCount, 0, "onCommandCallCount should remain 0");
|
||||
Assert.equal(onIframeShownCount, 2, "onIframeShownCount should be inc'ed");
|
||||
Assert.equal(onIframeShowingCount, 2, "onIframeShowingCount should be inc'ed");
|
||||
|
||||
// The activated-action panel should have opened, again anchored to the
|
||||
// action's urlbar button.
|
||||
@ -558,7 +558,7 @@ add_task(async function withIframe() {
|
||||
EventUtils.synthesizeMouseAtCenter(panelButtonNode, {});
|
||||
await promisePanelShown(BrowserPageActions._activatedActionPanelID);
|
||||
Assert.equal(onCommandCallCount, 0, "onCommandCallCount should remain 0");
|
||||
Assert.equal(onIframeShownCount, 3, "onIframeShownCount should be inc'ed");
|
||||
Assert.equal(onIframeShowingCount, 3, "onIframeShowingCount should be inc'ed");
|
||||
|
||||
// The activated-action panel should have opened, this time anchored to the
|
||||
// main page action button in the urlbar.
|
||||
|
@ -66,7 +66,7 @@ tabbrowser {
|
||||
padding: 0 @horizontalTabPadding@;
|
||||
}
|
||||
|
||||
.tab-content[pinned] {
|
||||
:root:not([uidensity=compact]) .tab-content[pinned] {
|
||||
padding: 0 12px;
|
||||
}
|
||||
|
||||
@ -193,7 +193,7 @@ tabbrowser {
|
||||
100% { transform: translateX(100%); }
|
||||
}
|
||||
|
||||
#TabsToolbar[brighttext] .tab-throbber[busy]:not([visuallyselected=true])::before {
|
||||
#TabsToolbar[brighttext] .tab-throbber[busy]:not([selected=true])::before {
|
||||
/* Don't change the --tab-loading-fill variable because this should only affect
|
||||
tabs that are not visually selected. */
|
||||
fill: #717171;
|
||||
@ -205,7 +205,7 @@ tabbrowser {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
#TabsToolbar[brighttext] .tab-throbber[progress]:not([visuallyselected=true])::before {
|
||||
#TabsToolbar[brighttext] .tab-throbber[progress]:not([selected=true])::before {
|
||||
/* Don't change the --tab-loading-fill variable because this should only affect
|
||||
tabs that are not visually selected. */
|
||||
fill: #84c1ff;
|
||||
|
14
build/moz.configure/compile-checks.configure
Normal file → Executable file
14
build/moz.configure/compile-checks.configure
Normal file → Executable file
@ -105,6 +105,8 @@ def check_and_add_flags(flag, cflags, cxxflags, test_flags,
|
||||
if when is None:
|
||||
when = always
|
||||
|
||||
results = []
|
||||
|
||||
if test_flags:
|
||||
flags = test_flags
|
||||
else:
|
||||
@ -132,6 +134,10 @@ def check_and_add_flags(flag, cflags, cxxflags, test_flags,
|
||||
if result:
|
||||
list_of_flags.append(flag)
|
||||
|
||||
results.append(result)
|
||||
|
||||
return tuple(results)
|
||||
|
||||
|
||||
@dependable
|
||||
def warnings_cflags():
|
||||
@ -168,8 +174,8 @@ def check_and_add_gcc_warning(warning, compiler=None, when=None, check=True):
|
||||
else:
|
||||
flags = ['-Werror', warning]
|
||||
|
||||
check_and_add_flags(warning, warnings_cflags, warnings_cxxflags,
|
||||
flags, compiler=compiler, when=when, check=check)
|
||||
return check_and_add_flags(warning, warnings_cflags, warnings_cxxflags,
|
||||
flags, compiler=compiler, when=when, check=check)
|
||||
|
||||
|
||||
# Add the given warning to the list of warning flags for the build.
|
||||
@ -212,8 +218,8 @@ def compilation_cxxflags():
|
||||
def check_and_add_gcc_flag(flag, compiler=None, when=None, check=True):
|
||||
flags = ['-Werror', flag]
|
||||
|
||||
check_and_add_flags(flag, compilation_cflags, compilation_cxxflags,
|
||||
flags, compiler=compiler, when=when, check=check)
|
||||
return check_and_add_flags(flag, compilation_cflags, compilation_cxxflags,
|
||||
flags, compiler=compiler, when=when, check=check)
|
||||
|
||||
|
||||
# Add the given flag to the list of flags for the build.
|
||||
|
@ -102,31 +102,45 @@ check_and_add_gcc_warning('-Wno-error=coverage-mismatch', when='MOZ_PGO')
|
||||
check_and_add_gcc_warning('-Wno-error=free-nonheap-object')
|
||||
|
||||
# catches format/argument mismatches with printf
|
||||
check_and_add_gcc_warning('-Wformat')
|
||||
c_format_warning, cxx_format_warning = check_and_add_gcc_warning(
|
||||
'-Wformat', when=depends(target)(lambda t: t.kernel != 'WINNT'))
|
||||
|
||||
# We use mix of both POSIX and Win32 printf format across the tree, so format
|
||||
# warnings are useless on mingw.
|
||||
check_and_add_gcc_warning('-Wno-format',
|
||||
when=depends(target)(lambda t: t.kernel == 'WINNT'))
|
||||
# Add compile-time warnings for unprotected functions and format functions
|
||||
# that represent possible security problems. Enable this only when -Wformat
|
||||
# is enabled, otherwise it is an error
|
||||
check_and_add_gcc_warning('-Wformat-security',
|
||||
when=c_format_warning & cxx_format_warning)
|
||||
check_and_add_gcc_warning('-Wformat-overflow=2',
|
||||
when=c_format_warning & cxx_format_warning)
|
||||
|
||||
# When compiling for Windows with gcc, we encounter lots of "#pragma warning"'s
|
||||
# which is an MSVC-only pragma that GCC does not recognize.
|
||||
check_and_add_gcc_warning('-Wno-unknown-pragmas',
|
||||
when=depends(target)(lambda t: t.kernel == 'WINNT'))
|
||||
# Other MinGW specific things
|
||||
with only_when(depends(target)(lambda t: t.kernel == 'WINNT')):
|
||||
# When compiling for Windows with gcc, we encounter lots of "#pragma warning"'s
|
||||
# which is an MSVC-only pragma that GCC does not recognize.
|
||||
check_and_add_gcc_warning('-Wno-unknown-pragmas')
|
||||
|
||||
# When compiling for Windows with gcc, gcc throws false positives and true
|
||||
# positives where the callsite is ifdef-ed out
|
||||
check_and_add_gcc_warning('-Wno-unused-function',
|
||||
when=depends(target)(lambda t: t.kernel == 'WINNT'))
|
||||
# When compiling for Windows with gcc, gcc throws false positives and true
|
||||
# positives where the callsite is ifdef-ed out
|
||||
check_and_add_gcc_warning('-Wno-unused-function')
|
||||
|
||||
# When compiling for Windows with gcc, gcc cannot produce this warning
|
||||
# correctly: it mistakes DWORD_PTR and ULONG_PTR as types you cannot
|
||||
# give NULL to. (You can in fact do that.)
|
||||
check_and_add_gcc_warning('-Wno-conversion-null')
|
||||
|
||||
# Throughout the codebase we regularly have switch statements off of enums
|
||||
# without covering every value in the enum. We don't care about these warnings.
|
||||
check_and_add_gcc_warning('-Wno-switch')
|
||||
|
||||
# Another code pattern we have is using start and end constants in enums of
|
||||
# different types. We do this for safety, but then when comparing it throws
|
||||
# an error, which we would like to ignore. This seems to only affect the MinGW
|
||||
# build, but we're not sure why.
|
||||
check_and_add_gcc_warning('-Wno-enum-compare')
|
||||
|
||||
# We hit this all over the place with the gtest INSTANTIATE_TEST_CASE_P macro
|
||||
check_and_add_gcc_warning('-Wno-gnu-zero-variadic-macro-arguments')
|
||||
|
||||
# Add compile-time warnings for unprotected functions and format functions
|
||||
# that represent possible security problems
|
||||
check_and_add_gcc_warning('-Wformat-security')
|
||||
check_and_add_gcc_warning('-Wformat-overflow=2')
|
||||
|
||||
# Disable a warning with gcc 7. See bug 1320656
|
||||
# We are far from using C++17 and the impact of the warning will be
|
||||
# limited to a potential public ABI.
|
||||
|
58
client.mk
58
client.mk
@ -37,27 +37,8 @@ PYTHON ?= $(shell which python2.7 > /dev/null 2>&1 && echo python2.7 || echo pyt
|
||||
####################################
|
||||
# Load mozconfig Options
|
||||
|
||||
# See build pages, http://www.mozilla.org/build/ for how to set up mozconfig.
|
||||
|
||||
define CR
|
||||
|
||||
|
||||
endef
|
||||
|
||||
# As $(shell) doesn't preserve newlines, use sed to replace them with an
|
||||
# unlikely sequence (||), which is then replaced back to newlines by make
|
||||
# before evaluation. $(shell) replacing newlines with spaces, || is always
|
||||
# followed by a space (since sed doesn't remove newlines), except on the
|
||||
# last line, so replace both '|| ' and '||'.
|
||||
MOZCONFIG_CONTENT := $(subst ||,$(CR),$(subst || ,$(CR),$(shell cat $(OBJDIR)/.mozconfig-client-mk | sed 's/$$/||/')))
|
||||
include $(OBJDIR)/.mozconfig-client-mk
|
||||
|
||||
# As '||' was used as a newline separator, it means it's not occurring in
|
||||
# lines themselves. It can thus safely be used to replaces normal spaces,
|
||||
# to then replace newlines with normal spaces. This allows to get a list
|
||||
# of mozconfig output lines.
|
||||
MOZCONFIG_OUT_LINES := $(subst $(CR), ,$(subst $(NULL) $(NULL),||,$(MOZCONFIG_CONTENT)))
|
||||
|
||||
ifdef MOZ_PARALLEL_BUILD
|
||||
MOZ_MAKE_FLAGS := $(filter-out -j%,$(MOZ_MAKE_FLAGS))
|
||||
MOZ_MAKE_FLAGS += -j$(MOZ_PARALLEL_BUILD)
|
||||
@ -92,23 +73,6 @@ $(error client.mk must be used via `mach`. Try running \
|
||||
`./mach $(firstword $(MAKECMDGOALS) $(.DEFAULT_GOAL))`)
|
||||
endif
|
||||
|
||||
# For now, only output "export" lines and lines containing UPLOAD_EXTRA_FILES.
|
||||
MOZCONFIG_MK_LINES := $(filter export||% UPLOAD_EXTRA_FILES% %UPLOAD_EXTRA_FILES%,$(MOZCONFIG_OUT_LINES))
|
||||
$(OBJDIR)/.mozconfig.mk: $(TOPSRCDIR)/client.mk $(FOUND_MOZCONFIG)
|
||||
$(if $(MOZCONFIG_MK_LINES),( $(foreach line,$(MOZCONFIG_MK_LINES), echo '$(subst ||, ,$(line))';) )) > $@
|
||||
|
||||
# Include that makefile so that it is created. This should not actually change
|
||||
# the environment since MOZCONFIG_CONTENT, which MOZCONFIG_OUT_LINES derives
|
||||
# from, has already been eval'ed.
|
||||
include $(OBJDIR)/.mozconfig.mk
|
||||
|
||||
# Print out any options loaded from mozconfig.
|
||||
all build clean distclean export libs install realclean::
|
||||
ifneq (,$(strip $(MOZCONFIG_OUT_LINES)))
|
||||
$(info Adding client.mk options from $(FOUND_MOZCONFIG):)
|
||||
$(foreach line,$(MOZCONFIG_OUT_LINES),$(info $(NULL) $(NULL) $(NULL) $(NULL) $(subst ||, ,$(line))))
|
||||
endif
|
||||
|
||||
# In automation, manage an sccache daemon. The starting of the server
|
||||
# needs to be in a make file so sccache inherits the jobserver.
|
||||
ifdef MOZBUILD_MANAGE_SCCACHE_DAEMON
|
||||
@ -174,24 +138,9 @@ configure-files: $(CONFIGURES)
|
||||
|
||||
configure-preqs = \
|
||||
configure-files \
|
||||
save-mozconfig \
|
||||
$(OBJDIR)/.mozconfig.json \
|
||||
$(NULL)
|
||||
|
||||
CREATE_MOZCONFIG_JSON = $(shell $(TOPSRCDIR)/mach environment --format=json -o $(OBJDIR)/.mozconfig.json)
|
||||
# Force CREATE_MOZCONFIG_JSON above to be resolved, without side effects in
|
||||
# case the result is non empty, and allowing an override on the make command
|
||||
# line not running the command (using := $(shell) still runs the shell command).
|
||||
ifneq (,$(CREATE_MOZCONFIG_JSON))
|
||||
endif
|
||||
|
||||
$(OBJDIR)/.mozconfig.json: ;
|
||||
|
||||
save-mozconfig: $(FOUND_MOZCONFIG)
|
||||
ifdef FOUND_MOZCONFIG
|
||||
-cp $(FOUND_MOZCONFIG) $(OBJDIR)/.mozconfig
|
||||
endif
|
||||
|
||||
configure:: $(configure-preqs)
|
||||
$(call BUILDSTATUS,TIERS configure)
|
||||
$(call BUILDSTATUS,TIER_START configure)
|
||||
@ -210,12 +159,7 @@ $(OBJDIR)/config.status: $(CONFIG_STATUS_DEPS)
|
||||
else
|
||||
$(OBJDIR)/Makefile: $(CONFIG_STATUS_DEPS)
|
||||
endif
|
||||
@$(MAKE) -f $(TOPSRCDIR)/client.mk configure CREATE_MOZCONFIG_JSON=
|
||||
|
||||
ifneq (,$(CONFIG_STATUS))
|
||||
$(OBJDIR)/config/autoconf.mk: $(TOPSRCDIR)/config/autoconf.mk.in
|
||||
$(PYTHON) $(OBJDIR)/config.status -n --file=$(OBJDIR)/config/autoconf.mk
|
||||
endif
|
||||
@$(MAKE) -f $(TOPSRCDIR)/client.mk configure
|
||||
|
||||
####################################
|
||||
# Build it
|
||||
|
@ -3,8 +3,10 @@
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
"use strict";
|
||||
|
||||
const {DOM, Component, PropTypes} = require("devtools/client/shared/vendor/react");
|
||||
const {img, button, span} = DOM;
|
||||
const { Component } = require("devtools/client/shared/vendor/react");
|
||||
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
||||
const dom = require("devtools/client/shared/vendor/react-dom-factories");
|
||||
const {img, button, span} = dom;
|
||||
|
||||
class ToolboxTab extends Component {
|
||||
// See toolbox-toolbar propTypes for details on the props used here.
|
||||
|
@ -3,10 +3,11 @@
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
"use strict";
|
||||
|
||||
const {DOM, Component, createFactory, PropTypes} = require("devtools/client/shared/vendor/react");
|
||||
|
||||
const { Component, createFactory } = require("devtools/client/shared/vendor/react");
|
||||
const dom = require("devtools/client/shared/vendor/react-dom-factories");
|
||||
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
||||
const {findDOMNode} = require("devtools/client/shared/vendor/react-dom");
|
||||
const {button, div} = DOM;
|
||||
const {button, div} = dom;
|
||||
|
||||
const Menu = require("devtools/client/framework/menu");
|
||||
const MenuItem = require("devtools/client/framework/menu-item");
|
||||
|
@ -3,8 +3,10 @@
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
"use strict";
|
||||
|
||||
const {DOM, Component, createFactory, PropTypes} = require("devtools/client/shared/vendor/react");
|
||||
const {div, button} = DOM;
|
||||
const { Component, createFactory } = require("devtools/client/shared/vendor/react");
|
||||
const dom = require("devtools/client/shared/vendor/react-dom-factories");
|
||||
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
||||
const {div, button} = dom;
|
||||
|
||||
const ToolboxTab = createFactory(require("devtools/client/framework/components/toolbox-tab"));
|
||||
const ToolboxTabs = createFactory(require("devtools/client/framework/components/toolbox-tabs"));
|
||||
|
@ -7,17 +7,7 @@ devtools.jar:
|
||||
content/shared/vendor/d3.js (shared/vendor/d3.js)
|
||||
content/shared/vendor/dagre-d3.js (shared/vendor/dagre-d3.js)
|
||||
content/shared/widgets/widgets.css (shared/widgets/widgets.css)
|
||||
content/netmonitor/src/assets/styles/httpi.css (netmonitor/src/assets/styles/httpi.css)
|
||||
content/netmonitor/src/assets/styles/MdnLink.css (netmonitor/src/assets/styles/MdnLink.css)
|
||||
content/netmonitor/src/assets/styles/netmonitor.css (netmonitor/src/assets/styles/netmonitor.css)
|
||||
content/netmonitor/src/assets/styles/NetworkDetailsPanel.css (netmonitor/src/assets/styles/NetworkDetailsPanel.css)
|
||||
content/netmonitor/src/assets/styles/RequestList.css (netmonitor/src/assets/styles/RequestList.css)
|
||||
content/netmonitor/src/assets/styles/StatisticsPanel.css (netmonitor/src/assets/styles/StatisticsPanel.css)
|
||||
content/netmonitor/src/assets/styles/StatusBar.css (netmonitor/src/assets/styles/StatusBar.css)
|
||||
content/netmonitor/src/assets/styles/Toolbar.css (netmonitor/src/assets/styles/Toolbar.css)
|
||||
content/netmonitor/src/assets/styles/variables.css (netmonitor/src/assets/styles/variables.css)
|
||||
content/shared/widgets/VariablesView.xul (shared/widgets/VariablesView.xul)
|
||||
content/netmonitor/index.html (netmonitor/index.html)
|
||||
content/webconsole/webconsole.html (webconsole/webconsole.html)
|
||||
content/webconsole/webconsole.xul (webconsole/webconsole.xul)
|
||||
content/scratchpad/scratchpad.xul (scratchpad/scratchpad.xul)
|
||||
@ -318,3 +308,16 @@ devtools.jar:
|
||||
skin/images/debugger/stepIn.svg (themes/images/debugger/stepIn.svg)
|
||||
skin/images/debugger/stepOut.svg (themes/images/debugger/stepOut.svg)
|
||||
skin/images/debugger/stepOver.svg (themes/images/debugger/stepOver.svg)
|
||||
|
||||
# Netmonitor
|
||||
content/netmonitor/src/assets/styles/httpi.css (netmonitor/src/assets/styles/httpi.css)
|
||||
content/netmonitor/src/assets/styles/MdnLink.css (netmonitor/src/assets/styles/MdnLink.css)
|
||||
content/netmonitor/src/assets/styles/netmonitor.css (netmonitor/src/assets/styles/netmonitor.css)
|
||||
content/netmonitor/src/assets/styles/NetworkDetailsPanel.css (netmonitor/src/assets/styles/NetworkDetailsPanel.css)
|
||||
content/netmonitor/src/assets/styles/RequestList.css (netmonitor/src/assets/styles/RequestList.css)
|
||||
content/netmonitor/src/assets/styles/StatisticsPanel.css (netmonitor/src/assets/styles/StatisticsPanel.css)
|
||||
content/netmonitor/src/assets/styles/StatusBar.css (netmonitor/src/assets/styles/StatusBar.css)
|
||||
content/netmonitor/src/assets/styles/Toolbar.css (netmonitor/src/assets/styles/Toolbar.css)
|
||||
content/netmonitor/src/assets/styles/variables.css (netmonitor/src/assets/styles/variables.css)
|
||||
content/netmonitor/src/assets/icons/play.svg (netmonitor/src/assets/icons/play.svg)
|
||||
content/netmonitor/index.html (netmonitor/index.html)
|
||||
|
@ -25,7 +25,6 @@ const BinaryInput = CC("@mozilla.org/binaryinputstream;1",
|
||||
const BufferStream = CC("@mozilla.org/io/arraybuffer-input-stream;1",
|
||||
"nsIArrayBufferInputStream", "setData");
|
||||
const encodingLength = 2;
|
||||
const encoder = new TextEncoder();
|
||||
|
||||
// Localization
|
||||
loader.lazyGetter(this, "jsonViewStrings", () => {
|
||||
@ -58,7 +57,7 @@ Converter.prototype = {
|
||||
* 1. asyncConvertData captures the listener
|
||||
* 2. onStartRequest fires, initializes stuff, modifies the listener
|
||||
* to match our output type
|
||||
* 3. onDataAvailable converts to UTF-8 and spits back to the listener
|
||||
* 3. onDataAvailable decodes and inserts data into a text node
|
||||
* 4. onStopRequest flushes data and spits back to the listener
|
||||
* 5. convert does nothing, it's just the synchronous version
|
||||
* of asyncConvertData
|
||||
@ -87,20 +86,15 @@ Converter.prototype = {
|
||||
this.determineEncoding(request, context);
|
||||
}
|
||||
|
||||
// Spit back the data if the encoding is UTF-8, otherwise convert it first.
|
||||
if (!this.decoder) {
|
||||
this.listener.onDataAvailable(request, context, inputStream, offset, count);
|
||||
} else {
|
||||
let buffer = new ArrayBuffer(count);
|
||||
new BinaryInput(inputStream).readArrayBuffer(count, buffer);
|
||||
this.convertAndSendBuffer(request, context, buffer);
|
||||
}
|
||||
// Decode and insert data.
|
||||
let buffer = new ArrayBuffer(count);
|
||||
new BinaryInput(inputStream).readArrayBuffer(count, buffer);
|
||||
this.decodeAndInsertBuffer(request, context, buffer);
|
||||
},
|
||||
|
||||
onStartRequest: function (request, context) {
|
||||
// Set the content type to HTML in order to parse the doctype, styles
|
||||
// and scripts, but later a <plaintext> element will switch the tokenizer
|
||||
// to the plaintext state in order to parse the JSON.
|
||||
// and scripts. The JSON will be manually inserted as text.
|
||||
request.QueryInterface(Ci.nsIChannel);
|
||||
request.contentType = "text/html";
|
||||
|
||||
@ -121,14 +115,14 @@ Converter.prototype = {
|
||||
// Initialize stuff.
|
||||
let win = NetworkHelper.getWindowForRequest(request);
|
||||
this.data = exportData(win, request);
|
||||
win.addEventListener("DOMContentLoaded", event => {
|
||||
win.addEventListener("contentMessage", onContentMessage, false, true);
|
||||
}, {once: true});
|
||||
insertJsonData(win, this.data.json);
|
||||
win.addEventListener("contentMessage", onContentMessage, false, true);
|
||||
keepThemeUpdated(win);
|
||||
|
||||
// Send the initial HTML code.
|
||||
let bytes = encoder.encode(initialHTML(win.document));
|
||||
this.convertAndSendBuffer(request, context, bytes.buffer);
|
||||
let buffer = new TextEncoder().encode(initialHTML(win.document)).buffer;
|
||||
let stream = new BufferStream(buffer, 0, buffer.byteLength);
|
||||
this.listener.onDataAvailable(request, context, stream, 0, stream.available());
|
||||
|
||||
// Create an array to store data until the encoding is determined.
|
||||
this.encodingArray = [];
|
||||
@ -139,7 +133,7 @@ Converter.prototype = {
|
||||
if (this.encodingArray) {
|
||||
this.determineEncoding(request, context, true);
|
||||
} else {
|
||||
this.convertAndSendBuffer(request, context, new ArrayBuffer(0), true);
|
||||
this.decodeAndInsertBuffer(request, context, new ArrayBuffer(0), true);
|
||||
}
|
||||
|
||||
// Stop the request.
|
||||
@ -168,32 +162,24 @@ Converter.prototype = {
|
||||
}
|
||||
}
|
||||
|
||||
// Create a decoder unless the data is already in UTF-8.
|
||||
if (encoding !== "UTF-8") {
|
||||
this.decoder = new TextDecoder(encoding, {ignoreBOM: true});
|
||||
}
|
||||
|
||||
// Create a decoder for that encoding.
|
||||
this.decoder = new TextDecoder(encoding);
|
||||
this.data.encoding = encoding;
|
||||
|
||||
// Send the bytes in encodingArray, and remove it.
|
||||
// Decode and insert the bytes in encodingArray, and remove it.
|
||||
let buffer = new Uint8Array(bytes).buffer;
|
||||
this.convertAndSendBuffer(request, context, buffer, flush);
|
||||
this.decodeAndInsertBuffer(request, context, buffer, flush);
|
||||
this.encodingArray = null;
|
||||
},
|
||||
|
||||
// Converts an ArrayBuffer to UTF-8 and sends it.
|
||||
convertAndSendBuffer: function (request, context, buffer, flush = false) {
|
||||
// If the encoding is not UTF-8, decode the buffer and encode into UTF-8.
|
||||
if (this.decoder) {
|
||||
let data = this.decoder.decode(buffer, {stream: !flush});
|
||||
buffer = encoder.encode(data).buffer;
|
||||
}
|
||||
// Decodes an ArrayBuffer into a string and inserts it into the page.
|
||||
decodeAndInsertBuffer: function (request, context, buffer, flush = false) {
|
||||
// Decode the buffer into a string.
|
||||
let data = this.decoder.decode(buffer, {stream: !flush});
|
||||
|
||||
// Create an input stream that contains the bytes in the buffer.
|
||||
let stream = new BufferStream(buffer, 0, buffer.byteLength);
|
||||
|
||||
// Send the input stream.
|
||||
this.listener.onDataAvailable(request, context, stream, 0, stream.available());
|
||||
// Using `appendData` instead of `textContent +=` is important to avoid
|
||||
// repainting previous data.
|
||||
this.data.json.appendData(data);
|
||||
}
|
||||
};
|
||||
|
||||
@ -231,6 +217,8 @@ function exportData(win, request) {
|
||||
|
||||
data.debug = debug;
|
||||
|
||||
data.json = new win.Text();
|
||||
|
||||
let Locale = {
|
||||
$STR: key => {
|
||||
try {
|
||||
@ -266,23 +254,18 @@ function exportData(win, request) {
|
||||
return data;
|
||||
}
|
||||
|
||||
// Serializes a qualifiedName and an optional set of attributes into an HTML
|
||||
// start tag. Be aware qualifiedName and attribute names are not validated.
|
||||
// Attribute values are escaped with escapingString algorithm in attribute mode
|
||||
// (https://html.spec.whatwg.org/multipage/syntax.html#escapingString).
|
||||
function startTag(qualifiedName, attributes = {}) {
|
||||
return Object.entries(attributes).reduce(function (prev, [attr, value]) {
|
||||
return prev + " " + attr + "=\"" +
|
||||
value.replace(/&/g, "&")
|
||||
.replace(/\u00a0/g, " ")
|
||||
.replace(/"/g, """) +
|
||||
"\"";
|
||||
}, "<" + qualifiedName) + ">";
|
||||
}
|
||||
|
||||
// Builds an HTML string that will be used to load stylesheets and scripts,
|
||||
// and switch the parser to plaintext state.
|
||||
// Builds an HTML string that will be used to load stylesheets and scripts.
|
||||
function initialHTML(doc) {
|
||||
// Creates an element with the specified type, attributes and children.
|
||||
function element(type, attributes = {}, children = []) {
|
||||
let el = doc.createElement(type);
|
||||
for (let [attr, value] of Object.entries(attributes)) {
|
||||
el.setAttribute(attr, value);
|
||||
}
|
||||
el.append(...children);
|
||||
return el;
|
||||
}
|
||||
|
||||
let os;
|
||||
let platform = Services.appinfo.OS;
|
||||
if (platform.startsWith("WINNT")) {
|
||||
@ -297,29 +280,53 @@ function initialHTML(doc) {
|
||||
// because the latter can be blocked by a CSP base-uri directive (bug 1316393)
|
||||
let baseURI = "resource://devtools-client-jsonview/";
|
||||
|
||||
let style = doc.createElement("link");
|
||||
style.rel = "stylesheet";
|
||||
style.type = "text/css";
|
||||
style.href = baseURI + "css/main.css";
|
||||
|
||||
let script = doc.createElement("script");
|
||||
script.src = baseURI + "lib/require.js";
|
||||
script.dataset.main = baseURI + "viewer-config.js";
|
||||
script.defer = true;
|
||||
|
||||
let head = doc.createElement("head");
|
||||
head.append(style, script);
|
||||
|
||||
return "<!DOCTYPE html>\n" +
|
||||
startTag("html", {
|
||||
element("html", {
|
||||
"platform": os,
|
||||
"class": "theme-" + Services.prefs.getCharPref("devtools.theme"),
|
||||
"dir": Services.locale.isAppLocaleRTL ? "rtl" : "ltr"
|
||||
}) +
|
||||
head.outerHTML +
|
||||
startTag("body") +
|
||||
startTag("div", {"id": "content"}) +
|
||||
startTag("plaintext", {"id": "json"});
|
||||
}, [
|
||||
element("head", {}, [
|
||||
element("link", {
|
||||
rel: "stylesheet",
|
||||
type: "text/css",
|
||||
href: baseURI + "css/main.css",
|
||||
}),
|
||||
element("script", {
|
||||
src: baseURI + "lib/require.js",
|
||||
"data-main": baseURI + "viewer-config.js",
|
||||
defer: true,
|
||||
})
|
||||
]),
|
||||
element("body", {}, [
|
||||
element("div", {"id": "content"}, [
|
||||
element("div", {"id": "json"})
|
||||
])
|
||||
])
|
||||
]).outerHTML;
|
||||
}
|
||||
|
||||
// We insert the received data into a text node, which should be appended into
|
||||
// the #json element so that the JSON is still displayed even if JS is disabled.
|
||||
// However, the HTML parser is not synchronous, so this function uses a mutation
|
||||
// observer to detect the creation of the element. Then the text node is appended.
|
||||
function insertJsonData(win, json) {
|
||||
new win.MutationObserver(function (mutations, observer) {
|
||||
for (let {target, addedNodes} of mutations) {
|
||||
if (target.nodeType == 1 && target.id == "content") {
|
||||
for (let node of addedNodes) {
|
||||
if (node.nodeType == 1 && node.id == "json") {
|
||||
observer.disconnect();
|
||||
node.append(json);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}).observe(win.document, {
|
||||
childList: true,
|
||||
subtree: true,
|
||||
});
|
||||
}
|
||||
|
||||
function keepThemeUpdated(win) {
|
||||
|
@ -12,7 +12,6 @@ define(function (require, exports, module) {
|
||||
const { MainTabbedArea } = createFactories(require("./components/MainTabbedArea"));
|
||||
const TreeViewClass = require("devtools/client/shared/components/tree/TreeView");
|
||||
|
||||
const json = document.getElementById("json");
|
||||
const AUTO_EXPAND_MAX_SIZE = 100 * 1024;
|
||||
const AUTO_EXPAND_MAX_LEVEL = 7;
|
||||
|
||||
@ -20,18 +19,13 @@ define(function (require, exports, module) {
|
||||
|
||||
// Application state object.
|
||||
let input = {
|
||||
jsonText: json.textContent,
|
||||
jsonText: JSONView.json.textContent,
|
||||
jsonPretty: null,
|
||||
headers: JSONView.headers,
|
||||
tabActive: 0,
|
||||
prettified: false
|
||||
};
|
||||
|
||||
// Remove BOM.
|
||||
if (input.jsonText.startsWith("\ufeff")) {
|
||||
input.jsonText = input.jsonText.slice(1);
|
||||
}
|
||||
|
||||
try {
|
||||
input.json = JSON.parse(input.jsonText);
|
||||
} catch (err) {
|
||||
@ -48,8 +42,6 @@ define(function (require, exports, module) {
|
||||
input.expandedNodes = new Set();
|
||||
}
|
||||
|
||||
json.remove();
|
||||
|
||||
/**
|
||||
* Application actions/commands. This list implements all commands
|
||||
* available for the JSON viewer.
|
||||
|
@ -50,6 +50,12 @@ add_task(function* () {
|
||||
"UTF-16LE": "%FF%FE"
|
||||
};
|
||||
|
||||
// Test double BOM.
|
||||
tests.push(Object.entries(bom).reduce((obj, [prop, value]) => {
|
||||
obj[prop + " with BOM"] = value;
|
||||
return obj;
|
||||
}, {[text]: "\uFEFF"}));
|
||||
|
||||
for (let test of tests) {
|
||||
let result = test[text];
|
||||
for (let [encoding, data] of Object.entries(test)) {
|
||||
|
@ -13,6 +13,6 @@ add_task(function* () {
|
||||
|
||||
yield selectJsonViewContentTab("rawdata");
|
||||
let rawData = yield getElementText(".textPanelBox .data");
|
||||
is(rawData, "\"foo_\uFFFD_bar\"",
|
||||
"The NUL character has been replaced by the replacement character.");
|
||||
is(rawData, "\"foo_\u0000_bar\"",
|
||||
"The NUL character has been preserved.");
|
||||
});
|
||||
|
8
devtools/client/netmonitor/src/assets/icons/play.svg
Normal file
8
devtools/client/netmonitor/src/assets/icons/play.svg
Normal file
@ -0,0 +1,8 @@
|
||||
<!-- 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/. -->
|
||||
<svg width="10" height="12" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="context-fill #0b0b0b">
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<polygon id="Triangle-2" fill="#0A84FF" points="14 6 4 12 4 0"></polygon>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 505 B |
@ -41,6 +41,6 @@
|
||||
|
||||
/* Icons */
|
||||
:root {
|
||||
--play-icon-url: url("chrome://devtools/skin/images/play.svg");
|
||||
--play-icon-url: url("chrome://devtools/content/netmonitor/src/assets/icons/play.svg");
|
||||
--pause-icon-url: url("chrome://devtools/skin/images/pause.svg");
|
||||
}
|
||||
|
@ -103,7 +103,10 @@ class RequestListHeader extends Component {
|
||||
|
||||
return (
|
||||
div({ className: "devtools-toolbar requests-list-headers-wrapper" },
|
||||
div({ className: "devtools-toolbar requests-list-headers" },
|
||||
div({
|
||||
className: "devtools-toolbar requests-list-headers",
|
||||
onContextMenu: this.onContextMenu
|
||||
},
|
||||
HEADERS.filter((header) => columns.get(header.name)).map((header) => {
|
||||
let name = header.name;
|
||||
let boxName = header.boxName || name;
|
||||
@ -127,7 +130,6 @@ class RequestListHeader extends Component {
|
||||
ref: `${name}Header`,
|
||||
// Used to style the next column.
|
||||
"data-active": active,
|
||||
onContextMenu: this.onContextMenu,
|
||||
},
|
||||
button({
|
||||
id: `requests-list-${name}-button`,
|
||||
|
@ -22,8 +22,28 @@ add_task(function* () {
|
||||
yield testVisibleColumnContextMenuItem(column, document, parent);
|
||||
}
|
||||
}
|
||||
|
||||
for (let [column, shown] of store.getState().ui.columns) {
|
||||
if (shown) {
|
||||
yield testVisibleColumnContextMenuItem(column, document, parent);
|
||||
// Right click on the white-space for the context menu to appear
|
||||
// and toggle column visibility
|
||||
yield testWhiteSpaceContextMenuItem(column, document, parent);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function* testWhiteSpaceContextMenuItem(column, document, parent) {
|
||||
ok(!document.querySelector(`#requests-list-${column}-button`),
|
||||
`Column ${column} should be hidden`);
|
||||
|
||||
info(`Right clicking on white-space in the header to get the context menu`);
|
||||
EventUtils.sendMouseEvent({ type: "contextmenu" },
|
||||
document.querySelector(".devtools-toolbar.requests-list-headers"));
|
||||
|
||||
yield toggleAndCheckColumnVisibility(column, document, parent);
|
||||
}
|
||||
|
||||
function* testVisibleColumnContextMenuItem(column, document, parent) {
|
||||
ok(document.querySelector(`#requests-list-${column}-button`),
|
||||
`Column ${column} should be visible`);
|
||||
@ -59,6 +79,10 @@ function* testHiddenColumnContextMenuItem(column, document, parent) {
|
||||
document.querySelector("#requests-list-status-button") ||
|
||||
document.querySelector("#requests-list-waterfall-button"));
|
||||
|
||||
yield toggleAndCheckColumnVisibility(column, document, parent);
|
||||
}
|
||||
|
||||
function* toggleAndCheckColumnVisibility(column, document, parent) {
|
||||
let menuItem = parent.document.querySelector(`#request-list-header-${column}-toggle`);
|
||||
|
||||
is(menuItem.getAttribute("type"), "checkbox",
|
||||
|
@ -190,8 +190,13 @@ HUD_SERVICE.prototype =
|
||||
|
||||
if (!DebuggerServer.initialized) {
|
||||
DebuggerServer.init();
|
||||
DebuggerServer.addBrowserActors();
|
||||
}
|
||||
|
||||
// Ensure that the root actor and the tab actors have been registered on the DebuggerServer,
|
||||
// so that the Browser Console can retrieve the console actors.
|
||||
// (See Bug 1416105 for rationale).
|
||||
DebuggerServer.registerActors({ root: true, browser: false, tab: true });
|
||||
|
||||
DebuggerServer.allowChromeProcess = true;
|
||||
|
||||
let client = new DebuggerClient(DebuggerServer.connectPipe());
|
||||
|
@ -56,8 +56,6 @@ support-files =
|
||||
test-bug-597136-external-script-errors.js
|
||||
test-bug-597756-reopen-closed-tab.html
|
||||
test-bug-599725-response-headers.sjs
|
||||
test-bug-600183-charset.html
|
||||
test-bug-600183-charset.html^headers^
|
||||
test-bug-601177-log-levels.html
|
||||
test-bug-601177-log-levels.js
|
||||
test-bug-603750-websocket.html
|
||||
@ -166,6 +164,7 @@ support-files =
|
||||
!/devtools/client/netmonitor/test/sjs_cors-test-server.sjs
|
||||
!/image/test/mochitest/blue.png
|
||||
!/devtools/client/framework/test/shared-head.js
|
||||
!/devtools/client/netmonitor/test/shared-head.js
|
||||
[browser_console.js]
|
||||
skip-if = true # Bug 1406060
|
||||
[browser_console_addonsdk_loader_exception.js]
|
||||
@ -230,13 +229,10 @@ tags = mcb
|
||||
[browser_webconsole_cached_messages.js]
|
||||
[browser_webconsole_cd_iframe.js]
|
||||
[browser_webconsole_certificate_messages.js]
|
||||
[browser_webconsole_charset.js]
|
||||
skip-if = true # Bug 1404400
|
||||
[browser_webconsole_click_function_to_source.js]
|
||||
skip-if = true # Bug 1406038
|
||||
[browser_webconsole_clickable_urls.js]
|
||||
[browser_webconsole_closing_after_completion.js]
|
||||
skip-if = true # Bug 1408927
|
||||
[browser_webconsole_closure_inspection.js]
|
||||
skip-if = true # Bug 1405250
|
||||
[browser_webconsole_completion.js]
|
||||
|
@ -1,61 +0,0 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// See Bug 600183.
|
||||
|
||||
const INIT_URI = "data:text/html;charset=utf-8,Web Console - bug 600183 test";
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test-bug-600183-charset.html";
|
||||
|
||||
function performTest(lastFinishedRequest, console) {
|
||||
let deferred = defer();
|
||||
|
||||
ok(lastFinishedRequest, "charset test page was loaded and logged");
|
||||
HUDService.lastFinishedRequest.callback = null;
|
||||
|
||||
executeSoon(() => {
|
||||
console.webConsoleClient.getResponseContent(lastFinishedRequest.actor,
|
||||
(response) => {
|
||||
ok(!response.contentDiscarded, "response body was not discarded");
|
||||
|
||||
let body = response.content.text;
|
||||
ok(body, "we have the response body");
|
||||
|
||||
// 的问候!
|
||||
let chars = "\u7684\u95ee\u5019!";
|
||||
isnot(body.indexOf("<p>" + chars + "</p>"), -1,
|
||||
"found the chinese simplified string");
|
||||
|
||||
HUDService.lastFinishedRequest.callback = null;
|
||||
executeSoon(deferred.resolve);
|
||||
});
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function waitForRequest() {
|
||||
let deferred = defer();
|
||||
HUDService.lastFinishedRequest.callback = (req, console) => {
|
||||
performTest(req, console).then(deferred.resolve);
|
||||
};
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
add_task(function* () {
|
||||
let { browser } = yield loadTab(INIT_URI);
|
||||
|
||||
yield openConsole();
|
||||
|
||||
let gotLastRequest = waitForRequest();
|
||||
|
||||
let loaded = loadBrowser(browser);
|
||||
BrowserTestUtils.loadURI(browser, TEST_URI);
|
||||
yield loaded;
|
||||
|
||||
yield gotLastRequest;
|
||||
});
|
@ -9,17 +9,15 @@
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test-console.html";
|
||||
"new-console-output/test/mochitest/test-console.html";
|
||||
|
||||
add_task(function* () {
|
||||
let { browser } = yield loadTab(TEST_URI);
|
||||
add_task(async function () {
|
||||
let tab = await addTab(TEST_URI);
|
||||
const browser = tab.linkedBrowser;
|
||||
const hud = await openConsole();
|
||||
|
||||
let hud = yield openConsole();
|
||||
yield testClosingAfterCompletion(hud, browser);
|
||||
});
|
||||
|
||||
function testClosingAfterCompletion(hud, browser) {
|
||||
let deferred = defer();
|
||||
// Fire a completion.
|
||||
await jstermSetValueAndComplete(hud.jsterm, "doc");
|
||||
|
||||
let errorWhileClosing = false;
|
||||
function errorListener() {
|
||||
@ -27,21 +25,17 @@ function testClosingAfterCompletion(hud, browser) {
|
||||
}
|
||||
|
||||
browser.addEventListener("error", errorListener);
|
||||
const onToolboxDestroyed = gDevTools.once("toolbox-destroyed");
|
||||
|
||||
// Focus the jsterm and perform the keycombo to close the WebConsole.
|
||||
hud.jsterm.focus();
|
||||
|
||||
gDevTools.once("toolbox-destroyed", function () {
|
||||
browser.removeEventListener("error", errorListener);
|
||||
is(errorWhileClosing, false, "no error while closing the WebConsole");
|
||||
deferred.resolve();
|
||||
EventUtils.synthesizeKey("i", {
|
||||
accelKey: true,
|
||||
[Services.appinfo.OS == "Darwin" ? "altKey" : "shiftKey"]: true
|
||||
});
|
||||
|
||||
if (Services.appinfo.OS == "Darwin") {
|
||||
EventUtils.synthesizeKey("i", { accelKey: true, altKey: true });
|
||||
} else {
|
||||
EventUtils.synthesizeKey("i", { accelKey: true, shiftKey: true });
|
||||
}
|
||||
await onToolboxDestroyed;
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
browser.removeEventListener("error", errorListener);
|
||||
is(errorWhileClosing, false, "no error while closing the WebConsole");
|
||||
});
|
||||
|
@ -1,9 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html dir="ltr" xml:lang="en-US" lang="en-US"><head>
|
||||
<meta charset="gb2312">
|
||||
<title>Console HTTP test page (chinese)</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>的问候!</p>
|
||||
</body>
|
||||
</html>
|
@ -1 +0,0 @@
|
||||
Content-Type: text/html; charset=gb2312
|
@ -361,8 +361,7 @@ public:
|
||||
static bool IsCustomElementEnabled(JSContext* aCx = nullptr,
|
||||
JSObject* aObject = nullptr)
|
||||
{
|
||||
return nsContentUtils::IsCustomElementsEnabled() ||
|
||||
nsContentUtils::IsWebComponentsEnabled();
|
||||
return nsContentUtils::IsCustomElementsEnabled();
|
||||
}
|
||||
|
||||
explicit CustomElementRegistry(nsPIDOMWindowInner* aWindow);
|
||||
|
@ -211,7 +211,7 @@ load 1324500.html
|
||||
pref(dom.IntersectionObserver.enabled,true) load 1326194-1.html
|
||||
pref(dom.IntersectionObserver.enabled,true) load 1326194-2.html
|
||||
pref(dom.IntersectionObserver.enabled,true) load 1332939.html
|
||||
pref(dom.webcomponents.enabled,true) load 1341693.html
|
||||
pref(dom.webcomponents.customelements.enabled,true) load 1341693.html
|
||||
load 1352453.html
|
||||
pref(dom.IntersectionObserver.enabled,true) load 1353529.xul
|
||||
load 1368327.html
|
||||
|
@ -22,7 +22,6 @@ public:
|
||||
BufferMediaResource(const uint8_t* aBuffer, uint32_t aLength)
|
||||
: mBuffer(aBuffer)
|
||||
, mLength(aLength)
|
||||
, mOffset(0)
|
||||
{
|
||||
}
|
||||
|
||||
@ -41,14 +40,11 @@ private:
|
||||
}
|
||||
*aBytes = std::min(mLength - static_cast<uint32_t>(aOffset), aCount);
|
||||
memcpy(aBuffer, mBuffer + aOffset, *aBytes);
|
||||
mOffset = aOffset + *aBytes;
|
||||
return NS_OK;
|
||||
}
|
||||
// Memory-based and no locks, caching discouraged.
|
||||
bool ShouldCacheReads() override { return false; }
|
||||
|
||||
int64_t Tell() override { return mOffset; }
|
||||
|
||||
void Pin() override {}
|
||||
void Unpin() override {}
|
||||
int64_t GetLength() override { return mLength; }
|
||||
@ -80,7 +76,6 @@ private:
|
||||
private:
|
||||
const uint8_t * mBuffer;
|
||||
uint32_t mLength;
|
||||
uint32_t mOffset;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -675,11 +675,6 @@ ChannelMediaResource::ThrottleReadahead(bool bThrottle)
|
||||
mCacheStream.ThrottleReadahead(bThrottle);
|
||||
}
|
||||
|
||||
int64_t ChannelMediaResource::Tell()
|
||||
{
|
||||
return mCacheStream.Tell();
|
||||
}
|
||||
|
||||
nsresult ChannelMediaResource::GetCachedRanges(MediaByteRangeSet& aRanges)
|
||||
{
|
||||
return mCacheStream.GetCachedRanges(aRanges);
|
||||
|
@ -124,7 +124,6 @@ public:
|
||||
uint32_t aCount, uint32_t* aBytes) override;
|
||||
// Data stored in IO&lock-encumbered MediaCacheStream, caching recommended.
|
||||
bool ShouldCacheReads() override { return true; }
|
||||
int64_t Tell() override;
|
||||
|
||||
// Any thread
|
||||
void Pin() override;
|
||||
|
@ -202,7 +202,6 @@ CloneableWithRangeMediaResource::ReadFromCache(char* aBuffer, int64_t aOffset,
|
||||
return rv;
|
||||
}
|
||||
|
||||
mCurrentPosition = bytes + aOffset;
|
||||
return bytes == aCount ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@ -223,14 +222,7 @@ CloneableWithRangeMediaResource::ReadAt(int64_t aOffset, char* aBuffer,
|
||||
return rv;
|
||||
}
|
||||
|
||||
mCurrentPosition = *aBytes + aOffset;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
int64_t CloneableWithRangeMediaResource::Tell()
|
||||
{
|
||||
MaybeInitialize();
|
||||
return mCurrentPosition;
|
||||
}
|
||||
|
||||
} // mozilla namespace
|
||||
|
@ -22,7 +22,6 @@ public:
|
||||
: BaseMediaResource(aCallback, aChannel, aURI)
|
||||
, mStream(do_QueryInterface(aStream))
|
||||
, mSize(aSize)
|
||||
, mCurrentPosition(0)
|
||||
, mInitialized(false)
|
||||
{
|
||||
MOZ_ASSERT(mStream);
|
||||
@ -49,7 +48,6 @@ public:
|
||||
uint32_t aCount, uint32_t* aBytes) override;
|
||||
// (Probably) file-based, caching recommended.
|
||||
bool ShouldCacheReads() override { return true; }
|
||||
int64_t Tell() override;
|
||||
|
||||
// Any thread
|
||||
void Pin() override {}
|
||||
@ -105,9 +103,6 @@ private:
|
||||
// The stream size.
|
||||
uint64_t mSize;
|
||||
|
||||
// The current position.
|
||||
uint64_t mCurrentPosition;
|
||||
|
||||
bool mInitialized;
|
||||
};
|
||||
|
||||
|
@ -212,17 +212,4 @@ FileMediaResource::UnsafeSeek(int32_t aWhence, int64_t aOffset)
|
||||
return mSeekable->Seek(aWhence, aOffset);
|
||||
}
|
||||
|
||||
int64_t
|
||||
FileMediaResource::Tell()
|
||||
{
|
||||
MutexAutoLock lock(mLock);
|
||||
EnsureSizeInitialized();
|
||||
|
||||
int64_t offset = 0;
|
||||
// Return mSize as offset (end of stream) in case of error
|
||||
if (!mSeekable || NS_FAILED(mSeekable->Tell(&offset)))
|
||||
return mSize;
|
||||
return offset;
|
||||
}
|
||||
|
||||
} // mozilla namespace
|
||||
|
@ -45,7 +45,6 @@ public:
|
||||
uint32_t aCount, uint32_t* aBytes) override;
|
||||
// (Probably) file-based, caching recommended.
|
||||
bool ShouldCacheReads() override { return true; }
|
||||
int64_t Tell() override;
|
||||
|
||||
// Any thread
|
||||
void Pin() override {}
|
||||
|
@ -2510,13 +2510,6 @@ MediaCacheStream::ReadBlockFromCache(int64_t aOffset,
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
int64_t
|
||||
MediaCacheStream::Tell()
|
||||
{
|
||||
ReentrantMonitorAutoEnter mon(mMediaCache->GetReentrantMonitor());
|
||||
return mStreamOffset;
|
||||
}
|
||||
|
||||
nsresult
|
||||
MediaCacheStream::Read(char* aBuffer, uint32_t aCount, uint32_t* aBytes)
|
||||
{
|
||||
|
@ -333,7 +333,6 @@ public:
|
||||
// These methods must be called on a different thread from the main
|
||||
// thread. They should always be called on the same thread for a given
|
||||
// stream.
|
||||
int64_t Tell();
|
||||
// *aBytes gets the number of bytes that were actually read. This can
|
||||
// be less than aCount. If the first byte of data is not in the cache,
|
||||
// this will block until the data is available or the stream is
|
||||
|
@ -152,17 +152,6 @@ static Atomic<bool> sInShutdown;
|
||||
|
||||
typedef media::Pledge<bool, dom::MediaStreamError*> PledgeVoid;
|
||||
|
||||
static bool
|
||||
HostIsHttps(nsIURI &docURI)
|
||||
{
|
||||
bool isHttps;
|
||||
nsresult rv = docURI.SchemeIs("https", &isHttps);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return false;
|
||||
}
|
||||
return isHttps;
|
||||
}
|
||||
|
||||
class SourceListener : public MediaStreamListener {
|
||||
public:
|
||||
SourceListener();
|
||||
@ -2346,7 +2335,7 @@ MediaManager::GetUserMedia(nsPIDOMWindowInner* aWindow,
|
||||
"media.getusermedia.browser.enabled" :
|
||||
"media.getusermedia.screensharing.enabled"),
|
||||
false) ||
|
||||
(!privileged && !HostIsHttps(*docURI))) {
|
||||
(!privileged && !aWindow->IsSecureContext())) {
|
||||
RefPtr<MediaStreamError> error =
|
||||
new MediaStreamError(aWindow,
|
||||
NS_LITERAL_STRING("NotAllowedError"));
|
||||
|
@ -69,12 +69,6 @@ public:
|
||||
// each read.
|
||||
virtual bool ShouldCacheReads() = 0;
|
||||
|
||||
// Report the current offset in bytes from the start of the stream.
|
||||
// This is used to approximate where we currently are in the playback of a
|
||||
// media.
|
||||
// A call to ReadAt will update this position.
|
||||
virtual int64_t Tell() = 0;
|
||||
|
||||
// These can be called on any thread.
|
||||
// Cached blocks associated with this stream will not be evicted
|
||||
// while the stream is pinned.
|
||||
|
@ -20,7 +20,6 @@ public:
|
||||
uint32_t* aBytes) override;
|
||||
// Data stored in file, caching recommended.
|
||||
bool ShouldCacheReads() override { return true; }
|
||||
int64_t Tell() override { return 0; }
|
||||
void Pin() override {}
|
||||
void Unpin() override {}
|
||||
int64_t GetLength() override;
|
||||
|
@ -67,10 +67,6 @@ SourceBufferResource::ReadAtInternal(int64_t aOffset,
|
||||
uint32_t available = GetLength() - aOffset;
|
||||
uint32_t count = std::min(aCount, available);
|
||||
|
||||
// Keep the position of the last read to have Tell() approximately give us
|
||||
// the position we're up to in the stream.
|
||||
mOffset = aOffset + count;
|
||||
|
||||
SBR_DEBUGV("offset=%" PRId64 " GetLength()=%" PRId64
|
||||
" available=%u count=%u mEnded=%d",
|
||||
aOffset,
|
||||
@ -160,12 +156,7 @@ SourceBufferResource::~SourceBufferResource()
|
||||
SourceBufferResource::SourceBufferResource()
|
||||
#if defined(DEBUG)
|
||||
: mTaskQueue(AbstractThread::GetCurrent()->AsTaskQueue())
|
||||
, mOffset(0)
|
||||
#else
|
||||
: mOffset(0)
|
||||
#endif
|
||||
, mClosed(false)
|
||||
, mEnded(false)
|
||||
{
|
||||
SBR_DEBUG("");
|
||||
}
|
||||
|
@ -37,7 +37,6 @@ public:
|
||||
uint32_t* aBytes) override;
|
||||
// Memory-based and no locks, caching discouraged.
|
||||
bool ShouldCacheReads() override { return false; }
|
||||
int64_t Tell() override { return mOffset; }
|
||||
void Pin() override { UNIMPLEMENTED(); }
|
||||
void Unpin() override { UNIMPLEMENTED(); }
|
||||
int64_t GetLength() override { return mInputBuffer.GetLength(); }
|
||||
@ -139,9 +138,8 @@ private:
|
||||
// The buffer holding resource data.
|
||||
ResourceQueue mInputBuffer;
|
||||
|
||||
uint64_t mOffset;
|
||||
bool mClosed;
|
||||
bool mEnded;
|
||||
bool mClosed = false;
|
||||
bool mEnded = false;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -39,6 +39,31 @@ mozilla::LazyLogModule gCamerasParentLog("CamerasParent");
|
||||
namespace mozilla {
|
||||
namespace camera {
|
||||
|
||||
std::map<uint32_t, const char *> sDeviceUniqueIDs;
|
||||
std::map<uint32_t, webrtc::VideoCaptureCapability> sAllRequestedCapabilities;
|
||||
|
||||
uint32_t
|
||||
ResolutionFeasibilityDistance(int32_t candidate, int32_t requested)
|
||||
{
|
||||
// The purpose of this function is to find a smallest resolution
|
||||
// which is larger than all requested capabilities.
|
||||
// Then we can use down-scaling to fulfill each request.
|
||||
uint32_t distance;
|
||||
if (candidate >= requested) {
|
||||
distance = (candidate - requested) * 1000 / std::max(candidate, requested);
|
||||
} else {
|
||||
distance = (UINT32_MAX / 2) + (requested - candidate) *
|
||||
1000 / std::max(candidate, requested);
|
||||
}
|
||||
return distance;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
FeasibilityDistance(int32_t candidate, int32_t requested)
|
||||
{
|
||||
return std::abs(candidate - requested) * 1000 / std::max(candidate, requested);
|
||||
}
|
||||
|
||||
RefPtr<VideoEngine> CamerasParent::sEngines[CaptureEngine::MaxEngine];
|
||||
int32_t CamerasParent::sNumOfOpenCamerasParentEngines = 0;
|
||||
int32_t CamerasParent::sNumOfCamerasParents = 0;
|
||||
@ -556,6 +581,17 @@ CamerasParent::RecvGetCaptureCapability(const CaptureEngine& aCapEngine,
|
||||
if (auto devInfo = engine->GetOrCreateVideoCaptureDeviceInfo()){
|
||||
error = devInfo->GetCapability(unique_id.get(), num, webrtcCaps);
|
||||
}
|
||||
|
||||
if (!error && aCapEngine == CameraEngine) {
|
||||
auto iter = self->mAllCandidateCapabilities.find(unique_id);
|
||||
if (iter == self->mAllCandidateCapabilities.end()) {
|
||||
std::map<uint32_t, webrtc::VideoCaptureCapability> candidateCapabilities;
|
||||
candidateCapabilities.emplace(num, webrtcCaps);
|
||||
self->mAllCandidateCapabilities.emplace(nsCString(unique_id), candidateCapabilities);
|
||||
} else {
|
||||
(iter->second).emplace(num, webrtcCaps);
|
||||
}
|
||||
}
|
||||
}
|
||||
RefPtr<nsIRunnable> ipc_runnable =
|
||||
media::NewRunnableFrom([self, webrtcCaps, error]() -> nsresult {
|
||||
@ -816,8 +852,9 @@ CamerasParent::RecvStartCapture(const CaptureEngine& aCapEngine,
|
||||
new CallbackHelper(static_cast<CaptureEngine>(aCapEngine), capnum, self));
|
||||
|
||||
engine = self->sEngines[aCapEngine];
|
||||
engine->WithEntry(capnum, [&error, &ipcCaps, &cbh](VideoEngine::CaptureEntry& cap) {
|
||||
error = 0;
|
||||
engine->WithEntry(capnum,
|
||||
[&capnum, &aCapEngine, &error, &ipcCaps, &cbh, self]
|
||||
(VideoEngine::CaptureEntry& cap) {
|
||||
webrtc::VideoCaptureCapability capability;
|
||||
capability.width = ipcCaps.width();
|
||||
capability.height = ipcCaps.height();
|
||||
@ -827,11 +864,59 @@ CamerasParent::RecvStartCapture(const CaptureEngine& aCapEngine,
|
||||
capability.codecType = static_cast<webrtc::VideoCodecType>(ipcCaps.codecType());
|
||||
capability.interlaced = ipcCaps.interlaced();
|
||||
|
||||
if (!error) {
|
||||
error = cap.VideoCapture()->StartCapture(capability);
|
||||
if (aCapEngine == CameraEngine) {
|
||||
#ifdef DEBUG
|
||||
auto deviceUniqueID = sDeviceUniqueIDs.find(capnum);
|
||||
MOZ_ASSERT(deviceUniqueID == sDeviceUniqueIDs.end());
|
||||
#endif
|
||||
sDeviceUniqueIDs.emplace(capnum, cap.VideoCapture()->CurrentDeviceName());
|
||||
sAllRequestedCapabilities.emplace(capnum, capability);
|
||||
|
||||
for (const auto &it : sDeviceUniqueIDs) {
|
||||
if (strcmp(it.second, cap.VideoCapture()->CurrentDeviceName()) == 0) {
|
||||
capability.width = std::max(
|
||||
capability.width, sAllRequestedCapabilities[it.first].width);
|
||||
capability.height = std::max(
|
||||
capability.height, sAllRequestedCapabilities[it.first].height);
|
||||
capability.maxFPS = std::max(
|
||||
capability.maxFPS, sAllRequestedCapabilities[it.first].maxFPS);
|
||||
}
|
||||
}
|
||||
|
||||
auto candidateCapabilities = self->mAllCandidateCapabilities.find(
|
||||
nsCString(cap.VideoCapture()->CurrentDeviceName()));
|
||||
MOZ_ASSERT(candidateCapabilities != self->mAllCandidateCapabilities.end());
|
||||
MOZ_ASSERT(candidateCapabilities->second.size() > 0);
|
||||
int32_t minIdx = -1;
|
||||
uint64_t minDistance = UINT64_MAX;
|
||||
|
||||
for (auto & candidateCapability : candidateCapabilities->second) {
|
||||
if (candidateCapability.second.rawType != capability.rawType) {
|
||||
continue;
|
||||
}
|
||||
// The first priority is finding a suitable resolution.
|
||||
// So here we raise the weight of width and height
|
||||
uint64_t distance =
|
||||
uint64_t(ResolutionFeasibilityDistance(
|
||||
candidateCapability.second.width, capability.width)) +
|
||||
uint64_t(ResolutionFeasibilityDistance(
|
||||
candidateCapability.second.height, capability.height)) +
|
||||
uint64_t(FeasibilityDistance(
|
||||
candidateCapability.second.maxFPS, capability.maxFPS));
|
||||
if (distance < minDistance) {
|
||||
minIdx = candidateCapability.first;;
|
||||
minDistance = distance;
|
||||
}
|
||||
}
|
||||
MOZ_ASSERT(minIdx != -1);
|
||||
capability = candidateCapabilities->second[minIdx];
|
||||
}
|
||||
|
||||
error = cap.VideoCapture()->StartCapture(capability);
|
||||
|
||||
if (!error) {
|
||||
cap.VideoCapture()->RegisterCaptureDataCallback(static_cast<rtc::VideoSinkInterface<webrtc::VideoFrame>*>(*cbh));
|
||||
cap.VideoCapture()->RegisterCaptureDataCallback(
|
||||
static_cast<rtc::VideoSinkInterface<webrtc::VideoFrame>*>(*cbh));
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -866,11 +951,16 @@ CamerasParent::StopCapture(const CaptureEngine& aCapEngine,
|
||||
mCallbacks[i - 1]->mStreamId == (uint32_t)capnum) {
|
||||
|
||||
CallbackHelper* cbh = mCallbacks[i-1];
|
||||
engine->WithEntry(capnum,[cbh](VideoEngine::CaptureEntry& cap) {
|
||||
engine->WithEntry(capnum,[cbh, &capnum, &aCapEngine](VideoEngine::CaptureEntry& cap){
|
||||
if (cap.VideoCapture()) {
|
||||
cap.VideoCapture()->DeRegisterCaptureDataCallback(
|
||||
static_cast<rtc::VideoSinkInterface<webrtc::VideoFrame>*>(cbh));
|
||||
cap.VideoCapture()->StopCaptureIfAllClientsClose();
|
||||
|
||||
if (aCapEngine == CameraEngine) {
|
||||
sDeviceUniqueIDs.erase(capnum);
|
||||
sAllRequestedCapabilities.erase(capnum);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -164,6 +164,8 @@ protected:
|
||||
// read cross-thread.
|
||||
mozilla::Atomic<bool> mWebRTCAlive;
|
||||
RefPtr<InputObserver> mCameraObserver;
|
||||
std::map<nsCString, std::map<uint32_t, webrtc::VideoCaptureCapability>>
|
||||
mAllCandidateCapabilities;
|
||||
};
|
||||
|
||||
PCamerasParent* CreateCamerasParent();
|
||||
|
@ -1,6 +1,8 @@
|
||||
WEBVTT
|
||||
Region: id=testOne lines=2 width=30%
|
||||
Region: id=testTwo lines=4 width=20%
|
||||
REGION
|
||||
id=testOne lines=2 width=30%
|
||||
REGION
|
||||
id=testTwo lines=4 width=20%
|
||||
|
||||
1
|
||||
00:00.500 --> 00:00.700 region:testOne
|
||||
|
@ -1,5 +1,6 @@
|
||||
WEBVTT
|
||||
Region: id=fred width=62% lines=5 regionanchor=4%,78% viewportanchor=10%,90% scroll=up
|
||||
REGION
|
||||
id=fred width=62% lines=5 regionanchor=4%,78% viewportanchor=10%,90% scroll=up
|
||||
|
||||
00:01.000 --> 00:02.000 region:fred
|
||||
Test here.
|
||||
|
@ -80,6 +80,7 @@ struct ParamTraits<mozilla::dom::RTCStatsReportInternal>
|
||||
WriteParam(aMsg, aParam.mIceRollbacks);
|
||||
WriteParam(aMsg, aParam.mTransportStats);
|
||||
WriteParam(aMsg, aParam.mRtpContributingSourceStats);
|
||||
WriteParam(aMsg, aParam.mOfferer);
|
||||
}
|
||||
|
||||
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
|
||||
@ -100,7 +101,8 @@ struct ParamTraits<mozilla::dom::RTCStatsReportInternal>
|
||||
!ReadParam(aMsg, aIter, &(aResult->mIceRestarts)) ||
|
||||
!ReadParam(aMsg, aIter, &(aResult->mIceRollbacks)) ||
|
||||
!ReadParam(aMsg, aIter, &(aResult->mTransportStats)) ||
|
||||
!ReadParam(aMsg, aIter, &(aResult->mRtpContributingSourceStats))) {
|
||||
!ReadParam(aMsg, aIter, &(aResult->mRtpContributingSourceStats)) ||
|
||||
!ReadParam(aMsg, aIter, &(aResult->mOfferer))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1200,7 +1200,6 @@ const { XPCOMUtils } = require("resource://gre/modules/XPCOMUtils.jsm");
|
||||
// 3.4 WebVTT region and WebVTT region settings syntax
|
||||
function parseRegion(input) {
|
||||
var settings = new Settings();
|
||||
|
||||
parseOptions(input, function (k, v) {
|
||||
switch (k) {
|
||||
case "id":
|
||||
@ -1275,6 +1274,16 @@ const { XPCOMUtils } = require("resource://gre/modules/XPCOMUtils.jsm");
|
||||
}
|
||||
}
|
||||
|
||||
function parseRegionOrStyle(input) {
|
||||
switch (self.substate) {
|
||||
case "REGION":
|
||||
parseRegion(input);
|
||||
break;
|
||||
case "STYLE":
|
||||
// TODO : not supported yet.
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Parsing the region and style information.
|
||||
// See spec, https://w3c.github.io/webvtt/#collect-a-webvtt-block
|
||||
//
|
||||
@ -1290,33 +1299,46 @@ const { XPCOMUtils } = require("resource://gre/modules/XPCOMUtils.jsm");
|
||||
let line = null;
|
||||
while (self.buffer && self.state === "HEADER") {
|
||||
line = collectNextLine();
|
||||
var tempStr = "";
|
||||
if (/^REGION|^STYLE/.test(line)) {
|
||||
self.substate = /^REGION/.test(line) ? "REGION" : "STYLE";
|
||||
|
||||
if (/^REGION|^STYLE/i.test(line)) {
|
||||
parseOptions(line, function (k, v) {
|
||||
switch (k.toUpperCase()) {
|
||||
case "REGION":
|
||||
parseRegion(v);
|
||||
break;
|
||||
case "STYLE":
|
||||
// TODO : not supported yet.
|
||||
while (true) {
|
||||
line = collectNextLine();
|
||||
if (!line || maybeIsTimeStampFormat(line) || onlyContainsWhiteSpaces(line) || containsTimeDirectionSymbol(line)) {
|
||||
// parse the tempStr and break the while loop.
|
||||
parseRegionOrStyle(tempStr);
|
||||
break;
|
||||
} else if (/^REGION|^STYLE/.test(line)) {
|
||||
// The line is another REGION/STYLE, parse tempStr then reset tempStr.
|
||||
// Don't break the while loop to parse the next REGION/STYLE.
|
||||
parseRegionOrStyle(tempStr);
|
||||
self.substate = /^REGION/.test(line) ? "REGION" : "STYLE";
|
||||
tempStr = "";
|
||||
} else {
|
||||
tempStr += line;;
|
||||
}
|
||||
}, ":");
|
||||
} else if (maybeIsTimeStampFormat(line)) {
|
||||
}
|
||||
}
|
||||
|
||||
if (maybeIsTimeStampFormat(line)) {
|
||||
self.state = "CUE";
|
||||
break;
|
||||
} else if (!line ||
|
||||
onlyContainsWhiteSpaces(line) ||
|
||||
containsTimeDirectionSymbol(line)) {
|
||||
// empty line, whitespaces or string contains "-->"
|
||||
} else if (containsTimeDirectionSymbol(line)) {
|
||||
// string contains "-->"
|
||||
break;
|
||||
} else if (!line || onlyContainsWhiteSpaces(line)) {
|
||||
// empty line, whitespaces
|
||||
continue;
|
||||
} else {
|
||||
//It is an ID.
|
||||
break;
|
||||
}
|
||||
}
|
||||
} // self.state === "HEADER"
|
||||
|
||||
// End parsing header part and doesn't see the timestamp.
|
||||
if (self.state === "HEADER") {
|
||||
self.state = "ID";
|
||||
line = null
|
||||
}
|
||||
return line;
|
||||
}
|
||||
@ -1378,8 +1400,9 @@ const { XPCOMUtils } = require("resource://gre/modules/XPCOMUtils.jsm");
|
||||
break;
|
||||
case "BADCUE": // BADCUE
|
||||
// 54-62 - Collect and discard the remaining cue.
|
||||
if (!line) {
|
||||
self.state = "ID";
|
||||
self.state = "ID";
|
||||
if (line) { // keep this line to ID state.
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -49,7 +49,3 @@ LOCAL_INCLUDES += [
|
||||
'/netwerk/base',
|
||||
'/netwerk/protocol/data', # for nsDataHandler.h
|
||||
]
|
||||
|
||||
if CONFIG['GNU_CC']:
|
||||
CFLAGS += ['-Wformat-security']
|
||||
CXXFLAGS += ['-Wformat-security']
|
||||
|
@ -47,7 +47,7 @@ test();
|
||||
// test with webcomponents disabled
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{ 'set': [["dom.webcomponents.enabled", false]]}, runTest);
|
||||
{ 'set': [["dom.webcomponents.customelements.enabled", false]]}, runTest);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
|
@ -185,6 +185,7 @@ dictionary RTCStatsReportInternal {
|
||||
DOMHighResTimeStamp timestamp;
|
||||
unsigned long iceRestarts;
|
||||
unsigned long iceRollbacks;
|
||||
boolean offerer; // Is the PC the offerer
|
||||
boolean closed; // Is the PC now closed
|
||||
};
|
||||
|
||||
|
@ -289,7 +289,7 @@ AsyncImagePipelineManager::ApplyAsyncImages()
|
||||
|
||||
float opacity = 1.0f;
|
||||
builder.PushStackingContext(wr::ToLayoutRect(pipeline->mScBounds),
|
||||
0,
|
||||
nullptr,
|
||||
&opacity,
|
||||
pipeline->mScTransform.IsIdentity() ? nullptr : &pipeline->mScTransform,
|
||||
wr::TransformStyle::Flat,
|
||||
|
@ -23,7 +23,7 @@ StackingContextHelper::StackingContextHelper(const StackingContextHelper& aParen
|
||||
wr::DisplayListBuilder& aBuilder,
|
||||
const nsTArray<wr::WrFilterOp>& aFilters,
|
||||
const gfx::Matrix4x4* aBoundTransform,
|
||||
uint64_t aAnimationsId,
|
||||
const wr::WrAnimationProperty* aAnimation,
|
||||
float* aOpacityPtr,
|
||||
gfx::Matrix4x4* aTransformPtr,
|
||||
gfx::Matrix4x4* aPerspectivePtr,
|
||||
@ -44,7 +44,7 @@ StackingContextHelper::StackingContextHelper(const StackingContextHelper& aParen
|
||||
}
|
||||
|
||||
mBuilder->PushStackingContext(wr::LayoutRect(),
|
||||
aAnimationsId,
|
||||
aAnimation,
|
||||
aOpacityPtr,
|
||||
aTransformPtr,
|
||||
aIsPreserve3D ? wr::TransformStyle::Preserve3D : wr::TransformStyle::Flat,
|
||||
|
@ -31,7 +31,7 @@ public:
|
||||
wr::DisplayListBuilder& aBuilder,
|
||||
const nsTArray<wr::WrFilterOp>& aFilters = nsTArray<wr::WrFilterOp>(),
|
||||
const gfx::Matrix4x4* aBoundTransform = nullptr,
|
||||
uint64_t aAnimationsId = 0,
|
||||
const wr::WrAnimationProperty* aAnimation = nullptr,
|
||||
float* aOpacityPtr = nullptr,
|
||||
gfx::Matrix4x4* aTransformPtr = nullptr,
|
||||
gfx::Matrix4x4* aPerspectivePtr = nullptr,
|
||||
|
44
gfx/src/CompositorHitTestInfo.h
Normal file
44
gfx/src/CompositorHitTestInfo.h
Normal file
@ -0,0 +1,44 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef MOZILLA_GFX_COMPOSITORHITTESTINFO_H_
|
||||
#define MOZILLA_GFX_COMPOSITORHITTESTINFO_H_
|
||||
|
||||
#include "mozilla/TypedEnumBits.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
// This set of flags is used to figure out what information a frame has
|
||||
// that is relevant to hit-testing in the compositor. The flags are
|
||||
// intentionally set up so that if all of them are 0 the item is effectively
|
||||
// invisible to hit-testing, and no information for this frame needs to be
|
||||
// sent to the compositor.
|
||||
enum class CompositorHitTestInfo : uint8_t {
|
||||
// Shortcut for checking that none of the flags are set
|
||||
eInvisibleToHitTest = 0,
|
||||
|
||||
// The frame participates in hit-testing
|
||||
eVisibleToHitTest = 1 << 0,
|
||||
// The frame requires main-thread handling for events
|
||||
eDispatchToContent = 1 << 1,
|
||||
|
||||
// The touch action flags are set up so that the default of
|
||||
// touch-action:auto on an element leaves all the flags as 0.
|
||||
eTouchActionPanXDisabled = 1 << 2,
|
||||
eTouchActionPanYDisabled = 1 << 3,
|
||||
eTouchActionPinchZoomDisabled = 1 << 4,
|
||||
eTouchActionDoubleTapZoomDisabled = 1 << 5,
|
||||
// Mask to check for all the touch-action flags at once
|
||||
eTouchActionMask = (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5),
|
||||
};
|
||||
|
||||
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(CompositorHitTestInfo)
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
|
||||
#endif /* MOZILLA_GFX_COMPOSITORHITTESTINFO_H_ */
|
@ -47,6 +47,7 @@ EXPORTS.mozilla += [
|
||||
]
|
||||
|
||||
EXPORTS.mozilla.gfx += [
|
||||
'CompositorHitTestInfo.h',
|
||||
'TiledRegion.h',
|
||||
]
|
||||
|
||||
|
@ -491,6 +491,7 @@ private:
|
||||
|
||||
DECL_GFX_PREF(Live, "gfx.webrender.blob-images", WebRenderBlobImages, bool, false);
|
||||
DECL_GFX_PREF(Live, "gfx.webrender.highlight-painted-layers",WebRenderHighlightPaintedLayers, bool, false);
|
||||
DECL_GFX_PREF(Live, "gfx.webrender.hit-test", WebRenderHitTest, bool, false);
|
||||
|
||||
// Use vsync events generated by hardware
|
||||
DECL_GFX_PREF(Once, "gfx.work-around-driver-bugs", WorkAroundDriverBugs, bool, true);
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include "mozilla/gfx/gfxVars.h"
|
||||
#include "mozilla/layers/CompositorThread.h"
|
||||
#include "mozilla/widget/CompositorWidget.h"
|
||||
#include "mozilla/widget/CompositorWidget.h"
|
||||
#include "mozilla/layers/SynchronousTask.h"
|
||||
|
||||
#define WRDL_LOG(...)
|
||||
@ -222,6 +221,18 @@ WebRenderAPI::UpdateScrollPosition(const wr::WrPipelineId& aPipelineId,
|
||||
wr_scroll_layer_with_id(mDocHandle, aPipelineId, aScrollId, aScrollPosition);
|
||||
}
|
||||
|
||||
bool
|
||||
WebRenderAPI::HitTest(const wr::WorldPoint& aPoint,
|
||||
wr::WrPipelineId& aOutPipelineId,
|
||||
layers::FrameMetrics::ViewID& aOutScrollId,
|
||||
gfx::CompositorHitTestInfo& aOutHitInfo)
|
||||
{
|
||||
static_assert(sizeof(gfx::CompositorHitTestInfo) == sizeof(uint8_t),
|
||||
"CompositorHitTestInfo should be u8-sized");
|
||||
return wr_api_hit_test(mDocHandle, aPoint,
|
||||
&aOutPipelineId, &aOutScrollId, (uint8_t*)&aOutHitInfo);
|
||||
}
|
||||
|
||||
void
|
||||
WebRenderAPI::GenerateFrame()
|
||||
{
|
||||
@ -686,7 +697,7 @@ DisplayListBuilder::Finalize(wr::LayoutSize& aOutContentSize,
|
||||
|
||||
void
|
||||
DisplayListBuilder::PushStackingContext(const wr::LayoutRect& aBounds,
|
||||
const uint64_t& aAnimationId,
|
||||
const WrAnimationProperty* aAnimation,
|
||||
const float* aOpacity,
|
||||
const gfx::Matrix4x4* aTransform,
|
||||
wr::TransformStyle aTransformStyle,
|
||||
@ -707,7 +718,7 @@ DisplayListBuilder::PushStackingContext(const wr::LayoutRect& aBounds,
|
||||
const wr::LayoutTransform* maybePerspective = aPerspective ? &perspective : nullptr;
|
||||
WRDL_LOG("PushStackingContext b=%s t=%s\n", mWrState, Stringify(aBounds).c_str(),
|
||||
aTransform ? Stringify(*aTransform).c_str() : "none");
|
||||
wr_dp_push_stacking_context(mWrState, aBounds, aAnimationId, aOpacity,
|
||||
wr_dp_push_stacking_context(mWrState, aBounds, aAnimation, aOpacity,
|
||||
maybeTransform, aTransformStyle, maybePerspective,
|
||||
aMixBlendMode, aFilters.Elements(), aFilters.Length(), aIsBackfaceVisible);
|
||||
}
|
||||
@ -1248,5 +1259,20 @@ DisplayListBuilder::TopmostIsClip()
|
||||
return mClipStack.back().is<wr::WrClipId>();
|
||||
}
|
||||
|
||||
void
|
||||
DisplayListBuilder::SetHitTestInfo(const layers::FrameMetrics::ViewID& aScrollId,
|
||||
gfx::CompositorHitTestInfo aHitInfo)
|
||||
{
|
||||
static_assert(sizeof(gfx::CompositorHitTestInfo) == sizeof(uint8_t),
|
||||
"CompositorHitTestInfo should be u8-sized");
|
||||
wr_set_item_tag(mWrState, aScrollId, static_cast<uint8_t>(aHitInfo));
|
||||
}
|
||||
|
||||
void
|
||||
DisplayListBuilder::ClearHitTestInfo()
|
||||
{
|
||||
wr_clear_item_tag(mWrState);
|
||||
}
|
||||
|
||||
} // namespace wr
|
||||
} // namespace mozilla
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <unordered_set>
|
||||
|
||||
#include "mozilla/AlreadyAddRefed.h"
|
||||
#include "mozilla/gfx/CompositorHitTestInfo.h"
|
||||
#include "mozilla/layers/SyncObject.h"
|
||||
#include "mozilla/Range.h"
|
||||
#include "mozilla/webrender/webrender_ffi.h"
|
||||
@ -143,6 +144,10 @@ public:
|
||||
void UpdateScrollPosition(const wr::WrPipelineId& aPipelineId,
|
||||
const layers::FrameMetrics::ViewID& aScrollId,
|
||||
const wr::LayoutPoint& aScrollPosition);
|
||||
bool HitTest(const wr::WorldPoint& aPoint,
|
||||
wr::WrPipelineId& aOutPipelineId,
|
||||
layers::FrameMetrics::ViewID& aOutScrollId,
|
||||
gfx::CompositorHitTestInfo& aOutHitInfo);
|
||||
|
||||
void GenerateFrame();
|
||||
void GenerateFrame(const nsTArray<wr::WrOpacityProperty>& aOpacityArray,
|
||||
@ -228,7 +233,7 @@ public:
|
||||
wr::BuiltDisplayList& aOutDisplayList);
|
||||
|
||||
void PushStackingContext(const wr::LayoutRect& aBounds, // TODO: We should work with strongly typed rects
|
||||
const uint64_t& aAnimationId,
|
||||
const wr::WrAnimationProperty* aAnimation,
|
||||
const float* aOpacity,
|
||||
const gfx::Matrix4x4* aTransform,
|
||||
wr::TransformStyle aTransformStyle,
|
||||
@ -421,6 +426,13 @@ public:
|
||||
// If the topmost item on the stack is a clip or a scroll layer
|
||||
bool TopmostIsClip();
|
||||
|
||||
// Set the hit-test info to be used for all display items until the next call
|
||||
// to SetHitTestInfo or ClearHitTestInfo.
|
||||
void SetHitTestInfo(const layers::FrameMetrics::ViewID& aScrollId,
|
||||
gfx::CompositorHitTestInfo aHitInfo);
|
||||
// Clears the hit-test info so that subsequent display items will not have it.
|
||||
void ClearHitTestInfo();
|
||||
|
||||
// Try to avoid using this when possible.
|
||||
wr::WrState* Raw() { return mWrState; }
|
||||
|
||||
|
@ -333,6 +333,18 @@ impl ExternalImageHandler for WrExternalImageHandler {
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(u32)]
|
||||
pub enum WrAnimationType {
|
||||
Transform = 0,
|
||||
Opacity = 1,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct WrAnimationProperty {
|
||||
effect_type: WrAnimationType,
|
||||
id: u64,
|
||||
}
|
||||
|
||||
#[repr(u32)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum WrFilterOpType {
|
||||
@ -1178,6 +1190,7 @@ impl WebRenderFrameBuilder {
|
||||
pub struct WrState {
|
||||
pipeline_id: WrPipelineId,
|
||||
frame_builder: WebRenderFrameBuilder,
|
||||
current_tag: Option<ItemTag>,
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@ -1191,6 +1204,7 @@ pub extern "C" fn wr_state_new(pipeline_id: WrPipelineId,
|
||||
frame_builder: WebRenderFrameBuilder::with_capacity(pipeline_id,
|
||||
content_size,
|
||||
capacity),
|
||||
current_tag: None,
|
||||
});
|
||||
|
||||
Box::into_raw(state)
|
||||
@ -1224,7 +1238,7 @@ pub extern "C" fn wr_dp_clear_save(state: &mut WrState) {
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wr_dp_push_stacking_context(state: &mut WrState,
|
||||
bounds: LayoutRect,
|
||||
animation_id: u64,
|
||||
animation: *const WrAnimationProperty,
|
||||
opacity: *const f32,
|
||||
transform: *const LayoutTransform,
|
||||
transform_style: TransformStyle,
|
||||
@ -1250,26 +1264,28 @@ pub extern "C" fn wr_dp_push_stacking_context(state: &mut WrState,
|
||||
}
|
||||
}).collect();
|
||||
|
||||
let opacity = unsafe { opacity.as_ref() };
|
||||
if let Some(opacity) = opacity {
|
||||
let opacity_ref = unsafe { opacity.as_ref() };
|
||||
if let Some(opacity) = opacity_ref {
|
||||
if *opacity < 1.0 {
|
||||
filters.push(FilterOp::Opacity(PropertyBinding::Value(*opacity)));
|
||||
}
|
||||
} else {
|
||||
if animation_id > 0 {
|
||||
filters.push(FilterOp::Opacity(PropertyBinding::Binding(PropertyBindingKey::new(animation_id))));
|
||||
}
|
||||
}
|
||||
|
||||
let transform = unsafe { transform.as_ref() };
|
||||
let transform_binding = match animation_id {
|
||||
0 => match transform {
|
||||
Some(transform) => Some(PropertyBinding::Value(transform.clone())),
|
||||
None => None,
|
||||
},
|
||||
_ => Some(PropertyBinding::Binding(PropertyBindingKey::new(animation_id))),
|
||||
let transform_ref = unsafe { transform.as_ref() };
|
||||
let mut transform_binding = match transform_ref {
|
||||
Some(transform) => Some(PropertyBinding::Value(transform.clone())),
|
||||
None => None,
|
||||
};
|
||||
|
||||
let anim = unsafe { animation.as_ref() };
|
||||
if let Some(anim) = anim {
|
||||
debug_assert!(anim.id > 0);
|
||||
match anim.effect_type {
|
||||
WrAnimationType::Opacity => filters.push(FilterOp::Opacity(PropertyBinding::Binding(PropertyBindingKey::new(anim.id)))),
|
||||
WrAnimationType::Transform => transform_binding = Some(PropertyBinding::Binding(PropertyBindingKey::new(anim.id))),
|
||||
}
|
||||
}
|
||||
|
||||
let perspective_ref = unsafe { perspective.as_ref() };
|
||||
let perspective = match perspective_ref {
|
||||
Some(perspective) => Some(perspective.clone()),
|
||||
@ -1278,6 +1294,7 @@ pub extern "C" fn wr_dp_push_stacking_context(state: &mut WrState,
|
||||
|
||||
let mut prim_info = LayoutPrimitiveInfo::new(bounds);
|
||||
prim_info.is_backface_visible = is_backface_visible;
|
||||
prim_info.tag = state.current_tag;
|
||||
|
||||
state.frame_builder
|
||||
.dl_builder
|
||||
@ -1468,6 +1485,7 @@ pub extern "C" fn wr_dp_push_iframe(state: &mut WrState,
|
||||
|
||||
let mut prim_info = LayoutPrimitiveInfo::new(rect);
|
||||
prim_info.is_backface_visible = is_backface_visible;
|
||||
prim_info.tag = state.current_tag;
|
||||
state.frame_builder.dl_builder.push_iframe(&prim_info, pipeline_id);
|
||||
}
|
||||
|
||||
@ -1481,6 +1499,7 @@ pub extern "C" fn wr_dp_push_rect(state: &mut WrState,
|
||||
|
||||
let mut prim_info = LayoutPrimitiveInfo::with_clip_rect(rect, clip.into());
|
||||
prim_info.is_backface_visible = is_backface_visible;
|
||||
prim_info.tag = state.current_tag;
|
||||
state.frame_builder.dl_builder.push_rect(&prim_info,
|
||||
color);
|
||||
}
|
||||
@ -1507,6 +1526,7 @@ pub extern "C" fn wr_dp_push_image(state: &mut WrState,
|
||||
|
||||
let mut prim_info = LayoutPrimitiveInfo::with_clip_rect(bounds, clip.into());
|
||||
prim_info.is_backface_visible = is_backface_visible;
|
||||
prim_info.tag = state.current_tag;
|
||||
state.frame_builder
|
||||
.dl_builder
|
||||
.push_image(&prim_info,
|
||||
@ -1531,6 +1551,7 @@ pub extern "C" fn wr_dp_push_yuv_planar_image(state: &mut WrState,
|
||||
|
||||
let mut prim_info = LayoutPrimitiveInfo::with_clip_rect(bounds, clip.into());
|
||||
prim_info.is_backface_visible = is_backface_visible;
|
||||
prim_info.tag = state.current_tag;
|
||||
state.frame_builder
|
||||
.dl_builder
|
||||
.push_yuv_image(&prim_info,
|
||||
@ -1553,6 +1574,7 @@ pub extern "C" fn wr_dp_push_yuv_NV12_image(state: &mut WrState,
|
||||
|
||||
let mut prim_info = LayoutPrimitiveInfo::with_clip_rect(bounds, clip.into());
|
||||
prim_info.is_backface_visible = is_backface_visible;
|
||||
prim_info.tag = state.current_tag;
|
||||
state.frame_builder
|
||||
.dl_builder
|
||||
.push_yuv_image(&prim_info,
|
||||
@ -1574,6 +1596,7 @@ pub extern "C" fn wr_dp_push_yuv_interleaved_image(state: &mut WrState,
|
||||
|
||||
let mut prim_info = LayoutPrimitiveInfo::with_clip_rect(bounds, clip.into());
|
||||
prim_info.is_backface_visible = is_backface_visible;
|
||||
prim_info.tag = state.current_tag;
|
||||
state.frame_builder
|
||||
.dl_builder
|
||||
.push_yuv_image(&prim_info,
|
||||
@ -1598,6 +1621,7 @@ pub extern "C" fn wr_dp_push_text(state: &mut WrState,
|
||||
|
||||
let mut prim_info = LayoutPrimitiveInfo::with_clip_rect(bounds, clip.into());
|
||||
prim_info.is_backface_visible = is_backface_visible;
|
||||
prim_info.tag = state.current_tag;
|
||||
state.frame_builder
|
||||
.dl_builder
|
||||
.push_text(&prim_info,
|
||||
@ -1617,6 +1641,7 @@ pub extern "C" fn wr_dp_push_shadow(state: &mut WrState,
|
||||
|
||||
let mut prim_info = LayoutPrimitiveInfo::with_clip_rect(bounds, clip.into());
|
||||
prim_info.is_backface_visible = is_backface_visible;
|
||||
prim_info.tag = state.current_tag;
|
||||
state.frame_builder.dl_builder.push_shadow(&prim_info, shadow.into());
|
||||
}
|
||||
|
||||
@ -1640,6 +1665,7 @@ pub extern "C" fn wr_dp_push_line(state: &mut WrState,
|
||||
|
||||
let mut prim_info = LayoutPrimitiveInfo::with_clip_rect(*bounds, (*clip).into());
|
||||
prim_info.is_backface_visible = is_backface_visible;
|
||||
prim_info.tag = state.current_tag;
|
||||
state.frame_builder
|
||||
.dl_builder
|
||||
.push_line(&prim_info,
|
||||
@ -1672,6 +1698,7 @@ pub extern "C" fn wr_dp_push_border(state: &mut WrState,
|
||||
});
|
||||
let mut prim_info = LayoutPrimitiveInfo::with_clip_rect(rect, clip.into());
|
||||
prim_info.is_backface_visible = is_backface_visible;
|
||||
prim_info.tag = state.current_tag;
|
||||
state.frame_builder
|
||||
.dl_builder
|
||||
.push_border(&prim_info,
|
||||
@ -1702,6 +1729,7 @@ pub extern "C" fn wr_dp_push_border_image(state: &mut WrState,
|
||||
});
|
||||
let mut prim_info = LayoutPrimitiveInfo::with_clip_rect(rect, clip.into());
|
||||
prim_info.is_backface_visible = is_backface_visible;
|
||||
prim_info.tag = state.current_tag;
|
||||
state.frame_builder
|
||||
.dl_builder
|
||||
.push_border(&prim_info,
|
||||
@ -1738,6 +1766,7 @@ pub extern "C" fn wr_dp_push_border_gradient(state: &mut WrState,
|
||||
});
|
||||
let mut prim_info = LayoutPrimitiveInfo::with_clip_rect(rect, clip.into());
|
||||
prim_info.is_backface_visible = is_backface_visible;
|
||||
prim_info.tag = state.current_tag;
|
||||
state.frame_builder
|
||||
.dl_builder
|
||||
.push_border(&prim_info,
|
||||
@ -1775,6 +1804,7 @@ pub extern "C" fn wr_dp_push_border_radial_gradient(state: &mut WrState,
|
||||
});
|
||||
let mut prim_info = LayoutPrimitiveInfo::with_clip_rect(rect, clip.into());
|
||||
prim_info.is_backface_visible = is_backface_visible;
|
||||
prim_info.tag = state.current_tag;
|
||||
state.frame_builder
|
||||
.dl_builder
|
||||
.push_border(&prim_info,
|
||||
@ -1807,6 +1837,7 @@ pub extern "C" fn wr_dp_push_linear_gradient(state: &mut WrState,
|
||||
extend_mode.into());
|
||||
let mut prim_info = LayoutPrimitiveInfo::with_clip_rect(rect, clip.into());
|
||||
prim_info.is_backface_visible = is_backface_visible;
|
||||
prim_info.tag = state.current_tag;
|
||||
state.frame_builder
|
||||
.dl_builder
|
||||
.push_gradient(&prim_info,
|
||||
@ -1840,6 +1871,7 @@ pub extern "C" fn wr_dp_push_radial_gradient(state: &mut WrState,
|
||||
extend_mode.into());
|
||||
let mut prim_info = LayoutPrimitiveInfo::with_clip_rect(rect, clip.into());
|
||||
prim_info.is_backface_visible = is_backface_visible;
|
||||
prim_info.tag = state.current_tag;
|
||||
state.frame_builder
|
||||
.dl_builder
|
||||
.push_radial_gradient(&prim_info,
|
||||
@ -1864,6 +1896,7 @@ pub extern "C" fn wr_dp_push_box_shadow(state: &mut WrState,
|
||||
|
||||
let mut prim_info = LayoutPrimitiveInfo::with_clip_rect(rect, clip.into());
|
||||
prim_info.is_backface_visible = is_backface_visible;
|
||||
prim_info.tag = state.current_tag;
|
||||
state.frame_builder
|
||||
.dl_builder
|
||||
.push_box_shadow(&prim_info,
|
||||
@ -1891,6 +1924,38 @@ pub unsafe extern "C" fn wr_api_finalize_builder(state: &mut WrState,
|
||||
*dl_descriptor = descriptor;
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wr_set_item_tag(state: &mut WrState,
|
||||
scroll_id: u64,
|
||||
hit_info: u8) {
|
||||
state.current_tag = Some((scroll_id, hit_info));
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wr_clear_item_tag(state: &mut WrState) {
|
||||
state.current_tag = None;
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wr_api_hit_test(dh: &mut DocumentHandle,
|
||||
point: WorldPoint,
|
||||
out_pipeline_id: &mut WrPipelineId,
|
||||
out_scroll_id: &mut u64,
|
||||
out_hit_info: &mut u8) -> bool {
|
||||
let result = dh.api.hit_test(dh.document_id, None, point, HitTestFlags::empty());
|
||||
for item in &result.items {
|
||||
// For now we should never be getting results back for which the tag is
|
||||
// 0 (== CompositorHitTestInfo::eInvisibleToHitTest). In the future if
|
||||
// we allow this, we'll want to |continue| on the loop in this scenario.
|
||||
debug_assert!(item.tag.1 != 0);
|
||||
*out_pipeline_id = item.pipeline;
|
||||
*out_scroll_id = item.tag.0;
|
||||
*out_hit_info = item.tag.1;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
pub type VecU8 = Vec<u8>;
|
||||
pub type ArcVecU8 = Arc<VecU8>;
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
* 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/. */
|
||||
|
||||
/* Generated with cbindgen:0.1.29 */
|
||||
/* Generated with cbindgen:0.2.0 */
|
||||
|
||||
/* DO NOT MODIFY THIS MANUALLY! This file was generated using cbindgen.
|
||||
* To generate this file:
|
||||
@ -202,6 +202,13 @@ enum class TransformStyle : uint32_t {
|
||||
Sentinel /* this must be last for serialization purposes. */
|
||||
};
|
||||
|
||||
enum class WrAnimationType : uint32_t {
|
||||
Transform = 0,
|
||||
Opacity = 1,
|
||||
|
||||
Sentinel /* this must be last for serialization purposes. */
|
||||
};
|
||||
|
||||
enum class WrExternalImageType : uint32_t {
|
||||
NativeTexture = 0,
|
||||
RawData = 1,
|
||||
@ -431,6 +438,19 @@ struct WrTransformProperty {
|
||||
|
||||
typedef IdNamespace WrIdNamespace;
|
||||
|
||||
// A 2d Point tagged with a unit.
|
||||
struct TypedPoint2D_f32__WorldPixel {
|
||||
float x;
|
||||
float y;
|
||||
|
||||
bool operator==(const TypedPoint2D_f32__WorldPixel& aOther) const {
|
||||
return x == aOther.x &&
|
||||
y == aOther.y;
|
||||
}
|
||||
};
|
||||
|
||||
typedef TypedPoint2D_f32__WorldPixel WorldPoint;
|
||||
|
||||
// Represents RGBA screen colors with floating point numbers.
|
||||
//
|
||||
// All components must be between 0.0 and 1.0.
|
||||
@ -653,6 +673,16 @@ struct Shadow {
|
||||
}
|
||||
};
|
||||
|
||||
struct WrAnimationProperty {
|
||||
WrAnimationType effect_type;
|
||||
uint64_t id;
|
||||
|
||||
bool operator==(const WrAnimationProperty& aOther) const {
|
||||
return effect_type == aOther.effect_type &&
|
||||
id == aOther.id;
|
||||
}
|
||||
};
|
||||
|
||||
struct WrFilterOp {
|
||||
WrFilterOpType filter_type;
|
||||
float argument;
|
||||
@ -1005,6 +1035,14 @@ WR_INLINE
|
||||
WrIdNamespace wr_api_get_namespace(DocumentHandle *aDh)
|
||||
WR_FUNC;
|
||||
|
||||
WR_INLINE
|
||||
bool wr_api_hit_test(DocumentHandle *aDh,
|
||||
WorldPoint aPoint,
|
||||
WrPipelineId *aOutPipelineId,
|
||||
uint64_t *aOutScrollId,
|
||||
uint8_t *aOutHitInfo)
|
||||
WR_FUNC;
|
||||
|
||||
WR_INLINE
|
||||
void wr_api_remove_pipeline(DocumentHandle *aDh,
|
||||
WrPipelineId aPipelineId)
|
||||
@ -1052,6 +1090,10 @@ void wr_api_update_resources(DocumentHandle *aDh,
|
||||
ResourceUpdates *aResources)
|
||||
WR_FUNC;
|
||||
|
||||
WR_INLINE
|
||||
void wr_clear_item_tag(WrState *aState)
|
||||
WR_FUNC;
|
||||
|
||||
WR_INLINE
|
||||
void wr_dec_ref_arc(const VecU8 *aArc)
|
||||
WR_FUNC;
|
||||
@ -1276,7 +1318,7 @@ WR_FUNC;
|
||||
WR_INLINE
|
||||
void wr_dp_push_stacking_context(WrState *aState,
|
||||
LayoutRect aBounds,
|
||||
uint64_t aAnimationId,
|
||||
const WrAnimationProperty *aAnimation,
|
||||
const float *aOpacity,
|
||||
const LayoutTransform *aTransform,
|
||||
TransformStyle aTransformStyle,
|
||||
@ -1524,6 +1566,12 @@ void wr_scroll_layer_with_id(DocumentHandle *aDh,
|
||||
LayoutPoint aNewScrollOrigin)
|
||||
WR_FUNC;
|
||||
|
||||
WR_INLINE
|
||||
void wr_set_item_tag(WrState *aState,
|
||||
uint64_t aScrollId,
|
||||
uint8_t aHitInfo)
|
||||
WR_FUNC;
|
||||
|
||||
WR_INLINE
|
||||
void wr_shutdown_external_log_handler()
|
||||
WR_FUNC;
|
||||
|
@ -42,11 +42,11 @@ class AccessibleCaretEventHub::NoActionState
|
||||
: public AccessibleCaretEventHub::State
|
||||
{
|
||||
public:
|
||||
virtual const char* Name() const override { return "NoActionState"; }
|
||||
const char* Name() const override { return "NoActionState"; }
|
||||
|
||||
virtual nsEventStatus OnPress(AccessibleCaretEventHub* aContext,
|
||||
const nsPoint& aPoint, int32_t aTouchId,
|
||||
EventClassID aEventClass) override
|
||||
nsEventStatus OnPress(AccessibleCaretEventHub* aContext,
|
||||
const nsPoint& aPoint, int32_t aTouchId,
|
||||
EventClassID aEventClass) override
|
||||
{
|
||||
nsEventStatus rv = nsEventStatus_eIgnore;
|
||||
|
||||
@ -63,37 +63,36 @@ public:
|
||||
return rv;
|
||||
}
|
||||
|
||||
virtual void OnScrollStart(AccessibleCaretEventHub* aContext) override
|
||||
void OnScrollStart(AccessibleCaretEventHub* aContext) override
|
||||
{
|
||||
aContext->mManager->OnScrollStart();
|
||||
aContext->SetState(aContext->ScrollState());
|
||||
}
|
||||
|
||||
virtual void OnScrollPositionChanged(
|
||||
AccessibleCaretEventHub* aContext) override
|
||||
void OnScrollPositionChanged(AccessibleCaretEventHub* aContext) override
|
||||
{
|
||||
aContext->mManager->OnScrollPositionChanged();
|
||||
}
|
||||
|
||||
virtual void OnSelectionChanged(AccessibleCaretEventHub* aContext,
|
||||
nsIDOMDocument* aDoc, nsISelection* aSel,
|
||||
int16_t aReason) override
|
||||
void OnSelectionChanged(AccessibleCaretEventHub* aContext,
|
||||
nsIDOMDocument* aDoc, nsISelection* aSel,
|
||||
int16_t aReason) override
|
||||
{
|
||||
aContext->mManager->OnSelectionChanged(aDoc, aSel, aReason);
|
||||
}
|
||||
|
||||
virtual void OnBlur(AccessibleCaretEventHub* aContext,
|
||||
bool aIsLeavingDocument) override
|
||||
void OnBlur(AccessibleCaretEventHub* aContext,
|
||||
bool aIsLeavingDocument) override
|
||||
{
|
||||
aContext->mManager->OnBlur();
|
||||
}
|
||||
|
||||
virtual void OnReflow(AccessibleCaretEventHub* aContext) override
|
||||
void OnReflow(AccessibleCaretEventHub* aContext) override
|
||||
{
|
||||
aContext->mManager->OnReflow();
|
||||
}
|
||||
|
||||
virtual void Enter(AccessibleCaretEventHub* aContext) override
|
||||
void Enter(AccessibleCaretEventHub* aContext) override
|
||||
{
|
||||
aContext->mPressPoint = nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
|
||||
aContext->mActiveTouchId = kInvalidTouchId;
|
||||
@ -107,10 +106,10 @@ class AccessibleCaretEventHub::PressCaretState
|
||||
: public AccessibleCaretEventHub::State
|
||||
{
|
||||
public:
|
||||
virtual const char* Name() const override { return "PressCaretState"; }
|
||||
const char* Name() const override { return "PressCaretState"; }
|
||||
|
||||
virtual nsEventStatus OnMove(AccessibleCaretEventHub* aContext,
|
||||
const nsPoint& aPoint) override
|
||||
nsEventStatus OnMove(AccessibleCaretEventHub* aContext,
|
||||
const nsPoint& aPoint) override
|
||||
{
|
||||
if (aContext->MoveDistanceIsLarge(aPoint)) {
|
||||
if (NS_SUCCEEDED(aContext->mManager->DragCaret(aPoint))) {
|
||||
@ -121,7 +120,7 @@ public:
|
||||
return nsEventStatus_eConsumeNoDefault;
|
||||
}
|
||||
|
||||
virtual nsEventStatus OnRelease(AccessibleCaretEventHub* aContext) override
|
||||
nsEventStatus OnRelease(AccessibleCaretEventHub* aContext) override
|
||||
{
|
||||
aContext->mManager->ReleaseCaret();
|
||||
aContext->mManager->TapCaret(aContext->mPressPoint);
|
||||
@ -130,8 +129,8 @@ public:
|
||||
return nsEventStatus_eConsumeNoDefault;
|
||||
}
|
||||
|
||||
virtual nsEventStatus OnLongTap(AccessibleCaretEventHub* aContext,
|
||||
const nsPoint& aPoint) override
|
||||
nsEventStatus OnLongTap(AccessibleCaretEventHub* aContext,
|
||||
const nsPoint& aPoint) override
|
||||
{
|
||||
return nsEventStatus_eConsumeNoDefault;
|
||||
}
|
||||
@ -144,17 +143,17 @@ class AccessibleCaretEventHub::DragCaretState
|
||||
: public AccessibleCaretEventHub::State
|
||||
{
|
||||
public:
|
||||
virtual const char* Name() const override { return "DragCaretState"; }
|
||||
const char* Name() const override { return "DragCaretState"; }
|
||||
|
||||
virtual nsEventStatus OnMove(AccessibleCaretEventHub* aContext,
|
||||
const nsPoint& aPoint) override
|
||||
nsEventStatus OnMove(AccessibleCaretEventHub* aContext,
|
||||
const nsPoint& aPoint) override
|
||||
{
|
||||
aContext->mManager->DragCaret(aPoint);
|
||||
|
||||
return nsEventStatus_eConsumeNoDefault;
|
||||
}
|
||||
|
||||
virtual nsEventStatus OnRelease(AccessibleCaretEventHub* aContext) override
|
||||
nsEventStatus OnRelease(AccessibleCaretEventHub* aContext) override
|
||||
{
|
||||
aContext->mManager->ReleaseCaret();
|
||||
aContext->SetState(aContext->NoActionState());
|
||||
@ -170,10 +169,10 @@ class AccessibleCaretEventHub::PressNoCaretState
|
||||
: public AccessibleCaretEventHub::State
|
||||
{
|
||||
public:
|
||||
virtual const char* Name() const override { return "PressNoCaretState"; }
|
||||
const char* Name() const override { return "PressNoCaretState"; }
|
||||
|
||||
virtual nsEventStatus OnMove(AccessibleCaretEventHub* aContext,
|
||||
const nsPoint& aPoint) override
|
||||
nsEventStatus OnMove(AccessibleCaretEventHub* aContext,
|
||||
const nsPoint& aPoint) override
|
||||
{
|
||||
if (aContext->MoveDistanceIsLarge(aPoint)) {
|
||||
aContext->SetState(aContext->NoActionState());
|
||||
@ -182,29 +181,29 @@ public:
|
||||
return nsEventStatus_eIgnore;
|
||||
}
|
||||
|
||||
virtual nsEventStatus OnRelease(AccessibleCaretEventHub* aContext) override
|
||||
nsEventStatus OnRelease(AccessibleCaretEventHub* aContext) override
|
||||
{
|
||||
aContext->SetState(aContext->NoActionState());
|
||||
|
||||
return nsEventStatus_eIgnore;
|
||||
}
|
||||
|
||||
virtual nsEventStatus OnLongTap(AccessibleCaretEventHub* aContext,
|
||||
const nsPoint& aPoint) override
|
||||
nsEventStatus OnLongTap(AccessibleCaretEventHub* aContext,
|
||||
const nsPoint& aPoint) override
|
||||
{
|
||||
aContext->SetState(aContext->LongTapState());
|
||||
|
||||
return aContext->GetState()->OnLongTap(aContext, aPoint);
|
||||
}
|
||||
|
||||
virtual void OnScrollStart(AccessibleCaretEventHub* aContext) override
|
||||
void OnScrollStart(AccessibleCaretEventHub* aContext) override
|
||||
{
|
||||
aContext->mManager->OnScrollStart();
|
||||
aContext->SetState(aContext->ScrollState());
|
||||
}
|
||||
|
||||
virtual void OnBlur(AccessibleCaretEventHub* aContext,
|
||||
bool aIsLeavingDocument) override
|
||||
void OnBlur(AccessibleCaretEventHub* aContext,
|
||||
bool aIsLeavingDocument) override
|
||||
{
|
||||
aContext->mManager->OnBlur();
|
||||
if (aIsLeavingDocument) {
|
||||
@ -212,24 +211,24 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnSelectionChanged(AccessibleCaretEventHub* aContext,
|
||||
nsIDOMDocument* aDoc, nsISelection* aSel,
|
||||
int16_t aReason) override
|
||||
void OnSelectionChanged(AccessibleCaretEventHub* aContext,
|
||||
nsIDOMDocument* aDoc, nsISelection* aSel,
|
||||
int16_t aReason) override
|
||||
{
|
||||
aContext->mManager->OnSelectionChanged(aDoc, aSel, aReason);
|
||||
}
|
||||
|
||||
virtual void OnReflow(AccessibleCaretEventHub* aContext) override
|
||||
void OnReflow(AccessibleCaretEventHub* aContext) override
|
||||
{
|
||||
aContext->mManager->OnReflow();
|
||||
}
|
||||
|
||||
virtual void Enter(AccessibleCaretEventHub* aContext) override
|
||||
void Enter(AccessibleCaretEventHub* aContext) override
|
||||
{
|
||||
aContext->LaunchLongTapInjector();
|
||||
}
|
||||
|
||||
virtual void Leave(AccessibleCaretEventHub* aContext) override
|
||||
void Leave(AccessibleCaretEventHub* aContext) override
|
||||
{
|
||||
aContext->CancelLongTapInjector();
|
||||
}
|
||||
@ -242,21 +241,20 @@ class AccessibleCaretEventHub::ScrollState
|
||||
: public AccessibleCaretEventHub::State
|
||||
{
|
||||
public:
|
||||
virtual const char* Name() const override { return "ScrollState"; }
|
||||
const char* Name() const override { return "ScrollState"; }
|
||||
|
||||
virtual void OnScrollEnd(AccessibleCaretEventHub* aContext) override
|
||||
void OnScrollEnd(AccessibleCaretEventHub* aContext) override
|
||||
{
|
||||
aContext->SetState(aContext->PostScrollState());
|
||||
}
|
||||
|
||||
virtual void OnScrollPositionChanged(
|
||||
AccessibleCaretEventHub* aContext) override
|
||||
void OnScrollPositionChanged(AccessibleCaretEventHub* aContext) override
|
||||
{
|
||||
aContext->mManager->OnScrollPositionChanged();
|
||||
}
|
||||
|
||||
virtual void OnBlur(AccessibleCaretEventHub* aContext,
|
||||
bool aIsLeavingDocument) override
|
||||
void OnBlur(AccessibleCaretEventHub* aContext,
|
||||
bool aIsLeavingDocument) override
|
||||
{
|
||||
aContext->mManager->OnBlur();
|
||||
if (aIsLeavingDocument) {
|
||||
@ -273,11 +271,11 @@ class AccessibleCaretEventHub::PostScrollState
|
||||
: public AccessibleCaretEventHub::State
|
||||
{
|
||||
public:
|
||||
virtual const char* Name() const override { return "PostScrollState"; }
|
||||
const char* Name() const override { return "PostScrollState"; }
|
||||
|
||||
virtual nsEventStatus OnPress(AccessibleCaretEventHub* aContext,
|
||||
const nsPoint& aPoint, int32_t aTouchId,
|
||||
EventClassID aEventClass) override
|
||||
nsEventStatus OnPress(AccessibleCaretEventHub* aContext,
|
||||
const nsPoint& aPoint, int32_t aTouchId,
|
||||
EventClassID aEventClass) override
|
||||
{
|
||||
aContext->mManager->OnScrollEnd();
|
||||
aContext->SetState(aContext->NoActionState());
|
||||
@ -286,19 +284,19 @@ public:
|
||||
aEventClass);
|
||||
}
|
||||
|
||||
virtual void OnScrollStart(AccessibleCaretEventHub* aContext) override
|
||||
void OnScrollStart(AccessibleCaretEventHub* aContext) override
|
||||
{
|
||||
aContext->SetState(aContext->ScrollState());
|
||||
}
|
||||
|
||||
virtual void OnScrollEnd(AccessibleCaretEventHub* aContext) override
|
||||
void OnScrollEnd(AccessibleCaretEventHub* aContext) override
|
||||
{
|
||||
aContext->mManager->OnScrollEnd();
|
||||
aContext->SetState(aContext->NoActionState());
|
||||
}
|
||||
|
||||
virtual void OnBlur(AccessibleCaretEventHub* aContext,
|
||||
bool aIsLeavingDocument) override
|
||||
void OnBlur(AccessibleCaretEventHub* aContext,
|
||||
bool aIsLeavingDocument) override
|
||||
{
|
||||
aContext->mManager->OnBlur();
|
||||
if (aIsLeavingDocument) {
|
||||
@ -306,13 +304,13 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual void Enter(AccessibleCaretEventHub* aContext) override
|
||||
void Enter(AccessibleCaretEventHub* aContext) override
|
||||
{
|
||||
// Launch the injector to leave PostScrollState.
|
||||
aContext->LaunchScrollEndInjector();
|
||||
}
|
||||
|
||||
virtual void Leave(AccessibleCaretEventHub* aContext) override
|
||||
void Leave(AccessibleCaretEventHub* aContext) override
|
||||
{
|
||||
aContext->CancelScrollEndInjector();
|
||||
}
|
||||
@ -325,10 +323,10 @@ class AccessibleCaretEventHub::LongTapState
|
||||
: public AccessibleCaretEventHub::State
|
||||
{
|
||||
public:
|
||||
virtual const char* Name() const override { return "LongTapState"; }
|
||||
const char* Name() const override { return "LongTapState"; }
|
||||
|
||||
virtual nsEventStatus OnLongTap(AccessibleCaretEventHub* aContext,
|
||||
const nsPoint& aPoint) override
|
||||
nsEventStatus OnLongTap(AccessibleCaretEventHub* aContext,
|
||||
const nsPoint& aPoint) override
|
||||
{
|
||||
// In general text selection is lower-priority than the context menu. If
|
||||
// we consume this long-press event, then it prevents the context menu from
|
||||
@ -338,7 +336,7 @@ public:
|
||||
return nsEventStatus_eIgnore;
|
||||
}
|
||||
|
||||
virtual nsEventStatus OnRelease(AccessibleCaretEventHub* aContext) override
|
||||
nsEventStatus OnRelease(AccessibleCaretEventHub* aContext) override
|
||||
{
|
||||
aContext->SetState(aContext->NoActionState());
|
||||
|
||||
@ -347,13 +345,13 @@ public:
|
||||
return nsEventStatus_eIgnore;
|
||||
}
|
||||
|
||||
virtual void OnScrollStart(AccessibleCaretEventHub* aContext) override
|
||||
void OnScrollStart(AccessibleCaretEventHub* aContext) override
|
||||
{
|
||||
aContext->mManager->OnScrollStart();
|
||||
aContext->SetState(aContext->ScrollState());
|
||||
}
|
||||
|
||||
virtual void OnReflow(AccessibleCaretEventHub* aContext) override
|
||||
void OnReflow(AccessibleCaretEventHub* aContext) override
|
||||
{
|
||||
aContext->mManager->OnReflow();
|
||||
}
|
||||
@ -401,10 +399,6 @@ AccessibleCaretEventHub::AccessibleCaretEventHub(nsIPresShell* aPresShell)
|
||||
}
|
||||
}
|
||||
|
||||
AccessibleCaretEventHub::~AccessibleCaretEventHub()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
AccessibleCaretEventHub::Init()
|
||||
{
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/WeakPtr.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsDocShell.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsIReflowObserver.h"
|
||||
#include "nsIScrollObserver.h"
|
||||
@ -19,7 +20,6 @@
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "nsWeakReference.h"
|
||||
|
||||
class nsDocShell;
|
||||
class nsIPresShell;
|
||||
class nsITimer;
|
||||
|
||||
@ -89,7 +89,7 @@ public:
|
||||
State* GetState() const;
|
||||
|
||||
protected:
|
||||
virtual ~AccessibleCaretEventHub();
|
||||
virtual ~AccessibleCaretEventHub() = default;
|
||||
|
||||
#define MOZ_DECL_STATE_CLASS_GETTER(aClassName) \
|
||||
class aClassName; \
|
||||
|
@ -122,10 +122,6 @@ AccessibleCaretManager::AccessibleCaretManager(nsIPresShell* aPresShell)
|
||||
}
|
||||
}
|
||||
|
||||
AccessibleCaretManager::~AccessibleCaretManager()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
AccessibleCaretManager::Terminate()
|
||||
{
|
||||
@ -219,7 +215,7 @@ AccessibleCaretManager::HideCarets()
|
||||
}
|
||||
|
||||
void
|
||||
AccessibleCaretManager::UpdateCarets(UpdateCaretsHintSet aHint)
|
||||
AccessibleCaretManager::UpdateCarets(const UpdateCaretsHintSet& aHint)
|
||||
{
|
||||
FlushLayout();
|
||||
if (IsTerminated()) {
|
||||
@ -280,7 +276,7 @@ AccessibleCaretManager::HasNonEmptyTextContent(nsINode* aNode) const
|
||||
}
|
||||
|
||||
void
|
||||
AccessibleCaretManager::UpdateCaretsForCursorMode(UpdateCaretsHintSet aHints)
|
||||
AccessibleCaretManager::UpdateCaretsForCursorMode(const UpdateCaretsHintSet& aHints)
|
||||
{
|
||||
AC_LOG("%s, selection: %p", __FUNCTION__, GetSelection());
|
||||
|
||||
@ -339,7 +335,7 @@ AccessibleCaretManager::UpdateCaretsForCursorMode(UpdateCaretsHintSet aHints)
|
||||
}
|
||||
|
||||
void
|
||||
AccessibleCaretManager::UpdateCaretsForSelectionMode(UpdateCaretsHintSet aHints)
|
||||
AccessibleCaretManager::UpdateCaretsForSelectionMode(const UpdateCaretsHintSet& aHints)
|
||||
{
|
||||
AC_LOG("%s: selection: %p", __FUNCTION__, GetSelection());
|
||||
|
||||
@ -789,24 +785,24 @@ AccessibleCaretManager::GetFrameSelection() const
|
||||
MOZ_ASSERT(fm);
|
||||
|
||||
nsIContent* focusedContent = fm->GetFocusedContent();
|
||||
if (focusedContent) {
|
||||
nsIFrame* focusFrame = focusedContent->GetPrimaryFrame();
|
||||
if (!focusFrame) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Prevent us from touching the nsFrameSelection associated with other
|
||||
// PresShell.
|
||||
RefPtr<nsFrameSelection> fs = focusFrame->GetFrameSelection();
|
||||
if (!fs || fs->GetShell() != mPresShell) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return fs.forget();
|
||||
} else {
|
||||
if (!focusedContent) {
|
||||
// For non-editable content
|
||||
return mPresShell->FrameSelection();
|
||||
}
|
||||
|
||||
nsIFrame* focusFrame = focusedContent->GetPrimaryFrame();
|
||||
if (!focusFrame) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Prevent us from touching the nsFrameSelection associated with other
|
||||
// PresShell.
|
||||
RefPtr<nsFrameSelection> fs = focusFrame->GetFrameSelection();
|
||||
if (!fs || fs->GetShell() != mPresShell) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return fs.forget();
|
||||
}
|
||||
|
||||
nsAutoString
|
||||
|
@ -49,7 +49,7 @@ class AccessibleCaretManager
|
||||
{
|
||||
public:
|
||||
explicit AccessibleCaretManager(nsIPresShell* aPresShell);
|
||||
virtual ~AccessibleCaretManager();
|
||||
virtual ~AccessibleCaretManager() = default;
|
||||
|
||||
// Called by AccessibleCaretEventHub to inform us that PresShell is destroyed.
|
||||
void Terminate();
|
||||
@ -145,13 +145,13 @@ protected:
|
||||
// Update carets based on current selection status. This function will flush
|
||||
// layout, so caller must ensure the PresShell is still valid after calling
|
||||
// this method.
|
||||
void UpdateCarets(UpdateCaretsHintSet aHints = UpdateCaretsHint::Default);
|
||||
void UpdateCarets(const UpdateCaretsHintSet& aHints = UpdateCaretsHint::Default);
|
||||
|
||||
// Force hiding all carets regardless of the current selection status.
|
||||
void HideCarets();
|
||||
|
||||
void UpdateCaretsForCursorMode(UpdateCaretsHintSet aHints);
|
||||
void UpdateCaretsForSelectionMode(UpdateCaretsHintSet aHints);
|
||||
void UpdateCaretsForCursorMode(const UpdateCaretsHintSet& aHints);
|
||||
void UpdateCaretsForSelectionMode(const UpdateCaretsHintSet& aHints);
|
||||
|
||||
// Provide haptic / touch feedback, primarily for select on longpress.
|
||||
void ProvideHapticFeedback();
|
||||
|
@ -71,15 +71,15 @@ public:
|
||||
mInitialized = true;
|
||||
}
|
||||
|
||||
virtual nsPoint GetTouchEventPosition(WidgetTouchEvent* aEvent,
|
||||
int32_t aIdentifier) const override
|
||||
nsPoint GetTouchEventPosition(WidgetTouchEvent* aEvent,
|
||||
int32_t aIdentifier) const override
|
||||
{
|
||||
// Return the device point directly.
|
||||
LayoutDeviceIntPoint touchIntPoint = aEvent->mTouches[0]->mRefPoint;
|
||||
return nsPoint(touchIntPoint.x, touchIntPoint.y);
|
||||
}
|
||||
|
||||
virtual nsPoint GetMouseEventPosition(WidgetMouseEvent* aEvent) const override
|
||||
nsPoint GetMouseEventPosition(WidgetMouseEvent* aEvent) const override
|
||||
{
|
||||
// Return the device point directly.
|
||||
LayoutDeviceIntPoint mouseIntPoint = aEvent->AsGUIEvent()->mRefPoint;
|
||||
@ -112,7 +112,7 @@ public:
|
||||
mHub.get()->AddRef();
|
||||
}
|
||||
|
||||
~AccessibleCaretEventHubTester()
|
||||
~AccessibleCaretEventHubTester() override
|
||||
{
|
||||
// Release the ref added in the constructor.
|
||||
mHub.get()->Release();
|
||||
|
@ -36,13 +36,13 @@ public:
|
||||
public:
|
||||
MockAccessibleCaret() : AccessibleCaret(nullptr) {}
|
||||
|
||||
virtual void SetAppearance(Appearance aAppearance) override
|
||||
void SetAppearance(Appearance aAppearance) override
|
||||
{
|
||||
// A simplified version without touching CaretElement().
|
||||
mAppearance = aAppearance;
|
||||
}
|
||||
|
||||
virtual void SetSelectionBarEnabled(bool aEnabled) override
|
||||
void SetSelectionBarEnabled(bool aEnabled) override
|
||||
{
|
||||
// A simplified version without touching CaretElement().
|
||||
mSelectionBarEnabled = aEnabled;
|
||||
@ -80,22 +80,22 @@ public:
|
||||
return static_cast<MockAccessibleCaret&>(*mSecondCaret);
|
||||
}
|
||||
|
||||
virtual bool CompareTreePosition(nsIFrame* aStartFrame,
|
||||
nsIFrame* aEndFrame) const override
|
||||
bool CompareTreePosition(nsIFrame* aStartFrame,
|
||||
nsIFrame* aEndFrame) const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool IsCaretDisplayableInCursorMode(
|
||||
nsIFrame** aOutFrame = nullptr, int32_t* aOutOffset = nullptr) const override
|
||||
bool IsCaretDisplayableInCursorMode(nsIFrame** aOutFrame = nullptr,
|
||||
int32_t* aOutOffset = nullptr) const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool UpdateCaretsForOverlappingTilt() override { return true; }
|
||||
bool UpdateCaretsForOverlappingTilt() override { return true; }
|
||||
|
||||
virtual void UpdateCaretsForAlwaysTilt(nsIFrame* aStartFrame,
|
||||
nsIFrame* aEndFrame)
|
||||
void UpdateCaretsForAlwaysTilt(nsIFrame* aStartFrame,
|
||||
nsIFrame* aEndFrame) override
|
||||
{
|
||||
if (mFirstCaret->IsVisuallyVisible()) {
|
||||
mFirstCaret->SetAppearance(Appearance::Left);
|
||||
@ -105,7 +105,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool IsTerminated() const override { return false; }
|
||||
bool IsTerminated() const override { return false; }
|
||||
|
||||
MOCK_CONST_METHOD0(GetCaretMode, CaretMode());
|
||||
MOCK_CONST_METHOD1(DispatchCaretStateChangedEvent,
|
||||
|
@ -586,7 +586,7 @@ load 1039454-1.html
|
||||
load 1042489.html
|
||||
load 1054010-1.html
|
||||
load 1058954-1.html
|
||||
asserts-if(!stylo,0-2) skip-if(stylo) pref(dom.webcomponents.enabled,true) load 1059138-1.html # bug 1389936 for non-stylo, bug 1409136 for stylo.
|
||||
asserts-if(!stylo,0-2) pref(dom.webcomponents.enabled,true) pref(dom.webcomponents.customelements.enabled,true) load 1059138-1.html # bug 1389936
|
||||
load 1134531.html
|
||||
load 1134667.html
|
||||
load 1137723-1.html
|
||||
|
@ -204,6 +204,7 @@ LOCAL_INCLUDES += [
|
||||
'../svg',
|
||||
'../tables',
|
||||
'../xul',
|
||||
'/docshell/base',
|
||||
'/dom/base',
|
||||
'/dom/html',
|
||||
'/dom/xul',
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsFrameList.h"
|
||||
#include "nsPlaceholderFrame.h"
|
||||
#include "nsPluginFrame.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIContentInlines.h"
|
||||
#include "nsContentUtils.h"
|
||||
@ -3021,6 +3022,13 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
|
||||
eventRegions = nullptr;
|
||||
}
|
||||
}
|
||||
if (aBuilder->BuildCompositorHitTestInfo()) {
|
||||
CompositorHitTestInfo info = GetCompositorHitTestInfo(aBuilder);
|
||||
if (info != CompositorHitTestInfo::eInvisibleToHitTest) {
|
||||
set.BorderBackground()->AppendNewToBottom(
|
||||
new (aBuilder) nsDisplayCompositorHitTestInfo(aBuilder, this, info));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (aBuilder->IsBackgroundOnly()) {
|
||||
@ -3451,6 +3459,13 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
|
||||
|
||||
CheckForApzAwareEventHandlers(aBuilder, child);
|
||||
|
||||
if (aBuilder->BuildCompositorHitTestInfo()) {
|
||||
CompositorHitTestInfo info = child->GetCompositorHitTestInfo(aBuilder);
|
||||
if (info != CompositorHitTestInfo::eInvisibleToHitTest) {
|
||||
aLists.BorderBackground()->AppendNewToTop(
|
||||
new (aBuilder) nsDisplayCompositorHitTestInfo(aBuilder, child, info));
|
||||
}
|
||||
}
|
||||
nsDisplayLayerEventRegions* eventRegions = aBuilder->GetLayerEventRegions();
|
||||
if (eventRegions) {
|
||||
eventRegions->AddFrame(aBuilder, child);
|
||||
@ -3668,6 +3683,18 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
|
||||
|
||||
child->MarkAbsoluteFramesForDisplayList(aBuilder);
|
||||
|
||||
if (aBuilder->BuildCompositorHitTestInfo()) {
|
||||
CompositorHitTestInfo info = child->GetCompositorHitTestInfo(aBuilder);
|
||||
if (info != CompositorHitTestInfo::eInvisibleToHitTest) {
|
||||
nsDisplayItem* item =
|
||||
new (aBuilder) nsDisplayCompositorHitTestInfo(aBuilder, child, info);
|
||||
if (isPositioned) {
|
||||
list.AppendNewToTop(item);
|
||||
} else {
|
||||
aLists.BorderBackground()->AppendNewToTop(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (aBuilder->IsBuildingLayerEventRegions()) {
|
||||
// If this frame has a different animated geometry root than its parent,
|
||||
// make sure we accumulate event regions for its layer.
|
||||
@ -11182,6 +11209,80 @@ nsIFrame::AddSizeOfExcludingThisForTree(nsWindowSizes& aSizes) const
|
||||
}
|
||||
}
|
||||
|
||||
CompositorHitTestInfo
|
||||
nsIFrame::GetCompositorHitTestInfo(nsDisplayListBuilder* aBuilder)
|
||||
{
|
||||
CompositorHitTestInfo result = CompositorHitTestInfo::eInvisibleToHitTest;
|
||||
|
||||
if (aBuilder->IsInsidePointerEventsNoneDoc()) {
|
||||
// Somewhere up the parent document chain is a subdocument with pointer-
|
||||
// events:none set on it.
|
||||
return result;
|
||||
}
|
||||
if (!GetParent()) {
|
||||
MOZ_ASSERT(IsViewportFrame());
|
||||
// Viewport frames are never event targets, other frames, like canvas frames,
|
||||
// are the event targets for any regions viewport frames may cover.
|
||||
return result;
|
||||
}
|
||||
uint8_t pointerEvents = StyleUserInterface()->GetEffectivePointerEvents(this);
|
||||
if (pointerEvents == NS_STYLE_POINTER_EVENTS_NONE) {
|
||||
return result;
|
||||
}
|
||||
if (!StyleVisibility()->IsVisible()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// Anything that didn't match the above conditions is visible to hit-testing.
|
||||
result |= CompositorHitTestInfo::eVisibleToHitTest;
|
||||
|
||||
if (aBuilder->IsBuildingNonLayerizedScrollbar() ||
|
||||
aBuilder->GetAncestorHasApzAwareEventHandler()) {
|
||||
// Scrollbars may be painted into a layer below the actual layer they will
|
||||
// scroll, and therefore wheel events may be dispatched to the outer frame
|
||||
// instead of the intended scrollframe. To address this, we force a d-t-c
|
||||
// region on scrollbar frames that won't be placed in their own layer. See
|
||||
// bug 1213324 for details.
|
||||
result |= CompositorHitTestInfo::eDispatchToContent;
|
||||
} else if (IsObjectFrame()) {
|
||||
// If the frame is a plugin frame and wants to handle wheel events as
|
||||
// default action, we should add the frame to dispatch-to-content region.
|
||||
nsPluginFrame* pluginFrame = do_QueryFrame(this);
|
||||
if (pluginFrame && pluginFrame->WantsToHandleWheelEventAsDefaultAction()) {
|
||||
result |= CompositorHitTestInfo::eDispatchToContent;
|
||||
}
|
||||
}
|
||||
|
||||
nsIFrame* touchActionFrame = this;
|
||||
if (nsIScrollableFrame* scrollFrame = nsLayoutUtils::GetScrollableFrameFor(this)) {
|
||||
touchActionFrame = do_QueryFrame(scrollFrame);
|
||||
}
|
||||
uint32_t touchAction = nsLayoutUtils::GetTouchActionFromFrame(touchActionFrame);
|
||||
// The CSS allows the syntax auto | none | [pan-x || pan-y] | manipulation
|
||||
// so we can eliminate some combinations of things.
|
||||
if (touchAction == NS_STYLE_TOUCH_ACTION_AUTO) {
|
||||
// nothing to do
|
||||
} else if (touchAction & NS_STYLE_TOUCH_ACTION_MANIPULATION) {
|
||||
result |= CompositorHitTestInfo::eTouchActionDoubleTapZoomDisabled;
|
||||
} else {
|
||||
if (!(touchAction & NS_STYLE_TOUCH_ACTION_PAN_X)) {
|
||||
result |= CompositorHitTestInfo::eTouchActionPanXDisabled;
|
||||
}
|
||||
if (!(touchAction & NS_STYLE_TOUCH_ACTION_PAN_Y)) {
|
||||
result |= CompositorHitTestInfo::eTouchActionPanYDisabled;
|
||||
}
|
||||
if (touchAction & NS_STYLE_TOUCH_ACTION_NONE) {
|
||||
result |= CompositorHitTestInfo::eTouchActionPinchZoomDisabled
|
||||
| CompositorHitTestInfo::eTouchActionDoubleTapZoomDisabled;
|
||||
// pan-x and pan-y disabled flags will already have been set above
|
||||
MOZ_ASSERT(result & CompositorHitTestInfo::eTouchActionPanXDisabled);
|
||||
MOZ_ASSERT(result & CompositorHitTestInfo::eTouchActionPanYDisabled);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Box layout debugging
|
||||
#ifdef DEBUG_REFLOW
|
||||
int32_t gIndent2 = 0;
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include "Visibility.h"
|
||||
#include "nsChangeHint.h"
|
||||
#include "nsStyleContextInlines.h"
|
||||
#include "mozilla/gfx/CompositorHitTestInfo.h"
|
||||
#include "mozilla/gfx/MatrixFwd.h"
|
||||
#include "nsDisplayItemTypes.h"
|
||||
|
||||
@ -4145,6 +4146,8 @@ public:
|
||||
bool BuiltBlendContainer() { return mBuiltBlendContainer; }
|
||||
void SetBuiltBlendContainer(bool aBuilt) { mBuiltBlendContainer = aBuilt; }
|
||||
|
||||
mozilla::gfx::CompositorHitTestInfo GetCompositorHitTestInfo(nsDisplayListBuilder* aBuilder);
|
||||
|
||||
protected:
|
||||
static void DestroyAnonymousContent(nsPresContext* aPresContext,
|
||||
already_AddRefed<nsIContent>&& aContent);
|
||||
|
@ -28,6 +28,7 @@ DECLARE_DISPLAY_ITEM_TYPE(CHECKED_RADIOBUTTON, TYPE_RENDERS_NO_IMAGES)
|
||||
DECLARE_DISPLAY_ITEM_TYPE(CLEAR_BACKGROUND, TYPE_RENDERS_NO_IMAGES)
|
||||
DECLARE_DISPLAY_ITEM_TYPE(COLUMN_RULE, TYPE_RENDERS_NO_IMAGES)
|
||||
DECLARE_DISPLAY_ITEM_TYPE(COMBOBOX_FOCUS, TYPE_RENDERS_NO_IMAGES)
|
||||
DECLARE_DISPLAY_ITEM_TYPE(COMPOSITOR_HITTEST_INFO, TYPE_RENDERS_NO_IMAGES)
|
||||
DECLARE_DISPLAY_ITEM_TYPE(EVENT_RECEIVER, TYPE_RENDERS_NO_IMAGES)
|
||||
DECLARE_DISPLAY_ITEM_TYPE(LAYER_EVENT_REGIONS, TYPE_RENDERS_NO_IMAGES)
|
||||
DECLARE_DISPLAY_ITEM_TYPE(FIELDSET_BORDER_BACKGROUND, 0)
|
||||
|
@ -82,7 +82,6 @@
|
||||
#include "nsDOMTokenList.h"
|
||||
#include "mozilla/RuleNodeCacheConditions.h"
|
||||
#include "nsCSSProps.h"
|
||||
#include "nsPluginFrame.h"
|
||||
#include "nsSVGMaskFrame.h"
|
||||
#include "nsTableCellFrame.h"
|
||||
#include "nsTableColFrame.h"
|
||||
@ -964,6 +963,11 @@ nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame,
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsDisplayListBuilder);
|
||||
|
||||
mBuildCompositorHitTestInfo = gfxVars::UseWebRender()
|
||||
&& gfxPrefs::WebRenderHitTest()
|
||||
&& mAsyncPanZoomEnabled
|
||||
&& mMode == nsDisplayListBuilderMode::PAINTING;
|
||||
|
||||
nsPresContext* pc = aReferenceFrame->PresContext();
|
||||
nsIPresShell *shell = pc->PresShell();
|
||||
if (pc->IsRenderingOnlySelection()) {
|
||||
@ -4829,36 +4833,83 @@ nsDisplayEventReceiver::HitTest(nsDisplayListBuilder* aBuilder,
|
||||
aOutFrames->AppendElement(mFrame);
|
||||
}
|
||||
|
||||
bool
|
||||
nsDisplayEventReceiver::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
|
||||
mozilla::wr::IpcResourceUpdateQueue& aResources,
|
||||
const StackingContextHelper& aSc,
|
||||
mozilla::layers::WebRenderLayerManager* aManager,
|
||||
nsDisplayListBuilder* aDisplayListBuilder)
|
||||
{
|
||||
// This display item should never be getting created when building a display
|
||||
// list for WebRender consumption, so this function should never get called.
|
||||
MOZ_ASSERT(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
nsDisplayCompositorHitTestInfo::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
|
||||
mozilla::wr::IpcResourceUpdateQueue& aResources,
|
||||
const StackingContextHelper& aSc,
|
||||
mozilla::layers::WebRenderLayerManager* aManager,
|
||||
nsDisplayListBuilder* aDisplayListBuilder)
|
||||
{
|
||||
nsRect borderBox;
|
||||
nsIScrollableFrame* scrollFrame = nsLayoutUtils::GetScrollableFrameFor(mFrame);
|
||||
if (scrollFrame) {
|
||||
// If the frame is content of a scrollframe, then we need to pick up the
|
||||
// area corresponding to the overflow rect as well. Otherwise the parts of
|
||||
// the overflow that are not occupied by descendants get skipped and the
|
||||
// APZ code sends touch events to the content underneath instead.
|
||||
// See https://bugzilla.mozilla.org/show_bug.cgi?id=1127773#c15.
|
||||
borderBox = mFrame->GetScrollableOverflowRect();
|
||||
} else {
|
||||
borderBox = nsRect(nsPoint(0, 0), mFrame->GetSize());
|
||||
}
|
||||
|
||||
if (borderBox.IsEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
wr::LayoutRect rect = aSc.ToRelativeLayoutRect(
|
||||
LayoutDeviceRect::FromAppUnits(
|
||||
borderBox + aDisplayListBuilder->ToReferenceFrame(mFrame),
|
||||
mFrame->PresContext()->AppUnitsPerDevPixel()));
|
||||
|
||||
// XXX: eventually this scrollId computation and the SetHitTestInfo
|
||||
// call will get moved out into the WR display item iteration code so that
|
||||
// we don't need to do it as often, and so that we can do it for other
|
||||
// display item types as well (reducing the need for as many instances of
|
||||
// this display item).
|
||||
FrameMetrics::ViewID scrollId = FrameMetrics::NULL_SCROLL_ID;
|
||||
if (const ActiveScrolledRoot* asr = GetActiveScrolledRoot()) {
|
||||
scrollId = nsLayoutUtils::ViewIDForASR(asr);
|
||||
}
|
||||
|
||||
// Insert a transparent rectangle with the hit-test info
|
||||
aBuilder.SetHitTestInfo(scrollId, mHitTestInfo);
|
||||
aBuilder.PushRect(rect, rect, true, wr::ToColorF(gfx::Color()));
|
||||
aBuilder.ClearHitTestInfo();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
nsDisplayCompositorHitTestInfo::WriteDebugInfo(std::stringstream& aStream)
|
||||
{
|
||||
aStream << nsPrintfCString(" (hitTestInfo 0x%x)", (int)mHitTestInfo).get();
|
||||
}
|
||||
|
||||
void
|
||||
nsDisplayLayerEventRegions::AddFrame(nsDisplayListBuilder* aBuilder,
|
||||
nsIFrame* aFrame)
|
||||
{
|
||||
NS_ASSERTION(aBuilder->FindReferenceFrameFor(aFrame) == aBuilder->FindReferenceFrameFor(mFrame),
|
||||
"Reference frame mismatch");
|
||||
if (aBuilder->IsInsidePointerEventsNoneDoc()) {
|
||||
// Somewhere up the parent document chain is a subdocument with pointer-
|
||||
// events:none set on it.
|
||||
CompositorHitTestInfo hitInfo =
|
||||
aFrame->GetCompositorHitTestInfo(aBuilder);
|
||||
if (hitInfo == CompositorHitTestInfo::eInvisibleToHitTest) {
|
||||
return;
|
||||
}
|
||||
if (!aFrame->GetParent()) {
|
||||
MOZ_ASSERT(aFrame->IsViewportFrame());
|
||||
// Viewport frames are never event targets, other frames, like canvas frames,
|
||||
// are the event targets for any regions viewport frames may cover.
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t pointerEvents =
|
||||
aFrame->StyleUserInterface()->GetEffectivePointerEvents(aFrame);
|
||||
if (pointerEvents == NS_STYLE_POINTER_EVENTS_NONE) {
|
||||
return;
|
||||
}
|
||||
bool simpleRegions = aFrame->HasAnyStateBits(NS_FRAME_SIMPLE_EVENT_REGIONS);
|
||||
if (!simpleRegions) {
|
||||
if (!aFrame->StyleVisibility()->IsVisible()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// XXX handle other pointerEvents values for SVG
|
||||
|
||||
@ -4889,6 +4940,11 @@ nsDisplayLayerEventRegions::AddFrame(nsDisplayListBuilder* aBuilder,
|
||||
borderBox += aBuilder->ToReferenceFrame(aFrame);
|
||||
|
||||
bool borderBoxHasRoundedCorners = false;
|
||||
|
||||
// use the NS_FRAME_SIMPLE_EVENT_REGIONS to avoid calling the slightly
|
||||
// expensive HasNonZeroCorner function if we know from a previous run that
|
||||
// the frame has zero corners.
|
||||
bool simpleRegions = aFrame->HasAnyStateBits(NS_FRAME_SIMPLE_EVENT_REGIONS);
|
||||
if (!simpleRegions) {
|
||||
if (nsLayoutUtils::HasNonZeroCorner(aFrame->StyleBorder()->mBorderRadius)) {
|
||||
borderBoxHasRoundedCorners = true;
|
||||
@ -4914,39 +4970,25 @@ nsDisplayLayerEventRegions::AddFrame(nsDisplayListBuilder* aBuilder,
|
||||
mHitRegion.Add(aFrame, borderBox);
|
||||
}
|
||||
|
||||
if (aBuilder->IsBuildingNonLayerizedScrollbar() ||
|
||||
aBuilder->GetAncestorHasApzAwareEventHandler())
|
||||
{
|
||||
// Scrollbars may be painted into a layer below the actual layer they will
|
||||
// scroll, and therefore wheel events may be dispatched to the outer frame
|
||||
// instead of the intended scrollframe. To address this, we force a d-t-c
|
||||
// region on scrollbar frames that won't be placed in their own layer. See
|
||||
// bug 1213324 for details.
|
||||
if (hitInfo & CompositorHitTestInfo::eDispatchToContent) {
|
||||
mDispatchToContentHitRegion.Add(aFrame, borderBox);
|
||||
} else if (aFrame->IsObjectFrame()) {
|
||||
// If the frame is a plugin frame and wants to handle wheel events as
|
||||
// default action, we should add the frame to dispatch-to-content region.
|
||||
nsPluginFrame* pluginFrame = do_QueryFrame(aFrame);
|
||||
if (pluginFrame && pluginFrame->WantsToHandleWheelEventAsDefaultAction()) {
|
||||
mDispatchToContentHitRegion.Add(aFrame, borderBox);
|
||||
}
|
||||
}
|
||||
|
||||
// Touch action region
|
||||
|
||||
nsIFrame* touchActionFrame = aFrame;
|
||||
if (scrollFrame) {
|
||||
touchActionFrame = do_QueryFrame(scrollFrame);
|
||||
}
|
||||
uint32_t touchAction = nsLayoutUtils::GetTouchActionFromFrame(touchActionFrame);
|
||||
if (touchAction != NS_STYLE_TOUCH_ACTION_AUTO) {
|
||||
if (touchAction & NS_STYLE_TOUCH_ACTION_NONE) {
|
||||
auto touchFlags = hitInfo & CompositorHitTestInfo::eTouchActionMask;
|
||||
if (touchFlags) {
|
||||
// something was disabled
|
||||
if (touchFlags == CompositorHitTestInfo::eTouchActionMask) {
|
||||
// everything was disabled, so touch-action:none
|
||||
mNoActionRegion.Add(aFrame, borderBox);
|
||||
} else {
|
||||
if ((touchAction & NS_STYLE_TOUCH_ACTION_PAN_X)) {
|
||||
if (!(hitInfo & CompositorHitTestInfo::eTouchActionPanXDisabled)) {
|
||||
// pan-x is allowed
|
||||
mHorizontalPanRegion.Add(aFrame, borderBox);
|
||||
}
|
||||
if ((touchAction & NS_STYLE_TOUCH_ACTION_PAN_Y)) {
|
||||
if (!(hitInfo & CompositorHitTestInfo::eTouchActionPanYDisabled)) {
|
||||
// pan-y is allowed
|
||||
mVerticalPanRegion.Add(aFrame, borderBox);
|
||||
}
|
||||
}
|
||||
@ -6510,10 +6552,14 @@ nsDisplayOpacity::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuil
|
||||
// Note that animationsId can be 0 (uninitialized in AnimationInfo) if there
|
||||
// are no active animations.
|
||||
uint64_t animationsId = animationInfo.GetCompositorAnimationsId();
|
||||
wr::WrAnimationProperty prop;
|
||||
|
||||
if (!animationInfo.GetAnimations().IsEmpty()) {
|
||||
opacityForSC = nullptr;
|
||||
OptionalOpacity opacityForCompositor = mOpacity;
|
||||
prop.id = animationsId;
|
||||
prop.effect_type = wr::WrAnimationType::Opacity;
|
||||
|
||||
|
||||
OpAddCompositorAnimations
|
||||
anim(CompositorAnimations(animationInfo.GetAnimations(), animationsId),
|
||||
@ -6526,7 +6572,8 @@ nsDisplayOpacity::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuil
|
||||
}
|
||||
|
||||
nsTArray<mozilla::wr::WrFilterOp> filters;
|
||||
StackingContextHelper sc(aSc, aBuilder, filters, nullptr, animationsId,
|
||||
StackingContextHelper sc(aSc, aBuilder, filters, nullptr,
|
||||
animationsId ? &prop : nullptr,
|
||||
opacityForSC);
|
||||
|
||||
aManager->CommandBuilder().CreateWebRenderCommandsFromDisplayList(&mList,
|
||||
@ -6815,8 +6862,13 @@ nsDisplayOwnLayer::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBui
|
||||
animationInfo.EnsureAnimationsId();
|
||||
mWrAnimationId = animationInfo.GetCompositorAnimationsId();
|
||||
|
||||
StackingContextHelper sc(aSc, aBuilder, nsTArray<wr::WrFilterOp>(), nullptr,
|
||||
mWrAnimationId);
|
||||
|
||||
wr::WrAnimationProperty prop;
|
||||
prop.id = mWrAnimationId;
|
||||
prop.effect_type = wr::WrAnimationType::Transform;
|
||||
|
||||
StackingContextHelper sc(aSc, aBuilder, nsTArray<wr::WrFilterOp>(),
|
||||
nullptr, &prop);
|
||||
|
||||
nsDisplayWrapList::CreateWebRenderCommands(aBuilder, aResources, sc,
|
||||
aManager, aDisplayListBuilder);
|
||||
@ -8324,13 +8376,16 @@ nsDisplayTransform::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBu
|
||||
// Note that animationsId can be 0 (uninitialized in AnimationInfo) if there
|
||||
// are no active animations.
|
||||
uint64_t animationsId = animationInfo.GetCompositorAnimationsId();
|
||||
|
||||
wr::WrAnimationProperty prop;
|
||||
if (!animationInfo.GetAnimations().IsEmpty()) {
|
||||
// Update transfrom as nullptr in stacking context if there exists
|
||||
// transform animation, the transform value will be resolved
|
||||
// after animation sampling on the compositor
|
||||
transformForSC = nullptr;
|
||||
|
||||
prop.id = animationsId;
|
||||
prop.effect_type = wr::WrAnimationType::Transform;
|
||||
|
||||
// Pass default transform to compositor in case gecko fails to
|
||||
// get animated value after animation sampling.
|
||||
OptionalTransform transformForCompositor = newTransformMatrix;
|
||||
@ -8350,7 +8405,7 @@ nsDisplayTransform::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBu
|
||||
aBuilder,
|
||||
filters,
|
||||
&newTransformMatrix,
|
||||
animationsId,
|
||||
animationsId ? &prop : nullptr,
|
||||
nullptr,
|
||||
transformForSC,
|
||||
nullptr,
|
||||
|
@ -502,6 +502,11 @@ public:
|
||||
return mMode == nsDisplayListBuilderMode::PAINTING_SELECTION_BACKGROUND;
|
||||
}
|
||||
|
||||
bool BuildCompositorHitTestInfo()
|
||||
{
|
||||
return mBuildCompositorHitTestInfo;
|
||||
}
|
||||
|
||||
bool WillComputePluginGeometry() { return mWillComputePluginGeometry; }
|
||||
/**
|
||||
* @return true if "painting is suppressed" during page load and we
|
||||
@ -1817,6 +1822,7 @@ private:
|
||||
bool mHitTestIsForVisibility;
|
||||
bool mIsBuilding;
|
||||
bool mInInvalidSubtree;
|
||||
bool mBuildCompositorHitTestInfo;
|
||||
};
|
||||
|
||||
class nsDisplayItem;
|
||||
@ -4299,11 +4305,60 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
||||
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) override;
|
||||
void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
||||
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) override;
|
||||
bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
|
||||
mozilla::wr::IpcResourceUpdateQueue& aResources,
|
||||
const StackingContextHelper& aSc,
|
||||
mozilla::layers::WebRenderLayerManager* aManager,
|
||||
nsDisplayListBuilder* aDisplayListBuilder) override;
|
||||
|
||||
NS_DISPLAY_DECL_NAME("EventReceiver", TYPE_EVENT_RECEIVER)
|
||||
};
|
||||
|
||||
/**
|
||||
* Similar to nsDisplayEventReceiver in that it is used for hit-testing. However
|
||||
* this gets built when we're doing widget painting and we need to send the
|
||||
* compositor some hit-test info for a frame. This is effectively a dummy item
|
||||
* whose sole purpose is to carry the hit-test info to the compositor.
|
||||
*/
|
||||
class nsDisplayCompositorHitTestInfo : public nsDisplayEventReceiver {
|
||||
public:
|
||||
nsDisplayCompositorHitTestInfo(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
|
||||
mozilla::gfx::CompositorHitTestInfo aHitTestInfo)
|
||||
: nsDisplayEventReceiver(aBuilder, aFrame)
|
||||
, mHitTestInfo(aHitTestInfo)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsDisplayCompositorHitTestInfo);
|
||||
// We should never even create this display item if we're not building
|
||||
// compositor hit-test info or if the computed hit info indicated the
|
||||
// frame is invisible to hit-testing
|
||||
MOZ_ASSERT(aBuilder->BuildCompositorHitTestInfo());
|
||||
MOZ_ASSERT(mHitTestInfo != mozilla::gfx::CompositorHitTestInfo::eInvisibleToHitTest);
|
||||
}
|
||||
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
virtual ~nsDisplayCompositorHitTestInfo()
|
||||
{
|
||||
MOZ_COUNT_DTOR(nsDisplayCompositorHitTestInfo);
|
||||
}
|
||||
#endif
|
||||
|
||||
mozilla::gfx::CompositorHitTestInfo HitTestInfo() const { return mHitTestInfo; }
|
||||
|
||||
bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
|
||||
mozilla::wr::IpcResourceUpdateQueue& aResources,
|
||||
const StackingContextHelper& aSc,
|
||||
mozilla::layers::WebRenderLayerManager* aManager,
|
||||
nsDisplayListBuilder* aDisplayListBuilder) override;
|
||||
void WriteDebugInfo(std::stringstream& aStream) override;
|
||||
|
||||
NS_DISPLAY_DECL_NAME("CompositorHitTestInfo", TYPE_COMPOSITOR_HITTEST_INFO)
|
||||
|
||||
private:
|
||||
mozilla::gfx::CompositorHitTestInfo mHitTestInfo;
|
||||
};
|
||||
|
||||
/**
|
||||
* A display item that tracks event-sensitive regions which will be set
|
||||
* on the ContainerLayer that eventually contains this item.
|
||||
|
@ -3673,6 +3673,7 @@ PeerConnectionImpl::BuildStatsQuery_m(
|
||||
NS_ConvertASCIItoUTF16(localDescription.c_str()));
|
||||
query->report->mRemoteSdp.Construct(
|
||||
NS_ConvertASCIItoUTF16(remoteDescription.c_str()));
|
||||
query->report->mOfferer.Construct(mJsepSession->IsOfferer());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -644,8 +644,8 @@ public class GeckoPreferences
|
||||
preferences.removePreference(pref);
|
||||
i--;
|
||||
continue;
|
||||
} else if (PREFS_CATEGORY_EXPERIMENTAL_FEATURES.equals(key)
|
||||
&& !AppConstants.MOZ_ANDROID_PWA) {
|
||||
|
||||
} else if (PREFS_CATEGORY_EXPERIMENTAL_FEATURES.equals(key) && ((PreferenceGroup) pref).getPreferenceCount() == 0) {
|
||||
preferences.removePreference(pref);
|
||||
i--;
|
||||
continue;
|
||||
|
@ -15,5 +15,4 @@ tags = webextensions
|
||||
[test_ext_options_ui.html]
|
||||
[test_ext_pageAction_show_hide.html]
|
||||
[test_ext_pageAction_getPopup_setPopup.html]
|
||||
skip-if = os == 'android' # bug 1373170
|
||||
[test_ext_popup_behavior.html]
|
||||
|
@ -31,9 +31,9 @@ add_task(async function test_setPopup_and_getPopup() {
|
||||
|
||||
async function createAndTestNewTab(expectedPopup, url) {
|
||||
// Create a tab.
|
||||
let [tab] = await Promise.all([
|
||||
browser.tabs.create({url}),
|
||||
let [, tab] = await Promise.all([
|
||||
tabCreatedPromise,
|
||||
browser.tabs.create({url}),
|
||||
]);
|
||||
|
||||
// Test that the default popup is returned before the popup is set for the tab.
|
||||
@ -58,12 +58,12 @@ add_task(async function test_setPopup_and_getPopup() {
|
||||
popup = await browser.pageAction.getPopup({tabId: tab2.id});
|
||||
browser.test.assertTrue(popup.includes("b.html"), "Expected the second tab popup");
|
||||
|
||||
// Unset the title for the first tab and confirm that it is unset.
|
||||
// Unset the popup for the first tab and confirm that it is unset.
|
||||
browser.pageAction.setPopup({tabId: tab1.id, popup: ""});
|
||||
popup = await browser.pageAction.getPopup({tabId: tab1.id});
|
||||
browser.test.assertTrue(popup.includes("default.html"), "Expected the default popup to be returned");
|
||||
|
||||
// Reset the title for the first tab.
|
||||
// Set the popup for the first tab.
|
||||
browser.pageAction.setPopup({tabId: tab1.id, popup: "a.html"});
|
||||
popup = await browser.pageAction.getPopup({tabId: tab1.id});
|
||||
browser.test.assertTrue(popup.includes("a.html"), "Expected the first tab popup");
|
||||
@ -78,25 +78,37 @@ add_task(async function test_setPopup_and_getPopup() {
|
||||
|
||||
browser.test.onMessage.addListener(async (msg, data) => {
|
||||
if (msg === "select-tab") {
|
||||
// Check if the requested tabId is already selected.
|
||||
const [activeTab] = await browser.tabs.query({active: true});
|
||||
if (activeTab.id === data.tabId) {
|
||||
browser.test.sendMessage("tab-selected");
|
||||
return;
|
||||
}
|
||||
|
||||
// Select the requested tabId and wait the tab to be activated.
|
||||
const onActivatedListener = ({tabId}) => {
|
||||
if (tabId === data.tabId) {
|
||||
browser.tabs.onActivated.removeListener(onActivatedListener);
|
||||
browser.test.sendMessage("tab-selected");
|
||||
}
|
||||
};
|
||||
browser.tabs.onActivated.addListener(onActivatedListener);
|
||||
|
||||
await browser.tabs.update(data.tabId, {active: true});
|
||||
browser.test.sendMessage("tab-selected");
|
||||
} else if (msg === "page-action-show") {
|
||||
browser.pageAction.show(data.tabId).then(() => {
|
||||
browser.test.sendMessage("page-action-shown");
|
||||
});
|
||||
await browser.pageAction.show(data.tabId);
|
||||
browser.test.sendMessage("page-action-shown");
|
||||
} else if (msg == "page-action-set-popup") {
|
||||
if (data.popup == "") {
|
||||
expectingOnClicked[data.tabId] = true;
|
||||
} else {
|
||||
delete expectingOnClicked[tabId];
|
||||
}
|
||||
browser.pageAction.setPopup({tabId: data.tabId, popup: data.popup}).then(() => {
|
||||
browser.test.sendMessage("page-action-popup-set");
|
||||
});
|
||||
await browser.pageAction.setPopup({tabId: data.tabId, popup: data.popup});
|
||||
browser.test.sendMessage("page-action-popup-set");
|
||||
} else if (msg == "page-action-get-popup") {
|
||||
browser.pageAction.getPopup({tabId: data.tabId}).then(url => {
|
||||
browser.test.sendMessage("page-action-got-popup", url);
|
||||
});
|
||||
const url = await browser.pageAction.getPopup({tabId: data.tabId});
|
||||
browser.test.sendMessage("page-action-got-popup", url);
|
||||
} else if (msg === "finish") {
|
||||
await browser.tabs.remove([tab1.id, tab2.id]);
|
||||
browser.test.notifyPass("page-action-popup");
|
||||
@ -110,6 +122,7 @@ add_task(async function test_setPopup_and_getPopup() {
|
||||
window.onload = () => {
|
||||
browser.test.sendMessage("page-action-from-popup", location.href);
|
||||
};
|
||||
|
||||
browser.test.onMessage.addListener((msg, details) => {
|
||||
if (msg == "page-action-close-popup") {
|
||||
if (details.location == location.href) {
|
||||
@ -168,13 +181,17 @@ add_task(async function test_setPopup_and_getPopup() {
|
||||
await extension.awaitMessage("page-action-shown");
|
||||
|
||||
ok(PageActions.isShown(uuid), "page action is shown");
|
||||
|
||||
info(`Click on the pageAction on tab ${tabId} and wait the popup to be loaded`);
|
||||
PageActions.synthesizeClick(uuid);
|
||||
let location = await extension.awaitMessage("page-action-from-popup");
|
||||
|
||||
ok(location.includes(expectedPopup), "The popup with the correct URL should be shown.");
|
||||
|
||||
const onceTabClosed = tabClosedPromise();
|
||||
extension.sendMessage("page-action-close-popup", {location});
|
||||
location = await tabClosedPromise();
|
||||
ok(location.includes(expectedPopup), "The popup with the correct URL should be closed.");
|
||||
location = await onceTabClosed;
|
||||
ok(location.includes(expectedPopup), "The popup with the correct URL should be closed");
|
||||
}
|
||||
|
||||
await extension.startup();
|
||||
|
@ -32,6 +32,7 @@ import android.graphics.drawable.ShapeDrawable;
|
||||
import android.graphics.drawable.shapes.RoundRectShape;
|
||||
import android.graphics.drawable.shapes.Shape;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.text.TextUtils;
|
||||
import android.util.TypedValue;
|
||||
@ -84,6 +85,20 @@ public class BaseMessageDialog extends Dialog {
|
||||
private boolean isHtml = false;
|
||||
private boolean isClosing = false;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
final Window window = getWindow();
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
|
||||
window.setStatusBarColor(Color.TRANSPARENT);
|
||||
|
||||
int flags = window.getDecorView().getSystemUiVisibility();
|
||||
flags |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
|
||||
window.getDecorView().setSystemUiVisibility(flags);
|
||||
}
|
||||
}
|
||||
|
||||
protected BaseMessageDialog(Activity activity, boolean fullscreen, BaseMessageOptions options,
|
||||
WebInterstitialOptions webOptions, HTMLOptions htmlOptions) {
|
||||
super(activity, getTheme(activity));
|
||||
|
@ -32,6 +32,7 @@ import com.leanplum.LeanplumActivityHelper;
|
||||
import com.leanplum.callbacks.ActionCallback;
|
||||
import com.leanplum.callbacks.PostponableAction;
|
||||
import com.leanplum.callbacks.VariablesChangedCallback;
|
||||
import com.leanplum.utils.SizeUtil;
|
||||
|
||||
/**
|
||||
* Registers a Leanplum action that displays a HTML message.
|
||||
@ -50,10 +51,12 @@ public class HTMLTemplate extends BaseMessageDialog {
|
||||
@Override
|
||||
public boolean dispatchTouchEvent(@NonNull MotionEvent ev) {
|
||||
if (!htmlOptions.isFullScreen()) {
|
||||
int height = SizeUtil.dpToPx(Leanplum.getContext(), htmlOptions.getHtmlHeight());
|
||||
int statusBarHeight = SizeUtil.getStatusBarHeight(Leanplum.getContext());
|
||||
if (htmlOptions.getHtmlAlign().equals(MessageTemplates.Args.HTML_ALIGN_TOP) && ev.getY()
|
||||
> htmlOptions.getHtmlHeight() ||
|
||||
> height + statusBarHeight ||
|
||||
htmlOptions.getHtmlAlign().equals(MessageTemplates.Args.HTML_ALIGN_BOTTOM) && ev.getY()
|
||||
< dialogView.getHeight() - htmlOptions.getHtmlHeight()) {
|
||||
< dialogView.getHeight() + statusBarHeight - height) {
|
||||
activity.dispatchTouchEvent(ev);
|
||||
}
|
||||
}
|
||||
|
@ -114,4 +114,17 @@ public class SizeUtil {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static int getStatusBarHeight(Context context) {
|
||||
init(context);
|
||||
int result = 0;
|
||||
try {
|
||||
int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
|
||||
if (resourceId > 0) {
|
||||
result = context.getResources().getDimensionPixelSize(resourceId);
|
||||
}
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ from mozbuild.backend.base import PartialBackend, HybridBackend
|
||||
from mozbuild.backend.recursivemake import RecursiveMakeBackend
|
||||
from mozbuild.shellutil import quote as shell_quote
|
||||
from mozbuild.util import OrderedDefaultDict
|
||||
from collections import defaultdict
|
||||
|
||||
from mozpack.files import (
|
||||
FileFinder,
|
||||
@ -21,17 +22,22 @@ from mozpack.files import (
|
||||
from .common import CommonBackend
|
||||
from ..frontend.data import (
|
||||
ChromeManifestEntry,
|
||||
ComputedFlags,
|
||||
ContextDerived,
|
||||
Defines,
|
||||
FinalTargetFiles,
|
||||
FinalTargetPreprocessedFiles,
|
||||
GeneratedFile,
|
||||
GeneratedSources,
|
||||
HostDefines,
|
||||
JARManifest,
|
||||
ObjdirFiles,
|
||||
PerSourceFlag,
|
||||
Sources,
|
||||
)
|
||||
from ..util import (
|
||||
FileAvoidWrite,
|
||||
expand_variables,
|
||||
)
|
||||
from ..frontend.context import (
|
||||
AbsolutePath,
|
||||
@ -55,6 +61,9 @@ class BackendTupfile(object):
|
||||
self.defines = []
|
||||
self.host_defines = []
|
||||
self.delayed_generated_files = []
|
||||
self.per_source_flags = defaultdict(list)
|
||||
self.local_flags = defaultdict(list)
|
||||
self.sources = defaultdict(list)
|
||||
|
||||
self.fh = FileAvoidWrite(self.name, capture_diff=True)
|
||||
self.fh.write('# THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT.\n')
|
||||
@ -68,7 +77,8 @@ class BackendTupfile(object):
|
||||
self.write('include_rules\n')
|
||||
self.rules_included = True
|
||||
|
||||
def rule(self, cmd, inputs=None, outputs=None, display=None, extra_outputs=None, check_unchanged=False):
|
||||
def rule(self, cmd, inputs=None, outputs=None, display=None,
|
||||
extra_inputs=None, extra_outputs=None, check_unchanged=False):
|
||||
inputs = inputs or []
|
||||
outputs = outputs or []
|
||||
display = display or ""
|
||||
@ -85,8 +95,9 @@ class BackendTupfile(object):
|
||||
else:
|
||||
caret_text = flags
|
||||
|
||||
self.write(': %(inputs)s |> %(display)s%(cmd)s |> %(outputs)s%(extra_outputs)s\n' % {
|
||||
self.write(': %(inputs)s%(extra_inputs)s |> %(display)s%(cmd)s |> %(outputs)s%(extra_outputs)s\n' % {
|
||||
'inputs': ' '.join(inputs),
|
||||
'extra_inputs': ' | ' + ' '.join(extra_inputs) if extra_inputs else '',
|
||||
'display': '^%s^ ' % caret_text if caret_text else '',
|
||||
'cmd': ' '.join(cmd),
|
||||
'outputs': ' '.join(outputs),
|
||||
@ -106,6 +117,29 @@ class BackendTupfile(object):
|
||||
outputs=outputs,
|
||||
)
|
||||
|
||||
def gen_sources_rules(self, extra_inputs):
|
||||
compilers = [
|
||||
('.S', 'AS', 'ASFLAGS'),
|
||||
('.cpp', 'CXX', 'CXXFLAGS'),
|
||||
('.c', 'CC', 'CFLAGS'),
|
||||
]
|
||||
for extension, compiler, flags in compilers:
|
||||
srcs = sorted(self.sources[extension])
|
||||
for src in srcs:
|
||||
# AS can be set to $(CC), so we need to call expand_variables on
|
||||
# the compiler to get the real value.
|
||||
cmd = [expand_variables(self.environment.substs[compiler], self.environment.substs)]
|
||||
cmd.extend(self.local_flags[flags])
|
||||
cmd.extend(self.per_source_flags[src])
|
||||
cmd.extend(['-c', '%f', '-o', '%o'])
|
||||
self.rule(
|
||||
cmd=cmd,
|
||||
inputs=[src],
|
||||
extra_inputs=extra_inputs,
|
||||
outputs=['%B.o'],
|
||||
display='%s %%f' % compiler,
|
||||
)
|
||||
|
||||
def export_shell(self):
|
||||
if not self.shell_exported:
|
||||
# These are used by mach/mixin/process.py to determine the current
|
||||
@ -141,8 +175,9 @@ class TupOnly(CommonBackend, PartialBackend):
|
||||
'*.rs',
|
||||
)
|
||||
|
||||
# This is a 'group' dependency - All rules that list this as an output
|
||||
# These are 'group' dependencies - All rules that list these as an output
|
||||
# will be built before any rules that list this as an input.
|
||||
self._installed_idls = '$(MOZ_OBJ_ROOT)/<installed-idls>'
|
||||
self._installed_files = '$(MOZ_OBJ_ROOT)/<installed-files>'
|
||||
|
||||
def _get_backend_file(self, relativedir):
|
||||
@ -217,6 +252,13 @@ class TupOnly(CommonBackend, PartialBackend):
|
||||
self._process_final_target_pp_files(obj, backend_file)
|
||||
elif isinstance(obj, JARManifest):
|
||||
self._consume_jar_manifest(obj)
|
||||
elif isinstance(obj, PerSourceFlag):
|
||||
backend_file.per_source_flags[obj.file_name].extend(obj.flags)
|
||||
elif isinstance(obj, ComputedFlags):
|
||||
self._process_computed_flags(obj, backend_file)
|
||||
elif isinstance(obj, (Sources, GeneratedSources)):
|
||||
if obj.relobjdir.startswith('xpcom'):
|
||||
backend_file.sources[obj.canonical_suffix].extend(obj.files)
|
||||
|
||||
return True
|
||||
|
||||
@ -233,6 +275,7 @@ class TupOnly(CommonBackend, PartialBackend):
|
||||
for objdir, backend_file in sorted(self._backend_files.items()):
|
||||
for obj in backend_file.delayed_generated_files:
|
||||
self._process_generated_file(backend_file, obj)
|
||||
backend_file.gen_sources_rules([self._installed_files])
|
||||
with self._write_file(fh=backend_file):
|
||||
pass
|
||||
|
||||
@ -274,6 +317,11 @@ class TupOnly(CommonBackend, PartialBackend):
|
||||
'layout/style/test', # HostSimplePrograms
|
||||
'toolkit/library', # libxul.so
|
||||
)
|
||||
install_exts = (
|
||||
'.h',
|
||||
'.inc',
|
||||
'new', # 'new' is an output from make-stl-wrappers.py
|
||||
)
|
||||
if obj.script and obj.method and obj.relobjdir not in skip_directories:
|
||||
backend_file.export_shell()
|
||||
cmd = self._py_action('file_generate')
|
||||
@ -291,11 +339,14 @@ class TupOnly(CommonBackend, PartialBackend):
|
||||
outputs.extend(obj.outputs)
|
||||
outputs.append('%s.pp' % obj.outputs[0])
|
||||
|
||||
extra_outputs = [self._installed_files] if any(f.endswith(install_exts) for f in obj.outputs) else None
|
||||
|
||||
backend_file.rule(
|
||||
display='python {script}:{method} -> [%o]'.format(script=obj.script, method=obj.method),
|
||||
cmd=cmd,
|
||||
inputs=full_inputs,
|
||||
outputs=outputs,
|
||||
extra_outputs=extra_outputs,
|
||||
)
|
||||
|
||||
def _process_defines(self, backend_file, obj, host=False):
|
||||
@ -376,13 +427,23 @@ class TupOnly(CommonBackend, PartialBackend):
|
||||
self._preprocess(backend_file, f.full_path,
|
||||
destdir=mozpath.join(self.environment.topobjdir, obj.install_target, path))
|
||||
|
||||
def _process_computed_flags(self, obj, backend_file):
|
||||
for var, flags in obj.get_flags():
|
||||
backend_file.local_flags[var] = flags
|
||||
|
||||
def _process_unified_sources(self, obj):
|
||||
backend_file = self._get_backend_file_for(obj)
|
||||
if obj.relobjdir.startswith('xpcom'):
|
||||
files = [f[0] for f in obj.unified_source_mapping]
|
||||
backend_file.sources[obj.canonical_suffix].extend(files)
|
||||
|
||||
def _handle_idl_manager(self, manager):
|
||||
if self.environment.is_artifact_build:
|
||||
return
|
||||
|
||||
dist_idl_backend_file = self._get_backend_file('dist/idl')
|
||||
for idl in manager.idls.values():
|
||||
dist_idl_backend_file.symlink_rule(idl['source'], output_group=self._installed_files)
|
||||
dist_idl_backend_file.symlink_rule(idl['source'], output_group=self._installed_idls)
|
||||
|
||||
backend_file = self._get_backend_file('xpcom/xpidl')
|
||||
backend_file.export_shell()
|
||||
@ -409,11 +470,12 @@ class TupOnly(CommonBackend, PartialBackend):
|
||||
inputs=[
|
||||
'$(MOZ_OBJ_ROOT)/xpcom/idl-parser/xpidl/xpidllex.py',
|
||||
'$(MOZ_OBJ_ROOT)/xpcom/idl-parser/xpidl/xpidlyacc.py',
|
||||
self._installed_files,
|
||||
self._installed_idls,
|
||||
],
|
||||
display='XPIDL %s' % module,
|
||||
cmd=cmd,
|
||||
outputs=outputs,
|
||||
extra_outputs=[self._installed_files],
|
||||
)
|
||||
|
||||
for manifest, entries in manager.interface_manifests.items():
|
||||
@ -491,6 +553,7 @@ class TupOnly(CommonBackend, PartialBackend):
|
||||
display='IPDL code generation',
|
||||
cmd=cmd,
|
||||
outputs=outputs,
|
||||
extra_outputs=[self._installed_files],
|
||||
check_unchanged=True,
|
||||
)
|
||||
|
||||
@ -522,6 +585,7 @@ class TupOnly(CommonBackend, PartialBackend):
|
||||
cmd=cmd,
|
||||
inputs=webidls.all_non_static_basenames(),
|
||||
outputs=outputs,
|
||||
extra_outputs=[self._installed_files],
|
||||
check_unchanged=True,
|
||||
)
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
|
||||
import errno
|
||||
import getpass
|
||||
import io
|
||||
import json
|
||||
@ -1337,21 +1338,66 @@ class BuildDriver(MozbuildObject):
|
||||
if self._check_clobber(mozconfig, os.environ):
|
||||
return 1
|
||||
|
||||
mozconfig_make_lines = []
|
||||
for arg in mozconfig['make_extra'] or []:
|
||||
mozconfig_make_lines.append(arg)
|
||||
|
||||
if mozconfig['make_flags']:
|
||||
mozconfig_make_lines.append(b'MOZ_MAKE_FLAGS=%s' %
|
||||
b' '.join(mozconfig['make_flags']))
|
||||
objdir = mozpath.normsep(self.topobjdir)
|
||||
mozconfig_make_lines.append(b'MOZ_OBJDIR=%s' % objdir)
|
||||
mozconfig_make_lines.append(b'OBJDIR=%s' % objdir)
|
||||
|
||||
if mozconfig['path']:
|
||||
mozconfig_make_lines.append(b'FOUND_MOZCONFIG=%s' %
|
||||
mozpath.normsep(mozconfig['path']))
|
||||
mozconfig_make_lines.append(b'export FOUND_MOZCONFIG')
|
||||
|
||||
# The .mozconfig.mk file only contains exported variables and lines with
|
||||
# UPLOAD_EXTRA_FILES.
|
||||
mozconfig_filtered_lines = [
|
||||
line for line in mozconfig_make_lines
|
||||
# Bug 1418122 investigate why UPLOAD_EXTRA_FILES is special and
|
||||
# remove it.
|
||||
if line.startswith(b'export ') or b'UPLOAD_EXTRA_FILES' in line
|
||||
]
|
||||
|
||||
mozconfig_client_mk = os.path.join(self.topobjdir,
|
||||
'.mozconfig-client-mk')
|
||||
with FileAvoidWrite(mozconfig_client_mk) as fh:
|
||||
for arg in mozconfig['make_extra'] or []:
|
||||
fh.write(arg)
|
||||
fh.write(b'\n')
|
||||
if mozconfig['make_flags']:
|
||||
fh.write(b'MOZ_MAKE_FLAGS=%s\n' % b' '.join(mozconfig['make_flags']))
|
||||
objdir = mozpath.normsep(self.topobjdir)
|
||||
fh.write(b'MOZ_OBJDIR=%s\n' % objdir)
|
||||
fh.write(b'OBJDIR=%s\n' % objdir)
|
||||
if mozconfig['path']:
|
||||
fh.write(b'FOUND_MOZCONFIG=%s\n' %
|
||||
mozpath.normsep(mozconfig['path']))
|
||||
fh.write(b'export FOUND_MOZCONFIG\n')
|
||||
fh.write(b'\n'.join(mozconfig_make_lines))
|
||||
|
||||
mozconfig_mk = os.path.join(self.topobjdir, '.mozconfig.mk')
|
||||
with FileAvoidWrite(mozconfig_mk) as fh:
|
||||
fh.write(b'\n'.join(mozconfig_filtered_lines))
|
||||
|
||||
mozconfig_json = os.path.join(self.topobjdir, '.mozconfig.json')
|
||||
with FileAvoidWrite(mozconfig_json) as fh:
|
||||
json.dump({
|
||||
'topsrcdir': self.topsrcdir,
|
||||
'topobjdir': self.topobjdir,
|
||||
'mozconfig': mozconfig,
|
||||
}, fh, sort_keys=True, indent=2)
|
||||
|
||||
# Copy the original mozconfig to the objdir.
|
||||
mozconfig_objdir = os.path.join(self.topobjdir, '.mozconfig')
|
||||
if mozconfig['path']:
|
||||
with open(mozconfig['path'], 'rb') as ifh:
|
||||
with FileAvoidWrite(mozconfig_objdir) as ofh:
|
||||
ofh.write(ifh.read())
|
||||
else:
|
||||
try:
|
||||
os.unlink(mozconfig_objdir)
|
||||
except OSError as e:
|
||||
if e.errno != errno.ENOENT:
|
||||
raise
|
||||
|
||||
if mozconfig_make_lines:
|
||||
self.log(logging.WARNING, 'mozconfig_content', {
|
||||
'path': mozconfig['path'],
|
||||
'content': '\n '.join(mozconfig_make_lines),
|
||||
}, 'Adding make options from {path}\n {content}')
|
||||
|
||||
append_env['OBJDIR'] = mozpath.normsep(self.topobjdir)
|
||||
|
||||
|
@ -161,7 +161,7 @@ let SyncedTabsInternal = {
|
||||
// Ask Sync to just do the tabs engine if it can.
|
||||
try {
|
||||
log.info("Doing a tab sync.");
|
||||
await Weave.Service.sync(["tabs"]);
|
||||
await Weave.Service.sync({why: "tabs", engines: ["tabs"]});
|
||||
return true;
|
||||
} catch (ex) {
|
||||
log.error("Sync failed", ex);
|
||||
|
@ -433,7 +433,7 @@ Sync11Service.prototype = {
|
||||
// Sync in the background (it's fine not to wait on the returned promise
|
||||
// because sync() has a lock).
|
||||
// [] = clients collection only
|
||||
this.sync([]).catch(e => {
|
||||
this.sync({why: "collection_changed", engines: []}).catch(e => {
|
||||
this._log.error(e);
|
||||
});
|
||||
}
|
||||
@ -1082,7 +1082,7 @@ Sync11Service.prototype = {
|
||||
return reason;
|
||||
},
|
||||
|
||||
async sync(engineNamesToSync) {
|
||||
async sync({engines, why} = {}) {
|
||||
let dateStr = Utils.formatTimestamp(new Date());
|
||||
this._log.debug("User-Agent: " + Utils.userAgent);
|
||||
this._log.info(`Starting sync at ${dateStr} in browser session ${browserSessionID}`);
|
||||
@ -1097,16 +1097,16 @@ Sync11Service.prototype = {
|
||||
} else {
|
||||
this._log.trace("In sync: no need to login.");
|
||||
}
|
||||
await this._lockedSync(engineNamesToSync);
|
||||
await this._lockedSync(engines, why);
|
||||
})();
|
||||
},
|
||||
|
||||
/**
|
||||
* Sync up engines with the server.
|
||||
*/
|
||||
async _lockedSync(engineNamesToSync) {
|
||||
async _lockedSync(engineNamesToSync, why) {
|
||||
return this._lock("service.js: sync",
|
||||
this._notify("sync", "", async function onNotify() {
|
||||
this._notify("sync", JSON.stringify({why}), async function onNotify() {
|
||||
|
||||
let histogram = Services.telemetry.getHistogramById("WEAVE_START_COUNT");
|
||||
histogram.add(1);
|
||||
|
@ -218,7 +218,7 @@ class EngineRecord {
|
||||
}
|
||||
|
||||
class TelemetryRecord {
|
||||
constructor(allowedEngines) {
|
||||
constructor(allowedEngines, why) {
|
||||
this.allowedEngines = allowedEngines;
|
||||
// Our failure reason. This property only exists in the generated ping if an
|
||||
// error actually occurred.
|
||||
@ -227,6 +227,7 @@ class TelemetryRecord {
|
||||
this.when = Date.now();
|
||||
this.startTime = tryGetMonotonicTimestamp();
|
||||
this.took = 0; // will be set later.
|
||||
this.why = why;
|
||||
|
||||
// All engines that have finished (ie, does not include the "current" one)
|
||||
// We omit this from the ping if it's empty.
|
||||
@ -243,6 +244,9 @@ class TelemetryRecord {
|
||||
status: this.status,
|
||||
devices: this.devices,
|
||||
};
|
||||
if (this.why) {
|
||||
result.why = this.why;
|
||||
}
|
||||
let engines = [];
|
||||
for (let engine of this.engines) {
|
||||
engines.push(engine.toJSON());
|
||||
@ -497,13 +501,14 @@ class SyncTelemetryImpl {
|
||||
}
|
||||
|
||||
|
||||
onSyncStarted() {
|
||||
onSyncStarted(data) {
|
||||
const why = data && JSON.parse(data).why;
|
||||
if (this.current) {
|
||||
log.warn("Observed weave:service:sync:start, but we're already recording a sync!");
|
||||
// Just discard the old record, consistent with our handling of engines, above.
|
||||
this.current = null;
|
||||
}
|
||||
this.current = new TelemetryRecord(this.allowedEngines);
|
||||
this.current = new TelemetryRecord(this.allowedEngines, why);
|
||||
}
|
||||
|
||||
_checkCurrent(topic) {
|
||||
@ -605,7 +610,7 @@ class SyncTelemetryImpl {
|
||||
|
||||
/* sync itself state changes */
|
||||
case "weave:service:sync:start":
|
||||
this.onSyncStarted();
|
||||
this.onSyncStarted(data);
|
||||
break;
|
||||
|
||||
case "weave:service:sync:finish":
|
||||
|
@ -53,7 +53,7 @@
|
||||
"service": { "type": "string" }
|
||||
}
|
||||
},
|
||||
"why": { "enum": ["startup", "schedule", "score", "user", "tabs"] },
|
||||
"why": { "type": "string" },
|
||||
"took": { "type": "integer", "minimum": -1 },
|
||||
"failureReason": { "$ref": "#/definitions/error" },
|
||||
"engines": {
|
||||
|
@ -394,7 +394,7 @@ add_task(async function test_bookmark_change_during_sync() {
|
||||
// because the bookmarks engine will automatically schedule a follow-up
|
||||
// sync for us.
|
||||
_("Perform first sync and immediate follow-up sync");
|
||||
Service.sync(["bookmarks"]);
|
||||
Service.sync({engines: ["bookmarks"]});
|
||||
|
||||
let pings = await pingsPromise;
|
||||
equal(pings.length, 2, "Should submit two pings");
|
||||
|
@ -90,7 +90,7 @@ add_task(async function test_noEngines() {
|
||||
|
||||
try {
|
||||
_("Sync with no engines specified.");
|
||||
await Service.sync([]);
|
||||
await Service.sync({engines: []});
|
||||
deepEqual(syncedEngines, [], "no engines were synced");
|
||||
|
||||
} finally {
|
||||
@ -108,7 +108,7 @@ add_task(async function test_oneEngine() {
|
||||
try {
|
||||
|
||||
_("Sync with 1 engine specified.");
|
||||
await Service.sync(["steam"]);
|
||||
await Service.sync({engines: ["steam"]});
|
||||
deepEqual(syncedEngines, ["steam"]);
|
||||
|
||||
} finally {
|
||||
@ -125,7 +125,7 @@ add_task(async function test_bothEnginesSpecified() {
|
||||
|
||||
try {
|
||||
_("Sync with both engines specified.");
|
||||
await Service.sync(["steam", "stirling"]);
|
||||
await Service.sync({engines: ["steam", "stirling"]});
|
||||
deepEqual(syncedEngines, ["steam", "stirling"]);
|
||||
|
||||
} finally {
|
||||
@ -142,7 +142,7 @@ add_task(async function test_bothEnginesSpecified() {
|
||||
|
||||
try {
|
||||
_("Sync with both engines specified.");
|
||||
await Service.sync(["stirling", "steam"]);
|
||||
await Service.sync({engines: ["stirling", "steam"]});
|
||||
deepEqual(syncedEngines, ["stirling", "steam"]);
|
||||
|
||||
} finally {
|
||||
|
@ -525,6 +525,29 @@ add_task(async function test_nserror() {
|
||||
}
|
||||
});
|
||||
|
||||
add_task(async function test_sync_why() {
|
||||
enableValidationPrefs();
|
||||
|
||||
await Service.engineManager.register(SteamEngine);
|
||||
let engine = Service.engineManager.get("steam");
|
||||
engine.enabled = true;
|
||||
let server = await serverForFoo(engine);
|
||||
await SyncTestingInfrastructure(server);
|
||||
let e = new Error("generic failure message");
|
||||
engine._errToThrow = e;
|
||||
|
||||
try {
|
||||
_(`test_generic_engine_fail: Steam tracker contents: ${
|
||||
JSON.stringify(engine._tracker.changedIDs)}`);
|
||||
let ping = await wait_for_ping(() => Service.sync({why: "user"}), true, false);
|
||||
_(JSON.stringify(ping))
|
||||
equal(ping.why, "user");
|
||||
} finally {
|
||||
await cleanAndGo(engine, server);
|
||||
Service.engineManager.unregister(engine);
|
||||
}
|
||||
});
|
||||
|
||||
add_task(async function test_discarding() {
|
||||
enableValidationPrefs();
|
||||
|
||||
|
1
servo/.gitignore
vendored
1
servo/.gitignore
vendored
@ -9,6 +9,7 @@
|
||||
/ports/android/obj
|
||||
/python/_virtualenv
|
||||
/python/tidy/servo_tidy.egg-info
|
||||
/tests/wpt/sync
|
||||
*~
|
||||
*.pkl
|
||||
*.pyc
|
||||
|
66
servo/Cargo.lock
generated
66
servo/Cargo.lock
generated
@ -297,8 +297,8 @@ dependencies = [
|
||||
"num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"offscreen_gl_context 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"servo_config 0.0.1",
|
||||
"webrender 0.53.1 (git+https://github.com/servo/webrender)",
|
||||
"webrender_api 0.53.1 (git+https://github.com/servo/webrender)",
|
||||
"webrender 0.53.2 (git+https://github.com/servo/webrender)",
|
||||
"webrender_api 0.53.2 (git+https://github.com/servo/webrender)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -315,7 +315,7 @@ dependencies = [
|
||||
"offscreen_gl_context 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"servo_config 0.0.1",
|
||||
"webrender_api 0.53.1 (git+https://github.com/servo/webrender)",
|
||||
"webrender_api 0.53.2 (git+https://github.com/servo/webrender)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -472,8 +472,8 @@ dependencies = [
|
||||
"servo_url 0.0.1",
|
||||
"style_traits 0.0.1",
|
||||
"time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"webrender 0.53.1 (git+https://github.com/servo/webrender)",
|
||||
"webrender_api 0.53.1 (git+https://github.com/servo/webrender)",
|
||||
"webrender 0.53.2 (git+https://github.com/servo/webrender)",
|
||||
"webrender_api 0.53.2 (git+https://github.com/servo/webrender)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -509,7 +509,7 @@ dependencies = [
|
||||
"servo_remutex 0.0.1",
|
||||
"servo_url 0.0.1",
|
||||
"style_traits 0.0.1",
|
||||
"webrender_api 0.53.1 (git+https://github.com/servo/webrender)",
|
||||
"webrender_api 0.53.2 (git+https://github.com/servo/webrender)",
|
||||
"webvr_traits 0.0.1",
|
||||
]
|
||||
|
||||
@ -802,7 +802,7 @@ dependencies = [
|
||||
"servo_geometry 0.0.1",
|
||||
"servo_url 0.0.1",
|
||||
"style_traits 0.0.1",
|
||||
"webrender_api 0.53.1 (git+https://github.com/servo/webrender)",
|
||||
"webrender_api 0.53.2 (git+https://github.com/servo/webrender)",
|
||||
"x11 2.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@ -1090,7 +1090,7 @@ dependencies = [
|
||||
"truetype 0.26.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-bidi 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-script 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"webrender_api 0.53.1 (git+https://github.com/servo/webrender)",
|
||||
"webrender_api 0.53.2 (git+https://github.com/servo/webrender)",
|
||||
"xi-unicode 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"xml5ever 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@ -1171,7 +1171,7 @@ dependencies = [
|
||||
"servo_url 0.0.1",
|
||||
"style_traits 0.0.1",
|
||||
"user32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"webrender_api 0.53.1 (git+https://github.com/servo/webrender)",
|
||||
"webrender_api 0.53.2 (git+https://github.com/servo/webrender)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"x11 2.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@ -1500,7 +1500,7 @@ dependencies = [
|
||||
"style_traits 0.0.1",
|
||||
"unicode-bidi 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-script 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"webrender_api 0.53.1 (git+https://github.com/servo/webrender)",
|
||||
"webrender_api 0.53.2 (git+https://github.com/servo/webrender)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1550,7 +1550,7 @@ dependencies = [
|
||||
"servo_url 0.0.1",
|
||||
"style 0.0.1",
|
||||
"style_traits 0.0.1",
|
||||
"webrender_api 0.53.1 (git+https://github.com/servo/webrender)",
|
||||
"webrender_api 0.53.2 (git+https://github.com/servo/webrender)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1565,7 +1565,7 @@ dependencies = [
|
||||
"profile_traits 0.0.1",
|
||||
"script_traits 0.0.1",
|
||||
"servo_url 0.0.1",
|
||||
"webrender_api 0.53.1 (git+https://github.com/servo/webrender)",
|
||||
"webrender_api 0.53.2 (git+https://github.com/servo/webrender)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1649,8 +1649,8 @@ dependencies = [
|
||||
"style 0.0.1",
|
||||
"style_traits 0.0.1",
|
||||
"webdriver_server 0.0.1",
|
||||
"webrender 0.53.1 (git+https://github.com/servo/webrender)",
|
||||
"webrender_api 0.53.1 (git+https://github.com/servo/webrender)",
|
||||
"webrender 0.53.2 (git+https://github.com/servo/webrender)",
|
||||
"webrender_api 0.53.2 (git+https://github.com/servo/webrender)",
|
||||
"webvr 0.0.1",
|
||||
"webvr_traits 0.0.1",
|
||||
]
|
||||
@ -1703,7 +1703,7 @@ dependencies = [
|
||||
"smallvec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"string_cache 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"webrender_api 0.53.1 (git+https://github.com/servo/webrender)",
|
||||
"webrender_api 0.53.2 (git+https://github.com/servo/webrender)",
|
||||
"xml5ever 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@ -1921,7 +1921,7 @@ dependencies = [
|
||||
"malloc_size_of_derive 0.0.1",
|
||||
"nonzero 0.0.1",
|
||||
"serde 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"webrender_api 0.53.1 (git+https://github.com/servo/webrender)",
|
||||
"webrender_api 0.53.2 (git+https://github.com/servo/webrender)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1970,7 +1970,7 @@ dependencies = [
|
||||
"profile_traits 0.0.1",
|
||||
"serde 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"servo-websocket 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"servo-websocket 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"servo_config 0.0.1",
|
||||
"servo_url 0.0.1",
|
||||
"threadpool 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -1979,7 +1979,7 @@ dependencies = [
|
||||
"unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"uuid 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"webrender_api 0.53.1 (git+https://github.com/servo/webrender)",
|
||||
"webrender_api 0.53.2 (git+https://github.com/servo/webrender)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2036,7 +2036,7 @@ dependencies = [
|
||||
"servo_url 0.0.1",
|
||||
"url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"uuid 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"webrender_api 0.53.1 (git+https://github.com/servo/webrender)",
|
||||
"webrender_api 0.53.2 (git+https://github.com/servo/webrender)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2659,7 +2659,7 @@ dependencies = [
|
||||
"url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"utf-8 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"uuid 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"webrender_api 0.53.1 (git+https://github.com/servo/webrender)",
|
||||
"webrender_api 0.53.2 (git+https://github.com/servo/webrender)",
|
||||
"webvr_traits 0.0.1",
|
||||
"xml5ever 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@ -2692,7 +2692,7 @@ dependencies = [
|
||||
"servo_atoms 0.0.1",
|
||||
"servo_url 0.0.1",
|
||||
"style 0.0.1",
|
||||
"webrender_api 0.53.1 (git+https://github.com/servo/webrender)",
|
||||
"webrender_api 0.53.2 (git+https://github.com/servo/webrender)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2736,7 +2736,7 @@ dependencies = [
|
||||
"style_traits 0.0.1",
|
||||
"time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"webrender_api 0.53.1 (git+https://github.com/servo/webrender)",
|
||||
"webrender_api 0.53.2 (git+https://github.com/servo/webrender)",
|
||||
"webvr_traits 0.0.1",
|
||||
]
|
||||
|
||||
@ -2933,10 +2933,10 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "servo-websocket"
|
||||
version = "0.19.1"
|
||||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"net2 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -3249,7 +3249,7 @@ dependencies = [
|
||||
"serde 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"servo_arc 0.0.1",
|
||||
"servo_atoms 0.0.1",
|
||||
"webrender_api 0.53.1 (git+https://github.com/servo/webrender)",
|
||||
"webrender_api 0.53.2 (git+https://github.com/servo/webrender)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3633,8 +3633,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "webrender"
|
||||
version = "0.53.1"
|
||||
source = "git+https://github.com/servo/webrender#30413c20684b4c8d82baf9e1296f9e10189c3591"
|
||||
version = "0.53.2"
|
||||
source = "git+https://github.com/servo/webrender#6dba5ed000b0c08e507390fff09ef4a134222cf0"
|
||||
dependencies = [
|
||||
"app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bincode 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -3655,13 +3655,13 @@ dependencies = [
|
||||
"rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"thread_profiler 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"webrender_api 0.53.1 (git+https://github.com/servo/webrender)",
|
||||
"webrender_api 0.53.2 (git+https://github.com/servo/webrender)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webrender_api"
|
||||
version = "0.53.1"
|
||||
source = "git+https://github.com/servo/webrender#30413c20684b4c8d82baf9e1296f9e10189c3591"
|
||||
version = "0.53.2"
|
||||
source = "git+https://github.com/servo/webrender#6dba5ed000b0c08e507390fff09ef4a134222cf0"
|
||||
dependencies = [
|
||||
"app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bincode 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -4042,7 +4042,7 @@ dependencies = [
|
||||
"checksum servo-freetype-sys 4.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9232032c2e85118c0282c6562c84cab12316e655491ba0a5d1905b2320060d1b"
|
||||
"checksum servo-glutin 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "91cdbc8014ea1171264622545b9b3d653f20336abb0e924682e98c951171fa58"
|
||||
"checksum servo-skia 0.30000007.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0abf282739e8b8e987f2b69736a0287a83b0f87189f53cc786a97bd2019e543d"
|
||||
"checksum servo-websocket 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8a1ff13c5d852c2793805226e688044309f2c1d8f063784805a13e99cb75b611"
|
||||
"checksum servo-websocket 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efde78dfcf2178d5a11e1e2268e0d8df0627dfe2724546db8585d6678e1af150"
|
||||
"checksum sha1 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cc30b1e1e8c40c121ca33b86c23308a090d19974ef001b4bf6e61fd1a0fb095c"
|
||||
"checksum shared_library 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fb04126b6fcfd2710fb5b6d18f4207b6c535f2850a7e1a43bcd526d44f30a79a"
|
||||
"checksum shell32-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "72f20b8f3c060374edb8046591ba28f62448c369ccbdc7b02075103fb3a9e38d"
|
||||
@ -4100,8 +4100,8 @@ dependencies = [
|
||||
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
||||
"checksum walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "bb08f9e670fab86099470b97cd2b252d6527f0b3cc1401acdb595ffc9dd288ff"
|
||||
"checksum webdriver 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d548aabf87411b1b4ba91fd07eacd8b238135c7131a452b8a9f6386209167e18"
|
||||
"checksum webrender 0.53.1 (git+https://github.com/servo/webrender)" = "<none>"
|
||||
"checksum webrender_api 0.53.1 (git+https://github.com/servo/webrender)" = "<none>"
|
||||
"checksum webrender 0.53.2 (git+https://github.com/servo/webrender)" = "<none>"
|
||||
"checksum webrender_api 0.53.2 (git+https://github.com/servo/webrender)" = "<none>"
|
||||
"checksum which 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4be6cfa54dab45266e98b5d7be2f8ce959ddd49abd141a05d52dce4b07f803bb"
|
||||
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
|
||||
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
|
||||
|
@ -34,7 +34,7 @@ serde = "1.0"
|
||||
serde_json = "1.0"
|
||||
servo_config = {path = "../config"}
|
||||
servo_url = {path = "../url"}
|
||||
servo-websocket = "0.19"
|
||||
servo-websocket = "0.20"
|
||||
threadpool = "1.0"
|
||||
time = "0.1.17"
|
||||
unicase = "1.4.0"
|
||||
|
8
servo/components/script/dom/test_mapping.json
Normal file
8
servo/components/script/dom/test_mapping.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"xmlhttprequest.rs": [
|
||||
"XMLHttpRequest"
|
||||
],
|
||||
"range.rs": [
|
||||
"dom/ranges"
|
||||
]
|
||||
}
|
@ -1418,7 +1418,7 @@ impl Window {
|
||||
Vector2D::new(0.0, 0.0)
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/cssom-view/#dom-element-scroll
|
||||
// https://drafts.csswg.org/cssom-view/#element-scrolling-members
|
||||
pub fn scroll_node(&self,
|
||||
node: &Node,
|
||||
x_: f64,
|
||||
|
@ -81,7 +81,7 @@ def write(directory, filename, content):
|
||||
def write_html(properties):
|
||||
properties = dict(
|
||||
(p.name, {
|
||||
"flag": p.experimental,
|
||||
"flag": p.servo_pref,
|
||||
"shorthand": hasattr(p, "sub_properties")
|
||||
})
|
||||
for p in properties.longhands + properties.shorthands
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user