import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo

This commit is contained in:
Roy Tam 2018-01-19 03:59:58 +08:00
commit dcd9973243
150858 changed files with 23884658 additions and 0 deletions

144
docshell/base/IHistory.h Normal file
View file

@ -0,0 +1,144 @@
/* -*- 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_IHistory_h_
#define mozilla_IHistory_h_
#include "nsISupports.h"
class nsIURI;
namespace mozilla {
namespace dom {
class Link;
} // namespace dom
// 0057c9d3-b98e-4933-bdc5-0275d06705e1
#define IHISTORY_IID \
{0x0057c9d3, 0xb98e, 0x4933, {0xbd, 0xc5, 0x02, 0x75, 0xd0, 0x67, 0x05, 0xe1}}
class IHistory : public nsISupports
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(IHISTORY_IID)
/**
* Registers the Link for notifications about the visited-ness of aURI.
* Consumers should assume that the URI is unvisited after calling this, and
* they will be notified if that state (unvisited) changes by having
* SetLinkState called on themselves. This function is guaranteed to run to
* completion before aLink is notified. After the node is notified, it will
* be unregistered.
*
* @note SetLinkState must not call RegisterVisitedCallback or
* UnregisterVisitedCallback.
*
* @pre aURI must not be null.
* @pre aLink may be null only in the parent (chrome) process.
*
* @param aURI
* The URI to check.
* @param aLink
* The link to update whenever the history status changes. The
* implementation will only hold onto a raw pointer, so if this
* object should be destroyed, be sure to call
* UnregisterVistedCallback first.
*/
NS_IMETHOD RegisterVisitedCallback(nsIURI* aURI, dom::Link* aLink) = 0;
/**
* Unregisters a previously registered Link object. This must be called
* before destroying the registered object.
*
* @pre aURI must not be null.
* @pre aLink must not be null.
*
* @param aURI
* The URI that aLink was registered for.
* @param aLink
* The link object to unregister for aURI.
*/
NS_IMETHOD UnregisterVisitedCallback(nsIURI* aURI, dom::Link* aLink) = 0;
enum VisitFlags
{
/**
* Indicates whether the URI was loaded in a top-level window.
*/
TOP_LEVEL = 1 << 0,
/**
* Indicates whether the URI was loaded as part of a permanent redirect.
*/
REDIRECT_PERMANENT = 1 << 1,
/**
* Indicates whether the URI was loaded as part of a temporary redirect.
*/
REDIRECT_TEMPORARY = 1 << 2,
/**
* Indicates the URI is redirecting (Response code 3xx).
*/
REDIRECT_SOURCE = 1 << 3,
/**
* Indicates the URI caused an error that is unlikely fixable by a
* retry, like a not found or unfetchable page.
*/
UNRECOVERABLE_ERROR = 1 << 4
};
/**
* Adds a history visit for the URI.
*
* @pre aURI must not be null.
*
* @param aURI
* The URI of the page being visited.
* @param aLastVisitedURI
* The URI of the last visit in the chain.
* @param aFlags
* The VisitFlags describing this visit.
*/
NS_IMETHOD VisitURI(nsIURI* aURI,
nsIURI* aLastVisitedURI,
uint32_t aFlags) = 0;
/**
* Set the title of the URI.
*
* @pre aURI must not be null.
*
* @param aURI
* The URI to set the title for.
* @param aTitle
* The title string.
*/
NS_IMETHOD SetURITitle(nsIURI* aURI, const nsAString& aTitle) = 0;
/**
* Notifies about the visited status of a given URI.
*
* @param aURI
* The URI to notify about.
*/
NS_IMETHOD NotifyVisited(nsIURI* aURI) = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(IHistory, IHISTORY_IID)
#define NS_DECL_IHISTORY \
NS_IMETHOD RegisterVisitedCallback(nsIURI* aURI, \
mozilla::dom::Link* aContent) override; \
NS_IMETHOD UnregisterVisitedCallback(nsIURI* aURI, \
mozilla::dom::Link* aContent) override; \
NS_IMETHOD VisitURI(nsIURI* aURI, \
nsIURI* aLastVisitedURI, \
uint32_t aFlags) override; \
NS_IMETHOD SetURITitle(nsIURI* aURI, const nsAString& aTitle) override; \
NS_IMETHOD NotifyVisited(nsIURI* aURI) override;
} // namespace mozilla
#endif // mozilla_IHistory_h_

View file

@ -0,0 +1,229 @@
/* -*- 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 "mozilla/Assertions.h"
#include "mozilla/BasePrincipal.h"
#include "mozilla/LoadContext.h"
#include "mozilla/Preferences.h"
#include "mozilla/dom/ScriptSettings.h" // for AutoJSAPI
#include "nsContentUtils.h"
#include "xpcpublic.h"
bool
nsILoadContext::GetOriginAttributes(mozilla::DocShellOriginAttributes& aAttrs)
{
mozilla::dom::AutoJSAPI jsapi;
bool ok = jsapi.Init(xpc::PrivilegedJunkScope());
NS_ENSURE_TRUE(ok, false);
JS::Rooted<JS::Value> v(jsapi.cx());
nsresult rv = GetOriginAttributes(&v);
NS_ENSURE_SUCCESS(rv, false);
NS_ENSURE_TRUE(v.isObject(), false);
JS::Rooted<JSObject*> obj(jsapi.cx(), &v.toObject());
// If we're JS-implemented, the object will be left in a different (System-Principaled)
// scope, so we may need to enter its compartment.
MOZ_ASSERT(nsContentUtils::IsSystemPrincipal(nsContentUtils::ObjectPrincipal(obj)));
JSAutoCompartment ac(jsapi.cx(), obj);
mozilla::DocShellOriginAttributes attrs;
ok = attrs.Init(jsapi.cx(), v);
NS_ENSURE_TRUE(ok, false);
aAttrs = attrs;
return true;
}
namespace mozilla {
NS_IMPL_ISUPPORTS(LoadContext, nsILoadContext, nsIInterfaceRequestor)
LoadContext::LoadContext(nsIPrincipal* aPrincipal,
nsILoadContext* aOptionalBase)
: mTopFrameElement(nullptr)
, mNestedFrameId(0)
, mIsContent(true)
, mUseRemoteTabs(false)
#ifdef DEBUG
, mIsNotNull(true)
#endif
{
PrincipalOriginAttributes poa = BasePrincipal::Cast(aPrincipal)->OriginAttributesRef();
mOriginAttributes.InheritFromDocToChildDocShell(poa);
if (!aOptionalBase) {
return;
}
MOZ_ALWAYS_SUCCEEDS(aOptionalBase->GetIsContent(&mIsContent));
MOZ_ALWAYS_SUCCEEDS(aOptionalBase->GetUseRemoteTabs(&mUseRemoteTabs));
}
//-----------------------------------------------------------------------------
// LoadContext::nsILoadContext
//-----------------------------------------------------------------------------
NS_IMETHODIMP
LoadContext::GetAssociatedWindow(mozIDOMWindowProxy**)
{
MOZ_ASSERT(mIsNotNull);
// can't support this in the parent process
return NS_ERROR_UNEXPECTED;
}
NS_IMETHODIMP
LoadContext::GetTopWindow(mozIDOMWindowProxy**)
{
MOZ_ASSERT(mIsNotNull);
// can't support this in the parent process
return NS_ERROR_UNEXPECTED;
}
NS_IMETHODIMP
LoadContext::GetTopFrameElement(nsIDOMElement** aElement)
{
nsCOMPtr<nsIDOMElement> element = do_QueryReferent(mTopFrameElement);
element.forget(aElement);
return NS_OK;
}
NS_IMETHODIMP
LoadContext::GetNestedFrameId(uint64_t* aId)
{
NS_ENSURE_ARG(aId);
*aId = mNestedFrameId;
return NS_OK;
}
NS_IMETHODIMP
LoadContext::GetIsContent(bool* aIsContent)
{
MOZ_ASSERT(mIsNotNull);
NS_ENSURE_ARG_POINTER(aIsContent);
*aIsContent = mIsContent;
return NS_OK;
}
NS_IMETHODIMP
LoadContext::GetUsePrivateBrowsing(bool* aUsePrivateBrowsing)
{
MOZ_ASSERT(mIsNotNull);
NS_ENSURE_ARG_POINTER(aUsePrivateBrowsing);
*aUsePrivateBrowsing = mOriginAttributes.mPrivateBrowsingId > 0;
return NS_OK;
}
NS_IMETHODIMP
LoadContext::SetUsePrivateBrowsing(bool aUsePrivateBrowsing)
{
MOZ_ASSERT(mIsNotNull);
// We shouldn't need this on parent...
return NS_ERROR_UNEXPECTED;
}
NS_IMETHODIMP
LoadContext::SetPrivateBrowsing(bool aUsePrivateBrowsing)
{
MOZ_ASSERT(mIsNotNull);
// We shouldn't need this on parent...
return NS_ERROR_UNEXPECTED;
}
NS_IMETHODIMP
LoadContext::GetUseRemoteTabs(bool* aUseRemoteTabs)
{
MOZ_ASSERT(mIsNotNull);
NS_ENSURE_ARG_POINTER(aUseRemoteTabs);
*aUseRemoteTabs = mUseRemoteTabs;
return NS_OK;
}
NS_IMETHODIMP
LoadContext::SetRemoteTabs(bool aUseRemoteTabs)
{
MOZ_ASSERT(mIsNotNull);
// We shouldn't need this on parent...
return NS_ERROR_UNEXPECTED;
}
NS_IMETHODIMP
LoadContext::GetIsInIsolatedMozBrowserElement(bool* aIsInIsolatedMozBrowserElement)
{
MOZ_ASSERT(mIsNotNull);
NS_ENSURE_ARG_POINTER(aIsInIsolatedMozBrowserElement);
*aIsInIsolatedMozBrowserElement = mOriginAttributes.mInIsolatedMozBrowser;
return NS_OK;
}
NS_IMETHODIMP
LoadContext::GetAppId(uint32_t* aAppId)
{
MOZ_ASSERT(mIsNotNull);
NS_ENSURE_ARG_POINTER(aAppId);
*aAppId = mOriginAttributes.mAppId;
return NS_OK;
}
NS_IMETHODIMP
LoadContext::GetOriginAttributes(JS::MutableHandleValue aAttrs)
{
JSContext* cx = nsContentUtils::GetCurrentJSContext();
MOZ_ASSERT(cx);
bool ok = ToJSValue(cx, mOriginAttributes, aAttrs);
NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
return NS_OK;
}
NS_IMETHODIMP
LoadContext::IsTrackingProtectionOn(bool* aIsTrackingProtectionOn)
{
MOZ_ASSERT(mIsNotNull);
if (Preferences::GetBool("privacy.trackingprotection.enabled", false)) {
*aIsTrackingProtectionOn = true;
} else if ((mOriginAttributes.mPrivateBrowsingId > 0) &&
Preferences::GetBool("privacy.trackingprotection.pbmode.enabled", false)) {
*aIsTrackingProtectionOn = true;
} else {
*aIsTrackingProtectionOn = false;
}
return NS_OK;
}
//-----------------------------------------------------------------------------
// LoadContext::nsIInterfaceRequestor
//-----------------------------------------------------------------------------
NS_IMETHODIMP
LoadContext::GetInterface(const nsIID& aIID, void** aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
*aResult = nullptr;
if (aIID.Equals(NS_GET_IID(nsILoadContext))) {
*aResult = static_cast<nsILoadContext*>(this);
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
} // namespace mozilla

123
docshell/base/LoadContext.h Normal file
View file

@ -0,0 +1,123 @@
/* -*- 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 LoadContext_h
#define LoadContext_h
#include "SerializedLoadContext.h"
#include "mozilla/Attributes.h"
#include "mozilla/BasePrincipal.h"
#include "nsIWeakReferenceUtils.h"
#include "mozilla/dom/Element.h"
#include "nsIInterfaceRequestor.h"
#include "nsILoadContext.h"
namespace mozilla {
/**
* Class that provides nsILoadContext info in Parent process. Typically copied
* from Child via SerializedLoadContext.
*
* Note: this is not the "normal" or "original" nsILoadContext. That is
* typically provided by nsDocShell. This is only used when the original
* docshell is in a different process and we need to copy certain values from
* it.
*
* Note: we also generate a new nsILoadContext using LoadContext(uint32_t aAppId)
* to separate the safebrowsing cookie.
*/
class LoadContext final
: public nsILoadContext
, public nsIInterfaceRequestor
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSILOADCONTEXT
NS_DECL_NSIINTERFACEREQUESTOR
// appId/inIsolatedMozBrowser arguments override those in SerializedLoadContext
// provided by child process.
LoadContext(const IPC::SerializedLoadContext& aToCopy,
dom::Element* aTopFrameElement,
DocShellOriginAttributes& aAttrs)
: mTopFrameElement(do_GetWeakReference(aTopFrameElement))
, mNestedFrameId(0)
, mIsContent(aToCopy.mIsContent)
, mUseRemoteTabs(aToCopy.mUseRemoteTabs)
, mOriginAttributes(aAttrs)
#ifdef DEBUG
, mIsNotNull(aToCopy.mIsNotNull)
#endif
{
}
// appId/inIsolatedMozBrowser arguments override those in SerializedLoadContext
// provided by child process.
LoadContext(const IPC::SerializedLoadContext& aToCopy,
uint64_t aNestedFrameId,
DocShellOriginAttributes& aAttrs)
: mTopFrameElement(nullptr)
, mNestedFrameId(aNestedFrameId)
, mIsContent(aToCopy.mIsContent)
, mUseRemoteTabs(aToCopy.mUseRemoteTabs)
, mOriginAttributes(aAttrs)
#ifdef DEBUG
, mIsNotNull(aToCopy.mIsNotNull)
#endif
{
}
LoadContext(dom::Element* aTopFrameElement,
bool aIsContent,
bool aUsePrivateBrowsing,
bool aUseRemoteTabs,
const DocShellOriginAttributes& aAttrs)
: mTopFrameElement(do_GetWeakReference(aTopFrameElement))
, mNestedFrameId(0)
, mIsContent(aIsContent)
, mUseRemoteTabs(aUseRemoteTabs)
, mOriginAttributes(aAttrs)
#ifdef DEBUG
, mIsNotNull(true)
#endif
{
}
// Constructor taking reserved origin attributes.
explicit LoadContext(DocShellOriginAttributes& aAttrs)
: mTopFrameElement(nullptr)
, mNestedFrameId(0)
, mIsContent(false)
, mUseRemoteTabs(false)
, mOriginAttributes(aAttrs)
#ifdef DEBUG
, mIsNotNull(true)
#endif
{
}
// Constructor for creating a LoadContext with a given principal's appId and
// browser flag.
explicit LoadContext(nsIPrincipal* aPrincipal,
nsILoadContext* aOptionalBase = nullptr);
private:
~LoadContext() {}
nsWeakPtr mTopFrameElement;
uint64_t mNestedFrameId;
bool mIsContent;
bool mUseRemoteTabs;
DocShellOriginAttributes mOriginAttributes;
#ifdef DEBUG
bool mIsNotNull;
#endif
};
} // namespace mozilla
#endif // LoadContext_h

View file

@ -0,0 +1,77 @@
/* -*- 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 "SerializedLoadContext.h"
#include "nsNetUtil.h"
#include "nsIChannel.h"
#include "nsIPrivateBrowsingChannel.h"
#include "nsIWebSocketChannel.h"
namespace IPC {
SerializedLoadContext::SerializedLoadContext(nsILoadContext* aLoadContext)
{
Init(aLoadContext);
}
SerializedLoadContext::SerializedLoadContext(nsIChannel* aChannel)
{
if (!aChannel) {
Init(nullptr);
return;
}
nsCOMPtr<nsILoadContext> loadContext;
NS_QueryNotificationCallbacks(aChannel, loadContext);
Init(loadContext);
if (!loadContext) {
// Attempt to retrieve the private bit from the channel if it has been
// overriden.
bool isPrivate = false;
bool isOverriden = false;
nsCOMPtr<nsIPrivateBrowsingChannel> pbChannel = do_QueryInterface(aChannel);
if (pbChannel &&
NS_SUCCEEDED(pbChannel->IsPrivateModeOverriden(&isPrivate,
&isOverriden)) &&
isOverriden) {
mIsPrivateBitValid = true;
}
mOriginAttributes.SyncAttributesWithPrivateBrowsing(isPrivate);
}
}
SerializedLoadContext::SerializedLoadContext(nsIWebSocketChannel* aChannel)
{
nsCOMPtr<nsILoadContext> loadContext;
if (aChannel) {
NS_QueryNotificationCallbacks(aChannel, loadContext);
}
Init(loadContext);
}
void
SerializedLoadContext::Init(nsILoadContext* aLoadContext)
{
if (aLoadContext) {
mIsNotNull = true;
mIsPrivateBitValid = true;
aLoadContext->GetIsContent(&mIsContent);
aLoadContext->GetUseRemoteTabs(&mUseRemoteTabs);
if (!aLoadContext->GetOriginAttributes(mOriginAttributes)) {
NS_WARNING("GetOriginAttributes failed");
}
} else {
mIsNotNull = false;
mIsPrivateBitValid = false;
// none of below values really matter when mIsNotNull == false:
// we won't be GetInterfaced to nsILoadContext
mIsContent = true;
mUseRemoteTabs = false;
}
}
} // namespace IPC

View file

@ -0,0 +1,92 @@
/* -*- 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 SerializedLoadContext_h
#define SerializedLoadContext_h
#include "base/basictypes.h"
#include "ipc/IPCMessageUtils.h"
#include "mozilla/BasePrincipal.h"
class nsILoadContext;
/*
* This file contains the IPC::SerializedLoadContext class, which is used to
* copy data across IPDL from Child process contexts so it is available in the
* Parent.
*/
class nsIChannel;
class nsIWebSocketChannel;
namespace IPC {
class SerializedLoadContext
{
public:
SerializedLoadContext()
: mIsNotNull(false)
, mIsPrivateBitValid(false)
, mIsContent(false)
, mUseRemoteTabs(false)
{
Init(nullptr);
}
explicit SerializedLoadContext(nsILoadContext* aLoadContext);
explicit SerializedLoadContext(nsIChannel* aChannel);
explicit SerializedLoadContext(nsIWebSocketChannel* aChannel);
void Init(nsILoadContext* aLoadContext);
bool IsNotNull() const { return mIsNotNull; }
bool IsPrivateBitValid() const { return mIsPrivateBitValid; }
// used to indicate if child-side LoadContext * was null.
bool mIsNotNull;
// used to indicate if child-side mUsePrivateBrowsing flag is valid, even if
// mIsNotNull is false, i.e., child LoadContext was null.
bool mIsPrivateBitValid;
bool mIsContent;
bool mUseRemoteTabs;
mozilla::DocShellOriginAttributes mOriginAttributes;
};
// Function to serialize over IPDL
template<>
struct ParamTraits<SerializedLoadContext>
{
typedef SerializedLoadContext paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
nsAutoCString suffix;
aParam.mOriginAttributes.CreateSuffix(suffix);
WriteParam(aMsg, aParam.mIsNotNull);
WriteParam(aMsg, aParam.mIsContent);
WriteParam(aMsg, aParam.mIsPrivateBitValid);
WriteParam(aMsg, aParam.mUseRemoteTabs);
WriteParam(aMsg, suffix);
}
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
{
nsAutoCString suffix;
if (!ReadParam(aMsg, aIter, &aResult->mIsNotNull) ||
!ReadParam(aMsg, aIter, &aResult->mIsContent) ||
!ReadParam(aMsg, aIter, &aResult->mIsPrivateBitValid) ||
!ReadParam(aMsg, aIter, &aResult->mUseRemoteTabs) ||
!ReadParam(aMsg, aIter, &suffix)) {
return false;
}
return aResult->mOriginAttributes.PopulateFromSuffix(suffix);
}
};
} // namespace IPC
#endif // SerializedLoadContext_h

View file

@ -0,0 +1,25 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!--
user_pref("browser.send_pings", true);
-->
<script>
function boom() {
var aLink = document.createElement('a');
document.body.appendChild(aLink);
aLink.ping = "ping";
aLink.href = "href";
aLink.click();
var baseElement = document.createElement('base');
baseElement.setAttribute("href", "javascript:void 0");
document.head.appendChild(baseElement);
}
</script>
</head>
<body onload="boom();"></body>
</html>

View file

@ -0,0 +1,25 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script>
function boom() {
setTimeout(function(){
var o=document.getElementById('b');
document.getElementById('a').appendChild(o.parentNode.removeChild(o));
},0);
var o=document.getElementById('c');
var p=document.getElementById('b');
p.id=[o.id, o.id=p.id][0];
o=document.getElementById('b');
o.setAttribute('sandbox', 'disc');
window.location.reload(true);
}
</script>
</head>
<body onload="boom();">
<header id='a'></header>
<output id='b'></output>
<iframe id='c' sandbox='allow-same-origin' src='http://a'></iframe>
</body>
</html>

View file

@ -0,0 +1,14 @@
<html>
<head>
<script>
o1 = document.createElement("script");
o2 = document.implementation.createDocument('', '', null);
o3 = document.createElement("iframe");
document.documentElement.appendChild(o3);
o4 = o3.contentWindow;
o5 = document.createTextNode('o2.adoptNode(o3); try { o4.location = "" } catch(e) {}');
o1.appendChild(o5);
document.documentElement.appendChild(o1);
</script>
</head>
</html>

View file

@ -0,0 +1,16 @@
<html class="reftest-wait">
<head>
<script>
function boom()
{
document.getElementById("frameset").removeChild(document.getElementById("frame"));
document.documentElement.removeAttribute("class");
}
</script>
</head>
<frameset id="frameset" onload="setTimeout(boom, 100)">
<frame id="frame" src="data:text/html,<body onUnload=&quot;location = 'http://www.mozilla.org/'&quot;>This frame's onunload tries to load another page.">
</frameset>
</html>

View file

@ -0,0 +1,23 @@
<html xmlns="http://www.w3.org/1999/xhtml" class="reftest-wait">
<head>
<bindings xmlns="http://www.mozilla.org/xbl"><binding id="foo"><content>
<frame xmlns="http://www.w3.org/1999/xhtml"><children xmlns="http://www.mozilla.org/xbl"/></frame>
</content></binding></bindings>
<script>
function boom()
{
document.getElementById("span").style.MozBinding = "url('#foo')";
document.documentElement.removeAttribute("class");
}
</script>
</head>
<body onload="setTimeout(boom, 100);">
<span id="span"></span>
</body>
</html>

View file

@ -0,0 +1,14 @@
<html><head><title>Infinite Loop</title></head>
<body onLoad="initNav(); initNav();">
<script language="JavaScript">
function initNav() {
++parent.i;
if (parent.i < 10)
window.location.href=window.location.href;
}
</script>
</body></html>

View file

@ -0,0 +1,6 @@
<html>
<head><title>Infinite Loop</title><script>var i=0;</script></head>
<body>
<iframe src="40929-1-inner.html"></iframe>
</body>
</html>

View file

@ -0,0 +1,5 @@
<!DOCTYPE html>
<html>
<head></head>
<body onpagehide="document.getElementById('a').focus();"><div id="a"></div></body>
</html>

View file

@ -0,0 +1,8 @@
<!DOCTYPE html>
<html>
<head>
</head>
<body onpagehide="document.body.removeChild(document.getElementById('s'));">
<span id="s" contenteditable="true"></span>
</body>
</html>

View file

@ -0,0 +1,8 @@
<html>
<head>
<title>Bug - Crash [@ PL_DHashTableOperate] with DOMNodeInserted event listener removing window and frameset contenteditable</title>
</head>
<body>
<iframe id="content" src="data:text/html;charset=utf-8,%3Cscript%3E%0Awindow.addEventListener%28%27DOMNodeInserted%27%2C%20function%28%29%20%7Bwindow.frameElement.parentNode.removeChild%28window.frameElement%29%3B%7D%2C%20true%29%3B%0A%3C/script%3E%0A%3Cframeset%20contenteditable%3D%22true%22%3E"></iframe>
</body>
</html>

View file

@ -0,0 +1,16 @@
<html class="reftest-wait">
<head>
<title>testcase2 Bug 432114 Crash [@ PL_DHashTableOperate] with DOMNodeInserted event listener removing window and frameset contenteditable</title>
</head>
<body>
<script>
window.addEventListener("DOMNodeRemoved", function() {
setTimeout(function() {
document.documentElement.removeAttribute("class");
}, 0);
}, false);
</script>
<iframe id="content" src="data:application/xhtml+xml;charset=utf-8,%3Chtml%20xmlns%3D%22http%3A//www.w3.org/1999/xhtml%22%3E%0A%3Cframeset%20contenteditable%3D%22true%22/%3E%0A%3Cscript%3E%0Afunction%20doExecCommand%28%29%7B%0Adocument.execCommand%28%27formatBlock%27%2C%20false%2C%20%27p%27%29%3B%0A%7D%0AsetTimeout%28doExecCommand%2C100%29%3B%0Awindow.addEventListener%28%27DOMNodeRemoved%27%2C%20function%28%29%20%7Bwindow.frameElement.parentNode.removeChild%28window.frameElement%29%3B%7D%2C%20true%29%3B%0A%3C/script%3E%0A%3C/html%3E" style="width:1000px;height: 200px;"></iframe>
</body>
</html>

View file

@ -0,0 +1,21 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="refresh" content="0">
<script language="javascript">
location.hash += "+++";
function done()
{
parent.document.documentElement.removeAttribute("class");
}
</script>
</head>
<body onload="setTimeout(done, 10)">
</body>
</html>

View file

@ -0,0 +1,8 @@
<!DOCTYPE html>
<html class="reftest-wait">
<head>
</head>
<body>
<iframe src="436900-1-inner.html#foo"></iframe>
</body>
</html>

View file

@ -0,0 +1,21 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="refresh" content="0">
<script language="javascript" id="foo+++">
location.hash += "+++";
function done()
{
parent.document.documentElement.removeAttribute("class");
}
</script>
</head>
<body onload="setTimeout(done, 10)">
</body>
</html>

View file

@ -0,0 +1,8 @@
<!DOCTYPE html>
<html class="reftest-wait">
<head>
</head>
<body>
<iframe src="436900-2-inner.html#foo"></iframe>
</body>
</html>

View file

@ -0,0 +1,17 @@
<!DOCTYPE HTML>
<html>
<body onload="test();">
<script>
function test() {
// Test that calling pushState() with a state object which calls
// history.back() doesn't crash. We need to make sure that there's at least
// one entry in the history before we do anything else.
history.pushState(null, "");
x = {};
x.toJSON = { history.back(); return "{a:1}"; };
history.pushState(x, "");
}
</script>
</body>
</html>

View file

@ -0,0 +1,9 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head></head>
<body onunload="document.getElementById('tbody').appendChild(document.createElementNS('http://www.w3.org/1999/xhtml', 'span'))">
<iframe/>
<tbody contenteditable="true" id="tbody">xy</tbody>
</body>
</html>

View file

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<script>
function boom()
{
var f = document.getElementById("f");
for (var i = 0; i < 50; ++i) {
f.contentWindow.history.pushState({}, "");
}
document.body.removeChild(f);
}
</script>
</head>
<body onload="boom();"><iframe id="f" src="data:text/html,1"></iframe></body>
</html>

View file

@ -0,0 +1,36 @@
<!DOCTYPE html>
<html>
<head>
<script>
var f1, f2;
function b1()
{
f1 = document.getElementById("f1");
f2 = document.getElementById("f2");
f1.contentWindow.document.write("11");
f1.contentWindow.history.back();
setTimeout(b2, 0);
}
function b2()
{
f2.contentWindow.history.forward();
f2.contentWindow.location.reload();
f1.parentNode.removeChild(f1);
}
</script>
</script>
</head>
<body onload="setTimeout(b1, 0);">
<iframe id="f1" src="data:text/html,1"></iframe>
<iframe id="f2" src="data:text/html,2"></iframe>
</body>
</html>

