зеркало из https://github.com/mozilla/gecko-dev.git
merge mozilla-inbound to mozilla-central a=merge
This commit is contained in:
Коммит
0ec3174fe6
|
@ -1091,22 +1091,50 @@ window.addEventListener('ContentStart', function update_onContentStart() {
|
|||
|
||||
updatePrompt.wrappedJSObject.handleContentStart(shell);
|
||||
});
|
||||
/* The "GPSChipOn" is to indicate that GPS engine is turned ON by the modem.
|
||||
During this GPS engine is turned ON by the modem, we make the location tracking icon visible to user.
|
||||
Once GPS engine is turned OFF, the location icon will disappear.
|
||||
If GPS engine is not turned ON by the modem or GPS location service is triggered,
|
||||
we let GPS service take over the control of showing the location tracking icon.
|
||||
The regular sequence of the geolocation-device-events is: starting-> GPSStarting-> shutdown-> GPSShutdown
|
||||
*/
|
||||
|
||||
|
||||
(function geolocationStatusTracker() {
|
||||
let gGeolocationActive = false;
|
||||
let GPSChipOn = false;
|
||||
|
||||
Services.obs.addObserver(function(aSubject, aTopic, aData) {
|
||||
let oldState = gGeolocationActive;
|
||||
if (aData == "starting") {
|
||||
gGeolocationActive = true;
|
||||
} else if (aData == "shutdown") {
|
||||
gGeolocationActive = false;
|
||||
let promptWarning = false;
|
||||
switch (aData) {
|
||||
case "GPSStarting":
|
||||
if (!gGeolocationActive) {
|
||||
gGeolocationActive = true;
|
||||
GPSChipOn = true;
|
||||
promptWarning = true;
|
||||
}
|
||||
break;
|
||||
case "GPSShutdown":
|
||||
if (GPSChipOn) {
|
||||
gGeolocationActive = false;
|
||||
GPSChipOn = false;
|
||||
}
|
||||
break;
|
||||
case "starting":
|
||||
gGeolocationActive = true;
|
||||
GPSChipOn = false;
|
||||
break;
|
||||
case "shutdown":
|
||||
gGeolocationActive = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (gGeolocationActive != oldState) {
|
||||
shell.sendChromeEvent({
|
||||
type: 'geolocation-status',
|
||||
active: gGeolocationActive
|
||||
active: gGeolocationActive,
|
||||
prompt: promptWarning
|
||||
});
|
||||
}
|
||||
}, "geolocation-device-events", false);
|
||||
|
|
|
@ -154,10 +154,14 @@ var SessionHistoryInternal = {
|
|||
if (shEntry.contentType)
|
||||
entry.contentType = shEntry.contentType;
|
||||
|
||||
let x = {}, y = {};
|
||||
shEntry.getScrollPosition(x, y);
|
||||
if (x.value != 0 || y.value != 0)
|
||||
entry.scroll = x.value + "," + y.value;
|
||||
if (shEntry.scrollRestorationIsManual) {
|
||||
entry.scrollRestorationIsManual = true;
|
||||
} else {
|
||||
let x = {}, y = {};
|
||||
shEntry.getScrollPosition(x, y);
|
||||
if (x.value != 0 || y.value != 0)
|
||||
entry.scroll = x.value + "," + y.value;
|
||||
}
|
||||
|
||||
// Collect owner data for the current history entry.
|
||||
try {
|
||||
|
@ -338,7 +342,9 @@ var SessionHistoryInternal = {
|
|||
entry.structuredCloneVersion);
|
||||
}
|
||||
|
||||
if (entry.scroll) {
|
||||
if (entry.scrollRestorationIsManual) {
|
||||
shEntry.scrollRestorationIsManual = true;
|
||||
} else if (entry.scroll) {
|
||||
var scrollPos = (entry.scroll || "0,0").split(",");
|
||||
scrollPos = [parseInt(scrollPos[0]) || 0, parseInt(scrollPos[1]) || 0];
|
||||
shEntry.setScrollPosition(scrollPos[0], scrollPos[1]);
|
||||
|
|
|
@ -100,10 +100,6 @@ dnl Picked from autoconf 2.13
|
|||
trap '' 1 2 15
|
||||
AC_CACHE_SAVE
|
||||
|
||||
test "x$prefix" = xNONE && prefix=$ac_default_prefix
|
||||
# Let make expand exec_prefix.
|
||||
test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
|
||||
|
||||
trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
|
||||
: ${CONFIG_STATUS=./config.status}
|
||||
|
||||
|
|
|
@ -15,6 +15,11 @@ define([_MOZ_AC_INIT_PREPARE], defn([AC_INIT_PREPARE]))
|
|||
define([AC_INIT_PREPARE],
|
||||
[_MOZ_AC_INIT_PREPARE($1)
|
||||
MOZ_CONFIG_LOG_TRAP
|
||||
|
||||
test "x$prefix" = xNONE && prefix=$ac_default_prefix
|
||||
# Let make expand exec_prefix.
|
||||
test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
|
||||
|
||||
> subconfigures
|
||||
> skip_subconfigures
|
||||
])
|
||||
|
|
|
@ -10043,9 +10043,11 @@ nsDocShell::InternalLoad(nsIURI* aURI,
|
|||
nsCOMPtr<nsIInputStream> postData;
|
||||
nsCOMPtr<nsISupports> cacheKey;
|
||||
|
||||
bool scrollRestorationIsManual = false;
|
||||
if (mOSHE) {
|
||||
/* save current position of scroller(s) (bug 59774) */
|
||||
mOSHE->SetScrollPosition(cx, cy);
|
||||
mOSHE->GetScrollRestorationIsManual(&scrollRestorationIsManual);
|
||||
// Get the postdata and page ident from the current page, if
|
||||
// the new load is being done via normal means. Note that
|
||||
// "normal means" can be checked for just by checking for
|
||||
|
@ -10060,6 +10062,11 @@ nsDocShell::InternalLoad(nsIURI* aURI,
|
|||
// cache data, since the two SHEntries correspond to the
|
||||
// same document.
|
||||
if (mLSHE) {
|
||||
if (!aSHEntry) {
|
||||
// If we're not doing a history load, scroll restoration
|
||||
// should be inherited from the previous session history entry.
|
||||
mLSHE->SetScrollRestorationIsManual(scrollRestorationIsManual);
|
||||
}
|
||||
mLSHE->AdoptBFCacheEntry(mOSHE);
|
||||
}
|
||||
}
|
||||
|
@ -10132,10 +10139,12 @@ nsDocShell::InternalLoad(nsIURI* aURI,
|
|||
/* restore previous position of scroller(s), if we're moving
|
||||
* back in history (bug 59774)
|
||||
*/
|
||||
nscoord bx, by;
|
||||
nscoord bx = 0;
|
||||
nscoord by = 0;
|
||||
bool needsScrollPosUpdate = false;
|
||||
if (mOSHE && (aLoadType == LOAD_HISTORY ||
|
||||
aLoadType == LOAD_RELOAD_NORMAL)) {
|
||||
aLoadType == LOAD_RELOAD_NORMAL) &&
|
||||
!scrollRestorationIsManual) {
|
||||
needsScrollPosUpdate = true;
|
||||
mOSHE->GetScrollPosition(&bx, &by);
|
||||
}
|
||||
|
@ -11624,6 +11633,9 @@ nsDocShell::AddState(JS::Handle<JS::Value> aData, const nsAString& aTitle,
|
|||
GetCurScrollPos(ScrollOrientation_Y, &cy);
|
||||
mOSHE->SetScrollPosition(cx, cy);
|
||||
|
||||
bool scrollRestorationIsManual = false;
|
||||
mOSHE->GetScrollRestorationIsManual(&scrollRestorationIsManual);
|
||||
|
||||
// Since we're not changing which page we have loaded, pass
|
||||
// true for aCloneChildren.
|
||||
rv = AddToSessionHistory(newURI, nullptr, nullptr, true,
|
||||
|
@ -11632,6 +11644,10 @@ nsDocShell::AddState(JS::Handle<JS::Value> aData, const nsAString& aTitle,
|
|||
|
||||
NS_ENSURE_TRUE(newSHEntry, NS_ERROR_FAILURE);
|
||||
|
||||
// Session history entries created by pushState inherit scroll restoration
|
||||
// mode from the current entry.
|
||||
newSHEntry->SetScrollRestorationIsManual(scrollRestorationIsManual);
|
||||
|
||||
// Link the new SHEntry to the old SHEntry's BFCache entry, since the
|
||||
// two entries correspond to the same document.
|
||||
NS_ENSURE_SUCCESS(newSHEntry->AdoptBFCacheEntry(oldOSHE), NS_ERROR_FAILURE);
|
||||
|
@ -11740,6 +11756,27 @@ nsDocShell::AddState(JS::Handle<JS::Value> aData, const nsAString& aTitle,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetCurrentScrollRestorationIsManual(bool* aIsManual)
|
||||
{
|
||||
*aIsManual = false;
|
||||
if (mOSHE) {
|
||||
mOSHE->GetScrollRestorationIsManual(aIsManual);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::SetCurrentScrollRestorationIsManual(bool aIsManual)
|
||||
{
|
||||
if (mOSHE) {
|
||||
mOSHE->SetScrollRestorationIsManual(aIsManual);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
nsDocShell::ShouldAddToSessionHistory(nsIURI* aURI)
|
||||
{
|
||||
|
@ -12140,10 +12177,21 @@ nsDocShell::PersistLayoutHistoryState()
|
|||
nsresult rv = NS_OK;
|
||||
|
||||
if (mOSHE) {
|
||||
bool scrollRestorationIsManual = false;
|
||||
mOSHE->GetScrollRestorationIsManual(&scrollRestorationIsManual);
|
||||
|
||||
nsCOMPtr<nsIPresShell> shell = GetPresShell();
|
||||
nsCOMPtr<nsILayoutHistoryState> layoutState;
|
||||
if (shell) {
|
||||
nsCOMPtr<nsILayoutHistoryState> layoutState;
|
||||
rv = shell->CaptureHistoryState(getter_AddRefs(layoutState));
|
||||
} else if (scrollRestorationIsManual) {
|
||||
// Even if we don't have layout anymore, we may want to reset the current
|
||||
// scroll state in layout history.
|
||||
GetLayoutHistoryState(getter_AddRefs(layoutState));
|
||||
}
|
||||
|
||||
if (scrollRestorationIsManual && layoutState) {
|
||||
layoutState->ResetScrollState();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ interface nsITabParent;
|
|||
|
||||
typedef unsigned long nsLoadFlags;
|
||||
|
||||
[scriptable, builtinclass, uuid(bc3524bd-023c-4fc8-ace1-472bc999fb12)]
|
||||
[scriptable, builtinclass, uuid(811aa3e1-7c4d-45ae-89da-ea1b107c60ed)]
|
||||
interface nsIDocShell : nsIDocShellTreeItem
|
||||
{
|
||||
/**
|
||||
|
@ -1090,4 +1090,10 @@ interface nsIDocShell : nsIDocShellTreeItem
|
|||
* top level chrome docshell.
|
||||
*/
|
||||
attribute boolean windowDraggingAllowed;
|
||||
|
||||
/**
|
||||
* Sets/gets the current scroll restoration mode.
|
||||
* @see https://html.spec.whatwg.org/#dom-history-scroll-restoration
|
||||
*/
|
||||
attribute boolean currentScrollRestorationIsManual;
|
||||
};
|
||||
|
|
|
@ -30,7 +30,7 @@ class nsSHEntryShared;
|
|||
[ptr] native nsDocShellEditorDataPtr(nsDocShellEditorData);
|
||||
[ptr] native nsSHEntryShared(nsSHEntryShared);
|
||||
|
||||
[scriptable, uuid(3a5e5fa0-5364-4fbb-a87a-3f12a6b51903)]
|
||||
[scriptable, uuid(0dad26b8-a259-42c7-93f1-2fa7fc076e45)]
|
||||
interface nsISHEntry : nsISupports
|
||||
{
|
||||
/**
|
||||
|
@ -301,6 +301,12 @@ interface nsISHEntry : nsISupports
|
|||
* for example with view-source.
|
||||
*/
|
||||
attribute nsIURI baseURI;
|
||||
|
||||
/**
|
||||
* Sets/gets the current scroll restoration state,
|
||||
* if true == "manual", false == "auto".
|
||||
*/
|
||||
attribute boolean scrollRestorationIsManual;
|
||||
};
|
||||
|
||||
[scriptable, uuid(bb66ac35-253b-471f-a317-3ece940f04c5)]
|
||||
|
|
|
@ -33,6 +33,7 @@ nsSHEntry::nsSHEntry()
|
|||
, mParent(nullptr)
|
||||
, mURIWasModified(false)
|
||||
, mIsSrcdocEntry(false)
|
||||
, mScrollRestorationIsManual(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -53,6 +54,7 @@ nsSHEntry::nsSHEntry(const nsSHEntry& aOther)
|
|||
, mURIWasModified(aOther.mURIWasModified)
|
||||
, mStateData(aOther.mStateData)
|
||||
, mIsSrcdocEntry(aOther.mIsSrcdocEntry)
|
||||
, mScrollRestorationIsManual(false)
|
||||
, mSrcdocData(aOther.mSrcdocData)
|
||||
, mBaseURI(aOther.mBaseURI)
|
||||
{
|
||||
|
@ -598,6 +600,20 @@ nsSHEntry::SetBaseURI(nsIURI* aBaseURI)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::GetScrollRestorationIsManual(bool* aIsManual)
|
||||
{
|
||||
*aIsManual = mScrollRestorationIsManual;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::SetScrollRestorationIsManual(bool aIsManual)
|
||||
{
|
||||
mScrollRestorationIsManual = aIsManual;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::GetChildCount(int32_t* aCount)
|
||||
{
|
||||
|
|
|
@ -64,6 +64,7 @@ private:
|
|||
bool mURIWasModified;
|
||||
nsCOMPtr<nsIStructuredCloneContainer> mStateData;
|
||||
bool mIsSrcdocEntry;
|
||||
bool mScrollRestorationIsManual;
|
||||
nsString mSrcdocData;
|
||||
nsCOMPtr<nsIURI> mBaseURI;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
<html>
|
||||
<head>
|
||||
<script>
|
||||
var oldHistoryObject = null;
|
||||
|
||||
function test(event) {
|
||||
if (!opener.scrollRestorationTest) {
|
||||
opener.scrollRestorationTest = 0;
|
||||
}
|
||||
++opener.scrollRestorationTest;
|
||||
|
||||
switch (opener.scrollRestorationTest) {
|
||||
case 1: {
|
||||
opener.is(event.persisted, false, "Shouldn't have persisted session history entry.");
|
||||
opener.ok(history.scrollRestoration, "History object has scrollRestoration property.");
|
||||
opener.ok(history.scrollRestoration, "auto", "history.scrollRestoration's default value should be 'auto'.");
|
||||
history.scrollRestoration = "foobar";
|
||||
opener.ok(history.scrollRestoration, "auto", "Invalid enum value should not change the value of an attribute.");
|
||||
history.scrollRestoration = "manual";
|
||||
opener.ok(history.scrollRestoration, "manual", "Valid enum value should change the value of an attribute.");
|
||||
history.scrollRestoration = "auto";
|
||||
opener.ok(history.scrollRestoration, "auto", "Valid enum value should change the value of an attribute.");
|
||||
document.getElementById("bottom").scrollIntoView();
|
||||
window.location.reload(false);
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
opener.is(event.persisted, false, "Shouldn't have persisted session history entry.");
|
||||
opener.isnot(window.scrollY, 0, "Should have restored scrolling.");
|
||||
opener.is(history.scrollRestoration, "auto", "Should have the same scrollRestoration as before reload.");
|
||||
history.scrollRestoration = "manual";
|
||||
window.onunload = function() {} // Disable bfcache.
|
||||
window.location.reload(false);
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
opener.is(event.persisted, false, "Shouldn't have persisted session history entry.");
|
||||
opener.is(window.scrollY, 0, "Should not have restored scrolling.");
|
||||
opener.is(history.scrollRestoration, "manual", "Should have the same scrollRestoration as before reload.");
|
||||
document.getElementById("bottom").scrollIntoView();
|
||||
window.onunload = null; // Should get bfcache behavior.
|
||||
opener.setTimeout("testWindow.history.back();", 250);
|
||||
window.location.href = 'data:text/html,';
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
opener.is(event.persisted, true, "Should have persisted session history entry.");
|
||||
opener.isnot(window.scrollY, 0, "Should have kept the old scroll position.");
|
||||
opener.is(history.scrollRestoration, "manual", "Should have the same scrollRestoration as before reload.");
|
||||
window.scrollTo(0, 0);
|
||||
window.location.hash = "hash";
|
||||
requestAnimationFrame(test);
|
||||
break;
|
||||
}
|
||||
case 5: {
|
||||
opener.isnot(window.scrollY, 0, "Should have scrolled to #hash.");
|
||||
opener.is(history.scrollRestoration, "manual", "Should have the same scrollRestoration mode as before fragment navigation.");
|
||||
window.onunload = function() {} // Disable bfcache.
|
||||
opener.setTimeout("is(testWindow.history.scrollRestoration, 'auto'); testWindow.history.back();", 250);
|
||||
window.location.href = 'data:text/html,';
|
||||
break;
|
||||
}
|
||||
case 6: {
|
||||
opener.is(event.persisted, false, "Shouldn't have persisted session history entry.");
|
||||
opener.is(window.scrollY, 0, "Shouldn't have kept the old scroll position.");
|
||||
opener.is(history.scrollRestoration, "manual", "Should have the same scrollRestoration mode as before fragment navigation.");
|
||||
history.scrollRestoration = "auto";
|
||||
document.getElementById("bottom").scrollIntoView();
|
||||
history.pushState({ state: "state1" }, "state1");
|
||||
history.pushState({ state: "state2" }, "state2");
|
||||
window.scrollTo(0, 0);
|
||||
history.back();
|
||||
opener.isnot(window.scrollY, 0, "Should have scrolled back to the state1's position");
|
||||
opener.is(history.state.state, "state1", "Unexpected state.");
|
||||
|
||||
history.scrollRestoration = "manual";
|
||||
document.getElementById("bottom").scrollIntoView();
|
||||
history.pushState({ state: "state3" }, "state3");
|
||||
history.pushState({ state: "state4" }, "state4");
|
||||
window.scrollTo(0, 0);
|
||||
history.back();
|
||||
opener.is(window.scrollY, 0, "Shouldn't have scrolled back to the state3's position");
|
||||
opener.is(history.state.state, "state3", "Unexpected state.");
|
||||
|
||||
var ifr = document.createElement("iframe");
|
||||
ifr.src = "data:text/html,";
|
||||
document.body.appendChild(ifr);
|
||||
ifr.onload = test;
|
||||
break;
|
||||
}
|
||||
case 7: {
|
||||
oldHistoryObject = event.target.contentWindow.history;
|
||||
event.target.src = "about:blank";
|
||||
break;
|
||||
}
|
||||
case 8: {
|
||||
try {
|
||||
var sr = oldHistoryObject.scrollRestoration;
|
||||
opener.ok(false, "Should have thrown an exception.");
|
||||
} catch(ex) {
|
||||
opener.isnot(ex, null, "Did get an exception");
|
||||
}
|
||||
try {
|
||||
oldHistoryObject.scrollRestoration = "auto";
|
||||
opener.ok(false, "Should have thrown an exception.");
|
||||
} catch(ex) {
|
||||
opener.isnot(ex, null, "Did get an exception");
|
||||
}
|
||||
opener.nextTest();
|
||||
window.close();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener("pageshow",
|
||||
function(e) {
|
||||
setTimeout(test, 0, e);
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div style="border: 1px solid black; height: 5000px;">
|
||||
</div>
|
||||
<div id="bottom">Hello world</div>
|
||||
<a href="#hash" name="hash">hash</a>
|
||||
</body>
|
||||
</html>
|
|
@ -10,6 +10,7 @@ support-files =
|
|||
file_document_write_1.html
|
||||
file_fragment_handling_during_load.html
|
||||
file_nested_frames.html
|
||||
file_scrollRestoration.html
|
||||
file_shiftReload_and_pushState.html
|
||||
file_static_and_dynamic_1.html
|
||||
frame0.html
|
||||
|
|
|
@ -29,7 +29,8 @@ var testFiles =
|
|||
"file_bug534178.html", // Session history transaction clean-up.
|
||||
"file_fragment_handling_during_load.html",
|
||||
"file_nested_frames.html",
|
||||
"file_shiftReload_and_pushState.html"
|
||||
"file_shiftReload_and_pushState.html",
|
||||
"file_scrollRestoration.html"
|
||||
];
|
||||
var testCount = 0; // Used by the test files.
|
||||
|
||||
|
|
|
@ -2016,6 +2016,11 @@ KeyframeEffectReadOnly::ShouldBlockCompositorAnimations(const nsIFrame*
|
|||
bool shouldLog = nsLayoutUtils::IsAnimationLoggingEnabled();
|
||||
|
||||
for (const AnimationProperty& property : mProperties) {
|
||||
// If a property is overridden in the CSS cascade, it should not block other
|
||||
// animations from running on the compositor.
|
||||
if (!property.mWinsInCascade) {
|
||||
continue;
|
||||
}
|
||||
// Check for geometric properties
|
||||
if (IsGeometricProperty(property.mProperty)) {
|
||||
if (shouldLog) {
|
||||
|
|
|
@ -20,6 +20,10 @@
|
|||
from { transform: rotate(0deg); }
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
@keyframes rotate_and_opacity {
|
||||
from { transform: rotate(0deg); opacity: 1;}
|
||||
to { transform: rotate(360deg); opacity: 0;}
|
||||
}
|
||||
div {
|
||||
/* Element needs geometry to be eligible for layerization */
|
||||
width: 100px;
|
||||
|
@ -265,5 +269,22 @@ promise_test(function(t) {
|
|||
}));
|
||||
}, 'isRunningOnCompositor for transitions');
|
||||
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t, { style: 'animation: rotate_and_opacity 100s; ' +
|
||||
'backface-visibility: hidden; ' +
|
||||
'transform: none !important;' });
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
return animation.ready.then(t.step_func(function() {
|
||||
assert_equals(animation.isRunningOnCompositor, omtaEnabled,
|
||||
'If an animation has a property that can run on the compositor and a '
|
||||
+ 'property that cannot (due to Gecko limitations) but where the latter'
|
||||
+ 'property is overridden in the CSS cascade, the animation should '
|
||||
+ 'still report that it is running on the compositor');
|
||||
}));
|
||||
}, 'isRunningOnCompositor is true when a property that would otherwise block ' +
|
||||
'running on the compositor is overridden in the CSS cascade');
|
||||
|
||||
</script>
|
||||
</script>
|
||||
</body>
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#include "nsHistory.h"
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "mozilla/dom/HistoryBinding.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsIDocument.h"
|
||||
|
@ -96,6 +95,38 @@ nsHistory::GetLength(ErrorResult& aRv) const
|
|||
return len >= 0 ? len : 0;
|
||||
}
|
||||
|
||||
ScrollRestoration
|
||||
nsHistory::GetScrollRestoration(mozilla::ErrorResult& aRv)
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mInnerWindow));
|
||||
if (!win || !win->HasActiveDocument() || !win->GetDocShell()) {
|
||||
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return mozilla::dom::ScrollRestoration::Auto;
|
||||
}
|
||||
|
||||
bool currentScrollRestorationIsManual = false;
|
||||
win->GetDocShell()->
|
||||
GetCurrentScrollRestorationIsManual(¤tScrollRestorationIsManual);
|
||||
return currentScrollRestorationIsManual ?
|
||||
mozilla::dom::ScrollRestoration::Manual :
|
||||
mozilla::dom::ScrollRestoration::Auto;
|
||||
}
|
||||
|
||||
void
|
||||
nsHistory::SetScrollRestoration(mozilla::dom::ScrollRestoration aMode,
|
||||
mozilla::ErrorResult& aRv)
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mInnerWindow));
|
||||
if (!win || !win->HasActiveDocument() || !win->GetDocShell()) {
|
||||
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
win->GetDocShell()->
|
||||
SetCurrentScrollRestorationIsManual(
|
||||
aMode == mozilla::dom::ScrollRestoration::Manual);
|
||||
}
|
||||
|
||||
void
|
||||
nsHistory::GetState(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
|
||||
ErrorResult& aRv) const
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/dom/HistoryBinding.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsIDOMHistory.h"
|
||||
|
@ -36,6 +37,9 @@ public:
|
|||
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
uint32_t GetLength(mozilla::ErrorResult& aRv) const;
|
||||
mozilla::dom::ScrollRestoration GetScrollRestoration(mozilla::ErrorResult& aRv);
|
||||
void SetScrollRestoration(mozilla::dom::ScrollRestoration aMode,
|
||||
mozilla::ErrorResult& aRv);
|
||||
void GetState(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
|
||||
mozilla::ErrorResult& aRv) const;
|
||||
void Go(int32_t aDelta, mozilla::ErrorResult& aRv);
|
||||
|
|
|
@ -153,30 +153,53 @@ GonkGPSGeolocationProvider::LocationCallback(GpsLocation* location)
|
|||
#endif
|
||||
}
|
||||
|
||||
class NotifyObserversGPSTask final : public nsRunnable
|
||||
{
|
||||
public:
|
||||
explicit NotifyObserversGPSTask(const char16_t* aData)
|
||||
: mData(aData)
|
||||
{}
|
||||
NS_IMETHOD Run() override {
|
||||
RefPtr<nsIGeolocationProvider> provider =
|
||||
GonkGPSGeolocationProvider::GetSingleton();
|
||||
nsCOMPtr<nsIObserverService> obsService = services::GetObserverService();
|
||||
obsService->NotifyObservers(provider, "geolocation-device-events", mData);
|
||||
return NS_OK;
|
||||
}
|
||||
private:
|
||||
const char16_t* mData;
|
||||
};
|
||||
|
||||
|
||||
|
||||
void
|
||||
GonkGPSGeolocationProvider::StatusCallback(GpsStatus* status)
|
||||
{
|
||||
if (gDebug_isLoggingEnabled) {
|
||||
switch (status->status) {
|
||||
case GPS_STATUS_NONE:
|
||||
nsContentUtils::LogMessageToConsole("geo: GPS_STATUS_NONE\n");
|
||||
break;
|
||||
case GPS_STATUS_SESSION_BEGIN:
|
||||
nsContentUtils::LogMessageToConsole("geo: GPS_STATUS_SESSION_BEGIN\n");
|
||||
break;
|
||||
case GPS_STATUS_SESSION_END:
|
||||
nsContentUtils::LogMessageToConsole("geo: GPS_STATUS_SESSION_END\n");
|
||||
break;
|
||||
case GPS_STATUS_ENGINE_ON:
|
||||
nsContentUtils::LogMessageToConsole("geo: GPS_STATUS_ENGINE_ON\n");
|
||||
break;
|
||||
case GPS_STATUS_ENGINE_OFF:
|
||||
nsContentUtils::LogMessageToConsole("geo: GPS_STATUS_ENGINE_OFF\n");
|
||||
break;
|
||||
default:
|
||||
nsContentUtils::LogMessageToConsole("geo: Unknown GPS status\n");
|
||||
break;
|
||||
}
|
||||
const char* msgStream=0;
|
||||
switch (status->status) {
|
||||
case GPS_STATUS_NONE:
|
||||
msgStream = "geo: GPS_STATUS_NONE\n";
|
||||
break;
|
||||
case GPS_STATUS_SESSION_BEGIN:
|
||||
msgStream = "geo: GPS_STATUS_SESSION_BEGIN\n";
|
||||
break;
|
||||
case GPS_STATUS_SESSION_END:
|
||||
msgStream = "geo: GPS_STATUS_SESSION_END\n";
|
||||
break;
|
||||
case GPS_STATUS_ENGINE_ON:
|
||||
msgStream = "geo: GPS_STATUS_ENGINE_ON\n";
|
||||
NS_DispatchToMainThread(new NotifyObserversGPSTask( MOZ_UTF16("GPSStarting")));
|
||||
break;
|
||||
case GPS_STATUS_ENGINE_OFF:
|
||||
msgStream = "geo: GPS_STATUS_ENGINE_OFF\n";
|
||||
NS_DispatchToMainThread(new NotifyObserversGPSTask( MOZ_UTF16("GPSShutdown")));
|
||||
break;
|
||||
default:
|
||||
msgStream = "geo: Unknown GPS status\n";
|
||||
break;
|
||||
}
|
||||
if (gDebug_isLoggingEnabled){
|
||||
nsContentUtils::LogMessageToConsole(msgStream);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,10 +11,14 @@
|
|||
* and create derivative works of this document.
|
||||
*/
|
||||
|
||||
enum ScrollRestoration { "auto", "manual" };
|
||||
|
||||
interface History {
|
||||
[Throws]
|
||||
readonly attribute unsigned long length;
|
||||
[Throws]
|
||||
attribute ScrollRestoration scrollRestoration;
|
||||
[Throws]
|
||||
readonly attribute any state;
|
||||
[Throws, UnsafeInPrerendering]
|
||||
void go(optional long delta = 0);
|
||||
|
|
|
@ -21,7 +21,7 @@ This introduced shadow layers and edit lists and was originally done for e10s v1
|
|||
|
||||
- 3d transforms (September 2011 - Bug 505115)
|
||||
|
||||
- OMTC (December 2012 - Bug 711168)
|
||||
- OMTC (December 2011 - Bug 711168)
|
||||
This was prototyped on OS X but shipped first for Fennec
|
||||
|
||||
- Tiling v1 (April 2012 - Bug 739679)
|
||||
|
@ -34,7 +34,12 @@ painting.
|
|||
- C++ Async pan zoom controller (July 2012 - Bug 750974)
|
||||
The existing APZ code was in Java for Fennec so this was reimplemented.
|
||||
|
||||
- Streaming WebGL Buffers (February 2013 - Bug 716859)
|
||||
Infrastructure to allow OMTC WebGL and avoid the need to glFinish() every
|
||||
frame.
|
||||
|
||||
- Compositor API (April 2013 - Bug 825928)
|
||||
The planing for this started around November 2012.
|
||||
Layers refactoring created a compositor API that abstracted away the differences between the
|
||||
D3D vs OpenGL. The main piece of API is DrawQuad.
|
||||
|
||||
|
@ -48,3 +53,8 @@ of the sync messages to the compositor.
|
|||
|
||||
The slow performance of allocating was directly addressed by bug 959089 which allowed us
|
||||
to allocate gralloc buffers without sync messages to the compositor thread.
|
||||
|
||||
- B2G WebGL performance (May 2014 - Bug 1006957, 1001417, 1024144)
|
||||
This work improved the synchronization mechanism between the compositor
|
||||
and the producer.
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "GeckoProfiler.h"
|
||||
#include "FrameUniformityData.h"
|
||||
#include "TreeTraversal.h"
|
||||
#include "VsyncSource.h"
|
||||
|
||||
struct nsCSSValueSharedList;
|
||||
|
||||
|
@ -1378,7 +1379,6 @@ AsyncCompositionManager::TransformShadowTree(TimeStamp aCurrentFrame,
|
|||
// code also includes Fennec which is rendered async. Fennec uses
|
||||
// its own platform-specific async rendering that is done partially
|
||||
// in Gecko and partially in Java.
|
||||
wantNextFrame |= SampleAPZAnimations(LayerMetricsWrapper(root), aCurrentFrame);
|
||||
bool foundRoot = false;
|
||||
Maybe<ParentLayerIntRect> clipDeferredFromChildren;
|
||||
if (ApplyAsyncContentTransformToTree(root, &foundRoot, clipDeferredFromChildren)) {
|
||||
|
@ -1402,6 +1402,15 @@ AsyncCompositionManager::TransformShadowTree(TimeStamp aCurrentFrame,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Advance APZ animations to the next expected vsync timestamp, if we can
|
||||
// get it.
|
||||
TimeStamp nextFrame = aCurrentFrame;
|
||||
TimeDuration vsyncrate = gfxPlatform::GetPlatform()->GetHardwareVsync()->GetGlobalDisplay().GetVsyncRate();
|
||||
if (vsyncrate != TimeDuration::Forever()) {
|
||||
nextFrame += vsyncrate;
|
||||
}
|
||||
wantNextFrame |= SampleAPZAnimations(LayerMetricsWrapper(root), nextFrame);
|
||||
}
|
||||
|
||||
LayerComposite* rootComposite = root->AsLayerComposite();
|
||||
|
|
|
@ -129,6 +129,7 @@ bool LaunchApp(const std::vector<std::string>& argv,
|
|||
break;
|
||||
case PROCESS_ARCH_PPC:
|
||||
cpu_types[0] = CPU_TYPE_POWERPC;
|
||||
break;
|
||||
default:
|
||||
cpu_types[0] = CPU_TYPE_ANY;
|
||||
break;
|
||||
|
|
|
@ -1330,6 +1330,8 @@ if test "$GNU_CXX"; then
|
|||
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wsign-compare"
|
||||
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wtype-limits"
|
||||
|
||||
MOZ_CXX_SUPPORTS_WARNING(-W, class-varargs, ac_cxx_has_wclass_varargs)
|
||||
|
||||
# Treat some warnings as errors if --enable-warnings-as-errors:
|
||||
if test "$MOZ_ENABLE_WARNINGS_AS_ERRORS"; then
|
||||
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=char-subscripts"
|
||||
|
|
|
@ -1036,7 +1036,7 @@ BacktrackingAllocator::tryMergeReusedRegister(VirtualRegister& def, VirtualRegis
|
|||
MOZ_ASSERT(!inputRange->hasUses());
|
||||
|
||||
JitSpew(JitSpew_RegAlloc, " splitting reused input at %u to try to help grouping",
|
||||
inputOf(def.ins()));
|
||||
inputOf(def.ins()).bits());
|
||||
|
||||
LiveBundle* firstBundle = inputRange->bundle();
|
||||
input.removeRange(inputRange);
|
||||
|
|
|
@ -165,7 +165,7 @@ SafepointWriter::writeGcSlots(LSafepoint* safepoint)
|
|||
|
||||
#ifdef JS_JITSPEW
|
||||
for (uint32_t i = 0; i < slots.length(); i++)
|
||||
JitSpew(JitSpew_Safepoints, " gc slot: %d", slots[i]);
|
||||
JitSpew(JitSpew_Safepoints, " gc slot: %u", slots[i].slot);
|
||||
#endif
|
||||
|
||||
MapSlotsToBitset(frameSlots_, argumentSlots_, stream_, slots);
|
||||
|
@ -195,7 +195,7 @@ SafepointWriter::writeValueSlots(LSafepoint* safepoint)
|
|||
|
||||
#ifdef JS_JITSPEW
|
||||
for (uint32_t i = 0; i < slots.length(); i++)
|
||||
JitSpew(JitSpew_Safepoints, " gc value: %d", slots[i]);
|
||||
JitSpew(JitSpew_Safepoints, " gc value: %u", slots[i].slot);
|
||||
#endif
|
||||
|
||||
MapSlotsToBitset(frameSlots_, argumentSlots_, stream_, slots);
|
||||
|
|
|
@ -126,7 +126,7 @@ AccessibleCaret::SetSelectionBarEnabled(bool aEnabled)
|
|||
return;
|
||||
}
|
||||
|
||||
AC_LOG("Set selection bar %s", __FUNCTION__, aEnabled ? "Enabled" : "Disabled");
|
||||
AC_LOG("Set selection bar %s", aEnabled ? "Enabled" : "Disabled");
|
||||
|
||||
ErrorResult rv;
|
||||
CaretElement()->ClassList()->Toggle(NS_LITERAL_STRING("no-bar"),
|
||||
|
|
|
@ -2084,6 +2084,11 @@ nsDocumentViewer::Hide(void)
|
|||
|
||||
nsCOMPtr<nsIDocShell> docShell(mContainer);
|
||||
if (docShell) {
|
||||
#ifdef DEBUG
|
||||
nsCOMPtr<nsIContentViewer> currentViewer;
|
||||
docShell->GetContentViewer(getter_AddRefs(currentViewer));
|
||||
MOZ_ASSERT(currentViewer == this);
|
||||
#endif
|
||||
nsCOMPtr<nsILayoutHistoryState> layoutState;
|
||||
mPresShell->CaptureHistoryState(getter_AddRefs(layoutState));
|
||||
}
|
||||
|
|
|
@ -18,8 +18,8 @@ class nsPresState;
|
|||
template<typename> struct already_AddRefed;
|
||||
|
||||
#define NS_ILAYOUTHISTORYSTATE_IID \
|
||||
{ 0x5208993e, 0xd812, 0x431e, \
|
||||
{ 0x95, 0x9c, 0xc3, 0x84, 0x5b, 0x6e, 0x5a, 0xce } }
|
||||
{ 0xaef27cb3, 0x4df9, 0x4eeb, \
|
||||
{ 0xb0, 0xb0, 0xac, 0x56, 0xcf, 0x86, 0x1d, 0x04 } }
|
||||
|
||||
class nsILayoutHistoryState : public nsISupports {
|
||||
public:
|
||||
|
@ -53,6 +53,11 @@ class nsILayoutHistoryState : public nsISupports {
|
|||
* or all possible history
|
||||
*/
|
||||
virtual void SetScrollPositionOnly(const bool aFlag) = 0;
|
||||
|
||||
/**
|
||||
* Resets nsPresState::GetScrollState of all nsPresState objects to 0,0.
|
||||
*/
|
||||
virtual void ResetScrollState() = 0;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsILayoutHistoryState,
|
||||
|
|
|
@ -170,6 +170,7 @@ PrintDisplayItemTo(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem,
|
|||
nsDisplayList* list = aItem->GetChildren();
|
||||
const DisplayItemClip& clip = aItem->GetClip();
|
||||
nsRegion opaque = aItem->GetOpaqueRegion(aBuilder, &snap);
|
||||
|
||||
#ifdef MOZ_DUMP_PAINTING
|
||||
if (aDumpHtml && aItem->Painted()) {
|
||||
nsCString string(aItem->Name());
|
||||
|
@ -178,6 +179,7 @@ PrintDisplayItemTo(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem,
|
|||
aStream << nsPrintfCString("<a href=\"javascript:ViewImage('%s')\">", string.BeginReading());
|
||||
}
|
||||
#endif
|
||||
|
||||
aStream << nsPrintfCString("%s p=0x%p f=0x%p(%s) %sbounds(%d,%d,%d,%d) layerBounds(%d,%d,%d,%d) visible(%d,%d,%d,%d) componentAlpha(%d,%d,%d,%d) clip(%s) scrollClip(%s)%s ref=0x%p agr=0x%p",
|
||||
aItem->Name(), aItem, (void*)f, NS_ConvertUTF16toUTF8(contentData).get(),
|
||||
(aItem->ZIndex() ? nsPrintfCString("z=%d ", aItem->ZIndex()).get() : ""),
|
||||
|
@ -188,7 +190,7 @@ PrintDisplayItemTo(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem,
|
|||
clip.ToString().get(),
|
||||
DisplayItemScrollClip::ToString(aItem->ScrollClip()).get(),
|
||||
aItem->IsUniform(aBuilder, &color) ? " uniform" : "",
|
||||
aItem->ReferenceFrame(), *aItem->GetAnimatedGeometryRoot());
|
||||
aItem->ReferenceFrame(), aItem->GetAnimatedGeometryRoot());
|
||||
|
||||
nsRegionRectIterator iter(opaque);
|
||||
for (const nsRect* r = iter.Next(); r; r = iter.Next()) {
|
||||
|
|
|
@ -36,7 +36,8 @@ public:
|
|||
HasStates() const override;
|
||||
virtual void
|
||||
SetScrollPositionOnly(const bool aFlag) override;
|
||||
|
||||
virtual void
|
||||
ResetScrollState() override;
|
||||
|
||||
private:
|
||||
~nsLayoutHistoryState() {}
|
||||
|
@ -94,3 +95,14 @@ nsLayoutHistoryState::SetScrollPositionOnly(const bool aFlag)
|
|||
{
|
||||
mScrollPositionOnly = aFlag;
|
||||
}
|
||||
|
||||
void
|
||||
nsLayoutHistoryState::ResetScrollState()
|
||||
{
|
||||
for (auto iter = mStates.Iter(); !iter.Done(); iter.Next()) {
|
||||
nsPresState* state = iter.UserData();
|
||||
if (state) {
|
||||
state->SetScrollState(nsPoint(0, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -423,7 +423,7 @@ nsContainerFrame::CreateViewForFrame(nsIFrame* aFrame,
|
|||
|
||||
NS_FRAME_LOG(NS_FRAME_TRACE_CALLS,
|
||||
("nsContainerFrame::CreateViewForFrame: frame=%p view=%p",
|
||||
aFrame));
|
||||
aFrame, view));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "mozilla/AsyncEventDispatcher.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/SizePrintfMacros.h"
|
||||
#include "mozilla/Snprintf.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "nsCORSListenerProxy.h"
|
||||
|
@ -792,7 +793,7 @@ FontFaceSet::UpdateRules(const nsTArray<nsFontFaceRuleContainer>& aRules)
|
|||
mUserFontSet->mLocalRulesUsed = false;
|
||||
|
||||
if (LOG_ENABLED() && !mRuleFaces.IsEmpty()) {
|
||||
LOG(("userfonts (%p) userfont rules update (%s) rule count: %d",
|
||||
LOG(("userfonts (%p) userfont rules update (%s) rule count: %" PRIuSIZE,
|
||||
mUserFontSet.get(),
|
||||
(modified ? "modified" : "not modified"),
|
||||
mRuleFaces.Length()));
|
||||
|
|
|
@ -1813,7 +1813,7 @@ Loader::SheetComplete(SheetLoadData* aLoadData, nsresult aStatus)
|
|||
SheetLoadData* data = datasToNotify[i];
|
||||
NS_ASSERTION(data && data->mMustNotify, "How did this data get here?");
|
||||
if (data->mObserver) {
|
||||
LOG((" Notifying observer 0x%x for data 0x%x. wasAlternate: %d",
|
||||
LOG((" Notifying observer %p for data %p. wasAlternate: %d",
|
||||
data->mObserver.get(), data, data->mWasAlternate));
|
||||
data->mObserver->StyleSheetLoaded(data->mSheet, data->mWasAlternate,
|
||||
aStatus);
|
||||
|
@ -1823,7 +1823,7 @@ Loader::SheetComplete(SheetLoadData* aLoadData, nsresult aStatus)
|
|||
nsCOMPtr<nsICSSLoaderObserver> obs;
|
||||
while (iter.HasMore()) {
|
||||
obs = iter.GetNext();
|
||||
LOG((" Notifying global observer 0x%x for data 0x%s. wasAlternate: %d",
|
||||
LOG((" Notifying global observer %p for data %p. wasAlternate: %d",
|
||||
obs.get(), data, data->mWasAlternate));
|
||||
obs->StyleSheetLoaded(data->mSheet, data->mWasAlternate, aStatus);
|
||||
}
|
||||
|
|
|
@ -869,6 +869,7 @@ void TransportLayerDtls::Handshake() {
|
|||
MOZ_MTLOG(ML_ERROR, LAYER_INFO << "Malformed DTLS message; ignoring");
|
||||
// If this were TLS (and not DTLS), this would be fatal, but
|
||||
// here we're required to ignore bad messages, so fall through
|
||||
MOZ_FALLTHROUGH;
|
||||
case PR_WOULD_BLOCK_ERROR:
|
||||
MOZ_MTLOG(ML_NOTICE, LAYER_INFO << "Handshake would have blocked");
|
||||
PRIntervalTime timeout;
|
||||
|
|
|
@ -756,10 +756,14 @@ SessionStore.prototype = {
|
|||
entry.contentType = aEntry.contentType;
|
||||
}
|
||||
|
||||
let x = {}, y = {};
|
||||
aEntry.getScrollPosition(x, y);
|
||||
if (x.value != 0 || y.value != 0) {
|
||||
entry.scroll = x.value + "," + y.value;
|
||||
if (aEntry.scrollRestorationIsManual) {
|
||||
entry.scrollRestorationIsManual = true;
|
||||
} else {
|
||||
let x = {}, y = {};
|
||||
aEntry.getScrollPosition(x, y);
|
||||
if (x.value != 0 || y.value != 0) {
|
||||
entry.scroll = x.value + "," + y.value;
|
||||
}
|
||||
}
|
||||
|
||||
if (aEntry.owner) {
|
||||
|
@ -862,7 +866,9 @@ SessionStore.prototype = {
|
|||
shEntry.stateData.initFromBase64(aEntry.structuredCloneState, aEntry.structuredCloneVersion);
|
||||
}
|
||||
|
||||
if (aEntry.scroll) {
|
||||
if (aEntry.scrollRestorationIsManual) {
|
||||
shEntry.scrollRestorationIsManual = true;
|
||||
} else if (aEntry.scroll) {
|
||||
let scrollPos = aEntry.scroll.split(",");
|
||||
scrollPos = [parseInt(scrollPos[0]) || 0, parseInt(scrollPos[1]) || 0];
|
||||
shEntry.setScrollPosition(scrollPos[0], scrollPos[1]);
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "nsAutoPtr.h"
|
||||
|
||||
#include "nsWindowsDllInterceptor.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/WindowsVersion.h"
|
||||
#include "nsWindowsHelpers.h"
|
||||
|
||||
|
@ -478,8 +479,8 @@ DllBlockSet::Write(HANDLE file)
|
|||
::LeaveCriticalSection(&sLock);
|
||||
}
|
||||
|
||||
static
|
||||
wchar_t* getFullPath (PWCHAR filePath, wchar_t* fname)
|
||||
static UniquePtr<wchar_t[]>
|
||||
getFullPath (PWCHAR filePath, wchar_t* fname)
|
||||
{
|
||||
// In Windows 8, the first parameter seems to be used for more than just the
|
||||
// path name. For example, its numerical value can be 1. Passing a non-valid
|
||||
|
@ -494,14 +495,14 @@ wchar_t* getFullPath (PWCHAR filePath, wchar_t* fname)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
wchar_t* full_fname = new wchar_t[pathlen+1];
|
||||
auto full_fname = MakeUnique<wchar_t[]>(pathlen+1);
|
||||
if (!full_fname) {
|
||||
// couldn't allocate memory?
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// now actually grab it
|
||||
SearchPathW(sanitizedFilePath, fname, L".dll", pathlen + 1, full_fname,
|
||||
SearchPathW(sanitizedFilePath, fname, L".dll", pathlen + 1, full_fname.get(),
|
||||
nullptr);
|
||||
return full_fname;
|
||||
}
|
||||
|
@ -529,7 +530,7 @@ patched_LdrLoadDll (PWCHAR filePath, PULONG flags, PUNICODE_STRING moduleFileNam
|
|||
|
||||
int len = moduleFileName->Length / 2;
|
||||
wchar_t *fname = moduleFileName->Buffer;
|
||||
nsAutoArrayPtr<wchar_t> full_fname;
|
||||
UniquePtr<wchar_t[]> full_fname;
|
||||
|
||||
// The filename isn't guaranteed to be null terminated, but in practice
|
||||
// it always will be; ensure that this is so, and bail if not.
|
||||
|
@ -652,23 +653,23 @@ patched_LdrLoadDll (PWCHAR filePath, PULONG flags, PUNICODE_STRING moduleFileNam
|
|||
}
|
||||
|
||||
if (info->flags & DllBlockInfo::USE_TIMESTAMP) {
|
||||
fVersion = GetTimestamp(full_fname);
|
||||
fVersion = GetTimestamp(full_fname.get());
|
||||
if (fVersion > info->maxVersion) {
|
||||
load_ok = true;
|
||||
}
|
||||
} else {
|
||||
DWORD zero;
|
||||
DWORD infoSize = GetFileVersionInfoSizeW(full_fname, &zero);
|
||||
DWORD infoSize = GetFileVersionInfoSizeW(full_fname.get(), &zero);
|
||||
|
||||
// If we failed to get the version information, we block.
|
||||
|
||||
if (infoSize != 0) {
|
||||
nsAutoArrayPtr<unsigned char> infoData(new unsigned char[infoSize]);
|
||||
auto infoData = MakeUnique<unsigned char[]>(infoSize);
|
||||
VS_FIXEDFILEINFO *vInfo;
|
||||
UINT vInfoLen;
|
||||
|
||||
if (GetFileVersionInfoW(full_fname, 0, infoSize, infoData) &&
|
||||
VerQueryValueW(infoData, L"\\", (LPVOID*) &vInfo, &vInfoLen))
|
||||
if (GetFileVersionInfoW(full_fname.get(), 0, infoSize, infoData.get()) &&
|
||||
VerQueryValueW(infoData.get(), L"\\", (LPVOID*) &vInfo, &vInfoLen))
|
||||
{
|
||||
fVersion =
|
||||
((unsigned long long)vInfo->dwFileVersionMS) << 32 |
|
||||
|
@ -704,7 +705,7 @@ continue_loading:
|
|||
return STATUS_DLL_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (IsVistaOrLater() && !CheckASLR(full_fname)) {
|
||||
if (IsVistaOrLater() && !CheckASLR(full_fname.get())) {
|
||||
printf_stderr("LdrLoadDll: Blocking load of '%s'. XPCOM components must support ASLR.\n", dllName);
|
||||
return STATUS_DLL_NOT_FOUND;
|
||||
}
|
||||
|
|
|
@ -21,46 +21,27 @@ using mozilla::dom::ContentParent;
|
|||
using mozilla::LogLevel;
|
||||
using mozilla::Unused;
|
||||
|
||||
#define kAPP NS_LITERAL_CSTRING("app")
|
||||
#define kGRE NS_LITERAL_CSTRING("gre")
|
||||
#define kAPP "app"
|
||||
#define kGRE "gre"
|
||||
|
||||
nsresult
|
||||
nsResProtocolHandler::Init()
|
||||
{
|
||||
nsresult rv;
|
||||
nsAutoCString appURI, greURI;
|
||||
rv = mozilla::Omnijar::GetURIString(mozilla::Omnijar::APP, appURI);
|
||||
rv = mozilla::Omnijar::GetURIString(mozilla::Omnijar::APP, mAppURI);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = mozilla::Omnijar::GetURIString(mozilla::Omnijar::GRE, greURI);
|
||||
rv = mozilla::Omnijar::GetURIString(mozilla::Omnijar::GRE, mGREURI);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
//
|
||||
// make resource:/// point to the application directory or omnijar
|
||||
//
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
rv = NS_NewURI(getter_AddRefs(uri), appURI.Length() ? appURI : greURI);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = SetSubstitution(EmptyCString(), uri);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
//
|
||||
// make resource://app/ point to the application directory or omnijar
|
||||
//
|
||||
rv = SetSubstitution(kAPP, uri);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
//
|
||||
// make resource://gre/ point to the GRE directory
|
||||
//
|
||||
if (appURI.Length()) { // We already have greURI in uri if appURI.Length() is 0.
|
||||
rv = NS_NewURI(getter_AddRefs(uri), greURI);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
// mozilla::Omnijar::GetURIString always returns a string ending with /,
|
||||
// and we want to remove it.
|
||||
mGREURI.Truncate(mGREURI.Length() - 1);
|
||||
if (mAppURI.Length()) {
|
||||
mAppURI.Truncate(mAppURI.Length() - 1);
|
||||
} else {
|
||||
mAppURI = mGREURI;
|
||||
}
|
||||
|
||||
rv = SetSubstitution(kGRE, uri);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
//XXXbsmedberg Neil wants a resource://pchrome/ for the profile chrome dir...
|
||||
// but once I finish multiple chrome registration I'm not sure that it is needed
|
||||
|
||||
|
@ -83,20 +64,36 @@ NS_IMPL_RELEASE_INHERITED(nsResProtocolHandler, SubstitutingProtocolHandler)
|
|||
nsresult
|
||||
nsResProtocolHandler::GetSubstitutionInternal(const nsACString& root, nsIURI **result)
|
||||
{
|
||||
// try invoking the directory service for "resource:root"
|
||||
nsAutoCString uri;
|
||||
|
||||
nsAutoCString key;
|
||||
key.AssignLiteral("resource:");
|
||||
key.Append(root);
|
||||
|
||||
nsCOMPtr<nsIFile> file;
|
||||
nsresult rv = NS_GetSpecialDirectory(key.get(), getter_AddRefs(file));
|
||||
if (NS_FAILED(rv))
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
rv = IOService()->NewFileURI(file, result);
|
||||
if (NS_FAILED(rv))
|
||||
if (!ResolveSpecialCases(root, NS_LITERAL_CSTRING("/"), uri)) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
return NS_NewURI(result, uri);
|
||||
}
|
||||
|
||||
bool
|
||||
nsResProtocolHandler::ResolveSpecialCases(const nsACString& aHost,
|
||||
const nsACString& aPath,
|
||||
nsACString& aResult)
|
||||
{
|
||||
if (aHost.Equals("") || aHost.Equals(kAPP)) {
|
||||
aResult.Assign(mAppURI);
|
||||
} else if (aHost.Equals(kGRE)) {
|
||||
aResult.Assign(mGREURI);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
aResult.Append(aPath);
|
||||
return true;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsResProtocolHandler::SetSubstitution(const nsACString& aRoot, nsIURI* aBaseURI)
|
||||
{
|
||||
MOZ_ASSERT(!aRoot.Equals(""));
|
||||
MOZ_ASSERT(!aRoot.Equals(kAPP));
|
||||
MOZ_ASSERT(!aRoot.Equals(kGRE));
|
||||
return SubstitutingProtocolHandler::SetSubstitution(aRoot, aBaseURI);
|
||||
}
|
||||
|
|
|
@ -23,7 +23,6 @@ public:
|
|||
NS_DECL_NSIRESPROTOCOLHANDLER
|
||||
|
||||
NS_FORWARD_NSIPROTOCOLHANDLER(mozilla::SubstitutingProtocolHandler::)
|
||||
NS_FORWARD_NSISUBSTITUTINGPROTOCOLHANDLER(mozilla::SubstitutingProtocolHandler::)
|
||||
|
||||
nsResProtocolHandler()
|
||||
: SubstitutingProtocolHandler("resource", URI_STD | URI_IS_UI_RESOURCE | URI_IS_LOCAL_RESOURCE,
|
||||
|
@ -32,9 +31,33 @@ public:
|
|||
|
||||
nsresult Init();
|
||||
|
||||
NS_IMETHOD SetSubstitution(const nsACString& aRoot, nsIURI* aBaseURI) override;
|
||||
|
||||
NS_IMETHOD GetSubstitution(const nsACString& aRoot, nsIURI** aResult) override
|
||||
{
|
||||
return mozilla::SubstitutingProtocolHandler::GetSubstitution(aRoot, aResult);
|
||||
}
|
||||
|
||||
NS_IMETHOD HasSubstitution(const nsACString& aRoot, bool* aResult) override
|
||||
{
|
||||
return mozilla::SubstitutingProtocolHandler::HasSubstitution(aRoot, aResult);
|
||||
}
|
||||
|
||||
NS_IMETHOD ResolveURI(nsIURI *aResURI, nsACString& aResult) override
|
||||
{
|
||||
return mozilla::SubstitutingProtocolHandler::ResolveURI(aResURI, aResult);
|
||||
}
|
||||
|
||||
protected:
|
||||
nsresult GetSubstitutionInternal(const nsACString& aRoot, nsIURI** aResult) override;
|
||||
virtual ~nsResProtocolHandler() {}
|
||||
|
||||
bool ResolveSpecialCases(const nsACString& aHost, const nsACString& aPath,
|
||||
nsACString& aResult) override;
|
||||
|
||||
private:
|
||||
nsCString mAppURI;
|
||||
nsCString mGREURI;
|
||||
};
|
||||
|
||||
#endif /* nsResProtocolHandler_h___ */
|
||||
|
|
|
@ -5083,7 +5083,7 @@ nsWindow::ProcessMessage(UINT msg, WPARAM& wParam, LPARAM& lParam,
|
|||
case WM_MOUSEMOVE:
|
||||
{
|
||||
if (!mMousePresent) {
|
||||
// First MOOUSEMOVE over the client area. Ask for MOUSELEAVE
|
||||
// First MOUSEMOVE over the client area. Ask for MOUSELEAVE
|
||||
TRACKMOUSEEVENT mTrack;
|
||||
mTrack.cbSize = sizeof(TRACKMOUSEEVENT);
|
||||
mTrack.dwFlags = TME_LEAVE;
|
||||
|
|
Загрузка…
Ссылка в новой задаче