mirror of
https://github.com/Feodor2/Mypal68.git
synced 2025-06-18 14:55:44 -04:00
68.14.3 - dom
This commit is contained in:
parent
6a4f7fd1d0
commit
f2f1bfa92d
@ -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]]
|
||||
|
@ -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",
|
||||
|
@ -13,9 +13,6 @@
|
||||
"use strict";
|
||||
|
||||
const testcases = [
|
||||
{
|
||||
property: "-moz-appearance",
|
||||
},
|
||||
{
|
||||
property: "-moz-box-align"
|
||||
},
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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 document’s
|
||||
// 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()) {
|
||||
|
@ -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();
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -85,7 +85,7 @@ class EncodingCompleteEvent : public CancelableRunnable {
|
||||
mEncodeCompleteCallback(aEncodeCompleteCallback),
|
||||
mFailed(false) {
|
||||
if (!NS_IsMainThread() && IsCurrentThreadRunningWorker()) {
|
||||
mCreationEventTarget = GetCurrentThreadEventTarget();
|
||||
mCreationEventTarget = GetCurrentEventTarget();
|
||||
} else {
|
||||
mCreationEventTarget = GetMainThreadEventTarget();
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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) {
|
||||
|
@ -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();
|
||||
|
@ -284,7 +284,7 @@ StructuredCloneHolder::StructuredCloneHolder(
|
||||
mGlobal(nullptr)
|
||||
#ifdef DEBUG
|
||||
,
|
||||
mCreationEventTarget(GetCurrentThreadEventTarget())
|
||||
mCreationEventTarget(GetCurrentEventTarget())
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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__ */
|
||||
|
@ -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:
|
||||
|
@ -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(
|
||||
|
@ -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 (;;) {
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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]
|
||||
|
@ -1,4 +0,0 @@
|
||||
<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
@ -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) {}
|
||||
}
|
||||
}
|
@ -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>
|
@ -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>
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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]
|
||||
|
@ -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;
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
@ -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>
|
@ -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);
|
||||
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
/**
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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) {
|
||||
|
@ -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,
|
||||
|
@ -468,10 +468,6 @@ DOMInterfaces = {
|
||||
'wrapperCache': False,
|
||||
},
|
||||
|
||||
'MediaKeys' : {
|
||||
'implicitJSContext': [ 'createSession']
|
||||
},
|
||||
|
||||
'MediaStream': {
|
||||
'headerFile': 'DOMMediaStream.h',
|
||||
'nativeType': 'mozilla::DOMMediaStream'
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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()) {
|
||||
|
@ -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 {
|
||||
|
@ -1,8 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
"extends": [
|
||||
"plugin:mozilla/chrome-test",
|
||||
"plugin:mozilla/mochitest-test",
|
||||
],
|
||||
};
|
@ -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);
|
Binary file not shown.
@ -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)
|
||||
);
|
||||
});
|
@ -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);
|
@ -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);
|
@ -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
|
||||
);
|
||||
});
|
@ -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);
|
@ -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);
|
@ -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);
|
@ -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);
|
@ -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);
|
@ -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);
|
@ -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
|
||||
);
|
||||
});
|
@ -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
|
||||
);
|
||||
});
|
@ -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);
|
@ -1,5 +0,0 @@
|
||||
<html>
|
||||
<body>
|
||||
foo
|
||||
</body>
|
||||
</html>
|
@ -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);
|
@ -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);
|
@ -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);
|
@ -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);
|
@ -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);
|
@ -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);
|
@ -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);
|
@ -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);
|
@ -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);
|
@ -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);
|
@ -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);
|
@ -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
Loading…
Reference in New Issue
Block a user