View file

@ -0,0 +1,33 @@
<!DOCTYPE html>
<html class="reftest-wait">
<head>
<meta charset="UTF-8">
<script>
function f()
{
function spin() {
for (var i = 0; i < 8; ++i) {
var x = new XMLHttpRequest();
x.open('GET', 'data:text/html,' + i, false);
x.send();
}
}
window.addEventListener("popstate", spin, false);
window.close();
window.location = "#c";
finish();
}
function start()
{
var html = "<script>" + f + "<\/script><body onload=f()>";
var win = window.open("data:text/html," + encodeURIComponent(html), null, "width=300,height=300");
win.finish = function() { document.documentElement.removeAttribute("class"); };
}
</script>
</head>
<body onload="start();"></body>
</html>

View file

@ -0,0 +1,16 @@
load 40929-1.html
load 369126-1.html
load 403574-1.xhtml
load 430124-1.html
load 430628-1.html
load 432114-1.html
load 432114-2.html
load 436900-1.html
asserts(0-1) load 436900-2.html # bug 566159
load 500328-1.html
load 514779-1.xhtml
load 614499-1.html
load 678872-1.html
skip-if(Android) pref(dom.disable_open_during_load,false) load 914521.html
pref(browser.send_pings,true) load 1257730-1.html
load 1341657.html

88
docshell/base/moz.build Normal file
View file

@ -0,0 +1,88 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
DIRS += [
'timeline',
]
XPIDL_SOURCES += [
'nsCDefaultURIFixup.idl',
'nsIClipboardCommands.idl',
'nsIContentViewer.idl',
'nsIContentViewerContainer.idl',
'nsIContentViewerEdit.idl',
'nsIContentViewerFile.idl',
'nsIDocCharset.idl',
'nsIDocShell.idl',
'nsIDocShellLoadInfo.idl',
'nsIDocShellTreeItem.idl',
'nsIDocShellTreeOwner.idl',
'nsIDocumentLoaderFactory.idl',
'nsIDownloadHistory.idl',
'nsIGlobalHistory2.idl',
'nsILoadContext.idl',
'nsIPrivacyTransitionObserver.idl',
'nsIReflowObserver.idl',
'nsIRefreshURI.idl',
'nsIScrollable.idl',
'nsITextScroll.idl',
'nsIURIFixup.idl',
'nsIWebNavigation.idl',
'nsIWebNavigationInfo.idl',
'nsIWebPageDescriptor.idl',
]
XPIDL_MODULE = 'docshell'
EXPORTS += [
'nsDocShellLoadTypes.h',
'nsILinkHandler.h',
'nsIScrollObserver.h',
'nsIWebShellServices.h',
'SerializedLoadContext.h',
]
EXPORTS.mozilla += [
'IHistory.h',
'LoadContext.h',
]
UNIFIED_SOURCES += [
'LoadContext.cpp',
'nsAboutRedirector.cpp',
'nsDefaultURIFixup.cpp',
'nsDocShell.cpp',
'nsDocShellEditorData.cpp',
'nsDocShellEnumerator.cpp',
'nsDocShellLoadInfo.cpp',
'nsDocShellTransferableHooks.cpp',
'nsDownloadHistory.cpp',
'nsDSURIContentListener.cpp',
'nsWebNavigationInfo.cpp',
'SerializedLoadContext.cpp',
]
include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'xul'
LOCAL_INCLUDES += [
'/docshell/shistory',
'/dom/base',
'/layout/base',
'/layout/generic',
'/layout/xul',
'/netwerk/protocol/viewsource',
'/tools/profiler',
]
if CONFIG['MOZ_TOOLKIT_SEARCH']:
DEFINES['MOZ_TOOLKIT_SEARCH'] = True
if CONFIG['MOZ_DEVTOOLS'] == 'all':
DEFINES['MOZ_DEVTOOLS_ALL'] = True
if CONFIG['GNU_CXX']:
CXXFLAGS += ['-Wno-error=shadow']

View file

@ -0,0 +1,224 @@
/* -*- 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 "nsAboutRedirector.h"
#include "nsNetUtil.h"
#include "nsAboutProtocolUtils.h"
#include "mozilla/ArrayUtils.h"
#include "nsIProtocolHandler.h"
NS_IMPL_ISUPPORTS(nsAboutRedirector, nsIAboutModule)
struct RedirEntry
{
const char* id;
const char* url;
uint32_t flags;
};
/*
Entries which do not have URI_SAFE_FOR_UNTRUSTED_CONTENT will run with chrome
privileges. This is potentially dangerous. Please use
URI_SAFE_FOR_UNTRUSTED_CONTENT in the third argument to each map item below
unless your about: page really needs chrome privileges. Security review is
required before adding new map entries without
URI_SAFE_FOR_UNTRUSTED_CONTENT. Also note, however, that adding
URI_SAFE_FOR_UNTRUSTED_CONTENT will allow random web sites to link to that
URI. Perhaps we should separate the two concepts out...
*/
static RedirEntry kRedirMap[] = {
{
"", "chrome://global/content/about.xhtml",
nsIAboutModule::ALLOW_SCRIPT
},
{ "about", "chrome://global/content/aboutAbout.xhtml", 0 },
{
"addons", "chrome://mozapps/content/extensions/extensions.xul",
nsIAboutModule::ALLOW_SCRIPT
},
{
"buildconfig", "chrome://global/content/buildconfig.html",
nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT
},
{
"checkerboard", "chrome://global/content/aboutCheckerboard.xhtml",
nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
nsIAboutModule::ALLOW_SCRIPT
},
{ "config", "chrome://global/content/config.xul", 0 },
#ifdef MOZ_CRASHREPORTER
{ "crashes", "chrome://global/content/crashes.xhtml", 0 },
#endif
{
"credits", "https://www.mozilla.org/credits/",
nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT
},
#ifdef MOZ_DEVTOOLS_ALL
{
"debugging", "chrome://devtools/content/aboutdebugging/aboutdebugging.xhtml",
nsIAboutModule::ALLOW_SCRIPT
},
#endif
{
"license", "chrome://global/content/license.html",
nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
nsIAboutModule::MAKE_LINKABLE
},
{
"logo", "chrome://branding/content/about.png",
nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
// Linkable for testing reasons.
nsIAboutModule::MAKE_LINKABLE
},
{
"memory", "chrome://global/content/aboutMemory.xhtml",
nsIAboutModule::ALLOW_SCRIPT
},
{
"mozilla", "chrome://global/content/mozilla.xhtml",
nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT
},
{
"neterror", "chrome://global/content/netError.xhtml",
nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
nsIAboutModule::URI_CAN_LOAD_IN_CHILD |
nsIAboutModule::ALLOW_SCRIPT |
nsIAboutModule::HIDE_FROM_ABOUTABOUT
},
{
"networking", "chrome://global/content/aboutNetworking.xhtml",
nsIAboutModule::ALLOW_SCRIPT
},
{
"newaddon", "chrome://mozapps/content/extensions/newaddon.xul",
nsIAboutModule::ALLOW_SCRIPT |
nsIAboutModule::HIDE_FROM_ABOUTABOUT
},
{
"performance", "chrome://global/content/aboutPerformance.xhtml",
nsIAboutModule::ALLOW_SCRIPT
},
{
"plugins", "chrome://global/content/plugins.html",
nsIAboutModule::URI_MUST_LOAD_IN_CHILD
},
{
"serviceworkers", "chrome://global/content/aboutServiceWorkers.xhtml",
nsIAboutModule::URI_CAN_LOAD_IN_CHILD |
nsIAboutModule::URI_MUST_LOAD_IN_CHILD |
nsIAboutModule::ALLOW_SCRIPT
},
#ifndef ANDROID
{
"profiles", "chrome://global/content/aboutProfiles.xhtml",
nsIAboutModule::ALLOW_SCRIPT
},
#endif
// about:srcdoc is unresolvable by specification. It is included here
// because the security manager would disallow srcdoc iframes otherwise.
{
"srcdoc", "about:blank",
nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
nsIAboutModule::HIDE_FROM_ABOUTABOUT |
// Needs to be linkable so content can touch its own srcdoc frames
nsIAboutModule::MAKE_LINKABLE |
nsIAboutModule::URI_CAN_LOAD_IN_CHILD
},
{
"support", "chrome://global/content/aboutSupport.xhtml",
nsIAboutModule::ALLOW_SCRIPT
},
{
"telemetry", "chrome://global/content/aboutTelemetry.xhtml",
nsIAboutModule::ALLOW_SCRIPT
},
{
"webrtc", "chrome://global/content/aboutwebrtc/aboutWebrtc.html",
nsIAboutModule::ALLOW_SCRIPT
}
};
static const int kRedirTotal = mozilla::ArrayLength(kRedirMap);
NS_IMETHODIMP
nsAboutRedirector::NewChannel(nsIURI* aURI,
nsILoadInfo* aLoadInfo,
nsIChannel** aResult)
{
NS_ENSURE_ARG_POINTER(aURI);
NS_ASSERTION(aResult, "must not be null");
nsAutoCString path;
nsresult rv = NS_GetAboutModuleName(aURI, path);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIIOService> ioService = do_GetIOService(&rv);
NS_ENSURE_SUCCESS(rv, rv);
for (int i = 0; i < kRedirTotal; i++) {
if (!strcmp(path.get(), kRedirMap[i].id)) {
nsCOMPtr<nsIChannel> tempChannel;
nsCOMPtr<nsIURI> tempURI;
rv = NS_NewURI(getter_AddRefs(tempURI), kRedirMap[i].url);
NS_ENSURE_SUCCESS(rv, rv);
// If tempURI links to an external URI (i.e. something other than
// chrome:// or resource://) then set the LOAD_REPLACE flag on the
// channel which forces the channel owner to reflect the displayed
// URL rather then being the systemPrincipal.
bool isUIResource = false;
rv = NS_URIChainHasFlags(tempURI, nsIProtocolHandler::URI_IS_UI_RESOURCE,
&isUIResource);
NS_ENSURE_SUCCESS(rv, rv);
nsLoadFlags loadFlags =
isUIResource ? static_cast<nsLoadFlags>(nsIChannel::LOAD_NORMAL)
: static_cast<nsLoadFlags>(nsIChannel::LOAD_REPLACE);
rv = NS_NewChannelInternal(getter_AddRefs(tempChannel),
tempURI,
aLoadInfo,
nullptr, // aLoadGroup
nullptr, // aCallbacks
loadFlags);
NS_ENSURE_SUCCESS(rv, rv);
tempChannel->SetOriginalURI(aURI);
tempChannel.forget(aResult);
return rv;
}
}
NS_ERROR("nsAboutRedirector called for unknown case");
return NS_ERROR_ILLEGAL_VALUE;
}
NS_IMETHODIMP
nsAboutRedirector::GetURIFlags(nsIURI* aURI, uint32_t* aResult)
{
NS_ENSURE_ARG_POINTER(aURI);
nsAutoCString name;
nsresult rv = NS_GetAboutModuleName(aURI, name);
NS_ENSURE_SUCCESS(rv, rv);
for (int i = 0; i < kRedirTotal; i++) {
if (name.EqualsASCII(kRedirMap[i].id)) {
*aResult = kRedirMap[i].flags;
return NS_OK;
}
}
NS_ERROR("nsAboutRedirector called for unknown case");
return NS_ERROR_ILLEGAL_VALUE;
}
nsresult
nsAboutRedirector::Create(nsISupports* aOuter, REFNSIID aIID, void** aResult)
{
RefPtr<nsAboutRedirector> about = new nsAboutRedirector();
return about->QueryInterface(aIID, aResult);
}

View file

@ -0,0 +1,32 @@
/* -*- 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 nsAboutRedirector_h__
#define nsAboutRedirector_h__
#include "nsIAboutModule.h"
class nsAboutRedirector : public nsIAboutModule
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIABOUTMODULE
nsAboutRedirector() {}
static nsresult Create(nsISupports* aOuter, REFNSIID aIID, void** aResult);
protected:
virtual ~nsAboutRedirector() {}
};
/* 56ebedd4-6ccf-48e8-bdae-adc77f044567 */
#define NS_ABOUT_REDIRECTOR_MODULE_CID \
{ 0x56ebedd4, 0x6ccf, 0x48e8, \
{ 0xbd, 0xae, 0xad, 0xc7, 0x7f, 0x04, 0x45, 0x67 } }
#endif // nsAboutRedirector_h__

View file

@ -0,0 +1,13 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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/. */
%{ C++
// {214C48A0-B57F-11d4-959C-0020183BF181}
#define NS_DEFAULTURIFIXUP_CID \
{ 0x214c48a0, 0xb57f, 0x11d4, { 0x95, 0x9c, 0x0, 0x20, 0x18, 0x3b, 0xf1, 0x81 } }
#define NS_URIFIXUP_CONTRACTID \
"@mozilla.org/docshell/urifixup;1"
%}

View file

@ -0,0 +1,539 @@
/* -*- 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 "nsDocShell.h"
#include "nsDSURIContentListener.h"
#include "nsIChannel.h"
#include "nsServiceManagerUtils.h"
#include "nsDocShellCID.h"
#include "nsIWebNavigationInfo.h"
#include "nsIDocument.h"
#include "nsIDOMWindow.h"
#include "nsNetUtil.h"
#include "nsQueryObject.h"
#include "nsIHttpChannel.h"
#include "nsIScriptSecurityManager.h"
#include "nsError.h"
#include "nsCharSeparatedTokenizer.h"
#include "nsIConsoleService.h"
#include "nsIScriptError.h"
#include "nsDocShellLoadTypes.h"
#include "nsIMultiPartChannel.h"
using namespace mozilla;
nsDSURIContentListener::nsDSURIContentListener(nsDocShell* aDocShell)
: mDocShell(aDocShell)
, mExistingJPEGRequest(nullptr)
, mParentContentListener(nullptr)
{
}
nsDSURIContentListener::~nsDSURIContentListener()
{
}
nsresult
nsDSURIContentListener::Init()
{
nsresult rv;
mNavInfo = do_GetService(NS_WEBNAVIGATION_INFO_CONTRACTID, &rv);
NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to get webnav info");
return rv;
}
NS_IMPL_ADDREF(nsDSURIContentListener)
NS_IMPL_RELEASE(nsDSURIContentListener)
NS_INTERFACE_MAP_BEGIN(nsDSURIContentListener)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIURIContentListener)
NS_INTERFACE_MAP_ENTRY(nsIURIContentListener)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
NS_INTERFACE_MAP_END
NS_IMETHODIMP
nsDSURIContentListener::OnStartURIOpen(nsIURI* aURI, bool* aAbortOpen)
{
// If mDocShell is null here, that means someone's starting a load in our
// docshell after it's already been destroyed. Don't let that happen.
if (!mDocShell) {
*aAbortOpen = true;
return NS_OK;
}
nsCOMPtr<nsIURIContentListener> parentListener;
GetParentContentListener(getter_AddRefs(parentListener));
if (parentListener) {
return parentListener->OnStartURIOpen(aURI, aAbortOpen);
}
return NS_OK;
}
NS_IMETHODIMP
nsDSURIContentListener::DoContent(const nsACString& aContentType,
bool aIsContentPreferred,
nsIRequest* aRequest,
nsIStreamListener** aContentHandler,
bool* aAbortProcess)
{
nsresult rv;
NS_ENSURE_ARG_POINTER(aContentHandler);
NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE);
// Check whether X-Frame-Options permits us to load this content in an
// iframe and abort the load (unless we've disabled x-frame-options
// checking).
if (!CheckFrameOptions(aRequest)) {
*aAbortProcess = true;
return NS_OK;
}
*aAbortProcess = false;
// determine if the channel has just been retargeted to us...
nsLoadFlags loadFlags = 0;
nsCOMPtr<nsIChannel> aOpenedChannel = do_QueryInterface(aRequest);
if (aOpenedChannel) {
aOpenedChannel->GetLoadFlags(&loadFlags);
}
if (loadFlags & nsIChannel::LOAD_RETARGETED_DOCUMENT_URI) {
// XXX: Why does this not stop the content too?
mDocShell->Stop(nsIWebNavigation::STOP_NETWORK);
mDocShell->SetLoadType(aIsContentPreferred ? LOAD_LINK : LOAD_NORMAL);
}
// In case of multipart jpeg request (mjpeg) we don't really want to
// create new viewer since the one we already have is capable of
// rendering multipart jpeg correctly (see bug 625012)
nsCOMPtr<nsIChannel> baseChannel;
if (nsCOMPtr<nsIMultiPartChannel> mpchan = do_QueryInterface(aRequest)) {
mpchan->GetBaseChannel(getter_AddRefs(baseChannel));
}
bool reuseCV = baseChannel && baseChannel == mExistingJPEGRequest &&
aContentType.EqualsLiteral("image/jpeg");
if (mExistingJPEGStreamListener && reuseCV) {
RefPtr<nsIStreamListener> copy(mExistingJPEGStreamListener);
copy.forget(aContentHandler);
rv = NS_OK;
} else {
rv = mDocShell->CreateContentViewer(aContentType, aRequest, aContentHandler);
if (NS_SUCCEEDED(rv) && reuseCV) {
mExistingJPEGStreamListener = *aContentHandler;
} else {
mExistingJPEGStreamListener = nullptr;
}
mExistingJPEGRequest = baseChannel;
}
if (rv == NS_ERROR_REMOTE_XUL) {
aRequest->Cancel(rv);
*aAbortProcess = true;
return NS_OK;
}
if (NS_FAILED(rv)) {
// we don't know how to handle the content
*aContentHandler = nullptr;
return rv;
}
if (loadFlags & nsIChannel::LOAD_RETARGETED_DOCUMENT_URI) {
nsCOMPtr<nsPIDOMWindowOuter> domWindow =
mDocShell ? mDocShell->GetWindow() : nullptr;
NS_ENSURE_TRUE(domWindow, NS_ERROR_FAILURE);
domWindow->Focus();
}
return NS_OK;
}
NS_IMETHODIMP
nsDSURIContentListener::IsPreferred(const char* aContentType,
char** aDesiredContentType,
bool* aCanHandle)
{
NS_ENSURE_ARG_POINTER(aCanHandle);
NS_ENSURE_ARG_POINTER(aDesiredContentType);
// the docshell has no idea if it is the preferred content provider or not.
// It needs to ask its parent if it is the preferred content handler or not...
nsCOMPtr<nsIURIContentListener> parentListener;
GetParentContentListener(getter_AddRefs(parentListener));
if (parentListener) {
return parentListener->IsPreferred(aContentType,
aDesiredContentType,
aCanHandle);
}
// we used to return false here if we didn't have a parent properly registered
// at the top of the docshell hierarchy to dictate what content types this
// docshell should be a preferred handler for. But this really makes it hard
// for developers using iframe or browser tags because then they need to make
// sure they implement nsIURIContentListener otherwise all link clicks would
// get sent to another window because we said we weren't the preferred handler
// type. I'm going to change the default now... if we can handle the content,
// and someone didn't EXPLICITLY set a nsIURIContentListener at the top of our
// docshell chain, then we'll now always attempt to process the content
// ourselves...
return CanHandleContent(aContentType, true, aDesiredContentType, aCanHandle);
}
NS_IMETHODIMP
nsDSURIContentListener::CanHandleContent(const char* aContentType,
bool aIsContentPreferred,
char** aDesiredContentType,
bool* aCanHandleContent)
{
NS_PRECONDITION(aCanHandleContent, "Null out param?");
NS_ENSURE_ARG_POINTER(aDesiredContentType);
*aCanHandleContent = false;
*aDesiredContentType = nullptr;
nsresult rv = NS_OK;
if (aContentType) {
uint32_t canHandle = nsIWebNavigationInfo::UNSUPPORTED;
rv = mNavInfo->IsTypeSupported(nsDependentCString(aContentType),
mDocShell,
&canHandle);
*aCanHandleContent = (canHandle != nsIWebNavigationInfo::UNSUPPORTED);
}
return rv;
}
NS_IMETHODIMP
nsDSURIContentListener::GetLoadCookie(nsISupports** aLoadCookie)
{
NS_IF_ADDREF(*aLoadCookie = nsDocShell::GetAsSupports(mDocShell));
return NS_OK;
}
NS_IMETHODIMP
nsDSURIContentListener::SetLoadCookie(nsISupports* aLoadCookie)
{
#ifdef DEBUG
RefPtr<nsDocLoader> cookieAsDocLoader =
nsDocLoader::GetAsDocLoader(aLoadCookie);
NS_ASSERTION(cookieAsDocLoader && cookieAsDocLoader == mDocShell,
"Invalid load cookie being set!");
#endif
return NS_OK;
}
NS_IMETHODIMP
nsDSURIContentListener::GetParentContentListener(
nsIURIContentListener** aParentListener)
{
if (mWeakParentContentListener) {
nsCOMPtr<nsIURIContentListener> tempListener =
do_QueryReferent(mWeakParentContentListener);
*aParentListener = tempListener;
NS_IF_ADDREF(*aParentListener);
} else {
*aParentListener = mParentContentListener;
NS_IF_ADDREF(*aParentListener);
}
return NS_OK;
}
NS_IMETHODIMP
nsDSURIContentListener::SetParentContentListener(
nsIURIContentListener* aParentListener)
{
if (aParentListener) {
// Store the parent listener as a weak ref. Parents not supporting
// nsISupportsWeakReference assert but may still be used.
mParentContentListener = nullptr;
mWeakParentContentListener = do_GetWeakReference(aParentListener);
if (!mWeakParentContentListener) {
mParentContentListener = aParentListener;
}
} else {
mWeakParentContentListener = nullptr;
mParentContentListener = nullptr;
}
return NS_OK;
}
bool
nsDSURIContentListener::CheckOneFrameOptionsPolicy(nsIHttpChannel* aHttpChannel,
const nsAString& aPolicy)
{
static const char allowFrom[] = "allow-from";
const uint32_t allowFromLen = ArrayLength(allowFrom) - 1;
bool isAllowFrom =
StringHead(aPolicy, allowFromLen).LowerCaseEqualsLiteral(allowFrom);
// return early if header does not have one of the values with meaning
if (!aPolicy.LowerCaseEqualsLiteral("deny") &&
!aPolicy.LowerCaseEqualsLiteral("sameorigin") &&
!isAllowFrom) {
return true;
}
nsCOMPtr<nsIURI> uri;
aHttpChannel->GetURI(getter_AddRefs(uri));
// XXXkhuey when does this happen? Is returning true safe here?
if (!mDocShell) {
return true;
}
// We need to check the location of this window and the location of the top
// window, if we're not the top. X-F-O: SAMEORIGIN requires that the
// document must be same-origin with top window. X-F-O: DENY requires that
// the document must never be framed.
nsCOMPtr<nsPIDOMWindowOuter> thisWindow = mDocShell->GetWindow();
// If we don't have DOMWindow there is no risk of clickjacking
if (!thisWindow) {
return true;
}
// GetScriptableTop, not GetTop, because we want this to respect
// <iframe mozbrowser> boundaries.
nsCOMPtr<nsPIDOMWindowOuter> topWindow = thisWindow->GetScriptableTop();
// if the document is in the top window, it's not in a frame.
if (thisWindow == topWindow) {
return true;
}
// Find the top docshell in our parent chain that doesn't have the system
// principal and use it for the principal comparison. Finding the top
// content-type docshell doesn't work because some chrome documents are
// loaded in content docshells (see bug 593387).
nsCOMPtr<nsIDocShellTreeItem> thisDocShellItem(
do_QueryInterface(static_cast<nsIDocShell*>(mDocShell)));
nsCOMPtr<nsIDocShellTreeItem> parentDocShellItem;
nsCOMPtr<nsIDocShellTreeItem> curDocShellItem = thisDocShellItem;
nsCOMPtr<nsIDocument> topDoc;
nsresult rv;
nsCOMPtr<nsIScriptSecurityManager> ssm =
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
if (!ssm) {
MOZ_CRASH();
}
// Traverse up the parent chain and stop when we see a docshell whose
// parent has a system principal, or a docshell corresponding to
// <iframe mozbrowser>.
while (NS_SUCCEEDED(
curDocShellItem->GetParent(getter_AddRefs(parentDocShellItem))) &&
parentDocShellItem) {
nsCOMPtr<nsIDocShell> curDocShell = do_QueryInterface(curDocShellItem);
if (curDocShell && curDocShell->GetIsMozBrowserOrApp()) {
break;
}
bool system = false;
topDoc = parentDocShellItem->GetDocument();
if (topDoc) {
if (NS_SUCCEEDED(
ssm->IsSystemPrincipal(topDoc->NodePrincipal(), &system)) &&
system) {
// Found a system-principled doc: last docshell was top.
break;
}
} else {
return false;
}
curDocShellItem = parentDocShellItem;
}
// If this document has the top non-SystemPrincipal docshell it is not being
// framed or it is being framed by a chrome document, which we allow.
if (curDocShellItem == thisDocShellItem) {
return true;
}
// If the value of the header is DENY, and the previous condition is
// not met (current docshell is not the top docshell), prohibit the
// load.
if (aPolicy.LowerCaseEqualsLiteral("deny")) {
ReportXFOViolation(curDocShellItem, uri, eDENY);
return false;
}
topDoc = curDocShellItem->GetDocument();
nsCOMPtr<nsIURI> topUri;
topDoc->NodePrincipal()->GetURI(getter_AddRefs(topUri));
// If the X-Frame-Options value is SAMEORIGIN, then the top frame in the
// parent chain must be from the same origin as this document.
if (aPolicy.LowerCaseEqualsLiteral("sameorigin")) {
rv = ssm->CheckSameOriginURI(uri, topUri, true);
if (NS_FAILED(rv)) {
ReportXFOViolation(curDocShellItem, uri, eSAMEORIGIN);
return false; /* wasn't same-origin */
}
}
// If the X-Frame-Options value is "allow-from [uri]", then the top
// frame in the parent chain must be from that origin
if (isAllowFrom) {
if (aPolicy.Length() == allowFromLen ||
(aPolicy[allowFromLen] != ' ' &&
aPolicy[allowFromLen] != '\t')) {
ReportXFOViolation(curDocShellItem, uri, eALLOWFROM);
return false;
}
rv = NS_NewURI(getter_AddRefs(uri), Substring(aPolicy, allowFromLen));
if (NS_FAILED(rv)) {
return false;
}
rv = ssm->CheckSameOriginURI(uri, topUri, true);
if (NS_FAILED(rv)) {
ReportXFOViolation(curDocShellItem, uri, eALLOWFROM);
return false;
}
}
return true;
}
// Check if X-Frame-Options permits this document to be loaded as a subdocument.
// This will iterate through and check any number of X-Frame-Options policies
// in the request (comma-separated in a header, multiple headers, etc).
bool
nsDSURIContentListener::CheckFrameOptions(nsIRequest* aRequest)
{
nsresult rv;
nsCOMPtr<nsIChannel> chan = do_QueryInterface(aRequest);
if (!chan) {
return true;
}
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(chan);
if (!httpChannel) {
// check if it is hiding in a multipart channel
rv = mDocShell->GetHttpChannel(chan, getter_AddRefs(httpChannel));
if (NS_FAILED(rv)) {
return false;
}
}
if (!httpChannel) {
return true;
}
nsAutoCString xfoHeaderCValue;
httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("X-Frame-Options"),
xfoHeaderCValue);
NS_ConvertUTF8toUTF16 xfoHeaderValue(xfoHeaderCValue);
// if no header value, there's nothing to do.
if (xfoHeaderValue.IsEmpty()) {
return true;
}
// iterate through all the header values (usually there's only one, but can
// be many. If any want to deny the load, deny the load.
nsCharSeparatedTokenizer tokenizer(xfoHeaderValue, ',');
while (tokenizer.hasMoreTokens()) {
const nsSubstring& tok = tokenizer.nextToken();
if (!CheckOneFrameOptionsPolicy(httpChannel, tok)) {
// cancel the load and display about:blank
httpChannel->Cancel(NS_BINDING_ABORTED);
if (mDocShell) {
nsCOMPtr<nsIWebNavigation> webNav(do_QueryObject(mDocShell));
if (webNav) {
webNav->LoadURI(u"about:blank",
0, nullptr, nullptr, nullptr);
}
}
return false;
}
}
return true;
}
void
nsDSURIContentListener::ReportXFOViolation(nsIDocShellTreeItem* aTopDocShellItem,
nsIURI* aThisURI,
XFOHeader aHeader)
{
MOZ_ASSERT(aTopDocShellItem, "Need a top docshell");
nsCOMPtr<nsPIDOMWindowOuter> topOuterWindow = aTopDocShellItem->GetWindow();
if (!topOuterWindow) {
return;
}
nsPIDOMWindowInner* topInnerWindow = topOuterWindow->GetCurrentInnerWindow();
if (!topInnerWindow) {
return;
}
nsCOMPtr<nsIURI> topURI;
nsCOMPtr<nsIDocument> document = aTopDocShellItem->GetDocument();
nsresult rv = document->NodePrincipal()->GetURI(getter_AddRefs(topURI));
if (NS_FAILED(rv)) {
return;
}
if (!topURI) {
return;
}
nsCString topURIString;
nsCString thisURIString;
rv = topURI->GetSpec(topURIString);
if (NS_FAILED(rv)) {
return;
}
rv = aThisURI->GetSpec(thisURIString);
if (NS_FAILED(rv)) {
return;
}
nsCOMPtr<nsIConsoleService> consoleService =
do_GetService(NS_CONSOLESERVICE_CONTRACTID);
nsCOMPtr<nsIScriptError> errorObject =
do_CreateInstance(NS_SCRIPTERROR_CONTRACTID);
if (!consoleService || !errorObject) {
return;
}
nsString msg = NS_LITERAL_STRING("Load denied by X-Frame-Options: ");
msg.Append(NS_ConvertUTF8toUTF16(thisURIString));
switch (aHeader) {
case eDENY:
msg.AppendLiteral(" does not permit framing.");
break;
case eSAMEORIGIN:
msg.AppendLiteral(" does not permit cross-origin framing.");
break;
case eALLOWFROM:
msg.AppendLiteral(" does not permit framing by ");
msg.Append(NS_ConvertUTF8toUTF16(topURIString));
msg.Append('.');
break;
}
rv = errorObject->InitWithWindowID(msg, EmptyString(), EmptyString(), 0, 0,
nsIScriptError::errorFlag,
"X-Frame-Options",
topInnerWindow->WindowID());
if (NS_FAILED(rv)) {
return;
}
consoleService->LogMessage(errorObject);
}

