68.14.3 - dom

This commit is contained in:
Fedor 2024-07-21 11:41:06 +03:00
parent 6a4f7fd1d0
commit f2f1bfa92d
783 changed files with 6581 additions and 35759 deletions

View File

@ -1039,6 +1039,37 @@ promise_test(async t => {
}
}, 'background-color animation runs on the compositor');
promise_test(async t => {
const div = addDiv(t);
const animation = div.animate({ backgroundColor: ['blue', 'green'] },
100 * MS_PER_SEC);
await waitForAnimationReadyToRestyle(animation);
await waitForPaints();
if (!isWebRender) {
assert_animation_is_running_on_compositor(animation,
'background-color animation should be running on the compositor');
} else {
assert_animation_is_not_running_on_compositor(animation,
'background-color animation is not yet able to run on the compositor ' +
'on WebRender');
}
// Add a red opaque background image covering the background color animation.
div.style.backgroundImage =
'url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAIAAAAC64' +
'paAAAAG0lEQVR42mP8z0A%2BYKJA76jmUc2jmkc1U0EzACKcASfOgGoMAAAAAElFTkSuQmCC)';
await waitForAnimationReadyToRestyle(animation);
await waitForPaints();
assert_animation_is_not_running_on_compositor(animation,
'Opaque background image stops background-color animations from running ' +
'on the compositor');
}, 'Opaque background image stops background-color animations from running ' +
' on the compositor');
promise_test(async t => {
await SpecialPowers.pushPrefEnv({
set: [["gfx.omta.background-color", false]]

View File

@ -9,11 +9,6 @@
"use strict";
const gMozillaSpecificProperties = {
"-moz-appearance": {
// https://drafts.csswg.org/css-align/#propdef-align-content
from: "button",
to: "none"
},
"-moz-box-align": {
// https://developer.mozilla.org/en/docs/Web/CSS/box-align
from: "center",

View File

@ -13,9 +13,6 @@
"use strict";
const testcases = [
{
property: "-moz-appearance",
},
{
property: "-moz-box-align"
},

View File

@ -176,13 +176,12 @@ class AttrArray {
return sizeof(Impl) + aAttrCount * sizeof(InternalAttr);
}
mozilla::Span<const InternalAttr> NonMappedAttrs() const {
return mozilla::MakeSpan(static_cast<const InternalAttr*>(mBuffer),
mAttrCount);
auto NonMappedAttrs() const {
return mozilla::Span<const InternalAttr>{mBuffer, mAttrCount};
}
mozilla::Span<InternalAttr> NonMappedAttrs() {
return mozilla::MakeSpan(static_cast<InternalAttr*>(mBuffer), mAttrCount);
auto NonMappedAttrs() {
return mozilla::Span<InternalAttr>{mBuffer, mAttrCount};
}
Impl(const Impl&) = delete;

View File

@ -468,8 +468,8 @@ already_AddRefed<FormData> BodyUtil::ConsumeFormData(nsIGlobalObject* aParent,
// static
nsresult BodyUtil::ConsumeText(uint32_t aInputLength, uint8_t* aInput,
nsString& aText) {
nsresult rv = UTF_8_ENCODING->DecodeWithBOMRemoval(
MakeSpan(aInput, aInputLength), aText);
nsresult rv =
UTF_8_ENCODING->DecodeWithBOMRemoval(Span(aInput, aInputLength), aText);
if (NS_FAILED(rv)) {
return rv;
}

View File

@ -281,7 +281,7 @@ nsresult CharacterData::SetTextInternal(
if (aLength) {
to.Append(aBuffer, aLength);
if (!bidi && (!document || !document->GetBidiEnabled())) {
bidi = HasRTLChars(MakeSpan(aBuffer, aLength));
bidi = HasRTLChars(Span(aBuffer, aLength));
}
}
if (endOffset != textLength) {

View File

@ -68,7 +68,7 @@ class ContentProcessMessageManager : public nsIMessageSender,
JS::MutableHandle<JS::Value> aInitialProcessData,
ErrorResult& aError) {
if (!mMessageManager) {
aError.Throw(NS_ERROR_NULL_POINTER);
aError.Throw(NS_ERROR_NOT_INITIALIZED);
return;
}
mMessageManager->GetInitialProcessData(aCx, aInitialProcessData, aError);

View File

@ -117,7 +117,7 @@ already_AddRefed<Document> DOMParser::ParseFromBuffer(const Uint8Array& aBuf,
SupportedType aType,
ErrorResult& aRv) {
aBuf.ComputeState();
return ParseFromBuffer(MakeSpan(aBuf.Data(), aBuf.Length()), aType, aRv);
return ParseFromBuffer(Span(aBuf.Data(), aBuf.Length()), aType, aRv);
}
already_AddRefed<Document> DOMParser::ParseFromBuffer(Span<const uint8_t> aBuf,
@ -127,7 +127,7 @@ already_AddRefed<Document> DOMParser::ParseFromBuffer(Span<const uint8_t> aBuf,
nsCOMPtr<nsIInputStream> stream;
nsresult rv = NS_NewByteInputStream(
getter_AddRefs(stream),
MakeSpan(reinterpret_cast<const char*>(aBuf.Elements()), aBuf.Length()),
Span(reinterpret_cast<const char*>(aBuf.Elements()), aBuf.Length()),
NS_ASSIGNMENT_DEPEND);
if (NS_FAILED(rv)) {
aRv.Throw(rv);

View File

@ -6219,22 +6219,6 @@ void Document::SetScopeObject(nsIGlobalObject* aGlobal) {
}
}
bool Document::ContainsEMEContent() {
bool containsEME = false;
auto check = [&containsEME](nsISupports* aSupports) {
nsCOMPtr<nsIContent> content(do_QueryInterface(aSupports));
if (auto* mediaElem = HTMLMediaElement::FromNodeOrNull(content)) {
if (mediaElem->GetMediaKeys()) {
containsEME = true;
}
}
};
EnumerateActivityObservers(check);
return containsEME;
}
bool Document::ContainsMSEContent() {
bool containsMSE = false;
@ -9998,13 +9982,6 @@ bool Document::CanSavePresentation(nsIRequest* aNewRequest,
}
#endif // MOZ_WEBRTC
// Don't save presentations for documents containing EME content, so that
// CDMs reliably shutdown upon user navigation.
if (ContainsEMEContent()) {
aBFCacheCombo |= BFCacheStatus::CONTAINS_EME_CONTENT;
ret = false;
}
// Don't save presentations for documents containing MSE content, to
// reduce memory usage.
if (ContainsMSEContent()) {
@ -12940,16 +12917,13 @@ void Document::UnsetFullscreenElement() {
UpdateViewportScrollbarOverrideForFullscreen(this);
}
bool Document::SetFullscreenElement(Element* aElement) {
if (TopLayerPush(aElement)) {
EventStateManager::SetFullscreenState(aElement, true);
UpdateViewportScrollbarOverrideForFullscreen(this);
return true;
}
return false;
void Document::SetFullscreenElement(Element* aElement) {
TopLayerPush(aElement);
EventStateManager::SetFullscreenState(aElement, true);
UpdateViewportScrollbarOverrideForFullscreen(this);
}
bool Document::TopLayerPush(Element* aElement) {
void Document::TopLayerPush(Element* aElement) {
NS_ASSERTION(aElement, "Must pass non-null to TopLayerPush()");
auto predictFunc = [&aElement](Element* element) {
return element == aElement;
@ -12958,7 +12932,60 @@ bool Document::TopLayerPush(Element* aElement) {
mTopLayer.AppendElement(do_GetWeakReference(aElement));
NS_ASSERTION(GetTopLayerTop() == aElement, "Should match");
return true;
}
void Document::SetBlockedByModalDialog(HTMLDialogElement& aDialogElement) {
Element* root = GetRootElement();
MOZ_RELEASE_ASSERT(root, "dialog in document without root?");
// Add inert to the root element so that the inertness is
// applied to the entire document. Since the modal dialog
// also inherits the inertness, adding
// NS_EVENT_STATE_TOPMOST_MODAL_DIALOG to remove the inertness
// explicitly.
root->AddStates(NS_EVENT_STATE_MOZINERT);
aDialogElement.AddStates(NS_EVENT_STATE_TOPMOST_MODAL_DIALOG);
// It's possible that there's another modal dialog has opened
// previously which doesn't have the inertness (because we've
// removed the inertness explicitly). Since a
// new modal dialog is opened, we need to grant the inertness
// to the previous one.
for (const nsWeakPtr& weakPtr : Reversed(mTopLayer)) {
nsCOMPtr<Element> element(do_QueryReferent(weakPtr));
if (auto* dialog = HTMLDialogElement::FromNodeOrNull(element)) {
if (dialog != &aDialogElement) {
dialog->RemoveStates(NS_EVENT_STATE_TOPMOST_MODAL_DIALOG);
// It's ok to exit the loop as only one modal dialog should
// have the state
break;
}
}
}
}
void Document::UnsetBlockedByModalDialog(HTMLDialogElement& aDialogElement) {
aDialogElement.RemoveStates(NS_EVENT_STATE_TOPMOST_MODAL_DIALOG);
// The document could still be blocked by another modal dialog.
// We need to remove the inertness from this modal dialog.
for (const nsWeakPtr& weakPtr : Reversed(mTopLayer)) {
nsCOMPtr<Element> element(do_QueryReferent(weakPtr));
if (auto* dialog = HTMLDialogElement::FromNodeOrNull(element)) {
if (dialog != &aDialogElement) {
dialog->AddStates(NS_EVENT_STATE_TOPMOST_MODAL_DIALOG);
// Return here because we want to keep the inertness for the
// root element as the document is still blocked by a modal
// dialog
return;
}
}
}
Element* root = GetRootElement();
if (root && !root->GetBoolAttr(nsGkAtoms::inert)) {
root->RemoveStates(NS_EVENT_STATE_MOZINERT);
}
}
Element* Document::TopLayerPop(FunctionRef<bool(Element*)> aPredicateFunc) {
@ -13013,7 +13040,7 @@ Element* Document::GetTopLayerTop() {
Element* Document::GetUnretargetedFullScreenElement() {
for (const nsWeakPtr& weakPtr : Reversed(mTopLayer)) {
nsCOMPtr<Element> element(do_QueryReferent(weakPtr));
// Per spec, the fullscreen element is the topmost element in the documents
// Per spec, the fullscreen element is the topmost element in the document???s
// top layer whose fullscreen flag is set, if any, and null otherwise.
if (element && element->State().HasState(NS_EVENT_STATE_FULLSCREEN)) {
return element;
@ -13148,6 +13175,10 @@ bool Document::FullscreenElementReadyCheck(FullscreenRequest& aRequest) {
aRequest.Reject("FullscreenDeniedSubDocFullScreen");
return false;
}
if (elem->IsHTMLElement(nsGkAtoms::dialog)) {
aRequest.Reject("FullscreenDeniedHTMLDialog");
return false;
}
// XXXsmaug Note, we don't follow the latest fullscreen spec here.
// This whole check could be probably removed.
if (fullscreenElement && !nsContentUtils::ContentIsHostIncludingDescendantOf(
@ -13312,8 +13343,7 @@ bool Document::ApplyFullscreen(UniquePtr<FullscreenRequest> aRequest) {
// element, and the fullscreen-ancestor styles on ancestors of the element
// in this document.
Element* elem = aRequest->Element();
DebugOnly<bool> x = SetFullscreenElement(elem);
MOZ_ASSERT(x, "Fullscreen state of requesting doc should always change!");
SetFullscreenElement(elem);
// Set the iframe fullscreen flag.
if (auto* iframe = HTMLIFrameElement::FromNode(elem)) {
iframe->SetFullscreenFlag(true);
@ -13353,16 +13383,14 @@ bool Document::ApplyFullscreen(UniquePtr<FullscreenRequest> aRequest) {
}
Document* parent = child->GetInProcessParentDocument();
Element* element = parent->FindContentForSubDocument(child);
if (parent->SetFullscreenElement(element)) {
changed.AppendElement(parent);
child = parent;
} else {
// We've reached either the root, or a point in the doctree where the
// new fullscreen element container is the same as the previous
// fullscreen element's container. No more changes need to be made
// to the top layer of documents further up the tree.
if (!element) {
// We've reached the root.No more changes need to be made
// to the top layer stacks of documents further up the tree.
break;
}
parent->SetFullscreenElement(element);
changed.AppendElement(parent);
child = parent;
}
FullscreenRoots::Add(this);
@ -15031,7 +15059,7 @@ already_AddRefed<Promise> Document::RequestStorageAccess(ErrorResult& aRv) {
self->AutomaticStorageAccessCanBeGranted()->Then(
GetCurrentThreadSerialEventTarget(), __func__,
GetCurrentSerialEventTarget(), __func__,
[p, pr, sapr, inner, onAnySite](
const AutomaticStorageAccessGrantPromise::ResolveOrRejectValue&
aValue) -> void {
@ -15064,7 +15092,7 @@ already_AddRefed<Promise> Document::RequestStorageAccess(ErrorResult& aRv) {
p->Resolve(choice, __func__);
} else {
sapr->MaybeDelayAutomaticGrants()->Then(
GetCurrentThreadSerialEventTarget(), __func__,
GetCurrentSerialEventTarget(), __func__,
[p, choice] { p->Resolve(choice, __func__); },
[p] { p->Reject(false, __func__); });
}
@ -15085,7 +15113,7 @@ already_AddRefed<Promise> Document::RequestStorageAccess(ErrorResult& aRv) {
NodePrincipal(), inner, AntiTrackingCommon::eStorageAccessAPI,
performFinalChecks)
->Then(
GetCurrentThreadSerialEventTarget(), __func__,
GetCurrentSerialEventTarget(), __func__,
[outer, promise] {
// Step 10. Grant the document access to cookies and store
// that fact for
@ -15121,7 +15149,7 @@ Document::AutomaticStorageAccessCanBeGranted() {
->SendAutomaticStorageAccessCanBeGranted(
IPC::Principal(NodePrincipal()))
->Then(
GetCurrentThreadSerialEventTarget(), __func__,
GetCurrentSerialEventTarget(), __func__,
[](const ContentChild::AutomaticStorageAccessCanBeGrantedPromise::
ResolveOrRejectValue& aValue) {
if (aValue.IsResolve()) {

View File

@ -189,6 +189,7 @@ class ImageTracker;
class HTMLAllCollection;
class HTMLBodyElement;
class HTMLMetaElement;
class HTMLDialogElement;
class HTMLSharedElement;
class HTMLImageElement;
struct LifecycleCallbackArgs;
@ -2076,7 +2077,7 @@ class Document : public nsINode,
void CleanupFullscreenState();
// Pushes aElement onto the top layer
bool TopLayerPush(Element* aElement);
void TopLayerPush(Element* aElement);
// Removes the topmost element which have aPredicate return true from the top
// layer. The removed element, if any, is returned.
@ -2088,11 +2089,15 @@ class Document : public nsINode,
// Pushes the given element into the top of top layer and set fullscreen
// flag.
bool SetFullscreenElement(Element* aElement);
void SetFullscreenElement(Element* aElement);
// Cancel the dialog element if the document is blocked by the dialog
void TryCancelDialog();
void SetBlockedByModalDialog(HTMLDialogElement&);
void UnsetBlockedByModalDialog(HTMLDialogElement&);
/**
* Called when a frame in a child process has entered fullscreen or when a
* fullscreen frame in a child process changes to another origin.
@ -4105,7 +4110,6 @@ class Document : public nsINode,
// Returns true if the scheme for the url for this document is "about".
bool IsAboutPage() const;
bool ContainsEMEContent();
bool ContainsMSEContent();
/**

View File

@ -170,7 +170,7 @@ void DocumentOrShadowRoot::SetAdoptedStyleSheets(
mAdoptedStyleSheets.SetCapacity(aAdoptedStyleSheets.Length());
// Only add sheets that are not already in the common prefix.
for (const auto& sheet : MakeSpan(aAdoptedStyleSheets).From(commonPrefix)) {
for (const auto& sheet : Span(aAdoptedStyleSheets).From(commonPrefix)) {
if (MOZ_UNLIKELY(!set.EnsureInserted(sheet))) {
// The idea is that this case is rare, so we pay the price of removing the
// old sheet from the styles and append it later rather than the other way

View File

@ -585,9 +585,10 @@ class Element : public FragmentOrElement {
FlushType aFlushType = FlushType::Layout);
private:
// Need to allow the ESM, nsGlobalWindow, and the focus manager to
// set our state
// Need to allow the ESM, nsGlobalWindow, and the focus manager
// and Document to set our state
friend class mozilla::EventStateManager;
friend class mozilla::dom::Document;
friend class ::nsGlobalWindowInner;
friend class ::nsGlobalWindowOuter;
friend class ::nsFocusManager;
@ -606,7 +607,8 @@ class Element : public FragmentOrElement {
EventStates StyleStateFromLocks() const;
protected:
// Methods for the ESM, nsGlobalWindow and focus manager to manage state bits.
// Methods for the ESM, nsGlobalWindow, focus manager and Document to
// manage state bits.
// These will handle setting up script blockers when they notify, so no need
// to do it in the callers unless desired. States passed here must only be
// those in EXTERNALLY_MANAGED_STATES.

View File

@ -689,8 +689,8 @@ void EventSourceImpl::ParseSegment(const char* aBuffer, uint32_t aLength) {
return;
}
char16_t buffer[1024];
auto dst = MakeSpan(buffer);
auto src = AsBytes(MakeSpan(aBuffer, aLength));
auto dst = Span(buffer);
auto src = AsBytes(Span(aBuffer, aLength));
// XXX EOF handling is https://bugzilla.mozilla.org/show_bug.cgi?id=1369018
for (;;) {
uint32_t result;

View File

@ -85,7 +85,7 @@ class EncodingCompleteEvent : public CancelableRunnable {
mEncodeCompleteCallback(aEncodeCompleteCallback),
mFailed(false) {
if (!NS_IsMainThread() && IsCurrentThreadRunningWorker()) {
mCreationEventTarget = GetCurrentThreadEventTarget();
mCreationEventTarget = GetCurrentEventTarget();
} else {
mCreationEventTarget = GetMainThreadEventTarget();
}

View File

@ -24,18 +24,16 @@ using namespace mozilla::dom;
using namespace mozilla::dom::ipc;
bool InProcessBrowserChildMessageManager::DoSendBlockingMessage(
JSContext* aCx, const nsAString& aMessage, StructuredCloneData& aData,
JS::Handle<JSObject*> aCpows, nsIPrincipal* aPrincipal,
nsTArray<StructuredCloneData>* aRetVal, bool aIsSync) {
const nsAString& aMessage, StructuredCloneData& aData,
nsTArray<StructuredCloneData>* aRetVal) {
SameProcessMessageQueue* queue = SameProcessMessageQueue::Get();
queue->Flush();
if (mChromeMessageManager) {
SameProcessCpowHolder cpows(JS::RootingContext::get(aCx), aCpows);
RefPtr<nsFrameMessageManager> mm = mChromeMessageManager;
RefPtr<nsFrameLoader> fl = GetFrameLoader();
mm->ReceiveMessage(mOwner, fl, aMessage, true, &aData, &cpows, aPrincipal,
aRetVal, IgnoreErrors());
mm->ReceiveMessage(mOwner, fl, aMessage, true, &aData, aRetVal,
IgnoreErrors());
}
return true;
}
@ -43,11 +41,9 @@ bool InProcessBrowserChildMessageManager::DoSendBlockingMessage(
class nsAsyncMessageToParent : public nsSameProcessAsyncMessageBase,
public SameProcessMessageQueue::Runnable {
public:
nsAsyncMessageToParent(JS::RootingContext* aRootingCx,
JS::Handle<JSObject*> aCpows,
InProcessBrowserChildMessageManager* aBrowserChild)
: nsSameProcessAsyncMessageBase(aRootingCx, aCpows),
mBrowserChild(aBrowserChild) {}
explicit nsAsyncMessageToParent(
InProcessBrowserChildMessageManager* aBrowserChild)
: nsSameProcessAsyncMessageBase(), mBrowserChild(aBrowserChild) {}
virtual nsresult HandleMessage() override {
RefPtr<nsFrameLoader> fl = mBrowserChild->GetFrameLoader();
@ -59,14 +55,11 @@ class nsAsyncMessageToParent : public nsSameProcessAsyncMessageBase,
};
nsresult InProcessBrowserChildMessageManager::DoSendAsyncMessage(
JSContext* aCx, const nsAString& aMessage, StructuredCloneData& aData,
JS::Handle<JSObject*> aCpows, nsIPrincipal* aPrincipal) {
const nsAString& aMessage, StructuredCloneData& aData) {
SameProcessMessageQueue* queue = SameProcessMessageQueue::Get();
JS::RootingContext* rcx = JS::RootingContext::get(aCx);
RefPtr<nsAsyncMessageToParent> ev =
new nsAsyncMessageToParent(rcx, aCpows, this);
RefPtr<nsAsyncMessageToParent> ev = new nsAsyncMessageToParent(this);
nsresult rv = ev->Init(aMessage, aData, aPrincipal);
nsresult rv = ev->Init(aMessage, aData);
if (NS_FAILED(rv)) {
return rv;
}

View File

@ -78,16 +78,11 @@ class InProcessBrowserChildMessageManager final
/**
* MessageManagerCallback methods that we override.
*/
virtual bool DoSendBlockingMessage(JSContext* aCx, const nsAString& aMessage,
StructuredCloneData& aData,
JS::Handle<JSObject*> aCpows,
nsIPrincipal* aPrincipal,
nsTArray<StructuredCloneData>* aRetVal,
bool aIsSync) override;
virtual nsresult DoSendAsyncMessage(JSContext* aCx, const nsAString& aMessage,
StructuredCloneData& aData,
JS::Handle<JSObject*> aCpows,
nsIPrincipal* aPrincipal) override;
virtual bool DoSendBlockingMessage(
const nsAString& aMessage, StructuredCloneData& aData,
nsTArray<StructuredCloneData>* aRetVal) override;
virtual nsresult DoSendAsyncMessage(const nsAString& aMessage,
StructuredCloneData& aData) override;
void GetEventTargetParent(EventChainPreVisitor& aVisitor) override;

View File

@ -26,10 +26,9 @@ class MessageBroadcaster : public MessageListenerManager {
void BroadcastAsyncMessage(JSContext* aCx, const nsAString& aMessageName,
JS::Handle<JS::Value> aObj,
JS::Handle<JSObject*> aObjects,
mozilla::ErrorResult& aError) {
DispatchAsyncMessage(aCx, aMessageName, aObj, aObjects, nullptr,
JS::UndefinedHandleValue, aError);
DispatchAsyncMessage(aCx, aMessageName, aObj, JS::UndefinedHandleValue,
aError);
}
uint32_t ChildCount() { return mChildManagers.Length(); }
MessageListenerManager* GetChildAt(uint32_t aIndex) {

View File

@ -35,14 +35,6 @@ void MessageManagerGlobal::Dump(const nsAString& aStr) {
fflush(stdout);
}
void MessageManagerGlobal::PrivateNoteIntentionalCrash(ErrorResult& aError) {
if (XRE_IsContentProcess()) {
NoteIntentionalCrash("tab");
return;
}
aError.Throw(NS_ERROR_NOT_IMPLEMENTED);
}
void MessageManagerGlobal::Atob(const nsAString& aAsciiString,
nsAString& aBase64Data, ErrorResult& aError) {
aError = nsContentUtils::Atob(aAsciiString, aBase64Data);

View File

@ -21,7 +21,7 @@ class MessageManagerGlobal {
MessageListener& aListener, bool aListenWhenClosed,
ErrorResult& aError) {
if (!mMessageManager) {
aError.Throw(NS_ERROR_NULL_POINTER);
aError.Throw(NS_ERROR_NOT_INITIALIZED);
return;
}
mMessageManager->AddMessageListener(aMessageName, aListener,
@ -30,7 +30,7 @@ class MessageManagerGlobal {
void RemoveMessageListener(const nsAString& aMessageName,
MessageListener& aListener, ErrorResult& aError) {
if (!mMessageManager) {
aError.Throw(NS_ERROR_NULL_POINTER);
aError.Throw(NS_ERROR_NOT_INITIALIZED);
return;
}
mMessageManager->RemoveMessageListener(aMessageName, aListener, aError);
@ -38,7 +38,7 @@ class MessageManagerGlobal {
void AddWeakMessageListener(const nsAString& aMessageName,
MessageListener& aListener, ErrorResult& aError) {
if (!mMessageManager) {
aError.Throw(NS_ERROR_NULL_POINTER);
aError.Throw(NS_ERROR_NOT_INITIALIZED);
return;
}
mMessageManager->AddWeakMessageListener(aMessageName, aListener, aError);
@ -47,7 +47,7 @@ class MessageManagerGlobal {
MessageListener& aListener,
ErrorResult& aError) {
if (!mMessageManager) {
aError.Throw(NS_ERROR_NULL_POINTER);
aError.Throw(NS_ERROR_NOT_INITIALIZED);
return;
}
mMessageManager->RemoveWeakMessageListener(aMessageName, aListener, aError);
@ -56,20 +56,18 @@ class MessageManagerGlobal {
// MessageSender
void SendAsyncMessage(JSContext* aCx, const nsAString& aMessageName,
JS::Handle<JS::Value> aObj,
JS::Handle<JSObject*> aObjects,
nsIPrincipal* aPrincipal,
JS::Handle<JS::Value> aTransfers, ErrorResult& aError) {
if (!mMessageManager) {
aError.Throw(NS_ERROR_NULL_POINTER);
aError.Throw(NS_ERROR_NOT_INITIALIZED);
return;
}
mMessageManager->SendAsyncMessage(aCx, aMessageName, aObj, aObjects,
aPrincipal, aTransfers, aError);
mMessageManager->SendAsyncMessage(aCx, aMessageName, aObj, aTransfers,
aError);
}
already_AddRefed<ProcessMessageManager> GetProcessMessageManager(
mozilla::ErrorResult& aError) {
if (!mMessageManager) {
aError.Throw(NS_ERROR_NULL_POINTER);
aError.Throw(NS_ERROR_NOT_INITIALIZED);
return nullptr;
}
return mMessageManager->GetProcessMessageManager(aError);
@ -77,7 +75,7 @@ class MessageManagerGlobal {
void GetRemoteType(nsAString& aRemoteType, mozilla::ErrorResult& aError) {
if (!mMessageManager) {
aError.Throw(NS_ERROR_NULL_POINTER);
aError.Throw(NS_ERROR_NOT_INITIALIZED);
return;
}
mMessageManager->GetRemoteType(aRemoteType, aError);
@ -85,31 +83,17 @@ class MessageManagerGlobal {
// SyncMessageSender
void SendSyncMessage(JSContext* aCx, const nsAString& aMessageName,
JS::Handle<JS::Value> aObj,
JS::Handle<JSObject*> aObjects, nsIPrincipal* aPrincipal,
nsTArray<JS::Value>& aResult, ErrorResult& aError) {
JS::Handle<JS::Value> aObj, nsTArray<JS::Value>& aResult,
ErrorResult& aError) {
if (!mMessageManager) {
aError.Throw(NS_ERROR_NULL_POINTER);
aError.Throw(NS_ERROR_NOT_INITIALIZED);
return;
}
mMessageManager->SendSyncMessage(aCx, aMessageName, aObj, aObjects,
aPrincipal, aResult, aError);
}
void SendRpcMessage(JSContext* aCx, const nsAString& aMessageName,
JS::Handle<JS::Value> aObj,
JS::Handle<JSObject*> aObjects, nsIPrincipal* aPrincipal,
nsTArray<JS::Value>& aResult, ErrorResult& aError) {
if (!mMessageManager) {
aError.Throw(NS_ERROR_NULL_POINTER);
return;
}
mMessageManager->SendRpcMessage(aCx, aMessageName, aObj, aObjects,
aPrincipal, aResult, aError);
mMessageManager->SendSyncMessage(aCx, aMessageName, aObj, aResult, aError);
}
// MessageManagerGlobal
void Dump(const nsAString& aStr);
void PrivateNoteIntentionalCrash(ErrorResult& aError);
void Atob(const nsAString& aAsciiString, nsAString& aBase64Data,
ErrorResult& aError);
void Btoa(const nsAString& aBase64Data, nsAString& aAsciiString,

View File

@ -94,8 +94,6 @@
# include "mozilla/Hal.h"
#endif
#include "mozilla/EMEUtils.h"
#include "mozilla/DetailedPromise.h"
#include "mozilla/Unused.h"
#ifdef MOZ_WEBGPU
@ -147,7 +145,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Navigator)
#endif
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindow)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMediaKeySystemAccessManager)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPresentation)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGamepadServiceTest)
#ifdef MOZ_VR
@ -199,11 +196,6 @@ void Navigator::Invalidate() {
mServiceWorkerContainer = nullptr;
if (mMediaKeySystemAccessManager) {
mMediaKeySystemAccessManager->Shutdown();
mMediaKeySystemAccessManager = nullptr;
}
if (mGamepadServiceTest) {
mGamepadServiceTest->Shutdown();
mGamepadServiceTest = nullptr;
@ -1744,64 +1736,6 @@ nsresult Navigator::GetUserAgent(nsPIDOMWindowInner* aWindow,
return NS_OK;
}
static nsCString RequestKeySystemAccessLogString(
const nsAString& aKeySystem,
const Sequence<MediaKeySystemConfiguration>& aConfigs,
bool aIsSecureContext) {
nsCString str;
str.AppendPrintf(
"Navigator::RequestMediaKeySystemAccess(keySystem='%s' options=",
NS_ConvertUTF16toUTF8(aKeySystem).get());
str.Append(MediaKeySystemAccess::ToCString(aConfigs));
str.AppendLiteral(") secureContext=");
str.AppendInt(aIsSecureContext);
return str;
}
already_AddRefed<Promise> Navigator::RequestMediaKeySystemAccess(
const nsAString& aKeySystem,
const Sequence<MediaKeySystemConfiguration>& aConfigs, ErrorResult& aRv) {
EME_LOG("%s", RequestKeySystemAccessLogString(aKeySystem, aConfigs,
mWindow->IsSecureContext())
.get());
if (!mWindow->IsSecureContext()) {
Document* doc = mWindow->GetExtantDoc();
AutoTArray<nsString, 1> params;
nsString* uri = params.AppendElement();
if (doc) {
Unused << doc->GetDocumentURI(*uri);
}
nsContentUtils::ReportToConsole(
nsIScriptError::warningFlag, NS_LITERAL_CSTRING("Media"), doc,
nsContentUtils::eDOM_PROPERTIES,
"MediaEMEInsecureContextDeprecatedWarning", params);
}
Document* doc = mWindow->GetExtantDoc();
if (doc && !FeaturePolicyUtils::IsFeatureAllowed(
doc, NS_LITERAL_STRING("encrypted-media"))) {
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return nullptr;
}
RefPtr<DetailedPromise> promise = DetailedPromise::Create(
mWindow->AsGlobal(), aRv,
NS_LITERAL_CSTRING("navigator.requestMediaKeySystemAccess"),
Telemetry::VIDEO_EME_REQUEST_SUCCESS_LATENCY_MS,
Telemetry::VIDEO_EME_REQUEST_FAILURE_LATENCY_MS);
if (aRv.Failed()) {
return nullptr;
}
if (!mMediaKeySystemAccessManager) {
mMediaKeySystemAccessManager = new MediaKeySystemAccessManager(mWindow);
}
mMediaKeySystemAccessManager->Request(promise, aKeySystem, aConfigs);
return promise.forget();
}
Presentation* Navigator::GetPresentation(ErrorResult& aRv) {
if (!mPresentation) {
if (!mWindow) {

View File

@ -16,7 +16,6 @@
#include "nsInterfaceHashtable.h"
#include "nsString.h"
#include "nsTArray.h"
#include "mozilla/dom/MediaKeySystemAccessManager.h"
class nsPluginArray;
class nsMimeTypeArray;
@ -231,13 +230,6 @@ class Navigator final : public nsISupports, public nsWrapperCache {
static already_AddRefed<nsPIDOMWindowInner> GetWindowFromGlobal(
JSObject* aGlobal);
already_AddRefed<Promise> RequestMediaKeySystemAccess(
const nsAString& aKeySystem,
const Sequence<MediaKeySystemConfiguration>& aConfig, ErrorResult& aRv);
private:
RefPtr<MediaKeySystemAccessManager> mMediaKeySystemAccessManager;
#ifdef MOZ_VR
public:
void NotifyVRDisplaysUpdated();

View File

@ -284,7 +284,7 @@ StructuredCloneHolder::StructuredCloneHolder(
mGlobal(nullptr)
#ifdef DEBUG
,
mCreationEventTarget(GetCurrentThreadEventTarget())
mCreationEventTarget(GetCurrentEventTarget())
#endif
{
}

View File

@ -27,6 +27,7 @@
#include "nsIDocShell.h"
#include "nsIContent.h"
#include "nsIContentInlines.h"
#include "nsIContentPolicy.h"
#include "nsIImageLoadingContent.h"
#include "nsUnicharUtils.h"
#include "nsIURL.h"
@ -125,7 +126,8 @@ NS_IMPL_ISUPPORTS(nsContentAreaDragDropDataProvider, nsIFlavorDataProvider)
// into the file system
nsresult nsContentAreaDragDropDataProvider::SaveURIToFile(
nsIURI* inSourceURI, nsIPrincipal* inTriggeringPrincipal,
nsIFile* inDestFile, bool isPrivate) {
nsIFile* inDestFile, nsContentPolicyType inContentPolicyType,
bool isPrivate) {
nsCOMPtr<nsIURL> sourceURL = do_QueryInterface(inSourceURI);
if (!sourceURL) {
return NS_ERROR_NO_INTERFACE;
@ -146,7 +148,7 @@ nsresult nsContentAreaDragDropDataProvider::SaveURIToFile(
// referrer policy can be anything since the referrer is nullptr
return persist->SavePrivacyAwareURI(inSourceURI, inTriggeringPrincipal, 0,
nullptr, nullptr, nullptr, inDestFile,
isPrivate);
inContentPolicyType, isPrivate);
}
/*
@ -310,7 +312,10 @@ nsContentAreaDragDropDataProvider::GetFlavorData(nsITransferable* aTransferable,
bool isPrivate = aTransferable->GetIsPrivateData();
nsCOMPtr<nsIPrincipal> principal = aTransferable->GetRequestingPrincipal();
rv = SaveURIToFile(sourceURI, principal, file, isPrivate);
nsContentPolicyType contentPolicyType =
aTransferable->GetContentPolicyType();
rv =
SaveURIToFile(sourceURI, principal, file, contentPolicyType, isPrivate);
// send back an nsIFile
if (NS_SUCCEEDED(rv)) {
CallQueryInterface(file, aData);

View File

@ -68,7 +68,8 @@ class nsContentAreaDragDropDataProvider : public nsIFlavorDataProvider {
nsresult SaveURIToFile(nsIURI* inSourceURI,
nsIPrincipal* inTriggeringPrincipal,
nsIFile* inDestFile, bool isPrivate);
nsIFile* inDestFile, nsContentPolicyType inPolicyType,
bool isPrivate);
};
#endif /* nsContentAreaDragDrop_h__ */

View File

@ -8292,26 +8292,26 @@ class StringBuilder {
EncodeAttrString(*(u.mString), appender);
break;
case Unit::eLiteral:
appender.Append(MakeSpan(u.mLiteral, u.mLength));
appender.Append(Span(u.mLiteral, u.mLength));
break;
case Unit::eTextFragment:
if (u.mTextFragment->Is2b()) {
appender.Append(MakeSpan(u.mTextFragment->Get2b(),
u.mTextFragment->GetLength()));
appender.Append(
Span(u.mTextFragment->Get2b(), u.mTextFragment->GetLength()));
} else {
appender.Append(MakeSpan(u.mTextFragment->Get1b(),
u.mTextFragment->GetLength()));
appender.Append(
Span(u.mTextFragment->Get1b(), u.mTextFragment->GetLength()));
}
break;
case Unit::eTextFragmentWithEncode:
if (u.mTextFragment->Is2b()) {
EncodeTextFragment(MakeSpan(u.mTextFragment->Get2b(),
u.mTextFragment->GetLength()),
appender);
EncodeTextFragment(
Span(u.mTextFragment->Get2b(), u.mTextFragment->GetLength()),
appender);
} else {
EncodeTextFragment(MakeSpan(u.mTextFragment->Get1b(),
u.mTextFragment->GetLength()),
appender);
EncodeTextFragment(
Span(u.mTextFragment->Get1b(), u.mTextFragment->GetLength()),
appender);
}
break;
default:

View File

@ -4122,7 +4122,7 @@ nsDOMWindowUtils::SetCompositionRecording(bool aValue) {
RefPtr<nsDOMWindowUtils> self = this;
cbc->SendBeginRecording(TimeStamp::Now())
->Then(
GetCurrentThreadSerialEventTarget(), __func__,
GetCurrentSerialEventTarget(), __func__,
[self](const bool& aSuccess) {
if (!aSuccess) {
self->ReportErrorMessageForWindow(

View File

@ -113,8 +113,8 @@ nsresult TextStreamer::EncodeAndWrite() {
}
uint8_t buffer[kEncoderBufferSizeInBytes];
auto src = MakeSpan(mOutputBuffer);
auto bufferSpan = MakeSpan(buffer);
auto src = Span(mOutputBuffer);
auto bufferSpan = Span(buffer);
// Reserve space for terminator
auto dst = bufferSpan.To(bufferSpan.Length() - 1);
for (;;) {

View File

@ -169,8 +169,8 @@ static const char* kObservedPrefs[] = {
nsFocusManager::nsFocusManager() : mEventHandlingNeedsFlush(false) {}
nsFocusManager::~nsFocusManager() {
Preferences::UnregisterCallbacks(
PREF_CHANGE_METHOD(nsFocusManager::PrefChanged), kObservedPrefs, this);
Preferences::UnregisterCallbacks(nsFocusManager::PrefChanged, kObservedPrefs,
this);
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
if (obs) {
@ -193,8 +193,8 @@ nsresult nsFocusManager::Init() {
sTestMode = Preferences::GetBool("focusmanager.testmode", false);
Preferences::RegisterCallbacks(
PREF_CHANGE_METHOD(nsFocusManager::PrefChanged), kObservedPrefs, fm);
Preferences::RegisterCallbacks(nsFocusManager::PrefChanged, kObservedPrefs,
fm);
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
if (obs) {
@ -207,6 +207,11 @@ nsresult nsFocusManager::Init() {
// static
void nsFocusManager::Shutdown() { NS_IF_RELEASE(sInstance); }
// static
void nsFocusManager::PrefChanged(const char* aPref, void* aSelf) {
static_cast<nsFocusManager*>(aSelf)->PrefChanged(aPref);
}
void nsFocusManager::PrefChanged(const char* aPref) {
nsDependentCString pref(aPref);
if (pref.EqualsLiteral("accessibility.browsewithcaret")) {
@ -1017,12 +1022,6 @@ nsFocusManager::ParentActivated(mozIDOMWindowProxy* aWindow, bool aActive) {
static bool ShouldMatchFocusVisible(const Element& aElement,
int32_t aFocusFlags) {
if (StaticPrefs::browser_display_show_focus_rings()) {
// FIXME: Spec is ambiguous about whether we should take platform
// conventions into account. This branch does make us account for them.
return true;
}
switch (nsFocusManager::GetFocusMoveActionCause(aFocusFlags)) {
case InputContextAction::CAUSE_UNKNOWN:
case InputContextAction::CAUSE_KEY:
@ -1045,6 +1044,23 @@ static bool ShouldMatchFocusVisible(const Element& aElement,
return false;
}
// On Windows and Linux, focus rings are only shown when the FLAG_SHOWRING flag
// is used.
static bool ShouldShowFocusRingForElement(Element& aElement, int32_t aFlags) {
if (aFlags & nsIFocusManager::FLAG_SHOWRING) {
return true;
}
#if defined(XP_MACOSX) || defined(ANDROID)
if (aFlags & nsIFocusManager::FLAG_BYMOUSE) {
return !nsContentUtils::ContentIsLink(&aElement) &&
!aElement.IsAnyOfHTMLElements(nsGkAtoms::video, nsGkAtoms::audio);
}
return true;
#else
return false;
#endif
}
/* static */
void nsFocusManager::NotifyFocusStateChange(nsIContent* aContent,
nsIContent* aContentToFocus,
@ -1052,7 +1068,8 @@ void nsFocusManager::NotifyFocusStateChange(nsIContent* aContent,
int32_t aFlags,
bool aGettingFocus) {
MOZ_ASSERT_IF(aContentToFocus, !aGettingFocus);
if (!aContent->IsElement()) {
auto* element = Element::FromNode(aContent);
if (!element) {
return;
}
@ -1064,18 +1081,20 @@ void nsFocusManager::NotifyFocusStateChange(nsIContent* aContent,
if (aGettingFocus) {
EventStates eventStateToAdd = NS_EVENT_STATE_FOCUS;
if (aWindowShouldShowFocusRing) {
if (aWindowShouldShowFocusRing ||
ShouldShowFocusRingForElement(*element, aFlags)) {
eventStateToAdd |= NS_EVENT_STATE_FOCUSRING;
}
if (ShouldMatchFocusVisible(*aContent->AsElement(), aFlags)) {
if (aWindowShouldShowFocusRing ||
ShouldMatchFocusVisible(*element, aFlags)) {
eventStateToAdd |= NS_EVENT_STATE_FOCUS_VISIBLE;
}
aContent->AsElement()->AddStates(eventStateToAdd);
element->AddStates(eventStateToAdd);
} else {
EventStates eventStateToRemove = NS_EVENT_STATE_FOCUS |
NS_EVENT_STATE_FOCUSRING |
NS_EVENT_STATE_FOCUS_VISIBLE;
aContent->AsElement()->RemoveStates(eventStateToRemove);
element->RemoveStates(eventStateToRemove);
}
for (nsIContent* content = aContent; content && content != commonAncestor;

View File

@ -61,6 +61,7 @@ class nsFocusManager final : public nsIFocusManager,
// This raises the window and switches to the tab as needed.
static void FocusWindow(nsPIDOMWindowOuter* aWindow);
static void PrefChanged(const char* aPref, void* aSelf);
void PrefChanged(const char* aPref);
/**

View File

@ -78,7 +78,6 @@
#include "mozilla/dom/MozFrameLoaderOwnerBinding.h"
#include "mozilla/dom/SessionStoreListener.h"
#include "mozilla/gfx/CrossProcessPaint.h"
#include "mozilla/jsipc/CrossProcessObjectWrappers.h"
#include "mozilla/layout/RenderFrame.h"
#include "mozilla/ServoCSSParser.h"
#include "mozilla/ServoStyleSet.h"
@ -261,25 +260,30 @@ static void GetFrameName(Element* aOwnerContent, nsAString& aFrameName) {
// manner, they are no longer handled by typeContent and typeChrome. Instead,
// the actual BrowsingContext tree is broken at these edges.
static bool IsTopContent(BrowsingContext* aParent, Element* aOwner) {
if (XRE_IsContentProcess()) {
return false;
}
// If we have a (deprecated) mozbrowser element, we want to start a new
// BrowsingContext tree regardless of whether the parent is chrome or content.
nsCOMPtr<nsIMozBrowserFrame> mozbrowser = aOwner->GetAsMozBrowserFrame();
if (mozbrowser && mozbrowser->GetReallyIsBrowser()) {
return true;
}
if (aParent->IsContent()) {
// If we're already in content, we may still want to create a new
// BrowsingContext tree if our element is either:
// a) a real <iframe mozbrowser> frame, or
// b) a xul browser element with a `remote="true"` marker.
return (mozbrowser && mozbrowser->GetReallyIsBrowser()) ||
(aOwner->IsXULElement() &&
aOwner->AttrValueIs(kNameSpaceID_None, nsGkAtoms::remote,
nsGkAtoms::_true, eCaseMatters));
// BrowsingContext tree if our element is a xul browser element with a
// `remote="true"` marker.
return aOwner->IsXULElement() &&
aOwner->AttrValueIs(kNameSpaceID_None, nsGkAtoms::remote,
nsGkAtoms::_true, eCaseMatters);
}
// If we're in a chrome context, we want to start a new tree if:
// a) we have any mozbrowser frame (even if disabled), or
// b) we are an element with a `type="content"` marker.
return (mozbrowser && mozbrowser->GetMozbrowser()) ||
(aOwner->AttrValueIs(kNameSpaceID_None, TypeAttrName(aOwner),
nsGkAtoms::content, eIgnoreCase));
// If we're in a chrome context, we want to start a new tree if we are an
// element with a `type="content"` marker.
return aOwner->AttrValueIs(kNameSpaceID_None, TypeAttrName(aOwner),
nsGkAtoms::content, eIgnoreCase);
}
static already_AddRefed<BrowsingContext> CreateBrowsingContext(
@ -2160,19 +2164,15 @@ nsresult nsFrameLoader::MaybeCreateDocShell() {
attrs = oa;
}
if (OwnerIsMozBrowserFrame()) {
docShell->SetFrameType(nsIDocShell::FRAME_TYPE_BROWSER);
} else {
nsCOMPtr<nsIDocShellTreeItem> parentCheck;
docShell->GetInProcessSameTypeParent(getter_AddRefs(parentCheck));
if (!!parentCheck) {
docShell->SetIsFrame();
}
nsCOMPtr<nsIDocShellTreeItem> parentCheck;
docShell->GetInProcessSameTypeParent(getter_AddRefs(parentCheck));
if (!!parentCheck) {
docShell->SetIsFrame();
}
// Apply sandbox flags even if our owner is not an iframe, as this copies
// flags from our owning content's owning document.
// Note: ApplySandboxFlags should be called after docShell->SetFrameType
// Note: ApplySandboxFlags should be called after docShell->SetIsFrame
// because we need to get the correct presentation URL in ApplySandboxFlags.
uint32_t sandboxFlags = 0;
HTMLIFrameElement* iframe = HTMLIFrameElement::FromNode(mOwnerContent);
@ -2200,10 +2200,6 @@ nsresult nsFrameLoader::MaybeCreateDocShell() {
if (mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::name, name)) {
docShell->SetName(name);
}
docShell->SetFullscreenAllowed(
mOwnerContent->HasAttr(kNameSpaceID_None, nsGkAtoms::allowfullscreen) ||
mOwnerContent->HasAttr(kNameSpaceID_None,
nsGkAtoms::mozallowfullscreen));
bool isPrivate = mOwnerContent->HasAttr(kNameSpaceID_None,
nsGkAtoms::mozprivatebrowsing);
if (isPrivate) {
@ -2228,8 +2224,7 @@ nsresult nsFrameLoader::MaybeCreateDocShell() {
// that the window exists to ensure we don't try to gather ancestors for
// those cases.
nsCOMPtr<nsPIDOMWindowOuter> win = doc->GetWindow();
if (!docShell->GetIsMozBrowser() &&
parentDocShell->ItemType() == docShell->ItemType() &&
if (parentDocShell->ItemType() == docShell->ItemType() &&
!doc->IsStaticDocument() && win) {
// Propagate through the ancestor principals.
nsTArray<nsCOMPtr<nsIPrincipal>> ancestorPrincipals;
@ -2828,10 +2823,8 @@ bool nsFrameLoader::DoLoadMessageManagerScript(const nsAString& aURL,
class nsAsyncMessageToChild : public nsSameProcessAsyncMessageBase,
public Runnable {
public:
nsAsyncMessageToChild(JS::RootingContext* aRootingCx,
JS::Handle<JSObject*> aCpows,
nsFrameLoader* aFrameLoader)
: nsSameProcessAsyncMessageBase(aRootingCx, aCpows),
explicit nsAsyncMessageToChild(nsFrameLoader* aFrameLoader)
: nsSameProcessAsyncMessageBase(),
mozilla::Runnable("nsAsyncMessageToChild"),
mFrameLoader(aFrameLoader) {}
@ -2852,11 +2845,8 @@ class nsAsyncMessageToChild : public nsSameProcessAsyncMessageBase,
RefPtr<nsFrameLoader> mFrameLoader;
};
nsresult nsFrameLoader::DoSendAsyncMessage(JSContext* aCx,
const nsAString& aMessage,
StructuredCloneData& aData,
JS::Handle<JSObject*> aCpows,
nsIPrincipal* aPrincipal) {
nsresult nsFrameLoader::DoSendAsyncMessage(const nsAString& aMessage,
StructuredCloneData& aData) {
BrowserParent* browserParent = mBrowserParent;
if (browserParent) {
ClonedMessageData data;
@ -2865,13 +2855,7 @@ nsresult nsFrameLoader::DoSendAsyncMessage(JSContext* aCx,
MOZ_CRASH();
return NS_ERROR_DOM_DATA_CLONE_ERR;
}
nsTArray<mozilla::jsipc::CpowEntry> cpows;
jsipc::CPOWManager* mgr = cp->GetCPOWManager();
if (aCpows && (!mgr || !mgr->Wrap(aCx, aCpows, &cpows))) {
return NS_ERROR_UNEXPECTED;
}
if (browserParent->SendAsyncMessage(nsString(aMessage), cpows, aPrincipal,
data)) {
if (browserParent->SendAsyncMessage(nsString(aMessage), data)) {
return NS_OK;
} else {
return NS_ERROR_UNEXPECTED;
@ -2879,10 +2863,8 @@ nsresult nsFrameLoader::DoSendAsyncMessage(JSContext* aCx,
}
if (mChildMessageManager) {
JS::RootingContext* rcx = JS::RootingContext::get(aCx);
RefPtr<nsAsyncMessageToChild> ev =
new nsAsyncMessageToChild(rcx, aCpows, this);
nsresult rv = ev->Init(aMessage, aData, aPrincipal);
RefPtr<nsAsyncMessageToChild> ev = new nsAsyncMessageToChild(this);
nsresult rv = ev->Init(aMessage, aData);
if (NS_FAILED(rv)) {
return rv;
}
@ -3374,9 +3356,9 @@ nsresult nsFrameLoader::GetNewTabContext(MutableTabContext* aTabContext,
}
}
bool tabContextUpdated = aTabContext->SetTabContext(
OwnerIsMozBrowserFrame(), chromeOuterWindowID, showFocusRings, attrs,
presentationURLStr);
bool tabContextUpdated =
aTabContext->SetTabContext(chromeOuterWindowID, showFocusRings, attrs,
presentationURLStr);
NS_ENSURE_STATE(tabContextUpdated);
return NS_OK;

View File

@ -238,9 +238,8 @@ class nsFrameLoader final : public nsStubMutationObserver,
virtual bool DoLoadMessageManagerScript(const nsAString& aURL,
bool aRunInGlobalScope) override;
virtual nsresult DoSendAsyncMessage(
JSContext* aCx, const nsAString& aMessage,
mozilla::dom::ipc::StructuredCloneData& aData,
JS::Handle<JSObject*> aCpows, nsIPrincipal* aPrincipal) override;
const nsAString& aMessage,
mozilla::dom::ipc::StructuredCloneData& aData) override;
/**
* Called from the layout frame associated with this frame loader;

View File

@ -49,7 +49,6 @@
#include "mozilla/dom/ipc/SharedMap.h"
#include "mozilla/dom/ipc/StructuredCloneData.h"
#include "mozilla/dom/DOMStringList.h"
#include "mozilla/jsipc/CrossProcessObjectWrappers.h"
#include "nsPrintfCString.h"
#include "nsXULAppAPI.h"
#include "nsQueryObject.h"
@ -184,16 +183,6 @@ void mozilla::dom::ipc::UnpackClonedMessageDataForChild(
aData.BorrowFromClonedMessageDataForChild(aClonedData);
}
bool SameProcessCpowHolder::ToObject(JSContext* aCx,
JS::MutableHandle<JSObject*> aObjp) {
if (!mObj) {
return true;
}
aObjp.set(mObj);
return JS_WrapObject(aCx, aObjp);
}
void nsFrameMessageManager::AddMessageListener(const nsAString& aMessageName,
MessageListener& aListener,
bool aListenWhenClosed,
@ -442,10 +431,11 @@ static bool AllowMessage(size_t aDataLength, const nsAString& aMessageName) {
return aDataLength < kMaxMessageSize;
}
void nsFrameMessageManager::SendMessage(
JSContext* aCx, const nsAString& aMessageName, JS::Handle<JS::Value> aObj,
JS::Handle<JSObject*> aObjects, nsIPrincipal* aPrincipal, bool aIsSync,
nsTArray<JS::Value>& aResult, ErrorResult& aError) {
void nsFrameMessageManager::SendSyncMessage(JSContext* aCx,
const nsAString& aMessageName,
JS::Handle<JS::Value> aObj,
nsTArray<JS::Value>& aResult,
ErrorResult& aError) {
NS_ASSERTION(!IsGlobal(), "Should not call SendSyncMessage in chrome");
NS_ASSERTION(!IsBroadcaster(), "Should not call SendSyncMessage in chrome");
NS_ASSERTION(!GetParentManager(),
@ -454,7 +444,7 @@ void nsFrameMessageManager::SendMessage(
AUTO_PROFILER_LABEL_DYNAMIC_LOSSY_NSSTRING(
"nsFrameMessageManager::SendMessage", OTHER, aMessageName);
if (sSendingSyncMessage && aIsSync) {
if (sSendingSyncMessage) {
// No kind of blocking send should be issued on top of a sync message.
aError.Throw(NS_ERROR_UNEXPECTED);
return;
@ -487,12 +477,9 @@ void nsFrameMessageManager::SendMessage(
nsTArray<StructuredCloneData> retval;
TimeStamp start = TimeStamp::Now();
sSendingSyncMessage |= aIsSync;
bool ok = mCallback->DoSendBlockingMessage(aCx, aMessageName, data, aObjects,
aPrincipal, &retval, aIsSync);
if (aIsSync) {
sSendingSyncMessage = false;
}
sSendingSyncMessage = true;
bool ok = mCallback->DoSendBlockingMessage(aMessageName, data, &retval);
sSendingSyncMessage = false;
uint32_t latencyMs = round((TimeStamp::Now() - start).ToMilliseconds());
if (latencyMs >= kMinTelemetrySyncMessageManagerLatencyMs) {
@ -523,13 +510,11 @@ void nsFrameMessageManager::SendMessage(
}
nsresult nsFrameMessageManager::DispatchAsyncMessageInternal(
JSContext* aCx, const nsAString& aMessage, StructuredCloneData& aData,
JS::Handle<JSObject*> aCpows, nsIPrincipal* aPrincipal) {
JSContext* aCx, const nsAString& aMessage, StructuredCloneData& aData) {
if (mIsBroadcaster) {
uint32_t len = mChildManagers.Length();
for (uint32_t i = 0; i < len; ++i) {
mChildManagers[i]->DispatchAsyncMessageInternal(aCx, aMessage, aData,
aCpows, aPrincipal);
mChildManagers[i]->DispatchAsyncMessageInternal(aCx, aMessage, aData);
}
return NS_OK;
}
@ -538,8 +523,7 @@ nsresult nsFrameMessageManager::DispatchAsyncMessageInternal(
return NS_ERROR_NOT_INITIALIZED;
}
nsresult rv =
mCallback->DoSendAsyncMessage(aCx, aMessage, aData, aCpows, aPrincipal);
nsresult rv = mCallback->DoSendAsyncMessage(aMessage, aData);
if (NS_FAILED(rv)) {
return rv;
}
@ -548,7 +532,6 @@ nsresult nsFrameMessageManager::DispatchAsyncMessageInternal(
void nsFrameMessageManager::DispatchAsyncMessage(
JSContext* aCx, const nsAString& aMessageName, JS::Handle<JS::Value> aObj,
JS::Handle<JSObject*> aObjects, nsIPrincipal* aPrincipal,
JS::Handle<JS::Value> aTransfers, ErrorResult& aError) {
StructuredCloneData data;
if (!aObj.isUndefined() &&
@ -568,8 +551,7 @@ void nsFrameMessageManager::DispatchAsyncMessage(
return;
}
aError = DispatchAsyncMessageInternal(aCx, aMessageName, data, aObjects,
aPrincipal);
aError = DispatchAsyncMessageInternal(aCx, aMessageName, data);
}
class MMListenerRemover {
@ -594,7 +576,6 @@ class MMListenerRemover {
void nsFrameMessageManager::ReceiveMessage(
nsISupports* aTarget, nsFrameLoader* aTargetFrameLoader, bool aTargetClosed,
const nsAString& aMessage, bool aIsSync, StructuredCloneData* aCloneData,
mozilla::jsipc::CpowHolder* aCpows, nsIPrincipal* aPrincipal,
nsTArray<StructuredCloneData>* aRetVal, ErrorResult& aError) {
MOZ_ASSERT(aTarget);
@ -656,21 +637,6 @@ void nsFrameMessageManager::ReceiveMessage(
RootedDictionary<ReceiveMessageArgument> argument(cx);
JS::Rooted<JSObject*> cpows(cx);
if (aCpows && !aCpows->ToObject(cx, &cpows)) {
aError.Throw(NS_ERROR_UNEXPECTED);
return;
}
if (!cpows) {
cpows = JS_NewPlainObject(cx);
if (!cpows) {
aError.Throw(NS_ERROR_UNEXPECTED);
return;
}
}
argument.mObjects = cpows;
JS::Rooted<JS::Value> json(cx, JS::NullValue());
if (aCloneData && aCloneData->DataLength()) {
aCloneData->Read(cx, &json, aError);
@ -694,7 +660,6 @@ void nsFrameMessageManager::ReceiveMessage(
}
argument.mName = aMessage;
argument.mPrincipal = aPrincipal;
argument.mSync = aIsSync;
argument.mTarget = aTarget;
if (aTargetFrameLoader) {
@ -801,8 +766,8 @@ void nsFrameMessageManager::ReceiveMessage(
RefPtr<nsFrameMessageManager> kungFuDeathGrip = GetParentManager();
if (kungFuDeathGrip) {
kungFuDeathGrip->ReceiveMessage(aTarget, aTargetFrameLoader, aTargetClosed,
aMessage, aIsSync, aCloneData, aCpows,
aPrincipal, aRetVal, aError);
aMessage, aIsSync, aCloneData, aRetVal,
aError);
}
}
@ -1231,9 +1196,15 @@ void nsMessageManagerScriptExecutor::TryCacheLoadAndCompileScript(
return;
}
JSContext* cx = jsapi.cx();
JS::Rooted<JSScript*> script(cx);
script = ScriptPreloader::GetChildSingleton().GetCachedScript(cx, url);
JS::CompileOptions options(cx);
ScriptPreloader::FillCompileOptionsForCachedScript(options);
options.setFileAndLine(url.get(), 1);
options.setNonSyntacticScope(true);
JS::Rooted<JSScript*> script(cx);
script =
ScriptPreloader::GetChildSingleton().GetCachedScript(cx, options, url);
if (!script) {
nsCOMPtr<nsIChannel> channel;
@ -1276,11 +1247,6 @@ void nsMessageManagerScriptExecutor::TryCacheLoadAndCompileScript(
return;
}
JS::CompileOptions options(cx);
options.setFileAndLine(url.get(), 1);
options.setNoScriptRval(true);
options.setNonSyntacticScope(true);
script = JS::Compile(cx, options, srcBuf);
if (!script) {
return;
@ -1343,9 +1309,8 @@ nsFrameMessageManager* nsFrameMessageManager::sSameProcessParentManager =
class nsAsyncMessageToSameProcessChild : public nsSameProcessAsyncMessageBase,
public Runnable {
public:
nsAsyncMessageToSameProcessChild(JS::RootingContext* aRootingCx,
JS::Handle<JSObject*> aCpows)
: nsSameProcessAsyncMessageBase(aRootingCx, aCpows),
nsAsyncMessageToSameProcessChild()
: nsSameProcessAsyncMessageBase(),
mozilla::Runnable("nsAsyncMessageToSameProcessChild") {}
NS_IMETHOD Run() override {
nsFrameMessageManager* ppm =
@ -1375,15 +1340,12 @@ class SameParentProcessMessageManagerCallback : public MessageManagerCallback {
return true;
}
nsresult DoSendAsyncMessage(JSContext* aCx, const nsAString& aMessage,
StructuredCloneData& aData,
JS::Handle<JSObject*> aCpows,
nsIPrincipal* aPrincipal) override {
JS::RootingContext* rcx = JS::RootingContext::get(aCx);
nsresult DoSendAsyncMessage(const nsAString& aMessage,
StructuredCloneData& aData) override {
RefPtr<nsAsyncMessageToSameProcessChild> ev =
new nsAsyncMessageToSameProcessChild(rcx, aCpows);
new nsAsyncMessageToSameProcessChild();
nsresult rv = ev->Init(aMessage, aData, aPrincipal);
nsresult rv = ev->Init(aMessage, aData);
if (NS_FAILED(rv)) {
return rv;
}
@ -1407,12 +1369,9 @@ class ChildProcessMessageManagerCallback : public MessageManagerCallback {
MOZ_COUNT_DTOR(ChildProcessMessageManagerCallback);
}
bool DoSendBlockingMessage(JSContext* aCx, const nsAString& aMessage,
bool DoSendBlockingMessage(const nsAString& aMessage,
StructuredCloneData& aData,
JS::Handle<JSObject*> aCpows,
nsIPrincipal* aPrincipal,
nsTArray<StructuredCloneData>* aRetVal,
bool aIsSync) override {
nsTArray<StructuredCloneData>* aRetVal) override {
mozilla::dom::ContentChild* cc = mozilla::dom::ContentChild::GetSingleton();
if (!cc) {
return true;
@ -1421,22 +1380,11 @@ class ChildProcessMessageManagerCallback : public MessageManagerCallback {
if (!BuildClonedMessageDataForChild(cc, aData, data)) {
return false;
}
nsTArray<mozilla::jsipc::CpowEntry> cpows;
if (aCpows && !cc->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) {
return false;
}
if (aIsSync) {
return cc->SendSyncMessage(PromiseFlatString(aMessage), data, cpows,
IPC::Principal(aPrincipal), aRetVal);
}
return cc->SendRpcMessage(PromiseFlatString(aMessage), data, cpows,
IPC::Principal(aPrincipal), aRetVal);
return cc->SendSyncMessage(PromiseFlatString(aMessage), data, aRetVal);
}
nsresult DoSendAsyncMessage(JSContext* aCx, const nsAString& aMessage,
StructuredCloneData& aData,
JS::Handle<JSObject*> aCpows,
nsIPrincipal* aPrincipal) override {
nsresult DoSendAsyncMessage(const nsAString& aMessage,
StructuredCloneData& aData) override {
mozilla::dom::ContentChild* cc = mozilla::dom::ContentChild::GetSingleton();
if (!cc) {
return NS_OK;
@ -1445,12 +1393,7 @@ class ChildProcessMessageManagerCallback : public MessageManagerCallback {
if (!BuildClonedMessageDataForChild(cc, aData, data)) {
return NS_ERROR_DOM_DATA_CLONE_ERR;
}
nsTArray<mozilla::jsipc::CpowEntry> cpows;
if (aCpows && !cc->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) {
return NS_ERROR_UNEXPECTED;
}
if (!cc->SendAsyncMessage(PromiseFlatString(aMessage), cpows,
IPC::Principal(aPrincipal), data)) {
if (!cc->SendAsyncMessage(PromiseFlatString(aMessage), data)) {
return NS_ERROR_UNEXPECTED;
}
@ -1462,9 +1405,7 @@ class nsAsyncMessageToSameProcessParent
: public nsSameProcessAsyncMessageBase,
public SameProcessMessageQueue::Runnable {
public:
nsAsyncMessageToSameProcessParent(JS::RootingContext* aRootingCx,
JS::Handle<JSObject*> aCpows)
: nsSameProcessAsyncMessageBase(aRootingCx, aCpows) {}
nsAsyncMessageToSameProcessParent() : nsSameProcessAsyncMessageBase() {}
nsresult HandleMessage() override {
nsFrameMessageManager* ppm =
nsFrameMessageManager::sSameProcessParentManager;
@ -1485,34 +1426,27 @@ class SameChildProcessMessageManagerCallback : public MessageManagerCallback {
MOZ_COUNT_DTOR(SameChildProcessMessageManagerCallback);
}
bool DoSendBlockingMessage(JSContext* aCx, const nsAString& aMessage,
bool DoSendBlockingMessage(const nsAString& aMessage,
StructuredCloneData& aData,
JS::Handle<JSObject*> aCpows,
nsIPrincipal* aPrincipal,
nsTArray<StructuredCloneData>* aRetVal,
bool aIsSync) override {
nsTArray<StructuredCloneData>* aRetVal) override {
SameProcessMessageQueue* queue = SameProcessMessageQueue::Get();
queue->Flush();
if (nsFrameMessageManager::sSameProcessParentManager) {
SameProcessCpowHolder cpows(JS::RootingContext::get(aCx), aCpows);
RefPtr<nsFrameMessageManager> ppm =
nsFrameMessageManager::sSameProcessParentManager;
ppm->ReceiveMessage(ppm, nullptr, aMessage, true, &aData, &cpows,
aPrincipal, aRetVal, IgnoreErrors());
ppm->ReceiveMessage(ppm, nullptr, aMessage, true, &aData, aRetVal,
IgnoreErrors());
}
return true;
}
nsresult DoSendAsyncMessage(JSContext* aCx, const nsAString& aMessage,
StructuredCloneData& aData,
JS::Handle<JSObject*> aCpows,
nsIPrincipal* aPrincipal) override {
nsresult DoSendAsyncMessage(const nsAString& aMessage,
StructuredCloneData& aData) override {
SameProcessMessageQueue* queue = SameProcessMessageQueue::Get();
JS::RootingContext* rcx = JS::RootingContext::get(aCx);
RefPtr<nsAsyncMessageToSameProcessParent> ev =
new nsAsyncMessageToSameProcessParent(rcx, aCpows);
nsresult rv = ev->Init(aMessage, aData, aPrincipal);
new nsAsyncMessageToSameProcessParent();
nsresult rv = ev->Init(aMessage, aData);
if (NS_FAILED(rv)) {
return rv;
@ -1594,19 +1528,15 @@ void nsFrameMessageManager::MarkForCC() {
}
}
nsSameProcessAsyncMessageBase::nsSameProcessAsyncMessageBase(
JS::RootingContext* aRootingCx, JS::Handle<JSObject*> aCpows)
: mCpows(aRootingCx, aCpows)
nsSameProcessAsyncMessageBase::nsSameProcessAsyncMessageBase()
#ifdef DEBUG
,
mCalledInit(false)
: mCalledInit(false)
#endif
{
}
nsresult nsSameProcessAsyncMessageBase::Init(const nsAString& aMessage,
StructuredCloneData& aData,
nsIPrincipal* aPrincipal) {
StructuredCloneData& aData) {
if (!mData.Copy(aData)) {
Telemetry::Accumulate(Telemetry::IPC_SAME_PROCESS_MESSAGE_COPY_OOM_KB,
aData.DataLength());
@ -1614,7 +1544,6 @@ nsresult nsSameProcessAsyncMessageBase::Init(const nsAString& aMessage,
}
mMessage = aMessage;
mPrincipal = aPrincipal;
#ifdef DEBUG
mCalledInit = true;
#endif
@ -1628,10 +1557,8 @@ void nsSameProcessAsyncMessageBase::ReceiveMessage(
// Make sure that we have called Init() and it has succeeded.
MOZ_ASSERT(mCalledInit);
if (aManager) {
SameProcessCpowHolder cpows(RootingCx(), mCpows);
RefPtr<nsFrameMessageManager> mm = aManager;
mm->ReceiveMessage(aTarget, aTargetFrameLoader, mMessage, false, &mData,
&cpows, mPrincipal, nullptr, IgnoreErrors());
nullptr, IgnoreErrors());
}
}

View File

@ -29,7 +29,6 @@
#include "mozilla/dom/CallbackObject.h"
#include "mozilla/dom/SameProcessMessageQueue.h"
#include "mozilla/dom/ipc/StructuredCloneData.h"
#include "mozilla/jsipc/CpowHolder.h"
class nsFrameLoader;
@ -82,19 +81,14 @@ class MessageManagerCallback {
return true;
}
virtual bool DoSendBlockingMessage(JSContext* aCx, const nsAString& aMessage,
virtual bool DoSendBlockingMessage(const nsAString& aMessage,
StructuredCloneData& aData,
JS::Handle<JSObject*> aCpows,
nsIPrincipal* aPrincipal,
nsTArray<StructuredCloneData>* aRetVal,
bool aIsSync) {
nsTArray<StructuredCloneData>* aRetVal) {
return true;
}
virtual nsresult DoSendAsyncMessage(JSContext* aCx, const nsAString& aMessage,
StructuredCloneData& aData,
JS::Handle<JSObject*> aCpows,
nsIPrincipal* aPrincipal) {
virtual nsresult DoSendAsyncMessage(const nsAString& aMessage,
StructuredCloneData& aData) {
return NS_OK;
}
@ -137,20 +131,6 @@ struct nsMessageListenerInfo {
bool mListenWhenClosed;
};
class MOZ_STACK_CLASS SameProcessCpowHolder
: public mozilla::jsipc::CpowHolder {
public:
SameProcessCpowHolder(JS::RootingContext* aRootingCx,
JS::Handle<JSObject*> aObj)
: mObj(aRootingCx, aObj) {}
virtual bool ToObject(JSContext* aCx,
JS::MutableHandle<JSObject*> aObjp) override;
private:
JS::Rooted<JSObject*> mObj;
};
class nsFrameMessageManager : public nsIMessageSender {
friend class mozilla::dom::MessageManagerReporter;
typedef mozilla::dom::ipc::StructuredCloneData StructuredCloneData;
@ -190,12 +170,9 @@ class nsFrameMessageManager : public nsIMessageSender {
// MessageSender
void SendAsyncMessage(JSContext* aCx, const nsAString& aMessageName,
JS::Handle<JS::Value> aObj,
JS::Handle<JSObject*> aObjects,
nsIPrincipal* aPrincipal,
JS::Handle<JS::Value> aTransfers,
mozilla::ErrorResult& aError) {
DispatchAsyncMessage(aCx, aMessageName, aObj, aObjects, aPrincipal,
aTransfers, aError);
DispatchAsyncMessage(aCx, aMessageName, aObj, aTransfers, aError);
}
already_AddRefed<mozilla::dom::ProcessMessageManager>
GetProcessMessageManager(mozilla::ErrorResult& aError);
@ -204,21 +181,8 @@ class nsFrameMessageManager : public nsIMessageSender {
// SyncMessageSender
void SendSyncMessage(JSContext* aCx, const nsAString& aMessageName,
JS::Handle<JS::Value> aObj,
JS::Handle<JSObject*> aObjects, nsIPrincipal* aPrincipal,
nsTArray<JS::Value>& aResult,
mozilla::ErrorResult& aError) {
SendMessage(aCx, aMessageName, aObj, aObjects, aPrincipal, true, aResult,
aError);
}
void SendRpcMessage(JSContext* aCx, const nsAString& aMessageName,
JS::Handle<JS::Value> aObj,
JS::Handle<JSObject*> aObjects, nsIPrincipal* aPrincipal,
nsTArray<JS::Value>& aResult,
mozilla::ErrorResult& aError) {
SendMessage(aCx, aMessageName, aObj, aObjects, aPrincipal, false, aResult,
aError);
}
JS::Handle<JS::Value> aObj, nsTArray<JS::Value>& aResult,
mozilla::ErrorResult& aError);
// GlobalProcessScriptLoader
void GetInitialProcessData(JSContext* aCx,
@ -235,12 +199,10 @@ class nsFrameMessageManager : public nsIMessageSender {
void ReceiveMessage(nsISupports* aTarget, nsFrameLoader* aTargetFrameLoader,
const nsAString& aMessage, bool aIsSync,
StructuredCloneData* aCloneData,
mozilla::jsipc::CpowHolder* aCpows,
nsIPrincipal* aPrincipal,
nsTArray<StructuredCloneData>* aRetVal,
mozilla::ErrorResult& aError) {
ReceiveMessage(aTarget, aTargetFrameLoader, mClosed, aMessage, aIsSync,
aCloneData, aCpows, aPrincipal, aRetVal, aError);
aCloneData, aRetVal, aError);
}
void Disconnect(bool aRemoveFromParent = true);
@ -252,9 +214,7 @@ class nsFrameMessageManager : public nsIMessageSender {
nsresult DispatchAsyncMessageInternal(JSContext* aCx,
const nsAString& aMessage,
StructuredCloneData& aData,
JS::Handle<JSObject*> aCpows,
nsIPrincipal* aPrincipal);
StructuredCloneData& aData);
bool IsGlobal() { return mGlobal; }
bool IsBroadcaster() { return mIsBroadcaster; }
bool IsChrome() { return mChrome; }
@ -292,21 +252,12 @@ class nsFrameMessageManager : public nsIMessageSender {
void DispatchAsyncMessage(JSContext* aCx, const nsAString& aMessageName,
JS::Handle<JS::Value> aObj,
JS::Handle<JSObject*> aObjects,
nsIPrincipal* aPrincipal,
JS::Handle<JS::Value> aTransfers,
mozilla::ErrorResult& aError);
void SendMessage(JSContext* aCx, const nsAString& aMessageName,
JS::Handle<JS::Value> aObj, JS::Handle<JSObject*> aObjects,
nsIPrincipal* aPrincipal, bool aIsSync,
nsTArray<JS::Value>& aResult, mozilla::ErrorResult& aError);
void ReceiveMessage(nsISupports* aTarget, nsFrameLoader* aTargetFrameLoader,
bool aTargetClosed, const nsAString& aMessage,
bool aIsSync, StructuredCloneData* aCloneData,
mozilla::jsipc::CpowHolder* aCpows,
nsIPrincipal* aPrincipal,
nsTArray<StructuredCloneData>* aRetVal,
mozilla::ErrorResult& aError);
@ -372,10 +323,8 @@ class nsSameProcessAsyncMessageBase {
public:
typedef mozilla::dom::ipc::StructuredCloneData StructuredCloneData;
nsSameProcessAsyncMessageBase(JS::RootingContext* aRootingCx,
JS::Handle<JSObject*> aCpows);
nsresult Init(const nsAString& aMessage, StructuredCloneData& aData,
nsIPrincipal* aPrincipal);
nsSameProcessAsyncMessageBase();
nsresult Init(const nsAString& aMessage, StructuredCloneData& aData);
void ReceiveMessage(nsISupports* aTarget, nsFrameLoader* aTargetFrameLoader,
nsFrameMessageManager* aManager);
@ -385,8 +334,6 @@ class nsSameProcessAsyncMessageBase {
nsString mMessage;
StructuredCloneData mData;
JS::PersistentRooted<JSObject*> mCpows;
nsCOMPtr<nsIPrincipal> mPrincipal;
#ifdef DEBUG
bool mCalledInit;
#endif
@ -429,7 +376,6 @@ class nsMessageManagerScriptExecutor {
bool Init();
void Trace(const TraceCallbacks& aCallbacks, void* aClosure);
void Unlink();
nsCOMPtr<nsIPrincipal> mPrincipal;
AutoTArray<JS::Heap<JSObject*>, 2> mAnonymousGlobalScopes;
// Returns true if this is a process message manager. There should only be a

View File

@ -109,6 +109,7 @@
#include "PostMessageEvent.h"
#include "mozilla/dom/DocGroup.h"
#include "mozilla/dom/TabGroup.h"
#include "mozilla/StaticPrefs_browser.h"
#include "mozilla/StaticPrefs_dom.h"
#include "PaintWorkletImpl.h"
@ -833,7 +834,6 @@ nsGlobalWindowInner::nsGlobalWindowInner(nsGlobalWindowOuter* aOuterWindow)
mCleanMessageManager(false),
mNeedsFocus(true),
mHasFocus(false),
mShowFocusRingForContent(false),
mFocusByKeyOccurred(false),
mDidFireDocElemInserted(false),
mHasGamepad(false),
@ -4045,16 +4045,6 @@ void nsGlobalWindowInner::StopVRActivity() {
}
#endif
#ifndef XP_WIN // This guard should match the guard at the callsite.
static bool ShouldShowFocusRingIfFocusedByMouse(nsIContent* aNode) {
if (!aNode) {
return true;
}
return !nsContentUtils::ContentIsLink(aNode) &&
!aNode->IsAnyOfHTMLElements(nsGkAtoms::video, nsGkAtoms::audio);
}
#endif
void nsGlobalWindowInner::SetFocusedElement(Element* aElement,
uint32_t aFocusMethod,
bool aNeedsFocus) {
@ -4072,7 +4062,6 @@ void nsGlobalWindowInner::SetFocusedElement(Element* aElement,
UpdateCanvasFocus(false, aElement);
mFocusedElement = aElement;
mFocusMethod = aFocusMethod & FOCUSMETHOD_MASK;
mShowFocusRingForContent = false;
}
if (mFocusedElement) {
@ -4080,17 +4069,6 @@ void nsGlobalWindowInner::SetFocusedElement(Element* aElement,
// window.
if (mFocusMethod & nsIFocusManager::FLAG_BYKEY) {
mFocusByKeyOccurred = true;
} else if (
// otherwise, we set mShowFocusRingForContent, as we don't want this to
// be permanent for the window. On Windows, focus rings are only shown
// when the FLAG_SHOWRING flag is used. On other platforms, focus rings
// are only visible on some elements.
#ifndef XP_WIN
!(mFocusMethod & nsIFocusManager::FLAG_BYMOUSE) ||
ShouldShowFocusRingIfFocusedByMouse(aElement) ||
#endif
aFocusMethod & nsIFocusManager::FLAG_SHOWRING) {
mShowFocusRingForContent = true;
}
}
@ -4100,12 +4078,13 @@ void nsGlobalWindowInner::SetFocusedElement(Element* aElement,
uint32_t nsGlobalWindowInner::GetFocusMethod() { return mFocusMethod; }
bool nsGlobalWindowInner::ShouldShowFocusRing() {
if (mShowFocusRingForContent || mFocusByKeyOccurred) {
if (mFocusByKeyOccurred &&
StaticPrefs::browser_display_always_show_rings_after_key_focus()) {
return true;
}
nsCOMPtr<nsPIWindowRoot> root = GetTopWindowRoot();
return root ? root->ShowFocusRings() : false;
return root && root->ShowFocusRings();
}
bool nsGlobalWindowInner::TakeFocus(bool aFocus, uint32_t aFocusMethod) {

View File

@ -1283,10 +1283,6 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
bool mNeedsFocus : 1;
bool mHasFocus : 1;
// when true, show focus rings for the current focused content only.
// This will be reset when another element is focused
bool mShowFocusRingForContent : 1;
// true if tab navigation has occurred for this window. Focus rings
// should be displayed.
bool mFocusByKeyOccurred : 1;

View File

@ -1218,7 +1218,7 @@ nsGlobalWindowOuter::~nsGlobalWindowOuter() {
mBrowsingContext->ClearWindowProxy();
}
js::SetProxyReservedSlot(proxy, OUTER_WINDOW_SLOT,
js::PrivateValue(nullptr));
JS::PrivateValue(nullptr));
}
// An outer window is destroyed with inner windows still possibly
@ -2069,7 +2069,7 @@ nsresult nsGlobalWindowOuter::SetNewDocument(Document* aDocument,
NS_ENSURE_TRUE(outer, NS_ERROR_FAILURE);
js::SetProxyReservedSlot(outer, OUTER_WINDOW_SLOT,
js::PrivateValue(ToSupports(this)));
JS::PrivateValue(ToSupports(this)));
// Inform the nsJSContext, which is the canonical holder of the outer.
mContext->SetWindowProxy(outer);
@ -2088,9 +2088,9 @@ nsresult nsGlobalWindowOuter::SetNewDocument(Document* aDocument,
MOZ_ASSERT(js::IsWindowProxy(obj));
js::SetProxyReservedSlot(obj, OUTER_WINDOW_SLOT,
js::PrivateValue(nullptr));
JS::PrivateValue(nullptr));
js::SetProxyReservedSlot(outerObject, OUTER_WINDOW_SLOT,
js::PrivateValue(nullptr));
JS::PrivateValue(nullptr));
js::SetProxyReservedSlot(obj, HOLDER_WEAKMAP_SLOT, JS::UndefinedValue());
outerObject = xpc::TransplantObject(cx, obj, outerObject);
@ -2101,7 +2101,7 @@ nsresult nsGlobalWindowOuter::SetNewDocument(Document* aDocument,
}
js::SetProxyReservedSlot(outerObject, OUTER_WINDOW_SLOT,
js::PrivateValue(ToSupports(this)));
JS::PrivateValue(ToSupports(this)));
SetWrapper(outerObject);
@ -2975,12 +2975,12 @@ nsPIDOMWindowOuter* nsGlobalWindowOuter::GetInProcessScriptableParent() {
return nullptr;
}
if (mDocShell->GetIsMozBrowser()) {
return this;
if (BrowsingContext* parentBC = GetBrowsingContext()->GetParent()) {
if (nsCOMPtr<nsPIDOMWindowOuter> parent = parentBC->GetDOMWindow()) {
return parent;
}
}
nsCOMPtr<nsPIDOMWindowOuter> parent = GetInProcessParent();
return parent;
return this;
}
/**
@ -3150,13 +3150,6 @@ already_AddRefed<nsPIDOMWindowOuter> nsGlobalWindowOuter::GetContentInternal(
return content.forget();
}
// If we're contained in <iframe mozbrowser>, then GetContent is the same as
// window.top.
if (mDocShell && mDocShell->GetIsInMozBrowser()) {
nsCOMPtr<nsPIDOMWindowOuter> domWindow(GetInProcessScriptableTop());
return domWindow.forget();
}
nsCOMPtr<nsIDocShellTreeItem> primaryContent;
if (aCallerType != CallerType::System) {
if (mDoc) {
@ -5190,19 +5183,6 @@ nsresult nsGlobalWindowOuter::MoveBy(int32_t aXDif, int32_t aYDif) {
void nsGlobalWindowOuter::ResizeToOuter(int32_t aWidth, int32_t aHeight,
CallerType aCallerType,
ErrorResult& aError) {
/*
* If caller is a browser-element then dispatch a resize event to
* the embedder.
*/
if (mDocShell && mDocShell->GetIsMozBrowser()) {
CSSIntSize size(aWidth, aHeight);
if (!DispatchResizeEvent(size)) {
// The embedder chose to prevent the default action for this
// event, so let's not resize this window after all...
return;
}
}
/*
* If caller is not chrome and the user has not explicitly exempted the site,
* prevent window.resizeTo() by exiting early
@ -5231,26 +5211,6 @@ void nsGlobalWindowOuter::ResizeToOuter(int32_t aWidth, int32_t aHeight,
void nsGlobalWindowOuter::ResizeByOuter(int32_t aWidthDif, int32_t aHeightDif,
CallerType aCallerType,
ErrorResult& aError) {
/*
* If caller is a browser-element then dispatch a resize event to
* parent.
*/
if (mDocShell && mDocShell->GetIsMozBrowser()) {
CSSIntSize size;
if (NS_FAILED(GetInnerSize(size))) {
return;
}
size.width += aWidthDif;
size.height += aHeightDif;
if (!DispatchResizeEvent(size)) {
// The embedder chose to prevent the default action for this
// event, so let's not resize this window after all...
return;
}
}
/*
* If caller is not chrome and the user has not explicitly exempted the site,
* prevent window.resizeBy() by exiting early
@ -6152,8 +6112,7 @@ bool nsGlobalWindowOuter::CanClose() {
}
void nsGlobalWindowOuter::CloseOuter(bool aTrustedCaller) {
if (!mDocShell || IsInModalState() ||
(IsFrame() && !mDocShell->GetIsMozBrowser())) {
if (!mDocShell || IsInModalState() || IsFrame()) {
// window.close() is called on a frame in a frameset, on a window
// that's already closed, or on a window for which there's
// currently a modal dialog open. Ignore such calls.
@ -6454,7 +6413,7 @@ void nsGlobalWindowOuter::NotifyWindowIDDestroyed(const char* aTopic) {
Element* nsGlobalWindowOuter::GetFrameElementOuter(
nsIPrincipal& aSubjectPrincipal) {
if (!mDocShell || mDocShell->GetIsMozBrowser()) {
if (!mDocShell) {
return nullptr;
}

View File

@ -271,8 +271,8 @@ nsresult nsJSUtils::ExecutionContext::Decode(
}
MOZ_ASSERT(!mWantsReturnValue);
JS::TranscodeResult tr =
JS::DecodeScript(mCx, aBytecodeBuf, &mScript, aBytecodeIndex);
JS::TranscodeResult tr = JS::DecodeScriptMaybeStencil(
mCx, aCompileOptions, aBytecodeBuf, &mScript, aBytecodeIndex);
// These errors are external parameters which should be handled before the
// decoding phase, and which are the only reasons why you might want to
// fallback on decoding failures.

View File

@ -57,9 +57,8 @@ bool nsNameSpaceManager::Init() {
rv = AddDisabledNameSpace(dont_AddRef(uri), id); \
NS_ENSURE_SUCCESS(rv, false)
mozilla::Preferences::RegisterCallbacks(
PREF_CHANGE_METHOD(nsNameSpaceManager::PrefChanged), kObservedNSPrefs,
this);
mozilla::Preferences::RegisterCallbacks(nsNameSpaceManager::PrefChanged,
kObservedNSPrefs, this);
PrefChanged(nullptr);
@ -262,6 +261,11 @@ nsresult nsNameSpaceManager::AddDisabledNameSpace(already_AddRefed<nsAtom> aURI,
return NS_OK;
}
// static
void nsNameSpaceManager::PrefChanged(const char* aPref, void* aSelf) {
static_cast<nsNameSpaceManager*>(aSelf)->PrefChanged(aPref);
}
void nsNameSpaceManager::PrefChanged(const char* aPref) {
mMathMLDisabled = mozilla::Preferences::GetBool(kPrefMathMLDisabled);
mSVGDisabled = mozilla::Preferences::GetBool(kPrefSVGDisabled);

View File

@ -62,6 +62,7 @@ class nsNameSpaceManager final {
bool mSVGDisabled;
private:
static void PrefChanged(const char* aPref, void* aSelf);
void PrefChanged(const char* aPref);
bool Init();

View File

@ -299,8 +299,7 @@ bool nsTextFragment::SetTo(const char16_t* aBuffer, int32_t aLength,
}
// Copy data
LossyConvertUtf16toLatin1(MakeSpan(aBuffer, aLength),
MakeSpan(buff, aLength));
LossyConvertUtf16toLatin1(Span(aBuffer, aLength), Span(buff, aLength));
m1b = buff;
mState.mIs2b = false;
}
@ -329,7 +328,7 @@ void nsTextFragment::CopyTo(char16_t* aDest, int32_t aOffset, int32_t aCount) {
memcpy(aDest, Get2b() + aOffset, sizeof(char16_t) * aCount);
} else {
const char* cp = m1b + aOffset;
ConvertLatin1toUtf16(MakeSpan(cp, aCount), MakeSpan(aDest, aCount));
ConvertLatin1toUtf16(Span(cp, aCount), Span(aDest, aCount));
}
}
}
@ -414,8 +413,7 @@ bool nsTextFragment::Append(const char16_t* aBuffer, uint32_t aLength,
// Copy data into buff
char16_t* data = static_cast<char16_t*>(buff->Data());
ConvertLatin1toUtf16(MakeSpan(m1b, mState.mLength),
MakeSpan(data, mState.mLength));
ConvertLatin1toUtf16(Span(m1b, mState.mLength), Span(data, mState.mLength));
memcpy(data + mState.mLength, aBuffer, aLength * sizeof(char16_t));
mState.mLength += aLength;
@ -456,8 +454,8 @@ bool nsTextFragment::Append(const char16_t* aBuffer, uint32_t aLength,
}
// Copy aBuffer into buff.
LossyConvertUtf16toLatin1(MakeSpan(aBuffer, aLength),
MakeSpan(buff + mState.mLength, aLength));
LossyConvertUtf16toLatin1(Span(aBuffer, aLength),
Span(buff + mState.mLength, aLength));
m1b = buff;
mState.mLength += aLength;
@ -483,7 +481,7 @@ size_t nsTextFragment::SizeOfExcludingThis(
// every allocation
void nsTextFragment::UpdateBidiFlag(const char16_t* aBuffer, uint32_t aLength) {
if (mState.mIs2b && !mState.mIsBidi) {
if (HasRTLChars(MakeSpan(aBuffer, aLength))) {
if (HasRTLChars(Span(aBuffer, aLength))) {
mState.mIsBidi = true;
}
}

View File

@ -203,7 +203,7 @@ nsresult nsWindowRoot::GetControllerForCommand(const char* aCommand,
void nsWindowRoot::GetEnabledDisabledCommandsForControllers(
nsIControllers* aControllers,
nsTHashtable<nsCharPtrHashKey>& aCommandsHandled,
nsTHashtable<nsCStringHashKey>& aCommandsHandled,
nsTArray<nsCString>& aEnabledCommands,
nsTArray<nsCString>& aDisabledCommands) {
uint32_t controllerCount;
@ -215,21 +215,20 @@ void nsWindowRoot::GetEnabledDisabledCommandsForControllers(
nsCOMPtr<nsICommandController> commandController(
do_QueryInterface(controller));
if (commandController) {
uint32_t commandsCount;
char** commands;
if (NS_SUCCEEDED(commandController->GetSupportedCommands(&commandsCount,
&commands))) {
for (uint32_t e = 0; e < commandsCount; e++) {
// All of our default command controllers have 20-60 commands. Let's just
// leave enough space here for all of them so we probably don't need to
// heap-allocate.
AutoTArray<nsCString, 64> commands;
if (NS_SUCCEEDED(commandController->GetSupportedCommands(commands))) {
for (auto& commandStr : commands) {
// Use a hash to determine which commands have already been handled by
// earlier controllers, as the earlier controller's result should get
// priority.
if (aCommandsHandled.EnsureInserted(commands[e])) {
if (aCommandsHandled.EnsureInserted(commandStr)) {
// We inserted a new entry into aCommandsHandled.
bool enabled = false;
controller->IsCommandEnabled(commands[e], &enabled);
controller->IsCommandEnabled(commandStr.get(), &enabled);
const nsDependentCSubstring commandStr(commands[e],
strlen(commands[e]));
if (enabled) {
aEnabledCommands.AppendElement(commandStr);
} else {
@ -237,8 +236,6 @@ void nsWindowRoot::GetEnabledDisabledCommandsForControllers(
}
}
}
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(commandsCount, commands);
}
}
}
@ -247,7 +244,7 @@ void nsWindowRoot::GetEnabledDisabledCommandsForControllers(
void nsWindowRoot::GetEnabledDisabledCommands(
nsTArray<nsCString>& aEnabledCommands,
nsTArray<nsCString>& aDisabledCommands) {
nsTHashtable<nsCharPtrHashKey> commandsHandled;
nsTHashtable<nsCStringHashKey> commandsHandled;
nsCOMPtr<nsIControllers> controllers;
GetControllers(false, getter_AddRefs(controllers));

View File

@ -21,9 +21,8 @@ class nsWindowRoot final : public nsPIWindowRoot {
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
virtual mozilla::EventListenerManager* GetExistingListenerManager()
const override;
virtual mozilla::EventListenerManager* GetOrCreateListenerManager() override;
mozilla::EventListenerManager* GetExistingListenerManager() const override;
mozilla::EventListenerManager* GetOrCreateListenerManager() override;
bool ComputeDefaultWantsUntrusted(mozilla::ErrorResult& aRv) final;
@ -37,54 +36,47 @@ class nsWindowRoot final : public nsPIWindowRoot {
// nsPIWindowRoot
virtual nsPIDOMWindowOuter* GetWindow() override;
nsPIDOMWindowOuter* GetWindow() override;
virtual nsresult GetControllers(bool aForVisibleWindow,
nsIControllers** aResult) override;
virtual nsresult GetControllerForCommand(const char* aCommand,
bool aForVisibleWindow,
nsIController** _retval) override;
nsresult GetControllers(bool aForVisibleWindow,
nsIControllers** aResult) override;
nsresult GetControllerForCommand(const char* aCommand, bool aForVisibleWindow,
nsIController** _retval) override;
virtual void GetEnabledDisabledCommands(
void GetEnabledDisabledCommands(
nsTArray<nsCString>& aEnabledCommands,
nsTArray<nsCString>& aDisabledCommands) override;
virtual already_AddRefed<nsINode> GetPopupNode() override;
virtual void SetPopupNode(nsINode* aNode) override;
already_AddRefed<nsINode> GetPopupNode() override;
void SetPopupNode(nsINode* aNode) override;
virtual void SetParentTarget(mozilla::dom::EventTarget* aTarget) override {
void SetParentTarget(mozilla::dom::EventTarget* aTarget) override {
mParent = aTarget;
}
virtual mozilla::dom::EventTarget* GetParentTarget() override {
return mParent;
}
virtual nsPIDOMWindowOuter* GetOwnerGlobalForBindingsInternal() override;
virtual nsIGlobalObject* GetOwnerGlobal() const override;
mozilla::dom::EventTarget* GetParentTarget() override { return mParent; }
nsPIDOMWindowOuter* GetOwnerGlobalForBindingsInternal() override;
nsIGlobalObject* GetOwnerGlobal() const override;
nsIGlobalObject* GetParentObject();
virtual JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
JSObject* WrapObject(JSContext*, JS::Handle<JSObject*> aGivenProto) override;
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsWindowRoot)
virtual void AddBrowser(mozilla::dom::BrowserParent* aBrowser) override;
virtual void RemoveBrowser(mozilla::dom::BrowserParent* aBrowser) override;
virtual void EnumerateBrowsers(BrowserEnumerator aEnumFunc,
void* aArg) override;
void AddBrowser(mozilla::dom::BrowserParent* aBrowser) override;
void RemoveBrowser(mozilla::dom::BrowserParent* aBrowser) override;
void EnumerateBrowsers(BrowserEnumerator aEnumFunc, void* aArg) override;
virtual bool ShowFocusRings() override { return mShowFocusRings; }
bool ShowFocusRings() override { return mShowFocusRings; }
virtual void SetShowFocusRings(bool aEnable) override {
mShowFocusRings = aEnable;
}
void SetShowFocusRings(bool aEnable) override { mShowFocusRings = aEnable; }
protected:
virtual ~nsWindowRoot();
void GetEnabledDisabledCommandsForControllers(
nsIControllers* aControllers,
nsTHashtable<nsCharPtrHashKey>& aCommandsHandled,
nsTHashtable<nsCStringHashKey>& aCommandsHandled,
nsTArray<nsCString>& aEnabledCommands,
nsTArray<nsCString>& aDisabledCommands);

View File

@ -163,16 +163,16 @@ nsresult nsXMLContentSerializer::AppendTextData(nsIContent* aNode,
NS_ERROR_OUT_OF_MEMORY);
}
} else {
nsAutoString utf16;
if (!CopyASCIItoUTF16(Span(frag->Get1b() + aStartOffset, length), utf16,
mozilla::fallible_t())) {
return NS_ERROR_OUT_OF_MEMORY;
}
if (aTranslateEntities) {
NS_ENSURE_TRUE(
AppendAndTranslateEntities(
NS_ConvertASCIItoUTF16(frag->Get1b() + aStartOffset, length),
aStr),
NS_ERROR_OUT_OF_MEMORY);
NS_ENSURE_TRUE(AppendAndTranslateEntities(utf16, aStr),
NS_ERROR_OUT_OF_MEMORY);
} else {
NS_ENSURE_TRUE(aStr.Append(NS_ConvertASCIItoUTF16(
frag->Get1b() + aStartOffset, length),
mozilla::fallible),
NS_ENSURE_TRUE(aStr.Append(utf16, mozilla::fallible),
NS_ERROR_OUT_OF_MEMORY);
}
}

View File

@ -13,7 +13,6 @@ support-files =
file_script.js
referrer_helper.js
referrer_testserver.sjs
mozbrowser_api_utils.js
!/image/test/mochitest/shaver.png
[test_anonymousContent_xul_window.xul]
@ -25,12 +24,9 @@ support-files =
[test_bug1016960.html]
[test_anchor_target_blank_referrer.html]
[test_copypaste.xul]
tags = clipboard
[test_domrequesthelper.xul]
[test_fragment_sanitization.xul]
[test_messagemanager_principal.html]
[test_messagemanager_send_principal.html]
[test_mozbrowser_apis_allowed.html]
[test_navigator_resolve_identity_xrays.xul]
support-files = file_navigator_resolve_identity_xrays.xul
[test_sandboxed_blob_uri.html]

View File

@ -1,4 +0,0 @@
<html>
<body>
</body>
</html>

View File

@ -1,424 +0,0 @@
/* eslint-env mozilla/frame-script */
dump("loaded child cpow test\n");
Cu.importGlobalProperties(["XMLHttpRequest"]);
var is_remote;
(function start() {
[is_remote] = sendRpcMessage("cpows:is_remote");
var tests = [
parent_test,
error_reporting_test,
dom_test,
xray_test,
symbol_test,
compartment_test,
regexp_test,
postmessage_test,
sync_test,
async_test,
rpc_test,
lifetime_test,
cancel_test,
cancel_test2,
dead_test,
localStorage_test,
unsafe_test,
];
function go() {
if (tests.length == 0) {
sendRpcMessage("cpows:done", {});
return;
}
var test = tests[0];
tests.shift();
test(function() {
go();
});
}
go();
})();
function ok(condition, message) {
dump("condition: " + condition + ", " + message + "\n");
if (!condition) {
sendAsyncMessage("cpows:fail", { message });
}
}
var sync_obj;
var async_obj;
function make_object() {
let o = {};
o.i = 5;
o.b = true;
o.s = "hello";
o.x = { i: 10 };
o.f = function() {
return 99;
};
o.ctor = function() {
this.a = 3;
};
// Doing anything with this Proxy will throw.
var throwing = new Proxy(
{},
new Proxy(
{},
{
get(trap) {
throw trap;
},
}
)
);
let array = [1, 2, 3];
let for_json = { n: 3, a: array, s: "hello", o: { x: 10 } };
let proto = { data: 42 };
let with_proto = Object.create(proto);
let with_null_proto = Object.create(null);
content.document.title = "Hello, Kitty";
return {
data: o,
throwing,
document: content.document,
array,
for_json,
with_proto,
with_null_proto,
};
}
function make_json() {
return { check: "ok" };
}
function parent_test(finish) {
function f(check_func) {
// Make sure this doesn't crash.
let array = new Uint32Array(10);
content.crypto.getRandomValues(array);
let result = check_func(10);
ok(result == 20, "calling function in parent worked");
return result;
}
addMessageListener("cpows:from_parent", msg => {
let obj = msg.objects.obj;
if (is_remote) {
ok(obj.a == undefined, "__exposedProps__ should not work");
} else {
// The same process test is not run as content, so the field can
// be accessed even though __exposedProps__ has been removed.
ok(obj.a == 1, "correct value from parent");
}
// Test that a CPOW reference to a function in the chrome process
// is callable from unprivileged content. Greasemonkey uses this
// functionality.
let func = msg.objects.func;
let sb = Cu.Sandbox("http://www.example.com", {});
sb.func = func;
ok(sb.eval("func()") == 101, "can call parent's function in child");
finish();
});
sendRpcMessage("cpows:parent_test", {}, { func: f });
}
function error_reporting_test(finish) {
sendRpcMessage("cpows:error_reporting_test", {}, {});
finish();
}
function dom_test(finish) {
let element = content.document.createElement("div");
element.id = "it_works";
content.document.body.appendChild(element);
sendRpcMessage("cpows:dom_test", {}, { element });
Cu.schedulePreciseGC(function() {
sendRpcMessage("cpows:dom_test_after_gc");
finish();
});
}
function xray_test(finish) {
let element = content.document.createElement("div");
element.wrappedJSObject.foo = "hello";
sendRpcMessage("cpows:xray_test", {}, { element });
finish();
}
function symbol_test(finish) {
let iterator = Symbol.iterator;
let named = Symbol.for("cpow-test");
let object = {
[iterator]: iterator,
[named]: named,
};
let test = ["a"];
sendRpcMessage("cpows:symbol_test", {}, { object, test });
finish();
}
// Parent->Child references should go X->parent.privilegedJunkScope->child.privilegedJunkScope->Y
// Child->Parent references should go X->child.privilegedJunkScope->parent.unprivilegedJunkScope->Y
function compartment_test(finish) {
// This test primarily checks various compartment invariants for CPOWs, and
// doesn't make sense to run in-process.
if (!is_remote) {
finish();
return;
}
let sb = Cu.Sandbox("http://www.example.com", {
wantGlobalProperties: ["XMLHttpRequest"],
});
sb.eval(
"function getUnprivilegedObject() { var xhr = new XMLHttpRequest(); xhr.expando = 42; return xhr; }"
);
function testParentObject(obj) {
let results = [];
function is(a, b, msg) {
results.push({ result: a === b ? "PASS" : "FAIL", message: msg });
}
function ok1(x, msg) {
results.push({ result: x ? "PASS" : "FAIL", message: msg });
}
let cpowLocation = Cu.getRealmLocation(obj);
ok1(
/shared JSM global/.test(cpowLocation),
"child->parent CPOWs should live in the privileged junk scope: " +
cpowLocation
);
is(obj(), 42, "child->parent CPOW is invokable");
try {
obj.expando;
ok1(false, "child->parent CPOW cannot access properties");
} catch (e) {
ok1(true, "child->parent CPOW cannot access properties");
}
return results;
}
sendRpcMessage(
"cpows:compartment_test",
{},
{ getUnprivilegedObject: sb.getUnprivilegedObject, testParentObject }
);
finish();
}
function regexp_test(finish) {
sendRpcMessage("cpows:regexp_test", {}, { regexp: /myRegExp/g });
finish();
}
function postmessage_test(finish) {
sendRpcMessage("cpows:postmessage_test", {}, { win: content.window });
finish();
}
function sync_test(finish) {
dump("beginning cpow sync test\n");
sync_obj = make_object();
sendRpcMessage("cpows:sync", make_json(), make_object());
finish();
}
function async_test(finish) {
dump("beginning cpow async test\n");
async_obj = make_object();
sendAsyncMessage("cpows:async", make_json(), async_obj);
addMessageListener("cpows:async_done", finish);
}
var rpc_obj;
function rpc_test(finish) {
dump("beginning cpow rpc test\n");
rpc_obj = make_object();
rpc_obj.data.reenter = function() {
sendRpcMessage("cpows:reenter", {}, { data: { valid: true } });
return "ok";
};
sendRpcMessage("cpows:rpc", make_json(), rpc_obj);
finish();
}
function lifetime_test(finish) {
if (!is_remote) {
// Only run this test when running out-of-process. Otherwise it
// will fail, since local CPOWs don't follow the same ownership
// rules.
finish();
return;
}
dump("beginning lifetime test\n");
var obj = { will_die: { f: 1 } };
let [result] = sendRpcMessage("cpows:lifetime_test_1", {}, { obj });
ok(result == 10, "got sync result");
ok(obj.wont_die.f == undefined, "got reverse CPOW");
obj.will_die = null;
Cu.schedulePreciseGC(function() {
addMessageListener("cpows:lifetime_test_3", msg => {
ok(obj.wont_die.f == undefined, "reverse CPOW still works");
finish();
});
sendRpcMessage("cpows:lifetime_test_2");
});
}
function cancel_test(finish) {
if (!is_remote) {
// No point in doing this in single-process mode.
finish();
return;
}
let fin1 = false,
fin2 = false;
// CPOW from the parent runs f. When it sends a sync message, the
// CPOW is canceled. The parent starts running again immediately
// after the CPOW is canceled; f also continues running.
function f() {
let res = sendSyncMessage("cpows:cancel_sync_message");
ok(res[0] == 12, "cancel_sync_message result correct");
fin1 = true;
if (fin1 && fin2) {
finish();
}
}
sendAsyncMessage("cpows:cancel_test", null, { f });
addMessageListener("cpows:cancel_test_done", msg => {
fin2 = true;
if (fin1 && fin2) {
finish();
}
});
}
function cancel_test2(finish) {
if (!is_remote) {
// No point in doing this in single-process mode.
finish();
return;
}
let fin1 = false,
fin2 = false;
// CPOW from the parent runs f. When it does a sync XHR, the
// CPOW is canceled. The parent starts running again immediately
// after the CPOW is canceled; f also continues running.
function f() {
let req = new XMLHttpRequest();
let fin = false;
let reqListener = () => {
if (req.readyState != req.DONE) {
return;
}
ok(req.status == 200, "XHR succeeded");
fin = true;
};
req.onload = reqListener;
req.open("get", "http://example.com", false);
req.send(null);
ok(fin === true, "XHR happened");
fin1 = true;
if (fin1 && fin2) {
finish();
}
}
sendAsyncMessage("cpows:cancel_test2", null, { f });
addMessageListener("cpows:cancel_test2_done", msg => {
fin2 = true;
if (fin1 && fin2) {
finish();
}
});
}
function unsafe_test(finish) {
if (!is_remote) {
// Only run this test when running out-of-process.
finish();
return;
}
function f() {}
sendAsyncMessage("cpows:unsafe", null, { f });
addMessageListener("cpows:unsafe_done", msg => {
sendRpcMessage("cpows:safe", null, { f });
addMessageListener("cpows:safe_done", finish);
});
}
function dead_test(finish) {
if (!is_remote) {
// Only run this test when running out-of-process.
finish();
return;
}
let gcTrigger = function() {
// Force the GC to dead-ify the thing.
content.windowUtils.garbageCollect();
};
{
let thing = { value: "Gonna croak" };
sendAsyncMessage("cpows:dead", null, { thing, gcTrigger });
}
addMessageListener("cpows:dead_done", finish);
}
function localStorage_test(finish) {
// This test exits because a synchronous message can be sent from the parent
// while localStorage is synchronously blocking the main thread in the child
// which can result in deadlock. When unsafe CPOWS go away:
// 1. The test can go away.
// 2. LocalStorage can be further cleaned up and a bug should be filed to
// clean it up.
if (!is_remote) {
// Only run this test when running out-of-process.
finish();
return;
}
function f() {}
sendAsyncMessage("cpows:localStorage", null, { f });
addMessageListener("cpows:localStorage_done", finish);
for (let i = 0; i < 3; i++) {
try {
content.localStorage.setItem("foo", "bar");
} catch (ex) {}
}
}

View File

@ -1,520 +0,0 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
type="text/css"?>
<window title="MessageManager CPOW tests"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="start()">
<!-- test results are displayed in the html:body -->
<label value="CPOWs"/>
<script type="application/javascript"><![CDATA[
var test_state = "remote";
var test_node = null;
var reentered = false;
var savedMM = null;
function info(message) {
return opener.wrappedJSObject.info(message);
}
function ok(condition, message) {
return opener.wrappedJSObject.ok(condition, message);
}
function is(v1, v2, message) {
return opener.wrappedJSObject.is(v1, v2, message);
}
function todo_is(v1, v2, message) {
return opener.wrappedJSObject.todo_is(v1, v2, message);
}
// Make sure that an error in this file actually causes the test to fail.
var gReceivedErrorProbe = false;
window.onerror = function (msg, url, line) {
if (/Test Error Probe/.test(msg)) {
gReceivedErrorProbe = true;
return;
}
ok(false, "Error while executing: \n" + msg + "\n" + url + ":" + line);
};
function testCpowMessage(message) {
ok(message.json.check == "ok", "correct json");
ok(!Cu.isCrossProcessWrapper(message.json), "not everything is a CPOW");
let data = message.objects.data;
let document = message.objects.document;
if (test_state == "remote") {
ok(Cu.isCrossProcessWrapper(data), "got a CPOW");
ok(Cu.isCrossProcessWrapper(document), "got a CPOW");
}
ok(data.i === 5, "integer property");
ok(data.b === true, "boolean property");
ok(data.s === "hello", "string property");
ok(data.x.i === 10, "nested property");
ok(data.f() === 99, "function call");
is(Object.getOwnPropertyDescriptor(data, "doesn't exist"), undefined,
"getOwnPropertyDescriptor returns undefined for non-existant properties");
ok(Object.getOwnPropertyDescriptor(data, "i").value, 5,
"getOwnPropertyDescriptor.value works");
let obj = new data.ctor();
ok(obj.a === 3, "constructor call");
is(document.title, "Hello, Kitty", "document node");
is(typeof document.cookie, "string", "can get document.cookie");
is(typeof document.defaultView.navigator.userAgent, "string", "can get navigator.userAgent");
// Don't crash.
document.defaultView.screen;
data.i = 6;
data.b = false;
data.s = "bye";
data.x = null;
ok(data.i === 6, "integer property");
ok(data.b === false, "boolean property");
ok(data.s === "bye", "string property");
ok(data.x === null, "nested property");
let throwing = message.objects.throwing;
// Based on the table on:
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy
let tests = [
() => Object.getOwnPropertyDescriptor(throwing, 'test'),
() => Object.getOwnPropertyNames(throwing),
() => Object.defineProperty(throwing, 'test', {value: 1}),
() => delete throwing.test,
() => "test" in throwing,
() => Object.prototype.hasOwnProperty.call(throwing, 'test'),
() => throwing.test,
() => { throwing.test = 1 },
// () => { for (let prop in throwing) {} }, Bug 783829
() => { for (let prop of throwing) {} },
() => Object.keys(throwing),
() => Function.prototype.call.call(throwing),
() => new throwing,
() => Object.preventExtensions(throwing),
() => Object.freeze(throwing),
() => Object.seal(throwing),
]
for (let test of tests) {
let threw = false;
try {
test()
} catch (e) {
threw = true;
}
ok(threw, "proxy operation threw exception");
}
let array = message.objects.array;
let i = 1;
for (let elt of array) {
ok(elt === i, "correct element found");
i++;
}
ok(i === 4, "array has correct length");
let j = message.objects.for_json;
let str = JSON.stringify(j);
let j2 = JSON.parse(str);
ok(j2.n === 3, "JSON integer property");
ok(j2.a[0] === 1, "JSON array index");
ok(j2.a[1] === 2, "JSON array index");
ok(j2.a[2] === 3, "JSON array index");
ok(j2.s === "hello", "JSON string property");
ok(j2.o.x === 10, "JSON object property");
let with_proto = message.objects.with_proto;
let proto = Object.getPrototypeOf(with_proto);
ok(proto.data == 42, "Object.getPrototypeOf works on CPOW");
let with_null_proto = message.objects.with_null_proto;
proto = Object.getPrototypeOf(with_null_proto);
ok(proto === null, "Object.getPrototypeOf works on CPOW (null proto)");
}
function recvAsyncMessage(message) {
testCpowMessage(message);
savedMM.sendAsyncMessage("cpows:async_done");
}
function recvSyncMessage(message) {
testCpowMessage(message);
}
function recvRpcMessage(message) {
ok(message.json.check == "ok", "correct json");
let data = message.objects.data;
// Sanity check.
ok(data.i === 5, "integer property");
// Check that we re-enter.
reentered = false;
let result = data.reenter();
ok(reentered, "re-entered rpc");
ok(result == "ok", "got correct result");
}
function recvReenterMessage(message) {
ok(message.objects.data.valid === true, "cpows work");
reentered = true;
}
function recvNestedSyncMessage(message) {
message.objects.data.reenter();
}
function recvReenterSyncMessage(message) {
ok(false, "should not have received re-entered sync message");
}
function recvFailMessage(message) {
ok(false, message.json.message);
}
function recvDoneMessage(message) {
if (test_state == "remote") {
test_node.remove();
run_tests("inprocess");
return;
}
finish();
}
function recvParentTest(message) {
let func = message.objects.func;
let result = func(n => 2*n);
ok(result == 20, "result == 20");
function f() {
return 101;
}
let obj = {a:1, __exposedProps__: {"a": "r"}};
savedMM.sendAsyncMessage("cpows:from_parent", {}, {obj: obj, func: f});
}
// Make sure errors in this file actually hit window.onerror.
function recvErrorReportingTest(message) {
throw "Test Error Probe";
}
let savedElement = null;
function recvDomTest(message) {
savedElement = message.objects.element;
is(savedElement.QueryInterface(Ci.nsISupports), savedElement,
"QI to nsISupports works");
function testNoInterface(savedElement, i) {
try {
savedElement.QueryInterface(i);
ok(false, "should have thrown an exception");
} catch (e) {
is(e.result, Cr.NS_ERROR_NO_INTERFACE, "threw the right exception");
}
}
testNoInterface(savedElement, Ci.nsIClassInfo);
// Test to ensure that we don't pass CPOWs to C++-implemented interfaces.
// See bug 1072980.
if (test_state == "remote") {
// This doesn't work because we intercept toString specially
// and don't cache the function pointer.
// See bug 1140636.
todo_is(savedElement.toString, savedElement.toString, "toString identity works");
is(savedElement.QueryInterface, savedElement.QueryInterface, "QueryInterface identity works");
is(Object.prototype.toString.call(savedElement), "[object HTMLDivElement]",
"prove that this works (and doesn't leak)");
is(Object.prototype.toString.call(savedElement), "[object HTMLDivElement]",
"prove that this works twice (since we cache it and doesn't leak)");
// This does work because we create a CPOW for isEqualNode that stays
// alive as long as we have a reference to the first CPOW (so as long
// as it's detectable).
is(savedElement.isEqualNode, savedElement.isEqualNode, "webidl function identity works");
// We want to test what happens when a CPOW is passed through XPConnect
// as an XPCOM interface. But elements are losing all their XPCOM
// interfaces, so let's use an object that will likely stay an XPCOM
// one.
let docshell = savedElement.ownerGlobal.docShell;
ok(docshell, "We should have a docshell here!");
let secureUI = Cc['@mozilla.org/secure_browser_ui;1']
.createInstance(Ci.nsISecureBrowserUI);
try {
secureUI.init(docshell);
ok(false, "expected exception passing CPOW to C++");
} catch (e) {
is(e.result, Cr.NS_ERROR_XPC_CANT_PASS_CPOW_TO_NATIVE,
"got exception when passing CPOW to C++");
}
}
}
function recvDomTestAfterGC(message) {
let id;
try {
id = savedElement.id;
} catch (e) {
ok(false, "Got exception using DOM element");
}
is(id, "it_works", "DOM element has expected ID");
}
function recvXrayTest(message) {
let element = message.objects.element;
is(element.foo, undefined, "DOM element does not expose content properties");
}
function recvSymbolTest(message) {
let object = message.objects.object;
is(object[Symbol.iterator], Symbol.iterator, "Should use Symbol.iterator");
is(Symbol.keyFor(object[Symbol.for("cpow-test")]), "cpow-test", "Symbols aren't registered correctly");
let symbols = Object.getOwnPropertySymbols(object);
is(symbols.length, 2, "Object should have two symbol keys");
let test = undefined;
for (let x of message.objects.test) {
test = x;
}
is(test, "a", "for .. of iteration should work");
}
let systemGlobal = this;
function recvCompartmentTest(message) {
let getUnprivilegedObject = message.objects.getUnprivilegedObject;
let testParentObject = message.objects.testParentObject;
// Make sure that parent->child CPOWs live in the parent's privileged junk scope.
let unprivilegedObject = getUnprivilegedObject();
is(Cu.getGlobalForObject(getUnprivilegedObject),
Cu.getGlobalForObject(unprivilegedObject),
"all parent->child CPOWs should live in the same scope");
let cpowLocation = Cu.getRealmLocation(getUnprivilegedObject);
ok(/shared JSM global/.test(cpowLocation),
"parent->child CPOWs should live in the privileged junk scope: " + cpowLocation);
// Make sure that parent->child CPOWs point through a privileged scope in the child
// (the privileged junk scope, but we don't have a good way to test for that
// specifically).
is(unprivilegedObject.expando, undefined, "parent->child references should get Xrays");
is(unprivilegedObject.wrappedJSObject.expando, 42, "parent->child references should get waivable Xrays");
// Send an object to the child to let it verify invariants in the other direction.
function passMe() { return 42; };
passMe.expando = 42;
let results = testParentObject(passMe);
ok(results.length > 0, "Need results");
results.forEach((x) => is(x.result, "PASS", x.message));
}
function recvRegExpTest(message) {
let regexp = message.objects.regexp;
// These work generically.
is(regexp.toString(), "/myRegExp/g", "toString works right");
ok(regexp.test("I like myRegExp to match"), "No false positives");
ok(!regexp.test("asdfsdf"), "No false positives");
// These go over regexp_toShared.
is("filler myRegExp filler".search(regexp), 7, "String.prototype.match works right");
var shell = /x/;
shell.compile(regexp);
is(regexp.toString(), shell.toString(), ".compile works right");
}
function recvPostMessageTest(message) {
let win = message.objects.win;
win.postMessage('nookery', '*');
ok(true, "Didn't crash invoking postMessage over CPOW");
}
let savedWilldieObj;
let wontDie = {f:2, __exposedProps__: {"f": "r"}};
function recvLifetimeTest1(message) {
let obj = message.objects.obj;
savedWilldieObj = obj.will_die;
ok(savedWilldieObj.f == 1, "limited-lifetime CPOW works at first");
obj.wont_die = wontDie;
obj = null;
return 10;
}
function recvLifetimeTest2(message) {
let threw = false;
try {
savedWilldieObj.f;
} catch (e) {
threw = true;
}
ok(threw, "limited-lifetime CPOW stopped working");
wontDie = null;
Cu.schedulePreciseGC(function() {
savedMM.sendAsyncMessage("cpows:lifetime_test_3");
});
}
function recvCancelTest(msg) {
let failed = false;
try {
msg.objects.f();
} catch (e) {
if (!/cross-process JS call failed/.test(String(e))) {
throw e;
}
failed = true;
}
ok(failed, "CPOW should fail due to cancelation");
msg.target.messageManager.sendAsyncMessage("cpows:cancel_test_done");
}
function recvCancelSyncMessage() {
return 12;
}
function recvCancelTest2(msg) {
let failed = false;
try {
msg.objects.f();
} catch (e) {
if (!/cross-process JS call failed/.test(String(e))) {
throw e;
}
failed = true;
}
ok(failed, "CPOW should fail due to cancelation");
msg.target.messageManager.sendAsyncMessage("cpows:cancel_test2_done");
}
function recvUnsafe(msg) {
let failed = false;
const PREF_UNSAFE_FORBIDDEN = "dom.ipc.cpows.forbid-unsafe-from-browser";
opener.wrappedJSObject.SpecialPowers.setBoolPref(PREF_UNSAFE_FORBIDDEN, true);
try {
msg.objects.f();
} catch (e) {
if (!/unsafe CPOW usage forbidden/.test(String(e))) {
throw e;
}
failed = true;
}
opener.wrappedJSObject.SpecialPowers.clearUserPref(PREF_UNSAFE_FORBIDDEN);
ok(failed, "CPOW should fail when unsafe");
msg.target.messageManager.sendAsyncMessage("cpows:unsafe_done");
}
function recvSafe(msg) {
const PREF_UNSAFE_FORBIDDEN = "dom.ipc.cpows.forbid-unsafe-from-browser";
opener.wrappedJSObject.SpecialPowers.setBoolPref(PREF_UNSAFE_FORBIDDEN, true);
try {
msg.objects.f();
} catch (e) {
if (!/unsafe CPOW usage forbidden/.test(String(e))) {
throw e;
}
ok(false, "cpow failed");
}
opener.wrappedJSObject.SpecialPowers.clearUserPref(PREF_UNSAFE_FORBIDDEN);
msg.target.messageManager.sendAsyncMessage("cpows:safe_done");
}
function recvDead(msg) {
// Need to do this in a separate turn of the event loop.
setTimeout(() => {
msg.objects.gcTrigger();
try {
msg.objects.thing.value;
ok(false, "Should have been a dead CPOW");
} catch (e) {
if (!/dead CPOW/.test(String(e))) {
throw e;
}
ok(true, "Got the expected dead CPOW");
ok(e.stack, "The exception has a stack");
}
msg.target.messageManager.sendAsyncMessage("cpows:dead_done");
}, 0);
}
function recvLocalStorage(msg) {
msg.objects.f();
msg.target.messageManager.sendAsyncMessage("cpows:localStorage_done");
}
function run_tests(type) {
info("Running tests: " + type);
var node = document.getElementById('cpowbrowser_' + type);
test_state = type;
test_node = node;
function recvIsRemote(message) {
return type == "remote";
}
var mm = node.messageManager;
savedMM = mm;
mm.addMessageListener("cpows:is_remote", recvIsRemote);
mm.addMessageListener("cpows:async", recvAsyncMessage);
mm.addMessageListener("cpows:sync", recvSyncMessage);
mm.addMessageListener("cpows:rpc", recvRpcMessage);
mm.addMessageListener("cpows:reenter", recvReenterMessage);
mm.addMessageListener("cpows:reenter", recvReenterMessage);
mm.addMessageListener("cpows:nested_sync", recvNestedSyncMessage);
mm.addMessageListener("cpows:reenter_sync", recvReenterSyncMessage);
mm.addMessageListener("cpows:done", recvDoneMessage);
mm.addMessageListener("cpows:fail", recvFailMessage);
mm.addMessageListener("cpows:parent_test", recvParentTest);
mm.addMessageListener("cpows:error_reporting_test", recvErrorReportingTest);
mm.addMessageListener("cpows:dom_test", recvDomTest);
mm.addMessageListener("cpows:dom_test_after_gc", recvDomTestAfterGC);
mm.addMessageListener("cpows:xray_test", recvXrayTest);
if (typeof Symbol === "function") {
mm.addMessageListener("cpows:symbol_test", recvSymbolTest);
}
mm.addMessageListener("cpows:compartment_test", recvCompartmentTest);
mm.addMessageListener("cpows:regexp_test", recvRegExpTest);
mm.addMessageListener("cpows:postmessage_test", recvPostMessageTest);
mm.addMessageListener("cpows:lifetime_test_1", recvLifetimeTest1);
mm.addMessageListener("cpows:lifetime_test_2", recvLifetimeTest2);
mm.addMessageListener("cpows:cancel_test", recvCancelTest);
mm.addMessageListener("cpows:cancel_sync_message", recvCancelSyncMessage);
mm.addMessageListener("cpows:cancel_test2", recvCancelTest2);
mm.addMessageListener("cpows:unsafe", recvUnsafe);
mm.addMessageListener("cpows:safe", recvSafe);
mm.addMessageListener("cpows:dead", recvDead);
mm.addMessageListener("cpows:localStorage", recvLocalStorage);
mm.loadFrameScript("chrome://mochitests/content/chrome/dom/base/test/chrome/cpows_child.js", true);
}
async function start() {
const {BrowserTestUtils} = ChromeUtils.import("resource://testing-common/BrowserTestUtils.jsm");
let browser = document.getElementById("cpowbrowser_remote");
BrowserTestUtils.loadURI(browser, "http://mochi.test:8888/tests/dom/base/test/chrome/cpows_child.html");
await BrowserTestUtils.browserLoaded(browser);
run_tests('remote');
}
function finish() {
ok(gReceivedErrorProbe, "Should have reported error probe");
opener.setTimeout(function() { this.done(); }, 0);
window.close();
}
]]></script>
<browser type="content" src="about:blank" id="cpowbrowser_remote" remote="true"/>
<browser type="content" src="about:blank" id="cpowbrowser_inprocess"/>
</window>

View File

@ -1,32 +0,0 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
type="text/css"?>
<window title="Test CPOWs"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<!-- test results are displayed in the html:body -->
<body xmlns="http://www.w3.org/1999/xhtml">
</body>
<!-- test code goes here -->
<script type="application/javascript"><![CDATA[
SimpleTest.waitForExplicitFinish();
const PREF_UNSAFE_FORBIDDEN = "dom.ipc.cpows.forbid-unsafe-from-browser";
SpecialPowers.setBoolPref(PREF_UNSAFE_FORBIDDEN, false);
SimpleTest.registerCleanupFunction(() => {
SpecialPowers.clearUserPref(PREF_UNSAFE_FORBIDDEN);
});
function done() {
SimpleTest.finish();
}
addLoadEvent(function() {
window.open("cpows_parent.xul", "", "chrome");
});
]]></script>
</window>

View File

@ -99,8 +99,7 @@ Test swapFrameLoaders with different frame types and remoteness
add_task(async function() {
await SpecialPowers.pushPrefEnv(
{ "set": [["dom.mozBrowserFramesEnabled", true],
["network.disable.ipc.security", true]] });
{ "set": [["network.disable.ipc.security", true]] });
});
add_task(async function() {
@ -221,35 +220,6 @@ Test swapFrameLoaders with different frame types and remoteness
is(pongB, "A", "Frame B message manager acquired after swap gets reply A after swap");
}
// Verify browser API frame scripts destroyed if swapped out of browser frame
if (frameA.hasAttribute("mozbrowser") != frameB.hasAttribute("mozbrowser")) {
let mmA = frameA.frameLoader.messageManager;
let mmB = frameB.frameLoader.messageManager;
let inflightA = once(mmA, "check-browser-api");
let inflightB = once(mmB, "check-browser-api");
info("Check browser API for frame A");
mmA.sendAsyncMessage("check-browser-api");
let [ { data: apiA } ] = await inflightA;
if (frameA.hasAttribute("mozbrowser")) {
ok(apiA.exists && apiA.running, "Frame A browser API exists and is running");
} else {
ok(apiA.exists && !apiA.running, "Frame A browser API did exist but is now destroyed");
}
info("Check browser API for frame B");
mmB.sendAsyncMessage("check-browser-api");
let [ { data: apiB } ] = await inflightB;
if (frameB.hasAttribute("mozbrowser")) {
ok(apiB.exists && apiB.running, "Frame B browser API exists and is running");
} else {
ok(apiB.exists && !apiB.running, "Frame B browser API did exist but is now destroyed");
}
} else {
info("Frames have matching mozbrowser state, skipping browser API destruction check");
}
frameA.remove();
frameB.remove();
}

View File

@ -450,12 +450,9 @@ async function testCopyPaste(isXHTML) {
var val = "1\n 2\n 3";
textarea.value = val;
textarea.select();
await SimpleTest.promiseClipboardChange(
() => true,
() => {
textarea.editor.copy();
}
);
await SimpleTest.promiseClipboardChange(textarea.value, () => {
textarea.editor.copy();
});
textarea.value = "";
textarea.editor.paste(1);
is(textarea.value, val);

View File

@ -2,13 +2,6 @@
<html>
<head>
<script>
// Uncomment this definition of SimpleTest (and comment out the one below) to
// debug in mozBrowser mode.
/*
var SimpleTest = { ok: function(c, m) { dump(m + ": " + c + "\n"); },
info: function(m) { dump(m + "\n"); },
finish: function() { dump("Test done\n");} };
*/
var SimpleTest = parent.SimpleTest;
var ok = SimpleTest.ok;

View File

@ -214,7 +214,6 @@ support-files =
file_bug1250148.sjs
file_bug1268962.sjs
iframe_meta_refresh.sjs
mozbrowser_api_utils.js
!/dom/security/test/cors/file_CrossSiteXHR_server.sjs
!/image/test/mochitest/blue.png
script_bug1238440.js
@ -711,7 +710,6 @@ skip-if = (verify && (os == 'win' || os == 'mac'))
skip-if = !e10s # Track Bug 1281415
[test_link_preload.html]
[test_link_stylesheet.html]
[test_messagemanager_targetchain.html]
[test_meta_refresh_referrer.html]
[test_meta_viewport0.html]
[test_meta_viewport1.html]
@ -757,7 +755,6 @@ skip-if = !e10s # Track Bug 1281415
[test_meta_viewport_tiny_display_size.html]
[test_meta_viewport_initial_scale_with_trailing_characters.html]
[test_meta_viewport_width_with_trailing_characters.html]
[test_mozbrowser_apis_blocked.html]
[test_mozMatchesSelector.html]
[test_mutationobserver_anonymous.html]
[test_mutationobservers.html]

View File

@ -1,53 +0,0 @@
const FRAME_URL = "http://example.org/";
const METHODS = {
sendMouseEvent: {},
goBack: {},
goForward: {},
reload: {},
stop: {},
getCanGoBack: {},
getCanGoForward: {},
};
const ATTRIBUTES = [];
function once(target, eventName, useCapture = false) {
info(
"Waiting for event: '" + JSON.stringify(eventName) + "' on " + target + "."
);
return new Promise(resolve => {
for (let [add, remove] of [
["addEventListener", "removeEventListener"],
["addMessageListener", "removeMessageListener"],
]) {
if (add in target && remove in target) {
eventName.forEach(evName => {
target[add](
evName,
function onEvent(...aArgs) {
info("Got event: '" + evName + "' on " + target + ".");
target[remove](evName, onEvent, useCapture);
resolve(aArgs);
},
useCapture
);
});
break;
}
}
});
}
async function loadFrame(attributes = {}) {
let iframe = document.createElement("iframe");
iframe.setAttribute("src", FRAME_URL);
for (let key in attributes) {
iframe.setAttribute(key, attributes[key]);
}
let loaded = once(iframe, ["load", "mozbrowserloadend"]);
document.body.appendChild(iframe);
await loaded;
return iframe;
}

View File

@ -11,25 +11,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1022229
<script type="application/javascript">
/** Test for postMessage between sandboxed iframe and non-sandboxed window.
This test is particularly interesting on b2g where we're in a mozBrowser.
We set the test up with an extra iframe so that we can easily run it in
an artificial mozbrowser for desktop builds.
**/
SimpleTest.waitForExplicitFinish();
function go() {
var ifr = document.createElement('iframe');
/* Uncomment this chunk to run in a mozBrowser. Make sure to uncomment the
chunk in iframe_main as well. */
/*
SpecialPowers.Services.prefs.setBoolPref("dom.mozBrowserFramesEnabled", true);
SpecialPowers.Services.prefs.setBoolPref("network.disable.ipc.security", true);
SpecialPowers.Services.prefs.setBoolPref("dom.ipc.browser_frames.oop_by_default", false);
SpecialPowers.addPermission("browser", true, document);
SpecialPowers.wrap(ifr).mozbrowser = true;
*/
ifr.setAttribute('src', 'iframe_main_bug1022229.html');
document.body.appendChild(ifr);
}

View File

@ -1,88 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for Principal in MessageManager</title>
<script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
</head>
<body>
<script type="application/javascript">
"use strict";
var permManager = Cc["@mozilla.org/permissionmanager;1"]
.getService(Ci.nsIPermissionManager);
SimpleTest.waitForExplicitFinish();
const childFrameURL =
"data:text/html,<!DOCTYPE HTML><html><body></body></html>";
function childFrameScript() {
"use strict";
addMessageListener("test:ipcMessage", function(message) {
sendAsyncMessage(message.name, "principal: " + (message.principal ? "OK" : "KO"));
sendAsyncMessage(message.name, "principal.origin: " +
("origin" in message.principal ? "OK" : "KO"));
sendAsyncMessage(message.name, "principal.isInIsolatedMozBrowserElement: " +
("isInIsolatedMozBrowserElement" in message.principal ? "OK" : "KO"));
sendAsyncMessage(message.name, "DONE");
});
}
function runTests() {
ok("Browser prefs set.");
let iframe = document.createElement("iframe");
SpecialPowers.wrap(iframe).mozbrowser = true;
iframe.id = "iframe";
iframe.src = childFrameURL;
iframe.addEventListener("mozbrowserloadend", function() {
ok(true, "Got iframe load event.");
let mm = SpecialPowers.getBrowserFrameMessageManager(iframe);
mm.addMessageListener("test:ipcMessage", function(message) {
// We need to wrap to access message.json, and unwrap to do the
// identity check.
var msg = SpecialPowers.unwrap(SpecialPowers.wrap(message).json);
if (/OK$/.exec(msg)) {
ok(true, msg);
} else if(/KO$/.exec(msg)) {
ok(true, false);
} else if (/DONE/.exec(msg)) {
permManager.removeFromPrincipal(window.document.nodePrincipal, "browser",
Ci.nsIPermissionManager.ALLOW_ACTION);
SimpleTest.finish();
}
});
mm.loadFrameScript("data:,(" + childFrameScript.toString() + ")();",
false);
mm.sendAsyncMessage("test:ipcMessage", 42, null, window.document.nodePrincipal);
});
document.body.appendChild(iframe);
}
addEventListener("load", function() {
info("Got load event.");
permManager.addFromPrincipal(window.document.nodePrincipal, "browser",
Ci.nsIPermissionManager.ALLOW_ACTION);
SpecialPowers.pushPrefEnv({
"set": [
["dom.mozBrowserFramesEnabled", true],
["network.disable.ipc.security", true],
["browser.pagethumbnails.capturing_disabled", true]
]
}, runTests);
});
</script>
</body>
</html>

View File

@ -28,9 +28,6 @@
sendAsyncMessage("test:result", "principal.origin: " +
("origin" in message.data ? "OK" : "KO"));
sendAsyncMessage("test:result", "principal.isInIsolatedMozBrowserElement: " +
("isInIsolatedMozBrowserElement" in message.data ? "OK" : "KO"));
});
addMessageListener("test:system", function(message) {
@ -58,18 +55,19 @@
function runTests() {
ok("Browser prefs set.");
let iframe = document.createElement("iframe");
SpecialPowers.wrap(iframe).mozbrowser = true;
let iframe = document.createXULElement("browser");
iframe.setAttribute("type", "content");
iframe.setAttribute("forcemessagemanager", "true");
iframe.id = "iframe";
iframe.src = childFrameURL;
let sb = new Cu.Sandbox(['http://foo.example.com', 'http://bar.example.com']);
let ep = Cu.getObjectPrincipal(sb);
iframe.addEventListener("mozbrowserloadend", function() {
iframe.addEventListener("load", function() {
ok(true, "Got iframe load event.");
let mm = SpecialPowers.getBrowserFrameMessageManager(iframe);
let mm = iframe.messageManager;
mm.addMessageListener("test:result", function(message) {
// We need to wrap to access message.json, and unwrap to do the
// identity check.
@ -79,8 +77,6 @@
} else if(/KO$/.exec(msg)) {
ok(true, false);
} else if (/DONE/.exec(msg)) {
permManager.removeFromPrincipal(window.document.nodePrincipal, "browser",
Ci.nsIPermissionManager.ALLOW_ACTION);
SimpleTest.finish();
}
});
@ -106,13 +102,8 @@
addEventListener("load", function() {
info("Got load event.");
permManager.addFromPrincipal(window.document.nodePrincipal, "browser",
Ci.nsIPermissionManager.ALLOW_ACTION);
SpecialPowers.pushPrefEnv({
"set": [
["dom.mozBrowserFramesEnabled", true],
["network.disable.ipc.security", true],
["browser.pagethumbnails.capturing_disabled", true]
]
}, runTests);

View File

@ -1,121 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for EventTarget chain of MessageManagers</title>
<script src="/tests/SimpleTest/SimpleTest.js">
</script>
<script src="/tests/SimpleTest/EventUtils.js">
</script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<script type="application/javascript">
"use strict";
SimpleTest.waitForExplicitFinish();
const browserFrameURL = "file_empty.html";
const contentFrameURL =
"data:text/html,<!DOCTYPE HTML><html><body><button id=\"target\">target</button></body></html>";
function frameScript() {
"use strict";
addEventListener("test-event", function (e) {
sendSyncMessage("test-event");
}, true);
}
function runTests() {
// messageIndex is incremented for each message/event received
let messageIndex = 0;
let iframe = document.createElement("iframe");
iframe.setAttribute("mozbrowser", true);
iframe.setAttribute("src", browserFrameURL);
iframe.addEventListener("mozbrowserloadend", function () {
info("First iframe loaded");
// First message manager
let mm = SpecialPowers.getBrowserFrameMessageManager(iframe);
mm.addMessageListener("test-event", function onEvent(message) {
is(messageIndex, 0,
"first mm should be the first one to receive the test event");
messageIndex++;
});
mm.loadFrameScript("data:,(" + frameScript.toString() + ")();", false);
// Document in the middle
let doc1 = SpecialPowers.wrap(iframe).contentDocument;
doc1.addEventListener("test-event", function (e) {
ok(false, "content document shouldn't receive test event from child");
}, true);
let iframe2 = doc1.createElement("iframe");
iframe2.setAttribute("mozbrowser", true);
iframe2.setAttribute("src", browserFrameURL);
iframe2.addEventListener("mozbrowserloadend", function () {
info("Second iframe loaded");
// Second message manager
let mm2 = SpecialPowers.getBrowserFrameMessageManager(iframe2);
mm2.addMessageListener("test-event", function onEvent(message) {
is(messageIndex, 1,
"second mm should be the second one to receive the test event");
messageIndex++;
});
mm2.loadFrameScript("data:,(" + frameScript.toString() +")();", false);
// Third is the regular iframe
let doc2 = SpecialPowers.wrap(iframe2).contentDocument;
let iframe3 = doc2.createElement("iframe");
iframe3.setAttribute("src", contentFrameURL);
iframe3.addEventListener("load", function (e) {
info("Third iframe loaded");
let doc3 = SpecialPowers.wrap(iframe3).contentDocument;
let target = doc3.getElementById("target");
target.addEventListener("test-event", function onEvent() {
is(messageIndex, 2,
"target should be the last one to receive the test event");
messageIndex++;
SimpleTest.finish();
});
// Fire test event after load
SimpleTest.executeSoon(function () {
var event = new Event("test-event");
SpecialPowers.dispatchEvent(iframe3.contentWindow, target, event);
});
});
doc2.body.appendChild(iframe3);
});
doc1.body.appendChild(iframe2);
});
document.addEventListener("test-event", function (e) {
ok(false, "top document shouldn't receive test event from child");
}, true);
document.body.appendChild(iframe);
}
addEventListener("load", function() {
var principal = SpecialPowers.wrap(document).nodePrincipal;
SpecialPowers.pushPermissions([
{ type: "browser", allow: 1, context: { url: principal.URI.spec,
originAttributes: {}}},
{ type: "browser", allow: 1, context: { url: principal.URI.spec,
originAttributes: {
inIsolatedMozBrowser: true }}}
], () => {
SpecialPowers.pushPrefEnv({
set: [
["dom.mozBrowserFramesEnabled", true],
["network.disable.ipc.security", true],
["dom.ipc.browser_frames.oop_by_default", false],
]
}, runTests);
});
});
</script>
</body>
</html>

View File

@ -1,42 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Verify mozbrowser APIs are allowed with browser permission</title>
<script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="mozbrowser_api_utils.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
</head>
<body>
<script type="application/javascript">
add_task(async function() {
await SpecialPowers.pushPrefEnv(
{ "set": [["dom.mozBrowserFramesEnabled", true],
["network.disable.ipc.security", true]] });
});
add_task(async function() {
// Create <iframe mozbrowser>
let frame = await loadFrame({
mozbrowser: "true",
// FIXME: Bug 1270790
remote: true
});
// Verify that mozbrowser APIs are accessible
for (let method in METHODS) {
let { alwaysFails } = METHODS[method];
if (alwaysFails) {
ok(!(method in frame), `frame does not have method ${method}, ` +
`needs more permissions`);
} else {
ok(method in frame, `frame has method ${method}`);
}
}
for (let attribute of ATTRIBUTES) {
ok(attribute in frame, `frame has attribute ${attribute}`);
}
});
</script>
</body>
</html>

View File

@ -1,34 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Verify mozbrowser APIs are blocked without browser permission</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="mozbrowser_api_utils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<script type="application/javascript">
add_task(async function() {
await SpecialPowers.pushPrefEnv(
{ "set": [["dom.mozBrowserFramesEnabled", true],
["network.disable.ipc.security", true]] });
});
add_task(async function() {
// Create <iframe mozbrowser>
let frame = await loadFrame({
mozbrowser: "true"
});
// Verify that mozbrowser APIs are not accessible
for (let method in METHODS) {
ok(!(method in frame), `frame does not have method ${method}`);
}
for (let attribute of ATTRIBUTES) {
ok(!(attribute in frame), `frame does not have attribute ${attribute}`);
}
});
</script>
</body>
</html>

View File

@ -10,8 +10,6 @@ const nsIProperties = I.nsIProperties;
const nsIFileInputStream = I.nsIFileInputStream;
const nsIInputStream = I.nsIInputStream;
Cu.importGlobalProperties(["DOMParser", "Element", "Node", "XMLSerializer"]);
function getParser() {
var parser = new DOMParser();
parser.forceEnableXULXBL();

View File

@ -2,8 +2,6 @@
* 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/. */
Cu.importGlobalProperties(["NodeFilter"]);
function run_test() {
/*
* NOTE: [i] is not allowed in this test, since it's done via classinfo and

View File

@ -2,8 +2,6 @@
* 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/. */
Cu.importGlobalProperties(["NodeFilter"]);
const UNORDERED_TYPE = 8; // XPathResult.ANY_UNORDERED_NODE_TYPE
/**

View File

@ -2,8 +2,6 @@
* 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/. */
Cu.importGlobalProperties(["NodeFilter"]);
function run_test() {
test_treeWalker_currentNode();
}

View File

@ -2,8 +2,6 @@
* 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/. */
Cu.importGlobalProperties(["DOMParser"]);
var { HttpServer } = ChromeUtils.import("resource://testing-common/httpd.js");
var server = new HttpServer();

View File

@ -70,7 +70,6 @@
#include "mozilla/dom/XrayExpandoClass.h"
#include "mozilla/dom/WindowProxyHolder.h"
#include "mozilla/Encoding.h"
#include "mozilla/jsipc/CrossProcessObjectWrappers.h"
#include "ipc/ErrorIPCUtils.h"
#include "mozilla/dom/DocGroup.h"
#include "nsXULElement.h"
@ -777,7 +776,7 @@ static JSObject* CreateConstructor(JSContext* cx, JS::Handle<JSObject*> global,
JSObject* constructor = JS_GetFunctionObject(fun);
js::SetFunctionNativeReserved(
constructor, CONSTRUCTOR_NATIVE_HOLDER_RESERVED_SLOT,
js::PrivateValue(const_cast<JSNativeHolder*>(nativeHolder)));
JS::PrivateValue(const_cast<JSNativeHolder*>(nativeHolder)));
return constructor;
}
@ -2531,16 +2530,6 @@ bool InterfaceHasInstance(JSContext* cx, unsigned argc, JS::Value* vp) {
return true;
}
if (jsipc::IsWrappedCPOW(instance)) {
bool boolp = false;
if (!jsipc::DOMInstanceOf(cx, js::UncheckedUnwrap(instance),
clasp->mPrototypeID, clasp->mDepth, &boolp)) {
return false;
}
args.rval().setBoolean(boolp);
return true;
}
return CallOrdinaryHasInstance(cx, args);
}
@ -2751,7 +2740,7 @@ bool NormalizeUSVString(binding_detail::FakeString<char16_t>& aString) {
}
char16_t* ptr = aString.BeginWriting();
auto span = MakeSpan(ptr, len);
auto span = Span(ptr, len);
span[upTo] = 0xFFFD;
EnsureUtf16ValiditySpan(span.From(upTo + 1));
return true;
@ -3435,6 +3424,16 @@ bool CreateGlobalOptionsWithXPConnect::PostCreateGlobal(
return true;
}
uint64_t GetWindowID(void* aGlobal) { return 0; }
uint64_t GetWindowID(nsGlobalWindowInner* aGlobal) {
return aGlobal->WindowID();
}
uint64_t GetWindowID(DedicatedWorkerGlobalScope* aGlobal) {
return aGlobal->WindowID();
}
#ifdef DEBUG
void AssertReturnTypeMatchesJitinfo(const JSJitInfo* aJitInfo,
JS::Handle<JS::Value> aValue) {

View File

@ -56,6 +56,7 @@ namespace mozilla {
namespace dom {
class CustomElementReactionsStack;
class MessageManagerGlobal;
class DedicatedWorkerGlobalScope;
template <typename KeyType, typename ValueType>
class Record;
class WindowProxyHolder;
@ -609,16 +610,12 @@ struct VerifyTraceProtoAndIfaceCacheCalledTracer : public JS::CallbackTracer {
bool ok;
explicit VerifyTraceProtoAndIfaceCacheCalledTracer(JSContext* cx)
: JS::CallbackTracer(cx), ok(false) {}
: JS::CallbackTracer(cx, JS::TracerKind::VerifyTraceProtoAndIface),
ok(false) {}
bool onChild(const JS::GCCellPtr&) override {
void onChild(const JS::GCCellPtr&) override {
// We don't do anything here, we only want to verify that
// TraceProtoAndIfaceCache was called.
return true;
}
TracerKind getTracerKind() const override {
return TracerKind::VerifyTraceProtoAndIface;
}
};
#endif
@ -627,9 +624,7 @@ inline void TraceProtoAndIfaceCache(JSTracer* trc, JSObject* obj) {
MOZ_ASSERT(JS::GetClass(obj)->flags & JSCLASS_DOM_GLOBAL);
#ifdef DEBUG
if (trc->isCallbackTracer() &&
(trc->asCallbackTracer()->getTracerKind() ==
JS::CallbackTracer::TracerKind::VerifyTraceProtoAndIface)) {
if (trc->kind() == JS::TracerKind::VerifyTraceProtoAndIface) {
// We don't do anything here, we only want to verify that
// TraceProtoAndIfaceCache was called.
static_cast<VerifyTraceProtoAndIfaceCacheCalledTracer*>(trc)->ok = true;
@ -2823,7 +2818,8 @@ struct CreateGlobalOptionsWithXPConnect {
template <class T>
using IsGlobalWithXPConnect =
IntegralConstant<bool, std::is_base_of<nsGlobalWindowInner, T>::value ||
std::integral_constant<bool,
std::is_base_of<nsGlobalWindowInner, T>::value ||
std::is_base_of<MessageManagerGlobal, T>::value>;
template <class T>
@ -2842,6 +2838,10 @@ struct CreateGlobalOptions<nsGlobalWindowInner>
ProtoAndIfaceCache::WindowLike;
};
uint64_t GetWindowID(void* aGlobal);
uint64_t GetWindowID(nsGlobalWindowInner* aGlobal);
uint64_t GetWindowID(DedicatedWorkerGlobalScope* aGlobal);
// The return value is true if we created and successfully performed our part of
// the setup for the global, false otherwise.
//
@ -2854,7 +2854,9 @@ bool CreateGlobal(JSContext* aCx, T* aNative, nsWrapperCache* aCache,
const JSClass* aClass, JS::RealmOptions& aOptions,
JSPrincipals* aPrincipal, bool aInitStandardClasses,
JS::MutableHandle<JSObject*> aGlobal) {
aOptions.creationOptions().setTrace(CreateGlobalOptions<T>::TraceGlobal);
aOptions.creationOptions()
.setTrace(CreateGlobalOptions<T>::TraceGlobal)
.setProfilerRealmID(GetWindowID(aNative));
xpc::SetPrefableRealmOptions(aOptions);
aGlobal.set(JS_NewGlobalObject(aCx, aClass, aPrincipal,

View File

@ -468,10 +468,6 @@ DOMInterfaces = {
'wrapperCache': False,
},
'MediaKeys' : {
'implicitJSContext': [ 'createSession']
},
'MediaStream': {
'headerFile': 'DOMMediaStream.h',
'nativeType': 'mozilla::DOMMediaStream'

View File

@ -10446,10 +10446,10 @@ class CGEnum(CGThing):
static_assert(static_cast<size_t>(${name}::EndGuard_) == Count,
"Mismatch between enum value and enum count");
inline Span<const char> GetString(${name} stringId) {
inline auto GetString(${name} stringId) {
MOZ_ASSERT(static_cast<${type}>(stringId) < Count);
const EnumEntry& entry = ${entry_array}[static_cast<${type}>(stringId)];
return MakeSpan(entry.value, entry.length);
return Span<const char>{entry.value, entry.length};
}
""",
entry_array=ENUM_ENTRY_VARIABLE_NAME,

View File

@ -77,11 +77,14 @@ struct FakeString {
operator mozilla::Span<const char_type>() const {
MOZ_ASSERT(mDataInitialized);
return mozilla::MakeSpan(mData, Length());
// Explicitly specify template argument here to avoid instantiating
// Span<char_type> first and then implicitly converting to Span<const
// char_type>
return mozilla::Span<const char_type>{mData, Length()};
}
operator mozilla::Span<char_type>() {
return mozilla::MakeSpan(BeginWriting(), Length());
return mozilla::Span{BeginWriting(), Length()};
}
mozilla::BulkWriteHandle<CharT> BulkWrite(size_type aCapacity,

View File

@ -22,6 +22,15 @@ namespace {
BroadcastChannelService* sInstance = nullptr;
ClonedMessageData CloneClonedMessageData(const ClonedMessageData& aOther) {
auto cloneData = SerializedStructuredCloneBuffer{};
cloneData.data.initScope(aOther.data().data.scope());
const bool res = cloneData.data.Append(aOther.data().data);
MOZ_RELEASE_ASSERT(res, "out of memory");
return {std::move(cloneData), aOther.blobs(), aOther.inputStreams(),
aOther.identifiers()};
}
} // namespace
BroadcastChannelService::BroadcastChannelService() {
@ -125,7 +134,7 @@ void BroadcastChannelService::PostMessage(BroadcastChannelParent* aParent,
}
// We need to have a copy of the data for this parent.
MessageData newData(aData);
MessageData newData = CloneClonedMessageData(aData);
MOZ_ASSERT(newData.type() == aData.type());
if (!blobImpls.IsEmpty()) {

View File

@ -10,7 +10,6 @@ include protocol PParentToChildStream; // FIXME: bug 792908
include DOMTypes;
using struct mozilla::SerializedStructuredCloneBuffer from "ipc/IPCMessageUtils.h";
using struct nsID from "nsID.h";
namespace mozilla {

View File

@ -1,8 +0,0 @@
"use strict";
module.exports = {
"extends": [
"plugin:mozilla/chrome-test",
"plugin:mozilla/mochitest-test",
],
};

View File

@ -1,76 +0,0 @@
/* 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/. */
/*
* This is an approximate implementation of ES7's async-await pattern.
* see: https://github.com/tc39/ecmascript-asyncawait
*
* It allows for simple creation of async function and "tasks".
*
* For example:
*
* var myThinger = {
* doAsynThing: async(function*(url){
* var result = yield fetch(url);
* return process(result);
* });
* }
*
* And Task-like things can be created as follows:
*
* var myTask = async(function*{
* var result = yield fetch(url);
* return result;
* });
* //returns a promise
*
* myTask().then(doSomethingElse);
*
*/
(function(exports) {
"use strict";
function async(func, self) {
return function asyncFunction() {
const functionArgs = Array.from(arguments);
return new Promise(function(resolve, reject) {
var gen;
if (typeof func !== "function") {
reject(new TypeError("Expected a Function."));
}
// not a generator, wrap it.
if (func.constructor.name !== "GeneratorFunction") {
gen = (function*() {
return func.apply(self, functionArgs);
})();
} else {
gen = func.apply(self, functionArgs);
}
try {
step(gen.next(undefined));
} catch (err) {
reject(err);
}
function step({ value, done }) {
if (done) {
return resolve(value);
}
if (value instanceof Promise) {
return value
.then(
result => step(gen.next(result)),
error => {
step(gen.throw(error));
}
)
.catch(err => reject(err));
}
return step(gen.next(value));
}
});
};
}
exports.async = async;
})(this || self);

View File

@ -1,300 +0,0 @@
/* Any copyright is dedicated to the public domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Helpers for managing the browser frame preferences.
"use strict";
function _getPath() {
if (window.location.protocol == "chrome:") {
return "/chrome/dom/browser-element/mochitest";
}
return window.location.pathname
.substring(0, window.location.pathname.lastIndexOf("/"))
.replace("/priority", "");
}
const browserElementTestHelpers = {
_getBoolPref(pref) {
try {
return SpecialPowers.getBoolPref(pref);
} catch (e) {
return undefined;
}
},
_setPref(pref, value) {
this.lockTestReady();
if (value !== undefined && value !== null) {
SpecialPowers.pushPrefEnv(
{ set: [[pref, value]] },
this.unlockTestReady.bind(this)
);
} else {
SpecialPowers.pushPrefEnv(
{ clear: [[pref]] },
this.unlockTestReady.bind(this)
);
}
},
_setPrefs() {
this.lockTestReady();
SpecialPowers.pushPrefEnv(
{ set: Array.from(arguments) },
this.unlockTestReady.bind(this)
);
},
_testReadyLockCount: 0,
_firedTestReady: false,
lockTestReady() {
this._testReadyLockCount++;
},
unlockTestReady() {
this._testReadyLockCount--;
if (this._testReadyLockCount == 0 && !this._firedTestReady) {
this._firedTestReady = true;
dispatchEvent(new Event("testready"));
}
},
enableProcessPriorityManager() {
this._setPrefs(
["dom.ipc.processPriorityManager.testMode", true],
["dom.ipc.processPriorityManager.enabled", true]
);
},
setClipboardPlainTextOnlyPref(value) {
this._setPref("clipboard.plainTextOnly", value);
},
setEnabledPref(value) {
this._setPrefs(
["dom.mozBrowserFramesEnabled", value],
["network.disable.ipc.security", value]
);
},
setupAccessibleCaretPref() {
this._setPref("layout.accessiblecaret.enabled", true);
// Disable hide carets for mouse input for select-all tests so that we can
// get mozbrowsercaretstatechanged events.
this._setPref("layout.accessiblecaret.hide_carets_for_mouse_input", false);
},
getOOPByDefaultPref() {
return this._getBoolPref("dom.ipc.browser_frames.oop_by_default");
},
addPermission() {
this.lockTestReady();
SpecialPowers.pushPermissions(
[{ type: "browser", allow: 1, context: document }],
this.unlockTestReady.bind(this)
);
},
allowTopLevelDataURINavigation() {
this._setPref(
"security.data_uri.block_toplevel_data_uri_navigations",
false
);
},
_observers: [],
// This function is a wrapper which lets you register an observer to one of
// the process priority manager's test-only topics. observerFn should be a
// function which takes (subject, topic, data).
//
// We'll clean up any observers you add at the end of the test.
addProcessPriorityObserver(processPriorityTopic, observerFn) {
var topic = "process-priority-manager:TEST-ONLY:" + processPriorityTopic;
// SpecialPowers appears to require that the observer be an object, not a
// function.
var observer = {
observe: observerFn,
};
SpecialPowers.addObserver(observer, topic);
this._observers.push([observer, topic]);
},
cleanUp() {
for (var i = 0; i < this._observers.length; i++) {
SpecialPowers.removeObserver(
this._observers[i][0],
this._observers[i][1]
);
}
},
// Some basically-empty pages from different domains you can load.
emptyPage1: "http://example.com" + _getPath() + "/file_empty.html",
fileEmptyPage1: "file_empty.html",
emptyPage2: "http://example.org" + _getPath() + "/file_empty.html",
emptyPage3: "http://test1.example.org" + _getPath() + "/file_empty.html",
focusPage: "http://example.org" + _getPath() + "/file_focus.html",
};
// Returns a promise which is resolved when a subprocess is created. The
// argument to resolve() is the childID of the subprocess.
function expectProcessCreated(/* optional */ initialPriority) {
return new Promise(function(resolve, reject) {
var observed = false;
browserElementTestHelpers.addProcessPriorityObserver(
"process-created",
function(subject, topic, data) {
// Don't run this observer twice, so we don't ok(true) twice. (It's fine
// to resolve a promise twice; the second resolve() call does nothing.)
if (observed) {
return;
}
observed = true;
var childID = parseInt(data);
ok(true, "Got new process, id=" + childID);
if (initialPriority) {
expectPriorityChange(childID, initialPriority).then(function() {
resolve(childID);
});
} else {
resolve(childID);
}
}
);
});
}
// Just like expectProcessCreated(), except we'll call ok(false) if a second
// process is created.
function expectOnlyOneProcessCreated(/* optional */ initialPriority) {
var p = expectProcessCreated(initialPriority);
p.then(function() {
expectProcessCreated().then(function(childID) {
ok(false, "Got unexpected process creation, childID=" + childID);
});
});
return p;
}
// Returns a promise which is resolved or rejected the next time the process
// childID changes its priority. We resolve if the priority matches
// expectedPriority, and we reject otherwise.
function expectPriorityChange(childID, expectedPriority) {
return new Promise(function(resolve, reject) {
var observed = false;
browserElementTestHelpers.addProcessPriorityObserver(
"process-priority-set",
function(subject, topic, data) {
if (observed) {
return;
}
var [id, priority] = data.split(":");
if (id != childID) {
return;
}
// Make sure we run the is() calls in this observer only once, otherwise
// we'll expect /every/ priority change to match expectedPriority.
observed = true;
is(
priority,
expectedPriority,
"Expected priority of childID " +
childID +
" to change to " +
expectedPriority
);
if (priority == expectedPriority) {
resolve();
} else {
reject();
}
}
);
});
}
// Returns a promise which is resolved the first time the given iframe fires
// the mozbrowser##eventName event.
function expectMozbrowserEvent(iframe, eventName) {
return new Promise(function(resolve, reject) {
iframe.addEventListener("mozbrowser" + eventName, function handler(e) {
iframe.removeEventListener("mozbrowser" + eventName, handler);
resolve(e);
});
});
}
// Set some prefs:
//
// * browser.pagethumbnails.capturing_disabled: true
//
// Disable tab view; it seriously messes us up.
//
// * dom.ipc.browser_frames.oop_by_default
//
// Enable or disable OOP-by-default depending on the test's filename. You
// can still force OOP on or off with <iframe mozbrowser remote=true/false>,
// at least until bug 756376 lands.
//
// * dom.ipc.tabs.disabled: false
//
// Allow us to create OOP frames. Even if they're not the default, some
// "in-process" tests create OOP frames.
//
// * network.disable.ipc.security: true
//
// Disable the networking security checks; our test harness just tests
// browser elements without sticking them in apps, and the security checks
// dislike that.
//
// Unfortunately setting network.disable.ipc.security to false before the
// child process(es) created by this test have shut down can cause us to
// assert and kill the child process. That doesn't cause the tests to fail,
// but it's still scary looking. So we just set the pref to true and never
// pop that value. We'll rely on the tests which test IPC security to set
// it to false.
//
// * security.mixed_content.block_active_content: false
//
// Disable mixed active content blocking, so that tests can confirm that mixed
// content results in a broken security state.
(function() {
var oop = !location.pathname.includes("_inproc_");
browserElementTestHelpers.lockTestReady();
SpecialPowers.setBoolPref("network.disable.ipc.security", true);
SpecialPowers.pushPrefEnv(
{
set: [
["browser.pagethumbnails.capturing_disabled", true],
["dom.ipc.browser_frames.oop_by_default", oop],
["dom.ipc.tabs.disabled", false],
["security.mixed_content.block_active_content", false],
],
},
browserElementTestHelpers.unlockTestReady.bind(browserElementTestHelpers)
);
})();
addEventListener("unload", function() {
browserElementTestHelpers.cleanUp();
});
// Wait for the load event before unlocking the test-ready event.
browserElementTestHelpers.lockTestReady();
addEventListener("load", function() {
SimpleTest.executeSoon(
browserElementTestHelpers.unlockTestReady.bind(browserElementTestHelpers)
);
});

View File

@ -1,326 +0,0 @@
/* Any copyright is dedicated to the public domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Test that alert works.
"use strict";
/* global browserElementTestHelpers */
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
var numPendingChildTests = 0;
var iframe;
var mm;
function runTest() {
iframe = document.createElement("iframe");
iframe.setAttribute("mozbrowser", "true");
document.body.appendChild(iframe);
mm = SpecialPowers.getBrowserFrameMessageManager(iframe);
mm.addMessageListener("test-success", function(msg) {
numPendingChildTests--;
ok(true, SpecialPowers.wrap(msg).json);
});
mm.addMessageListener("test-fail", function(msg) {
numPendingChildTests--;
ok(false, SpecialPowers.wrap(msg).json);
});
// Wait for the initial load to finish, then navigate the page, then wait
// for that load to finish, then start test1.
iframe.addEventListener(
"mozbrowserloadend",
function() {
iframe.src = browserElementTestHelpers.emptyPage1;
iframe.addEventListener(
"mozbrowserloadend",
function() {
SimpleTest.executeSoon(test1);
},
{ once: true }
);
},
{ once: true }
);
}
function test1() {
iframe.addEventListener("mozbrowsershowmodalprompt", test2);
// Do window.alert within the iframe, then modify the global |testState|
// after the alert.
var script =
'data:,\
this.testState = 0; \
content.alert("Hello, world!"); \
this.testState = 1; \
';
mm.loadFrameScript(script, /* allowDelayedLoad = */ false);
// Triggers a mozbrowsershowmodalprompt event, which sends us down to test2.
}
// test2 is a mozbrowsershowmodalprompt listener.
function test2(e) {
iframe.removeEventListener("mozbrowsershowmodalprompt", test2);
is(e.detail.message, "Hello, world!");
e.preventDefault(); // cause the alert to block.
SimpleTest.executeSoon(function() {
test2a(e);
});
}
function test2a(e) {
// The iframe should be blocked on the alert call at the moment, so testState
// should still be 0.
var script =
'data:,\
if (this.testState === 0) { \
sendAsyncMessage("test-success", "1: Correct testState"); \
} \
else { \
sendAsyncMessage("test-fail", "1: Wrong testState: " + this.testState); \
}';
mm.loadFrameScript(script, /* allowDelayedLoad = */ false);
numPendingChildTests++;
waitForPendingTests(function() {
test3(e);
});
}
function test3(e) {
// Now unblock the iframe and check that the script completed.
e.detail.unblock();
var script2 =
'data:,\
if (this.testState === 1) { \
sendAsyncMessage("test-success", "2: Correct testState"); \
} \
else { \
sendAsyncMessage("test-try-again", "2: Wrong testState (for now): " + this.testState); \
}';
// Urgh. e.unblock() didn't necessarily unblock us immediately, so we have
// to spin and wait.
function onTryAgain() {
SimpleTest.executeSoon(function() {
// dump('onTryAgain\n');
mm.loadFrameScript(script2, /* allowDelayedLoad = */ false);
});
}
mm.addMessageListener("test-try-again", onTryAgain);
numPendingChildTests++;
onTryAgain();
waitForPendingTests(function() {
mm.removeMessageListener("test-try-again", onTryAgain);
test4();
});
}
function test4() {
// Navigate the iframe while an alert is pending. This shouldn't screw
// things up.
iframe.addEventListener("mozbrowsershowmodalprompt", test5);
var script = 'data:,content.alert("test4");';
mm.loadFrameScript(script, /* allowDelayedLoad = */ false);
}
// test4 is a mozbrowsershowmodalprompt listener.
function test5(e) {
iframe.removeEventListener("mozbrowsershowmodalprompt", test5);
is(e.detail.message, "test4");
e.preventDefault(); // cause the page to block.
SimpleTest.executeSoon(test5a);
}
function test5a() {
iframe.addEventListener("mozbrowserloadend", test5b);
iframe.src = browserElementTestHelpers.emptyPage2;
}
function test5b() {
iframe.removeEventListener("mozbrowserloadend", test5b);
SimpleTest.executeSoon(test6);
}
// Test nested alerts
var promptBlockers = [];
function test6() {
iframe.addEventListener("mozbrowsershowmodalprompt", test6a);
var script =
"data:,\
this.testState = 0; \
content.alert(1); \
this.testState = 3; \
";
mm.loadFrameScript(script, /* allowDelayedLoad = */ false);
}
function test6a(e) {
iframe.removeEventListener("mozbrowsershowmodalprompt", test6a);
is(e.detail.message, "1");
e.preventDefault(); // cause the alert to block.
promptBlockers.push(e);
SimpleTest.executeSoon(test6b);
}
function test6b() {
var script =
'data:,\
if (this.testState === 0) { \
sendAsyncMessage("test-success", "1: Correct testState"); \
} \
else { \
sendAsyncMessage("test-fail", "1: Wrong testState: " + this.testState); \
}';
mm.loadFrameScript(script, /* allowDelayedLoad = */ false);
numPendingChildTests++;
waitForPendingTests(test6c);
}
function test6c() {
iframe.addEventListener("mozbrowsershowmodalprompt", test6d);
var script =
"data:,\
this.testState = 1; \
content.alert(2); \
this.testState = 2; \
";
mm.loadFrameScript(script, /* allowDelayedLoad = */ false);
}
function test6d(e) {
iframe.removeEventListener("mozbrowsershowmodalprompt", test6d);
is(e.detail.message, "2");
e.preventDefault(); // cause the alert to block.
promptBlockers.push(e);
SimpleTest.executeSoon(test6e);
}
function test6e() {
var script =
'data:,\
if (this.testState === 1) { \
sendAsyncMessage("test-success", "2: Correct testState"); \
} \
else { \
sendAsyncMessage("test-fail", "2: Wrong testState: " + this.testState); \
}';
mm.loadFrameScript(script, /* allowDelayedLoad = */ false);
numPendingChildTests++;
waitForPendingTests(test6f);
}
function test6f() {
var e = promptBlockers.pop();
// Now unblock the iframe and check that the script completed.
e.detail.unblock();
var script2 =
'data:,\
if (this.testState === 2) { \
sendAsyncMessage("test-success", "3: Correct testState"); \
} \
else { \
sendAsyncMessage("test-try-again", "3: Wrong testState (for now): " + this.testState); \
}';
// Urgh. e.unblock() didn't necessarily unblock us immediately, so we have
// to spin and wait.
function onTryAgain() {
SimpleTest.executeSoon(function() {
// dump('onTryAgain\n');
mm.loadFrameScript(script2, /* allowDelayedLoad = */ false);
});
}
mm.addMessageListener("test-try-again", onTryAgain);
numPendingChildTests++;
onTryAgain();
waitForPendingTests(function() {
mm.removeMessageListener("test-try-again", onTryAgain);
test6g();
});
}
function test6g() {
var e = promptBlockers.pop();
// Now unblock the iframe and check that the script completed.
e.detail.unblock();
var script2 =
'data:,\
if (this.testState === 3) { \
sendAsyncMessage("test-success", "4: Correct testState"); \
} \
else { \
sendAsyncMessage("test-try-again", "4: Wrong testState (for now): " + this.testState); \
}';
// Urgh. e.unblock() didn't necessarily unblock us immediately, so we have
// to spin and wait.
function onTryAgain() {
SimpleTest.executeSoon(function() {
// dump('onTryAgain\n');
mm.loadFrameScript(script2, /* allowDelayedLoad = */ false);
});
}
mm.addMessageListener("test-try-again", onTryAgain);
numPendingChildTests++;
onTryAgain();
waitForPendingTests(function() {
mm.removeMessageListener("test-try-again", onTryAgain);
test6h();
});
}
function test6h() {
SimpleTest.finish();
}
var prevNumPendingTests = null;
function waitForPendingTests(next) {
if (numPendingChildTests !== prevNumPendingTests) {
dump("Waiting for end; " + numPendingChildTests + " pending tests\n");
prevNumPendingTests = numPendingChildTests;
}
if (numPendingChildTests > 0) {
SimpleTest.executeSoon(function() {
waitForPendingTests(next);
});
return;
}
prevNumPendingTests = null;
next();
}
addEventListener("testready", runTest);

View File

@ -1,26 +0,0 @@
/* Any copyright is dedicated to the public domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Test that alert works from inside an <iframe> inside an <iframe mozbrowser>.
"use strict";
/* global browserElementTestHelpers */
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
function runTest() {
var iframe = document.createElement("iframe");
iframe.setAttribute("mozbrowser", "true");
iframe.addEventListener("mozbrowsershowmodalprompt", function(e) {
is(e.detail.message, "Hello");
SimpleTest.finish();
});
iframe.src = "file_browserElement_AlertInFrame.html";
document.body.appendChild(iframe);
}
addEventListener("testready", runTest);

View File

@ -1,378 +0,0 @@
/* Any copyright is dedicated to the public domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Test that auth prompt works.
"use strict";
/* global browserElementTestHelpers */
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
const { NetUtil } = SpecialPowers.Cu.import(
"resource://gre/modules/NetUtil.jsm"
);
function testFail(msg) {
ok(false, JSON.stringify(msg));
}
var iframe;
function runTest() {
iframe = document.createElement("iframe");
iframe.setAttribute("mozbrowser", "true");
document.body.appendChild(iframe);
// Wait for the initial load to finish, then navigate the page, then start test
// by loading SJS with http 401 response.
iframe.addEventListener(
"mozbrowserloadend",
function() {
iframe.addEventListener(
"mozbrowserusernameandpasswordrequired",
testHttpAuthCancel
);
SimpleTest.executeSoon(function() {
// Use absolute path because we need to specify host.
iframe.src =
"http://test/tests/dom/browser-element/mochitest/file_http_401_response.sjs";
});
},
{ once: true }
);
}
function testHttpAuthCancel(e) {
iframe.removeEventListener(
"mozbrowserusernameandpasswordrequired",
testHttpAuthCancel
);
// Will cancel authentication, but prompt should not be shown again. Instead,
// we will be led to fail message
iframe.addEventListener("mozbrowserusernameandpasswordrequired", testFail);
iframe.addEventListener(
"mozbrowsertitlechange",
function(f) {
iframe.removeEventListener(
"mozbrowserusernameandpasswordrequired",
testFail
);
is(f.detail, "http auth failed", "expected authentication to fail");
iframe.addEventListener(
"mozbrowserusernameandpasswordrequired",
testHttpAuth
);
SimpleTest.executeSoon(function() {
// Use absolute path because we need to specify host.
iframe.src =
"http://test/tests/dom/browser-element/mochitest/file_http_401_response.sjs";
});
},
{ once: true }
);
is(e.detail.realm, "http_realm", "expected realm matches");
is(e.detail.host, "http://test", "expected host matches");
is(
e.detail.path,
"/tests/dom/browser-element/mochitest/file_http_401_response.sjs",
"expected path matches"
);
e.preventDefault();
SimpleTest.executeSoon(function() {
e.detail.cancel();
});
}
function testHttpAuth(e) {
iframe.removeEventListener(
"mozbrowserusernameandpasswordrequired",
testHttpAuth
);
// Will authenticate with correct password, prompt should not be
// called again.
iframe.addEventListener("mozbrowserusernameandpasswordrequired", testFail);
iframe.addEventListener(
"mozbrowsertitlechange",
function(f) {
iframe.removeEventListener(
"mozbrowserusernameandpasswordrequired",
testFail
);
is(f.detail, "http auth success", "expect authentication to succeed");
SimpleTest.executeSoon(testProxyAuth);
},
{ once: true }
);
is(e.detail.realm, "http_realm", "expected realm matches");
is(e.detail.host, "http://test", "expected host matches");
is(
e.detail.path,
"/tests/dom/browser-element/mochitest/file_http_401_response.sjs",
"expected path matches"
);
is(e.detail.isProxy, false, "expected isProxy is false");
e.preventDefault();
SimpleTest.executeSoon(function() {
e.detail.authenticate("httpuser", "httppass");
});
}
function testProxyAuth() {
// The testingSJS simulates the 407 proxy authentication required response
// for proxy server, which will trigger the browser element to send prompt
// event with proxy infomation.
var testingSJS =
"http://test/tests/dom/browser-element/mochitest/file_http_407_response.sjs";
var mozproxy;
function onUserNameAndPasswordRequired(e) {
iframe.removeEventListener(
"mozbrowserusernameandpasswordrequired",
onUserNameAndPasswordRequired
);
iframe.addEventListener(
"mozbrowsertitlechange",
function(event) {
iframe.removeEventListener(
"mozbrowserusernameandpasswordrequired",
testFail
);
is(
event.detail,
"http auth success",
"expect authentication to succeed"
);
SimpleTest.executeSoon(testAuthJarNoInterfere);
},
{ once: true }
);
is(e.detail.realm, "http_realm", "expected realm matches");
is(e.detail.host, mozproxy, "expected host matches");
is(
e.detail.path,
"/tests/dom/browser-element/mochitest/file_http_407_response.sjs",
"expected path matches"
);
is(e.detail.isProxy, true, "expected isProxy is true");
e.preventDefault();
SimpleTest.executeSoon(function() {
e.detail.authenticate("proxyuser", "proxypass");
});
}
// Resolve proxy information used by the test suite, we need it to validate
// whether the proxy information delivered with the prompt event is correct.
var resolveCallback = SpecialPowers.wrapCallbackObject({
// eslint-disable-next-line mozilla/use-chromeutils-generateqi
QueryInterface(iid) {
const interfaces = [Ci.nsIProtocolProxyCallback, Ci.nsISupports];
if (
!interfaces.some(function(v) {
return iid.equals(v);
})
) {
throw SpecialPowers.Cr.NS_ERROR_NO_INTERFACE;
}
return this;
},
onProxyAvailable(req, channel, pi, status) {
isnot(pi, null, "expected proxy information available");
if (pi) {
mozproxy = "moz-proxy://" + pi.host + ":" + pi.port;
}
iframe.addEventListener(
"mozbrowserusernameandpasswordrequired",
onUserNameAndPasswordRequired
);
iframe.src = testingSJS;
},
});
var channel = NetUtil.newChannel({
uri: testingSJS,
loadUsingSystemPrincipal: true,
});
var pps = SpecialPowers.Cc[
"@mozilla.org/network/protocol-proxy-service;1"
].getService();
pps.asyncResolve(channel, 0, resolveCallback);
}
function testAuthJarNoInterfere(e) {
let authMgr = SpecialPowers.Cc[
"@mozilla.org/network/http-auth-manager;1"
].getService(SpecialPowers.Ci.nsIHttpAuthManager);
let secMan = SpecialPowers.Services.scriptSecurityManager;
let ioService = SpecialPowers.Services.io;
var uri = ioService.newURI(
"http://test/tests/dom/browser-element/mochitest/file_http_401_response.sjs"
);
// Set a bunch of auth data that should not conflict with the correct auth data already
// stored in the cache.
var attrs = { userContextId: 1 };
var principal = secMan.createCodebasePrincipal(uri, attrs);
authMgr.setAuthIdentity(
"http",
"test",
-1,
"basic",
"http_realm",
"tests/dom/browser-element/mochitest/file_http_401_response.sjs",
"",
"httpuser",
"wrongpass",
false,
principal
);
attrs = { userContextId: 1, inIsolatedMozBrowser: true };
principal = secMan.createCodebasePrincipal(uri, attrs);
authMgr.setAuthIdentity(
"http",
"test",
-1,
"basic",
"http_realm",
"tests/dom/browser-element/mochitest/file_http_401_response.sjs",
"",
"httpuser",
"wrongpass",
false,
principal
);
principal = secMan.createCodebasePrincipal(uri, {});
authMgr.setAuthIdentity(
"http",
"test",
-1,
"basic",
"http_realm",
"tests/dom/browser-element/mochitest/file_http_401_response.sjs",
"",
"httpuser",
"wrongpass",
false,
principal
);
// Will authenticate with correct password, prompt should not be
// called again.
iframe.addEventListener("mozbrowserusernameandpasswordrequired", testFail);
iframe.addEventListener(
"mozbrowsertitlechange",
function(f) {
iframe.removeEventListener(
"mozbrowserusernameandpasswordrequired",
testFail
);
is(f.detail, "http auth success", "expected authentication success");
SimpleTest.executeSoon(testAuthJarInterfere);
},
{ once: true }
);
// Once more with feeling. Ensure that our new auth data doesn't interfere with this mozbrowser's
// auth data.
iframe.src =
"http://test/tests/dom/browser-element/mochitest/file_http_401_response.sjs";
}
function testAuthJarInterfere(e) {
let authMgr = SpecialPowers.Cc[
"@mozilla.org/network/http-auth-manager;1"
].getService(SpecialPowers.Ci.nsIHttpAuthManager);
let secMan = SpecialPowers.Services.scriptSecurityManager;
let ioService = SpecialPowers.Services.io;
var uri = ioService.newURI(
"http://test/tests/dom/browser-element/mochitest/file_http_401_response.sjs"
);
// Set some auth data that should overwrite the successful stored details.
var principal = secMan.createCodebasePrincipal(uri, {
inIsolatedMozBrowser: true,
});
authMgr.setAuthIdentity(
"http",
"test",
-1,
"basic",
"http_realm",
"tests/dom/browser-element/mochitest/file_http_401_response.sjs",
"",
"httpuser",
"wrongpass",
false,
principal
);
// Will authenticate with correct password, prompt should not be
// called again.
var gotusernamepasswordrequired = false;
function onUserNameAndPasswordRequired() {
gotusernamepasswordrequired = true;
}
iframe.addEventListener(
"mozbrowserusernameandpasswordrequired",
onUserNameAndPasswordRequired
);
iframe.addEventListener(
"mozbrowsertitlechange",
function(f) {
iframe.removeEventListener(
"mozbrowserusernameandpasswordrequired",
onUserNameAndPasswordRequired
);
ok(
gotusernamepasswordrequired,
"Should have dispatched mozbrowserusernameandpasswordrequired event"
);
testFinish();
},
{ once: true }
);
// Once more with feeling. Ensure that our new auth data interferes with this mozbrowser's
// auth data.
iframe.src =
"http://test/tests/dom/browser-element/mochitest/file_http_401_response.sjs";
}
function testFinish() {
// Clear login information stored in password manager.
let authMgr = SpecialPowers.Cc[
"@mozilla.org/network/http-auth-manager;1"
].getService(SpecialPowers.Ci.nsIHttpAuthManager);
authMgr.clearAll();
SpecialPowers.Services.logins.removeAllLogins();
SimpleTest.finish();
}
addEventListener("testready", function() {
// Enable http authentiication.
SpecialPowers.pushPrefEnv(
{
set: [
[
"network.auth.non-web-content-triggered-resources-http-auth-allow",
true,
],
],
},
runTest
);
});

View File

@ -1,115 +0,0 @@
/* Any copyright is dedicated to the public domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Bug 741755 - Test that canGo{Back,Forward} and go{Forward,Back} work with
// <iframe mozbrowser>.
"use strict";
/* global browserElementTestHelpers */
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
var iframe;
function addOneShotIframeEventListener(event, fn) {
function wrapper(e) {
iframe.removeEventListener(event, wrapper);
fn(e);
}
iframe.addEventListener(event, wrapper);
}
function runTest() {
iframe = document.createElement("iframe");
iframe.setAttribute("mozbrowser", "true");
addOneShotIframeEventListener("mozbrowserloadend", function() {
SimpleTest.executeSoon(test2);
});
iframe.src = browserElementTestHelpers.emptyPage1;
document.body.appendChild(iframe);
}
function checkCanGoBackAndForward(canGoBack, canGoForward, nextTest) {
var seenCanGoBackResult = false;
iframe.getCanGoBack().then(function(result) {
is(
seenCanGoBackResult,
false,
"onsuccess handler shouldn't be called twice."
);
seenCanGoBackResult = true;
is(result, canGoBack);
maybeRunNextTest();
});
var seenCanGoForwardResult = false;
iframe.getCanGoForward().then(function(result) {
is(
seenCanGoForwardResult,
false,
"onsuccess handler shouldn't be called twice."
);
seenCanGoForwardResult = true;
is(result, canGoForward);
maybeRunNextTest();
});
function maybeRunNextTest() {
if (seenCanGoBackResult && seenCanGoForwardResult) {
nextTest();
}
}
}
function test2() {
checkCanGoBackAndForward(false, false, test3);
}
function test3() {
addOneShotIframeEventListener("mozbrowserloadend", function() {
checkCanGoBackAndForward(true, false, test4);
});
SimpleTest.executeSoon(function() {
iframe.src = browserElementTestHelpers.emptyPage2;
});
}
function test4() {
addOneShotIframeEventListener("mozbrowserlocationchange", function(e) {
is(e.detail.url, browserElementTestHelpers.emptyPage3);
is(e.detail.canGoBack, true);
is(e.detail.canGoForward, false);
checkCanGoBackAndForward(true, false, test5);
});
SimpleTest.executeSoon(function() {
iframe.src = browserElementTestHelpers.emptyPage3;
});
}
function test5() {
addOneShotIframeEventListener("mozbrowserlocationchange", function(e) {
is(e.detail.url, browserElementTestHelpers.emptyPage2);
is(e.detail.canGoBack, true);
is(e.detail.canGoForward, true);
checkCanGoBackAndForward(true, true, test6);
});
iframe.goBack();
}
function test6() {
addOneShotIframeEventListener("mozbrowserlocationchange", function(e) {
is(e.detail.url, browserElementTestHelpers.emptyPage1);
is(e.detail.canGoBack, false);
is(e.detail.canGoForward, true);
checkCanGoBackAndForward(false, true, SimpleTest.finish);
});
iframe.goBack();
}
addEventListener("testready", runTest);

View File

@ -1,60 +0,0 @@
/* Any copyright is dedicated to the public domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Bug 780351 - Test that mozbrowser does /not/ divide the window name namespace.
// Multiple mozbrowsers inside the same app are like multiple browser tabs;
// they share a window name namespace.
"use strict";
/* global browserElementTestHelpers */
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
function runTest() {
var iframe1 = document.createElement("iframe");
iframe1.setAttribute("mozbrowser", "true");
// Two mozbrowser frames with the same code both do the same
// window.open("foo", "bar") call. We should only get one
// mozbrowseropenwindow event.
iframe1.addEventListener("mozbrowseropenwindow", function(e) {
ok(true, "Got first mozbrowseropenwindow event.");
document.body.appendChild(e.detail.frameElement);
e.detail.frameElement.addEventListener("mozbrowserlocationchange", function(
f
) {
if (f.detail.url == "http://example.com/#2") {
ok(true, "Got locationchange to http://example.com/#2");
SimpleTest.finish();
} else {
ok(true, "Got locationchange to " + f.detail.url);
}
});
SimpleTest.executeSoon(function() {
var iframe2 = document.createElement("iframe");
// Make sure that iframe1 and iframe2 are in the same TabGroup by linking
// them through opener. Right now this API requires chrome privileges, as
// it is on MozFrameLoaderOwner.
SpecialPowers.wrap(iframe2).presetOpenerWindow(iframe1.contentWindow);
iframe2.setAttribute("mozbrowser", "true");
iframe2.addEventListener("mozbrowseropenwindow", function(f) {
ok(false, "Got second mozbrowseropenwindow event.");
});
document.body.appendChild(iframe2);
iframe2.src = "file_browserElement_BrowserWindowNamespace.html#2";
});
});
document.body.appendChild(iframe1);
iframe1.src = "file_browserElement_BrowserWindowNamespace.html#1";
}
addEventListener("testready", runTest);

View File

@ -1,56 +0,0 @@
/* Any copyright is dedicated to the public domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Bug 891763 - Test the mozbrowserresize event
"use strict";
/* global browserElementTestHelpers */
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
browserElementTestHelpers.allowTopLevelDataURINavigation();
function runTest() {
var srcResizeTo =
"data:text/html, \
<script type='application/javascript'> \
window.resizeTo(300, 300); \
</script> \
";
var srcResizeBy =
"data:text/html, \
<script type='application/javascript'> \
window.resizeBy(-100, -100); \
</script> \
";
var count = 0;
function checkSize(iframe) {
count++;
is(iframe.clientWidth, 400, "iframe width does not change");
is(iframe.clientHeight, 400, "iframe height does not change");
if (count == 2) {
SimpleTest.finish();
}
}
function testIFrameWithSrc(src) {
var iframe = document.createElement("iframe");
iframe.setAttribute("mozbrowser", "true");
iframe.style = "border:none; width:400px; height:400px;";
iframe.src = src;
iframe.addEventListener("mozbrowserresize", function(e) {
is(e.detail.width, 300, "Received correct resize event width");
is(e.detail.height, 300, "Received correct resize event height");
SimpleTest.executeSoon(checkSize.bind(undefined, iframe));
});
document.body.appendChild(iframe);
}
testIFrameWithSrc(srcResizeTo);
testIFrameWithSrc(srcResizeBy);
}
addEventListener("testready", runTest);

View File

@ -1,28 +0,0 @@
/* Any copyright is dedicated to the public domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Test that window.close() works.
"use strict";
/* global browserElementTestHelpers */
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
browserElementTestHelpers.allowTopLevelDataURINavigation();
function runTest() {
var iframe = document.createElement("iframe");
iframe.setAttribute("mozbrowser", "true");
document.body.appendChild(iframe);
iframe.addEventListener("mozbrowserclose", function(e) {
ok(true, "got mozbrowserclose event.");
SimpleTest.finish();
});
iframe.src =
"data:text/html,<html><body><script>window.close()</script></body></html>";
}
addEventListener("testready", runTest);

View File

@ -1,34 +0,0 @@
/* Any copyright is dedicated to the public domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Bug 764718 - Test that window.close() works from the opener window.
"use strict";
/* global browserElementTestHelpers */
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
function runTest() {
var iframe = document.createElement("iframe");
iframe.setAttribute("mozbrowser", "true");
iframe.addEventListener("mozbrowseropenwindow", function(e) {
ok(true, "got openwindow event.");
document.body.appendChild(e.detail.frameElement);
e.detail.frameElement.addEventListener("mozbrowserclose", function(f) {
ok(true, "got mozbrowserclose event.");
SimpleTest.finish();
});
});
document.body.appendChild(iframe);
// file_browserElement_CloseFromOpener opens a new window and then calls
// close() on it.
iframe.src = "file_browserElement_CloseFromOpener.html";
}
addEventListener("testready", runTest);

View File

@ -1,474 +0,0 @@
"use strict";
/* global browserElementTestHelpers */
/* eslint-env mozilla/frame-script */
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.setClipboardPlainTextOnlyPref(false);
browserElementTestHelpers.addPermission();
browserElementTestHelpers.allowTopLevelDataURINavigation();
var audioUrl =
"http://mochi.test:8888/tests/dom/browser-element/mochitest/audio.ogg";
var videoUrl =
"http://mochi.test:8888/tests/dom/browser-element/mochitest/short-video.ogv";
function runTests() {
createIframe(function onIframeLoaded() {
checkEmptyContextMenu();
});
}
function checkEmptyContextMenu() {
sendContextMenuTo("body", function onContextMenu(detail) {
is(detail.contextmenu, null, "Body context clicks have no context menu");
checkInnerContextMenu();
});
}
function checkInnerContextMenu() {
sendContextMenuTo("#inner-link", function onContextMenu(detail) {
is(detail.systemTargets.length, 1, "Includes anchor data");
is(
detail.contextmenu.items.length,
3,
"Inner clicks trigger correct customized menu"
);
is(
detail.contextmenu.items[0].label,
"foo",
'Customized menu has a "foo" menu item'
);
is(
detail.contextmenu.items[1].label,
"bar",
'Customized menu has a "bar" menu item'
);
is(
detail.contextmenu.items[2].id,
"copy-link",
"#inner-link has a copy-link menu item"
);
is(
detail.contextmenu.customized,
true,
"Make sure contextmenu has customized items"
);
var target = detail.systemTargets[0];
is(target.nodeName, "A", "Reports correct nodeName");
is(target.data.uri, "foo.html", "Reports correct uri");
is(target.data.text, "Menu 1", "Reports correct link text");
checkCustomContextMenu();
});
}
function checkCustomContextMenu() {
sendContextMenuTo("#menu1-trigger", function onContextMenu(detail) {
is(detail.contextmenu.items.length, 2, "trigger custom contextmenu");
checkNestedContextMenu();
});
}
function checkNestedContextMenu() {
sendContextMenuTo("#menu2-trigger", function onContextMenu(detail) {
var innerMenu = detail.contextmenu.items.filter(function(x) {
return x.type === "menu";
});
is(detail.systemTargets.length, 2, "Includes two systemTargets");
is(detail.systemTargets[0].nodeName, "IMG", 'Includes "IMG" node');
is(
detail.systemTargets[0].data.uri,
"example.png",
"Img data has the correct uri"
);
is(detail.systemTargets[1].nodeName, "A", 'Includes "A" node');
is(
detail.systemTargets[1].data.uri,
"bar.html",
"Anchor has the correct uri"
);
ok(innerMenu.length > 0, "Menu contains a nested menu");
is(detail.contextmenu.items.length, 4, "We have correct # of menu items");
is(
detail.contextmenu.customized,
true,
"Make sure contextmenu has customized items"
);
is(
detail.contextmenu.items[0].label,
"outer",
'Customized menu has an "outer" menu item'
);
is(
detail.contextmenu.items[1].label,
"submenu",
'Customized menu has an "submenu" menu item'
);
is(
detail.contextmenu.items[2].id,
"copy-link",
"Has a copy-link menu item"
);
is(
detail.contextmenu.items[3].id,
"copy-image",
"Has a copy-image menu item"
);
checkPreviousContextMenuHandler();
});
}
// Finished testing the data passed to the contextmenu handler,
// now we start selecting contextmenu items
function checkPreviousContextMenuHandler() {
// This is previously triggered contextmenu data, since we have
// fired subsequent contextmenus this should not be mistaken
// for a current menuitem
var detail = previousContextMenuDetail;
var previousId = detail.contextmenu.items[0].id;
checkContextMenuCallbackForId(detail, previousId, function onCallbackFired(
label
) {
is(label, null, "Callback label should be empty since this handler is old");
checkCurrentContextMenuHandler();
});
}
function checkCurrentContextMenuHandler() {
// This triggers a current menuitem
var detail = currentContextMenuDetail;
var innerMenu = detail.contextmenu.items.filter(function(x) {
return x.type === "menu";
});
var currentId = innerMenu[0].items[1].id;
checkContextMenuCallbackForId(detail, currentId, function onCallbackFired(
label
) {
is(label, "inner 2", "Callback label should be set correctly");
checkAgainCurrentContextMenuHandler();
});
}
function checkAgainCurrentContextMenuHandler() {
// Once an item it selected, subsequent selections are ignored
var detail = currentContextMenuDetail;
var innerMenu = detail.contextmenu.items.filter(function(x) {
return x.type === "menu";
});
var currentId = innerMenu[0].items[1].id;
checkContextMenuCallbackForId(detail, currentId, function onCallbackFired(
label
) {
is(
label,
null,
"Callback label should be empty since this handler has already been used"
);
checkCallbackWithPreventDefault();
});
}
// Finished testing callbacks if the embedder calls preventDefault() on the
// mozbrowsercontextmenu event, now we start checking for some cases where the embedder
// does not want to call preventDefault() for some reasons.
function checkCallbackWithPreventDefault() {
sendContextMenuTo("#menu1-trigger", function onContextMenu(detail) {
var id = detail.contextmenu.items[0].id;
checkContextMenuCallbackForId(detail, id, function onCallbackFired(label) {
is(label, "foo", "Callback label should be set correctly");
checkCallbackWithoutPreventDefault();
});
});
}
function checkCallbackWithoutPreventDefault() {
sendContextMenuTo(
"#menu1-trigger",
function onContextMenu(detail) {
var id = detail.contextmenu.items[0].id;
checkContextMenuCallbackForId(detail, id, function onCallbackFired(
label
) {
is(label, null, "Callback label should be null");
checkImageContextMenu();
});
},
/* ignorePreventDefault */ true
);
}
function checkImageContextMenu() {
sendContextMenuTo(
"#menu3-trigger",
function onContextMenu(detail) {
var target = detail.systemTargets[0];
is(target.nodeName, "IMG", "Reports correct nodeName");
is(target.data.uri, "example.png", "Reports correct uri");
is(detail.contextmenu.items.length, 1, "Reports correct # of menu items");
is(
detail.contextmenu.items[0].id,
"copy-image",
"IMG has a copy-image menu item"
);
is(
detail.contextmenu.customized,
false,
"Make sure we do not have customized items"
);
checkVideoContextMenu();
},
/* ignorePreventDefault */ true
);
}
function checkVideoContextMenu() {
sendContextMenuTo(
"#menu4-trigger",
function onContextMenu(detail) {
var target = detail.systemTargets[0];
is(target.nodeName, "VIDEO", "Reports correct nodeName");
is(target.data.uri, videoUrl, "Reports uri correctly in data");
is(target.data.hasVideo, true, 'Video data in video tag does "hasVideo"');
checkAudioContextMenu();
},
/* ignorePreventDefault */ true
);
}
function checkAudioContextMenu() {
sendContextMenuTo(
"#menu6-trigger",
function onContextMenu(detail) {
var target = detail.systemTargets[0];
is(target.nodeName, "AUDIO", "Reports correct nodeName");
is(target.data.uri, audioUrl, "Reports uri correctly in data");
checkAudioinVideoContextMenu();
},
/* ignorePreventDefault */ true
);
}
function checkAudioinVideoContextMenu() {
sendSrcTo("#menu5-trigger", audioUrl, function onSrcSet() {
sendContextMenuTo(
"#menu5-trigger",
function onContextMenu(detail) {
var target = detail.systemTargets[0];
is(target.nodeName, "VIDEO", "Reports correct nodeName");
is(target.data.uri, audioUrl, "Reports uri correctly in data");
is(
target.data.hasVideo,
false,
'Audio data in video tag reports no "hasVideo"'
);
checkFormNoMethod();
},
/* ignorePreventDefault */ true
);
});
}
function checkFormNoMethod() {
sendContextMenuTo(
"#menu7-trigger",
function onContextMenu(detail) {
var target = detail.systemTargets[0];
is(target.nodeName, "INPUT", "Reports correct nodeName");
is(target.data.method, "get", "Reports correct method");
is(target.data.action, "no_method", "Reports correct action url");
is(target.data.name, "input1", "Reports correct input name");
checkFormGetMethod();
},
/* ignorePreventDefault */ true
);
}
function checkFormGetMethod() {
sendContextMenuTo(
"#menu8-trigger",
function onContextMenu(detail) {
var target = detail.systemTargets[0];
is(target.nodeName, "INPUT", "Reports correct nodeName");
is(target.data.method, "get", "Reports correct method");
is(
target.data.action,
"http://example.com/get_method",
"Reports correct action url"
);
is(target.data.name, "input2", "Reports correct input name");
checkFormPostMethod();
},
/* ignorePreventDefault */ true
);
}
function checkFormPostMethod() {
sendContextMenuTo(
"#menu9-trigger",
function onContextMenu(detail) {
var target = detail.systemTargets[0];
is(target.nodeName, "INPUT", "Reports correct nodeName");
is(target.data.method, "post", "Reports correct method");
is(target.data.action, "post_method", "Reports correct action url");
is(target.data.name, "input3", "Reports correct input name");
SimpleTest.finish();
},
/* ignorePreventDefault */ true
);
}
/* Helpers */
var mm = null;
var previousContextMenuDetail = null;
var currentContextMenuDetail = null;
function sendSrcTo(selector, src, callback) {
mm.sendAsyncMessage("setsrc", { selector, src });
mm.addMessageListener("test:srcset", function onSrcSet(msg) {
mm.removeMessageListener("test:srcset", onSrcSet);
callback();
});
}
function sendContextMenuTo(selector, callback, ignorePreventDefault) {
iframe.addEventListener("mozbrowsercontextmenu", function oncontextmenu(e) {
iframe.removeEventListener(e.type, oncontextmenu);
// The embedder should call preventDefault() on the event if it will handle
// it. Not calling preventDefault() means it won't handle the event and
// should not be able to deal with context menu callbacks.
if (ignorePreventDefault !== true) {
e.preventDefault();
}
// Keep a reference to previous/current contextmenu event details.
previousContextMenuDetail = currentContextMenuDetail;
currentContextMenuDetail = e.detail;
setTimeout(function() {
callback(e.detail);
});
});
mm.sendAsyncMessage("contextmenu", { selector });
}
function checkContextMenuCallbackForId(detail, id, callback) {
mm.addMessageListener("test:callbackfired", function onCallbackFired(msg) {
mm.removeMessageListener("test:callbackfired", onCallbackFired);
msg = SpecialPowers.wrap(msg);
setTimeout(function() {
callback(msg.data.label);
});
});
detail.contextMenuItemSelected(id);
}
var iframe = null;
function createIframe(callback) {
iframe = document.createElement("iframe");
iframe.setAttribute("mozbrowser", "true");
iframe.src =
"data:text/html,<html>" +
"<body>" +
'<menu type="context" id="menu1" label="firstmenu">' +
'<menuitem label="foo" onclick="window.onContextMenuCallbackFired(event)"></menuitem>' +
'<menuitem label="bar" onclick="window.onContextMenuCallbackFired(event)"></menuitem>' +
"</menu>" +
'<menu type="context" id="menu2" label="secondmenu">' +
'<menuitem label="outer" onclick="window.onContextMenuCallbackFired(event)"></menuitem>' +
'<menu label="submenu">' +
'<menuitem label="inner 1"></menuitem>' +
'<menuitem label="inner 2" onclick="window.onContextMenuCallbackFired(event)"></menuitem>' +
"</menu>" +
"</menu>" +
'<div id="menu1-trigger" contextmenu="menu1"><a id="inner-link" href="foo.html">Menu 1</a></div>' +
'<a href="bar.html" contextmenu="menu2"><img id="menu2-trigger" src="example.png" /></a>' +
'<img id="menu3-trigger" src="example.png" />' +
'<video id="menu4-trigger" src="' +
videoUrl +
'"></video>' +
'<video id="menu5-trigger" preload="metadata"></video>' +
'<audio id="menu6-trigger" src="' +
audioUrl +
'"></audio>' +
'<form action="no_method"><input id="menu7-trigger" name="input1"></input></form>' +
'<form action="http://example.com/get_method" method="get"><input id="menu8-trigger" name="input2"></input></form>' +
'<form action="post_method" method="post"><input id="menu9-trigger" name="input3"></input></form>' +
"</body></html>";
document.body.appendChild(iframe);
// The following code will be included in the child
// =========================================================================
function iframeScript() {
addMessageListener("contextmenu", function onContextMenu(msg) {
var document = content.document;
var evt = document.createEvent("HTMLEvents");
evt.initEvent("contextmenu", true, true);
document.querySelector(msg.data.selector).dispatchEvent(evt);
});
addMessageListener("setsrc", function onContextMenu(msg) {
var wrappedTarget = content.document.querySelector(msg.data.selector);
var target = XPCNativeWrapper.unwrap(wrappedTarget);
target.addEventListener("loadedmetadata", function() {
sendAsyncMessage("test:srcset");
});
target.src = msg.data.src;
});
addMessageListener("browser-element-api:call", function onCallback(msg) {
if (msg.data.msg_name != "fire-ctx-callback") {
return;
}
/* Use setTimeout in order to react *after* the platform */
content.setTimeout(function() {
sendAsyncMessage("test:callbackfired", { label });
label = null;
});
});
var label = null;
XPCNativeWrapper.unwrap(content).onContextMenuCallbackFired = function(e) {
label = e.target.getAttribute("label");
};
}
// =========================================================================
iframe.addEventListener("mozbrowserloadend", function onload(e) {
iframe.removeEventListener(e.type, onload);
mm = SpecialPowers.getBrowserFrameMessageManager(iframe);
mm.loadFrameScript("data:,(" + iframeScript.toString() + ")();", false);
// Now we're ready, let's start testing.
callback();
});
}
addEventListener("testready", runTests);

View File

@ -1,57 +0,0 @@
/* Any copyright is dedicated to the public domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Bug 806127 - Test that cookies set by <iframe mozbrowser> are not considered
// third-party.
"use strict";
/* global browserElementTestHelpers */
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
function runTest() {
const innerPage =
"http://example.com/tests/dom/browser-element/mochitest/file_browserElement_CookiesNotThirdParty.html";
var iframe = document.createElement("iframe");
iframe.setAttribute("mozbrowser", "true");
iframe.addEventListener("mozbrowsershowmodalprompt", function(e) {
if (e.detail.message == "next") {
iframe.src = innerPage + "?step=2";
return;
}
if (e.detail.message.startsWith("success:")) {
ok(true, e.detail.message);
return;
}
if (e.detail.message.startsWith("failure:")) {
ok(false, e.detail.message);
return;
}
if (e.detail.message == "finish") {
SimpleTest.finish();
}
});
// innerPage will set a cookie and then alert('next'). We'll load
// innerPage?step=2. That page will check that the cooke exists (despite the
// fact that we've disabled third-party cookies) and alert('success:') or
// alert('failure:'), as appropriate. Finally, the page will
// alert('finish');
iframe.src = innerPage;
document.body.appendChild(iframe);
}
// Disable third-party cookies for this test.
addEventListener("testready", function() {
SpecialPowers.pushPrefEnv(
{ set: [["network.cookie.cookieBehavior", 1]] },
runTest
);
});

View File

@ -1,428 +0,0 @@
/* Any copyright is dedicated to the public domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Test that "cut, copy, paste, selectall" and caretstatechanged event works from inside an <iframe mozbrowser>.
"use strict";
/* global browserElementTestHelpers */
SimpleTest.waitForExplicitFinish();
SimpleTest.requestFlakyTimeout("untriaged");
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.setupAccessibleCaretPref();
browserElementTestHelpers.addPermission();
browserElementTestHelpers.allowTopLevelDataURINavigation();
var gTextarea = null;
var mm;
var iframeOuter;
var iframeInner;
var state = 0;
var stateMeaning;
var defaultData;
var pasteData;
var focusScript;
var createEmbededFrame = false;
var testSelectionChange = false;
function copyToClipboard(str, callback) {
gTextarea.value = str;
SpecialPowers.wrap(gTextarea).editor.selectAll();
SimpleTest.waitForClipboard(
() => true,
() => {
SpecialPowers.wrap(gTextarea).editor.copy();
},
callback,
() => {
ok(false, "clipboard copy failed");
}
);
}
function getScriptForGetContent() {
var script =
'data:,\
var elt = content.document.getElementById("text"); \
var txt = ""; \
if (elt) { \
if (elt.tagName === "DIV" || elt.tagName === "BODY") { \
txt = elt.textContent; \
} else { \
txt = elt.value; \
} \
} \
sendAsyncMessage("content-text", txt);';
return script;
}
function getScriptForSetFocus() {
var script = "data:," + focusScript + 'sendAsyncMessage("content-focus")';
return script;
}
function runTest() {
iframeOuter = document.createElement("iframe");
iframeOuter.setAttribute("mozbrowser", "true");
if (createEmbededFrame) {
iframeOuter.src = "file_empty.html";
}
document.body.appendChild(iframeOuter);
gTextarea = document.createElement("textarea");
document.body.appendChild(gTextarea);
iframeOuter.addEventListener(
"mozbrowserloadend",
function(e) {
if (createEmbededFrame) {
var contentWin = SpecialPowers.wrap(iframeOuter).frameLoader.docShell
.contentViewer.DOMDocument.defaultView;
var contentDoc = contentWin.document;
iframeInner = contentDoc.createElement("iframe");
iframeInner.setAttribute("mozbrowser", true);
iframeInner.setAttribute("remote", "false");
contentDoc.body.appendChild(iframeInner);
iframeInner.addEventListener(
"mozbrowserloadend",
function(f) {
mm = SpecialPowers.getBrowserFrameMessageManager(iframeInner);
dispatchTest(f);
},
{ once: true }
);
} else {
iframeInner = iframeOuter;
mm = SpecialPowers.getBrowserFrameMessageManager(iframeInner);
dispatchTest(e);
}
},
{ once: true }
);
}
function doCommand(cmd) {
var COMMAND_MAP = {
cut: "cmd_cut",
copy: "cmd_copy",
paste: "cmd_paste",
selectall: "cmd_selectAll",
};
var script = 'data:,docShell.doCommand("' + COMMAND_MAP[cmd] + '");';
mm.loadFrameScript(script, false);
}
function dispatchTest(e) {
iframeInner.addEventListener(
"mozbrowserloadend",
function(f) {
iframeInner.focus();
SimpleTest.executeSoon(function() {
testSelectAll(f);
});
},
{ once: true }
);
switch (state) {
case 0: // test for textarea
defaultData = "Test for selection change event";
pasteData = "from parent ";
iframeInner.src =
"data:text/html,<html><body>" +
"<textarea id='text'>" +
defaultData +
"</textarea>" +
"</body>" +
"</html>";
stateMeaning = " (test: textarea)";
focusScript =
"var elt=content.document.getElementById('text');elt.focus();elt.select();";
break;
case 1: // test for input text
defaultData = "Test for selection change event";
pasteData = "from parent ";
iframeInner.src =
"data:text/html,<html><body>" +
"<input type='text' id='text' value='" +
defaultData +
"'>" +
"</body>" +
"</html>";
stateMeaning = " (test: <input type=text>)";
focusScript =
"var elt=content.document.getElementById('text');elt.focus();elt.select();";
break;
case 2: // test for input number
defaultData = "12345";
pasteData = "67890";
iframeInner.src =
"data:text/html,<html><body>" +
"<input type='number' id='text' value='" +
defaultData +
"'>" +
"</body>" +
"</html>";
stateMeaning = " (test: <input type=number>)";
focusScript =
"var elt=content.document.getElementById('text');elt.focus();elt.select();";
break;
case 3: // test for div contenteditable
defaultData = "Test for selection change event";
pasteData = "from parent ";
iframeInner.src =
"data:text/html,<html><body>" +
"<div contenteditable='true' id='text'>" +
defaultData +
"</div>" +
"</body>" +
"</html>";
stateMeaning = " (test: content editable div)";
focusScript =
"var elt=content.document.getElementById('text');elt.focus();";
break;
case 4: // test for normal div
defaultData = "Test for selection change event";
pasteData = "from parent ";
iframeInner.src =
"data:text/html,<html><body>" +
"<div id='text'>" +
defaultData +
"</div>" +
"</body>" +
"</html>";
stateMeaning = " (test: normal div)";
focusScript =
"var elt=content.document.getElementById('text');elt.focus();";
break;
case 5: // test for normal div with designMode:on
defaultData = "Test for selection change event";
pasteData = "from parent ";
iframeInner.src =
"data:text/html,<html><body id='text'>" +
defaultData +
"</body>" +
"<script>document.designMode='on';</script>" +
"</html>";
stateMeaning = " (test: normal div with designMode:on)";
focusScript =
"var elt=content.document.getElementById('text');elt.focus();";
break;
default:
if (
createEmbededFrame ||
browserElementTestHelpers.getOOPByDefaultPref()
) {
SimpleTest.finish();
} else {
createEmbededFrame = true;
// clean up and run test again.
document.body.removeChild(iframeOuter);
document.body.removeChild(gTextarea);
state = 0;
runTest();
}
break;
}
}
function isChildProcess() {
return (
SpecialPowers.Services.appinfo.processType !=
SpecialPowers.Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT
);
}
function testSelectAll(e) {
// Skip mozbrowser test if we're at child process.
if (!isChildProcess()) {
let eventName = "mozbrowsercaretstatechanged";
iframeOuter.addEventListener(
eventName,
function(f) {
ok(true, "got mozbrowsercaretstatechanged event." + stateMeaning);
ok(f.detail, "event.detail is not null." + stateMeaning);
ok(
f.detail.width != 0,
"event.detail.width is not zero" + stateMeaning
);
ok(
f.detail.height != 0,
"event.detail.height is not zero" + stateMeaning
);
SimpleTest.executeSoon(function() {
testCopy1(f);
});
},
{ capture: true, once: true }
);
}
mm.addMessageListener("content-focus", function messageforfocus(msg) {
mm.removeMessageListener("content-focus", messageforfocus);
// test selectall command, after calling this the caretstatechanged event should be fired.
doCommand("selectall");
if (isChildProcess()) {
SimpleTest.executeSoon(function() {
testCopy1(e);
});
}
});
mm.loadFrameScript(getScriptForSetFocus(), false);
}
function testCopy1(e) {
// Right now we're at "selectall" state, so we can test copy commnad by
// calling doCommand
copyToClipboard("", () => {
let setup = function() {
doCommand("copy");
};
let nextTest = function(success) {
ok(success, "copy command works" + stateMeaning);
SimpleTest.executeSoon(function() {
testPaste1(e);
});
};
let success = function() {
nextTest(true);
};
let fail = function() {
nextTest(false);
};
let compareData = defaultData;
SimpleTest.waitForClipboard(compareData, setup, success, fail);
});
}
function testPaste1(e) {
// Next test paste command, first we copy to global clipboard in parent side.
// Then paste it to child side.
copyToClipboard(pasteData, () => {
doCommand("selectall");
doCommand("paste");
SimpleTest.executeSoon(function() {
testPaste2(e);
});
});
}
function testPaste2(e) {
mm.addMessageListener("content-text", function messageforpaste(msg) {
mm.removeMessageListener("content-text", messageforpaste);
if (state == 4) {
// normal div cannot paste, so the content remain unchange
ok(
SpecialPowers.wrap(msg).json === defaultData,
"paste command works" + stateMeaning
);
} else if (state == 3 && browserElementTestHelpers.getOOPByDefaultPref()) {
// Something weird when we doCommand with content editable element in OOP. Mark this case as todo
todo(false, "paste command works" + stateMeaning);
} else {
ok(
SpecialPowers.wrap(msg).json === pasteData,
"paste command works" + stateMeaning
);
}
SimpleTest.executeSoon(function() {
testCut1(e);
});
});
mm.loadFrameScript(getScriptForGetContent(), false);
}
function testCut1(e) {
// Clean clipboard first
copyToClipboard("", () => {
let setup = function() {
doCommand("selectall");
doCommand("cut");
};
let nextTest = function(success) {
if (state == 3 && browserElementTestHelpers.getOOPByDefaultPref()) {
// Something weird when we doCommand with content editable element in OOP.
todo(false, "cut function works" + stateMeaning);
} else {
ok(success, "cut function works" + stateMeaning);
}
SimpleTest.executeSoon(function() {
testCut2(e);
});
};
let success = function() {
nextTest(true);
};
let fail = function() {
nextTest(false);
};
let compareData = pasteData;
// Something weird when we doCommand with content editable element in OOP.
// Always true in this case
// Normal div case cannot cut, always true as well.
if (
(state == 3 && browserElementTestHelpers.getOOPByDefaultPref()) ||
state == 4
) {
compareData = function() {
return true;
};
}
SimpleTest.waitForClipboard(compareData, setup, success, fail);
});
}
function testCut2(e) {
mm.addMessageListener("content-text", function messageforcut(msg) {
mm.removeMessageListener("content-text", messageforcut);
// normal div cannot cut
if (state == 4) {
ok(
SpecialPowers.wrap(msg).json !== "",
"cut command works" + stateMeaning
);
} else if (state == 3 && browserElementTestHelpers.getOOPByDefaultPref()) {
// Something weird when we doCommand with content editable element in OOP. Mark this case as todo
todo(false, "cut command works" + stateMeaning);
} else {
ok(
SpecialPowers.wrap(msg).json === "",
"cut command works" + stateMeaning
);
}
state++;
dispatchTest(e);
});
mm.loadFrameScript(getScriptForGetContent(), false);
}
// Give our origin permission to open browsers, and remove it when the test is complete.
var principal = SpecialPowers.wrap(document).nodePrincipal;
var context = {
url: SpecialPowers.wrap(principal.URI).spec,
originAttributes: {
inIsolatedMozBrowser: true,
},
};
addEventListener("testready", function() {
SpecialPowers.pushPermissions(
[{ type: "browser", allow: 1, context }],
runTest
);
});

View File

@ -1,74 +0,0 @@
/* Any copyright is dedicated to the public domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Test that data: URIs work with mozbrowserlocationchange events.
"use strict";
/* global browserElementTestHelpers */
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
browserElementTestHelpers.allowTopLevelDataURINavigation();
function runTest() {
var iframe1 = document.createElement("iframe");
iframe1.setAttribute("mozbrowser", "true");
iframe1.id = "iframe1";
iframe1.addEventListener(
"mozbrowserloadend",
function() {
ok(true, "Got first loadend event.");
SimpleTest.executeSoon(runTest2);
},
{ once: true }
);
iframe1.src = browserElementTestHelpers.emptyPage1;
document.body.appendChild(iframe1);
var iframe2 = document.createElement("iframe");
iframe2.id = "iframe2";
document.body.appendChild(iframe2);
}
function runTest2() {
var iframe1 = document.getElementById("iframe1");
var iframe2 = document.getElementById("iframe2");
var sawLoadEnd = false;
var sawLocationChange = false;
iframe1.addEventListener("mozbrowserlocationchange", function(e) {
ok(e.isTrusted, "Event should be trusted.");
ok(!sawLocationChange, "Just one locationchange event.");
ok(!sawLoadEnd, "locationchange before load.");
is(e.detail.url, "data:text/html,1", "event's reported location");
sawLocationChange = true;
});
iframe1.addEventListener("mozbrowserloadend", function() {
ok(sawLocationChange, "Loadend after locationchange.");
ok(!sawLoadEnd, "Just one loadend event.");
sawLoadEnd = true;
});
function iframe2Load() {
if (!sawLoadEnd || !sawLocationChange) {
// Spin if iframe1 hasn't loaded yet.
SimpleTest.executeSoon(iframe2Load);
return;
}
ok(true, "Got iframe2 load.");
SimpleTest.finish();
}
iframe2.addEventListener("load", iframe2Load);
iframe1.src = "data:text/html,1";
// Load something into iframe2 to check that it doesn't trigger a
// locationchange for our iframe1 listener.
iframe2.src = browserElementTestHelpers.emptyPage2;
}
addEventListener("testready", runTest);

View File

@ -1,5 +0,0 @@
<html>
<body>
foo
</body>
</html>

View File

@ -1,72 +0,0 @@
/* Any copyright is dedicated to the public domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/* global browserElementTestHelpers */
SimpleTest.waitForExplicitFinish();
SimpleTest.requestFlakyTimeout(
"testing mozbrowser data: navigation is blocked"
);
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
// make sure top level data: URI navigations are blocked.
const PREF = "security.data_uri.block_toplevel_data_uri_navigations";
browserElementTestHelpers._setPref(PREF, true);
const INNER = "foo";
const DATA_URI = "data:text/html,<html><body>" + INNER + "</body></html>";
const HTTP_URI = "browserElement_DataURILoad.html";
function runTest1() {
let frame = document.createElement("iframe");
frame.setAttribute("mozbrowser", "true");
frame.src = DATA_URI;
document.body.appendChild(frame);
let wrappedFrame = SpecialPowers.wrap(frame);
// wait for 1000ms and check that the data: URI did not load
setTimeout(function() {
isnot(
wrappedFrame.contentWindow.document.body.innerHTML,
INNER,
"data: URI navigation should be blocked"
);
runTest2();
}, 1000);
}
function runTest2() {
let frame = document.createElement("iframe");
frame.setAttribute("mozbrowser", "true");
frame.src = HTTP_URI;
document.body.appendChild(frame);
let wrappedFrame = SpecialPowers.wrap(frame);
wrappedFrame.addEventListener(
"mozbrowserloadend",
function onloadend(e) {
ok(
wrappedFrame.contentWindow.document.location.href.endsWith(HTTP_URI),
"http: URI navigation should be allowed"
);
frame.src = DATA_URI;
// wait for 1000ms and check that the data: URI did not load
setTimeout(function() {
isnot(
wrappedFrame.contentWindow.document.body.innerHTML,
INNER,
"data: URI navigation should be blocked"
);
SimpleTest.finish();
}, 1000);
},
{ once: true }
);
}
addEventListener("testready", runTest1);

View File

@ -1,77 +0,0 @@
/* Any copyright is dedicated to the public domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Bug 829486 - Add mozdocumentbrowserfirstpaint event.
"use strict";
/* global browserElementTestHelpers */
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
var iframe;
function runTestQueue(queue) {
if (queue.length == 0) {
SimpleTest.finish();
return;
}
var gotFirstPaint = false;
var gotFirstLocationChange = false;
var test = queue.shift();
function runNext() {
iframe.removeEventListener(
"mozbrowserdocumentfirstpaint",
documentfirstpainthandler
);
iframe.removeEventListener("mozbrowserloadend", loadendhandler);
runTestQueue(queue);
}
function documentfirstpainthandler(e) {
ok(!gotFirstPaint, "Got firstpaint only once");
gotFirstPaint = true;
if (gotFirstLocationChange) {
runNext();
}
}
function loadendhandler(e) {
gotFirstLocationChange = true;
if (gotFirstPaint) {
runNext();
}
}
iframe.addEventListener(
"mozbrowserdocumentfirstpaint",
documentfirstpainthandler
);
iframe.addEventListener("mozbrowserloadend", loadendhandler);
test();
}
function testChangeLocation() {
iframe.src = browserElementTestHelpers.emptyPage1 + "?2";
}
function testReload() {
iframe.reload();
}
function testFirstLoad() {
document.body.appendChild(iframe);
iframe.src = browserElementTestHelpers.emptyPage1;
}
function runTest() {
iframe = document.createElement("iframe");
iframe.setAttribute("mozbrowser", "true");
runTestQueue([testFirstLoad, testReload, testChangeLocation]);
}
addEventListener("testready", runTest);

View File

@ -1,74 +0,0 @@
/* Any copyright is dedicated to the public domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Bug 764718 - Test that mozbrowsererror works for a security error.
"use strict";
/* global browserElementTestHelpers */
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
var iframe = null;
function runTest() {
iframe = document.createElement("iframe");
iframe.setAttribute("mozbrowser", "true");
document.body.appendChild(iframe);
checkForDnsError();
}
function checkForDnsError() {
iframe.addEventListener("mozbrowsererror", function onDnsError(e) {
iframe.removeEventListener(e.type, onDnsError);
ok(true, "Got mozbrowsererror event.");
ok(
e.detail.type == "dnsNotFound",
"Event's detail has a |type| param with the value '" +
e.detail.type +
"'."
);
checkForExpiredCertificateError();
});
iframe.src = "http://this_is_not_a_domain.example.com";
}
function checkForExpiredCertificateError() {
iframe.addEventListener("mozbrowsererror", function onCertError(e) {
iframe.removeEventListener(e.type, onCertError);
ok(true, "Got mozbrowsererror event.");
ok(
e.detail.type == "certerror",
"Event's detail has a |type| param with the value '" +
e.detail.type +
"'."
);
checkForNoCertificateError();
});
iframe.src = "https://expired.example.com";
}
function checkForNoCertificateError() {
iframe.addEventListener("mozbrowsererror", function onCertError(e) {
iframe.removeEventListener(e.type, onCertError);
ok(true, "Got mozbrowsererror event.");
ok(
e.detail.type == "certerror",
"Event's detail has a |type| param with the value '" +
e.detail.type +
"'."
);
SimpleTest.finish();
});
iframe.src = "https://nocert.example.com";
}
addEventListener("testready", runTest);

View File

@ -1,45 +0,0 @@
/* Any copyright is dedicated to the public domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Bug 795317: Test that the browser element sanitizes its URIs by removing the
// "unexposable" parts before sending them in the locationchange event.
"use strict";
/* global browserElementTestHelpers */
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
var iframe;
function testPassword() {
function locationchange(e) {
var uri = e.detail.url;
is(
uri,
"http://mochi.test:8888/tests/dom/browser-element/mochitest/file_empty.html",
"Username and password shouldn't be exposed in uri."
);
SimpleTest.finish();
}
iframe.addEventListener("mozbrowserlocationchange", locationchange);
iframe.src =
"http://iamuser:iampassword@mochi.test:8888/tests/dom/browser-element/mochitest/file_empty.html";
}
function runTest() {
SpecialPowers.pushPrefEnv(
{ set: [["network.http.rcwn.enabled", false]] },
_ => {
iframe = document.createElement("iframe");
iframe.setAttribute("mozbrowser", "true");
document.body.appendChild(iframe);
testPassword();
}
);
}
addEventListener("testready", runTest);

View File

@ -1,44 +0,0 @@
/* Any copyright is dedicated to the public domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Bug 787378 - Add mozbrowserfirstpaint event.
"use strict";
/* global browserElementTestHelpers */
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
function runTest() {
var iframe = document.createElement("iframe");
iframe.setAttribute("mozbrowser", "true");
var gotFirstPaint = false;
var gotFirstLocationChange = false;
iframe.addEventListener("mozbrowserfirstpaint", function(e) {
ok(!gotFirstPaint, "Got only one first paint.");
gotFirstPaint = true;
if (gotFirstLocationChange) {
iframe.src = browserElementTestHelpers.emptyPage1 + "?2";
}
});
iframe.addEventListener("mozbrowserlocationchange", function(e) {
if (e.detail.url == browserElementTestHelpers.emptyPage1) {
gotFirstLocationChange = true;
if (gotFirstPaint) {
iframe.src = browserElementTestHelpers.emptyPage1 + "?2";
}
} else if (e.detail.url.endsWith("?2")) {
SimpleTest.finish();
}
});
document.body.appendChild(iframe);
iframe.src = browserElementTestHelpers.emptyPage1;
}
addEventListener("testready", runTest);

View File

@ -1,45 +0,0 @@
/* Any copyright is dedicated to the public domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Bug 781320 - Test that the name in <iframe mozbrowser name="foo"> is
// forwarded down to remote mozbrowsers.
"use strict";
/* global browserElementTestHelpers */
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
function runTest() {
var iframe = document.createElement("iframe");
iframe.setAttribute("mozbrowser", "true");
iframe.setAttribute("name", "foo");
iframe.addEventListener("mozbrowseropenwindow", function(e) {
ok(false, "Got mozbrowseropenwindow, but should not have.");
});
iframe.addEventListener("mozbrowserlocationchange", function(e) {
ok(true, "Got locationchange to " + e.detail.url);
if (e.detail.url.endsWith("ForwardName.html#finish")) {
SimpleTest.finish();
}
});
// The file sends us messages via alert() that start with "success:" or
// "failure:".
iframe.addEventListener("mozbrowsershowmodalprompt", function(e) {
ok(e.detail.message.startsWith("success:"), e.detail.message);
});
document.body.appendChild(iframe);
// This file does window.open('file_browserElement_ForwardName.html#finish',
// 'foo'); That should open in the curent window, because the window should
// be named foo.
iframe.src = "file_browserElement_ForwardName.html";
}
addEventListener("testready", runTest);

View File

@ -1,57 +0,0 @@
/* Any copyright is dedicated to the public domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Bug 804446 - Test that window.open(javascript:..) works with <iframe mozbrowser>.
"use strict";
/* global browserElementTestHelpers */
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
function runTest() {
var iframeJS = document.createElement("iframe");
iframeJS.setAttribute("mozbrowser", "true");
iframeJS.addEventListener("mozbrowserloadstart", function(e) {
ok(false, "This should not happen!");
});
iframeJS.addEventListener("mozbrowserloadend", function(e) {
ok(false, "This should not happen!");
});
iframeJS.src = 'javascript:alert("Foo");';
document.body.appendChild(iframeJS);
var iframe = document.createElement("iframe");
iframe.setAttribute("mozbrowser", "true");
var gotPopup = false;
iframe.addEventListener("mozbrowseropenwindow", function(e) {
is(gotPopup, false, "Should get just one popup.");
gotPopup = true;
document.body.appendChild(e.detail.frameElement);
});
iframe.addEventListener("mozbrowsershowmodalprompt", function(e) {
ok(
gotPopup,
"Got mozbrowseropenwindow event before showmodalprompt event."
);
if (e.detail.message.indexOf("success") == 0) {
ok(true, e.detail.message);
SimpleTest.finish();
} else {
ok(false, "Got invalid message: " + e.detail.message);
}
});
iframe.src = "file_browserElement_FrameWrongURI.html";
document.body.appendChild(iframe);
}
addEventListener("testready", runTest);

View File

@ -1,139 +0,0 @@
/* Any copyright is dedicated to the public domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Test that the onmozbrowsericonchange event works.
"use strict";
/* global browserElementTestHelpers */
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
browserElementTestHelpers.allowTopLevelDataURINavigation();
function createHtml(link) {
return "data:text/html,<html><head>" + link + "<body></body></html>";
}
function createLink(name, sizes, rel) {
var s = sizes ? 'sizes="' + sizes + '"' : "";
if (!rel) {
rel = "icon";
}
return (
'<link rel="' +
rel +
'" type="image/png" ' +
s +
' href="http://example.com/' +
name +
'.png">'
);
}
function runTest() {
var iframe1 = document.createElement("iframe");
iframe1.setAttribute("mozbrowser", "true");
document.body.appendChild(iframe1);
// iframe2 is a red herring; we modify its favicon but don't listen for
// iconchanges; we want to make sure that its iconchange events aren't
// picked up by the listener on iframe1.
var iframe2 = document.createElement("iframe");
iframe2.setAttribute("mozbrowser", "true");
document.body.appendChild(iframe2);
// iframe3 is another red herring. It's not a mozbrowser, so we shouldn't
// get any iconchange events on it.
var iframe3 = document.createElement("iframe");
document.body.appendChild(iframe3);
var numIconChanges = 0;
iframe1.addEventListener("mozbrowsericonchange", function(e) {
numIconChanges++;
if (numIconChanges == 1) {
is(e.detail.href, "http://example.com/myicon.png");
// We should recieve iconchange events when the user creates new links
// to a favicon, but only when we listen for them
SpecialPowers.getBrowserFrameMessageManager(iframe1).loadFrameScript(
"data:,content.document.title='New title';",
/* allowDelayedLoad = */ false
);
SpecialPowers.getBrowserFrameMessageManager(iframe1).loadFrameScript(
"data:,content.document.head.insertAdjacentHTML('beforeend', '<link rel=ICON href=http://example.com/newicon.png>')",
/* allowDelayedLoad = */ false
);
SpecialPowers.getBrowserFrameMessageManager(iframe2).loadFrameScript(
"data:,content.document.head.insertAdjacentHTML('beforeend', '<link rel=ICON href=http://example.com/newicon.png>')",
/* allowDelayedLoad = */ false
);
} else if (numIconChanges == 2) {
is(e.detail.href, "http://example.com/newicon.png");
// Full new pages should trigger iconchange events
iframe1.src = createHtml(createLink("3rdicon"));
} else if (numIconChanges == 3) {
is(e.detail.href, "http://example.com/3rdicon.png");
// the rel attribute can have various space seperated values, make
// sure we only pick up correct values for 'icon'
SpecialPowers.getBrowserFrameMessageManager(iframe1).loadFrameScript(
"data:,content.document.head.insertAdjacentHTML('beforeend', '<link rel=shortcuticon href=http://example.com/newicon.png>')",
/* allowDelayedLoad = */ false
);
// Test setting a page with multiple links elements
iframe1.src = createHtml(createLink("another") + createLink("icon"));
} else if (numIconChanges == 4) {
is(e.detail.href, "http://example.com/another.png");
// 2 events will be triggered by previous test, wait for next
} else if (numIconChanges == 5) {
is(e.detail.href, "http://example.com/icon.png");
// Make sure icon check is case insensitive
SpecialPowers.getBrowserFrameMessageManager(iframe1).loadFrameScript(
"data:,content.document.head.insertAdjacentHTML('beforeend', '<link rel=ICON href=http://example.com/ucaseicon.png>')",
/* allowDelayedLoad = */ false
);
} else if (numIconChanges == 6) {
is(e.detail.href, "http://example.com/ucaseicon.png");
iframe1.src = createHtml(createLink("testsize", "50x50", "icon"));
} else if (numIconChanges == 7) {
is(e.detail.href, "http://example.com/testsize.png");
is(e.detail.sizes, "50x50");
iframe1.src = createHtml(
createLink("testapple1", "100x100", "apple-touch-icon")
);
} else if (numIconChanges == 8) {
is(e.detail.href, "http://example.com/testapple1.png");
is(e.detail.rel, "apple-touch-icon");
is(e.detail.sizes, "100x100");
iframe1.src = createHtml(
createLink("testapple2", "100x100", "apple-touch-icon-precomposed")
);
} else if (numIconChanges == 9) {
is(e.detail.href, "http://example.com/testapple2.png");
is(e.detail.rel, "apple-touch-icon-precomposed");
is(e.detail.sizes, "100x100");
SimpleTest.finish();
} else {
ok(false, "Too many iconchange events.");
}
});
iframe3.addEventListener("mozbrowsericonchange", function(e) {
ok(false, "Should not get a iconchange event for iframe3.");
});
iframe1.src = createHtml(createLink("myicon"));
// We should not recieve icon change events for either of the below iframes
iframe2.src = createHtml(createLink("myicon"));
iframe3.src = createHtml(createLink("myicon"));
}
addEventListener("testready", runTest);

View File

@ -1,144 +0,0 @@
/* Any copyright is dedicated to the public domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Test that an iframe with the |mozbrowser| attribute emits mozbrowserloadX
// events when this page is in the whitelist.
"use strict";
/* global browserElementTestHelpers */
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
function runTest() {
// Load emptypage1 into the iframe, wait for that to finish loading, then
// call runTest2.
//
// This should trigger loadstart, locationchange, and loadend events.
var seenLoadEnd = false;
var seenLoadStart = false;
var seenLocationChange = false;
var iframe = document.createElement("iframe");
iframe.setAttribute("mozbrowser", "true");
iframe.id = "iframe";
iframe.src =
"http://example.com/tests/dom/browser-element/mochitest/file_browserElement_LoadEvents.html";
function loadstart(e) {
ok(e.isTrusted, "Event should be trusted.");
ok(!seenLoadEnd, "loadstart before loadend.");
ok(!seenLoadStart, "Just one loadstart event.");
ok(!seenLocationChange, "loadstart before locationchange.");
seenLoadStart = true;
}
function locationchange(e) {
ok(e.isTrusted, "Event should be trusted.");
ok(!seenLocationChange, "Just one locationchange event.");
seenLocationChange = true;
ok(seenLoadStart, "Location change after load start.");
ok(!seenLoadEnd, "Location change before load end.");
// XXX: Switched to from ok() to todo_is() in Bug 1467712. Follow up in 1503862
// Fails with: event's reported location -
// got "http://example.com/tests/dom/browser-element/mochitest/file_browserElement_LoadEvents.html",
// expected "http://example.com/tests/dom/browser-element/mochitest/file_empty.html"
todo_is(
e.detail.url,
browserElementTestHelpers.emptyPage1,
"event's reported location"
);
}
function loadend(e) {
ok(e.isTrusted, "Event should be trusted.");
ok(seenLoadStart, "loadend after loadstart.");
ok(!seenLoadEnd, "Just one loadend event.");
ok(seenLocationChange, "loadend after locationchange.");
is(
e.detail.backgroundColor,
"rgb(0, 128, 0)",
"Expected background color reported"
);
seenLoadEnd = true;
}
iframe.addEventListener("mozbrowserloadstart", loadstart);
iframe.addEventListener("mozbrowserlocationchange", locationchange);
iframe.addEventListener("mozbrowserloadend", loadend);
function waitForAllCallbacks() {
if (!seenLoadStart || !seenLoadEnd) {
SimpleTest.executeSoon(waitForAllCallbacks);
return;
}
iframe.removeEventListener("mozbrowserloadstart", loadstart);
iframe.removeEventListener("mozbrowserlocationchange", locationchange);
iframe.removeEventListener("mozbrowserloadend", loadend);
runTest2();
}
document.body.appendChild(iframe);
waitForAllCallbacks();
}
function runTest2() {
var seenLoadStart = false;
var seenLoadEnd = false;
var seenLocationChange = false;
// Add this event listener to the document; the events should bubble.
document.addEventListener("mozbrowserloadstart", function(e) {
ok(e.isTrusted, "Event should be trusted.");
ok(!seenLoadStart, "Just one loadstart event.");
seenLoadStart = true;
ok(!seenLoadEnd, "Got mozbrowserloadstart before loadend.");
ok(!seenLocationChange, "Got mozbrowserloadstart before locationchange.");
});
var iframe = document.getElementById("iframe");
iframe.addEventListener("mozbrowserlocationchange", function(e) {
ok(e.isTrusted, "Event should be trusted.");
ok(!seenLocationChange, "Just one locationchange event.");
seenLocationChange = true;
ok(seenLoadStart, "Location change after load start.");
ok(!seenLoadEnd, "Location change before load end.");
is(
e.detail.url,
browserElementTestHelpers.emptyPage2,
"event's reported location"
);
});
iframe.addEventListener("mozbrowserloadend", function(e) {
ok(e.isTrusted, "Event should be trusted.");
ok(!seenLoadEnd, "Just one load end event.");
seenLoadEnd = true;
ok(seenLoadStart, "Load end after load start.");
ok(seenLocationChange, "Load end after location change.");
is(
e.detail.backgroundColor,
"rgba(0, 0, 0, 0)",
"Expected background color reported"
);
});
iframe.src = browserElementTestHelpers.emptyPage2;
function waitForAllCallbacks() {
if (!seenLoadStart || !seenLoadEnd || !seenLocationChange) {
SimpleTest.executeSoon(waitForAllCallbacks);
return;
}
SimpleTest.finish();
}
waitForAllCallbacks();
}
addEventListener("testready", runTest);

View File

@ -1,198 +0,0 @@
/* Any copyright is dedicated to the public domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Test that the onmozbrowsermetachange event works.
"use strict";
/* global browserElementTestHelpers */
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
browserElementTestHelpers.allowTopLevelDataURINavigation();
function createHtml(meta) {
return (
'data:text/html,<html xmlns:xml="http://www.w3.org/XML/1998/namespace"><head>' +
meta +
"<body></body></html>"
);
}
function createHtmlWithLang(meta, lang) {
return (
'data:text/html,<html xmlns:xml="http://www.w3.org/XML/1998/namespace" lang="' +
lang +
'"><head>' +
meta +
"<body></body></html>"
);
}
function createMeta(name, content) {
return '<meta name="' + name + '" content="' + content + '">';
}
function createMetaWithLang(name, content, lang) {
return (
'<meta name="' + name + '" content="' + content + '" lang="' + lang + '">'
);
}
function createMetaWithProperty(property, content) {
return '<meta property="' + property + '" content="' + content + '">';
}
function runTest() {
var iframe1 = document.createElement("iframe");
iframe1.setAttribute("mozbrowser", "true");
document.body.appendChild(iframe1);
// iframe2 is a red herring; we modify its meta elements but don't listen for
// metachanges; we want to make sure that its metachange events aren't
// picked up by the listener on iframe1.
var iframe2 = document.createElement("iframe");
iframe2.setAttribute("mozbrowser", "true");
document.body.appendChild(iframe2);
// iframe3 is another red herring. It's not a mozbrowser, so we shouldn't
// get any metachange events on it.
var iframe3 = document.createElement("iframe");
document.body.appendChild(iframe3);
var numMetaChanges = 0;
iframe1.addEventListener("mozbrowsermetachange", function(e) {
numMetaChanges++;
if (numMetaChanges == 1) {
is(e.detail.name, "application-name");
is(e.detail.content, "foobar");
// We should recieve metachange events when the user creates new metas
SpecialPowers.getBrowserFrameMessageManager(iframe1).loadFrameScript(
"data:,content.document.title='New title';",
/* allowDelayedLoad = */ false
);
SpecialPowers.getBrowserFrameMessageManager(iframe1).loadFrameScript(
"data:,content.document.head.insertAdjacentHTML('beforeend', '<meta name=application-name content=new_foobar>')",
/* allowDelayedLoad = */ false
);
SpecialPowers.getBrowserFrameMessageManager(iframe2).loadFrameScript(
"data:,content.document.head.insertAdjacentHTML('beforeend', '<meta name=application-name content=new_foobar>')",
/* allowDelayedLoad = */ false
);
} else if (numMetaChanges == 2) {
is(e.detail.name, "application-name", "name matches");
is(e.detail.content, "new_foobar", "content matches");
ok(!("lang" in e.detail), "lang not present");
// Full new pages should trigger metachange events
iframe1.src = createHtml(createMeta("application-name", "3rd_foobar"));
} else if (numMetaChanges == 3) {
is(e.detail.name, "application-name", "name matches");
is(e.detail.content, "3rd_foobar", "content matches");
ok(!("lang" in e.detail), "lang not present");
// Test setting a page with multiple meta elements
iframe1.src = createHtml(
createMeta("application-name", "foobar_1") +
createMeta("application-name", "foobar_2")
);
} else if (numMetaChanges == 4) {
is(e.detail.name, "application-name", "name matches");
is(e.detail.content, "foobar_1", "content matches");
ok(!("lang" in e.detail), "lang not present");
// 2 events will be triggered by previous test, wait for next
} else if (numMetaChanges == 5) {
is(e.detail.name, "application-name", "name matches");
is(e.detail.content, "foobar_2", "content matches");
ok(!("lang" in e.detail), "lang not present");
// Test the language
iframe1.src = createHtml(
createMetaWithLang("application-name", "foobar_lang_1", "en")
);
} else if (numMetaChanges == 6) {
is(e.detail.name, "application-name", "name matches");
is(e.detail.content, "foobar_lang_1", "content matches");
is(e.detail.lang, "en", "language matches");
// Test the language in the ancestor element
iframe1.src = createHtmlWithLang(
createMeta("application-name", "foobar_lang_2"),
"es"
);
} else if (numMetaChanges == 7) {
is(e.detail.name, "application-name", "name matches");
is(e.detail.content, "foobar_lang_2", "content matches");
is(e.detail.lang, "es", "language matches");
// Test the language in the ancestor element
iframe1.src = createHtmlWithLang(
createMetaWithLang("application-name", "foobar_lang_3", "it"),
"fi"
);
} else if (numMetaChanges == 8) {
is(e.detail.name, "application-name", "name matches");
is(e.detail.content, "foobar_lang_3", "content matches");
is(e.detail.lang, "it", "language matches");
// Test the content-language
iframe1.src =
"http://test/tests/dom/browser-element/mochitest/file_browserElement_Metachange.sjs?ru";
} else if (numMetaChanges == 9) {
is(e.detail.name, "application-name", "name matches");
is(e.detail.content, "sjs", "content matches");
is(e.detail.lang, "ru", "language matches");
// Test the content-language
iframe1.src =
"http://test/tests/dom/browser-element/mochitest/file_browserElement_Metachange.sjs?ru|dk";
} else if (numMetaChanges == 10) {
is(e.detail.name, "application-name", "name matches");
is(e.detail.content, "sjs", "content matches");
is(e.detail.lang, "dk", "language matches");
// Test Open Graph property
iframe1.src = createHtml(
createMetaWithProperty("og:description", "Fascinating article")
);
// We should not get event if property doesn't start with 'og:'
iframe3.src = createHtml(
createMetaWithProperty("go:description", "Fascinating article")
);
} else if (numMetaChanges == 11) {
is(e.detail.name, "og:description", "property name matches");
is(e.detail.content, "Fascinating article", "content matches");
// Sometimes 'name' is used instead of 'property'. Verify that works.
iframe1.src = createHtml(createMeta("og:title", "One weird trick!"));
// We should not get event if property doesn't start with 'og:'
iframe3.src = createHtml(createMeta("go:title", "One weird trick!"));
} else if (numMetaChanges == 12) {
is(e.detail.name, "og:title", "property name matches");
is(e.detail.content, "One weird trick!", "content matches");
// Test the language
SimpleTest.finish();
} else {
ok(false, "Too many metachange events.");
}
});
iframe3.addEventListener("mozbrowsermetachange", function(e) {
ok(false, "Should not get a metachange event for iframe3.");
});
iframe1.src = createHtml(createMeta("application-name", "foobar"));
// We should not recieve meta change events for either of the below iframes
iframe2.src = createHtml(createMeta("application-name", "foobar"));
iframe3.src = createHtml(createMeta("application-name", "foobar"));
}
addEventListener("testready", runTest);

View File

@ -1,62 +0,0 @@
/* Any copyright is dedicated to the public domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Bug 742944 - In <iframe mozbrowser>, test that if we call window.open twice
// with the same name, we get only one mozbrowseropenwindow event.
"use strict";
/* global browserElementTestHelpers */
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
var iframe;
var popupFrame;
function runTest() {
iframe = document.createElement("iframe");
iframe.setAttribute("mozbrowser", "true");
var gotPopup = false;
iframe.addEventListener("mozbrowseropenwindow", function(e) {
is(gotPopup, false, "Should get just one popup.");
gotPopup = true;
popupFrame = e.detail.frameElement;
is(popupFrame.getAttribute("name"), "OpenNamed");
// Called when file_browserElement_OpenNamed2.html loads into popupFrame.
popupFrame.addEventListener(
"mozbrowsershowmodalprompt",
function(f) {
ok(gotPopup, "Got openwindow event before showmodalprompt event.");
is(f.detail.message, "success: loaded");
SimpleTest.executeSoon(test2);
},
{ once: true }
);
document.body.appendChild(popupFrame);
});
// OpenNamed.html will call
//
// window.open('file_browserElement_OpenNamed2.html', 'OpenNamed').
//
// Once that popup loads, we reload OpenNamed.html. That will call
// window.open again, but we shouldn't get another openwindow event, because
// we're opening into the same named window.
iframe.src = "file_browserElement_OpenNamed.html";
document.body.appendChild(iframe);
}
function test2() {
popupFrame.addEventListener("mozbrowsershowmodalprompt", function(e) {
is(e.detail.message, "success: loaded");
SimpleTest.finish();
});
iframe.src = "file_browserElement_OpenNamed.html?test2";
}
addEventListener("testready", runTest);

View File

@ -1,65 +0,0 @@
/* Any copyright is dedicated to the public domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Bug 1144015 - test middle/ctrl/cmd-click on a link.
"use strict";
/* global browserElementTestHelpers */
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
function runTest() {
let iframe = document.createElement("iframe");
iframe.setAttribute("mozbrowser", "true");
document.body.appendChild(iframe);
let x = 2;
let y = 2;
// This test used to try to transform the coordinates from child
// to parent coordinate space by first calling
// iframe.getBoundingClientRect();
// to refresh offsets and then calling
// var remoteTab = SpecialPowers.wrap(iframe)
// .frameLoader.remoteTab;
// and calling remoteTab.getChildProcessOffset(offsetX, offsetY) if
// remoteTab was not null, but remoteTab was always null.
let sendCtrlClick = () => {
let nsIDOMWindowUtils = SpecialPowers.Ci.nsIDOMWindowUtils;
let mod =
nsIDOMWindowUtils.MODIFIER_META | nsIDOMWindowUtils.MODIFIER_CONTROL;
iframe.sendMouseEvent("mousedown", x, y, 0, 1, mod);
iframe.sendMouseEvent("mouseup", x, y, 0, 1, mod);
};
let onCtrlClick = e => {
is(e.detail.url, "http://example.com/", "URL matches");
iframe.removeEventListener("mozbrowseropentab", onCtrlClick);
iframe.addEventListener("mozbrowseropentab", onMiddleClick);
sendMiddleClick();
};
let sendMiddleClick = () => {
iframe.sendMouseEvent("mousedown", x, y, 1, 1, 0);
iframe.sendMouseEvent("mouseup", x, y, 1, 1, 0);
};
let onMiddleClick = e => {
is(e.detail.url, "http://example.com/", "URL matches");
iframe.removeEventListener("mozbrowseropentab", onMiddleClick);
SimpleTest.finish();
};
iframe.addEventListener("mozbrowserloadend", e => {
iframe.addEventListener("mozbrowseropentab", onCtrlClick);
sendCtrlClick();
});
iframe.src =
'data:text/html,<body style="margin:0"><a href="http://example.com"><span>click here</span></a></body>';
}
addEventListener("testready", runTest);

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