Files
palemoon27/dom/base/nsHistory.cpp
T
roytam1 01cb9ab79e import changes from `dev' branch of rmottola/Arctic-Fox:
- Bug 1233497 - Fix infrastructure for disallowing unsafe CPOWs in browser code. r=mrbkap (d8c6be9ef0)
- Bug 1235615 - Split JS::CompartmentOptions into JS::CompartmentCreationOptions that are immutable characteristics of a compartment, and JS::CompartmentBehaviors that may be changed after the compartment's been created. r=terrence (d664435b2c)
- Bug 1245801 - Disable non-standard flag argument of String.prototype. {search,match,replace} in non-release channel. r=jandem (2e41d087e4)
- Bug 1207922 - Part 1: Self-host RegExp.prototype.{exec,test}. r=till,h4writer (21dddac0e3)
- Bug 1207922 - Part 2: Propagate OOM thrown from stub generation. r=till (507c3fc5e0)
- Bug 1207922 - Part 3: Add masm.branchLatin1String and masm.branchTwoByteString. r=h4writer (59f56d60d8)
- Bug 1207922 - Clean-up RRegExp{Match,Test}er function in Recover.cpp. r=arai (fd4f0e4744)
- Bug 1226904 - Fix boundary checking for leaves collecting. r=roc (0736fec30c)
- Bug 1222880 - Followup to handle the case when aStopAtAnimatedGeometryRoot isn't an ancestor of aAnimatedGeometryRoot. CLOSED TREE (648d12bbcb)
- Bug 1222880. Followup to the followup to handle the case when aStopAtAnimatedGeometryRoot isn't an ancestor of aAnimatedGeometryRoot the same way we did before the patches of this bug. r=mattwoordrow (more or less) (e4ce4414ef)
- Bug 1200611 - Size ImageLayers correctly for <img>s using object-fit. r=dholbert (cc3b82a126)
- Bug 1232852 (part 1) - Set |aSnap| in two GetOpaqueRegion() overloadings that are missing it. r=roc. (114660bbbe)
- Bug 1232852 (part 2) - Remove some dead member functions from nsILayoutDebugger. r=roc. (b9eb5ca6b4)
- Bug 1233605 - Cull some uses of gfxContext. r=dholbert. (2ae4a1d390)
- Bug 1059519. Relax assertion. r=mstange (79a1f08992)
- Bug 1176395 - When an element is both position:sticky and transformed, apply the position:sticky outside the transform. r=roc (b2d86a714b)
- Bug 1147673 - Use ancestor clip for root scrollable framemetrics clips. r=tn (6fd10a0ea3)
- Bug 1187804 - Reftests for async scrolling with position:fixed in an iframe. r=kats (2e30186596)
- Bug 1223944 - Reftest bg-fixed-transformed-image-ref.html fails for Fennec when C++APZ enabled. r=kats (99bfa3344b)
- Bug 1208829 - Reftest. r=mstange (e35a18d12a)
- Bug 1224209. Add reftest. (acfd2fba9d)
- Bug 1201889 - Reftest. r=mstange (ec4b26fbd2)
- Bug 1208829 - Another reftest. r=botond (558ca3cdbc)
- Bug 1147673 - Make display items know about their scroll clips. r=tn, r=roc (3485c3fada)
- Bug 1152049 - Rename GetClippedBoundsUpTo into GetScrollClippedBoundsUpTo. r=tn (aeeaf3bcdb)
- Bug 1232852 (part 3) - Remove unused parameters from some accessibility code. r=tbsaunde. (97041bf561)
- Bug 1232852 (part 4) - Remove some unused parameters in and around layout/base/. r=heycam. (2dcf169efa)
- Bug 1232852 (part 5) - Remove some unused parameters in and around layout/base/. r=heycam. (9a302428f1)
- Bug 1232852 (part 6) - Remove unused parameters from some layout sort functions. r=tn. (26faa2c71f)
- Bug 1232852 (part 7) - Remove some unused parameters in and around layout/base/. r=tn. (6f9417aa0b)
- Bug 1232852 (part 8) - Remove some unused parameters in and around layout/base/. r=roc. (30315134c4)
- Bug 1186774 - Scroll position (scrollX/scrollY) should be restored after popstate, not before, r=bz (3d8cd617ce)
- Bug 1155730, implement History.scrollRestoration r=jst (4e0ffb69a9)
- Bug 1237075 - Navigating from 'manual' to 'auto' session history entry should scroll the page, r=jst (d8eb9296bf)
- Bug 1228229 part 2 - Add a helper to get the appropriate (pseudo-)element for a frame; r=dbaron (2a8b5bdc95)
- Bug 1228229 part 3 - Factor out a method to get compositor-animatable overridden properties; r=dbaron (0e5fef1fc9)
- Bug 1228229 part 4 - Add a flag to EffectSet to mark when the cascade needs to be updated; r=dbaron (206e42236e)
- Bug 1228229 part 5 - Separate target element registration in NotifyAnimationTimingUpdated; r=dbaron (fe4b799d14)
- Bug 1228229 part 6 - Mark the animation cascade results as dirty when an effect goes in or out of being "in effect"; r=dbaron (6be413b655)
- Bug 1228229 part 7 - Add a method to Animation to indicate if it applies to the transitions level of the cascade; r=dbaron (d1845e299b)
- Bug 1228229 part 8 - Add EffectCompositor::(Maybe)UpdateCascadeResults; r=dbaron (dfdd0b9822)
- Bug 1228229 part 9 - Use EffectCompositor::UpdateCascadeResults; r=dbaron (917ec2023c)
- Bug 1228229 part 10 - Remove no-longer-used cascade functions; r=dbaron (3dc6662f3a)
- Bug 1228229 part 11 - Avoid calling nsRuleNode::ComputePropertiesOverridingAnimation when there are no compositor-animatable properties; r=dbaron (9b90a1d9a6)
- Bug 1229662 (part 1) - Remove AzureState::clipWasReset. r=jrmuizel. (ce48b700f7)
- Bug 1229662 (part 2) - Remove AzureState::parentTarget. r=jrmuizel. (95713803b1)
- Bug 1229662 (part 3) - Remove AzureState::fillRule. r=jrmuizel. (e1f936af7d)
- part of Bug 1232576 (part 1) - Move the reference |cairo_t*| from gfxContext (e81dd09541)
- part of  Bug 1232576 (part 2) - Rename gfxContext::GetCairo() as GetRefCairo() (82538c1451)
- Bug 1232822 (part 1) - Moz2Dify SetupCairoFont(). r=jfkthame. (ef6b1e99b3)
- Bug 1232822 (part 2) - Moz2Dify SetupGlyphExtents(). r=jfkthame. (9ed9a03559)
- Bug 1232822 (part 3) - Moz2Dify gfxFont::CalcXScale() and gfxFont::PostShapingFixup(). r=jfkthame. (60f5f49df8)
- Bug 1232822 (part 4) - Remove unused argument from SetPotentialLineBreaks(). r=jfkthame. (7fb087a26b)
- Bug 1232822 (part 5) - Moz2Dify GetRoundOffsetsToPixels(). r=jfkthame. (4055a07cba)
- Bug 1232822 (part 6) - Move RefCairo() from gfxContext to gfxFont. r=jfkthame. (c5d2db8eab)
- Bug 1235185 - Fix clang -Wclass-varargs warnings in js/. r=bhackett (43fc9c0b1c)
- Bug 1232772 - suppress numerous clang-style warnings when using clang-cl; r=glandium (c26dab4483)
- Bug 1204752 - Disable thread-safe statics on VS2015 to fix WinXP startup crash. r=glandium (59c67ca7ba)
- Bug 1235743 - Move compiler flags used for dependency generation to a separate variable. r=gps (649853408e)
- Bug 1232159 followup, test for the existence of TypedObject so the test doesn't fail when it hits mozilla-aurora, r=efaust (c87a681a64)
2023-07-31 14:29:48 +08:00

358 lines
8.9 KiB
C++

/* -*- 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/. */
#include "nsHistory.h"
#include "jsapi.h"
#include "nsCOMPtr.h"
#include "nsPIDOMWindow.h"
#include "nsIDocument.h"
#include "nsIPresShell.h"
#include "nsPresContext.h"
#include "nsIDocShell.h"
#include "nsIWebNavigation.h"
#include "nsIURI.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsReadableUtils.h"
#include "nsContentUtils.h"
#include "nsISHistory.h"
#include "nsISHistoryInternal.h"
#include "mozilla/Preferences.h"
using namespace mozilla;
using namespace mozilla::dom;
static const char* sAllowPushStatePrefStr =
"browser.history.allowPushState";
static const char* sAllowReplaceStatePrefStr =
"browser.history.allowReplaceState";
//
// History class implementation
//
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(nsHistory)
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsHistory)
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsHistory)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsHistory)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_ENTRY(nsIDOMHistory) // Empty, needed for extension compat
NS_INTERFACE_MAP_END
nsHistory::nsHistory(nsPIDOMWindow* aInnerWindow)
: mInnerWindow(do_GetWeakReference(aInnerWindow))
{
MOZ_ASSERT(aInnerWindow->IsInnerWindow());
}
nsHistory::~nsHistory()
{
}
nsPIDOMWindow*
nsHistory::GetParentObject() const
{
nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mInnerWindow));
return win;
}
JSObject*
nsHistory::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
{
return HistoryBinding::Wrap(aCx, this, aGivenProto);
}
uint32_t
nsHistory::GetLength(ErrorResult& aRv) const
{
nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mInnerWindow));
if (!win || !win->HasActiveDocument()) {
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return 0;
}
// Get session History from docshell
nsCOMPtr<nsISHistory> sHistory = GetSessionHistory();
if (!sHistory) {
aRv.Throw(NS_ERROR_FAILURE);
return 0;
}
int32_t len;
nsresult rv = sHistory->GetCount(&len);
if (NS_FAILED(rv)) {
aRv.Throw(rv);
return 0;
}
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(&currentScrollRestorationIsManual);
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
{
nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mInnerWindow));
if (!win) {
aRv.Throw(NS_ERROR_NOT_AVAILABLE);
return;
}
if (!win->HasActiveDocument()) {
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return;
}
nsCOMPtr<nsIDocument> doc =
do_QueryInterface(win->GetExtantDoc());
if (!doc) {
aRv.Throw(NS_ERROR_NOT_AVAILABLE);
return;
}
nsCOMPtr<nsIVariant> variant;
doc->GetStateObject(getter_AddRefs(variant));
if (variant) {
aRv = variant->GetAsJSVal(aResult);
if (aRv.Failed()) {
return;
}
if (!JS_WrapValue(aCx, aResult)) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
}
return;
}
aResult.setNull();
}
void
nsHistory::Go(int32_t aDelta, ErrorResult& aRv)
{
nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mInnerWindow));
if (!win || !win->HasActiveDocument()) {
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return;
}
if (!aDelta) {
nsCOMPtr<nsPIDOMWindow> window;
if (nsIDocShell* docShell = GetDocShell()) {
window = docShell->GetWindow();
}
if (window && window->IsHandlingResizeEvent()) {
// history.go(0) (aka location.reload()) was called on a window
// that is handling a resize event. Sites do this since Netscape
// 4.x needed it, but we don't, and it's a horrible experience
// for nothing. In stead of reloading the page, just clear
// style data and reflow the page since some sites may use this
// trick to work around gecko reflow bugs, and this should have
// the same effect.
nsCOMPtr<nsIDocument> doc = window->GetExtantDoc();
nsIPresShell *shell;
nsPresContext *pcx;
if (doc && (shell = doc->GetShell()) && (pcx = shell->GetPresContext())) {
pcx->RebuildAllStyleData(NS_STYLE_HINT_REFLOW, eRestyle_Subtree);
}
return;
}
}
nsCOMPtr<nsISHistory> session_history = GetSessionHistory();
nsCOMPtr<nsIWebNavigation> webnav(do_QueryInterface(session_history));
if (!webnav) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
int32_t curIndex = -1;
int32_t len = 0;
session_history->GetIndex(&curIndex);
session_history->GetCount(&len);
int32_t index = curIndex + aDelta;
if (index > -1 && index < len)
webnav->GotoIndex(index);
// Ignore the return value from GotoIndex(), since returning errors
// from GotoIndex() can lead to exceptions and a possible leak
// of history length
}
void
nsHistory::Back(ErrorResult& aRv)
{
nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mInnerWindow));
if (!win || !win->HasActiveDocument()) {
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return;
}
nsCOMPtr<nsISHistory> sHistory = GetSessionHistory();
nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(sHistory));
if (!webNav) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
webNav->GoBack();
}
void
nsHistory::Forward(ErrorResult& aRv)
{
nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mInnerWindow));
if (!win || !win->HasActiveDocument()) {
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return;
}
nsCOMPtr<nsISHistory> sHistory = GetSessionHistory();
nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(sHistory));
if (!webNav) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
webNav->GoForward();
}
void
nsHistory::PushState(JSContext* aCx, JS::Handle<JS::Value> aData,
const nsAString& aTitle, const nsAString& aUrl,
ErrorResult& aRv)
{
PushOrReplaceState(aCx, aData, aTitle, aUrl, aRv, false);
}
void
nsHistory::ReplaceState(JSContext* aCx, JS::Handle<JS::Value> aData,
const nsAString& aTitle, const nsAString& aUrl,
ErrorResult& aRv)
{
PushOrReplaceState(aCx, aData, aTitle, aUrl, aRv, true);
}
void
nsHistory::PushOrReplaceState(JSContext* aCx, JS::Handle<JS::Value> aData,
const nsAString& aTitle, const nsAString& aUrl,
ErrorResult& aRv, bool aReplace)
{
nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mInnerWindow));
if (!win) {
aRv.Throw(NS_ERROR_NOT_AVAILABLE);
return;
}
if (!win->HasActiveDocument()) {
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return;
}
// Check that PushState hasn't been pref'ed off.
if (!Preferences::GetBool(aReplace ? sAllowReplaceStatePrefStr :
sAllowPushStatePrefStr, false)) {
return;
}
// AddState might run scripts, so we need to hold a strong reference to the
// docShell here to keep it from going away.
nsCOMPtr<nsIDocShell> docShell = win->GetDocShell();
if (!docShell) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
// The "replace" argument tells the docshell to whether to add a new
// history entry or modify the current one.
aRv = docShell->AddState(aData, aTitle, aUrl, aReplace, aCx);
}
nsIDocShell*
nsHistory::GetDocShell() const
{
nsCOMPtr<nsPIDOMWindow> win = do_QueryReferent(mInnerWindow);
if (!win) {
return nullptr;
}
return win->GetDocShell();
}
already_AddRefed<nsISHistory>
nsHistory::GetSessionHistory() const
{
nsIDocShell *docShell = GetDocShell();
NS_ENSURE_TRUE(docShell, nullptr);
// Get the root DocShell from it
nsCOMPtr<nsIDocShellTreeItem> root;
docShell->GetSameTypeRootTreeItem(getter_AddRefs(root));
nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(root));
NS_ENSURE_TRUE(webNav, nullptr);
nsCOMPtr<nsISHistory> shistory;
// Get SH from nsIWebNavigation
webNav->GetSessionHistory(getter_AddRefs(shistory));
return shistory.forget();
}