View file

@ -0,0 +1,74 @@
/* -*- 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 nsDSURIContentListener_h__
#define nsDSURIContentListener_h__
#include "nsCOMPtr.h"
#include "nsIURIContentListener.h"
#include "nsWeakReference.h"
class nsDocShell;
class nsIWebNavigationInfo;
class nsIHttpChannel;
class nsAString;
class nsDSURIContentListener final
: public nsIURIContentListener
, public nsSupportsWeakReference
{
friend class nsDocShell;
public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIURICONTENTLISTENER
nsresult Init();
protected:
explicit nsDSURIContentListener(nsDocShell* aDocShell);
virtual ~nsDSURIContentListener();
void DropDocShellReference()
{
mDocShell = nullptr;
mExistingJPEGRequest = nullptr;
mExistingJPEGStreamListener = nullptr;
}
// Determine if X-Frame-Options allows content to be framed
// as a subdocument
bool CheckFrameOptions(nsIRequest* aRequest);
bool CheckOneFrameOptionsPolicy(nsIHttpChannel* aHttpChannel,
const nsAString& aPolicy);
enum XFOHeader
{
eDENY,
eSAMEORIGIN,
eALLOWFROM
};
void ReportXFOViolation(nsIDocShellTreeItem* aTopDocShellItem,
nsIURI* aThisURI,
XFOHeader aHeader);
protected:
nsDocShell* mDocShell;
// Hack to handle multipart images without creating a new viewer
nsCOMPtr<nsIStreamListener> mExistingJPEGStreamListener;
nsCOMPtr<nsIChannel> mExistingJPEGRequest;
// Store the parent listener in either of these depending on
// if supports weak references or not. Proper weak refs are
// preferred and encouraged!
nsWeakPtr mWeakParentContentListener;
nsIURIContentListener* mParentContentListener;
nsCOMPtr<nsIWebNavigationInfo> mNavInfo;
};
#endif /* nsDSURIContentListener_h__ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,69 @@
/* -*- 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 NSDEFAULTURIFIXUP_H
#define NSDEFAULTURIFIXUP_H
#include "nsIURIFixup.h"
class nsDefaultURIFixupInfo;
/* Header file */
class nsDefaultURIFixup : public nsIURIFixup
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIURIFIXUP
nsDefaultURIFixup();
protected:
virtual ~nsDefaultURIFixup();
private:
/* additional members */
nsresult FileURIFixup(const nsACString& aStringURI, nsIURI** aURI);
nsresult ConvertFileToStringURI(const nsACString& aIn, nsCString& aResult);
nsresult FixupURIProtocol(const nsACString& aIn,
nsDefaultURIFixupInfo* aFixupInfo,
nsIURI** aURI);
nsresult KeywordURIFixup(const nsACString& aStringURI,
nsDefaultURIFixupInfo* aFixupInfo,
nsIInputStream** aPostData);
nsresult TryKeywordFixupForURIInfo(const nsACString& aStringURI,
nsDefaultURIFixupInfo* aFixupInfo,
nsIInputStream** aPostData);
bool PossiblyByteExpandedFileName(const nsAString& aIn);
bool PossiblyHostPortUrl(const nsACString& aUrl);
bool MakeAlternateURI(nsIURI* aURI);
bool IsDomainWhitelisted(const nsACString& aAsciiHost,
const uint32_t aDotLoc);
};
class nsDefaultURIFixupInfo : public nsIURIFixupInfo
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIURIFIXUPINFO
explicit nsDefaultURIFixupInfo(const nsACString& aOriginalInput);
friend class nsDefaultURIFixup;
protected:
virtual ~nsDefaultURIFixupInfo();
private:
nsCOMPtr<nsISupports> mConsumer;
nsCOMPtr<nsIURI> mPreferredURI;
nsCOMPtr<nsIURI> mFixedURI;
bool mFixupChangedProtocol;
bool mFixupCreatedAlternateURI;
nsString mKeywordProviderName;
nsString mKeywordAsSent;
nsCString mOriginalInput;
};
#endif

14853
docshell/base/nsDocShell.cpp Normal file

File diff suppressed because it is too large Load diff

1083
docshell/base/nsDocShell.h Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,192 @@
/* -*- 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 "nsDocShellEditorData.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsComponentManagerUtils.h"
#include "nsPIDOMWindow.h"
#include "nsIDOMDocument.h"
#include "nsIEditor.h"
#include "nsIEditingSession.h"
#include "nsIDocShell.h"
nsDocShellEditorData::nsDocShellEditorData(nsIDocShell* aOwningDocShell)
: mDocShell(aOwningDocShell)
, mMakeEditable(false)
, mIsDetached(false)
, mDetachedMakeEditable(false)
, mDetachedEditingState(nsIHTMLDocument::eOff)
{
NS_ASSERTION(mDocShell, "Where is my docShell?");
}
nsDocShellEditorData::~nsDocShellEditorData()
{
TearDownEditor();
}
void
nsDocShellEditorData::TearDownEditor()
{
if (mEditor) {
mEditor->PreDestroy(false);
mEditor = nullptr;
}
mEditingSession = nullptr;
mIsDetached = false;
}
nsresult
nsDocShellEditorData::MakeEditable(bool aInWaitForUriLoad)
{
if (mMakeEditable) {
return NS_OK;
}
// if we are already editable, and are getting turned off,
// nuke the editor.
if (mEditor) {
NS_WARNING("Destroying existing editor on frame");
mEditor->PreDestroy(false);
mEditor = nullptr;
}
if (aInWaitForUriLoad) {
mMakeEditable = true;
}
return NS_OK;
}
bool
nsDocShellEditorData::GetEditable()
{
return mMakeEditable || (mEditor != nullptr);
}
nsresult
nsDocShellEditorData::CreateEditor()
{
nsCOMPtr<nsIEditingSession> editingSession;
nsresult rv = GetEditingSession(getter_AddRefs(editingSession));
if (NS_FAILED(rv)) {
return rv;
}
nsCOMPtr<nsPIDOMWindowOuter> domWindow =
mDocShell ? mDocShell->GetWindow() : nullptr;
rv = editingSession->SetupEditorOnWindow(domWindow);
if (NS_FAILED(rv)) {
return rv;
}
return NS_OK;
}
nsresult
nsDocShellEditorData::GetEditingSession(nsIEditingSession** aResult)
{
nsresult rv = EnsureEditingSession();
NS_ENSURE_SUCCESS(rv, rv);
NS_ADDREF(*aResult = mEditingSession);
return NS_OK;
}
nsresult
nsDocShellEditorData::GetEditor(nsIEditor** aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
NS_IF_ADDREF(*aResult = mEditor);
return NS_OK;
}
nsresult
nsDocShellEditorData::SetEditor(nsIEditor* aEditor)
{
// destroy any editor that we have. Checks for equality are
// necessary to ensure that assigment into the nsCOMPtr does
// not temporarily reduce the refCount of the editor to zero
if (mEditor.get() != aEditor) {
if (mEditor) {
mEditor->PreDestroy(false);
mEditor = nullptr;
}
mEditor = aEditor; // owning addref
if (!mEditor) {
mMakeEditable = false;
}
}
return NS_OK;
}
// This creates the editing session on the content docShell that owns 'this'.
nsresult
nsDocShellEditorData::EnsureEditingSession()
{
NS_ASSERTION(mDocShell, "Should have docShell here");
NS_ASSERTION(!mIsDetached, "This will stomp editing session!");
nsresult rv = NS_OK;
if (!mEditingSession) {
mEditingSession =
do_CreateInstance("@mozilla.org/editor/editingsession;1", &rv);
}
return rv;
}
nsresult
nsDocShellEditorData::DetachFromWindow()
{
NS_ASSERTION(mEditingSession,
"Can't detach when we don't have a session to detach!");
nsCOMPtr<nsPIDOMWindowOuter> domWindow =
mDocShell ? mDocShell->GetWindow() : nullptr;
nsresult rv = mEditingSession->DetachFromWindow(domWindow);
NS_ENSURE_SUCCESS(rv, rv);
mIsDetached = true;
mDetachedMakeEditable = mMakeEditable;
mMakeEditable = false;
nsCOMPtr<nsIDocument> doc = domWindow->GetDoc();
nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(doc);
if (htmlDoc) {
mDetachedEditingState = htmlDoc->GetEditingState();
}
mDocShell = nullptr;
return NS_OK;
}
nsresult
nsDocShellEditorData::ReattachToWindow(nsIDocShell* aDocShell)
{
mDocShell = aDocShell;
nsCOMPtr<nsPIDOMWindowOuter> domWindow =
mDocShell ? mDocShell->GetWindow() : nullptr;
nsresult rv = mEditingSession->ReattachToWindow(domWindow);
NS_ENSURE_SUCCESS(rv, rv);
mIsDetached = false;
mMakeEditable = mDetachedMakeEditable;
nsCOMPtr<nsIDocument> doc = domWindow->GetDoc();
nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(doc);
if (htmlDoc) {
htmlDoc->SetEditingState(mDetachedEditingState);
}
return NS_OK;
}

View file

@ -0,0 +1,63 @@
/* -*- 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 nsDocShellEditorData_h__
#define nsDocShellEditorData_h__
#ifndef nsCOMPtr_h___
#include "nsCOMPtr.h"
#endif
#include "nsIHTMLDocument.h"
class nsIDocShell;
class nsIEditingSession;
class nsIEditor;
class nsDocShellEditorData
{
public:
explicit nsDocShellEditorData(nsIDocShell* aOwningDocShell);
~nsDocShellEditorData();
nsresult MakeEditable(bool aWaitForUriLoad);
bool GetEditable();
nsresult CreateEditor();
nsresult GetEditingSession(nsIEditingSession** aResult);
nsresult GetEditor(nsIEditor** aResult);
nsresult SetEditor(nsIEditor* aEditor);
void TearDownEditor();
nsresult DetachFromWindow();
nsresult ReattachToWindow(nsIDocShell* aDocShell);
bool WaitingForLoad() const { return mMakeEditable; }
protected:
nsresult EnsureEditingSession();
// The doc shell that owns us. Weak ref, since it always outlives us.
nsIDocShell* mDocShell;
// Only present for the content root docShell. Session is owned here.
nsCOMPtr<nsIEditingSession> mEditingSession;
// Indicates whether to make an editor after a url load.
bool mMakeEditable;
// If this frame is editable, store editor here. Editor is owned here.
nsCOMPtr<nsIEditor> mEditor;
// Denotes if the editor is detached from its window. The editor is detached
// while it's stored in the session history bfcache.
bool mIsDetached;
// Backup for mMakeEditable while the editor is detached.
bool mDetachedMakeEditable;
// Backup for the corresponding nsIHTMLDocument's editing state while
// the editor is detached.
nsIHTMLDocument::EditingState mDetachedEditingState;
};
#endif // nsDocShellEditorData_h__

View file

@ -0,0 +1,205 @@
/* -*- 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 "nsDocShellEnumerator.h"
#include "nsIDocShellTreeItem.h"
nsDocShellEnumerator::nsDocShellEnumerator(int32_t aEnumerationDirection)
: mRootItem(nullptr)
, mCurIndex(0)
, mDocShellType(nsIDocShellTreeItem::typeAll)
, mArrayValid(false)
, mEnumerationDirection(aEnumerationDirection)
{
}
nsDocShellEnumerator::~nsDocShellEnumerator()
{
}
NS_IMPL_ISUPPORTS(nsDocShellEnumerator, nsISimpleEnumerator)
NS_IMETHODIMP
nsDocShellEnumerator::GetNext(nsISupports** aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
*aResult = nullptr;
nsresult rv = EnsureDocShellArray();
if (NS_FAILED(rv)) {
return rv;
}
if (mCurIndex >= mItemArray.Length()) {
return NS_ERROR_FAILURE;
}
// post-increment is important here
nsCOMPtr<nsISupports> item = do_QueryReferent(mItemArray[mCurIndex++], &rv);
item.forget(aResult);
return rv;
}
NS_IMETHODIMP
nsDocShellEnumerator::HasMoreElements(bool* aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
*aResult = false;
nsresult rv = EnsureDocShellArray();
if (NS_FAILED(rv)) {
return rv;
}
*aResult = (mCurIndex < mItemArray.Length());
return NS_OK;
}
nsresult
nsDocShellEnumerator::GetEnumerationRootItem(
nsIDocShellTreeItem** aEnumerationRootItem)
{
NS_ENSURE_ARG_POINTER(aEnumerationRootItem);
nsCOMPtr<nsIDocShellTreeItem> item = do_QueryReferent(mRootItem);
item.forget(aEnumerationRootItem);
return NS_OK;
}
nsresult
nsDocShellEnumerator::SetEnumerationRootItem(
nsIDocShellTreeItem* aEnumerationRootItem)
{
mRootItem = do_GetWeakReference(aEnumerationRootItem);
ClearState();
return NS_OK;
}
nsresult
nsDocShellEnumerator::GetEnumDocShellType(int32_t* aEnumerationItemType)
{
NS_ENSURE_ARG_POINTER(aEnumerationItemType);
*aEnumerationItemType = mDocShellType;
return NS_OK;
}
nsresult
nsDocShellEnumerator::SetEnumDocShellType(int32_t aEnumerationItemType)
{
mDocShellType = aEnumerationItemType;
ClearState();
return NS_OK;
}
nsresult
nsDocShellEnumerator::First()
{
mCurIndex = 0;
return EnsureDocShellArray();
}
nsresult
nsDocShellEnumerator::EnsureDocShellArray()
{
if (!mArrayValid) {
mArrayValid = true;
return BuildDocShellArray(mItemArray);
}
return NS_OK;
}
nsresult
nsDocShellEnumerator::ClearState()
{
mItemArray.Clear();
mArrayValid = false;
mCurIndex = 0;
return NS_OK;
}
nsresult
nsDocShellEnumerator::BuildDocShellArray(nsTArray<nsWeakPtr>& aItemArray)
{
NS_ENSURE_TRUE(mRootItem, NS_ERROR_NOT_INITIALIZED);
aItemArray.Clear();
nsCOMPtr<nsIDocShellTreeItem> item = do_QueryReferent(mRootItem);
return BuildArrayRecursive(item, aItemArray);
}
nsresult
nsDocShellForwardsEnumerator::BuildArrayRecursive(
nsIDocShellTreeItem* aItem,
nsTArray<nsWeakPtr>& aItemArray)
{
nsresult rv;
// add this item to the array
if (mDocShellType == nsIDocShellTreeItem::typeAll ||
aItem->ItemType() == mDocShellType) {
if (!aItemArray.AppendElement(do_GetWeakReference(aItem))) {
return NS_ERROR_OUT_OF_MEMORY;
}
}
int32_t numChildren;
rv = aItem->GetChildCount(&numChildren);
if (NS_FAILED(rv)) {
return rv;
}
for (int32_t i = 0; i < numChildren; ++i) {
nsCOMPtr<nsIDocShellTreeItem> curChild;
rv = aItem->GetChildAt(i, getter_AddRefs(curChild));
if (NS_FAILED(rv)) {
return rv;
}
rv = BuildArrayRecursive(curChild, aItemArray);
if (NS_FAILED(rv)) {
return rv;
}
}
return NS_OK;
}
nsresult
nsDocShellBackwardsEnumerator::BuildArrayRecursive(
nsIDocShellTreeItem* aItem,
nsTArray<nsWeakPtr>& aItemArray)
{
nsresult rv;
int32_t numChildren;
rv = aItem->GetChildCount(&numChildren);
if (NS_FAILED(rv)) {
return rv;
}
for (int32_t i = numChildren - 1; i >= 0; --i) {
nsCOMPtr<nsIDocShellTreeItem> curChild;
rv = aItem->GetChildAt(i, getter_AddRefs(curChild));
if (NS_FAILED(rv)) {
return rv;
}
rv = BuildArrayRecursive(curChild, aItemArray);
if (NS_FAILED(rv)) {
return rv;
}
}
// add this item to the array
if (mDocShellType == nsIDocShellTreeItem::typeAll ||
aItem->ItemType() == mDocShellType) {
if (!aItemArray.AppendElement(do_GetWeakReference(aItem))) {
return NS_ERROR_OUT_OF_MEMORY;
}
}
return NS_OK;
}

View file

@ -0,0 +1,107 @@
/* -*- 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 nsDocShellEnumerator_h___
#define nsDocShellEnumerator_h___
#include "nsISimpleEnumerator.h"
#include "nsTArray.h"
#include "nsIWeakReferenceUtils.h"
class nsIDocShellTreeItem;
/*
// {13cbc281-35ae-11d5-be5b-bde0edece43c}
#define NS_DOCSHELL_FORWARDS_ENUMERATOR_CID \
{ 0x13cbc281, 0x35ae, 0x11d5, { 0xbe, 0x5b, 0xbd, 0xe0, 0xed, 0xec, 0xe4, 0x3c } }
#define NS_DOCSHELL_FORWARDS_ENUMERATOR_CONTRACTID \
"@mozilla.org/docshell/enumerator-forwards;1"
// {13cbc282-35ae-11d5-be5b-bde0edece43c}
#define NS_DOCSHELL_BACKWARDS_ENUMERATOR_CID \
{ 0x13cbc282, 0x35ae, 0x11d5, { 0xbe, 0x5b, 0xbd, 0xe0, 0xed, 0xec, 0xe4, 0x3c } }
#define NS_DOCSHELL_BACKWARDS_ENUMERATOR_CONTRACTID \
"@mozilla.org/docshell/enumerator-backwards;1"
*/
class nsDocShellEnumerator : public nsISimpleEnumerator
{
protected:
enum
{
enumerateForwards,
enumerateBackwards
};
virtual ~nsDocShellEnumerator();
public:
explicit nsDocShellEnumerator(int32_t aEnumerationDirection);
// nsISupports
NS_DECL_ISUPPORTS
// nsISimpleEnumerator
NS_DECL_NSISIMPLEENUMERATOR
public:
nsresult GetEnumerationRootItem(nsIDocShellTreeItem** aEnumerationRootItem);
nsresult SetEnumerationRootItem(nsIDocShellTreeItem* aEnumerationRootItem);
nsresult GetEnumDocShellType(int32_t* aEnumerationItemType);
nsresult SetEnumDocShellType(int32_t aEnumerationItemType);
nsresult First();
protected:
nsresult EnsureDocShellArray();
nsresult ClearState();
nsresult BuildDocShellArray(nsTArray<nsWeakPtr>& aItemArray);
virtual nsresult BuildArrayRecursive(nsIDocShellTreeItem* aItem,
nsTArray<nsWeakPtr>& aItemArray) = 0;
protected:
nsWeakPtr mRootItem; // weak ref!
nsTArray<nsWeakPtr> mItemArray; // flattened list of items with matching type
uint32_t mCurIndex;
int32_t mDocShellType; // only want shells of this type
bool mArrayValid; // is mItemArray up to date?
const int8_t mEnumerationDirection;
};
class nsDocShellForwardsEnumerator : public nsDocShellEnumerator
{
public:
nsDocShellForwardsEnumerator()
: nsDocShellEnumerator(enumerateForwards)
{
}
protected:
virtual nsresult BuildArrayRecursive(nsIDocShellTreeItem* aItem,
nsTArray<nsWeakPtr>& aItemArray);
};
class nsDocShellBackwardsEnumerator : public nsDocShellEnumerator
{
public:
nsDocShellBackwardsEnumerator()
: nsDocShellEnumerator(enumerateBackwards)
{
}
protected:
virtual nsresult BuildArrayRecursive(nsIDocShellTreeItem* aItem,
nsTArray<nsWeakPtr>& aItemArray);
};
#endif // nsDocShellEnumerator_h___

View file

@ -0,0 +1,297 @@
/* -*- 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 "nsDocShellLoadInfo.h"
#include "nsISHEntry.h"
#include "nsIInputStream.h"
#include "nsIURI.h"
#include "nsIDocShell.h"
#include "mozilla/net/ReferrerPolicy.h"
nsDocShellLoadInfo::nsDocShellLoadInfo()
: mLoadReplace(false)
, mInheritPrincipal(false)
, mPrincipalIsExplicit(false)
, mSendReferrer(true)
, mReferrerPolicy(mozilla::net::RP_Default)
, mLoadType(nsIDocShellLoadInfo::loadNormal)
, mIsSrcdocLoad(false)
{
}
nsDocShellLoadInfo::~nsDocShellLoadInfo()
{
}
NS_IMPL_ADDREF(nsDocShellLoadInfo)
NS_IMPL_RELEASE(nsDocShellLoadInfo)
NS_INTERFACE_MAP_BEGIN(nsDocShellLoadInfo)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDocShellLoadInfo)
NS_INTERFACE_MAP_ENTRY(nsIDocShellLoadInfo)
NS_INTERFACE_MAP_END
NS_IMETHODIMP
nsDocShellLoadInfo::GetReferrer(nsIURI** aReferrer)
{
NS_ENSURE_ARG_POINTER(aReferrer);
*aReferrer = mReferrer;
NS_IF_ADDREF(*aReferrer);
return NS_OK;
}
NS_IMETHODIMP
nsDocShellLoadInfo::SetReferrer(nsIURI* aReferrer)
{
mReferrer = aReferrer;
return NS_OK;
}
NS_IMETHODIMP
nsDocShellLoadInfo::GetOriginalURI(nsIURI** aOriginalURI)
{
NS_ENSURE_ARG_POINTER(aOriginalURI);
*aOriginalURI = mOriginalURI;
NS_IF_ADDREF(*aOriginalURI);
return NS_OK;
}
NS_IMETHODIMP
nsDocShellLoadInfo::SetOriginalURI(nsIURI* aOriginalURI)
{
mOriginalURI = aOriginalURI;
return NS_OK;
}
NS_IMETHODIMP
nsDocShellLoadInfo::GetLoadReplace(bool* aLoadReplace)
{
*aLoadReplace = mLoadReplace;
return NS_OK;
}
NS_IMETHODIMP
nsDocShellLoadInfo::SetLoadReplace(bool aLoadReplace)
{
mLoadReplace = aLoadReplace;
return NS_OK;
}
NS_IMETHODIMP
nsDocShellLoadInfo::GetTriggeringPrincipal(nsIPrincipal** aTriggeringPrincipal)
{
NS_ENSURE_ARG_POINTER(aTriggeringPrincipal);
NS_IF_ADDREF(*aTriggeringPrincipal = mTriggeringPrincipal);
return NS_OK;
}
NS_IMETHODIMP
nsDocShellLoadInfo::SetTriggeringPrincipal(nsIPrincipal* aTriggeringPrincipal)
{
mTriggeringPrincipal = aTriggeringPrincipal;
return NS_OK;
}
NS_IMETHODIMP
nsDocShellLoadInfo::GetInheritPrincipal(bool* aInheritPrincipal)
{
NS_ENSURE_ARG_POINTER(aInheritPrincipal);
*aInheritPrincipal = mInheritPrincipal;
return NS_OK;
}
NS_IMETHODIMP
nsDocShellLoadInfo::SetInheritPrincipal(bool aInheritPrincipal)
{
mInheritPrincipal = aInheritPrincipal;
return NS_OK;
}
NS_IMETHODIMP
nsDocShellLoadInfo::GetPrincipalIsExplicit(bool* aPrincipalIsExplicit)
{
*aPrincipalIsExplicit = mPrincipalIsExplicit;
return NS_OK;
}
NS_IMETHODIMP
nsDocShellLoadInfo::SetPrincipalIsExplicit(bool aPrincipalIsExplicit)
{
mPrincipalIsExplicit = aPrincipalIsExplicit;
return NS_OK;
}
NS_IMETHODIMP
nsDocShellLoadInfo::GetLoadType(nsDocShellInfoLoadType* aLoadType)
{
NS_ENSURE_ARG_POINTER(aLoadType);
*aLoadType = mLoadType;
return NS_OK;
}
NS_IMETHODIMP
nsDocShellLoadInfo::SetLoadType(nsDocShellInfoLoadType aLoadType)
{
mLoadType = aLoadType;
return NS_OK;
}
NS_IMETHODIMP
nsDocShellLoadInfo::GetSHEntry(nsISHEntry** aSHEntry)
{
NS_ENSURE_ARG_POINTER(aSHEntry);
*aSHEntry = mSHEntry;
NS_IF_ADDREF(*aSHEntry);
return NS_OK;
}
NS_IMETHODIMP
nsDocShellLoadInfo::SetSHEntry(nsISHEntry* aSHEntry)
{
mSHEntry = aSHEntry;
return NS_OK;
}
NS_IMETHODIMP
nsDocShellLoadInfo::GetTarget(char16_t** aTarget)
{
NS_ENSURE_ARG_POINTER(aTarget);
*aTarget = ToNewUnicode(mTarget);
return NS_OK;
}
NS_IMETHODIMP
nsDocShellLoadInfo::SetTarget(const char16_t* aTarget)
{
mTarget.Assign(aTarget);
return NS_OK;
}
NS_IMETHODIMP
nsDocShellLoadInfo::GetPostDataStream(nsIInputStream** aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
*aResult = mPostDataStream;
NS_IF_ADDREF(*aResult);
return NS_OK;
}
NS_IMETHODIMP
nsDocShellLoadInfo::SetPostDataStream(nsIInputStream* aStream)
{
mPostDataStream = aStream;
return NS_OK;
}
NS_IMETHODIMP
nsDocShellLoadInfo::GetHeadersStream(nsIInputStream** aHeadersStream)
{
NS_ENSURE_ARG_POINTER(aHeadersStream);
*aHeadersStream = mHeadersStream;
NS_IF_ADDREF(*aHeadersStream);
return NS_OK;
}
NS_IMETHODIMP
nsDocShellLoadInfo::SetHeadersStream(nsIInputStream* aHeadersStream)
{
mHeadersStream = aHeadersStream;
return NS_OK;
}
NS_IMETHODIMP
nsDocShellLoadInfo::GetSendReferrer(bool* aSendReferrer)
{
NS_ENSURE_ARG_POINTER(aSendReferrer);
*aSendReferrer = mSendReferrer;
return NS_OK;
}
NS_IMETHODIMP
nsDocShellLoadInfo::SetSendReferrer(bool aSendReferrer)
{
mSendReferrer = aSendReferrer;
return NS_OK;
}
NS_IMETHODIMP
nsDocShellLoadInfo::GetReferrerPolicy(
nsDocShellInfoReferrerPolicy* aReferrerPolicy)
{
*aReferrerPolicy = mReferrerPolicy;
return NS_OK;
}
NS_IMETHODIMP
nsDocShellLoadInfo::SetReferrerPolicy(
nsDocShellInfoReferrerPolicy aReferrerPolicy)
{
mReferrerPolicy = aReferrerPolicy;
return NS_OK;
}
NS_IMETHODIMP
nsDocShellLoadInfo::GetIsSrcdocLoad(bool* aIsSrcdocLoad)
{
*aIsSrcdocLoad = mIsSrcdocLoad;
return NS_OK;
}
NS_IMETHODIMP
nsDocShellLoadInfo::GetSrcdocData(nsAString& aSrcdocData)
{
aSrcdocData = mSrcdocData;
return NS_OK;
}
NS_IMETHODIMP
nsDocShellLoadInfo::SetSrcdocData(const nsAString& aSrcdocData)
{
mSrcdocData = aSrcdocData;
mIsSrcdocLoad = true;
return NS_OK;
}
NS_IMETHODIMP
nsDocShellLoadInfo::GetSourceDocShell(nsIDocShell** aSourceDocShell)
{
MOZ_ASSERT(aSourceDocShell);
nsCOMPtr<nsIDocShell> result = mSourceDocShell;
result.forget(aSourceDocShell);
return NS_OK;
}
NS_IMETHODIMP
nsDocShellLoadInfo::SetSourceDocShell(nsIDocShell* aSourceDocShell)
{
mSourceDocShell = aSourceDocShell;
return NS_OK;
}
NS_IMETHODIMP
nsDocShellLoadInfo::GetBaseURI(nsIURI** aBaseURI)
{
NS_ENSURE_ARG_POINTER(aBaseURI);
*aBaseURI = mBaseURI;
NS_IF_ADDREF(*aBaseURI);
return NS_OK;
}
NS_IMETHODIMP
nsDocShellLoadInfo::SetBaseURI(nsIURI* aBaseURI)
{
mBaseURI = aBaseURI;
return NS_OK;
}

View file

@ -0,0 +1,53 @@
/* -*- 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 nsDocShellLoadInfo_h__
#define nsDocShellLoadInfo_h__
// Helper Classes
#include "nsCOMPtr.h"
#include "nsString.h"
// Interfaces Needed
#include "nsIDocShellLoadInfo.h"
class nsIInputStream;
class nsISHEntry;
class nsIURI;
class nsIDocShell;
class nsDocShellLoadInfo : public nsIDocShellLoadInfo
{
public:
nsDocShellLoadInfo();
NS_DECL_ISUPPORTS
NS_DECL_NSIDOCSHELLLOADINFO
protected:
virtual ~nsDocShellLoadInfo();
protected:
nsCOMPtr<nsIURI> mReferrer;
nsCOMPtr<nsIURI> mOriginalURI;
nsCOMPtr<nsIPrincipal> mTriggeringPrincipal;
bool mLoadReplace;
bool mInheritPrincipal;
bool mPrincipalIsExplicit;
bool mSendReferrer;
nsDocShellInfoReferrerPolicy mReferrerPolicy;
nsDocShellInfoLoadType mLoadType;
nsCOMPtr<nsISHEntry> mSHEntry;
nsString mTarget;
nsCOMPtr<nsIInputStream> mPostDataStream;
nsCOMPtr<nsIInputStream> mHeadersStream;
bool mIsSrcdocLoad;
nsString mSrcdocData;
nsCOMPtr<nsIDocShell> mSourceDocShell;
nsCOMPtr<nsIURI> mBaseURI;
};
#endif /* nsDocShellLoadInfo_h__ */

View file

@ -0,0 +1,117 @@
/* -*- 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 nsDocShellLoadTypes_h_
#define nsDocShellLoadTypes_h_
#ifdef MOZILLA_INTERNAL_API
#include "nsIDocShell.h"
#include "nsIWebNavigation.h"
/**
* Load flag for error pages. This uses one of the reserved flag
* values from nsIWebNavigation.
*/
#define LOAD_FLAGS_ERROR_PAGE 0x0001U
#define MAKE_LOAD_TYPE(type, flags) ((type) | ((flags) << 16))
#define LOAD_TYPE_HAS_FLAGS(type, flags) ((type) & ((flags) << 16))
/**
* These are flags that confuse ConvertLoadTypeToDocShellLoadInfo and should
* not be passed to MAKE_LOAD_TYPE. In particular this includes all flags
* above 0xffff (e.g. LOAD_FLAGS_BYPASS_CLASSIFIER), since MAKE_LOAD_TYPE would
* just shift them out anyway.
*/
#define EXTRA_LOAD_FLAGS (LOAD_FLAGS_FIRST_LOAD | \
LOAD_FLAGS_ALLOW_POPUPS | \
0xffff0000)
/* load types are legal combinations of load commands and flags
*
* NOTE:
* Remember to update the IsValidLoadType function below if you change this
* enum to ensure bad flag combinations will be rejected.
*/
enum LoadType
{
LOAD_NORMAL = MAKE_LOAD_TYPE(nsIDocShell::LOAD_CMD_NORMAL, nsIWebNavigation::LOAD_FLAGS_NONE),
LOAD_NORMAL_REPLACE = MAKE_LOAD_TYPE(nsIDocShell::LOAD_CMD_NORMAL, nsIWebNavigation::LOAD_FLAGS_REPLACE_HISTORY),
LOAD_NORMAL_EXTERNAL = MAKE_LOAD_TYPE(nsIDocShell::LOAD_CMD_NORMAL, nsIWebNavigation::LOAD_FLAGS_FROM_EXTERNAL),
LOAD_HISTORY = MAKE_LOAD_TYPE(nsIDocShell::LOAD_CMD_HISTORY, nsIWebNavigation::LOAD_FLAGS_NONE),
LOAD_NORMAL_BYPASS_CACHE = MAKE_LOAD_TYPE(nsIDocShell::LOAD_CMD_NORMAL, nsIWebNavigation::LOAD_FLAGS_BYPASS_CACHE),
LOAD_NORMAL_BYPASS_PROXY = MAKE_LOAD_TYPE(nsIDocShell::LOAD_CMD_NORMAL, nsIWebNavigation::LOAD_FLAGS_BYPASS_PROXY),
LOAD_NORMAL_BYPASS_PROXY_AND_CACHE = MAKE_LOAD_TYPE(nsIDocShell::LOAD_CMD_NORMAL, nsIWebNavigation::LOAD_FLAGS_BYPASS_CACHE | nsIWebNavigation::LOAD_FLAGS_BYPASS_PROXY),
LOAD_NORMAL_ALLOW_MIXED_CONTENT = MAKE_LOAD_TYPE(nsIDocShell::LOAD_CMD_NORMAL, nsIWebNavigation::LOAD_FLAGS_ALLOW_MIXED_CONTENT | nsIWebNavigation::LOAD_FLAGS_BYPASS_CACHE),
LOAD_RELOAD_NORMAL = MAKE_LOAD_TYPE(nsIDocShell::LOAD_CMD_RELOAD, nsIWebNavigation::LOAD_FLAGS_NONE),
LOAD_RELOAD_BYPASS_CACHE = MAKE_LOAD_TYPE(nsIDocShell::LOAD_CMD_RELOAD, nsIWebNavigation::LOAD_FLAGS_BYPASS_CACHE),
LOAD_RELOAD_BYPASS_PROXY = MAKE_LOAD_TYPE(nsIDocShell::LOAD_CMD_RELOAD, nsIWebNavigation::LOAD_FLAGS_BYPASS_PROXY),
LOAD_RELOAD_ALLOW_MIXED_CONTENT = MAKE_LOAD_TYPE(nsIDocShell::LOAD_CMD_RELOAD, nsIWebNavigation::LOAD_FLAGS_ALLOW_MIXED_CONTENT | nsIWebNavigation::LOAD_FLAGS_BYPASS_CACHE),
LOAD_RELOAD_BYPASS_PROXY_AND_CACHE = MAKE_LOAD_TYPE(nsIDocShell::LOAD_CMD_RELOAD, nsIWebNavigation::LOAD_FLAGS_BYPASS_CACHE | nsIWebNavigation::LOAD_FLAGS_BYPASS_PROXY),
LOAD_LINK = MAKE_LOAD_TYPE(nsIDocShell::LOAD_CMD_NORMAL, nsIWebNavigation::LOAD_FLAGS_IS_LINK),
LOAD_REFRESH = MAKE_LOAD_TYPE(nsIDocShell::LOAD_CMD_NORMAL, nsIWebNavigation::LOAD_FLAGS_IS_REFRESH),
LOAD_RELOAD_CHARSET_CHANGE = MAKE_LOAD_TYPE(nsIDocShell::LOAD_CMD_RELOAD, nsIWebNavigation::LOAD_FLAGS_CHARSET_CHANGE),
LOAD_BYPASS_HISTORY = MAKE_LOAD_TYPE(nsIDocShell::LOAD_CMD_NORMAL, nsIWebNavigation::LOAD_FLAGS_BYPASS_HISTORY),
LOAD_STOP_CONTENT = MAKE_LOAD_TYPE(nsIDocShell::LOAD_CMD_NORMAL, nsIWebNavigation::LOAD_FLAGS_STOP_CONTENT),
LOAD_STOP_CONTENT_AND_REPLACE = MAKE_LOAD_TYPE(nsIDocShell::LOAD_CMD_NORMAL, nsIWebNavigation::LOAD_FLAGS_STOP_CONTENT | nsIWebNavigation::LOAD_FLAGS_REPLACE_HISTORY),
LOAD_PUSHSTATE = MAKE_LOAD_TYPE(nsIDocShell::LOAD_CMD_PUSHSTATE, nsIWebNavigation::LOAD_FLAGS_NONE),
LOAD_REPLACE_BYPASS_CACHE = MAKE_LOAD_TYPE(nsIDocShell::LOAD_CMD_NORMAL, nsIWebNavigation::LOAD_FLAGS_REPLACE_HISTORY | nsIWebNavigation::LOAD_FLAGS_BYPASS_CACHE),
/**
* Load type for an error page. These loads are never triggered by users of
* Docshell. Instead, Docshell triggers the load itself when a
* consumer-triggered load failed.
*/
LOAD_ERROR_PAGE = MAKE_LOAD_TYPE(nsIDocShell::LOAD_CMD_NORMAL,
LOAD_FLAGS_ERROR_PAGE)
// NOTE: Adding a new value? Remember to update IsValidLoadType!
};
static inline bool
IsValidLoadType(uint32_t aLoadType)
{
switch (aLoadType) {
case LOAD_NORMAL:
case LOAD_NORMAL_REPLACE:
case LOAD_NORMAL_EXTERNAL:
case LOAD_NORMAL_BYPASS_CACHE:
case LOAD_NORMAL_BYPASS_PROXY:
case LOAD_NORMAL_BYPASS_PROXY_AND_CACHE:
case LOAD_NORMAL_ALLOW_MIXED_CONTENT:
case LOAD_HISTORY:
case LOAD_RELOAD_NORMAL:
case LOAD_RELOAD_BYPASS_CACHE:
case LOAD_RELOAD_BYPASS_PROXY:
case LOAD_RELOAD_BYPASS_PROXY_AND_CACHE:
case LOAD_RELOAD_ALLOW_MIXED_CONTENT:
case LOAD_LINK:
case LOAD_REFRESH:
case LOAD_RELOAD_CHARSET_CHANGE:
case LOAD_BYPASS_HISTORY:
case LOAD_STOP_CONTENT:
case LOAD_STOP_CONTENT_AND_REPLACE:
case LOAD_PUSHSTATE:
case LOAD_REPLACE_BYPASS_CACHE:
case LOAD_ERROR_PAGE:
return true;
}
return false;
}
static inline bool
IsForceReloadType(uint32_t aLoadType) {
switch (aLoadType) {
case LOAD_RELOAD_BYPASS_CACHE:
case LOAD_RELOAD_BYPASS_PROXY:
case LOAD_RELOAD_BYPASS_PROXY_AND_CACHE:
case LOAD_RELOAD_ALLOW_MIXED_CONTENT:
return true;
}
return false;
}
#endif // MOZILLA_INTERNAL_API
#endif

View file

@ -0,0 +1,54 @@
/* -*- 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 "nsDocShellTransferableHooks.h"
#include "nsIClipboardDragDropHooks.h"
#include "nsIClipboardDragDropHookList.h"
#include "nsArrayEnumerator.h"
nsTransferableHookData::nsTransferableHookData()
{
}
nsTransferableHookData::~nsTransferableHookData()
{
}
NS_IMPL_ISUPPORTS(nsTransferableHookData, nsIClipboardDragDropHookList)
NS_IMETHODIMP
nsTransferableHookData::AddClipboardDragDropHooks(
nsIClipboardDragDropHooks* aOverrides)
{
NS_ENSURE_ARG(aOverrides);
// don't let a hook be added more than once
if (mHookList.IndexOfObject(aOverrides) == -1) {
if (!mHookList.AppendObject(aOverrides)) {
return NS_ERROR_FAILURE;
}
}
return NS_OK;
}
NS_IMETHODIMP
nsTransferableHookData::RemoveClipboardDragDropHooks(
nsIClipboardDragDropHooks* aOverrides)
{
NS_ENSURE_ARG(aOverrides);
if (!mHookList.RemoveObject(aOverrides)) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
NS_IMETHODIMP
nsTransferableHookData::GetHookEnumerator(nsISimpleEnumerator** aResult)
{
return NS_NewArrayEnumerator(aResult, mHookList);
}

View file

@ -0,0 +1,28 @@
/* -*- 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 nsDocShellTransferableHooks_h__
#define nsDocShellTransferableHooks_h__
#include "nsIClipboardDragDropHookList.h"
#include "nsCOMArray.h"
class nsIClipboardDragDropHooks;
class nsTransferableHookData : public nsIClipboardDragDropHookList
{
public:
nsTransferableHookData();
NS_DECL_ISUPPORTS
NS_DECL_NSICLIPBOARDDRAGDROPHOOKLIST
protected:
virtual ~nsTransferableHookData();
nsCOMArray<nsIClipboardDragDropHooks> mHookList;
};
#endif // nsDocShellTransferableHooks_h__

View file

@ -0,0 +1,52 @@
/* -*- 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 "nsDownloadHistory.h"
#include "nsCOMPtr.h"
#include "nsServiceManagerUtils.h"
#include "nsIGlobalHistory2.h"
#include "nsIObserverService.h"
#include "nsIURI.h"
#include "mozilla/Services.h"
NS_IMPL_ISUPPORTS(nsDownloadHistory, nsIDownloadHistory)
NS_IMETHODIMP
nsDownloadHistory::AddDownload(nsIURI* aSource,
nsIURI* aReferrer,
PRTime aStartTime,
nsIURI* aDestination)
{
NS_ENSURE_ARG_POINTER(aSource);
nsCOMPtr<nsIGlobalHistory2> history =
do_GetService("@mozilla.org/browser/global-history;2");
if (!history) {
return NS_ERROR_NOT_AVAILABLE;
}
bool visited;
nsresult rv = history->IsVisited(aSource, &visited);
NS_ENSURE_SUCCESS(rv, rv);
rv = history->AddURI(aSource, false, true, aReferrer);
NS_ENSURE_SUCCESS(rv, rv);
if (!visited) {
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
if (os) {
os->NotifyObservers(aSource, NS_LINK_VISITED_EVENT_TOPIC, nullptr);
}
}
return NS_OK;
}
NS_IMETHODIMP
nsDownloadHistory::RemoveAllDownloads()
{
return NS_ERROR_NOT_IMPLEMENTED;
}

View file

@ -0,0 +1,28 @@
/* -*- 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 __nsDownloadHistory_h__
#define __nsDownloadHistory_h__
#include "nsIDownloadHistory.h"
#include "mozilla/Attributes.h"
#define NS_DOWNLOADHISTORY_CID \
{0x2ee83680, 0x2af0, 0x4bcb, {0xbf, 0xa0, 0xc9, 0x70, 0x5f, 0x65, 0x54, 0xf1}}
class nsDownloadHistory final : public nsIDownloadHistory
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIDOWNLOADHISTORY
NS_DEFINE_STATIC_CID_ACCESSOR(NS_DOWNLOADHISTORY_CID)
private:
~nsDownloadHistory() {}
};
#endif // __nsDownloadHistory_h__

View file

@ -0,0 +1,111 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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 "nsISupports.idl"
/**
* An interface for embedding clients who wish to interact with
* the system-wide OS clipboard. Mozilla does not use a private
* clipboard, instead it places its data directly onto the system
* clipboard. The webshell implements this interface.
*/
[scriptable, uuid(b8100c90-73be-11d2-92a5-00105a1b0d64)]
interface nsIClipboardCommands : nsISupports {
/**
* Returns whether there is a selection and it is not read-only.
*
* @return <code>true</code> if the current selection can be cut,
* <code>false</code> otherwise.
*/
boolean canCutSelection();
/**
* Returns whether there is a selection and it is copyable.
*
* @return <code>true</code> if there is a selection,
* <code>false</code> otherwise.
*/
boolean canCopySelection();
/**
* Returns whether we can copy a link location.
*
* @return <code>true</code> if a link is selected,
* <code>false</code> otherwise.
*/
boolean canCopyLinkLocation();
/**
* Returns whether we can copy an image location.
*
* @return <code>true</code> if an image is selected,
<code>false</code> otherwise.
*/
boolean canCopyImageLocation();
/**
* Returns whether we can copy an image's contents.
*
* @return <code>true</code> if an image is selected,
* <code>false</code> otherwise
*/
boolean canCopyImageContents();
/**
* Returns whether the current contents of the clipboard can be
* pasted and if the current selection is not read-only.
*
* @return <code>true</code> there is data to paste on the clipboard
* and the current selection is not read-only,
* <code>false</code> otherwise
*/
boolean canPaste();
/**
* Cut the current selection onto the clipboard.
*/
void cutSelection();
/**
* Copy the current selection onto the clipboard.
*/
void copySelection();
/**
* Copy the link location of the current selection (e.g.,
* the |href| attribute of a selected |a| tag).
*/
void copyLinkLocation();
/**
* Copy the location of the selected image.
*/
void copyImageLocation();
/**
* Copy the contents of the selected image.
*/
void copyImageContents();
/**
* Paste the contents of the clipboard into the current selection.
*/
void paste();
/**
* Select the entire contents.
*/
void selectAll();
/**
* Clear the current selection (if any). Insertion point ends up
* at beginning of current selection.
*/
void selectNone();
};

View file

@ -0,0 +1,280 @@
/* 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 "nsISupports.idl"
interface nsIDocShell;
interface nsIDocument;
interface nsIDOMDocument;
interface nsIDOMNode;
interface nsISHEntry;
interface nsIPrintSettings;
%{ C++
#include "nsTArray.h"
#include "nsRect.h"
class nsIWidget;
class nsIPresShell;
class nsPresContext;
class nsView;
class nsDOMNavigationTiming;
%}
[ptr] native nsIWidgetPtr(nsIWidget);
[ref] native nsIntRectRef(nsIntRect);
[ptr] native nsIPresShellPtr(nsIPresShell);
[ptr] native nsPresContextPtr(nsPresContext);
[ptr] native nsViewPtr(nsView);
[ptr] native nsDOMNavigationTimingPtr(nsDOMNavigationTiming);
[ref] native nsIContentViewerTArray(nsTArray<nsCOMPtr<nsIContentViewer> >);
[scriptable, builtinclass, uuid(2da17016-7851-4a45-a7a8-00b360e01595)]
interface nsIContentViewer : nsISupports
{
[noscript] void init(in nsIWidgetPtr aParentWidget,
[const] in nsIntRectRef aBounds);
attribute nsIDocShell container;
[noscript,notxpcom,nostdcall] void loadStart(in nsIDocument aDoc);
void loadComplete(in nsresult aStatus);
[noscript] readonly attribute boolean loadCompleted;
/**
* Checks if the document wants to prevent unloading by firing beforeunload on
* the document, and if it does, prompts the user. The result is returned.
*/
boolean permitUnload();
/**
* Exposes whether we're blocked in a call to permitUnload.
*/
readonly attribute boolean inPermitUnload;
/**
* As above, but this passes around the aShouldPrompt argument to keep
* track of whether the user has responded to a prompt.
* Used internally by the scriptable version to ensure we only prompt once.
*/
[noscript,nostdcall] boolean permitUnloadInternal(inout boolean aShouldPrompt);
/**
* Exposes whether we're in the process of firing the beforeunload event.
* In this case, the corresponding docshell will not allow navigation.
*/
readonly attribute boolean beforeUnloadFiring;
void pageHide(in boolean isUnload);
/**
* All users of a content viewer are responsible for calling both
* close() and destroy(), in that order.
*
* close() should be called when the load of a new page for the next
* content viewer begins, and destroy() should be called when the next
* content viewer replaces this one.
*
* |historyEntry| sets the session history entry for the content viewer. If
* this is null, then Destroy() will be called on the document by close().
* If it is non-null, the document will not be destroyed, and the following
* actions will happen when destroy() is called (*):
* - Sanitize() will be called on the viewer's document
* - The content viewer will set the contentViewer property on the
* history entry, and release its reference (ownership reversal).
* - hide() will be called, and no further destruction will happen.
*
* (*) unless the document is currently being printed, in which case
* it will never be saved in session history.
*
*/
void close(in nsISHEntry historyEntry);
void destroy();
void stop();
attribute nsIDOMDocument DOMDocument;
/**
* Returns DOMDocument as nsIDocument and without addrefing.
*/
[noscript,notxpcom] nsIDocument getDocument();
[noscript] void getBounds(in nsIntRectRef aBounds);
[noscript] void setBounds([const] in nsIntRectRef aBounds);
/**
* The 'aFlags' argument to setBoundsWithFlags is a set of these bits.
*/
const unsigned long eDelayResize = 1;
[noscript] void setBoundsWithFlags([const] in nsIntRectRef aBounds,
in unsigned long aFlags);
/**
* The previous content viewer, which has been |close|d but not
* |destroy|ed.
*/
[noscript] attribute nsIContentViewer previousViewer;
void move(in long aX, in long aY);
void show();
void hide();
attribute boolean sticky;
/*
* This is called when the DOM window wants to be closed. Returns true
* if the window can close immediately. Otherwise, returns false and will
* close the DOM window as soon as practical.
*/
boolean requestWindowClose();
/**
* Attach the content viewer to its DOM window and docshell.
* @param aState A state object that might be useful in attaching the DOM
* window.
* @param aSHEntry The history entry that the content viewer was stored in.
* The entry must have the docshells for all of the child
* documents stored in its child shell list.
*/
void open(in nsISupports aState, in nsISHEntry aSHEntry);
/**
* Clears the current history entry. This is used if we need to clear out
* the saved presentation state.
*/
void clearHistoryEntry();
/**
* Change the layout to view the document with page layout (like print preview), but
* dynamic and editable (like Galley layout).
*/
void setPageMode(in boolean aPageMode, in nsIPrintSettings aPrintSettings);
/**
* Get the history entry that this viewer will save itself into when
* destroyed. Can return null
*/
readonly attribute nsISHEntry historyEntry;
/**
* Indicates when we're in a state where content shouldn't be allowed to
* trigger a tab-modal prompt (as opposed to a window-modal prompt) because
* we're part way through some operation (eg beforeunload) that shouldn't be
* rentrant if the user closes the tab while the prompt is showing.
* See bug 613800.
*/
readonly attribute boolean isTabModalPromptAllowed;
/**
* Returns whether this content viewer is in a hidden state.
*
* @note Only Gecko internal code should set the attribute!
*/
attribute boolean isHidden;
[noscript] readonly attribute nsIPresShellPtr presShell;
[noscript] readonly attribute nsPresContextPtr presContext;
// aDocument must not be null.
[noscript] void setDocumentInternal(in nsIDocument aDocument,
in boolean aForceReuseInnerWindow);
/**
* Find the view to use as the container view for MakeWindow. Returns
* null if this will be the root of a view manager hierarchy. In that
* case, if mParentWidget is null then this document should not even
* be displayed.
*/
[noscript,notxpcom,nostdcall] nsViewPtr findContainerView();
/**
* Set collector for navigation timing data (load, unload events).
*/
[noscript,notxpcom,nostdcall] void setNavigationTiming(in nsDOMNavigationTimingPtr aTiming);
/*
Scrolls to a given DOM content node.
*/
void scrollToNode(in nsIDOMNode node);
/** The amount by which to scale all text. Default is 1.0. */
attribute float textZoom;
/** The amount by which to scale all lengths. Default is 1.0. */
attribute float fullZoom;
/**
* The value used to override devicePixelRatio and media queries dppx.
* Default is 0.0, that means no overriding is done (only a positive value
* is applied).
*/
attribute float overrideDPPX;
/** Disable entire author style level (including HTML presentation hints) */
attribute boolean authorStyleDisabled;
/**
* XXX comm-central only: bug 829543. Not the Character Encoding menu in
* browser!
*/
attribute ACString forceCharacterSet;
/**
* XXX comm-central only: bug 829543.
*/
attribute ACString hintCharacterSet;
/**
* XXX comm-central only: bug 829543.
*/
attribute int32_t hintCharacterSetSource;
/**
* Requests the size of the content to the container.
*/
void getContentSize(out long width, out long height);
/**
* Returns the preferred width and height of the content, constrained to the
* given maximum values. If either maxWidth or maxHeight is less than zero,
* that dimension is not constrained.
*
* All input and output values are in device pixels, rather than CSS pixels.
*/
void getContentSizeConstrained(in long maxWidth, in long maxHeight,
out long width, out long height);
/** The minimum font size */
attribute long minFontSize;
/**
* Append |this| and all of its descendants to the given array,
* in depth-first pre-order traversal.
*/
[noscript] void appendSubtree(in nsIContentViewerTArray array);
/**
* Instruct the refresh driver to discontinue painting until further
* notice.
*/
void pausePainting();
/**
* Instruct the refresh driver to resume painting after a previous call to
* pausePainting().
*/
void resumePainting();
/*
* Render the document as if being viewed on a device with the specified
* media type. This will cause a reflow.
*
* @param mediaType The media type to be emulated
*/
void emulateMedium(in AString aMediaType);
/*
* Restore the viewer's natural media type
*/
void stopEmulatingMedium();
};

View file

@ -0,0 +1,20 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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 "nsISupports.idl"
interface nsIContentViewer;
[scriptable, uuid(ea2ce7a0-5c3d-11d4-90c2-0050041caf44)]
interface nsIContentViewerContainer : nsISupports {
void embed(in nsIContentViewer aDocViewer, in string aCommand, in nsISupports aExtraInfo);
/**
* Allows the PrintEngine to make this call on
* an internal interface to the DocShell
*/
void setIsPrinting(in boolean aIsPrinting);
};

View file

@ -0,0 +1,36 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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 "nsISupports.idl"
interface nsIDOMNode;
[scriptable, uuid(35BE2D7E-F29B-48EC-BF7E-80A30A724DE3)]
interface nsIContentViewerEdit : nsISupports
{
void clearSelection();
void selectAll();
void copySelection();
readonly attribute boolean copyable;
void copyLinkLocation();
readonly attribute boolean inLink;
const long COPY_IMAGE_TEXT = 0x0001;
const long COPY_IMAGE_HTML = 0x0002;
const long COPY_IMAGE_DATA = 0x0004;
const long COPY_IMAGE_ALL = -1;
void copyImage(in long aCopyFlags);
readonly attribute boolean inImage;
AString getContents(in string aMimeType, in boolean aSelectionOnly);
readonly attribute boolean canGetContents;
// Set the node that will be the subject of the editing commands above.
// Usually this will be the node that was context-clicked.
void setCommandNode(in nsIDOMNode aNode);
};

View file

@ -0,0 +1,31 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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 "nsISupports.idl"
interface nsIDOMWindow;
interface nsIPrintSettings;
interface nsIWebProgressListener;
%{ C++
#include <stdio.h>
%}
[ptr] native FILE(FILE);
/**
* The nsIDocShellFile
*/
[scriptable, uuid(564a3276-6228-401e-9b5c-d82cb382a60f)]
interface nsIContentViewerFile : nsISupports
{
readonly attribute boolean printable;
[noscript] void print(in boolean aSilent,
in FILE aDebugFile,
in nsIPrintSettings aPrintSettings);
};

View file

@ -0,0 +1,19 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* 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 "nsISupports.idl"
/**
* The functionality of the nsIDocCharset interface has been incorporated into
* nsIDocShell.
*
* This is an empty interface for backwards compatibility that will go away at
* some point in the future
*
*/
[scriptable, uuid(c3faaf6e-40f0-11e1-95fc-6c626d69675c)]
interface nsIDocCharset : nsISupports
{};

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,125 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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 "nsISupports.idl"
/**
* The nsIDocShellLoadInfo interface defines an interface for specifying
* setup information used in a nsIDocShell::loadURI call.
*/
interface nsIURI;
interface nsIInputStream;
interface nsISHEntry;
interface nsIDocShell;
interface nsIPrincipal;
typedef long nsDocShellInfoLoadType;
typedef unsigned long nsDocShellInfoReferrerPolicy;
[scriptable, uuid(e7570e5a-f1d6-452d-b4f8-b35fdc63aa03)]
interface nsIDocShellLoadInfo : nsISupports
{
/** This is the referrer for the load. */
attribute nsIURI referrer;
/**
* The originalURI to be passed to nsIDocShell.internalLoad. May be null.
*/
attribute nsIURI originalURI;
/**
* loadReplace flag to be passed to nsIDocShell.internalLoad.
*/
attribute boolean loadReplace;
/** The principal of the load, that is, the entity responsible for
* causing the load to occur. In most cases the referrer and
* the triggeringPrincipal's URI will be identical.
*/
attribute nsIPrincipal triggeringPrincipal;
/** If this attribute is true and no triggeringPrincipal is specified,
* copy the principal from the referring document.
*/
attribute boolean inheritPrincipal;
/** If this attribute is true only ever use the principal specified
* by the triggeringPrincipal and inheritPrincipal attributes.
* If there are security reasons for why this is unsafe, such
* as trying to use a systemprincipal as the triggeringPrincipal
* for a content docshell the load fails.
*/
attribute boolean principalIsExplicit;
/* these are load type enums... */
const long loadNormal = 0; // Normal Load
const long loadNormalReplace = 1; // Normal Load but replaces current history slot
const long loadHistory = 2; // Load from history
const long loadReloadNormal = 3; // Reload
const long loadReloadBypassCache = 4;
const long loadReloadBypassProxy = 5;
const long loadReloadBypassProxyAndCache = 6;
const long loadLink = 7;
const long loadRefresh = 8;
const long loadReloadCharsetChange = 9;
const long loadBypassHistory = 10;
const long loadStopContent = 11;
const long loadStopContentAndReplace = 12;
const long loadNormalExternal = 13;
const long loadNormalBypassCache = 14;
const long loadNormalBypassProxy = 15;
const long loadNormalBypassProxyAndCache = 16;
const long loadPushState = 17; // history.pushState or replaceState
const long loadReplaceBypassCache = 18;
const long loadReloadMixedContent = 19;
const long loadNormalAllowMixedContent = 20;
/** Contains a load type as specified by the load* constants */
attribute nsDocShellInfoLoadType loadType;
/** SHEntry for this page */
attribute nsISHEntry SHEntry;
/** Target for load, like _content, _blank etc. */
attribute wstring target;
/** Post data */
attribute nsIInputStream postDataStream;
/** Additional headers */
attribute nsIInputStream headersStream;
/** True if the referrer should be sent, false if it shouldn't be
* sent, even if it's available. This attribute defaults to true.
*/
attribute boolean sendReferrer;
/** Referrer policy for the load. This attribute holds one of
* the values (REFERRER_POLICY_*) defined in nsIHttpChannel.
*/
attribute nsDocShellInfoReferrerPolicy referrerPolicy;
/** True if the docshell has been created to load an iframe where the
* srcdoc attribute has been set. Set when srcdocData is specified.
*/
readonly attribute boolean isSrcdocLoad;
/** When set, the load will be interpreted as a srcdoc load, where contents
* of this string will be loaded instead of the URI. Setting srcdocData
* sets isSrcdocLoad to true
*/
attribute AString srcdocData;
/** When set, this is the Source Browsing Context for the navigation. */
attribute nsIDocShell sourceDocShell;
/**
* Used for srcdoc loads to give view-source knowledge of the load's base
* URI as this information isn't embedded in the load's URI.
*/
attribute nsIURI baseURI;
};

View file

@ -0,0 +1,184 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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 "nsISupports.idl"
interface nsIDocShellTreeOwner;
interface nsIDocument;
interface nsPIDOMWindowOuter;
/**
* The nsIDocShellTreeItem supplies the methods that are required of any item
* that wishes to be able to live within the docshell tree either as a middle
* node or a leaf.
*/
[scriptable, uuid(9b7c586f-9214-480c-a2c4-49b526fff1a6)]
interface nsIDocShellTreeItem : nsISupports
{
/*
name of the DocShellTreeItem
*/
attribute AString name;
/**
* Compares the provided name against the item's name and
* returns the appropriate result.
*
* @return <CODE>PR_TRUE</CODE> if names match;
* <CODE>PR_FALSE</CODE> otherwise.
*/
boolean nameEquals(in AString name);
/*
Definitions for the item types.
*/
const long typeChrome=0; // typeChrome must equal 0
const long typeContent=1; // typeContent must equal 1
const long typeContentWrapper=2; // typeContentWrapper must equal 2
const long typeChromeWrapper=3; // typeChromeWrapper must equal 3
const long typeAll=0x7FFFFFFF;
/*
The type this item is.
*/
attribute long itemType;
[noscript,notxpcom,nostdcall] long ItemType();
/*
Parent DocShell.
*/
readonly attribute nsIDocShellTreeItem parent;
/*
This getter returns the same thing parent does however if the parent
is of a different itemType, or if the parent is an <iframe mozbrowser>
or <iframe mozapp>, it will instead return nullptr. This call is a
convience function for those wishing to not cross the boundaries at
which item types change.
*/
readonly attribute nsIDocShellTreeItem sameTypeParent;
/*
Returns the root DocShellTreeItem. This is a convience equivalent to
getting the parent and its parent until there isn't a parent.
*/
readonly attribute nsIDocShellTreeItem rootTreeItem;
/*
Returns the root DocShellTreeItem of the same type. This is a convience
equivalent to getting the parent of the same type and its parent until
there isn't a parent.
*/
readonly attribute nsIDocShellTreeItem sameTypeRootTreeItem;
/*
Returns the docShellTreeItem with the specified name. Search order is as
follows...
1.) Check name of self, if it matches return it.
2.) For each immediate child.
a.) Check name of child and if it matches return it.
b.) Ask the child to perform the check
i.) Do not ask a child if it is the aRequestor
ii.) Do not ask a child if it is of a different item type.
3.) If there is a parent of the same item type ask parent to perform the check
a.) Do not ask parent if it is the aRequestor
4.) If there is a tree owner ask the tree owner to perform the check
a.) Do not ask the tree owner if it is the aRequestor
b.) This should only be done if there is no parent of the same type.
Return the child DocShellTreeItem with the specified name.
name - This is the name of the item that is trying to be found.
aRequestor - This is the object that is requesting the find. This
parameter is used to identify when the child is asking its parent to find
a child with the specific name. The parent uses this parameter to ensure
a resursive state does not occur by not again asking the requestor to find
a shell by the specified name. Inversely the child uses it to ensure it
does not ask its parent to do the search if its parent is the one that
asked it to search. Children also use this to test against the treeOwner;
aOriginalRequestor - The original treeitem that made the request, if any.
This is used to ensure that we don't run into cross-site issues.
*/
nsIDocShellTreeItem findItemWithName(in AString name,
in nsISupports aRequestor,
in nsIDocShellTreeItem aOriginalRequestor);
/*
The owner of the DocShell Tree. This interface will be called upon when
the docshell has things it needs to tell to the owner of the docshell.
Note that docShell tree ownership does not cross tree types. Meaning
setting ownership on a chrome tree does not set ownership on the content
sub-trees. A given tree's boundaries are identified by the type changes.
Trees of different types may be connected, but should not be traversed
for things such as ownership.
Note implementers of this interface should NOT effect the lifetime of the
parent DocShell by holding this reference as it creates a cycle. Owners
when releasing this interface should set the treeOwner to nullptr.
Implementers of this interface are guaranteed that when treeOwner is
set that the poitner is valid without having to addref.
Further note however when others try to get the interface it should be
addref'd before handing it to them.
*/
readonly attribute nsIDocShellTreeOwner treeOwner;
[noscript] void setTreeOwner(in nsIDocShellTreeOwner treeOwner);
/*
The current number of DocShells which are immediate children of the
this object.
*/
readonly attribute long childCount;
/*
Add a new child DocShellTreeItem. Adds to the end of the list.
Note that this does NOT take a reference to the child. The child stays
alive only as long as it's referenced from outside the docshell tree.
@throws NS_ERROR_ILLEGAL_VALUE if child corresponds to the same
object as this treenode or an ancestor of this treenode
@throws NS_ERROR_UNEXPECTED if this node is a leaf in the tree.
*/
void addChild(in nsIDocShellTreeItem child);
/*
Removes a child DocShellTreeItem.
@throws NS_ERROR_UNEXPECTED if this node is a leaf in the tree.
*/
void removeChild(in nsIDocShellTreeItem child);
/**
* Return the child at the index requested. This is 0-based.
*
* @throws NS_ERROR_UNEXPECTED if the index is out of range
*/
nsIDocShellTreeItem getChildAt(in long index);
/*
Return the child DocShellTreeItem with the specified name.
aName - This is the name of the item that is trying to be found.
aRecurse - Is used to tell the function to recurse through children.
Note, recursion will only happen through items of the same type.
aSameType - If this is set only children of the same type will be returned.
aRequestor - This is the docshellTreeItem that is requesting the find. This
parameter is used when recursion is being used to avoid searching the same
tree again when a child has asked a parent to search for children.
aOriginalRequestor - The original treeitem that made the request, if any.
This is used to ensure that we don't run into cross-site issues.
Note the search is depth first when recursing.
*/
nsIDocShellTreeItem findChildWithName(in AString aName,
in boolean aRecurse,
in boolean aSameType,
in nsIDocShellTreeItem aRequestor,
in nsIDocShellTreeItem aOriginalRequestor);
[noscript,nostdcall,notxpcom] nsIDocument getDocument();
[noscript,nostdcall,notxpcom] nsPIDOMWindowOuter getWindow();
};

View file

@ -0,0 +1,109 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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 "nsISupports.idl"
/**
* The nsIDocShellTreeOwner
*/
interface nsIDocShellTreeItem;
interface nsITabParent;
[scriptable, uuid(0e3dc4b1-4cea-4a37-af71-79f0afd07574)]
interface nsIDocShellTreeOwner : nsISupports
{
/**
* Called when a content shell is added to the docshell tree. This is
* _only_ called for "root" content shells (that is, ones whose parent is a
* chrome shell).
*
* @param aContentShell the shell being added.
* @param aPrimary whether the shell is primary.
* @param aTargetable whether the shell can be a target for named window
* targeting.
* @param aID the "id" of the shell. What this actually means is
* undefined. Don't rely on this for anything.
*/
void contentShellAdded(in nsIDocShellTreeItem aContentShell,
in boolean aPrimary, in boolean aTargetable,
in AString aID);
/**
* Called when a content shell is removed from the docshell tree. This is
* _only_ called for "root" content shells (that is, ones whose parent is a
* chrome shell). Note that if aContentShell was never added,
* contentShellRemoved should just do nothing.
*
* @param aContentShell the shell being removed.
*/
void contentShellRemoved(in nsIDocShellTreeItem aContentShell);
/*
Returns the Primary Content Shell
*/
readonly attribute nsIDocShellTreeItem primaryContentShell;
void tabParentAdded(in nsITabParent aTab, in boolean aPrimary);
void tabParentRemoved(in nsITabParent aTab);
/*
In multiprocess case we may not have primaryContentShell but
primaryTabParent.
*/
readonly attribute nsITabParent primaryTabParent;
/*
Tells the tree owner to size its window or parent window in such a way
that the shell passed along will be the size specified.
*/
void sizeShellTo(in nsIDocShellTreeItem shell, in long cx, in long cy);
/*
Gets the size of the primary content area in CSS pixels. This should work
for both in-process and out-of-process content areas.
*/
void getPrimaryContentSize(out long width, out long height);
/*
Sets the size of the primary content area in CSS pixels. This should work
for both in-process and out-of-process content areas.
*/
void setPrimaryContentSize(in long width, in long height);
/*
Gets the size of the root docshell in CSS pixels.
*/
void getRootShellSize(out long width, out long height);
/*
Sets the size of the root docshell in CSS pixels.
*/
void setRootShellSize(in long width, in long height);
/*
Sets the persistence of different attributes of the window.
*/
void setPersistence(in boolean aPersistPosition,
in boolean aPersistSize,
in boolean aPersistSizeMode);
/*
Gets the current persistence states of the window.
*/
void getPersistence(out boolean aPersistPosition,
out boolean aPersistSize,
out boolean aPersistSizeMode);
/*
Gets the number of targettable docshells.
*/
readonly attribute unsigned long targetableShellCount;
/*
Returns true if there is a primary content shell or a primary
tab parent.
*/
readonly attribute bool hasPrimaryContent;
};

View file

@ -0,0 +1,46 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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 "nsISupports.idl"
interface nsIChannel;
interface nsIContentViewer;
interface nsIStreamListener;
interface nsIDocShell;
interface nsIDocument;
interface nsILoadGroup;
interface nsIPrincipal;
/**
* To get a component that implements nsIDocumentLoaderFactory
* for a given mimetype, use nsICategoryManager to find an entry
* with the mimetype as its name in the category "Gecko-Content-Viewers".
* The value of the entry is the contractid of the component.
* The component is a service, so use GetService, not CreateInstance to get it.
*/
[scriptable, uuid(e795239e-9d3c-47c4-b063-9e600fb3b287)]
interface nsIDocumentLoaderFactory : nsISupports {
nsIContentViewer createInstance(in string aCommand,
in nsIChannel aChannel,
in nsILoadGroup aLoadGroup,
in ACString aContentType,
in nsIDocShell aContainer,
in nsISupports aExtraInfo,
out nsIStreamListener aDocListenerResult);
nsIContentViewer createInstanceForDocument(in nsISupports aContainer,
in nsIDocument aDocument,
in string aCommand);
/**
* Create a blank document using the given loadgroup and given
* principal. aPrincipal is allowed to be null, in which case the
* new document will get the about:blank codebase principal.
*/
nsIDocument createBlankDocument(in nsILoadGroup aLoadGroup,
in nsIPrincipal aPrincipal);
};

View file

@ -0,0 +1,58 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: sw=2 ts=2 sts=2
* 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 "nsISupports.idl"
interface nsIURI;
/**
* This interface can be used to add a download to history. There is a separate
* interface specifically for downloads in case embedders choose to track
* downloads differently from other types of history.
*/
[scriptable, uuid(4dcd6a12-a091-4f38-8360-022929635746)]
interface nsIDownloadHistory : nsISupports {
/**
* Adds a download to history. This will also notify observers that the
* URI aSource is visited with the topic NS_LINK_VISITED_EVENT_TOPIC if
* aSource has not yet been visited.
*
* @param aSource
* The source of the download we are adding to history. This cannot be
* null.
* @param aReferrer
* [optional] The referrer of source URI.
* @param aStartTime
* [optional] The time the download was started. If the start time
* is not given, the current time is used.
* @param aDestination
* [optional] The target where the download is to be saved on the local
* filesystem.
* @throws NS_ERROR_NOT_AVAILABLE
* In a situation where a history implementation is not available,
* where 'history implementation' refers to something like
* nsIGlobalHistory and friends.
* @note This addition is not guaranteed to be synchronous, since it delegates
* the actual addition to the underlying history implementation. If you
* need to observe the completion of the addition, use the underlying
* history implementation's notifications system (e.g. nsINavHistoryObserver
* for toolkit's implementation of this interface).
*/
void addDownload(in nsIURI aSource, [optional] in nsIURI aReferrer,
[optional] in PRTime aStartTime,
[optional] in nsIURI aDestination);
/**
* Remove all downloads from history.
*
* @note This removal is not guaranteed to be synchronous, since it delegates
* the actual removal to the underlying history implementation. If you
* need to observe the completion of the removal, use the underlying
* history implementation's notifications system (e.g. nsINavHistoryObserver
* for toolkit's implementation of this interface).
*/
void removeAllDownloads();
};

View file

@ -0,0 +1,59 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* 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/. */
/**
* Provides information about global history to gecko.
*
* @note This interface replaces and deprecates nsIGlobalHistory.
*/
#include "nsISupports.idl"
interface nsIURI;
%{ C++
// nsIObserver topic to fire when you add new visited URIs to the history;
// the nsIURI is the subject
#define NS_LINK_VISITED_EVENT_TOPIC "link-visited"
%}
[scriptable, uuid(cf777d42-1270-4b34-be7b-2931c93feda5)]
interface nsIGlobalHistory2 : nsISupports
{
/**
* Add a URI to global history
*
* @param aURI the URI of the page
* @param aRedirect whether the URI was redirected to another location;
* this is 'true' for the original URI which is
* redirected.
* @param aToplevel whether the URI is loaded in a top-level window
* @param aReferrer the URI of the referring page
*
* @note Docshell will not filter out URI schemes like chrome: data:
* about: and view-source:. Embedders should consider filtering out
* these schemes and others, e.g. mailbox: for the main URI and the
* referrer.
*/
void addURI(in nsIURI aURI, in boolean aRedirect, in boolean aToplevel, in nsIURI aReferrer);
/**
* Checks to see whether the given URI is in history.
*
* @param aURI the uri to the page
* @return true if a URI has been visited
*/
boolean isVisited(in nsIURI aURI);
/**
* Set the page title for the given uri. URIs that are not already in
* global history will not be added.
*
* @param aURI the URI for which to set to the title
* @param aTitle the page title
*/
void setPageTitle(in nsIURI aURI, in AString aTitle);
};

View file

@ -0,0 +1,94 @@
/* -*- 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 nsILinkHandler_h___
#define nsILinkHandler_h___
#include "nsISupports.h"
#include "mozilla/EventForwards.h"
class nsIContent;
class nsIDocShell;
class nsIInputStream;
class nsIRequest;
#define NS_ILINKHANDLER_IID \
{ 0xceb9aade, 0x43da, 0x4f1a, \
{ 0xac, 0x8a, 0xc7, 0x09, 0xfb, 0x22, 0x46, 0x64 } }
/**
* Interface used for handling clicks on links
*/
class nsILinkHandler : public nsISupports
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ILINKHANDLER_IID)
/**
* Process a click on a link.
*
* @param aContent the content for the frame that generated the trigger
* @param aURI a URI object that defines the destination for the link
* @param aTargetSpec indicates where the link is targeted (may be an empty
* string)
* @param aPostDataStream the POST data to send
* @param aFileName non-null when the link should be downloaded as the given file
* @param aHeadersDataStream ???
* @param aIsTrusted false if the triggerer is an untrusted DOM event.
*/
NS_IMETHOD OnLinkClick(nsIContent* aContent,
nsIURI* aURI,
const char16_t* aTargetSpec,
const nsAString& aFileName,
nsIInputStream* aPostDataStream,
nsIInputStream* aHeadersDataStream,
bool aIsTrusted) = 0;
/**
* Process a click on a link.
*
* Works the same as OnLinkClick() except it happens immediately rather than
* through an event.
*
* @param aContent the content for the frame that generated the trigger
* @param aURI a URI obect that defines the destination for the link
* @param aTargetSpec indicates where the link is targeted (may be an empty
* string)
* @param aFileName non-null when the link should be downloaded as the given file
* @param aPostDataStream the POST data to send
* @param aHeadersDataStream ???
* @param aDocShell (out-param) the DocShell that the request was opened on
* @param aRequest the request that was opened
*/
NS_IMETHOD OnLinkClickSync(nsIContent* aContent,
nsIURI* aURI,
const char16_t* aTargetSpec,
const nsAString& aFileName,
nsIInputStream* aPostDataStream = 0,
nsIInputStream* aHeadersDataStream = 0,
nsIDocShell** aDocShell = 0,
nsIRequest** aRequest = 0) = 0;
/**
* Process a mouse-over a link.
*
* @param aContent the linked content.
* @param aURI an URI object that defines the destination for the link
* @param aTargetSpec indicates where the link is targeted (it may be an empty
* string)
*/
NS_IMETHOD OnOverLink(nsIContent* aContent,
nsIURI* aURLSpec,
const char16_t* aTargetSpec) = 0;
/**
* Process the mouse leaving a link.
*/
NS_IMETHOD OnLeaveLink() = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsILinkHandler, NS_ILINKHANDLER_IID)
#endif /* nsILinkHandler_h___ */

View file

@ -0,0 +1,155 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: ft=cpp tw=78 sw=2 et ts=2 sts=2 cin
* 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 "nsISupports.idl"
interface mozIDOMWindowProxy;
interface nsIDOMElement;
%{C++
#ifdef MOZILLA_INTERNAL_API
#include "mozilla/BasePrincipal.h" // for DocShellOriginAttributes
#endif
%}
/**
* An nsILoadContext represents the context of a load. This interface
* can be queried for various information about where the load is
* happening.
*/
[scriptable, uuid(2813a7a3-d084-4d00-acd0-f76620315c02)]
interface nsILoadContext : nsISupports
{
/**
* associatedWindow is the window with which the load is associated, if any.
* Note that the load may be triggered by a document which is different from
* the document in associatedWindow, and in fact the source of the load need
* not be same-origin with the document in associatedWindow. This attribute
* may be null if there is no associated window.
*/
readonly attribute mozIDOMWindowProxy associatedWindow;
/**
* topWindow is the top window which is of same type as associatedWindow.
* This is equivalent to associatedWindow.top, but is provided here as a
* convenience. All the same caveats as associatedWindow of apply, of
* course. This attribute may be null if there is no associated window.
*/
readonly attribute mozIDOMWindowProxy topWindow;
/**
* topFrameElement is the <iframe>, <frame>, or <browser> element which
* contains the topWindow with which the load is associated.
*
* Note that we may have a topFrameElement even when we don't have an
* associatedWindow, if the topFrameElement's content lives out of process.
* topFrameElement is available in single-process and multiprocess contexts.
* Note that topFrameElement may be in chrome even when the nsILoadContext is
* associated with content.
*/
readonly attribute nsIDOMElement topFrameElement;
/**
* If this LoadContext corresponds to a nested remote iframe, we don't have
* access to the topFrameElement. Instead, we must use this id to send
* messages. A return value of 0 signifies that this load context is not for
* a nested frame.
*/
readonly attribute unsigned long long nestedFrameId;
/**
* True if the load context is content (as opposed to chrome). This is
* determined based on the type of window the load is performed in, NOT based
* on any URIs that might be around.
*/
readonly attribute boolean isContent;
/*
* Attribute that determines if private browsing should be used. May not be
* changed after a document has been loaded in this context.
*/
attribute boolean usePrivateBrowsing;
/**
* Attribute that determines if remote (out-of-process) tabs should be used.
*/
readonly attribute boolean useRemoteTabs;
%{C++
/**
* De-XPCOMed getter to make call-sites cleaner.
*/
bool UsePrivateBrowsing() {
bool usingPB;
GetUsePrivateBrowsing(&usingPB);
return usingPB;
}
bool UseRemoteTabs() {
bool usingRT;
GetUseRemoteTabs(&usingRT);
return usingRT;
}
%}
/**
* Set the private browsing state of the load context, meant to be used internally.
*/
[noscript] void SetPrivateBrowsing(in boolean aInPrivateBrowsing);
/**
* Set the remote tabs state of the load context, meant to be used internally.
*/
[noscript] void SetRemoteTabs(in boolean aUseRemoteTabs);
/**
* Returns true iff the load is occurring inside an isolated mozbrowser
* element. <iframe mozbrowser mozapp> and <xul:browser> are not considered to
* be mozbrowser elements. <iframe mozbrowser noisolation> does not count as
* isolated since isolation is disabled. Isolation can only be disabled if
* the containing document is chrome.
*/
readonly attribute boolean isInIsolatedMozBrowserElement;
/**
* Returns the app id of the app the load is occurring is in. Returns
* nsIScriptSecurityManager::NO_APP_ID if the load is not part of an app.
*/
readonly attribute unsigned long appId;
/**
* A dictionary of the non-default origin attributes associated with this
* nsILoadContext.
*/
readonly attribute jsval originAttributes;
%{C++
#ifdef MOZILLA_INTERNAL_API
/**
* The C++ getter for origin attributes.
*
* Defined in LoadContext.cpp
*/
bool GetOriginAttributes(mozilla::DocShellOriginAttributes& aAttrs);
#endif
%}
/**
* Returns true if tracking protection is enabled for the load context.
*/
boolean IsTrackingProtectionOn();
%{C++
/**
* De-XPCOMed getter to make call-sites cleaner.
*/
bool UseTrackingProtection() {
bool usingTP;
IsTrackingProtectionOn(&usingTP);
return usingTP;
}
%}
};

View file

@ -0,0 +1,11 @@
/* 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 "nsISupports.idl"
[scriptable, function, uuid(b4b1449d-0ef0-47f5-b62e-adc57fd49702)]
interface nsIPrivacyTransitionObserver : nsISupports
{
void privateModeChanged(in bool enabled);
};

View file

@ -0,0 +1,31 @@
/* 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 "domstubs.idl"
[scriptable, uuid(832e692c-c4a6-11e2-8fd1-dce678957a39)]
interface nsIReflowObserver : nsISupports
{
/**
* Called when an uninterruptible reflow has occurred.
*
* @param start timestamp when reflow ended, in milliseconds since
* navigationStart (accurate to 1/1000 of a ms)
* @param end timestamp when reflow ended, in milliseconds since
* navigationStart (accurate to 1/1000 of a ms)
*/
void reflow(in DOMHighResTimeStamp start,
in DOMHighResTimeStamp end);
/**
* Called when an interruptible reflow has occurred.
*
* @param start timestamp when reflow ended, in milliseconds since
* navigationStart (accurate to 1/1000 of a ms)
* @param end timestamp when reflow ended, in milliseconds since
* navigationStart (accurate to 1/1000 of a ms)
*/
void reflowInterruptible(in DOMHighResTimeStamp start,
in DOMHighResTimeStamp end);
};

View file

@ -0,0 +1,91 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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 "nsISupports.idl"
interface nsIChannel;
interface nsIPrincipal;
interface nsIURI;
[scriptable, uuid(a5e61a3c-51bd-45be-ac0c-e87b71860656)]
interface nsIRefreshURI : nsISupports {
/**
* Load a uri after waiting for aMillis milliseconds. If the docshell
* is busy loading a page currently, the refresh request will be
* queued and executed when the current load finishes.
*
* @param aUri The uri to refresh.
* @param aPrincipal The triggeringPrincipal for the refresh load
* May be null, in which case a principal will be built based on the
* referrer URI of the previous docshell load, or will use the system
* principal when there is no referrer.
* @param aMillis The number of milliseconds to wait.
* @param aRepeat Flag to indicate if the uri is to be
* repeatedly refreshed every aMillis milliseconds.
* @param aMetaRefresh Flag to indicate if this is a Meta refresh.
*/
void refreshURI(in nsIURI aURI,
in long aMillis, in boolean aRepeat,
in boolean aMetaRefresh,
[optional] in nsIPrincipal aPrincipal);
/**
* Loads a URI immediately as if it were a refresh.
*
* @param aURI The URI to refresh.
* @param aPrincipal The triggeringPrincipal for the refresh load
* May be null, in which case a principal will be built based on the
* referrer URI of the previous docshell load, or will use the system
* principal when there is no referrer.
* @param aMillis The number of milliseconds by which this refresh would
* be delayed if it were not being forced.
* @param aMetaRefresh Flag to indicate if this is a meta refresh.
*/
void forceRefreshURI(in nsIURI aURI,
in long aMillis, in boolean aMetaRefresh,
[optional] in nsIPrincipal aPrincipal);
/**
* Checks the passed in channel to see if there is a refresh header,
* if there is, will setup a timer to refresh the uri found
* in the header. If docshell is busy loading a page currently, the
* request will be queued and executed when the current page
* finishes loading.
*
* Returns the NS_REFRESHURI_HEADER_FOUND success code if a refresh
* header was found and successfully setup.
*
* @param aChannel The channel to be parsed.
*/
void setupRefreshURI(in nsIChannel aChannel);
/**
* Parses the passed in header string and sets up a refreshURI if
* a "refresh" header is found. If docshell is busy loading a page
* currently, the request will be queued and executed when
* the current page finishes loading.
*
* @param aBaseURI base URI to resolve refresh uri with.
* @param aPrincipal The triggeringPrincipal for the refresh load
* May be null, in which case a principal will be built based on the
* referrer URI of the previous docshell load, or will use the system
* principal when there is no referrer.
* @param aHeader The meta refresh header string.
*/
void setupRefreshURIFromHeader(in nsIURI aBaseURI,
in nsIPrincipal principal,
in ACString aHeader);
/**
* Cancels all timer loads.
*/
void cancelRefreshURITimers();
/**
* True when there are pending refreshes, false otherwise.
*/
readonly attribute boolean refreshPending;
};

View file

@ -0,0 +1,42 @@
/* -*- 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 nsIScrollObserver_h___
#define nsIScrollObserver_h___
#include "nsISupports.h"
#include "Units.h"
#define NS_ISCROLLOBSERVER_IID \
{ 0xaa5026eb, 0x2f88, 0x4026, \
{ 0xa4, 0x6b, 0xf4, 0x59, 0x6b, 0x4e, 0xdf, 0x00 } }
class nsIScrollObserver : public nsISupports
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ISCROLLOBSERVER_IID)
/**
* Called when the scroll position of some element has changed.
*/
virtual void ScrollPositionChanged() = 0;
/**
* Called when an async panning/zooming transform has started being applied
* and passed the scroll offset
*/
virtual void AsyncPanZoomStarted() {};
/**
* Called when an async panning/zooming transform is no longer applied
* and passed the scroll offset
*/
virtual void AsyncPanZoomStopped() {};
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIScrollObserver, NS_ISCROLLOBSERVER_IID)
#endif /* nsIScrollObserver_h___ */

View file

@ -0,0 +1,55 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: set ts=2 sw=2 et tw=78:
*
* 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 "nsISupports.idl"
/**
* The nsIScrollable is an interface that can be implemented by a control that
* supports scrolling. This is a generic interface without concern for the
* type of content that may be inside.
*/
[scriptable, uuid(3507fc93-313e-4a4c-8ca8-4d0ea0f97315)]
interface nsIScrollable : nsISupports
{
/**
* Constants declaring the two scroll orientations a scrollbar can be in.
* ScrollOrientation_X - Horizontal scrolling. When passing this
* in to a method you are requesting or setting data for the
* horizontal scrollbar.
* ScrollOrientation_Y - Vertical scrolling. When passing this
* in to a method you are requesting or setting data for the
* vertical scrollbar.
*/
const long ScrollOrientation_X = 1;
const long ScrollOrientation_Y = 2;
/**
* Constants declaring the states of the scrollbars.
* ScrollPref_Auto - bars visible only when needed.
* ScrollPref_Never - bars never visible, even when scrolling still possible.
* ScrollPref_Always - bars always visible, even when scrolling is not possible
*/
const long Scrollbar_Auto = 1;
const long Scrollbar_Never = 2;
const long Scrollbar_Always = 3;
/**
* Get or set the default scrollbar state for all documents in
* this shell.
*/
long getDefaultScrollbarPreferences(in long scrollOrientation);
void setDefaultScrollbarPreferences(in long scrollOrientation,
in long scrollbarPref);
/**
* Get information about whether the vertical and horizontal scrollbars are
* currently visible. If you are only interested in one of the visibility
* settings pass nullptr in for the one you aren't interested in.
*/
void getScrollbarVisibility(out boolean verticalVisible,
out boolean horizontalVisible);
};

View file

@ -0,0 +1,33 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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 "nsISupports.idl"
/**
* The nsITextScroll is an interface that can be implemented by a control that
* supports text scrolling.
*/
[scriptable, uuid(067B28A0-877F-11d3-AF7E-00A024FFC08C)]
interface nsITextScroll : nsISupports
{
/**
* Scroll the view up or down by aNumLines lines. positive
* values move down in the view. Prevents scrolling off the
* end of the view.
* @param numLines number of lines to scroll the view by
*/
void scrollByLines(in long numLines);
/**
* Scroll the view up or down by numPages pages. a page
* is considered to be the amount displayed by the clip view.
* positive values move down in the view. Prevents scrolling
* off the end of the view.
* @param numPages number of pages to scroll the view by
*/
void scrollByPages(in long numPages);
};

View file

@ -0,0 +1,166 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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 "nsISupports.idl"
interface nsIURI;
interface nsIInputStream;
/**
* Interface indicating what we found/corrected when fixing up a URI
*/
[scriptable, uuid(4819f183-b532-4932-ac09-b309cd853be7)]
interface nsIURIFixupInfo : nsISupports
{
/**
* Consumer that asked for fixed up URI.
*/
attribute nsISupports consumer;
/**
* Our best guess as to what URI the consumer will want. Might
* be null if we couldn't salvage anything (for instance, because
* the input was invalid as a URI and FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP
* was not passed)
*/
readonly attribute nsIURI preferredURI;
/**
* The fixed-up original input, *never* using a keyword search.
* (might be null if the original input was not recoverable as
* a URL, e.g. "foo bar"!)
*/
readonly attribute nsIURI fixedURI;
/**
* The name of the keyword search provider used to provide a keyword search;
* empty string if no keyword search was done.
*/
readonly attribute AString keywordProviderName;
/**
* The keyword as used for the search (post trimming etc.)
* empty string if no keyword search was done.
*/
readonly attribute AString keywordAsSent;
/**
* Whether we changed the protocol instead of using one from the input as-is.
*/
readonly attribute boolean fixupChangedProtocol;
/**
* Whether we created an alternative URI. We might have added a prefix and/or
* suffix, the contents of which are controlled by the
* browser.fixup.alternate.prefix and .suffix prefs, with the defaults being
* "www." and ".com", respectively.
*/
readonly attribute boolean fixupCreatedAlternateURI;
/**
* The original input
*/
readonly attribute AUTF8String originalInput;
};
/**
* Interface implemented by objects capable of fixing up strings into URIs
*/
[scriptable, uuid(1da7e9d4-620b-4949-849a-1cd6077b1b2d)]
interface nsIURIFixup : nsISupports
{
/** No fixup flags. */
const unsigned long FIXUP_FLAG_NONE = 0;
/**
* Allow the fixup to use a keyword lookup service to complete the URI.
* The fixup object implementer should honour this flag and only perform
* any lengthy keyword (or search) operation if it is set.
*/
const unsigned long FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP = 1;
/**
* Tell the fixup to make an alternate URI from the input URI, for example
* to turn foo into www.foo.com.
*/
const unsigned long FIXUP_FLAGS_MAKE_ALTERNATE_URI = 2;
/*
* Fix common scheme typos.
*/
const unsigned long FIXUP_FLAG_FIX_SCHEME_TYPOS = 8;
/* NB: If adding an extra flag, 4 is free (again) */
/**
* Converts an internal URI (e.g. a wyciwyg URI) into one which we can
* expose to the user, for example on the URL bar.
*
* @param aURI The URI to be converted
* @return nsIURI The converted, exposable URI
* @throws NS_ERROR_MALFORMED_URI when the exposable portion of aURI is malformed
* @throws NS_ERROR_UNKNOWN_PROTOCOL when we can't get a protocol handler service
* for the URI scheme.
*/
nsIURI createExposableURI(in nsIURI aURI);
/**
* Converts the specified string into a URI, first attempting
* to correct any errors in the syntax or other vagaries. Returns
* a wellformed URI or nullptr if it can't.
*
* @param aURIText Candidate URI.
* @param aFixupFlags Flags that govern ways the URI may be fixed up.
* @param aPostData The POST data to submit with the returned
* URI (see nsISearchSubmission).
*/
nsIURI createFixupURI(in AUTF8String aURIText, in unsigned long aFixupFlags,
[optional] out nsIInputStream aPostData);
/**
* Same as createFixupURI, but returns information about what it corrected
* (e.g. whether we could rescue the URI or "just" generated a keyword
* search URI instead).
*
* @param aURIText Candidate URI.
* @param aFixupFlags Flags that govern ways the URI may be fixed up.
* @param aPostData The POST data to submit with the returned
* URI (see nsISearchSubmission).
*/
nsIURIFixupInfo getFixupURIInfo(in AUTF8String aURIText,
in unsigned long aFixupFlags,
[optional] out nsIInputStream aPostData);
/**
* Converts the specified keyword string into a URI. Note that it's the
* caller's responsibility to check whether keywords are enabled and
* whether aKeyword is a sensible keyword.
*
* @param aKeyword The keyword string to convert into a URI
* @param aPostData The POST data to submit to the returned URI
* (see nsISearchSubmission).
*
* @throws NS_ERROR_FAILURE if the resulting URI requires submission of POST
* data and aPostData is null.
*/
nsIURIFixupInfo keywordToURI(in AUTF8String aKeyword,
[optional] out nsIInputStream aPostData);
/**
* Returns true if the specified domain is whitelisted and false otherwise.
* A whitelisted domain is relevant when we have a single word and can't be
* sure whether to treat the word as a host name or should instead be
* treated as a search term.
*
* @param aDomain A domain name to query.
* @param aDotPos The position of the first '.' character in aDomain, or
* -1 if no '.' character exists.
*/
bool isDomainWhitelisted(in AUTF8String aDomain,
in uint32_t aDotPos);
};

View file

@ -0,0 +1,367 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* 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 "nsISupports.idl"
interface nsIDOMDocument;
interface nsIInputStream;
interface nsISHistory;
interface nsIURI;
/**
* The nsIWebNavigation interface defines an interface for navigating the web.
* It provides methods and attributes to direct an object to navigate to a new
* location, stop or restart an in process load, or determine where the object
* has previously gone.
*/
[scriptable, uuid(3ade79d4-8cb9-4952-b18d-4f9b63ca0d31)]
interface nsIWebNavigation : nsISupports
{
/**
* Indicates if the object can go back. If true this indicates that
* there is back session history available for navigation.
*/
readonly attribute boolean canGoBack;
/**
* Indicates if the object can go forward. If true this indicates that
* there is forward session history available for navigation
*/
readonly attribute boolean canGoForward;
/**
* Tells the object to navigate to the previous session history item. When a
* page is loaded from session history, all content is loaded from the cache
* (if available) and page state (such as form values and scroll position) is
* restored.
*
* @throw NS_ERROR_UNEXPECTED
* Indicates that the call was unexpected at this time, which implies
* that canGoBack is false.
*/
void goBack();
/**
* Tells the object to navigate to the next session history item. When a
* page is loaded from session history, all content is loaded from the cache
* (if available) and page state (such as form values and scroll position) is
* restored.
*
* @throw NS_ERROR_UNEXPECTED
* Indicates that the call was unexpected at this time, which implies
* that canGoForward is false.
*/
void goForward();
/**
* Tells the object to navigate to the session history item at a given index.
*
* @throw NS_ERROR_UNEXPECTED
* Indicates that the call was unexpected at this time, which implies
* that session history entry at the given index does not exist.
*/
void gotoIndex(in long index);
/****************************************************************************
* The following flags may be bitwise combined to form the load flags
* parameter passed to either the loadURI or reload method. Some of these
* flags are only applicable to loadURI.
*/
/**
* This flags defines the range of bits that may be specified. Flags
* outside this range may be used, but may not be passed to Reload().
*/
const unsigned long LOAD_FLAGS_MASK = 0xffff;
/**
* This is the default value for the load flags parameter.
*/
const unsigned long LOAD_FLAGS_NONE = 0x0000;
/**
* Flags 0x1, 0x2, 0x4, 0x8 are reserved for internal use by
* nsIWebNavigation implementations for now.
*/
/**
* This flag specifies that the load should have the semantics of an HTML
* Meta-refresh tag (i.e., that the cache should be bypassed). This flag
* is only applicable to loadURI.
* XXX the meaning of this flag is poorly defined.
* XXX no one uses this, so we should probably deprecate and remove it.
*/
const unsigned long LOAD_FLAGS_IS_REFRESH = 0x0010;
/**
* This flag specifies that the load should have the semantics of a link
* click. This flag is only applicable to loadURI.
* XXX the meaning of this flag is poorly defined.
*/
const unsigned long LOAD_FLAGS_IS_LINK = 0x0020;
/**
* This flag specifies that history should not be updated. This flag is only
* applicable to loadURI.
*/
const unsigned long LOAD_FLAGS_BYPASS_HISTORY = 0x0040;
/**
* This flag specifies that any existing history entry should be replaced.
* This flag is only applicable to loadURI.
*/
const unsigned long LOAD_FLAGS_REPLACE_HISTORY = 0x0080;
/**
* This flag specifies that the local web cache should be bypassed, but an
* intermediate proxy cache could still be used to satisfy the load.
*/
const unsigned long LOAD_FLAGS_BYPASS_CACHE = 0x0100;
/**
* This flag specifies that any intermediate proxy caches should be bypassed
* (i.e., that the content should be loaded from the origin server).
*/
const unsigned long LOAD_FLAGS_BYPASS_PROXY = 0x0200;
/**
* This flag specifies that a reload was triggered as a result of detecting
* an incorrect character encoding while parsing a previously loaded
* document.
*/
const unsigned long LOAD_FLAGS_CHARSET_CHANGE = 0x0400;
/**
* If this flag is set, Stop() will be called before the load starts
* and will stop both content and network activity (the default is to
* only stop network activity). Effectively, this passes the
* STOP_CONTENT flag to Stop(), in addition to the STOP_NETWORK flag.
*/
const unsigned long LOAD_FLAGS_STOP_CONTENT = 0x0800;
/**
* A hint this load was prompted by an external program: take care!
*/
const unsigned long LOAD_FLAGS_FROM_EXTERNAL = 0x1000;
/**
This flag is set when a user explicitly disables the Mixed Content
Blocker, and allows Mixed Content to load on an https page.
*/
const unsigned long LOAD_FLAGS_ALLOW_MIXED_CONTENT = 0x2000;
/**
* This flag specifies that this is the first load in this object.
* Set with care, since setting incorrectly can cause us to assume that
* nothing was actually loaded in this object if the load ends up being
* handled by an external application. This flag must not be passed to
* Reload.
*/
const unsigned long LOAD_FLAGS_FIRST_LOAD = 0x4000;
/**
* This flag specifies that the load should not be subject to popup
* blocking checks. This flag must not be passed to Reload.
*/
const unsigned long LOAD_FLAGS_ALLOW_POPUPS = 0x8000;
/**
* This flag specifies that the URI classifier should not be checked for
* this load. This flag must not be passed to Reload.
*/
const unsigned long LOAD_FLAGS_BYPASS_CLASSIFIER = 0x10000;
/**
* Force relevant cookies to be sent with this load even if normally they
* wouldn't be.
*/
const unsigned long LOAD_FLAGS_FORCE_ALLOW_COOKIES = 0x20000;
/**
* Prevent the owner principal from being inherited for this load.
* Note: Within Gecko we use the term principal rather than owners
* but some legacy addons might still rely on the outdated term.
*/
const unsigned long LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL = 0x40000;
const unsigned long LOAD_FLAGS_DISALLOW_INHERIT_OWNER = 0x40000;
/**
* Overwrite the returned error code with a specific result code
* when an error page is displayed.
*/
const unsigned long LOAD_FLAGS_ERROR_LOAD_CHANGES_RV = 0x80000;
/**
* This flag specifies that the URI may be submitted to a third-party
* server for correction. This should only be applied to non-sensitive
* URIs entered by users. This flag must not be passed to Reload.
*/
const unsigned long LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP = 0x100000;
/**
* This flag specifies that common scheme typos should be corrected.
*/
const unsigned long LOAD_FLAGS_FIXUP_SCHEME_TYPOS = 0x200000;
/**
* Loads a given URI. This will give priority to loading the requested URI
* in the object implementing this interface. If it can't be loaded here
* however, the URI dispatcher will go through its normal process of content
* loading.
*
* @param aURI
* The URI string to load. For HTTP and FTP URLs and possibly others,
* characters above U+007F will be converted to UTF-8 and then URL-
* escaped per the rules of RFC 2396.
* @param aLoadFlags
* Flags modifying load behaviour. This parameter is a bitwise
* combination of the load flags defined above. (Undefined bits are
* reserved for future use.) Generally you will pass LOAD_FLAGS_NONE
* for this parameter.
* @param aReferrer
* The referring URI. If this argument is null, then the referring
* URI will be inferred internally.
* @param aPostData
* If the URI corresponds to a HTTP request, then this stream is
* appended directly to the HTTP request headers. It may be prefixed
* with additional HTTP headers. This stream must contain a "\r\n"
* sequence separating any HTTP headers from the HTTP request body.
* This parameter is optional and may be null.
* @param aHeaders
* If the URI corresponds to a HTTP request, then any HTTP headers
* contained in this stream are set on the HTTP request. The HTTP
* header stream is formatted as:
* ( HEADER "\r\n" )*
* This parameter is optional and may be null.
*/
void loadURI(in wstring aURI,
in unsigned long aLoadFlags,
in nsIURI aReferrer,
in nsIInputStream aPostData,
in nsIInputStream aHeaders);
/**
* Loads a given URI. This will give priority to loading the requested URI
* in the object implementing this interface. If it can't be loaded here
* however, the URI dispatcher will go through its normal process of content
* loading.
*
* Behaves like loadURI, but allows passing of additional parameters.
*
* @param aURI
* The URI string to load. For HTTP and FTP URLs and possibly others,
* characters above U+007F will be converted to UTF-8 and then URL-
* escaped per the rules of RFC 2396.
* @param aLoadFlags
* Flags modifying load behaviour. This parameter is a bitwise
* combination of the load flags defined above. (Undefined bits are
* reserved for future use.) Generally you will pass LOAD_FLAGS_NONE
* for this parameter.
* @param aReferrer
* The referring URI. If this argument is null, then the referring
* URI will be inferred internally.
* @param aReferrerPolicy
* One of the REFERRER_POLICY_* constants from nsIHttpChannel.
* Normal case is REFERRER_POLICY_DEFAULT.
* @param aPostData
* If the URI corresponds to a HTTP request, then this stream is
* appended directly to the HTTP request headers. It may be prefixed
* with additional HTTP headers. This stream must contain a "\r\n"
* sequence separating any HTTP headers from the HTTP request body.
* This parameter is optional and may be null.
* @param aHeaders
* If the URI corresponds to a HTTP request, then any HTTP headers
* contained in this stream are set on the HTTP request. The HTTP
* header stream is formatted as:
* ( HEADER "\r\n" )*
* This parameter is optional and may be null.
* @param aBaseURI
* Set to indicate a base URI to be associated with the load. Note
* that at present this argument is only used with view-source aURIs
* and cannot be used to resolve aURI.
* This parameter is optional and may be null.
*/
void loadURIWithOptions(in wstring aURI,
in unsigned long aLoadFlags,
in nsIURI aReferrer,
in unsigned long aReferrerPolicy,
in nsIInputStream aPostData,
in nsIInputStream aHeaders,
in nsIURI aBaseURI);
/**
* Tells the Object to reload the current page. There may be cases where the
* user will be asked to confirm the reload (for example, when it is
* determined that the request is non-idempotent).
*
* @param aReloadFlags
* Flags modifying load behaviour. This parameter is a bitwise
* combination of the Load Flags defined above. (Undefined bits are
* reserved for future use.) Generally you will pass LOAD_FLAGS_NONE
* for this parameter.
*
* @throw NS_BINDING_ABORTED
* Indicating that the user canceled the reload.
*/
void reload(in unsigned long aReloadFlags);
/****************************************************************************
* The following flags may be passed as the stop flags parameter to the stop
* method defined on this interface.
*/
/**
* This flag specifies that all network activity should be stopped. This
* includes both active network loads and pending META-refreshes.
*/
const unsigned long STOP_NETWORK = 0x01;
/**
* This flag specifies that all content activity should be stopped. This
* includes animated images, plugins and pending Javascript timeouts.
*/
const unsigned long STOP_CONTENT = 0x02;
/**
* This flag specifies that all activity should be stopped.
*/
const unsigned long STOP_ALL = 0x03;
/**
* Stops a load of a URI.
*
* @param aStopFlags
* This parameter is one of the stop flags defined above.
*/
void stop(in unsigned long aStopFlags);
/**
* Retrieves the current DOM document for the frame, or lazily creates a
* blank document if there is none. This attribute never returns null except
* for unexpected error situations.
*/
readonly attribute nsIDOMDocument document;
/**
* The currently loaded URI or null.
*/
readonly attribute nsIURI currentURI;
/**
* The referring URI for the currently loaded URI or null.
*/
readonly attribute nsIURI referringURI;
/**
* The session history object used by this web navigation instance.
*/
attribute nsISHistory sessionHistory;
/**
* Set an OriginAttributes dictionary in the docShell. This can be done only
* before loading any content.
*/
void setOriginAttributesBeforeLoading(in jsval originAttributes);
};

View file

@ -0,0 +1,63 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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 "nsISupports.idl"
interface nsIWebNavigation;
/**
* The nsIWebNavigationInfo interface exposes a way to get information
* on the capabilities of Gecko webnavigation objects.
*/
[scriptable, uuid(62a93afb-93a1-465c-84c8-0432264229de)]
interface nsIWebNavigationInfo : nsISupports
{
/**
* Returned by isTypeSupported to indicate lack of support for a type.
* @note this is guaranteed not to change, so that boolean tests can be done
* on the return value if isTypeSupported to detect whether a type is
* supported at all.
*/
const unsigned long UNSUPPORTED = 0;
/**
* Returned by isTypeSupported to indicate that a type is supported as an
* image.
*/
const unsigned long IMAGE = 1;
/**
* Returned by isTypeSupported to indicate that a type is supported via an
* NPAPI ("Netscape 4 API") plug-in. This is not the value returned for
* "XPCOM plug-ins".
*/
const unsigned long PLUGIN = 2;
/**
* @note Other return types may be added here in the future as they become
* relevant.
*/
/**
* Returned by isTypeSupported to indicate that a type is supported via some
* other means.
*/
const unsigned long OTHER = 1 << 15;
/**
* Query whether aType is supported.
* @param aType the MIME type in question.
* @param aWebNav the nsIWebNavigation object for which the request
* is being made. This is allowed to be null. If it is non-null,
* the return value of this method may depend on the exact state of
* aWebNav and the values set through nsIWebBrowserSetup; otherwise
* the method will assume that the caller is interested in information
* about nsIWebNavigation objects in their default state.
* @return an enum value indicating whether and how aType is supported.
* @note This method may rescan plugins to ensure that they're properly
* registered for the types they support.
*/
unsigned long isTypeSupported(in ACString aType, in nsIWebNavigation aWebNav);
};

View file

@ -0,0 +1,30 @@
/* 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 "nsISupports.idl"
/**
* The nsIWebPageDescriptor interface allows content being displayed in one
* window to be loaded into another window without refetching it from the
* network.
*/
[scriptable, uuid(6f30b676-3710-4c2c-80b1-0395fb26516e)]
interface nsIWebPageDescriptor : nsISupports
{
const unsigned long DISPLAY_AS_SOURCE = 0x0001;
const unsigned long DISPLAY_NORMAL = 0x0002;
/**
* Tells the object to load the page specified by the page descriptor
*
* @throws NS_ERROR_FAILURE -
*/
void loadPage(in nsISupports aPageDescriptor, in unsigned long aDisplayType);
/**
* Retrieves the page descriptor for the curent document.
*/
readonly attribute nsISupports currentDescriptor;
};

View file

@ -0,0 +1,34 @@
/* -*- 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 nsIWebShellServices_h___
#define nsIWebShellServices_h___
#include "nsISupports.h"
#include "nsCharsetSource.h"
/* 0c628af0-5638-4703-8f99-ed6134c9de18 */
#define NS_IWEB_SHELL_SERVICES_IID \
{ 0x0c628af0, 0x5638, 0x4703, {0x8f, 0x99, 0xed, 0x61, 0x34, 0xc9, 0xde, 0x18} }
class nsIWebShellServices : public nsISupports
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IWEB_SHELL_SERVICES_IID)
NS_IMETHOD ReloadDocument(const char* aCharset = nullptr,
int32_t aSource = kCharsetUninitialized) = 0;
NS_IMETHOD StopDocumentLoad(void) = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIWebShellServices, NS_IWEB_SHELL_SERVICES_IID)
/* Use this macro when declaring classes that implement this interface. */
#define NS_DECL_NSIWEBSHELLSERVICES \
NS_IMETHOD ReloadDocument(const char* aCharset = nullptr, \
int32_t aSource = kCharsetUninitialized) override; \
NS_IMETHOD StopDocumentLoad(void) override;
#endif /* nsIWebShellServices_h___ */

View file

@ -0,0 +1,134 @@
/* -*- 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 "nsWebNavigationInfo.h"
#include "nsIWebNavigation.h"
#include "nsServiceManagerUtils.h"
#include "nsIDocumentLoaderFactory.h"
#include "nsIPluginHost.h"
#include "nsIDocShell.h"
#include "nsContentUtils.h"
#include "imgLoader.h"
NS_IMPL_ISUPPORTS(nsWebNavigationInfo, nsIWebNavigationInfo)
#define CONTENT_DLF_CONTRACT "@mozilla.org/content/document-loader-factory;1"
#define PLUGIN_DLF_CONTRACT \
"@mozilla.org/content/plugin/document-loader-factory;1"
nsresult
nsWebNavigationInfo::Init()
{
nsresult rv;
mCategoryManager = do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
NS_IMETHODIMP
nsWebNavigationInfo::IsTypeSupported(const nsACString& aType,
nsIWebNavigation* aWebNav,
uint32_t* aIsTypeSupported)
{
NS_PRECONDITION(aIsTypeSupported, "null out param?");
// Note to self: aWebNav could be an nsWebBrowser or an nsDocShell here (or
// an nsSHistory, but not much we can do with that). So if we start using
// it here, we need to be careful to get to the docshell correctly.
// For now just report what the Gecko-Content-Viewers category has
// to say for itself.
*aIsTypeSupported = nsIWebNavigationInfo::UNSUPPORTED;
// We want to claim that the type for PDF documents is unsupported,
// so that the internal PDF viewer's stream converted will get used.
if (aType.LowerCaseEqualsLiteral("application/pdf") &&
nsContentUtils::IsPDFJSEnabled()) {
return NS_OK;
}
// We want to claim that the type for SWF movies is unsupported,
// so that the internal SWF player's stream converter will get used.
if (aType.LowerCaseEqualsLiteral("application/x-shockwave-flash") &&
nsContentUtils::IsSWFPlayerEnabled()) {
return NS_OK;
}
const nsCString& flatType = PromiseFlatCString(aType);
nsresult rv = IsTypeSupportedInternal(flatType, aIsTypeSupported);
NS_ENSURE_SUCCESS(rv, rv);
if (*aIsTypeSupported) {
return rv;
}
// If this request is for a docShell that isn't going to allow plugins,
// there's no need to try and find a plugin to handle it.
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(aWebNav));
bool allowed;
if (docShell &&
NS_SUCCEEDED(docShell->GetAllowPlugins(&allowed)) && !allowed) {
return NS_OK;
}
// Try reloading plugins in case they've changed.
nsCOMPtr<nsIPluginHost> pluginHost =
do_GetService(MOZ_PLUGIN_HOST_CONTRACTID);
if (pluginHost) {
// false will ensure that currently running plugins will not
// be shut down
rv = pluginHost->ReloadPlugins();
if (NS_SUCCEEDED(rv)) {
// OK, we reloaded plugins and there were new ones
// (otherwise NS_ERROR_PLUGINS_PLUGINSNOTCHANGED would have
// been returned). Try checking whether we can handle the
// content now.
return IsTypeSupportedInternal(flatType, aIsTypeSupported);
}
}
return NS_OK;
}
nsresult
nsWebNavigationInfo::IsTypeSupportedInternal(const nsCString& aType,
uint32_t* aIsSupported)
{
NS_PRECONDITION(aIsSupported, "Null out param?");
nsContentUtils::ContentViewerType vtype = nsContentUtils::TYPE_UNSUPPORTED;
nsCOMPtr<nsIDocumentLoaderFactory> docLoaderFactory =
nsContentUtils::FindInternalContentViewer(aType, &vtype);
switch (vtype) {
case nsContentUtils::TYPE_UNSUPPORTED:
*aIsSupported = nsIWebNavigationInfo::UNSUPPORTED;
break;
case nsContentUtils::TYPE_PLUGIN:
*aIsSupported = nsIWebNavigationInfo::PLUGIN;
break;
case nsContentUtils::TYPE_UNKNOWN:
*aIsSupported = nsIWebNavigationInfo::OTHER;
break;
case nsContentUtils::TYPE_CONTENT:
// XXXbz we only need this because images register for the same
// contractid as documents, so we can't tell them apart based on
// contractid.
if (imgLoader::SupportImageWithMimeType(aType.get())) {
*aIsSupported = nsIWebNavigationInfo::IMAGE;
} else {
*aIsSupported = nsIWebNavigationInfo::OTHER;
}
break;
}
return NS_OK;
}

View file

@ -0,0 +1,42 @@
/* -*- 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 nsWebNavigationInfo_h__
#define nsWebNavigationInfo_h__
#include "nsIWebNavigationInfo.h"
#include "nsCOMPtr.h"
#include "nsICategoryManager.h"
#include "mozilla/Attributes.h"
class nsCString;
#define NS_WEBNAVIGATION_INFO_CID \
{ 0xf30bc0a2, 0x958b, 0x4287,{0xbf, 0x62, 0xce, 0x38, 0xba, 0x0c, 0x81, 0x1e}}
class nsWebNavigationInfo final : public nsIWebNavigationInfo
{
public:
nsWebNavigationInfo() {}
NS_DECL_ISUPPORTS
NS_DECL_NSIWEBNAVIGATIONINFO
nsresult Init();
private:
~nsWebNavigationInfo() {}
// Check whether aType is supported. If this method throws, the
// value of aIsSupported is not changed.
nsresult IsTypeSupportedInternal(const nsCString& aType,
uint32_t* aIsSupported);
nsCOMPtr<nsICategoryManager> mCategoryManager;
};
#endif // nsWebNavigationInfo_h__

View file

@ -0,0 +1,90 @@
/* -*- 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 "AbstractTimelineMarker.h"
#include "mozilla/TimeStamp.h"
#include "MainThreadUtils.h"
#include "nsAppRunner.h"
namespace mozilla {
AbstractTimelineMarker::AbstractTimelineMarker(const char* aName,
MarkerTracingType aTracingType)
: mName(aName)
, mTracingType(aTracingType)
, mProcessType(XRE_GetProcessType())
, mIsOffMainThread(!NS_IsMainThread())
{
MOZ_COUNT_CTOR(AbstractTimelineMarker);
SetCurrentTime();
}
AbstractTimelineMarker::AbstractTimelineMarker(const char* aName,
const TimeStamp& aTime,
MarkerTracingType aTracingType)
: mName(aName)
, mTracingType(aTracingType)
, mProcessType(XRE_GetProcessType())
, mIsOffMainThread(!NS_IsMainThread())
{
MOZ_COUNT_CTOR(AbstractTimelineMarker);
SetCustomTime(aTime);
}
UniquePtr<AbstractTimelineMarker>
AbstractTimelineMarker::Clone()
{
MOZ_ASSERT(false, "Clone method not yet implemented on this marker type.");
return nullptr;
}
bool
AbstractTimelineMarker::Equals(const AbstractTimelineMarker& aOther)
{
// Check whether two markers should be considered the same, for the purpose
// of pairing start and end markers. Normally this definition suffices.
return strcmp(mName, aOther.mName) == 0;
}
AbstractTimelineMarker::~AbstractTimelineMarker()
{
MOZ_COUNT_DTOR(AbstractTimelineMarker);
}
void
AbstractTimelineMarker::SetCurrentTime()
{
TimeStamp now = TimeStamp::Now();
SetCustomTime(now);
}
void
AbstractTimelineMarker::SetCustomTime(const TimeStamp& aTime)
{
bool isInconsistent = false;
mTime = (aTime - TimeStamp::ProcessCreation(isInconsistent)).ToMilliseconds();
}
void
AbstractTimelineMarker::SetCustomTime(DOMHighResTimeStamp aTime)
{
mTime = aTime;
}
void
AbstractTimelineMarker::SetProcessType(GeckoProcessType aProcessType)
{
mProcessType = aProcessType;
}
void
AbstractTimelineMarker::SetOffMainThread(bool aIsOffMainThread)
{
mIsOffMainThread = aIsOffMainThread;
}
} // namespace mozilla

View file

@ -0,0 +1,73 @@
/* -*- 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_AbstractTimelineMarker_h_
#define mozilla_AbstractTimelineMarker_h_
#include "TimelineMarkerEnums.h" // for MarkerTracingType
#include "nsDOMNavigationTiming.h" // for DOMHighResTimeStamp
#include "nsXULAppAPI.h" // for GeckoProcessType
#include "mozilla/UniquePtr.h"
struct JSContext;
class JSObject;
namespace mozilla {
class TimeStamp;
namespace dom {
struct ProfileTimelineMarker;
}
class AbstractTimelineMarker
{
private:
AbstractTimelineMarker() = delete;
AbstractTimelineMarker(const AbstractTimelineMarker& aOther) = delete;
void operator=(const AbstractTimelineMarker& aOther) = delete;
public:
AbstractTimelineMarker(const char* aName,
MarkerTracingType aTracingType);
AbstractTimelineMarker(const char* aName,
const TimeStamp& aTime,
MarkerTracingType aTracingType);
virtual ~AbstractTimelineMarker();
virtual UniquePtr<AbstractTimelineMarker> Clone();
virtual bool Equals(const AbstractTimelineMarker& aOther);
virtual void AddDetails(JSContext* aCx, dom::ProfileTimelineMarker& aMarker) = 0;
virtual JSObject* GetStack() = 0;
const char* GetName() const { return mName; }
DOMHighResTimeStamp GetTime() const { return mTime; }
MarkerTracingType GetTracingType() const { return mTracingType; }
uint8_t GetProcessType() const { return mProcessType; };
bool IsOffMainThread() const { return mIsOffMainThread; };
private:
const char* mName;
DOMHighResTimeStamp mTime;
MarkerTracingType mTracingType;
uint8_t mProcessType; // @see `enum GeckoProcessType`.
bool mIsOffMainThread;
protected:
void SetCurrentTime();
void SetCustomTime(const TimeStamp& aTime);
void SetCustomTime(DOMHighResTimeStamp aTime);
void SetProcessType(GeckoProcessType aProcessType);
void SetOffMainThread(bool aIsOffMainThread);
};
} // namespace mozilla
#endif /* mozilla_AbstractTimelineMarker_h_ */

View file

@ -0,0 +1,43 @@
/* -*- 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 "AutoGlobalTimelineMarker.h"
#include "TimelineConsumers.h"
#include "MainThreadUtils.h"
namespace mozilla {
AutoGlobalTimelineMarker::AutoGlobalTimelineMarker(const char* aName,
MarkerStackRequest aStackRequest /* = STACK */
MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
: mName(aName)
, mStackRequest(aStackRequest)
{
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
MOZ_ASSERT(NS_IsMainThread());
RefPtr<TimelineConsumers> timelines = TimelineConsumers::Get();
if (!timelines || timelines->IsEmpty()) {
return;
}
timelines->AddMarkerForAllObservedDocShells(mName, MarkerTracingType::START, mStackRequest);
}
AutoGlobalTimelineMarker::~AutoGlobalTimelineMarker()
{
MOZ_ASSERT(NS_IsMainThread());
RefPtr<TimelineConsumers> timelines = TimelineConsumers::Get();
if (!timelines || timelines->IsEmpty()) {
return;
}
timelines->AddMarkerForAllObservedDocShells(mName, MarkerTracingType::END, mStackRequest);
}
} // namespace mozilla

View file

@ -0,0 +1,51 @@
/* -*- 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_AutoGlobalTimelineMarker_h_
#define mozilla_AutoGlobalTimelineMarker_h_
#include "mozilla/GuardObjects.h"
#include "TimelineMarkerEnums.h"
namespace mozilla {
// # AutoGlobalTimelineMarker
//
// Similar to `AutoTimelineMarker`, but adds its traced marker to all docshells,
// not a single particular one. This is useful for operations that aren't
// associated with any one particular doc shell, or when it isn't clear which
// docshell triggered the operation.
//
// Example usage:
//
// {
// AutoGlobalTimelineMarker marker("Cycle Collection");
// nsCycleCollector* cc = GetCycleCollector();
// cc->Collect();
// ...
// }
class MOZ_RAII AutoGlobalTimelineMarker
{
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER;
// The name of the marker we are adding.
const char* mName;
// Whether to capture the JS stack or not.
MarkerStackRequest mStackRequest;
public:
explicit AutoGlobalTimelineMarker(const char* aName,
MarkerStackRequest aStackRequest = MarkerStackRequest::STACK
MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
~AutoGlobalTimelineMarker();
AutoGlobalTimelineMarker(const AutoGlobalTimelineMarker& aOther) = delete;
void operator=(const AutoGlobalTimelineMarker& aOther) = delete;
};
} // namespace mozilla
#endif /* mozilla_AutoGlobalTimelineMarker_h_ */

View file

@ -0,0 +1,51 @@
/* -*- 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 "AutoTimelineMarker.h"
#include "TimelineConsumers.h"
#include "MainThreadUtils.h"
namespace mozilla {
AutoTimelineMarker::AutoTimelineMarker(nsIDocShell* aDocShell, const char* aName
MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
: mName(aName)
, mDocShell(nullptr)
{
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
MOZ_ASSERT(NS_IsMainThread());
if (!aDocShell) {
return;
}
RefPtr<TimelineConsumers> timelines = TimelineConsumers::Get();
if (!timelines || !timelines->HasConsumer(aDocShell)) {
return;
}
mDocShell = aDocShell;
timelines->AddMarkerForDocShell(mDocShell, mName, MarkerTracingType::START);
}
AutoTimelineMarker::~AutoTimelineMarker()
{
MOZ_ASSERT(NS_IsMainThread());
if (!mDocShell) {
return;
}
RefPtr<TimelineConsumers> timelines = TimelineConsumers::Get();
if (!timelines || !timelines->HasConsumer(mDocShell)) {
return;
}
timelines->AddMarkerForDocShell(mDocShell, mName, MarkerTracingType::END);
}
} // namespace mozilla

View file

@ -0,0 +1,51 @@
/* -*- 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_AutoTimelineMarker_h_
#define mozilla_AutoTimelineMarker_h_
#include "mozilla/GuardObjects.h"
#include "mozilla/RefPtr.h"
class nsIDocShell;
namespace mozilla {
// # AutoTimelineMarker
//
// An RAII class to trace some task in the platform by adding a start and end
// timeline marker pair. These markers are then rendered in the devtools'
// performance tool's waterfall graph.
//
// Example usage:
//
// {
// AutoTimelineMarker marker(mDocShell, "Parse CSS");
// nsresult rv = ParseTheCSSFile(mFile);
// ...
// }
class MOZ_RAII AutoTimelineMarker
{
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER;
// The name of the marker we are adding.
const char* mName;
// The docshell that is associated with this marker.
RefPtr<nsIDocShell> mDocShell;
public:
AutoTimelineMarker(nsIDocShell* aDocShell,
const char* aName MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
~AutoTimelineMarker();
AutoTimelineMarker(const AutoTimelineMarker& aOther) = delete;
void operator=(const AutoTimelineMarker& aOther) = delete;
};
} // namespace mozilla
#endif /* mozilla_AutoTimelineMarker_h_ */

View file

@ -0,0 +1,33 @@
/* -*- 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_CompositeTimelineMarker_h_
#define mozilla_CompositeTimelineMarker_h_
#include "TimelineMarker.h"
#include "mozilla/dom/ProfileTimelineMarkerBinding.h"
namespace mozilla {
class CompositeTimelineMarker : public TimelineMarker
{
public:
CompositeTimelineMarker(const TimeStamp& aTime,
MarkerTracingType aTracingType)
: TimelineMarker("Composite", aTime, aTracingType)
{
// Even though these markers end up being created on the main thread in the
// content or chrome processes, they actually trace down code in the
// compositor parent process. All the information for creating these markers
// is sent along via IPC to an nsView when a composite finishes.
// Mark this as 'off the main thread' to style it differently in frontends.
SetOffMainThread(true);
}
};
} // namespace mozilla
#endif // mozilla_CompositeTimelineMarker_h_

View file

@ -0,0 +1,58 @@
/* -*- 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_ConsoleTimelineMarker_h_
#define mozilla_ConsoleTimelineMarker_h_
#include "TimelineMarker.h"
#include "mozilla/dom/ProfileTimelineMarkerBinding.h"
namespace mozilla {
class ConsoleTimelineMarker : public TimelineMarker
{
public:
ConsoleTimelineMarker(const nsAString& aCause,
MarkerTracingType aTracingType)
: TimelineMarker("ConsoleTime", aTracingType)
, mCause(aCause)
{
// Stack is captured by default on the "start" marker. Explicitly also
// capture stack on the "end" marker.
if (aTracingType == MarkerTracingType::END) {
CaptureStack();
}
}
virtual bool Equals(const AbstractTimelineMarker& aOther) override
{
if (!TimelineMarker::Equals(aOther)) {
return false;
}
// Console markers must have matching causes as well. It is safe to perform
// a static_cast here as the previous equality check ensures that this is
// a console marker instance.
return mCause == static_cast<const ConsoleTimelineMarker*>(&aOther)->mCause;
}
virtual void AddDetails(JSContext* aCx, dom::ProfileTimelineMarker& aMarker) override
{
TimelineMarker::AddDetails(aCx, aMarker);
if (GetTracingType() == MarkerTracingType::START) {
aMarker.mCauseName.Construct(mCause);
} else {
aMarker.mEndStack = GetStack();
}
}
private:
nsString mCause;
};
} // namespace mozilla
#endif // mozilla_ConsoleTimelineMarker_h_

View file

@ -0,0 +1,40 @@
/* -*- 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_DocLoadingTimelineMarker_h_
#define mozilla_DocLoadingTimelineMarker_h_
#include "TimelineMarker.h"
#include "mozilla/dom/ProfileTimelineMarkerBinding.h"
namespace mozilla {
class DocLoadingTimelineMarker : public TimelineMarker
{
public:
explicit DocLoadingTimelineMarker(const char* aName)
: TimelineMarker(aName, MarkerTracingType::TIMESTAMP)
, mUnixTime(PR_Now())
{}
virtual void AddDetails(JSContext* aCx, dom::ProfileTimelineMarker& aMarker) override
{
TimelineMarker::AddDetails(aCx, aMarker);
aMarker.mUnixTime.Construct(mUnixTime);
}
private:
// Certain consumers might use Date.now() or similar for tracing time.
// However, TimelineMarkers use process creation as an epoch, which provides
// more precision. To allow syncing, attach an additional unix timestamp.
// Using this instead of `AbstractTimelineMarker::GetTime()'s` timestamp
// is strongly discouraged.
PRTime mUnixTime;
};
} // namespace mozilla
#endif // mozilla_DocLoadingTimelineMarker_h_

View file

@ -0,0 +1,43 @@
/* -*- 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_EventTimelineMarker_h_
#define mozilla_EventTimelineMarker_h_
#include "TimelineMarker.h"
#include "mozilla/dom/ProfileTimelineMarkerBinding.h"
namespace mozilla {
class EventTimelineMarker : public TimelineMarker
{
public:
EventTimelineMarker(const nsAString& aType,
uint16_t aPhase,
MarkerTracingType aTracingType)
: TimelineMarker("DOMEvent", aTracingType)
, mType(aType)
, mPhase(aPhase)
{}
virtual void AddDetails(JSContext* aCx, dom::ProfileTimelineMarker& aMarker) override
{
TimelineMarker::AddDetails(aCx, aMarker);
if (GetTracingType() == MarkerTracingType::START) {
aMarker.mType.Construct(mType);
aMarker.mEventPhase.Construct(mPhase);
}
}
private:
nsString mType;
uint16_t mPhase;
};
} // namespace mozilla
#endif // mozilla_EventTimelineMarker_h_

View file

@ -0,0 +1,95 @@
/* -*- 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_JavascriptTimelineMarker_h_
#define mozilla_JavascriptTimelineMarker_h_
#include "TimelineMarker.h"
#include "mozilla/dom/ProfileTimelineMarkerBinding.h"
#include "mozilla/dom/RootedDictionary.h"
#include "mozilla/dom/ToJSValue.h"
namespace mozilla {
class JavascriptTimelineMarker : public TimelineMarker
{
public:
// The caller owns |aAsyncCause| here, so we must copy it into a separate
// string for use later on.
JavascriptTimelineMarker(const char* aReason,
const char16_t* aFunctionName,
const char16_t* aFileName,
uint32_t aLineNumber,
MarkerTracingType aTracingType,
JS::Handle<JS::Value> aAsyncStack,
const char* aAsyncCause)
: TimelineMarker("Javascript", aTracingType, MarkerStackRequest::NO_STACK)
, mCause(NS_ConvertUTF8toUTF16(aReason))
, mFunctionName(aFunctionName)
, mFileName(aFileName)
, mLineNumber(aLineNumber)
, mAsyncCause(aAsyncCause)
{
JSContext* ctx = nsContentUtils::GetCurrentJSContext();
if (ctx) {
mAsyncStack.init(ctx, aAsyncStack);
}
}
virtual void AddDetails(JSContext* aCx, dom::ProfileTimelineMarker& aMarker) override
{
TimelineMarker::AddDetails(aCx, aMarker);
aMarker.mCauseName.Construct(mCause);
if (!mFunctionName.IsEmpty() || !mFileName.IsEmpty()) {
dom::RootedDictionary<dom::ProfileTimelineStackFrame> stackFrame(aCx);
stackFrame.mLine.Construct(mLineNumber);
stackFrame.mSource.Construct(mFileName);
stackFrame.mFunctionDisplayName.Construct(mFunctionName);
if (mAsyncStack.isObject() && !mAsyncStack.isNullOrUndefined() &&
!mAsyncCause.IsEmpty()) {
JS::Rooted<JSObject*> asyncStack(aCx, mAsyncStack.toObjectOrNull());
JS::Rooted<JSObject*> parentFrame(aCx);
JS::Rooted<JSString*> asyncCause(aCx, JS_NewUCStringCopyN(aCx, mAsyncCause.BeginReading(),
mAsyncCause.Length()));
if (!asyncCause) {
JS_ClearPendingException(aCx);
return;
}
if (JS::IsSavedFrame(asyncStack) &&
!JS::CopyAsyncStack(aCx, asyncStack, asyncCause, &parentFrame, 0)) {
JS_ClearPendingException(aCx);
} else {
stackFrame.mAsyncParent = parentFrame;
}
}
JS::Rooted<JS::Value> newStack(aCx);
if (ToJSValue(aCx, stackFrame, &newStack)) {
if (newStack.isObject()) {
aMarker.mStack = &newStack.toObject();
}
} else {
JS_ClearPendingException(aCx);
}
}
}
private:
nsString mCause;
nsString mFunctionName;
nsString mFileName;
uint32_t mLineNumber;
JS::PersistentRooted<JS::Value> mAsyncStack;
NS_ConvertUTF8toUTF16 mAsyncCause;
};
} // namespace mozilla
#endif // mozilla_JavascriptTimelineMarker_h_

View file

@ -0,0 +1,43 @@
/* -*- 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_LayerTimelineMarker_h_
#define mozilla_LayerTimelineMarker_h_
#include "TimelineMarker.h"
#include "mozilla/dom/ProfileTimelineMarkerBinding.h"
#include "nsRegion.h"
namespace mozilla {
class LayerTimelineMarker : public TimelineMarker
{
public:
explicit LayerTimelineMarker(const nsIntRegion& aRegion)
: TimelineMarker("Layer", MarkerTracingType::HELPER_EVENT)
, mRegion(aRegion)
{}
void AddLayerRectangles(dom::Sequence<dom::ProfileTimelineLayerRect>& aRectangles)
{
for (auto iter = mRegion.RectIter(); !iter.Done(); iter.Next()) {
const nsIntRect& iterRect = iter.Get();
dom::ProfileTimelineLayerRect rect;
rect.mX = iterRect.X();
rect.mY = iterRect.Y();
rect.mWidth = iterRect.Width();
rect.mHeight = iterRect.Height();
aRectangles.AppendElement(rect, fallible);
}
}
private:
nsIntRegion mRegion;
};
} // namespace mozilla
#endif // mozilla_LayerTimelineMarker_h_

View file

@ -0,0 +1,29 @@
/* -*- 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 "MarkersStorage.h"
#include "MainThreadUtils.h"
namespace mozilla {
MarkersStorage::MarkersStorage(const char* aMutexName)
: mLock(aMutexName)
{
MOZ_ASSERT(NS_IsMainThread());
}
MarkersStorage::~MarkersStorage()
{
MOZ_ASSERT(NS_IsMainThread());
}
Mutex&
MarkersStorage::GetLock()
{
return mLock;
}
} // namespace mozilla

View file

@ -0,0 +1,48 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_MarkersStorage_h_
#define mozilla_MarkersStorage_h_
#include "TimelineMarkerEnums.h" // for MarkerReleaseRequest
#include "mozilla/Mutex.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/LinkedList.h"
#include "nsTArray.h"
namespace mozilla {
class AbstractTimelineMarker;
namespace dom {
struct ProfileTimelineMarker;
}
class MarkersStorage : public LinkedListElement<MarkersStorage>
{
private:
MarkersStorage() = delete;
MarkersStorage(const MarkersStorage& aOther) = delete;
void operator=(const MarkersStorage& aOther) = delete;
public:
explicit MarkersStorage(const char* aMutexName);
virtual ~MarkersStorage();
virtual void AddMarker(UniquePtr<AbstractTimelineMarker>&& aMarker) = 0;
virtual void AddOTMTMarker(UniquePtr<AbstractTimelineMarker>&& aMarker) = 0;
virtual void ClearMarkers() = 0;
virtual void PopMarkers(JSContext* aCx, nsTArray<dom::ProfileTimelineMarker>& aStore) = 0;
protected:
Mutex& GetLock();
private:
Mutex mLock;
};
} // namespace mozilla
#endif /* mozilla_MarkersStorage_h_ */

View file

@ -0,0 +1,47 @@
/* -*- 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_MessagePortTimelineMarker_h_
#define mozilla_MessagePortTimelineMarker_h_
#include "TimelineMarker.h"
#include "mozilla/dom/ProfileTimelineMarkerBinding.h"
namespace mozilla {
class MessagePortTimelineMarker : public TimelineMarker
{
public:
MessagePortTimelineMarker(dom::ProfileTimelineMessagePortOperationType aOperationType,
MarkerTracingType aTracingType)
: TimelineMarker("MessagePort", aTracingType, MarkerStackRequest::NO_STACK)
, mOperationType(aOperationType)
{}
virtual UniquePtr<AbstractTimelineMarker> Clone() override
{
MessagePortTimelineMarker* clone =
new MessagePortTimelineMarker(mOperationType, GetTracingType());
clone->SetCustomTime(GetTime());
return UniquePtr<AbstractTimelineMarker>(clone);
}
virtual void AddDetails(JSContext* aCx, dom::ProfileTimelineMarker& aMarker) override
{
TimelineMarker::AddDetails(aCx, aMarker);
if (GetTracingType() == MarkerTracingType::START) {
aMarker.mMessagePortOperation.Construct(mOperationType);
}
}
private:
dom::ProfileTimelineMessagePortOperationType mOperationType;
};
} // namespace mozilla
#endif /* mozilla_MessagePortTimelineMarker_h_ */

View file

@ -0,0 +1,171 @@
/* -*- 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 "ObservedDocShell.h"
#include "AbstractTimelineMarker.h"
#include "LayerTimelineMarker.h"
#include "MainThreadUtils.h"
#include "mozilla/Move.h"
#include "mozilla/AutoRestore.h"
namespace mozilla {
ObservedDocShell::ObservedDocShell(nsIDocShell* aDocShell)
: MarkersStorage("ObservedDocShellMutex")
, mDocShell(aDocShell)
, mPopping(false)
{
MOZ_ASSERT(NS_IsMainThread());
}
void
ObservedDocShell::AddMarker(UniquePtr<AbstractTimelineMarker>&& aMarker)
{
// Only allow main thread markers to go into this list. No need to lock
// here since `mTimelineMarkers` will only be accessed or modified on the
// main thread only.
MOZ_ASSERT(NS_IsMainThread());
// Don't accept any markers generated by the process of popping
// markers.
if (!mPopping) {
mTimelineMarkers.AppendElement(Move(aMarker));
}
}
void
ObservedDocShell::AddOTMTMarker(UniquePtr<AbstractTimelineMarker>&& aMarker)
{
// Only allow off the main thread markers to go into this list. Since most
// of our markers come from the main thread, be a little more efficient and
// avoid dealing with multithreading scenarios until all the markers are
// actually cleared or popped in `ClearMarkers` or `PopMarkers`.
MOZ_ASSERT(!NS_IsMainThread());
MutexAutoLock lock(GetLock()); // for `mOffTheMainThreadTimelineMarkers`.
mOffTheMainThreadTimelineMarkers.AppendElement(Move(aMarker));
}
void
ObservedDocShell::ClearMarkers()
{
MOZ_ASSERT(NS_IsMainThread());
MutexAutoLock lock(GetLock()); // for `mOffTheMainThreadTimelineMarkers`.
mTimelineMarkers.Clear();
mOffTheMainThreadTimelineMarkers.Clear();
}
void
ObservedDocShell::PopMarkers(JSContext* aCx,
nsTArray<dom::ProfileTimelineMarker>& aStore)
{
MOZ_ASSERT(NS_IsMainThread());
MutexAutoLock lock(GetLock()); // for `mOffTheMainThreadTimelineMarkers`.
MOZ_RELEASE_ASSERT(!mPopping);
AutoRestore<bool> resetPopping(mPopping);
mPopping = true;
// First, move all of our markers into a single array. We'll chose
// the `mTimelineMarkers` store because that's where we expect most of
// our markers to be.
mTimelineMarkers.AppendElements(Move(mOffTheMainThreadTimelineMarkers));
// If we see an unpaired START, we keep it around for the next call
// to ObservedDocShell::PopMarkers. We store the kept START objects here.
nsTArray<UniquePtr<AbstractTimelineMarker>> keptStartMarkers;
for (uint32_t i = 0; i < mTimelineMarkers.Length(); ++i) {
UniquePtr<AbstractTimelineMarker>& startPayload = mTimelineMarkers.ElementAt(i);
// If this is a TIMESTAMP marker, there's no corresponding END,
// as it's a single unit of time, not a duration.
if (startPayload->GetTracingType() == MarkerTracingType::TIMESTAMP) {
dom::ProfileTimelineMarker* marker = aStore.AppendElement();
marker->mName = NS_ConvertUTF8toUTF16(startPayload->GetName());
marker->mStart = startPayload->GetTime();
marker->mEnd = startPayload->GetTime();
marker->mStack = startPayload->GetStack();
startPayload->AddDetails(aCx, *marker);
continue;
}
// Whenever a START marker is found, look for the corresponding END
// and build a {name,start,end} JS object.
if (startPayload->GetTracingType() == MarkerTracingType::START) {
bool hasSeenEnd = false;
// "Paint" markers are different because painting is handled at root
// docshell level. The information that a paint was done is stored at
// sub-docshell level, but we can only be sure that a paint did actually
// happen in if a "Layer" marker was recorded too.
bool startIsPaintType = strcmp(startPayload->GetName(), "Paint") == 0;
bool hasSeenLayerType = false;
// If we are processing a "Paint" marker, we append information from
// all the embedded "Layer" markers to this array.
dom::Sequence<dom::ProfileTimelineLayerRect> layerRectangles;
// DOM events can be nested, so we must take care when searching
// for the matching end. It doesn't hurt to apply this logic to
// all event types.
uint32_t markerDepth = 0;
// The assumption is that the devtools timeline flushes markers frequently
// enough for the amount of markers to always be small enough that the
// nested for loop isn't going to be a performance problem.
for (uint32_t j = i + 1; j < mTimelineMarkers.Length(); ++j) {
UniquePtr<AbstractTimelineMarker>& endPayload = mTimelineMarkers.ElementAt(j);
bool endIsLayerType = strcmp(endPayload->GetName(), "Layer") == 0;
// Look for "Layer" markers to stream out "Paint" markers.
if (startIsPaintType && endIsLayerType) {
AbstractTimelineMarker* raw = endPayload.get();
LayerTimelineMarker* layerPayload = static_cast<LayerTimelineMarker*>(raw);
layerPayload->AddLayerRectangles(layerRectangles);
hasSeenLayerType = true;
}
if (!startPayload->Equals(*endPayload)) {
continue;
}
if (endPayload->GetTracingType() == MarkerTracingType::START) {
++markerDepth;
continue;
}
if (endPayload->GetTracingType() == MarkerTracingType::END) {
if (markerDepth > 0) {
--markerDepth;
continue;
}
if (!startIsPaintType || (startIsPaintType && hasSeenLayerType)) {
dom::ProfileTimelineMarker* marker = aStore.AppendElement();
marker->mName = NS_ConvertUTF8toUTF16(startPayload->GetName());
marker->mStart = startPayload->GetTime();
marker->mEnd = endPayload->GetTime();
marker->mStack = startPayload->GetStack();
if (hasSeenLayerType) {
marker->mRectangles.Construct(layerRectangles);
}
startPayload->AddDetails(aCx, *marker);
endPayload->AddDetails(aCx, *marker);
}
hasSeenEnd = true;
break;
}
}
// If we did not see the corresponding END, keep the START.
if (!hasSeenEnd) {
keptStartMarkers.AppendElement(Move(mTimelineMarkers.ElementAt(i)));
mTimelineMarkers.RemoveElementAt(i);
--i;
}
}
}
mTimelineMarkers.SwapElements(keptStartMarkers);
}
} // namespace mozilla

View file

@ -0,0 +1,52 @@
/* -*- 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_ObservedDocShell_h_
#define mozilla_ObservedDocShell_h_
#include "MarkersStorage.h"
#include "mozilla/RefPtr.h"
#include "mozilla/UniquePtr.h"
#include "nsTArray.h"
class nsIDocShell;
namespace mozilla {
class AbstractTimelineMarker;
namespace dom {
struct ProfileTimelineMarker;
}
// # ObservedDocShell
//
// A wrapper around a docshell for which docshell-specific markers are
// allowed to exist. See TimelineConsumers for register/unregister logic.
class ObservedDocShell : public MarkersStorage
{
private:
RefPtr<nsIDocShell> mDocShell;
// Main thread only.
nsTArray<UniquePtr<AbstractTimelineMarker>> mTimelineMarkers;
bool mPopping;
// Off the main thread only.
nsTArray<UniquePtr<AbstractTimelineMarker>> mOffTheMainThreadTimelineMarkers;
public:
explicit ObservedDocShell(nsIDocShell* aDocShell);
nsIDocShell* operator*() const { return mDocShell.get(); }
void AddMarker(UniquePtr<AbstractTimelineMarker>&& aMarker) override;
void AddOTMTMarker(UniquePtr<AbstractTimelineMarker>&& aMarker) override;
void ClearMarkers() override;
void PopMarkers(JSContext* aCx, nsTArray<dom::ProfileTimelineMarker>& aStore) override;
};
} // namespace mozilla
#endif /* mozilla_ObservedDocShell_h_ */

View file

@ -0,0 +1,42 @@
/* -*- 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_RestyleTimelineMarker_h_
#define mozilla_RestyleTimelineMarker_h_
#include "TimelineMarker.h"
#include "mozilla/dom/ProfileTimelineMarkerBinding.h"
namespace mozilla {
class RestyleTimelineMarker : public TimelineMarker
{
public:
RestyleTimelineMarker(nsRestyleHint aRestyleHint,
MarkerTracingType aTracingType)
: TimelineMarker("Styles", aTracingType)
{
if (aRestyleHint) {
mRestyleHint.AssignWithConversion(RestyleManager::RestyleHintToString(aRestyleHint));
}
}
virtual void AddDetails(JSContext* aCx, dom::ProfileTimelineMarker& aMarker) override
{
TimelineMarker::AddDetails(aCx, aMarker);
if (GetTracingType() == MarkerTracingType::START) {
aMarker.mRestyleHint.Construct(mRestyleHint);
}
}
private:
nsString mRestyleHint;
};
} // namespace mozilla
#endif // mozilla_RestyleTimelineMarker_h_

View file

@ -0,0 +1,312 @@
/* -*- 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 "TimelineConsumers.h"
#include "mozilla/ClearOnShutdown.h"
#include "nsAppRunner.h" // for XRE_IsContentProcess, XRE_IsParentProcess
#include "nsDocShell.h"
namespace mozilla {
NS_IMPL_ISUPPORTS(TimelineConsumers, nsIObserver);
StaticMutex TimelineConsumers::sMutex;
// Manually manage this singleton's lifetime and destroy it before shutdown.
// This avoids the leakchecker detecting false-positive memory leaks when
// using automatic memory management (i.e. statically instantiating this
// singleton inside the `Get` method), which would automatically destroy it on
// application shutdown, but too late for the leakchecker. Sigh...
StaticRefPtr<TimelineConsumers> TimelineConsumers::sInstance;
// This flag makes sure the singleton never gets instantiated while a shutdown
// is in progress. This can actually happen, and `ClearOnShutdown` doesn't work
// in these cases.
bool TimelineConsumers::sInShutdown = false;
already_AddRefed<TimelineConsumers>
TimelineConsumers::Get()
{
// Using this class is not supported yet for other processes other than
// parent or content. To avoid accidental checks to methods like `IsEmpty`,
// which would probably always be true in those cases, assert here.
// Remember, there will be different singletons available to each process.
MOZ_ASSERT(XRE_IsContentProcess() || XRE_IsParentProcess());
// If we are shutting down, don't bother doing anything. Note: we can only
// know whether or not we're in shutdown if we're instantiated.
if (sInShutdown) {
return nullptr;
}
// Note: We don't simply check `sInstance` for null-ness here, since otherwise
// this can resurrect the TimelineConsumers pretty late during shutdown.
// We won't know if we're in shutdown or not though, because the singleton
// could have been destroyed or just never instantiated, so in the previous
// conditional `sInShutdown` would be false.
static bool firstTime = true;
if (firstTime) {
firstTime = false;
StaticMutexAutoLock lock(sMutex);
sInstance = new TimelineConsumers();
// Make sure the initialization actually suceeds, otherwise don't allow
// access by destroying the instance immediately.
if (sInstance->Init()) {
ClearOnShutdown(&sInstance);
} else {
sInstance->RemoveObservers();
sInstance = nullptr;
}
}
RefPtr<TimelineConsumers> copy = sInstance.get();
return copy.forget();
}
bool
TimelineConsumers::Init()
{
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
if (!obs) {
return false;
}
if (NS_WARN_IF(NS_FAILED(
obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false)))) {
return false;
}
return true;
}
bool
TimelineConsumers::RemoveObservers()
{
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
if (!obs) {
return false;
}
if (NS_WARN_IF(NS_FAILED(
obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID)))) {
return false;
}
return true;
}
nsresult
TimelineConsumers::Observe(nsISupports* aSubject,
const char* aTopic,
const char16_t* aData)
{
if (!nsCRT::strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
sInShutdown = true;
RemoveObservers();
return NS_OK;
}
MOZ_ASSERT(false, "TimelineConsumers got unexpected topic!");
return NS_ERROR_UNEXPECTED;
}
TimelineConsumers::TimelineConsumers()
: mActiveConsumers(0)
{
}
void
TimelineConsumers::AddConsumer(nsDocShell* aDocShell)
{
MOZ_ASSERT(NS_IsMainThread());
StaticMutexAutoLock lock(sMutex); // for `mActiveConsumers` and `mMarkersStores`.
UniquePtr<ObservedDocShell>& observed = aDocShell->mObserved;
MOZ_ASSERT(!observed);
mActiveConsumers++;
ObservedDocShell* obsDocShell = new ObservedDocShell(aDocShell);
MarkersStorage* storage = static_cast<MarkersStorage*>(obsDocShell);
observed.reset(obsDocShell);
mMarkersStores.insertFront(storage);
}
void
TimelineConsumers::RemoveConsumer(nsDocShell* aDocShell)
{
MOZ_ASSERT(NS_IsMainThread());
StaticMutexAutoLock lock(sMutex); // for `mActiveConsumers` and `mMarkersStores`.
UniquePtr<ObservedDocShell>& observed = aDocShell->mObserved;
MOZ_ASSERT(observed);
mActiveConsumers--;
// Clear all markers from the `mTimelineMarkers` store.
observed.get()->ClearMarkers();
// Remove self from the `mMarkersStores` store.
observed.get()->remove();
// Prepare for becoming a consumer later.
observed.reset(nullptr);
}
bool
TimelineConsumers::HasConsumer(nsIDocShell* aDocShell)
{
MOZ_ASSERT(NS_IsMainThread());
return aDocShell
? aDocShell->GetRecordProfileTimelineMarkers()
: false;
}
bool
TimelineConsumers::IsEmpty()
{
StaticMutexAutoLock lock(sMutex); // for `mActiveConsumers`.
return mActiveConsumers == 0;
}
void
TimelineConsumers::AddMarkerForDocShell(nsDocShell* aDocShell,
const char* aName,
MarkerTracingType aTracingType,
MarkerStackRequest aStackRequest)
{
MOZ_ASSERT(NS_IsMainThread());
if (HasConsumer(aDocShell)) {
aDocShell->mObserved->AddMarker(Move(MakeUnique<TimelineMarker>(aName, aTracingType, aStackRequest)));
}
}
void
TimelineConsumers::AddMarkerForDocShell(nsDocShell* aDocShell,
const char* aName,
const TimeStamp& aTime,
MarkerTracingType aTracingType,
MarkerStackRequest aStackRequest)
{
MOZ_ASSERT(NS_IsMainThread());
if (HasConsumer(aDocShell)) {
aDocShell->mObserved->AddMarker(Move(MakeUnique<TimelineMarker>(aName, aTime, aTracingType, aStackRequest)));
}
}
void
TimelineConsumers::AddMarkerForDocShell(nsDocShell* aDocShell,
UniquePtr<AbstractTimelineMarker>&& aMarker)
{
MOZ_ASSERT(NS_IsMainThread());
if (HasConsumer(aDocShell)) {
aDocShell->mObserved->AddMarker(Move(aMarker));
}
}
void
TimelineConsumers::AddMarkerForDocShell(nsIDocShell* aDocShell,
const char* aName,
MarkerTracingType aTracingType,
MarkerStackRequest aStackRequest)
{
MOZ_ASSERT(NS_IsMainThread());
AddMarkerForDocShell(static_cast<nsDocShell*>(aDocShell), aName, aTracingType, aStackRequest);
}
void
TimelineConsumers::AddMarkerForDocShell(nsIDocShell* aDocShell,
const char* aName,
const TimeStamp& aTime,
MarkerTracingType aTracingType,
MarkerStackRequest aStackRequest)
{
MOZ_ASSERT(NS_IsMainThread());
AddMarkerForDocShell(static_cast<nsDocShell*>(aDocShell), aName, aTime, aTracingType, aStackRequest);
}
void
TimelineConsumers::AddMarkerForDocShell(nsIDocShell* aDocShell,
UniquePtr<AbstractTimelineMarker>&& aMarker)
{
MOZ_ASSERT(NS_IsMainThread());
AddMarkerForDocShell(static_cast<nsDocShell*>(aDocShell), Move(aMarker));
}
void
TimelineConsumers::AddMarkerForAllObservedDocShells(const char* aName,
MarkerTracingType aTracingType,
MarkerStackRequest aStackRequest /* = STACK */)
{
bool isMainThread = NS_IsMainThread();
StaticMutexAutoLock lock(sMutex); // for `mMarkersStores`.
for (MarkersStorage* storage = mMarkersStores.getFirst();
storage != nullptr;
storage = storage->getNext()) {
UniquePtr<AbstractTimelineMarker> marker =
MakeUnique<TimelineMarker>(aName, aTracingType, aStackRequest);
if (isMainThread) {
storage->AddMarker(Move(marker));
} else {
storage->AddOTMTMarker(Move(marker));
}
}
}
void
TimelineConsumers::AddMarkerForAllObservedDocShells(const char* aName,
const TimeStamp& aTime,
MarkerTracingType aTracingType,
MarkerStackRequest aStackRequest /* = STACK */)
{
bool isMainThread = NS_IsMainThread();
StaticMutexAutoLock lock(sMutex); // for `mMarkersStores`.
for (MarkersStorage* storage = mMarkersStores.getFirst();
storage != nullptr;
storage = storage->getNext()) {
UniquePtr<AbstractTimelineMarker> marker =
MakeUnique<TimelineMarker>(aName, aTime, aTracingType, aStackRequest);
if (isMainThread) {
storage->AddMarker(Move(marker));
} else {
storage->AddOTMTMarker(Move(marker));
}
}
}
void
TimelineConsumers::AddMarkerForAllObservedDocShells(UniquePtr<AbstractTimelineMarker>& aMarker)
{
bool isMainThread = NS_IsMainThread();
StaticMutexAutoLock lock(sMutex); // for `mMarkersStores`.
for (MarkersStorage* storage = mMarkersStores.getFirst();
storage != nullptr;
storage = storage->getNext()) {
UniquePtr<AbstractTimelineMarker> clone = aMarker->Clone();
if (isMainThread) {
storage->AddMarker(Move(clone));
} else {
storage->AddOTMTMarker(Move(clone));
}
}
}
void
TimelineConsumers::PopMarkers(nsDocShell* aDocShell,
JSContext* aCx,
nsTArray<dom::ProfileTimelineMarker>& aStore)
{
MOZ_ASSERT(NS_IsMainThread());
if (!aDocShell || !aDocShell->mObserved) {
return;
}
aDocShell->mObserved->PopMarkers(aCx, aStore);
}
} // namespace mozilla

View file

@ -0,0 +1,135 @@
/* 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_TimelineConsumers_h_
#define mozilla_TimelineConsumers_h_
#include "nsIObserver.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/LinkedList.h"
#include "mozilla/StaticMutex.h"
#include "TimelineMarkerEnums.h" // for MarkerTracingType
class nsDocShell;
class nsIDocShell;
struct JSContext;
namespace mozilla {
class TimeStamp;
class MarkersStorage;
class AbstractTimelineMarker;
namespace dom {
struct ProfileTimelineMarker;
}
class TimelineConsumers : public nsIObserver
{
public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIOBSERVER
private:
TimelineConsumers();
TimelineConsumers(const TimelineConsumers& aOther) = delete;
void operator=(const TimelineConsumers& aOther) = delete;
virtual ~TimelineConsumers() = default;
bool Init();
bool RemoveObservers();
public:
static already_AddRefed<TimelineConsumers> Get();
// Methods for registering interested consumers (i.e. "devtools toolboxes").
// Each consumer should be directly focused on a particular docshell, but
// timeline markers don't necessarily have to be tied to that docshell.
// See the public `AddMarker*` methods below.
// Main thread only.
void AddConsumer(nsDocShell* aDocShell);
void RemoveConsumer(nsDocShell* aDocShell);
bool HasConsumer(nsIDocShell* aDocShell);
// Checks if there's any existing interested consumer.
// May be called from any thread.
bool IsEmpty();
// Methods for adding markers relevant for particular docshells, or generic
// (meaning that they either can't be tied to a particular docshell, or one
// wasn't accessible in the part of the codebase where they're instantiated).
// These will only add markers if at least one docshell is currently being
// observed by a timeline. Markers tied to a particular docshell won't be
// created unless that docshell is specifically being currently observed.
// See nsIDocShell::recordProfileTimelineMarkers
// These methods create a basic TimelineMarker from a name and some metadata,
// relevant for a specific docshell.
// Main thread only.
void AddMarkerForDocShell(nsDocShell* aDocShell,
const char* aName,
MarkerTracingType aTracingType,
MarkerStackRequest aStackRequest = MarkerStackRequest::STACK);
void AddMarkerForDocShell(nsIDocShell* aDocShell,
const char* aName,
MarkerTracingType aTracingType,
MarkerStackRequest aStackRequest = MarkerStackRequest::STACK);
void AddMarkerForDocShell(nsDocShell* aDocShell,
const char* aName,
const TimeStamp& aTime,
MarkerTracingType aTracingType,
MarkerStackRequest aStackRequest = MarkerStackRequest::STACK);
void AddMarkerForDocShell(nsIDocShell* aDocShell,
const char* aName,
const TimeStamp& aTime,
MarkerTracingType aTracingType,
MarkerStackRequest aStackRequest = MarkerStackRequest::STACK);
// These methods register and receive ownership of an already created marker,
// relevant for a specific docshell.
// Main thread only.
void AddMarkerForDocShell(nsDocShell* aDocShell,
UniquePtr<AbstractTimelineMarker>&& aMarker);
void AddMarkerForDocShell(nsIDocShell* aDocShell,
UniquePtr<AbstractTimelineMarker>&& aMarker);
// These methods create a basic marker from a name and some metadata,
// which doesn't have to be relevant to a specific docshell.
// May be called from any thread.
void AddMarkerForAllObservedDocShells(const char* aName,
MarkerTracingType aTracingType,
MarkerStackRequest aStackRequest = MarkerStackRequest::STACK);
void AddMarkerForAllObservedDocShells(const char* aName,
const TimeStamp& aTime,
MarkerTracingType aTracingType,
MarkerStackRequest aStackRequest = MarkerStackRequest::STACK);
// This method clones and registers an already instantiated marker,
// which doesn't have to be relevant to a specific docshell.
// May be called from any thread.
void AddMarkerForAllObservedDocShells(UniquePtr<AbstractTimelineMarker>& aMarker);
void PopMarkers(nsDocShell* aDocShell,
JSContext* aCx,
nsTArray<dom::ProfileTimelineMarker>& aStore);
private:
static StaticRefPtr<TimelineConsumers> sInstance;
static bool sInShutdown;
// Counter for how many timelines are currently interested in markers,
// and a list of the MarkersStorage interfaces representing them.
unsigned long mActiveConsumers;
LinkedList<MarkersStorage> mMarkersStores;
// Protects this class's data structures.
static StaticMutex sMutex;
};
} // namespace mozilla
#endif /* mozilla_TimelineConsumers_h_ */

View file

@ -0,0 +1,71 @@
/* -*- 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 "TimelineMarker.h"
namespace mozilla {
TimelineMarker::TimelineMarker(const char* aName,
MarkerTracingType aTracingType,
MarkerStackRequest aStackRequest)
: AbstractTimelineMarker(aName, aTracingType)
{
CaptureStackIfNecessary(aTracingType, aStackRequest);
}
TimelineMarker::TimelineMarker(const char* aName,
const TimeStamp& aTime,
MarkerTracingType aTracingType,
MarkerStackRequest aStackRequest)
: AbstractTimelineMarker(aName, aTime, aTracingType)
{
CaptureStackIfNecessary(aTracingType, aStackRequest);
}
void
TimelineMarker::AddDetails(JSContext* aCx, dom::ProfileTimelineMarker& aMarker)
{
if (GetTracingType() == MarkerTracingType::START) {
aMarker.mProcessType.Construct(GetProcessType());
aMarker.mIsOffMainThread.Construct(IsOffMainThread());
}
}
JSObject*
TimelineMarker::GetStack()
{
if (mStackTrace.initialized()) {
return mStackTrace;
}
return nullptr;
}
void
TimelineMarker::CaptureStack()
{
JSContext* ctx = nsContentUtils::GetCurrentJSContext();
if (ctx) {
JS::RootedObject stack(ctx);
if (JS::CaptureCurrentStack(ctx, &stack)) {
mStackTrace.init(ctx, stack.get());
} else {
JS_ClearPendingException(ctx);
}
}
}
void
TimelineMarker::CaptureStackIfNecessary(MarkerTracingType aTracingType,
MarkerStackRequest aStackRequest)
{
if ((aTracingType == MarkerTracingType::START ||
aTracingType == MarkerTracingType::TIMESTAMP) &&
aStackRequest != MarkerStackRequest::NO_STACK) {
CaptureStack();
}
}
} // namespace mozilla

View file

@ -0,0 +1,49 @@
/* -*- 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_TimelineMarker_h_
#define mozilla_TimelineMarker_h_
#include "AbstractTimelineMarker.h"
#include "js/RootingAPI.h"
namespace mozilla {
// Objects of this type can be added to the timeline if there is an interested
// consumer. The class can also be subclassed to let a given marker creator
// provide custom details.
class TimelineMarker : public AbstractTimelineMarker
{
public:
TimelineMarker(const char* aName,
MarkerTracingType aTracingType,
MarkerStackRequest aStackRequest = MarkerStackRequest::STACK);
TimelineMarker(const char* aName,
const TimeStamp& aTime,
MarkerTracingType aTracingType,
MarkerStackRequest aStackRequest = MarkerStackRequest::STACK);
virtual void AddDetails(JSContext* aCx, dom::ProfileTimelineMarker& aMarker) override;
virtual JSObject* GetStack() override;
protected:
void CaptureStack();
private:
// While normally it is not a good idea to make a persistent root,
// in this case changing nsDocShell to participate in cycle
// collection was deemed too invasive, and the markers are only held
// here temporarily to boot.
JS::PersistentRooted<JSObject*> mStackTrace;
void CaptureStackIfNecessary(MarkerTracingType aTracingType,
MarkerStackRequest aStackRequest);
};
} // namespace mozilla
#endif /* mozilla_TimelineMarker_h_ */

View file

@ -0,0 +1,26 @@
/* -*- 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_TimelineMarkerEnums_h_
#define mozilla_TimelineMarkerEnums_h_
namespace mozilla {
enum class MarkerTracingType {
START,
END,
TIMESTAMP,
HELPER_EVENT
};
enum class MarkerStackRequest {
STACK,
NO_STACK
};
} // namespace mozilla
#endif // mozilla_TimelineMarkerEnums_h_

View file

@ -0,0 +1,38 @@
/* -*- 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_TimestampTimelineMarker_h_
#define mozilla_TimestampTimelineMarker_h_
#include "TimelineMarker.h"
#include "mozilla/dom/ProfileTimelineMarkerBinding.h"
namespace mozilla {
class TimestampTimelineMarker : public TimelineMarker
{
public:
explicit TimestampTimelineMarker(const nsAString& aCause)
: TimelineMarker("TimeStamp", MarkerTracingType::TIMESTAMP)
, mCause(aCause)
{}
virtual void AddDetails(JSContext* aCx, dom::ProfileTimelineMarker& aMarker) override
{
TimelineMarker::AddDetails(aCx, aMarker);
if (!mCause.IsEmpty()) {
aMarker.mCauseName.Construct(mCause);
}
}
private:
nsString mCause;
};
} // namespace mozilla
#endif // mozilla_TimestampTimelineMarker_h_

View file

@ -0,0 +1,46 @@
/* -*- 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_WorkerTimelineMarker_h_
#define mozilla_WorkerTimelineMarker_h_
#include "TimelineMarker.h"
#include "mozilla/dom/ProfileTimelineMarkerBinding.h"
namespace mozilla {
class WorkerTimelineMarker : public TimelineMarker
{
public:
WorkerTimelineMarker(dom::ProfileTimelineWorkerOperationType aOperationType,
MarkerTracingType aTracingType)
: TimelineMarker("Worker", aTracingType, MarkerStackRequest::NO_STACK)
, mOperationType(aOperationType)
{}
virtual UniquePtr<AbstractTimelineMarker> Clone() override
{
WorkerTimelineMarker* clone = new WorkerTimelineMarker(mOperationType, GetTracingType());
clone->SetCustomTime(GetTime());
return UniquePtr<AbstractTimelineMarker>(clone);
}
virtual void AddDetails(JSContext* aCx, dom::ProfileTimelineMarker& aMarker) override
{
TimelineMarker::AddDetails(aCx, aMarker);
if (GetTracingType() == MarkerTracingType::START) {
aMarker.mWorkerOperation.Construct(mOperationType);
}
}
private:
dom::ProfileTimelineWorkerOperationType mOperationType;
};
} // namespace mozilla
#endif /* mozilla_WorkerTimelineMarker_h_ */

Some files were not shown because too many files have changed in this diff Show more