68.13.9 - everything else

This commit is contained in:
Fedor 2024-02-16 13:22:56 +02:00
parent 8ed7e5e7f4
commit 31cef1d61c
2395 changed files with 58512 additions and 146454 deletions

View File

@ -59,7 +59,6 @@ xpcom/reflect/xptcall/md/unix/.*
# awk '{print ""$1".*"}' ./tools/rewriting/ThirdPartyPaths.txt # awk '{print ""$1".*"}' ./tools/rewriting/ThirdPartyPaths.txt
browser/components/translation/cld2/.* browser/components/translation/cld2/.*
browser/extensions/mortar/ppapi/.* browser/extensions/mortar/ppapi/.*
db/sqlite3/src/.*
devtools/client/shared/sourceeditor/codemirror/.* devtools/client/shared/sourceeditor/codemirror/.*
devtools/client/shared/sourceeditor/tern/.* devtools/client/shared/sourceeditor/tern/.*
dom/canvas/test/webgl-conf/checkout/closure-library/.* dom/canvas/test/webgl-conf/checkout/closure-library/.*

View File

@ -145,23 +145,6 @@ module.exports = {
"no-redeclare": "off", "no-redeclare": "off",
"no-global-assign": "off", "no-global-assign": "off",
} }
}, {
"files": [
"image/**",
],
"rules": {
"mozilla/consistent-if-bracing": "off",
"mozilla/use-chromeutils-generateqi": "off",
"mozilla/use-services": "off",
"no-array-constructor": "off",
"no-implied-eval": "off",
"no-redeclare": "off",
"no-self-assign": "off",
"no-throw-literal": "off",
"no-undef": "off",
"no-unneeded-ternary": "off",
"no-unused-vars": "off",
}
}, { }, {
"files": [ "files": [
"netwerk/cookie/test/browser/**", "netwerk/cookie/test/browser/**",

View File

@ -22,4 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please # changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more. # don't change CLOBBER for WebIDL changes any more.
Bug 1632434 - Update to ICU 67 requires clobber Bug 1551084 - Part 2. Make QCMS transform files use C++. r=miko

521
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -35,7 +35,6 @@ exclude = [
"gfx/webrender_bindings", "gfx/webrender_bindings",
"media/mp4parse-rust/mp4parse", "media/mp4parse-rust/mp4parse",
"media/mp4parse-rust/mp4parse_capi", "media/mp4parse-rust/mp4parse_capi",
"media/mp4parse-rust/mp4parse_fallible",
"xpcom/rust/gkrust_utils", "xpcom/rust/gkrust_utils",
] ]

View File

@ -117,7 +117,7 @@ void DocAccessibleWrap::CacheViewportCallback(nsITimer* aTimer,
if (inViewAccs.Contains(acc->UniqueID())) { if (inViewAccs.Contains(acc->UniqueID())) {
break; break;
} }
inViewAccs.Put(acc->UniqueID(), acc); inViewAccs.Put(acc->UniqueID(), RefPtr{acc});
} }
} }
@ -213,7 +213,7 @@ void DocAccessibleWrap::CacheFocusPath(AccessibleWrap* aAccessible) {
acc->ActionCount(), name, textValue, nodeID, description, acc->ActionCount(), name, textValue, nodeID, description,
acc->CurValue(), acc->MinValue(), acc->MaxValue(), acc->CurValue(), acc->MinValue(), acc->MaxValue(),
acc->Step(), attributes)); acc->Step(), attributes));
mFocusPath.Put(acc->UniqueID(), acc); mFocusPath.Put(acc->UniqueID(), RefPtr{acc});
} }
ipcDoc->SendBatch(eBatch_FocusPath, cacheData); ipcDoc->SendBatch(eBatch_FocusPath, cacheData);
@ -223,7 +223,7 @@ void DocAccessibleWrap::CacheFocusPath(AccessibleWrap* aAccessible) {
for (AccessibleWrap* acc = aAccessible; acc && acc != this->Parent(); for (AccessibleWrap* acc = aAccessible; acc && acc != this->Parent();
acc = static_cast<AccessibleWrap*>(acc->Parent())) { acc = static_cast<AccessibleWrap*>(acc->Parent())) {
accessibles.AppendElement(acc); accessibles.AppendElement(acc);
mFocusPath.Put(acc->UniqueID(), acc); mFocusPath.Put(acc->UniqueID(), RefPtr{acc});
} }
sessionAcc->ReplaceFocusPathCache(accessibles); sessionAcc->ReplaceFocusPathCache(accessibles);

View File

@ -186,7 +186,7 @@ class AccessibleNode : public nsISupports, public nsWrapperCache {
if (!aValue) { if (!aValue) {
mRelationProperties.Remove(static_cast<int>(aProperty)); mRelationProperties.Remove(static_cast<int>(aProperty));
} else { } else {
mRelationProperties.Put(static_cast<int>(aProperty), aValue); mRelationProperties.Put(static_cast<int>(aProperty), RefPtr{aValue});
} }
} }

View File

@ -9,8 +9,8 @@
#include "xpcAccEvents.h" #include "xpcAccEvents.h"
#include "States.h" #include "States.h"
#include "mozilla/EventStateManager.h"
#include "mozilla/dom/Selection.h" #include "mozilla/dom/Selection.h"
#include "mozilla/dom/UserActivation.h"
using namespace mozilla; using namespace mozilla;
using namespace mozilla::a11y; using namespace mozilla::a11y;
@ -30,7 +30,7 @@ AccEvent::AccEvent(uint32_t aEventType, Accessible* aAccessible,
EIsFromUserInput aIsFromUserInput, EEventRule aEventRule) EIsFromUserInput aIsFromUserInput, EEventRule aEventRule)
: mEventType(aEventType), mEventRule(aEventRule), mAccessible(aAccessible) { : mEventType(aEventType), mEventRule(aEventRule), mAccessible(aAccessible) {
if (aIsFromUserInput == eAutoDetect) if (aIsFromUserInput == eAutoDetect)
mIsFromUserInput = EventStateManager::IsHandlingUserInput(); mIsFromUserInput = dom::UserActivation::IsHandlingUserInput();
else else
mIsFromUserInput = aIsFromUserInput == eFromUserInput ? true : false; mIsFromUserInput = aIsFromUserInput == eFromUserInput ? true : false;
} }

View File

@ -15,7 +15,7 @@ namespace a11y {
*/ */
class AccGroupInfo { class AccGroupInfo {
public: public:
~AccGroupInfo() { MOZ_COUNT_DTOR(AccGroupInfo); } MOZ_COUNTED_DTOR(AccGroupInfo)
/** /**
* Return 1-based position in the group. * Return 1-based position in the group.

View File

@ -125,7 +125,7 @@ xpcAccessibleDocument* DocManager::GetXPCDocument(DocAccessible* aDocument) {
xpcAccessibleDocument* xpcDoc = mXPCDocumentCache.GetWeak(aDocument); xpcAccessibleDocument* xpcDoc = mXPCDocumentCache.GetWeak(aDocument);
if (!xpcDoc) { if (!xpcDoc) {
xpcDoc = new xpcAccessibleDocument(aDocument); xpcDoc = new xpcAccessibleDocument(aDocument);
mXPCDocumentCache.Put(aDocument, xpcDoc); mXPCDocumentCache.Put(aDocument, RefPtr{xpcDoc});
} }
return xpcDoc; return xpcDoc;
} }
@ -144,7 +144,7 @@ xpcAccessibleDocument* DocManager::GetXPCDocument(DocAccessibleParent* aDoc) {
doc = new xpcAccessibleDocument(aDoc, doc = new xpcAccessibleDocument(aDoc,
Interfaces::DOCUMENT | Interfaces::HYPERTEXT); Interfaces::DOCUMENT | Interfaces::HYPERTEXT);
sRemoteXPCDocumentCache->Put(aDoc, doc); sRemoteXPCDocumentCache->Put(aDoc, RefPtr{doc});
return doc; return doc;
} }
@ -458,7 +458,7 @@ DocAccessible* DocManager::CreateDocOrRootAccessible(Document* aDocument) {
: new DocAccessibleWrap(aDocument, presShell); : new DocAccessibleWrap(aDocument, presShell);
// Cache the document accessible into document cache. // Cache the document accessible into document cache.
mDocAccessibleCache.Put(aDocument, docAcc); mDocAccessibleCache.Put(aDocument, RefPtr{docAcc});
// Initialize the document accessible. // Initialize the document accessible.
docAcc->Init(); docAcc->Init();

View File

@ -30,7 +30,9 @@ bool EventQueue::PushEvent(AccEvent* aEvent) {
aEvent->Document() == mDocument, aEvent->Document() == mDocument,
"Queued event belongs to another document!"); "Queued event belongs to another document!");
if (!mEvents.AppendElement(aEvent)) return false; // XXX(Bug 1631371) Check if this should use a fallible operation as it
// pretended earlier, or change the return type to void.
mEvents.AppendElement(aEvent);
// Filter events. // Filter events.
CoalesceEvents(); CoalesceEvents();

View File

@ -119,7 +119,7 @@ static void LogDocShellTree(dom::Document* aDocumentNode) {
nsCOMPtr<nsIDocShellTreeItem> parentTreeItem; nsCOMPtr<nsIDocShellTreeItem> parentTreeItem;
treeItem->GetInProcessParent(getter_AddRefs(parentTreeItem)); treeItem->GetInProcessParent(getter_AddRefs(parentTreeItem));
nsCOMPtr<nsIDocShellTreeItem> rootTreeItem; nsCOMPtr<nsIDocShellTreeItem> rootTreeItem;
treeItem->GetRootTreeItem(getter_AddRefs(rootTreeItem)); treeItem->GetInProcessRootTreeItem(getter_AddRefs(rootTreeItem));
printf("docshell hierarchy, parent: %p, root: %p, is tab document: %s;", printf("docshell hierarchy, parent: %p, root: %p, is tab document: %s;",
static_cast<void*>(parentTreeItem), static_cast<void*>(rootTreeItem), static_cast<void*>(parentTreeItem), static_cast<void*>(rootTreeItem),
(nsCoreUtils::IsTabDocument(aDocumentNode) ? "yes" : "no")); (nsCoreUtils::IsTabDocument(aDocumentNode) ? "yes" : "no"));

View File

@ -392,7 +392,7 @@ MARKUPMAP(
[](Element* aElement, Accessible* aContext) -> Accessible* { [](Element* aElement, Accessible* aContext) -> Accessible* {
return new HTMLOutputAccessible(aElement, aContext->Document()); return new HTMLOutputAccessible(aElement, aContext->Document());
}, },
roles::SECTION, Attr(live, polite)) roles::STATUSBAR, Attr(live, polite))
MARKUPMAP(p, nullptr, roles::PARAGRAPH) MARKUPMAP(p, nullptr, roles::PARAGRAPH)

View File

@ -948,7 +948,7 @@ void NotificationController::EventMap::PutEvent(AccTreeMutationEvent* aEvent) {
uint64_t addr = reinterpret_cast<uintptr_t>(aEvent->GetAccessible()); uint64_t addr = reinterpret_cast<uintptr_t>(aEvent->GetAccessible());
MOZ_ASSERT((addr & 0x3) == 0, "accessible is not 4 byte aligned"); MOZ_ASSERT((addr & 0x3) == 0, "accessible is not 4 byte aligned");
addr |= type; addr |= type;
mTable.Put(addr, aEvent); mTable.Put(addr, RefPtr{aEvent});
} }
AccTreeMutationEvent* NotificationController::EventMap::GetEvent( AccTreeMutationEvent* NotificationController::EventMap::GetEvent(

View File

@ -197,7 +197,10 @@ class NotificationController final : public EventQueue,
* Pend an accessible subtree relocation. * Pend an accessible subtree relocation.
*/ */
void ScheduleRelocation(Accessible* aOwner) { void ScheduleRelocation(Accessible* aOwner) {
if (!mRelocations.Contains(aOwner) && mRelocations.AppendElement(aOwner)) { if (!mRelocations.Contains(aOwner)) {
// XXX(Bug 1631371) Check if this should use a fallible operation as it
// pretended earlier, or change the return type to void.
mRelocations.AppendElement(aOwner);
ScheduleProcessing(); ScheduleProcessing();
} }
} }
@ -233,8 +236,12 @@ class NotificationController final : public EventQueue,
RefPtr<Notification> notification = RefPtr<Notification> notification =
new TNotification<Class, Args...>(aInstance, aMethod, aArgs...); new TNotification<Class, Args...>(aInstance, aMethod, aArgs...);
if (notification && mNotifications.AppendElement(notification)) if (notification) {
// XXX(Bug 1631371) Check if this should use a fallible operation as it
// pretended earlier.
mNotifications.AppendElement(notification);
ScheduleProcessing(); ScheduleProcessing();
}
} }
/** /**
@ -248,8 +255,12 @@ class NotificationController final : public EventQueue,
Class* aInstance, typename TNotification<Class>::Callback aMethod) { Class* aInstance, typename TNotification<Class>::Callback aMethod) {
RefPtr<Notification> notification = RefPtr<Notification> notification =
new TNotification<Class>(aInstance, aMethod); new TNotification<Class>(aInstance, aMethod);
if (notification && mNotifications.AppendElement(notification)) if (notification) {
// XXX(Bug 1631371) Check if this should use a fallible operation as it
// pretended earlier.
mNotifications.AppendElement(notification);
ScheduleProcessing(); ScheduleProcessing();
}
} }
template <class Class, class Arg> template <class Class, class Arg>
@ -258,7 +269,10 @@ class NotificationController final : public EventQueue,
Arg* aArg) { Arg* aArg) {
RefPtr<Notification> notification = RefPtr<Notification> notification =
new TNotification<Class, Arg>(aInstance, aMethod, aArg); new TNotification<Class, Arg>(aInstance, aMethod, aArg);
if (notification && mNotifications.AppendElement(notification)) { if (notification) {
// XXX(Bug 1631371) Check if this should use a fallible operation as it
// pretended earlier.
mNotifications.AppendElement(notification);
ScheduleProcessing(); ScheduleProcessing();
} }
} }

View File

@ -492,7 +492,7 @@ ROLE(SPINBUTTON,
NSAccessibilityIncrementorRole, //Subroles: Increment/Decrement. NSAccessibilityIncrementorRole, //Subroles: Increment/Decrement.
ROLE_SYSTEM_SPINBUTTON, ROLE_SYSTEM_SPINBUTTON,
ROLE_SYSTEM_SPINBUTTON, ROLE_SYSTEM_SPINBUTTON,
java::SessionAccessibility::CLASSNAME_VIEW, // A composite widget java::SessionAccessibility::CLASSNAME_EDITTEXT,
eNameFromValueRule) eNameFromValueRule)
ROLE(DIAGRAM, ROLE(DIAGRAM,

View File

@ -19,15 +19,12 @@ StyleInfo::StyleInfo(dom::Element* aElement) : mElement(aElement) {
void StyleInfo::Display(nsAString& aValue) { void StyleInfo::Display(nsAString& aValue) {
aValue.Truncate(); aValue.Truncate();
Servo_GetPropertyValue(mComputedStyle, eCSSProperty_display, &aValue); mComputedStyle->GetComputedPropertyValue(eCSSProperty_display, aValue);
} }
void StyleInfo::TextAlign(nsAString& aValue) { void StyleInfo::TextAlign(nsAString& aValue) {
aValue.Truncate(); aValue.Truncate();
AppendASCIItoUTF16( mComputedStyle->GetComputedPropertyValue(eCSSProperty_text_align, aValue);
nsCSSProps::ValueToKeyword(mComputedStyle->StyleText()->mTextAlign,
nsCSSProps::kTextAlignKTable),
aValue);
} }
void StyleInfo::TextIndent(nsAString& aValue) { void StyleInfo::TextIndent(nsAString& aValue) {
@ -72,7 +69,23 @@ void StyleInfo::FormatColor(const nscolor& aValue, nsString& aFormattedValue) {
void StyleInfo::FormatTextDecorationStyle(uint8_t aValue, void StyleInfo::FormatTextDecorationStyle(uint8_t aValue,
nsAString& aFormattedValue) { nsAString& aFormattedValue) {
nsCSSKeyword keyword = nsCSSProps::ValueToKeywordEnum( // TODO: When these are enum classes that rust also understands we should just
aValue, nsCSSProps::kTextDecorationStyleKTable); // make an FFI call here.
AppendUTF8toUTF16(nsCSSKeywords::GetStringValue(keyword), aFormattedValue); switch (aValue) {
case NS_STYLE_TEXT_DECORATION_STYLE_NONE:
return aFormattedValue.AssignASCII("-moz-none");
case NS_STYLE_TEXT_DECORATION_STYLE_SOLID:
return aFormattedValue.AssignASCII("solid");
case NS_STYLE_TEXT_DECORATION_STYLE_DOUBLE:
return aFormattedValue.AssignASCII("double");
case NS_STYLE_TEXT_DECORATION_STYLE_DOTTED:
return aFormattedValue.AssignASCII("dotted");
case NS_STYLE_TEXT_DECORATION_STYLE_DASHED:
return aFormattedValue.AssignASCII("dashed");
case NS_STYLE_TEXT_DECORATION_STYLE_WAVY:
return aFormattedValue.AssignASCII("wavy");
default:
MOZ_ASSERT_UNREACHABLE("Unknown decoration style");
break;
}
} }

View File

@ -19,6 +19,7 @@
#include "nsIPersistentProperties2.h" #include "nsIPersistentProperties2.h"
#include "mozilla/a11y/PDocAccessibleChild.h" #include "mozilla/a11y/PDocAccessibleChild.h"
#include "mozilla/dom/Element.h" #include "mozilla/dom/Element.h"
#include "nsAccessibilityService.h"
using namespace mozilla; using namespace mozilla;
using namespace mozilla::a11y; using namespace mozilla::a11y;
@ -137,7 +138,11 @@ void nsAccUtils::SetLiveContainerAttributes(
live); live);
} else if (role) { } else if (role) {
GetLiveAttrValue(role->liveAttRule, live); GetLiveAttrValue(role->liveAttRule, live);
} else if (nsStaticAtom* value = GetAccService()->MarkupAttribute(
ancestor, nsGkAtoms::live)) {
value->ToString(live);
} }
if (!live.IsEmpty()) { if (!live.IsEmpty()) {
SetAccAttr(aAttributes, nsGkAtoms::containerLive, live); SetAccAttr(aAttributes, nsGkAtoms::containerLive, live);
if (role) { if (role) {
@ -487,6 +492,9 @@ bool nsAccUtils::IsARIALive(const Accessible* aAccessible) {
docLive); docLive);
} else if (role) { } else if (role) {
GetLiveAttrValue(role->liveAttRule, docLive); GetLiveAttrValue(role->liveAttRule, docLive);
} else if (nsStaticAtom* value = GetAccService()->MarkupAttribute(
ancestor, nsGkAtoms::live)) {
value->ToString(docLive);
} }
if (!docLive.IsEmpty()) { if (!docLive.IsEmpty()) {
live = docLive; live = docLive;

View File

@ -335,6 +335,25 @@ void nsAccessibilityService::FireAccessibleEvent(uint32_t aEvent,
nsEventShell::FireEvent(aEvent, aTarget); nsEventShell::FireEvent(aEvent, aTarget);
} }
void nsAccessibilityService::NotifyOfImageSizeAvailable(
mozilla::PresShell* aPresShell, nsIContent* aContent) {
// If the size of an image is initially unknown, it will have the invisible
// state (and a 0 width and height), causing it to be ignored by some screen
// readers. Fire a state change event to update any client caches.
DocAccessible* document = GetDocAccessible(aPresShell);
if (document) {
Accessible* accessible = document->GetAccessible(aContent);
// The accessible may not be an ImageAccessible if this was previously a
// broken image with an alt attribute. In that case, do nothing; the
// accessible will be recreated if this becomes a valid image.
if (accessible && accessible->IsImage()) {
RefPtr<AccEvent> event =
new AccStateChangeEvent(accessible, states::INVISIBLE, false);
document->FireDelayedEvent(event);
}
}
}
Accessible* nsAccessibilityService::GetRootDocumentAccessible( Accessible* nsAccessibilityService::GetRootDocumentAccessible(
PresShell* aPresShell, bool aCanCreate) { PresShell* aPresShell, bool aCanCreate) {
PresShell* presShell = aPresShell; PresShell* presShell = aPresShell;
@ -343,7 +362,7 @@ Accessible* nsAccessibilityService::GetRootDocumentAccessible(
nsCOMPtr<nsIDocShellTreeItem> treeItem(documentNode->GetDocShell()); nsCOMPtr<nsIDocShellTreeItem> treeItem(documentNode->GetDocShell());
if (treeItem) { if (treeItem) {
nsCOMPtr<nsIDocShellTreeItem> rootTreeItem; nsCOMPtr<nsIDocShellTreeItem> rootTreeItem;
treeItem->GetRootTreeItem(getter_AddRefs(rootTreeItem)); treeItem->GetInProcessRootTreeItem(getter_AddRefs(rootTreeItem));
if (treeItem != rootTreeItem) { if (treeItem != rootTreeItem) {
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(rootTreeItem)); nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(rootTreeItem));
presShell = docShell->GetPresShell(); presShell = docShell->GetPresShell();

View File

@ -222,6 +222,15 @@ class nsAccessibilityService final : public mozilla::a11y::DocManager,
void FireAccessibleEvent(uint32_t aEvent, Accessible* aTarget); void FireAccessibleEvent(uint32_t aEvent, Accessible* aTarget);
/**
* Notify accessibility that the size has become available for an image.
* This occurs when the size of an image is initially not known, but we've
* now loaded enough data to know the size.
* Called by layout.
*/
void NotifyOfImageSizeAvailable(mozilla::PresShell* aPresShell,
nsIContent* aContent);
// nsAccessibiltiyService // nsAccessibiltiyService
/** /**
@ -246,6 +255,25 @@ class nsAccessibilityService final : public mozilla::a11y::DocManager,
return markupMap ? markupMap->role : mozilla::a11y::roles::NOTHING; return markupMap ? markupMap->role : mozilla::a11y::roles::NOTHING;
} }
/**
* Return the associated value for a given attribute if
* it appears in the MarkupMap. Otherwise, it returns null.
*/
nsStaticAtom* MarkupAttribute(const nsIContent* aContent,
nsStaticAtom* aAtom) const {
const mozilla::a11y::HTMLMarkupMapInfo* markupMap =
mHTMLMarkupMap.Get(aContent->NodeInfo()->NameAtom());
if (markupMap) {
for (size_t i = 0; i < mozilla::ArrayLength(markupMap->attrs); i++) {
const mozilla::a11y::MarkupAttrInfo* info = markupMap->attrs + i;
if (info->name == aAtom) {
return info->value;
}
}
}
return nullptr;
}
/** /**
* Set the object attribute defined by markup for the given element. * Set the object attribute defined by markup for the given element.
*/ */

View File

@ -364,7 +364,7 @@ bool nsCoreUtils::IsTabDocument(Document* aDocumentNode) {
// Parent of docshell for tab document running in chrome process is root. // Parent of docshell for tab document running in chrome process is root.
nsCOMPtr<nsIDocShellTreeItem> rootTreeItem; nsCOMPtr<nsIDocShellTreeItem> rootTreeItem;
treeItem->GetRootTreeItem(getter_AddRefs(rootTreeItem)); treeItem->GetInProcessRootTreeItem(getter_AddRefs(rootTreeItem));
return parentTreeItem == rootTreeItem; return parentTreeItem == rootTreeItem;
} }

View File

@ -142,8 +142,8 @@ class nsCoreUtils {
* @param aRange the range to scroll to * @param aRange the range to scroll to
* @param aScrollType the place a range should be scrolled to * @param aScrollType the place a range should be scrolled to
*/ */
static nsresult ScrollSubstringTo(nsIFrame* aFrame, nsRange* aRange, MOZ_CAN_RUN_SCRIPT_BOUNDARY static nsresult ScrollSubstringTo(
uint32_t aScrollType); nsIFrame* aFrame, nsRange* aRange, uint32_t aScrollType);
/** Helper method to scroll range into view, used for implementation of /** Helper method to scroll range into view, used for implementation of
* nsIAccessibleText::scrollSubstringTo[Point](). * nsIAccessibleText::scrollSubstringTo[Point]().
@ -155,9 +155,9 @@ class nsCoreUtils {
* @param aHorizontal how to align horizontally, specified in percents, * @param aHorizontal how to align horizontally, specified in percents,
* and when. * and when.
*/ */
static nsresult ScrollSubstringTo(nsIFrame* aFrame, nsRange* aRange, MOZ_CAN_RUN_SCRIPT_BOUNDARY static nsresult ScrollSubstringTo(
mozilla::ScrollAxis aVertical, nsIFrame* aFrame, nsRange* aRange, mozilla::ScrollAxis aVertical,
mozilla::ScrollAxis aHorizontal); mozilla::ScrollAxis aHorizontal);
/** /**
* Scrolls the given frame to the point, used for implememntation of * Scrolls the given frame to the point, used for implememntation of

View File

@ -65,7 +65,6 @@
#include "mozilla/Assertions.h" #include "mozilla/Assertions.h"
#include "mozilla/BasicEvents.h" #include "mozilla/BasicEvents.h"
#include "mozilla/ErrorResult.h" #include "mozilla/ErrorResult.h"
#include "mozilla/EventStateManager.h"
#include "mozilla/EventStates.h" #include "mozilla/EventStates.h"
#include "mozilla/FloatingPoint.h" #include "mozilla/FloatingPoint.h"
#include "mozilla/MouseEvents.h" #include "mozilla/MouseEvents.h"
@ -79,6 +78,7 @@
#include "mozilla/dom/HTMLBodyElement.h" #include "mozilla/dom/HTMLBodyElement.h"
#include "mozilla/dom/KeyboardEventBinding.h" #include "mozilla/dom/KeyboardEventBinding.h"
#include "mozilla/dom/TreeWalker.h" #include "mozilla/dom/TreeWalker.h"
#include "mozilla/dom/UserActivation.h"
using namespace mozilla; using namespace mozilla;
using namespace mozilla::a11y; using namespace mozilla::a11y;
@ -736,7 +736,7 @@ void Accessible::TakeFocus() const {
nsFocusManager* fm = nsFocusManager::GetFocusManager(); nsFocusManager* fm = nsFocusManager::GetFocusManager();
if (fm) { if (fm) {
AutoHandlingUserInputStatePusher inputStatePusher(true); dom::AutoHandlingUserInputStatePusher inputStatePusher(true);
// XXXbz: Can we actually have a non-element content here? // XXXbz: Can we actually have a non-element content here?
RefPtr<Element> element = RefPtr<Element> element =
focusContent->IsElement() ? focusContent->AsElement() : nullptr; focusContent->IsElement() ? focusContent->AsElement() : nullptr;
@ -2074,7 +2074,7 @@ RootAccessible* Accessible::RootAccessible() const {
} }
nsCOMPtr<nsIDocShellTreeItem> root; nsCOMPtr<nsIDocShellTreeItem> root;
docShell->GetRootTreeItem(getter_AddRefs(root)); docShell->GetInProcessRootTreeItem(getter_AddRefs(root));
NS_ASSERTION(root, "No root content tree item"); NS_ASSERTION(root, "No root content tree item");
if (!root) { if (!root) {
return nullptr; return nullptr;
@ -2106,10 +2106,13 @@ bool Accessible::InsertChildAt(uint32_t aIndex, Accessible* aChild) {
if (!aChild) return false; if (!aChild) return false;
if (aIndex == mChildren.Length()) { if (aIndex == mChildren.Length()) {
if (!mChildren.AppendElement(aChild)) return false; // XXX(Bug 1631371) Check if this should use a fallible operation as it
// pretended earlier.
mChildren.AppendElement(aChild);
} else { } else {
if (!mChildren.InsertElementAt(aIndex, aChild)) return false; // XXX(Bug 1631371) Check if this should use a fallible operation as it
// pretended earlier.
mChildren.InsertElementAt(aIndex, aChild);
MOZ_ASSERT(mStateFlags & eKidsMutating, "Illicit children change"); MOZ_ASSERT(mStateFlags & eKidsMutating, "Illicit children change");

View File

@ -110,8 +110,10 @@ inline void DocAccessible::NotifyOfLoad(uint32_t aLoadEventType) {
} }
inline void DocAccessible::MaybeNotifyOfValueChange(Accessible* aAccessible) { inline void DocAccessible::MaybeNotifyOfValueChange(Accessible* aAccessible) {
if (aAccessible->IsCombobox() || aAccessible->Role() == roles::ENTRY) if (aAccessible->IsCombobox() || aAccessible->Role() == roles::ENTRY ||
aAccessible->Role() == roles::SPINBUTTON) {
FireDelayedEvent(nsIAccessibleEvent::EVENT_TEXT_VALUE_CHANGE, aAccessible); FireDelayedEvent(nsIAccessibleEvent::EVENT_TEXT_VALUE_CHANGE, aAccessible);
}
} }
inline Accessible* DocAccessible::GetAccessibleEvenIfNotInMapOrContainer( inline Accessible* DocAccessible::GetAccessibleEvenIfNotInMapOrContainer(

View File

@ -35,15 +35,16 @@
#include "nsFocusManager.h" #include "nsFocusManager.h"
#include "mozilla/ArrayUtils.h" #include "mozilla/ArrayUtils.h"
#include "mozilla/Assertions.h" #include "mozilla/Assertions.h"
#include "mozilla/EventStateManager.h"
#include "mozilla/EventStates.h" #include "mozilla/EventStates.h"
#include "mozilla/HTMLEditor.h" #include "mozilla/HTMLEditor.h"
#include "mozilla/PresShell.h" #include "mozilla/PresShell.h"
#include "mozilla/TextEditor.h" #include "mozilla/TextEditor.h"
#include "mozilla/dom/AncestorIterator.h"
#include "mozilla/dom/BrowserChild.h" #include "mozilla/dom/BrowserChild.h"
#include "mozilla/dom/DocumentType.h" #include "mozilla/dom/DocumentType.h"
#include "mozilla/dom/Element.h" #include "mozilla/dom/Element.h"
#include "mozilla/dom/MutationEventBinding.h" #include "mozilla/dom/MutationEventBinding.h"
#include "mozilla/dom/UserActivation.h"
using namespace mozilla; using namespace mozilla;
using namespace mozilla::a11y; using namespace mozilla::a11y;
@ -290,7 +291,7 @@ void DocAccessible::TakeFocus() const {
// Focus the document. // Focus the document.
nsFocusManager* fm = nsFocusManager::GetFocusManager(); nsFocusManager* fm = nsFocusManager::GetFocusManager();
RefPtr<dom::Element> newFocus; RefPtr<dom::Element> newFocus;
AutoHandlingUserInputStatePusher inputStatePusher(true); dom::AutoHandlingUserInputStatePusher inputStatePusher(true);
fm->MoveFocus(mDocumentNode->GetWindow(), nullptr, fm->MoveFocus(mDocumentNode->GetWindow(), nullptr,
nsFocusManager::MOVEFOCUS_ROOT, 0, getter_AddRefs(newFocus)); nsFocusManager::MOVEFOCUS_ROOT, 0, getter_AddRefs(newFocus));
} }
@ -1136,24 +1137,20 @@ Accessible* DocAccessible::GetAccessibleOrContainer(
return nullptr; return nullptr;
} }
nsINode* currNode = nullptr; nsINode* start = aNode;
if (aNode->IsShadowRoot()) { if (auto* shadowRoot = dom::ShadowRoot::FromNode(aNode)) {
// This can happen, for example, when called within // This can happen, for example, when called within
// SelectionManager::ProcessSelectionChanged due to focusing a direct // SelectionManager::ProcessSelectionChanged due to focusing a direct
// child of a shadow root. // child of a shadow root.
// GetFlattenedTreeParent works on children of a shadow root, but not the // GetFlattenedTreeParent works on children of a shadow root, but not the
// shadow root itself. // shadow root itself.
const dom::ShadowRoot* shadowRoot = dom::ShadowRoot::FromNode(aNode); start = shadowRoot->GetHost();
currNode = shadowRoot->GetHost(); if (!start) {
if (!currNode) {
return nullptr; return nullptr;
} }
} else {
currNode = aNode;
} }
MOZ_ASSERT(currNode); for (nsINode* currNode : dom::InclusiveFlatTreeAncestors(*start)) {
for (; currNode; currNode = currNode->GetFlattenedTreeParentNode()) {
// No container if is inside of aria-hidden subtree. // No container if is inside of aria-hidden subtree.
if (aNoContainerIfPruned && currNode->IsElement() && if (aNoContainerIfPruned && currNode->IsElement() &&
aria::HasDefinedARIAHidden(currNode->AsElement())) { aria::HasDefinedARIAHidden(currNode->AsElement())) {
@ -1218,7 +1215,7 @@ void DocAccessible::BindToDocument(Accessible* aAccessible,
mNodeToAccessibleMap.Put(aAccessible->GetNode(), aAccessible); mNodeToAccessibleMap.Put(aAccessible->GetNode(), aAccessible);
// Put into unique ID cache. // Put into unique ID cache.
mAccessibleCache.Put(aAccessible->UniqueID(), aAccessible); mAccessibleCache.Put(aAccessible->UniqueID(), RefPtr{aAccessible});
aAccessible->SetRoleMapEntry(aRoleMapEntry); aAccessible->SetRoleMapEntry(aRoleMapEntry);
@ -1639,7 +1636,7 @@ class InsertIterator final {
MOZ_ASSERT(aNodes, "No nodes to search for accessible elements"); MOZ_ASSERT(aNodes, "No nodes to search for accessible elements");
MOZ_COUNT_CTOR(InsertIterator); MOZ_COUNT_CTOR(InsertIterator);
} }
~InsertIterator() { MOZ_COUNT_DTOR(InsertIterator); } MOZ_COUNTED_DTOR(InsertIterator)
Accessible* Context() const { return mWalker.Context(); } Accessible* Context() const { return mWalker.Context(); }
Accessible* Child() const { return mChild; } Accessible* Child() const { return mChild; }
@ -2287,7 +2284,7 @@ bool DocAccessible::IsLoadEventTarget() const {
// Return true if it's either: // Return true if it's either:
// a) tab document; // a) tab document;
nsCOMPtr<nsIDocShellTreeItem> rootTreeItem; nsCOMPtr<nsIDocShellTreeItem> rootTreeItem;
treeItem->GetRootTreeItem(getter_AddRefs(rootTreeItem)); treeItem->GetInProcessRootTreeItem(getter_AddRefs(rootTreeItem));
if (parentTreeItem == rootTreeItem) return true; if (parentTreeItem == rootTreeItem) return true;
// b) frame/iframe document and its parent document is not in loading state // b) frame/iframe document and its parent document is not in loading state

View File

@ -432,7 +432,10 @@ class DocAccessible : public HyperTextAccessibleWrap,
* accessibles. * accessibles.
*/ */
bool AppendChildDocument(DocAccessible* aChildDocument) { bool AppendChildDocument(DocAccessible* aChildDocument) {
return mChildDocuments.AppendElement(aChildDocument); // XXX(Bug 1631371) Check if this should use a fallible operation as it
// pretended earlier, or change the return type to void.
mChildDocuments.AppendElement(aChildDocument);
return true;
} }
/** /**

View File

@ -68,7 +68,7 @@ role HyperTextAccessible::NativeRole() const {
uint64_t HyperTextAccessible::NativeState() const { uint64_t HyperTextAccessible::NativeState() const {
uint64_t states = AccessibleWrap::NativeState(); uint64_t states = AccessibleWrap::NativeState();
if (mContent->AsElement()->State().HasState(NS_EVENT_STATE_MOZ_READWRITE)) { if (mContent->AsElement()->State().HasState(NS_EVENT_STATE_READWRITE)) {
states |= states::EDITABLE; states |= states::EDITABLE;
} else if (mContent->IsHTMLElement(nsGkAtoms::article)) { } else if (mContent->IsHTMLElement(nsGkAtoms::article)) {
@ -324,7 +324,7 @@ static nsIContent* GetElementAsContentOf(nsINode* aNode) {
bool HyperTextAccessible::OffsetsToDOMRange(int32_t aStartOffset, bool HyperTextAccessible::OffsetsToDOMRange(int32_t aStartOffset,
int32_t aEndOffset, int32_t aEndOffset,
nsRange* aRange) { nsRange* aRange) const {
DOMPoint startPoint = OffsetToDOMPoint(aStartOffset); DOMPoint startPoint = OffsetToDOMPoint(aStartOffset);
if (!startPoint.node) return false; if (!startPoint.node) return false;
@ -357,7 +357,7 @@ bool HyperTextAccessible::OffsetsToDOMRange(int32_t aStartOffset,
return true; return true;
} }
DOMPoint HyperTextAccessible::OffsetToDOMPoint(int32_t aOffset) { DOMPoint HyperTextAccessible::OffsetToDOMPoint(int32_t aOffset) const {
// 0 offset is valid even if no children. In this case the associated editor // 0 offset is valid even if no children. In this case the associated editor
// is empty so return a DOM point for editor root element. // is empty so return a DOM point for editor root element.
if (aOffset == 0) { if (aOffset == 0) {
@ -404,7 +404,7 @@ DOMPoint HyperTextAccessible::OffsetToDOMPoint(int32_t aOffset) {
} }
DOMPoint HyperTextAccessible::ClosestNotGeneratedDOMPoint( DOMPoint HyperTextAccessible::ClosestNotGeneratedDOMPoint(
const DOMPoint& aDOMPoint, nsIContent* aElementContent) { const DOMPoint& aDOMPoint, nsIContent* aElementContent) const {
MOZ_ASSERT(aDOMPoint.node, "The node must not be null"); MOZ_ASSERT(aDOMPoint.node, "The node must not be null");
// ::before pseudo element // ::before pseudo element
@ -521,8 +521,10 @@ uint32_t HyperTextAccessible::FindOffset(uint32_t aOffset,
nsresult rv = frameAtOffset->PeekOffset(&pos); nsresult rv = frameAtOffset->PeekOffset(&pos);
// PeekOffset fails on last/first lines of the text in certain cases. // PeekOffset fails on last/first lines of the text in certain cases.
bool fallBackToSelectEndLine = false;
if (NS_FAILED(rv) && aAmount == eSelectLine) { if (NS_FAILED(rv) && aAmount == eSelectLine) {
pos.mAmount = (aDirection == eDirNext) ? eSelectEndLine : eSelectBeginLine; fallBackToSelectEndLine = aDirection == eDirNext;
pos.mAmount = fallBackToSelectEndLine ? eSelectEndLine : eSelectBeginLine;
frameAtOffset->PeekOffset(&pos); frameAtOffset->PeekOffset(&pos);
} }
if (!pos.mResultContent) { if (!pos.mResultContent) {
@ -534,6 +536,14 @@ uint32_t HyperTextAccessible::FindOffset(uint32_t aOffset,
uint32_t hyperTextOffset = DOMPointToOffset( uint32_t hyperTextOffset = DOMPointToOffset(
pos.mResultContent, pos.mContentOffset, aDirection == eDirNext); pos.mResultContent, pos.mContentOffset, aDirection == eDirNext);
if (fallBackToSelectEndLine && IsLineEndCharAt(hyperTextOffset)) {
// We used eSelectEndLine, but the caller requested eSelectLine.
// If there's a '\n' at the end of the line, eSelectEndLine will stop
// on it rather than after it. This is not what we want, since the caller
// wants the next line, not the same line.
++hyperTextOffset;
}
if (aDirection == eDirPrevious) { if (aDirection == eDirPrevious) {
// If we reached the end during search, this means we didn't find the DOM // If we reached the end during search, this means we didn't find the DOM
// point and we're actually at the start of the paragraph // point and we're actually at the start of the paragraph
@ -1260,13 +1270,15 @@ nsresult HyperTextAccessible::SetSelectionRange(int32_t aStartPos,
// some input controls // some input controls
if (isFocusable) TakeFocus(); if (isFocusable) TakeFocus();
dom::Selection* domSel = DOMSelection(); RefPtr<dom::Selection> domSel = DOMSelection();
NS_ENSURE_STATE(domSel); NS_ENSURE_STATE(domSel);
// Set up the selection. // Set up the selection.
for (int32_t idx = domSel->RangeCount() - 1; idx > 0; idx--) for (int32_t idx = domSel->RangeCount() - 1; idx > 0; idx--) {
domSel->RemoveRangeAndUnselectFramesAndNotifyListeners( RefPtr<nsRange> range{domSel->GetRangeAt(idx)};
*domSel->GetRangeAt(idx), IgnoreErrors()); domSel->RemoveRangeAndUnselectFramesAndNotifyListeners(*range,
IgnoreErrors());
}
SetSelectionBoundsAt(0, aStartPos, aEndPos); SetSelectionBoundsAt(0, aStartPos, aEndPos);
// Make sure it is visible // Make sure it is visible
@ -1552,15 +1564,16 @@ bool HyperTextAccessible::SetSelectionBoundsAt(int32_t aSelectionNum,
return false; return false;
} }
dom::Selection* domSel = DOMSelection(); RefPtr<dom::Selection> domSel = DOMSelection();
if (!domSel) return false; if (!domSel) return false;
RefPtr<nsRange> range; RefPtr<nsRange> range;
uint32_t rangeCount = domSel->RangeCount(); uint32_t rangeCount = domSel->RangeCount();
if (aSelectionNum == static_cast<int32_t>(rangeCount)) if (aSelectionNum == static_cast<int32_t>(rangeCount)) {
range = new nsRange(mContent); range = nsRange::Create(mContent);
else } else {
range = domSel->GetRangeAt(aSelectionNum); range = domSel->GetRangeAt(aSelectionNum);
}
if (!range) return false; if (!range) return false;
@ -1589,22 +1602,23 @@ bool HyperTextAccessible::SetSelectionBoundsAt(int32_t aSelectionNum,
} }
bool HyperTextAccessible::RemoveFromSelection(int32_t aSelectionNum) { bool HyperTextAccessible::RemoveFromSelection(int32_t aSelectionNum) {
dom::Selection* domSel = DOMSelection(); RefPtr<dom::Selection> domSel = DOMSelection();
if (!domSel) return false; if (!domSel) return false;
if (aSelectionNum < 0 || if (aSelectionNum < 0 ||
aSelectionNum >= static_cast<int32_t>(domSel->RangeCount())) aSelectionNum >= static_cast<int32_t>(domSel->RangeCount()))
return false; return false;
domSel->RemoveRangeAndUnselectFramesAndNotifyListeners( const RefPtr<nsRange> range{domSel->GetRangeAt(aSelectionNum)};
*domSel->GetRangeAt(aSelectionNum), IgnoreErrors()); domSel->RemoveRangeAndUnselectFramesAndNotifyListeners(*range,
IgnoreErrors());
return true; return true;
} }
void HyperTextAccessible::ScrollSubstringTo(int32_t aStartOffset, void HyperTextAccessible::ScrollSubstringTo(int32_t aStartOffset,
int32_t aEndOffset, int32_t aEndOffset,
uint32_t aScrollType) { uint32_t aScrollType) {
RefPtr<nsRange> range = new nsRange(mContent); RefPtr<nsRange> range = nsRange::Create(mContent);
if (OffsetsToDOMRange(aStartOffset, aEndOffset, range)) if (OffsetsToDOMRange(aStartOffset, aEndOffset, range))
nsCoreUtils::ScrollSubstringTo(GetFrame(), range, aScrollType); nsCoreUtils::ScrollSubstringTo(GetFrame(), range, aScrollType);
} }
@ -1619,7 +1633,7 @@ void HyperTextAccessible::ScrollSubstringToPoint(int32_t aStartOffset,
nsIntPoint coords = nsIntPoint coords =
nsAccUtils::ConvertToScreenCoords(aX, aY, aCoordinateType, this); nsAccUtils::ConvertToScreenCoords(aX, aY, aCoordinateType, this);
RefPtr<nsRange> range = new nsRange(mContent); RefPtr<nsRange> range = nsRange::Create(mContent);
if (!OffsetsToDOMRange(aStartOffset, aEndOffset, range)) return; if (!OffsetsToDOMRange(aStartOffset, aEndOffset, range)) return;
nsPresContext* presContext = frame->PresContext(); nsPresContext* presContext = frame->PresContext();
@ -1683,7 +1697,7 @@ void HyperTextAccessible::SelectionRanges(
aRanges->SetCapacity(sel->RangeCount()); aRanges->SetCapacity(sel->RangeCount());
for (uint32_t idx = 0; idx < sel->RangeCount(); idx++) { for (uint32_t idx = 0; idx < sel->RangeCount(); idx++) {
nsRange* DOMRange = sel->GetRangeAt(idx); const nsRange* DOMRange = sel->GetRangeAt(idx);
HyperTextAccessible* startContainer = HyperTextAccessible* startContainer =
nsAccUtils::GetTextContainer(DOMRange->GetStartContainer()); nsAccUtils::GetTextContainer(DOMRange->GetStartContainer());
HyperTextAccessible* endContainer = HyperTextAccessible* endContainer =
@ -2003,7 +2017,7 @@ void HyperTextAccessible::GetSpellTextAttr(
uint32_t startOffset = 0, endOffset = 0; uint32_t startOffset = 0, endOffset = 0;
for (int32_t idx = 0; idx < rangeCount; idx++) { for (int32_t idx = 0; idx < rangeCount; idx++) {
nsRange* range = domSel->GetRangeAt(idx); const nsRange* range = domSel->GetRangeAt(idx);
if (range->Collapsed()) continue; if (range->Collapsed()) continue;
// See if the point comes after the range in which case we must continue in // See if the point comes after the range in which case we must continue in
@ -2057,7 +2071,7 @@ void HyperTextAccessible::GetSpellTextAttr(
endOffset = DOMPointToOffset(startNode, startNodeOffset); endOffset = DOMPointToOffset(startNode, startNodeOffset);
if (idx > 0) { if (idx > 0) {
nsRange* prevRange = domSel->GetRangeAt(idx - 1); const nsRange* prevRange = domSel->GetRangeAt(idx - 1);
startOffset = DOMPointToOffset(prevRange->GetEndContainer(), startOffset = DOMPointToOffset(prevRange->GetEndContainer(),
prevRange->EndOffset()); prevRange->EndOffset());
} }
@ -2077,7 +2091,7 @@ void HyperTextAccessible::GetSpellTextAttr(
// the point is not in a range, that we do not need to compute an end offset, // the point is not in a range, that we do not need to compute an end offset,
// and that we should use the end offset of the last range to compute the // and that we should use the end offset of the last range to compute the
// start offset of the text attribute range. // start offset of the text attribute range.
nsRange* prevRange = domSel->GetRangeAt(rangeCount - 1); const nsRange* prevRange = domSel->GetRangeAt(rangeCount - 1);
startOffset = startOffset =
DOMPointToOffset(prevRange->GetEndContainer(), prevRange->EndOffset()); DOMPointToOffset(prevRange->GetEndContainer(), prevRange->EndOffset());

View File

@ -142,7 +142,7 @@ class HyperTextAccessible : public AccessibleWrap {
* @return true if conversion was successful * @return true if conversion was successful
*/ */
bool OffsetsToDOMRange(int32_t aStartOffset, int32_t aEndOffset, bool OffsetsToDOMRange(int32_t aStartOffset, int32_t aEndOffset,
nsRange* aRange); nsRange* aRange) const;
/** /**
* Convert the given offset into DOM point. * Convert the given offset into DOM point.
@ -151,7 +151,7 @@ class HyperTextAccessible : public AccessibleWrap {
* if before embedded object then (parent node, indexInParent), if after then * if before embedded object then (parent node, indexInParent), if after then
* (parent node, indexInParent + 1). * (parent node, indexInParent + 1).
*/ */
DOMPoint OffsetToDOMPoint(int32_t aOffset); DOMPoint OffsetToDOMPoint(int32_t aOffset) const;
/** /**
* Return true if the used ARIA role (if any) allows the hypertext accessible * Return true if the used ARIA role (if any) allows the hypertext accessible
@ -340,8 +340,10 @@ class HyperTextAccessible : public AccessibleWrap {
* Changes the start and end offset of the specified selection. * Changes the start and end offset of the specified selection.
* @return true if succeeded * @return true if succeeded
*/ */
bool SetSelectionBoundsAt(int32_t aSelectionNum, int32_t aStartOffset, // TODO: annotate this with `MOZ_CAN_RUN_SCRIPT` instead.
int32_t aEndOffset); MOZ_CAN_RUN_SCRIPT_BOUNDARY bool SetSelectionBoundsAt(int32_t aSelectionNum,
int32_t aStartOffset,
int32_t aEndOffset);
/** /**
* Adds a selection bounded by the specified offsets. * Adds a selection bounded by the specified offsets.
@ -353,7 +355,8 @@ class HyperTextAccessible : public AccessibleWrap {
* Removes the specified selection. * Removes the specified selection.
* @return true if succeeded * @return true if succeeded
*/ */
bool RemoveFromSelection(int32_t aSelectionNum); // TODO: annotate this with `MOZ_CAN_RUN_SCRIPT` instead.
MOZ_CAN_RUN_SCRIPT_BOUNDARY bool RemoveFromSelection(int32_t aSelectionNum);
/** /**
* Scroll the given text range into view. * Scroll the given text range into view.
@ -507,7 +510,9 @@ class HyperTextAccessible : public AccessibleWrap {
void GetSelectionDOMRanges(SelectionType aSelectionType, void GetSelectionDOMRanges(SelectionType aSelectionType,
nsTArray<nsRange*>* aRanges); nsTArray<nsRange*>* aRanges);
nsresult SetSelectionRange(int32_t aStartPos, int32_t aEndPos); // TODO: annotate this with `MOZ_CAN_RUN_SCRIPT` instead.
MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult SetSelectionRange(int32_t aStartPos,
int32_t aEndPos);
/** /**
* Convert the given DOM point to a DOM point in non-generated contents. * Convert the given DOM point to a DOM point in non-generated contents.
@ -524,7 +529,7 @@ class HyperTextAccessible : public AccessibleWrap {
* contents. * contents.
*/ */
DOMPoint ClosestNotGeneratedDOMPoint(const DOMPoint& aDOMPoint, DOMPoint ClosestNotGeneratedDOMPoint(const DOMPoint& aDOMPoint,
nsIContent* aElementContent); nsIContent* aElementContent) const;
// Helpers // Helpers
nsresult GetDOMPointByFrameOffset(nsIFrame* aFrame, int32_t aOffset, nsresult GetDOMPointByFrameOffset(nsIFrame* aFrame, int32_t aOffset,

View File

@ -47,13 +47,30 @@ uint64_t ImageAccessible::NativeState() const {
content->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST, content->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
getter_AddRefs(imageRequest)); getter_AddRefs(imageRequest));
nsCOMPtr<imgIContainer> imgContainer; if (imageRequest) {
if (imageRequest) imageRequest->GetImage(getter_AddRefs(imgContainer)); nsCOMPtr<imgIContainer> imgContainer;
imageRequest->GetImage(getter_AddRefs(imgContainer));
if (imgContainer) {
bool animated = false;
imgContainer->GetAnimated(&animated);
if (animated) {
state |= states::ANIMATED;
}
}
if (imgContainer) { nsIFrame* frame = GetFrame();
bool animated = false; MOZ_ASSERT(!frame || frame->AccessibleType() == eImageType ||
imgContainer->GetAnimated(&animated); frame->AccessibleType() == a11y::eHTMLImageMapType);
if (animated) state |= states::ANIMATED; if (frame && !(frame->GetStateBits() & IMAGE_SIZECONSTRAINED)) {
uint32_t status = imgIRequest::STATUS_NONE;
imageRequest->GetImageStatus(&status);
if (!(status & imgIRequest::STATUS_SIZE_AVAILABLE)) {
// The size of this image hasn't been constrained and we haven't loaded
// enough of the image to know its size yet. This means it currently
// has 0 width and height.
state |= states::INVISIBLE;
}
}
} }
return state; return state;

View File

@ -459,7 +459,7 @@ Accessible* HTMLFileInputAccessible::CurrentItem() const {
role HTMLSpinnerAccessible::NativeRole() const { return roles::SPINBUTTON; } role HTMLSpinnerAccessible::NativeRole() const { return roles::SPINBUTTON; }
void HTMLSpinnerAccessible::Value(nsString& aValue) const { void HTMLSpinnerAccessible::Value(nsString& aValue) const {
AccessibleWrap::Value(aValue); HTMLTextFieldAccessible::Value(aValue);
if (!aValue.IsEmpty()) return; if (!aValue.IsEmpty()) return;
// Pass NonSystem as the caller type, to be safe. We don't expect to have a // Pass NonSystem as the caller type, to be safe. We don't expect to have a
@ -468,28 +468,28 @@ void HTMLSpinnerAccessible::Value(nsString& aValue) const {
} }
double HTMLSpinnerAccessible::MaxValue() const { double HTMLSpinnerAccessible::MaxValue() const {
double value = AccessibleWrap::MaxValue(); double value = HTMLTextFieldAccessible::MaxValue();
if (!IsNaN(value)) return value; if (!IsNaN(value)) return value;
return HTMLInputElement::FromNode(mContent)->GetMaximum().toDouble(); return HTMLInputElement::FromNode(mContent)->GetMaximum().toDouble();
} }
double HTMLSpinnerAccessible::MinValue() const { double HTMLSpinnerAccessible::MinValue() const {
double value = AccessibleWrap::MinValue(); double value = HTMLTextFieldAccessible::MinValue();
if (!IsNaN(value)) return value; if (!IsNaN(value)) return value;
return HTMLInputElement::FromNode(mContent)->GetMinimum().toDouble(); return HTMLInputElement::FromNode(mContent)->GetMinimum().toDouble();
} }
double HTMLSpinnerAccessible::Step() const { double HTMLSpinnerAccessible::Step() const {
double value = AccessibleWrap::Step(); double value = HTMLTextFieldAccessible::Step();
if (!IsNaN(value)) return value; if (!IsNaN(value)) return value;
return HTMLInputElement::FromNode(mContent)->GetStep().toDouble(); return HTMLInputElement::FromNode(mContent)->GetStep().toDouble();
} }
double HTMLSpinnerAccessible::CurValue() const { double HTMLSpinnerAccessible::CurValue() const {
double value = AccessibleWrap::CurValue(); double value = HTMLTextFieldAccessible::CurValue();
if (!IsNaN(value)) return value; if (!IsNaN(value)) return value;
return HTMLInputElement::FromNode(mContent)->GetValueAsDecimal().toDouble(); return HTMLInputElement::FromNode(mContent)->GetValueAsDecimal().toDouble();

View File

@ -62,7 +62,7 @@ class HTMLButtonAccessible : public HyperTextAccessibleWrap {
* Accessible for HTML input@type="text", input@type="password", textarea and * Accessible for HTML input@type="text", input@type="password", textarea and
* other HTML text controls. * other HTML text controls.
*/ */
class HTMLTextFieldAccessible final : public HyperTextAccessibleWrap { class HTMLTextFieldAccessible : public HyperTextAccessibleWrap {
public: public:
enum { eAction_Click = 0 }; enum { eAction_Click = 0 };
@ -128,10 +128,10 @@ class HTMLFileInputAccessible : public HyperTextAccessibleWrap {
/** /**
* Used for HTML input@type="number". * Used for HTML input@type="number".
*/ */
class HTMLSpinnerAccessible : public AccessibleWrap { class HTMLSpinnerAccessible final : public HTMLTextFieldAccessible {
public: public:
HTMLSpinnerAccessible(nsIContent* aContent, DocAccessible* aDoc) HTMLSpinnerAccessible(nsIContent* aContent, DocAccessible* aDoc)
: AccessibleWrap(aContent, aDoc) { : HTMLTextFieldAccessible(aContent, aDoc) {
mStateFlags |= eHasNumericValue; mStateFlags |= eHasNumericValue;
} }

View File

@ -9,7 +9,7 @@
#include "Role.h" #include "Role.h"
#include "States.h" #include "States.h"
#include "nsContainerFrame.h" #include "nsBulletFrame.h"
#include "nsLayoutUtils.h" #include "nsLayoutUtils.h"
using namespace mozilla; using namespace mozilla;
@ -36,10 +36,14 @@ HTMLLIAccessible::HTMLLIAccessible(nsIContent* aContent, DocAccessible* aDoc)
: HyperTextAccessibleWrap(aContent, aDoc), mBullet(nullptr) { : HyperTextAccessibleWrap(aContent, aDoc), mBullet(nullptr) {
mType = eHTMLLiType; mType = eHTMLLiType;
if (nsLayoutUtils::GetMarkerFrame(aContent)) { if (nsBulletFrame* bulletFrame =
mBullet = new HTMLListBulletAccessible(mContent, mDoc); do_QueryFrame(nsLayoutUtils::GetMarkerFrame(aContent))) {
Document()->BindToDocument(mBullet, nullptr); const nsStyleList* styleList = bulletFrame->StyleList();
AppendChild(mBullet); if (styleList->GetListStyleImage() || !styleList->mCounterStyle.IsNone()) {
mBullet = new HTMLListBulletAccessible(mContent, mDoc);
Document()->BindToDocument(mBullet, nullptr);
AppendChild(mBullet);
}
} }
} }
@ -123,10 +127,20 @@ ENameValueFlag HTMLListBulletAccessible::Name(nsString& aName) const {
aName.Truncate(); aName.Truncate();
// Native anonymous content, ARIA can't be used. Get list bullet text. // Native anonymous content, ARIA can't be used. Get list bullet text.
if (nsContainerFrame* frame = do_QueryFrame(mContent->GetPrimaryFrame())) { nsBulletFrame* frame = do_QueryFrame(GetFrame());
frame->GetSpokenMarkerText(aName); if (!frame) {
return eNameOK;
} }
if (frame->StyleList()->GetListStyleImage()) {
// Bullet is an image, so use default bullet character.
const char16_t kDiscCharacter = 0x2022;
aName.Assign(kDiscCharacter);
aName.Append(' ');
return eNameOK;
}
frame->GetSpokenText(aName);
return eNameOK; return eNameOK;
} }

View File

@ -658,36 +658,36 @@ bool HTMLTableAccessible::IsCellSelected(uint32_t aRowIdx, uint32_t aColIdx) {
void HTMLTableAccessible::SelectRow(uint32_t aRowIdx) { void HTMLTableAccessible::SelectRow(uint32_t aRowIdx) {
DebugOnly<nsresult> rv = DebugOnly<nsresult> rv =
RemoveRowsOrColumnsFromSelection(aRowIdx, TableSelection::Row, true); RemoveRowsOrColumnsFromSelection(aRowIdx, TableSelectionMode::Row, true);
NS_ASSERTION(NS_SUCCEEDED(rv), NS_ASSERTION(NS_SUCCEEDED(rv),
"RemoveRowsOrColumnsFromSelection() Shouldn't fail!"); "RemoveRowsOrColumnsFromSelection() Shouldn't fail!");
AddRowOrColumnToSelection(aRowIdx, TableSelection::Row); AddRowOrColumnToSelection(aRowIdx, TableSelectionMode::Row);
} }
void HTMLTableAccessible::SelectCol(uint32_t aColIdx) { void HTMLTableAccessible::SelectCol(uint32_t aColIdx) {
DebugOnly<nsresult> rv = DebugOnly<nsresult> rv = RemoveRowsOrColumnsFromSelection(
RemoveRowsOrColumnsFromSelection(aColIdx, TableSelection::Column, true); aColIdx, TableSelectionMode::Column, true);
NS_ASSERTION(NS_SUCCEEDED(rv), NS_ASSERTION(NS_SUCCEEDED(rv),
"RemoveRowsOrColumnsFromSelection() Shouldn't fail!"); "RemoveRowsOrColumnsFromSelection() Shouldn't fail!");
AddRowOrColumnToSelection(aColIdx, TableSelection::Column); AddRowOrColumnToSelection(aColIdx, TableSelectionMode::Column);
} }
void HTMLTableAccessible::UnselectRow(uint32_t aRowIdx) { void HTMLTableAccessible::UnselectRow(uint32_t aRowIdx) {
RemoveRowsOrColumnsFromSelection(aRowIdx, TableSelection::Row, false); RemoveRowsOrColumnsFromSelection(aRowIdx, TableSelectionMode::Row, false);
} }
void HTMLTableAccessible::UnselectCol(uint32_t aColIdx) { void HTMLTableAccessible::UnselectCol(uint32_t aColIdx) {
RemoveRowsOrColumnsFromSelection(aColIdx, TableSelection::Column, false); RemoveRowsOrColumnsFromSelection(aColIdx, TableSelectionMode::Column, false);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// HTMLTableAccessible: protected implementation // HTMLTableAccessible: protected implementation
nsresult HTMLTableAccessible::AddRowOrColumnToSelection( nsresult HTMLTableAccessible::AddRowOrColumnToSelection(
int32_t aIndex, TableSelection aTarget) { int32_t aIndex, TableSelectionMode aTarget) {
bool doSelectRow = (aTarget == TableSelection::Row); bool doSelectRow = (aTarget == TableSelectionMode::Row);
nsTableWrapperFrame* tableFrame = do_QueryFrame(mContent->GetPrimaryFrame()); nsTableWrapperFrame* tableFrame = do_QueryFrame(mContent->GetPrimaryFrame());
if (!tableFrame) return NS_OK; if (!tableFrame) return NS_OK;
@ -716,7 +716,7 @@ nsresult HTMLTableAccessible::AddRowOrColumnToSelection(
} }
nsresult HTMLTableAccessible::RemoveRowsOrColumnsFromSelection( nsresult HTMLTableAccessible::RemoveRowsOrColumnsFromSelection(
int32_t aIndex, TableSelection aTarget, bool aIsOuter) { int32_t aIndex, TableSelectionMode aTarget, bool aIsOuter) {
nsTableWrapperFrame* tableFrame = do_QueryFrame(mContent->GetPrimaryFrame()); nsTableWrapperFrame* tableFrame = do_QueryFrame(mContent->GetPrimaryFrame());
if (!tableFrame) return NS_OK; if (!tableFrame) return NS_OK;
@ -724,7 +724,7 @@ nsresult HTMLTableAccessible::RemoveRowsOrColumnsFromSelection(
RefPtr<nsFrameSelection> tableSelection = RefPtr<nsFrameSelection> tableSelection =
const_cast<nsFrameSelection*>(presShell->ConstFrameSelection()); const_cast<nsFrameSelection*>(presShell->ConstFrameSelection());
bool doUnselectRow = (aTarget == TableSelection::Row); bool doUnselectRow = (aTarget == TableSelectionMode::Row);
uint32_t count = doUnselectRow ? ColCount() : RowCount(); uint32_t count = doUnselectRow ? ColCount() : RowCount();
int32_t startRowIdx = doUnselectRow ? aIndex : 0; int32_t startRowIdx = doUnselectRow ? aIndex : 0;

View File

@ -14,7 +14,7 @@ class nsTableCellFrame;
namespace mozilla { namespace mozilla {
enum class TableSelection : uint32_t; enum class TableSelectionMode : uint32_t;
namespace a11y { namespace a11y {
@ -176,7 +176,8 @@ class HTMLTableAccessible : public HyperTextAccessibleWrap,
* @param aTarget [in] indicates what should be selected, either row or * @param aTarget [in] indicates what should be selected, either row or
* column (see nsFrameSelection) * column (see nsFrameSelection)
*/ */
nsresult AddRowOrColumnToSelection(int32_t aIndex, TableSelection aTarget); nsresult AddRowOrColumnToSelection(int32_t aIndex,
TableSelectionMode aTarget);
/** /**
* Removes rows or columns at the given index or outside it from selection. * Removes rows or columns at the given index or outside it from selection.
@ -188,7 +189,7 @@ class HTMLTableAccessible : public HyperTextAccessibleWrap,
* should be unselected only * should be unselected only
*/ */
nsresult RemoveRowsOrColumnsFromSelection(int32_t aIndex, nsresult RemoveRowsOrColumnsFromSelection(int32_t aIndex,
TableSelection aTarget, TableSelectionMode aTarget,
bool aIsOuter); bool aIsOuter);
#ifdef SHOW_LAYOUT_HEURISTIC #ifdef SHOW_LAYOUT_HEURISTIC

View File

@ -25,7 +25,7 @@ class ProxyAccessible : public ProxyAccessibleBase<ProxyAccessible> {
MOZ_COUNT_CTOR(ProxyAccessible); MOZ_COUNT_CTOR(ProxyAccessible);
} }
~ProxyAccessible() { MOZ_COUNT_DTOR(ProxyAccessible); } MOZ_COUNTED_DTOR(ProxyAccessible)
#include "mozilla/a11y/ProxyAccessibleShared.h" #include "mozilla/a11y/ProxyAccessibleShared.h"

View File

@ -2,11 +2,10 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this # 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/. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
# With --disable-accessibility, we need to compile PDocAccessible.ipdl, but
# not the C++.
IPDL_SOURCES += ['PDocAccessible.ipdl']
if CONFIG['ACCESSIBILITY']: if CONFIG['ACCESSIBILITY']:
IPDL_SOURCES += ['PDocAccessible.ipdl']
EXPORTS.mozilla.a11y += [ EXPORTS.mozilla.a11y += [
'DocAccessibleChild.h', 'DocAccessibleChild.h',
'ProxyAccessible.h', 'ProxyAccessible.h',

View File

@ -26,7 +26,7 @@ class ProxyAccessible : public ProxyAccessibleBase<ProxyAccessible> {
MOZ_COUNT_CTOR(ProxyAccessible); MOZ_COUNT_CTOR(ProxyAccessible);
} }
~ProxyAccessible() { MOZ_COUNT_DTOR(ProxyAccessible); } MOZ_COUNTED_DTOR(ProxyAccessible)
#include "mozilla/a11y/ProxyAccessibleShared.h" #include "mozilla/a11y/ProxyAccessibleShared.h"

View File

@ -8,15 +8,9 @@ if CONFIG['COMPILE_ENVIRONMENT'] and CONFIG['ACCESSIBILITY']:
'typelib', 'typelib',
] ]
# With --disable-accessibility, we need to compile PDocAccessible.ipdl (which
# also depends on COMPtrTypes.h), but not the C++.
IPDL_SOURCES += ['PDocAccessible.ipdl']
EXPORTS.mozilla.a11y += [
'COMPtrTypes.h',
]
if CONFIG['ACCESSIBILITY']: if CONFIG['ACCESSIBILITY']:
IPDL_SOURCES += ['PDocAccessible.ipdl']
if not CONFIG['HAVE_64BIT_BUILD']: if not CONFIG['HAVE_64BIT_BUILD']:
EXPORTS += [ EXPORTS += [
'IAccessible32.manifest', 'IAccessible32.manifest',
@ -27,6 +21,7 @@ if CONFIG['ACCESSIBILITY']:
] ]
EXPORTS.mozilla.a11y += [ EXPORTS.mozilla.a11y += [
'COMPtrTypes.h',
'DocAccessibleChild.h', 'DocAccessibleChild.h',
'HandlerProvider.h', 'HandlerProvider.h',
'PlatformChild.h', 'PlatformChild.h',

View File

@ -88,6 +88,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=558036
testAttrs("statusChild", {"container-live": "polite"}, true); testAttrs("statusChild", {"container-live": "polite"}, true);
testAttrs("timerChild", {"container-live": "off"}, true); testAttrs("timerChild", {"container-live": "off"}, true);
testAbsentAttrs("tablistChild", {"container-live": "polite"}); testAbsentAttrs("tablistChild", {"container-live": "polite"});
testAttrs("containerLiveOutput", {"container-live": "polite"}, true);
testAttrs("containerLiveOutput1", {"container-live": "polite"}, true);
testAttrs("containerLiveOutput2", {"container-live": "polite"}, true);
// container-live-role object attribute // container-live-role object attribute
testAttrs("log", {"container-live-role": "log"}, true); testAttrs("log", {"container-live-role": "log"}, true);
@ -121,7 +124,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=558036
testAttrs("search", {"text-input-type": "search"}, true); testAttrs("search", {"text-input-type": "search"}, true);
testAttrs("tel", {"text-input-type": "tel"}, true); testAttrs("tel", {"text-input-type": "tel"}, true);
testAttrs("url", {"text-input-type": "url"}, true); testAttrs("url", {"text-input-type": "url"}, true);
testAttrs(getAccessible("number").firstChild, {"text-input-type": "number"}, true); testAttrs("number", {"text-input-type": "number"}, true);
// ARIA // ARIA
testAttrs("searchbox", {"text-input-type": "search"}, true); testAttrs("searchbox", {"text-input-type": "search"}, true);
@ -166,6 +169,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=558036
<pre id="test"> <pre id="test">
</pre> </pre>
<!-- container live -->
<output id="containerLiveOutput"><div id="containerLiveOutput1"><div id="containerLiveOutput2">Test</div></div></output>
<!-- aria --> <!-- aria -->
<div id="atomic" aria-atomic="true">live region</div> <div id="atomic" aria-atomic="true">live region</div>
<div id="atomic_false" aria-atomic="false">live region</div> <div id="atomic_false" aria-atomic="false">live region</div>

View File

@ -190,7 +190,10 @@
obj = { obj = {
role: ROLE_PARAGRAPH, role: ROLE_PARAGRAPH,
children: [ { role: ROLE_WHITESPACE } ], children: [
{ role: ROLE_WHITESPACE },
{ role: ROLE_WHITESPACE }
]
}; };
testElm("br_container", obj); testElm("br_container", obj);
@ -707,25 +710,9 @@
obj = { obj = {
role: ROLE_SPINBUTTON, role: ROLE_SPINBUTTON,
interfaces: [ nsIAccessibleValue ], interfaces: [ nsIAccessibleValue, nsIAccessibleText, nsIAccessibleEditableText ],
children: [ children: [
{ { role: ROLE_TEXT_LEAF },
role: ROLE_ENTRY,
extraStates: EXT_STATE_EDITABLE | EXT_STATE_SINGLE_LINE,
actions: "activate",
interfaces: [ nsIAccessibleText, nsIAccessibleEditableText ],
children: [
{ role: ROLE_TEXT_LEAF },
],
},
{
role: ROLE_PUSHBUTTON,
actions: "press",
},
{
role: ROLE_PUSHBUTTON,
actions: "press",
},
], ],
}; };
testElm("input_number", obj); testElm("input_number", obj);
@ -1114,7 +1101,7 @@
// HTML:output // HTML:output
obj = { obj = {
role: ROLE_SECTION, role: ROLE_STATUSBAR,
attributes: { "live": "polite" }, attributes: { "live": "polite" },
todo_relations: { todo_relations: {
RELATION_CONTROLLED_BY: "output_input", RELATION_CONTROLLED_BY: "output_input",
@ -1428,7 +1415,7 @@
<p>This is a quotation taken from the Mozilla Developer Center.</p> <p>This is a quotation taken from the Mozilla Developer Center.</p>
</blockquote> </blockquote>
<!-- two BRs, one will be eaten --> <!-- two BRs, both will be present -->
<p id="br_container"><br><br></p> <p id="br_container"><br><br></p>
<button id="button">button</button> <button id="button">button</button>

View File

@ -171,6 +171,8 @@
let shadowSelect = getAccessible("selectShadow").firstChild; let shadowSelect = getAccessible("selectShadow").firstChild;
gQueue.push(new changeSelectValue(shadowSelect, "VK_DOWN", "2")); gQueue.push(new changeSelectValue(shadowSelect, "VK_DOWN", "2"));
gQueue.push(new changeValue("number", "2"));
gQueue.invoke(); // Will call SimpleTest.finish(); gQueue.invoke(); // Will call SimpleTest.finish();
} }
@ -269,5 +271,7 @@
select.appendChild(option); select.appendChild(option);
shadow.appendChild(select); shadow.appendChild(select);
</script> </script>
<input type="number" id="number" value="1">
</body> </body>
</html> </html>

View File

@ -112,12 +112,12 @@
two words two words
</div> </div>
<div id="dbr3">oneword<br/><br/>two words<br/><br/></div> <div id="dbr3">oneword<br/><br/>two words<br/></div>
<div id="e3" contenteditable="true">oneword <div id="e3" contenteditable="true">oneword
two words two words
</div> </div>
<div id="ebr3" contenteditable="true">oneword<br/><br/>two words<br/><br/></div> <div id="ebr3" contenteditable="true">oneword<br/><br/>two words<br/></div>
<textarea id="t3" cols="300">oneword <textarea id="t3" cols="300">oneword
two words two words

View File

@ -84,7 +84,7 @@
testTextAtOffset(2, nsIAccessibleText.BOUNDARY_CHAR, "o", 2, 3, "testbr", testTextAtOffset(2, nsIAccessibleText.BOUNDARY_CHAR, "o", 2, 3, "testbr",
kOk, kOk, kOk); kOk, kOk, kOk);
testTextAtOffset(2, nsIAccessibleText.BOUNDARY_WORD_START, "foo\n", 0, 4, testTextAtOffset(2, nsIAccessibleText.BOUNDARY_WORD_START, "foo\n", 0, 4,
"testbr", kTodo, kOk, kTodo); "testbr", kOk, kOk, kOk);
testTextBeforeOffset(2, nsIAccessibleText.BOUNDARY_LINE_START, "foo\n", testTextBeforeOffset(2, nsIAccessibleText.BOUNDARY_LINE_START, "foo\n",
0, 4, "testbr", kTodo, kOk, kTodo); 0, 4, "testbr", kTodo, kOk, kTodo);

View File

@ -106,10 +106,10 @@
testTextAtOffset([ getAccessible("ht_2").firstChild.firstChild ], testTextAtOffset([ getAccessible("ht_2").firstChild.firstChild ],
BOUNDARY_LINE_START, BOUNDARY_LINE_START,
[ [ 0, 3, "foo", 0, 3 ] ]); [ [ 0, 3, "foo\n", 0, 4 ] ]);
testTextAtOffset([ getAccessible("ht_3").firstChild.firstChild ], testTextAtOffset([ getAccessible("ht_3").firstChild.firstChild ],
BOUNDARY_LINE_START, BOUNDARY_LINE_START,
[ [ 0, 3, "foo\n", 0, 4 ], [ 4, 4, "", 4, 4 ] ]); [ [ 0, 3, "foo\n", 0, 4 ], [ 4, 4, "\n", 4, 5 ] ]);
// //////////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////////////
// 'Hello world ' (\n is rendered as space) // 'Hello world ' (\n is rendered as space)
@ -211,12 +211,12 @@
two words two words
</div> </div>
<div id="ml_divbr" style="border-style:outset;">oneword<br/><br/>two words<br/><br/></div> <div id="ml_divbr" style="border-style:outset;">oneword<br/><br/>two words<br/></div>
<div id="ml_editable" style="border-style:outset;" contenteditable="true">oneword <div id="ml_editable" style="border-style:outset;" contenteditable="true">oneword
two words two words
</div> </div>
<div id="ml_editablebr" contenteditable="true" style="border-style:outset;">oneword<br/><br/>two words<br/><br/></div> <div id="ml_editablebr" contenteditable="true" style="border-style:outset;">oneword<br/><br/>two words<br/></div>
<textarea id="ml_textarea" cols="300">oneword <textarea id="ml_textarea" cols="300">oneword
two words two words

View File

@ -305,12 +305,12 @@
two words two words
</div> </div>
<div id="ml_divbr1">oneword<br/><br/>two words<br/><br/></div> <div id="ml_divbr1">oneword<br/><br/>two words<br/></div>
<div id="ml_ediv1" contenteditable="true">oneword <div id="ml_ediv1" contenteditable="true">oneword
two words two words
</div> </div>
<div id="ml_edivbr1" contenteditable="true">oneword<br/><br/>two words<br/><br/></div> <div id="ml_edivbr1" contenteditable="true">oneword<br/><br/>two words<br/></div>
<textarea id="ml_t1" cols="300">oneword <textarea id="ml_t1" cols="300">oneword
two words two words

View File

@ -126,6 +126,12 @@
]; ];
this.invoke = function changeDOMSelection_invoke() { this.invoke = function changeDOMSelection_invoke() {
// HyperTextAccessible::GetSelectionDOMRanges ignores hidden selections.
// Here we may be focusing an editable element (and thus hiding the
// main document selection), so blur it so that we test what we want to
// test.
document.activeElement.blur();
var sel = window.getSelection(); var sel = window.getSelection();
var range = document.createRange(); var range = document.createRange();
range.setStart(getNode(aNodeID1), aNodeOffset1); range.setStart(getNode(aNodeID1), aNodeOffset1);

View File

@ -199,7 +199,11 @@ function doTest() {
{ TEXT_LEAF: [] }, // text { TEXT_LEAF: [] }, // text
], // end children first line ], // end children first line
}, // end first line }, // end first line
{ SECTION: [] }, // second, blank, line { role: ROLE_SECTION, // Second line
children: [
{ WHITESPACE: [] }, // whitespace
], // end children second line
}, // end second line
{ role: ROLE_SECTION, // Third line { role: ROLE_SECTION, // Third line
children: [ children: [
{ TEXT_LEAF: [] }, // text { TEXT_LEAF: [] }, // text

View File

@ -62,17 +62,12 @@
testAccessibleTree("range", accTree); testAccessibleTree("range", accTree);
// input@type="number" // input@type="number"
accTree = accTree = { SPINBUTTON: [ ] };
{ SPINBUTTON: [
{ ENTRY: [ ] },
{ PUSHBUTTON: [ ] },
{ PUSHBUTTON: [ ] },
] };
testAccessibleTree("number", accTree); testAccessibleTree("number", accTree);
// output // output
accTree = { accTree = {
role: ROLE_SECTION, role: ROLE_STATUSBAR,
children: [ children: [
{ {
role: ROLE_TEXT_LEAF, role: ROLE_TEXT_LEAF,

View File

@ -166,6 +166,63 @@
testAccessibleTree("list10", tree); testAccessibleTree("list10", tree);
// list-style-image
testAccessibleTree("list11", discAccTree);
// list-style: none
tree =
{ LIST: [ // ul
{ LISTITEM: [ // li
{ TEXT_LEAF: [] },
] },
{ LISTITEM: [ // li
{ TEXT_LEAF: [] },
] },
] };
testAccessibleTree("list12", tree);
// ::marker with content
tree = { // ol
role: ROLE_LIST,
children: [
{ // li
role: ROLE_LISTITEM,
children: [
{ // ::marker content text
role: ROLE_STATICTEXT,
name: "foo",
},
{ // ::marker content counter
role: ROLE_STATICTEXT,
name: "1",
},
{
role: ROLE_TEXT_LEAF,
name: "Oranges",
},
],
},
{ // li
role: ROLE_LISTITEM,
children: [
{ // ::marker content text
role: ROLE_STATICTEXT,
name: "foo",
},
{ // ::marker content counter
role: ROLE_STATICTEXT,
name: "2",
},
{
role: ROLE_TEXT_LEAF,
name: "Apples",
},
],
},
],
};
testAccessibleTree("list13", tree);
SimpleTest.finish(); SimpleTest.finish();
} }
@ -266,5 +323,32 @@
<div><dt>item2</td><dd>description</dd></div> <div><dt>item2</td><dd>description</dd></div>
</dl> </dl>
<!-- list-style-image -->
<ul id="list11"
style="list-style-type: none; list-style-image: url('../moz.png');">
<li>Oranges</li>
<li>Apples</li>
<li>Bananas</li>
</ul>
<!-- list-style: none -->
<ul id="list12" style="list-style: none;">
<li>Oranges</li>
<li>Apples</li>
</ul>
<!-- ::marker with content -->
<style>
#list13 li {
counter-increment: list13counter;
}
#list13 li::marker {
content: 'foo' counter(list13counter);
}
</style>
<ol id="list13">
<li>Oranges</li>
<li>Apples</li>
</ol>
</body> </body>
</html> </html>

View File

@ -115,7 +115,7 @@ sdnTextAccessible::scrollToSubstring(unsigned int aStartIndex,
unsigned int aEndIndex) { unsigned int aEndIndex) {
if (mAccessible->IsDefunct()) return CO_E_OBJNOTCONNECTED; if (mAccessible->IsDefunct()) return CO_E_OBJNOTCONNECTED;
RefPtr<nsRange> range = new nsRange(mAccessible->GetContent()); RefPtr<nsRange> range = nsRange::Create(mAccessible->GetContent());
if (NS_FAILED(range->SetStart(mAccessible->GetContent(), aStartIndex))) if (NS_FAILED(range->SetStart(mAccessible->GetContent(), aStartIndex)))
return E_FAIL; return E_FAIL;

View File

@ -109,7 +109,7 @@ uint64_t XULMenuitemAccessible::NativeInteractiveState() const {
if (!menuFrame || !menuFrame->IsOnMenuBar()) { if (!menuFrame || !menuFrame->IsOnMenuBar()) {
skipNavigatingDisabledMenuItem = skipNavigatingDisabledMenuItem =
LookAndFeel::GetInt( LookAndFeel::GetInt(
LookAndFeel::eIntID_SkipNavigatingDisabledMenuItem, 0) != 0; LookAndFeel::IntID::SkipNavigatingDisabledMenuItem, 0) != 0;
} }
if (skipNavigatingDisabledMenuItem) return states::UNAVAILABLE; if (skipNavigatingDisabledMenuItem) return states::UNAVAILABLE;

View File

@ -437,7 +437,7 @@ Accessible* XULTreeAccessible::GetTreeItemAccessible(int32_t aRow) const {
RefPtr<Accessible> treeItem = CreateTreeItemAccessible(aRow); RefPtr<Accessible> treeItem = CreateTreeItemAccessible(aRow);
if (treeItem) { if (treeItem) {
mAccessibleCache.Put(key, treeItem); mAccessibleCache.Put(key, RefPtr{treeItem});
Document()->BindToDocument(treeItem, nullptr); Document()->BindToDocument(treeItem, nullptr);
return treeItem; return treeItem;
} }

View File

@ -303,7 +303,7 @@ XULTreeGridCellAccessible* XULTreeGridRowAccessible::GetCellAccessible(
RefPtr<XULTreeGridCellAccessible> cell = new XULTreeGridCellAccessibleWrap( RefPtr<XULTreeGridCellAccessible> cell = new XULTreeGridCellAccessibleWrap(
mContent, mDoc, const_cast<XULTreeGridRowAccessible*>(this), mTree, mContent, mDoc, const_cast<XULTreeGridRowAccessible*>(this), mTree,
mTreeView, mRow, aColumn); mTreeView, mRow, aColumn);
mAccessibleCache.Put(key, cell); mAccessibleCache.Put(key, RefPtr{cell});
Document()->BindToDocument(cell, nullptr); Document()->BindToDocument(cell, nullptr);
return cell; return cell;
} }

View File

@ -77,7 +77,7 @@ class ClickHandlerChild extends ActorChild {
Ci.nsIReferrerInfo Ci.nsIReferrerInfo
); );
if (node) { if (node) {
referrerInfo.initWithNode(node); referrerInfo.initWithElement(node);
} else { } else {
referrerInfo.initWithDocument(ownerDoc); referrerInfo.initWithDocument(ownerDoc);
} }

View File

@ -586,7 +586,7 @@ class ContextMenuChild extends ActorChild {
let referrerInfo = Cc["@mozilla.org/referrer-info;1"].createInstance( let referrerInfo = Cc["@mozilla.org/referrer-info;1"].createInstance(
Ci.nsIReferrerInfo Ci.nsIReferrerInfo
); );
referrerInfo.initWithNode( referrerInfo.initWithElement(
context.onLink ? context.link : aEvent.composedTarget context.onLink ? context.link : aEvent.composedTarget
); );
@ -659,7 +659,7 @@ class ContextMenuChild extends ActorChild {
"@mozilla.org/referrer-info;1" "@mozilla.org/referrer-info;1"
].createInstance(Ci.nsIReferrerInfo); ].createInstance(Ci.nsIReferrerInfo);
targetReferrerInfo.initWithNode(aEvent.composedTarget); targetReferrerInfo.initWithElement(aEvent.composedTarget);
data.targetReferrerInfo = E10SUtils.serializeReferrerInfo( data.targetReferrerInfo = E10SUtils.serializeReferrerInfo(
targetReferrerInfo targetReferrerInfo
); );

View File

@ -365,13 +365,6 @@ pref("permissions.default.shortcuts", 0);
pref("permissions.postPrompt.animate", true); pref("permissions.postPrompt.animate", true);
// This is primarily meant to be enabled for studies.
#ifdef NIGHTLY_BUILD
pref("permissions.eventTelemetry.enabled", true);
#else
pref("permissions.eventTelemetry.enabled", false);
#endif
#ifdef NIGHTLY_BUILD #ifdef NIGHTLY_BUILD
pref("permissions.delegation.enable", true); pref("permissions.delegation.enable", true);
#else #else
@ -1400,11 +1393,6 @@ pref("identity.fxaccounts.commands.enabled", true);
// Default is 24 hours. // Default is 24 hours.
pref("identity.fxaccounts.commands.missed.fetch_interval", 86400); pref("identity.fxaccounts.commands.missed.fetch_interval", 86400);
// On GTK, we now default to showing the menubar only when alt is pressed:
#ifdef MOZ_WIDGET_GTK
pref("ui.key.menuAccessKeyFocuses", true);
#endif
// Whether we should run a test-pattern through EME GMPs before assuming they'll // Whether we should run a test-pattern through EME GMPs before assuming they'll
// decode H.264. // decode H.264.
pref("media.gmp.trial-create.enabled", true); pref("media.gmp.trial-create.enabled", true);
@ -1437,11 +1425,6 @@ pref("media.autoplay.default", 1); // 0=Allowed, 1=Blocked, 5=All Blocked
pref("media.autoplay.block-webaudio", false); pref("media.autoplay.block-webaudio", false);
#endif #endif
// Play with different values of the decay time and get telemetry,
// 0 means to randomize (and persist) the experiment value in users' profiles,
// -1 means no experiment is run and we use the preferred value for frecency (6h)
pref("browser.cache.frecency_experiment", 0);
pref("browser.translation.detectLanguage", false); pref("browser.translation.detectLanguage", false);
pref("browser.translation.neverForLanguages", ""); pref("browser.translation.neverForLanguages", "");
// Show the translation UI bits, like the info bar, notification icon and preferences. // Show the translation UI bits, like the info bar, notification icon and preferences.
@ -1704,14 +1687,6 @@ pref("fission.frontend.simulate-events", false);
// their destination (using the BrowsingContext id). // their destination (using the BrowsingContext id).
pref("fission.frontend.simulate-messages", false); pref("fission.frontend.simulate-messages", false);
// Prio preferences
// Only enable by default on Nightly.
// On platforms that do not build libprio, do not set these prefs at all, which gives us a way to detect support.
// Curve25519 public keys for Prio servers
pref("prio.publicKeyA", "35AC1C7576C7C6EDD7FED6BCFC337B34D48CB4EE45C86BEEFB40BD8875707733");
pref("prio.publicKeyB", "26E6674E65425B823F1F1D5F96E3BB3EF9E406EC7FBA7DEF8B08A35DD135AF50");
// Coverage ping is disabled by default. // Coverage ping is disabled by default.
pref("toolkit.coverage.enabled", false); pref("toolkit.coverage.enabled", false);
pref("toolkit.coverage.endpoint.base", "data:text/plain,"); pref("toolkit.coverage.endpoint.base", "data:text/plain,");

View File

@ -10,7 +10,7 @@
var gIdentityHandler = { var gIdentityHandler = {
/** /**
* nsIURI for which the identity UI is displayed. This has been already * nsIURI for which the identity UI is displayed. This has been already
* processed by nsIURIFixup.createExposableURI. * processed by createExposableURI.
*/ */
_uri: null, _uri: null,
@ -448,7 +448,7 @@ var gIdentityHandler = {
* Bitmask provided by nsIWebProgressListener.onSecurityChange. * Bitmask provided by nsIWebProgressListener.onSecurityChange.
* @param uri * @param uri
* nsIURI for which the identity UI should be displayed, already * nsIURI for which the identity UI should be displayed, already
* processed by nsIURIFixup.createExposableURI. * processed by createExposableURI.
*/ */
updateIdentity(state, uri) { updateIdentity(state, uri) {
let shouldHidePopup = this._uri && this._uri.spec != uri.spec; let shouldHidePopup = this._uri && this._uri.spec != uri.spec;

View File

@ -3285,7 +3285,7 @@ function URLBarSetURI(aURI, updatePopupNotifications) {
let uri = aURI || gBrowser.currentURI; let uri = aURI || gBrowser.currentURI;
// Strip off usernames and passwords for the location bar // Strip off usernames and passwords for the location bar
try { try {
uri = Services.uriFixup.createExposableURI(uri); uri = Services.io.createExposableURI(uri);
} catch (e) {} } catch (e) {}
// Replace initial page URIs with an empty string // Replace initial page URIs with an empty string
@ -5570,7 +5570,7 @@ var XULBrowserWindow = {
setOverLink(url, anchorElt) { setOverLink(url, anchorElt) {
if (url) { if (url) {
url = Services.textToSubURI.unEscapeURIForUI("UTF-8", url); url = Services.textToSubURI.unEscapeURIForUI(url);
// Encode bidirectional formatting characters. // Encode bidirectional formatting characters.
// (RFC 3987 sections 3.2 and 4.1 paragraph 6) // (RFC 3987 sections 3.2 and 4.1 paragraph 6)
@ -6000,7 +6000,7 @@ var XULBrowserWindow = {
gURLBarHandler.formatValue(); gURLBarHandler.formatValue();
try { try {
uri = Services.uriFixup.createExposableURI(uri); uri = Services.io.createExposableURI(uri);
} catch (e) {} } catch (e) {}
gIdentityHandler.updateIdentity(this._state, uri); gIdentityHandler.updateIdentity(this._state, uri);
}, },
@ -7508,7 +7508,7 @@ function handleLinkClick(event, href, linkNode) {
Ci.nsIReferrerInfo Ci.nsIReferrerInfo
); );
if (linkNode) { if (linkNode) {
referrerInfo.initWithNode(linkNode); referrerInfo.initWithElement(linkNode);
} else { } else {
referrerInfo.initWithDocument(doc); referrerInfo.initWithDocument(doc);
} }

View File

@ -1785,10 +1785,7 @@ nsContextMenu.prototype = {
// Let's try to unescape it using a character set // Let's try to unescape it using a character set
// in case the address is not ASCII. // in case the address is not ASCII.
try { try {
addresses = Services.textToSubURI.unEscapeURIForUI( addresses = Services.textToSubURI.unEscapeURIForUI(addresses);
gContextMenuContentData.charSet,
addresses
);
} catch (ex) { } catch (ex) {
// Do nothing. // Do nothing.
} }

View File

@ -9,6 +9,10 @@
/* import-globals-from permissions.js */ /* import-globals-from permissions.js */
/* import-globals-from security.js */ /* import-globals-from security.js */
XPCOMUtils.defineLazyModuleGetters(this, {
E10SUtils: "resource://gre/modules/E10SUtils.jsm",
});
// define a js object to implement nsITreeView // define a js object to implement nsITreeView
function pageInfoTreeView(treeid, copycol) { function pageInfoTreeView(treeid, copycol) {
// copycol is the index number for the column that we want to add to // copycol is the index number for the column that we want to add to
@ -955,10 +959,7 @@ function makePreview(row) {
var width = 0, var width = 0,
height = 0; height = 0;
let serial = Cc["@mozilla.org/network/serialization-helper;1"].getService( let triggeringPrinStr = E10SUtils.serializePrincipal(gDocInfo.principal);
Ci.nsISerializationHelper
);
let triggeringPrinStr = serial.serializeToString(gDocInfo.principal);
if ( if (
(item.HTMLLinkElement || (item.HTMLLinkElement ||
item.HTMLInputElement || item.HTMLInputElement ||

View File

@ -1001,7 +1001,7 @@
// XXX https://bugzilla.mozilla.org/show_bug.cgi?id=22183#c239 // XXX https://bugzilla.mozilla.org/show_bug.cgi?id=22183#c239
try { try {
if (docElement.getAttribute("chromehidden").includes("location")) { if (docElement.getAttribute("chromehidden").includes("location")) {
var uri = Services.uriFixup.createExposableURI(aBrowser.currentURI); var uri = Services.io.createExposableURI(aBrowser.currentURI);
if (uri.scheme == "about") { if (uri.scheme == "about") {
newTitle = uri.spec + sep + newTitle; newTitle = uri.spec + sep + newTitle;
} else { } else {
@ -1494,7 +1494,7 @@
// See if we can use the URI as the title. // See if we can use the URI as the title.
if (browser.currentURI.displaySpec) { if (browser.currentURI.displaySpec) {
try { try {
title = Services.uriFixup.createExposableURI(browser.currentURI) title = Services.io.createExposableURI(browser.currentURI)
.displaySpec; .displaySpec;
} catch (ex) { } catch (ex) {
title = browser.currentURI.displaySpec; title = browser.currentURI.displaySpec;

View File

@ -2,3 +2,5 @@
[browser_principalSerialization_version1.js] [browser_principalSerialization_version1.js]
[browser_principalSerialization_csp.js] [browser_principalSerialization_csp.js]
[browser_principalSerialization_json.js]
skip-if = debug # deliberately bypass assertions when deserializing. Bug 965637 removed the CSP from Principals, but the remaining bits in such Principals should deserialize correctly.

View File

@ -0,0 +1,164 @@
"use strict";
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/*
This test file exists to ensure whenever changes to principal serialization happens,
we guarantee that the data can be restored and generated into a new principal.
The tests are written to be brittle so we encode all versions of the changes into the tests.
*/
add_task(async function test_nullPrincipal() {
const nullId = "0";
// fields
const uri = 0;
const suffix = 1;
const nullReplaceRegex = /moz-nullprincipal:{[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}}/;
const NULL_REPLACE = "NULL_PRINCIPAL_URL";
/*
This test should NOT be resilient to changes in versioning,
however it exists purely to verify the code doesn't unintentionally change without updating versioning and migration code.
*/
let tests = [
{
input: { OA: {} },
expected: `{"${nullId}":{"${uri}":"${NULL_REPLACE}"}}`,
},
{
input: { OA: {} },
expected: `{"${nullId}":{"${uri}":"${NULL_REPLACE}"}}`,
},
{
input: { OA: { userContextId: 0 } },
expected: `{"${nullId}":{"${uri}":"${NULL_REPLACE}"}}`,
},
{
input: { OA: { userContextId: 2 } },
expected: `{"${nullId}":{"${uri}":"${NULL_REPLACE}","${suffix}":"^userContextId=2"}}`,
},
{
input: { OA: { privateBrowsingId: 1 } },
expected: `{"${nullId}":{"${uri}":"${NULL_REPLACE}","${suffix}":"^privateBrowsingId=1"}}`,
},
{
input: { OA: { privateBrowsingId: 0 } },
expected: `{"${nullId}":{"${uri}":"${NULL_REPLACE}"}}`,
},
];
for (let test of tests) {
let p = Services.scriptSecurityManager.createNullPrincipal(test.input.OA);
let sp = E10SUtils.serializePrincipal(p);
// Not sure why cppjson is adding a \n here
let spr = atob(sp).replace(nullReplaceRegex, NULL_REPLACE);
is(
test.expected,
spr,
"Expected serialized object for " + JSON.stringify(test.input)
);
let dp = E10SUtils.deserializePrincipal(sp);
// Check all the origin attributes
for (let key in test.input.OA) {
is(
dp.originAttributes[key],
test.input.OA[key],
"Ensure value of " + key + " is " + test.input.OA[key]
);
}
}
});
add_task(async function test_contentPrincipal() {
const contentId = "1";
// fields
const codebase = 0;
// const domain = 1;
const suffix = 2;
// const csp = 3;
/*
This test should NOT be resilient to changes in versioning,
however it exists purely to verify the code doesn't unintentionally change without updating versioning and migration code.
*/
let tests = [
{
input: { uri: "http://example.com/", OA: {} },
expected: `{"${contentId}":{"${codebase}":"http://example.com/"}}`,
},
{
input: { uri: "http://mozilla1.com/", OA: {} },
expected: `{"${contentId}":{"${codebase}":"http://mozilla1.com/"}}`,
},
{
input: { uri: "http://mozilla2.com/", OA: { userContextId: 0 } },
expected: `{"${contentId}":{"${codebase}":"http://mozilla2.com/"}}`,
},
{
input: { uri: "http://mozilla3.com/", OA: { userContextId: 2 } },
expected: `{"${contentId}":{"${codebase}":"http://mozilla3.com/","${suffix}":"^userContextId=2"}}`,
},
{
input: { uri: "http://mozilla4.com/", OA: { privateBrowsingId: 1 } },
expected: `{"${contentId}":{"${codebase}":"http://mozilla4.com/","${suffix}":"^privateBrowsingId=1"}}`,
},
{
input: { uri: "http://mozilla5.com/", OA: { privateBrowsingId: 0 } },
expected: `{"${contentId}":{"${codebase}":"http://mozilla5.com/"}}`,
},
];
for (let test of tests) {
let uri = Services.io.newURI(test.input.uri);
let p = Services.scriptSecurityManager.createCodebasePrincipal(
uri,
test.input.OA
);
let sp = E10SUtils.serializePrincipal(p);
is(
test.expected,
atob(sp),
"Expected serialized object for " + test.input.uri
);
is(
btoa(test.expected),
sp,
"Expected serialized string for " + test.input.uri
);
let dp = E10SUtils.deserializePrincipal(sp);
is(dp.URI.spec, test.input.uri, "Ensure spec is the same");
// Check all the origin attributes
for (let key in test.input.OA) {
is(
dp.originAttributes[key],
test.input.OA[key],
"Ensure value of " + key + " is " + test.input.OA[key]
);
}
}
});
add_task(async function test_systemPrincipal() {
const systemId = "3";
/*
This test should NOT be resilient to changes in versioning,
however it exists purely to verify the code doesn't unintentionally change without updating versioning and migration code.
*/
const expected = `{"${systemId}":{}}`;
let p = Services.scriptSecurityManager.getSystemPrincipal();
let sp = E10SUtils.serializePrincipal(p);
is(expected, atob(sp), "Expected serialized object for system principal");
is(btoa(expected), sp, "Expected serialized string for system principal");
let dp = E10SUtils.deserializePrincipal(sp);
is(
dp,
Services.scriptSecurityManager.getSystemPrincipal(),
"Deserialized the system principal"
);
});

View File

@ -39,66 +39,6 @@ add_task(function test_nullPrincipal() {
is(p2.originAttributes.userContextId, 2, "Expected a userContextId of 2"); is(p2.originAttributes.userContextId, 2, "Expected a userContextId of 2");
}); });
add_task(async function test_contentPrincipal() {
/*
This test should NOT be resilient to changes in versioning,
however it exists purely to verify the code doesn't unintentionally change without updating versioning and migration code.
*/
let tests = [
{
input: ["http://example.com/", {}],
expected:
"ZT4OTT7kRfqycpfCC8AeuAAAAAAAAAAAwAAAAAAAAEYB3pRy0IA0EdOTmQAQS6D9QJIHOlRteE8wkTq4cYEyCMYAAAAC/////wAAAFABAAAAE2h0dHA6Ly9leGFtcGxlLmNvbS8AAAAAAAAABAAAAAcAAAALAAAAB/////8AAAAH/////wAAAAcAAAALAAAAEgAAAAEAAAASAAAAAQAAABIAAAABAAAAEwAAAAAAAAAT/////wAAAAD/////AAAAEv////8AAAAS/////wEAAAAAAAAAAAAAAAA=",
},
{
input: ["http://mozilla1.com/", {}],
expected:
"ZT4OTT7kRfqycpfCC8AeuAAAAAAAAAAAwAAAAAAAAEYB3pRy0IA0EdOTmQAQS6D9QJIHOlRteE8wkTq4cYEyCMYAAAAC/////wAAAFABAAAAFGh0dHA6Ly9tb3ppbGxhMS5jb20vAAAAAAAAAAQAAAAHAAAADAAAAAf/////AAAAB/////8AAAAHAAAADAAAABMAAAABAAAAEwAAAAEAAAATAAAAAQAAABQAAAAAAAAAFP////8AAAAA/////wAAABP/////AAAAE/////8BAAAAAAAAAAAAAAAA",
},
{
input: ["http://mozilla2.com/", { userContextId: 0 }],
expected:
"ZT4OTT7kRfqycpfCC8AeuAAAAAAAAAAAwAAAAAAAAEYB3pRy0IA0EdOTmQAQS6D9QJIHOlRteE8wkTq4cYEyCMYAAAAC/////wAAAFABAAAAFGh0dHA6Ly9tb3ppbGxhMi5jb20vAAAAAAAAAAQAAAAHAAAADAAAAAf/////AAAAB/////8AAAAHAAAADAAAABMAAAABAAAAEwAAAAEAAAATAAAAAQAAABQAAAAAAAAAFP////8AAAAA/////wAAABP/////AAAAE/////8BAAAAAAAAAAAAAAAA",
},
{
input: ["http://mozilla3.com/", { userContextId: 2 }],
expected:
"ZT4OTT7kRfqycpfCC8AeuAAAAAAAAAAAwAAAAAAAAEYB3pRy0IA0EdOTmQAQS6D9QJIHOlRteE8wkTq4cYEyCMYAAAAC/////wAAAFABAAAAFGh0dHA6Ly9tb3ppbGxhMy5jb20vAAAAAAAAAAQAAAAHAAAADAAAAAf/////AAAAB/////8AAAAHAAAADAAAABMAAAABAAAAEwAAAAEAAAATAAAAAQAAABQAAAAAAAAAFP////8AAAAA/////wAAABP/////AAAAE/////8BAAAAAAAAAAAAABBedXNlckNvbnRleHRJZD0yAA==",
},
{
input: ["http://mozilla4.com/", { privateBrowsingId: 1 }],
expected:
"ZT4OTT7kRfqycpfCC8AeuAAAAAAAAAAAwAAAAAAAAEYB3pRy0IA0EdOTmQAQS6D9QJIHOlRteE8wkTq4cYEyCMYAAAAC/////wAAAFABAAAAFGh0dHA6Ly9tb3ppbGxhNC5jb20vAAAAAAAAAAQAAAAHAAAADAAAAAf/////AAAAB/////8AAAAHAAAADAAAABMAAAABAAAAEwAAAAEAAAATAAAAAQAAABQAAAAAAAAAFP////8AAAAA/////wAAABP/////AAAAE/////8BAAAAAAAAAAAAABRecHJpdmF0ZUJyb3dzaW5nSWQ9MQA=",
},
{
input: ["http://mozilla5.com/", { privateBrowsingId: 0 }],
expected:
"ZT4OTT7kRfqycpfCC8AeuAAAAAAAAAAAwAAAAAAAAEYB3pRy0IA0EdOTmQAQS6D9QJIHOlRteE8wkTq4cYEyCMYAAAAC/////wAAAFABAAAAFGh0dHA6Ly9tb3ppbGxhNS5jb20vAAAAAAAAAAQAAAAHAAAADAAAAAf/////AAAAB/////8AAAAHAAAADAAAABMAAAABAAAAEwAAAAEAAAATAAAAAQAAABQAAAAAAAAAFP////8AAAAA/////wAAABP/////AAAAE/////8BAAAAAAAAAAAAAAAA",
},
];
for (let test of tests) {
let uri = Services.io.newURI(test.input[0]);
let p = Services.scriptSecurityManager.createCodebasePrincipal(
uri,
test.input[1]
);
let sp = E10SUtils.serializePrincipal(p);
is(test.expected, sp, "Expected serialized string for " + test.input[0]);
let dp = E10SUtils.deserializePrincipal(sp);
is(dp.URI.spec, test.input[0], "Ensure spec is the same");
// Check all the origin attributes
for (let key in test.input[1]) {
is(
dp.originAttributes[key],
test.input[1][key],
"Ensure value of " + key + " is " + test.input[1][key]
);
}
}
});
add_task(async function test_realHistoryCheck() { add_task(async function test_realHistoryCheck() {
/* /*
This test should be resilient to changes in principal serialization, if these are failing then it's likely the code will break session storage. This test should be resilient to changes in principal serialization, if these are failing then it's likely the code will break session storage.

View File

@ -10,18 +10,6 @@ add_task(async function() {
await ContentTask.spawn(gBrowser.selectedBrowser, {}, async function() { await ContentTask.spawn(gBrowser.selectedBrowser, {}, async function() {
// Push the state before maximizing the window and clicking below. // Push the state before maximizing the window and clicking below.
content.history.pushState("page2", "page2", "page2"); content.history.pushState("page2", "page2", "page2");
// While in the child process, add a listener for the popstate event here. This
// event will fire when the mouse click happens.
content.addEventListener(
"popstate",
function() {
sendAsyncMessage("Test:PopStateOccurred", {
location: content.document.location.href,
});
},
{ once: true }
);
}); });
window.maximize(); window.maximize();
@ -32,23 +20,16 @@ add_task(async function() {
var yPixel = boundingRect.top + Math.floor(boundingRect.height / 2); var yPixel = boundingRect.top + Math.floor(boundingRect.height / 2);
var xPixel = 0; // Use the first pixel of the screen since it is maximized. var xPixel = 0; // Use the first pixel of the screen since it is maximized.
let resultLocation = await new Promise(resolve => { let popStatePromise = BrowserTestUtils.waitForContentEvent(
window.messageManager.addMessageListener( gBrowser.selectedBrowser,
"Test:PopStateOccurred", "popstate",
function statePopped(message) { true
window.messageManager.removeMessageListener( );
"Test:PopStateOccurred", EventUtils.synthesizeMouseAtPoint(xPixel, yPixel, {}, window);
statePopped await popStatePromise;
);
resolve(message.data.location);
}
);
EventUtils.synthesizeMouseAtPoint(xPixel, yPixel, {}, window);
});
is( is(
resultLocation, gBrowser.selectedBrowser.currentURI.spec,
firstLocation, firstLocation,
"Clicking the first pixel should have navigated back." "Clicking the first pixel should have navigated back."
); );

View File

@ -40,6 +40,10 @@ registerCleanupFunction(() => {
* browser in an e10s window, that the new tab will load properly. * browser in an e10s window, that the new tab will load properly.
*/ */
add_task(async function test_new_tab() { add_task(async function test_new_tab() {
await SpecialPowers.pushPrefEnv({
set: [["domsecurity.skip_html_fragment_assertion", true]],
});
let normalWindow = await BrowserTestUtils.openNewBrowserWindow({ let normalWindow = await BrowserTestUtils.openNewBrowserWindow({
remote: true, remote: true,
}); });
@ -84,6 +88,10 @@ add_task(async function test_new_tab() {
* window. Also tests with a private browsing window. * window. Also tests with a private browsing window.
*/ */
add_task(async function test_new_window() { add_task(async function test_new_window() {
await SpecialPowers.pushPrefEnv({
set: [["domsecurity.skip_html_fragment_assertion", true]],
});
let normalWindow = await BrowserTestUtils.openNewBrowserWindow( let normalWindow = await BrowserTestUtils.openNewBrowserWindow(
{ {
remote: true, remote: true,

View File

@ -49,11 +49,8 @@ function testFirstPartyDomain(pageInfo) {
} }
// Check the node has the attribute 'triggeringprincipal'. // Check the node has the attribute 'triggeringprincipal'.
let serial = Cc[
"@mozilla.org/network/serialization-helper;1"
].getService(Ci.nsISerializationHelper);
let loadingPrincipalStr = preview.getAttribute("triggeringprincipal"); let loadingPrincipalStr = preview.getAttribute("triggeringprincipal");
let loadingPrincipal = serial.deserializeObject(loadingPrincipalStr); let loadingPrincipal = E10SUtils.deserializePrincipal(loadingPrincipalStr);
Assert.equal( Assert.equal(
loadingPrincipal.originAttributes.firstPartyDomain, loadingPrincipal.originAttributes.firstPartyDomain,
EXPECTED_DOMAIN, EXPECTED_DOMAIN,

View File

@ -291,7 +291,7 @@ const startupPhases = {
// bug 975996 // bug 975996
path: "ProfD:permissions.sqlite", path: "ProfD:permissions.sqlite",
condition: WIN || MAC, condition: WIN || MAC,
fsync: 7, fsync: 8,
read: 2, read: 2,
stat: 1, stat: 1,
write: 10, write: 10,
@ -300,9 +300,9 @@ const startupPhases = {
// bug 975996 // bug 975996
path: "ProfD:permissions.sqlite-journal", path: "ProfD:permissions.sqlite-journal",
condition: WIN || MAC, condition: WIN || MAC,
fsync: 7, fsync: 8,
stat: 26, stat: 28,
write: 38, write: 40,
}, },
{ {
// bug 975996 // bug 975996

View File

@ -6,7 +6,6 @@ support-files=
[browser_canvas_fingerprinting_resistance.js] [browser_canvas_fingerprinting_resistance.js]
skip-if = debug || os == "linux" && asan # Bug 1522069 skip-if = debug || os == "linux" && asan # Bug 1522069
[browser_permissions.js] [browser_permissions.js]
[browser_permissions_event_telemetry.js]
[browser_permissions_postPrompt.js] [browser_permissions_postPrompt.js]
support-files= support-files=
dummy.js dummy.js

View File

@ -1,176 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const ORIGIN = "https://example.com";
const PERMISSIONS_PAGE =
getRootDirectory(gTestPath).replace("chrome://mochitests/content", ORIGIN) +
"permissions.html";
async function showPermissionPrompt(browser) {
let popupshown = BrowserTestUtils.waitForEvent(
PopupNotifications.panel,
"popupshown"
);
await ContentTask.spawn(browser, null, function() {
E10SUtils.wrapHandlingUserInput(content, true, () => {
// We need to synthesize the click instead of calling .click(),
// otherwise the document will not correctly register the user gesture.
let EventUtils = ContentTaskUtils.getEventUtils(content);
let notificationButton = content.document.getElementById(
"desktop-notification"
);
EventUtils.synthesizeMouseAtCenter(
notificationButton,
{ isSynthesized: false },
content
);
});
});
await popupshown;
ok(true, "Notification permission prompt was shown");
}
function checkEventTelemetry(method) {
let events = Services.telemetry.snapshotEvents(
Ci.nsITelemetry.DATASET_ALL_CHANNELS,
true
).parent;
events = events.filter(
e =>
e[1] == "security.ui.permissionprompt" &&
e[2] == method &&
e[3] == "notifications"
);
is(events.length, 1, "recorded telemetry for showing the prompt");
ok(
typeof events[0][4] == "string",
"recorded a hashed and salted variant of the domain"
);
is(events[0][4].length * 4, 256, "hash is a 256 bit string");
ok(
!events[0][4].includes("example.com"),
"we're not including the domain by accident"
);
// We assume that even the slowest infra machines are able to show
// a permission prompt within five minutes.
const FIVE_MINUTES = 1000 * 60 * 5;
let timeOnPage = Number(events[0][5].timeOnPage);
let lastInteraction = Number(events[0][5].lastInteraction);
ok(
timeOnPage > 0 && timeOnPage < FIVE_MINUTES,
`Has recorded time on page (${timeOnPage})`
);
is(events[0][5].hasUserInput, "true", "Has recorded user input");
is(events[0][5].allPermsDenied, "3", "Has recorded total denied permissions");
is(
events[0][5].allPermsGranted,
method == "accept" ? "3" : "2",
"Has recorded total granted permissions"
);
is(
events[0][5].thisPermDenied,
"0",
"Has recorded denied notification permissions"
);
is(
events[0][5].thisPermGranted,
method == "accept" ? "2" : "1",
"Has recorded granted notification permissions"
);
is(
events[0][5].docHasUserInput,
"true",
"Has recorded user input on document"
);
ok(
lastInteraction > Date.now() - FIVE_MINUTES && lastInteraction < Date.now(),
`Has recorded last user input time (${lastInteraction})`
);
}
add_task(async function setup() {
let oldCanRecord = Services.telemetry.canRecordExtended;
Services.telemetry.canRecordExtended = true;
Services.prefs.setBoolPref("permissions.eventTelemetry.enabled", true);
// Add some example permissions.
let uri = Services.io.newURI(PERMISSIONS_PAGE);
let uri2 = Services.io.newURI("https://example.org");
let uri3 = Services.io.newURI("http://sub.example.org");
PermissionTestUtils.add(uri, "geo", Services.perms.ALLOW_ACTION);
PermissionTestUtils.add(
uri3,
"desktop-notification",
Services.perms.ALLOW_ACTION
);
PermissionTestUtils.add(uri2, "microphone", Services.perms.DENY_ACTION);
PermissionTestUtils.add(uri, "camera", Services.perms.DENY_ACTION);
PermissionTestUtils.add(uri2, "geo", Services.perms.DENY_ACTION);
registerCleanupFunction(() => {
Services.perms.removeAll();
Services.prefs.clearUserPref("permissions.eventTelemetry.enabled");
Services.telemetry.canRecordExtended = oldCanRecord;
});
Services.telemetry.clearEvents();
});
add_task(async function testAccept() {
await BrowserTestUtils.withNewTab(PERMISSIONS_PAGE, async function(browser) {
await showPermissionPrompt(browser);
checkEventTelemetry("show");
let notification = PopupNotifications.panel.firstElementChild;
EventUtils.synthesizeMouseAtCenter(notification.button, {});
checkEventTelemetry("accept");
Services.telemetry.clearEvents();
PermissionTestUtils.remove(PERMISSIONS_PAGE, "desktop-notification");
});
});
add_task(async function testDeny() {
await BrowserTestUtils.withNewTab(PERMISSIONS_PAGE, async function(browser) {
await showPermissionPrompt(browser);
checkEventTelemetry("show");
let notification = PopupNotifications.panel.firstElementChild;
EventUtils.synthesizeMouseAtCenter(notification.secondaryButton, {});
checkEventTelemetry("deny");
Services.telemetry.clearEvents();
PermissionTestUtils.remove(PERMISSIONS_PAGE, "desktop-notification");
});
});
add_task(async function testLeave() {
let tab = await BrowserTestUtils.openNewForegroundTab(
gBrowser,
PERMISSIONS_PAGE
);
await showPermissionPrompt(tab.linkedBrowser);
checkEventTelemetry("show");
let tabClosed = BrowserTestUtils.waitForTabClosing(tab);
await BrowserTestUtils.removeTab(tab);
await tabClosed;
checkEventTelemetry("leave");
Services.telemetry.clearEvents();
PermissionTestUtils.remove(PERMISSIONS_PAGE, "desktop-notification");
});

View File

@ -190,7 +190,6 @@ add_task(async function testChromeHearsPluginCrashFirst() {
let event = new content.PluginCrashedEvent("PluginCrashed", { let event = new content.PluginCrashedEvent("PluginCrashed", {
pluginName: "", pluginName: "",
pluginDumpID: "", pluginDumpID: "",
browserDumpID: "",
submittedCrashReport: false, submittedCrashReport: false,
bubbles: true, bubbles: true,
cancelable: true, cancelable: true,
@ -247,7 +246,6 @@ add_task(async function testContentHearsCrashFirst() {
let event = new content.PluginCrashedEvent("PluginCrashed", { let event = new content.PluginCrashedEvent("PluginCrashed", {
pluginName: "", pluginName: "",
pluginDumpID: "", pluginDumpID: "",
browserDumpID: "",
submittedCrashReport: false, submittedCrashReport: false,
bubbles: true, bubbles: true,
cancelable: true, cancelable: true,

View File

@ -35,7 +35,7 @@ let whitelist = [
isFromDevTools: false, isFromDevTools: false,
}, },
{ {
sourceName: /\b(html|mathml|ua)\.css$/i, sourceName: /\b(minimal-xul|html|mathml|ua)\.css$/i,
errorMessage: /Unknown property.*-moz-/i, errorMessage: /Unknown property.*-moz-/i,
isFromDevTools: false, isFromDevTools: false,
}, },
@ -57,7 +57,7 @@ let whitelist = [
platforms: ["linux"], platforms: ["linux"],
isFromDevTools: false, isFromDevTools: false,
}, },
// The '-moz-menulist-button' value is only supported in chrome and UA sheets // The '-moz-menulist-arrow-button' value is only supported in chrome and UA sheets
// but forms.css is loaded as a document sheet by this test. // but forms.css is loaded as a document sheet by this test.
// Maybe bug 1261237 will fix this? // Maybe bug 1261237 will fix this?
{ {
@ -101,19 +101,6 @@ if (
}); });
} }
if (
!Services.prefs.getBoolPref(
"layout.css.line-height-moz-block-height.content.enabled"
)
) {
// -moz-block-height is used in form controls but not exposed to the web.
whitelist.push({
sourceName: /(?:res|gre-resources)\/forms\.css$/i,
errorMessage: /Error in parsing value for \u2018line-height\u2019/iu,
isFromDevTools: false,
});
}
if (!Services.prefs.getBoolPref("layout.css.scrollbar-width.enabled")) { if (!Services.prefs.getBoolPref("layout.css.scrollbar-width.enabled")) {
whitelist.push({ whitelist.push({
sourceName: /(?:res|gre-resources)\/forms\.css$/i, sourceName: /(?:res|gre-resources)\/forms\.css$/i,
@ -122,6 +109,15 @@ if (!Services.prefs.getBoolPref("layout.css.scrollbar-width.enabled")) {
}); });
} }
if (!Services.prefs.getBoolPref("layout.css.file-chooser-button.enabled")) {
// Reserved to UA sheets, behind a pref for content.
whitelist.push({
sourceName: /(?:res|gre-resources)\/forms\.css$/i,
errorMessage: /Unknown pseudo-.*file-chooser-button/i,
isFromDevTools: false,
});
}
if (!Services.prefs.getBoolPref("layout.css.scroll-anchoring.enabled")) { if (!Services.prefs.getBoolPref("layout.css.scroll-anchoring.enabled")) {
whitelist.push({ whitelist.push({
sourceName: /webconsole\.css$/i, sourceName: /webconsole\.css$/i,

View File

@ -1,4 +1,5 @@
const PREF_MULTISELECT_TABS = "browser.tabs.multiselect"; const PREF_MULTISELECT_TABS = "browser.tabs.multiselect";
const PREF_DELAY_AUTOPLAY = "media.block-autoplay-until-in-foreground";
const PAGE = const PAGE =
"https://example.com/browser/browser/base/content/test/tabs/file_mediaPlayback.html"; "https://example.com/browser/browser/base/content/test/tabs/file_mediaPlayback.html";
@ -19,7 +20,7 @@ async function addMediaTab() {
add_task(async function setPref() { add_task(async function setPref() {
await SpecialPowers.pushPrefEnv({ await SpecialPowers.pushPrefEnv({
set: [[PREF_MULTISELECT_TABS, true]], set: [[PREF_MULTISELECT_TABS, true], [PREF_DELAY_AUTOPLAY, true]],
}); });
}); });

View File

@ -1090,7 +1090,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
} else { } else {
// Only copy exposable URIs // Only copy exposable URIs
try { try {
aURI = Services.uriFixup.createExposableURI(aURI); aURI = Services.io.createExposableURI(aURI);
} catch (ex) {} } catch (ex) {}
} }
return aURI; return aURI;

View File

@ -1028,10 +1028,6 @@ BrowserGlue.prototype = {
os.removeObserver(this, "xpi-signature-changed"); os.removeObserver(this, "xpi-signature-changed");
os.removeObserver(this, "sync-ui-state:update"); os.removeObserver(this, "sync-ui-state:update");
Services.prefs.removeObserver(
"permissions.eventTelemetry.enabled",
this._togglePermissionPromptTelemetry
);
Services.prefs.removeObserver( Services.prefs.removeObserver(
"privacy.trackingprotection", "privacy.trackingprotection",
this._matchCBCategory this._matchCBCategory
@ -1590,24 +1586,6 @@ BrowserGlue.prototype = {
ContentBlockingCategoriesPrefs.updateCBCategory(); ContentBlockingCategoriesPrefs.updateCBCategory();
}, },
_togglePermissionPromptTelemetry() {
let enablePermissionPromptTelemetry = Services.prefs.getBoolPref(
"permissions.eventTelemetry.enabled",
false
);
Services.telemetry.setEventRecordingEnabled(
"security.ui.permissionprompt",
enablePermissionPromptTelemetry
);
if (!enablePermissionPromptTelemetry) {
// Remove the saved unique identifier to reduce the (remote) chance
// of leaking it to our servers in the future.
Services.prefs.clearUserPref("permissions.eventTelemetry.uuid");
}
},
_recordContentBlockingTelemetry() { _recordContentBlockingTelemetry() {
let recordIdentityPopupEvents = Services.prefs.getBoolPref( let recordIdentityPopupEvents = Services.prefs.getBoolPref(
"security.identitypopup.recordEventElemetry" "security.identitypopup.recordEventElemetry"
@ -1840,14 +1818,6 @@ BrowserGlue.prototype = {
); );
}); });
Services.tm.idleDispatchToMainThread(() => {
Services.prefs.addObserver(
"permissions.eventTelemetry.enabled",
this._togglePermissionPromptTelemetry
);
this._togglePermissionPromptTelemetry();
});
Services.tm.idleDispatchToMainThread(() => { Services.tm.idleDispatchToMainThread(() => {
this._recordContentBlockingTelemetry(); this._recordContentBlockingTelemetry();
}); });

View File

@ -1806,8 +1806,8 @@ var PanelView = class extends AssociatedToNode {
focusSelectedElement(byKey = false) { focusSelectedElement(byKey = false) {
let selected = this.selectedElement; let selected = this.selectedElement;
if (selected) { if (selected) {
let flag = byKey ? "FLAG_BYKEY" : "FLAG_BYELEMENTFOCUS"; let flag = byKey ? Services.focus.FLAG_BYKEY : 0;
Services.focus.setFocus(selected, Services.focus[flag]); Services.focus.setFocus(selected, flag);
} }
} }

View File

@ -8,7 +8,11 @@ function simulateItemDragAndEnd(aToDrag, aTarget) {
Ci.nsIDragService Ci.nsIDragService
); );
ds.startDragSession(); ds.startDragSessionForTests(
Ci.nsIDragService.DRAGDROP_ACTION_MOVE |
Ci.nsIDragService.DRAGDROP_ACTION_COPY |
Ci.nsIDragService.DRAGDROP_ACTION_LINK
);
try { try {
var [result, dataTransfer] = EventUtils.synthesizeDragOver( var [result, dataTransfer] = EventUtils.synthesizeDragOver(
aToDrag.parentNode, aToDrag.parentNode,

View File

@ -39,7 +39,11 @@ add_task(async function() {
Ci.nsIDragService Ci.nsIDragService
); );
ds.startDragSession(); ds.startDragSessionForTests(
Ci.nsIDragService.DRAGDROP_ACTION_MOVE |
Ci.nsIDragService.DRAGDROP_ACTION_COPY |
Ci.nsIDragService.DRAGDROP_ACTION_LINK
);
try { try {
var [result, dataTransfer] = EventUtils.synthesizeDragOver( var [result, dataTransfer] = EventUtils.synthesizeDragOver(
identityBox, identityBox,

View File

@ -10,7 +10,7 @@ The Activity Stream system add-on sends various types of pings to the backend (H
Schema definitions/validations that can be used for tests can be found in `system-addon/test/schemas/pings.js`. Schema definitions/validations that can be used for tests can be found in `system-addon/test/schemas/pings.js`.
# Example Activity Stream `health` log ## Example Activity Stream `health` log
```js ```js
{ {
@ -30,7 +30,7 @@ Schema definitions/validations that can be used for tests can be found in `syste
} }
``` ```
# Example Activity Stream `session` Log ## Example Activity Stream `session` Log
```js ```js
{ {
@ -54,7 +54,7 @@ Schema definitions/validations that can be used for tests can be found in `syste
} }
``` ```
# Example Activity Stream `user_event` Log ## Example Activity Stream `user_event` Log
```js ```js
{ {
@ -79,7 +79,7 @@ Schema definitions/validations that can be used for tests can be found in `syste
} }
``` ```
# Example Activity Stream `performance` Log ## Example Activity Stream `performance` Log
```js ```js
{ {
@ -103,7 +103,7 @@ Schema definitions/validations that can be used for tests can be found in `syste
} }
``` ```
# Example Activity Stream `undesired event` Log ## Example Activity Stream `undesired event` Log
```js ```js
{ {
@ -124,7 +124,7 @@ Schema definitions/validations that can be used for tests can be found in `syste
"date": "2016-03-07" "date": "2016-03-07"
} }
``` ```
# Example Activity Stream `impression_stats` Logs ## Example Activity Stream `impression_stats` Logs
```js ```js
{ {
@ -162,7 +162,7 @@ Schema definitions/validations that can be used for tests can be found in `syste
} }
``` ```
# Example Discovery Stream `SPOCS Fill` log ## Example Discovery Stream `SPOCS Fill` log
```js ```js
{ {
@ -186,7 +186,7 @@ Schema definitions/validations that can be used for tests can be found in `syste
} }
``` ```
# Example Activity Stream `Router` Pings ## Example Activity Stream `Router` Pings
```js ```js
{ {

View File

@ -362,7 +362,6 @@ PlacesController.prototype = {
var clipboard = this.clipboard; var clipboard = this.clipboard;
var hasPlacesData = clipboard.hasDataMatchingFlavors( var hasPlacesData = clipboard.hasDataMatchingFlavors(
flavors, flavors,
flavors.length,
Ci.nsIClipboard.kGlobalClipboard Ci.nsIClipboard.kGlobalClipboard
); );
if (hasPlacesData) { if (hasPlacesData) {

View File

@ -5,7 +5,7 @@
for var in ('MOZ_APP_NAME', 'MOZ_MACBUNDLE_NAME'): for var in ('MOZ_APP_NAME', 'MOZ_MACBUNDLE_NAME'):
DEFINES[var] = CONFIG[var] DEFINES[var] = CONFIG[var]
if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'gtk3', 'cocoa'): #if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'gtk3', 'cocoa'):
DEFINES['HAVE_SHELL_SERVICE'] = 1 # DEFINES['HAVE_SHELL_SERVICE'] = 1
JAR_MANIFESTS += ['jar.mn'] JAR_MANIFESTS += ['jar.mn']

View File

@ -14,8 +14,8 @@ BROWSER_CHROME_MANIFESTS += [
for var in ('MOZ_APP_NAME', 'MOZ_MACBUNDLE_NAME'): for var in ('MOZ_APP_NAME', 'MOZ_MACBUNDLE_NAME'):
DEFINES[var] = CONFIG[var] DEFINES[var] = CONFIG[var]
if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'gtk3', 'cocoa'): #if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'gtk3', 'cocoa'):
DEFINES['HAVE_SHELL_SERVICE'] = 1 # DEFINES['HAVE_SHELL_SERVICE'] = 1
JAR_MANIFESTS += ['jar.mn'] JAR_MANIFESTS += ['jar.mn']

View File

@ -18,23 +18,27 @@ add_task(async function test() {
let privateWin = await BrowserTestUtils.openNewBrowserWindow({ let privateWin = await BrowserTestUtils.openNewBrowserWindow({
private: true, private: true,
}); });
let privateBrowser = BrowserTestUtils.addTab( let testURL =
privateWin.gBrowser, prefix + "browser_privatebrowsing_localStorage_before_after_page.html";
prefix + "browser_privatebrowsing_localStorage_before_after_page.html" await BrowserTestUtils.openNewForegroundTab(privateWin.gBrowser, testURL);
).linkedBrowser;
await BrowserTestUtils.browserLoaded(privateBrowser);
is(privateBrowser.contentTitle, "1", "localStorage should contain 1 item"); is(
privateWin.gBrowser.selectedBrowser.contentTitle,
"1",
"localStorage should contain 1 item"
);
// Step 2. // Step 2.
let win = await BrowserTestUtils.openNewBrowserWindow(); let win = await BrowserTestUtils.openNewBrowserWindow();
let browser = BrowserTestUtils.addTab( testURL =
win.gBrowser, prefix + "browser_privatebrowsing_localStorage_before_after_page2.html";
prefix + "browser_privatebrowsing_localStorage_before_after_page2.html" await BrowserTestUtils.openNewForegroundTab(win.gBrowser, testURL);
).linkedBrowser;
await BrowserTestUtils.browserLoaded(browser);
is(browser.contentTitle, "null|0", "localStorage should contain 0 items"); is(
win.gBrowser.selectedBrowser.contentTitle,
"null|0",
"localStorage should contain 0 items"
);
// Cleanup // Cleanup
await BrowserTestUtils.closeWindow(privateWin); await BrowserTestUtils.closeWindow(privateWin);

View File

@ -5,10 +5,6 @@
* Ensure that we can restore old style favicon and principals. * Ensure that we can restore old style favicon and principals.
*/ */
add_task(async function test_label_and_icon() { add_task(async function test_label_and_icon() {
let helper = Cc["@mozilla.org/network/serialization-helper;1"].getService(
Ci.nsISerializationHelper
);
// Make sure that tabs are restored on demand as otherwise the tab will start // Make sure that tabs are restored on demand as otherwise the tab will start
// loading immediately and override the icon. // loading immediately and override the icon.
await SpecialPowers.pushPrefEnv({ await SpecialPowers.pushPrefEnv({
@ -24,7 +20,7 @@ add_task(async function test_label_and_icon() {
await promiseBrowserLoaded(browser); await promiseBrowserLoaded(browser);
let contentPrincipal = browser.contentPrincipal; let contentPrincipal = browser.contentPrincipal;
let serializedPrincipal = helper.serializeToString(contentPrincipal); let serializedPrincipal = E10SUtils.serializePrincipal(contentPrincipal);
// Retrieve the tab state. // Retrieve the tab state.
await TabStateFlusher.flush(browser); await TabStateFlusher.flush(browser);

View File

@ -48,9 +48,13 @@ if (sessionHistory) {
* to modify and query docShell data when running with multiple processes. * to modify and query docShell data when running with multiple processes.
*/ */
addEventListener("hashchange", function() { addEventListener(
sendAsyncMessage("ss-test:hashchange"); "hashchange",
}); function() {
sendAsyncMessage("ss-test:hashchange");
},
true
);
addMessageListener("ss-test:getStyleSheets", function(msg) { addMessageListener("ss-test:getStyleSheets", function(msg) {
let sheets = content.document.styleSheets; let sheets = content.document.styleSheets;

View File

@ -148,9 +148,7 @@ nsMacShellService::SetDesktopBackground(Element* aElement, int32_t aPosition,
loadContext = do_QueryInterface(docShell); loadContext = do_QueryInterface(docShell);
} }
nsCOMPtr<nsIReferrerInfo> referrerInfo = new mozilla::dom::ReferrerInfo(); auto referrerInfo = mozilla::MakeRefPtr<mozilla::dom::ReferrerInfo>(*aElement);
referrerInfo->InitWithNode(aElement);
return wbp->SaveURI(imageURI, aElement->NodePrincipal(), 0, referrerInfo, return wbp->SaveURI(imageURI, aElement->NodePrincipal(), 0, referrerInfo,
nullptr, nullptr, mBackgroundFile, loadContext); nullptr, nullptr, mBackgroundFile, loadContext);
} }

View File

@ -210,8 +210,8 @@ class UrlbarInput {
this._compositionState = UrlbarUtils.COMPOSITION.NONE; this._compositionState = UrlbarUtils.COMPOSITION.NONE;
this._compositionClosedPopup = false; this._compositionClosedPopup = false;
this.editor.QueryInterface(Ci.nsIPlaintextEditor).newlineHandling = this.editor.newlineHandling =
Ci.nsIPlaintextEditor.eNewlinesStripSurroundingWhitespace; Ci.nsIEditor.eNewlinesStripSurroundingWhitespace;
} }
/** /**
@ -328,7 +328,7 @@ class UrlbarInput {
} }
try { try {
return Services.uriFixup.createExposableURI(uri); return Services.io.createExposableURI(uri);
} catch (ex) {} } catch (ex) {}
return uri; return uri;
@ -1567,9 +1567,8 @@ class UrlbarInput {
} }
_on_overflow(event) { _on_overflow(event) {
const targetIsPlaceholder = !event.originalTarget.classList.contains( const targetIsPlaceholder =
"anonymous-div" event.originalTarget.implementedPseudoElement == "::placeholder";
);
// We only care about the non-placeholder text. // We only care about the non-placeholder text.
// This shouldn't be needed, see bug 1487036. // This shouldn't be needed, see bug 1487036.
if (targetIsPlaceholder) { if (targetIsPlaceholder) {
@ -1580,9 +1579,8 @@ class UrlbarInput {
} }
_on_underflow(event) { _on_underflow(event) {
const targetIsPlaceholder = !event.originalTarget.classList.contains( const targetIsPlaceholder =
"anonymous-div" event.originalTarget.implementedPseudoElement == "::placeholder";
);
// We only care about the non-placeholder text. // We only care about the non-placeholder text.
// This shouldn't be needed, see bug 1487036. // This shouldn't be needed, see bug 1487036.
if (targetIsPlaceholder) { if (targetIsPlaceholder) {

View File

@ -115,9 +115,6 @@ class ProviderUnifiedComplete extends UrlbarProvider {
// This is necessary because we insert matches one by one, thus we don't // This is necessary because we insert matches one by one, thus we don't
// want UnifiedComplete to reuse results. // want UnifiedComplete to reuse results.
params.push(`insert-method:${UrlbarUtils.INSERTMETHOD.APPEND}`); params.push(`insert-method:${UrlbarUtils.INSERTMETHOD.APPEND}`);
// The Quantum Bar has its own telemetry measurement, thus disable old
// telemetry logged by UnifiedComplete.
params.push("disable-telemetry");
if (queryContext.isPrivate) { if (queryContext.isPrivate) {
params.push("private-window"); params.push("private-window");
if (!PrivateBrowsingUtils.permanentPrivateBrowsing) { if (!PrivateBrowsingUtils.permanentPrivateBrowsing) {
@ -285,10 +282,7 @@ function makeUrlbarResult(tokens, info) {
if (!title) { if (!title) {
// If the url doesn't have an host (e.g. javascript urls), comment // If the url doesn't have an host (e.g. javascript urls), comment
// will be empty, and we can't build the usual title. Thus use the url. // will be empty, and we can't build the usual title. Thus use the url.
title = Services.textToSubURI.unEscapeURIForUI( title = Services.textToSubURI.unEscapeURIForUI(action.params.url);
"UTF-8",
action.params.url
);
} else if (tokens && tokens.length > 1) { } else if (tokens && tokens.length > 1) {
title = bundle.formatStringFromName( title = bundle.formatStringFromName(
"bookmarkKeywordSearch", "bookmarkKeywordSearch",

View File

@ -184,10 +184,7 @@ class UrlbarResult {
if (UrlbarPrefs.get("trimURLs")) { if (UrlbarPrefs.get("trimURLs")) {
url = BrowserUtils.trimURL(url || ""); url = BrowserUtils.trimURL(url || "");
} }
payloadInfo.displayUrl[0] = Services.textToSubURI.unEscapeURIForUI( payloadInfo.displayUrl[0] = Services.textToSubURI.unEscapeURIForUI(url);
"UTF-8",
url
);
} }
// For performance reasons limit excessive string lengths, to reduce the // For performance reasons limit excessive string lengths, to reduce the

View File

@ -17,7 +17,7 @@ add_task(async function test_ignoreFragment() {
tabRefAboutHome.linkedBrowser, tabRefAboutHome.linkedBrowser,
null, null,
async function() { async function() {
await ContentTaskUtils.waitForEvent(this, "hashchange", false); await ContentTaskUtils.waitForEvent(this, "hashchange", true);
} }
); );
switchTab("about:home#2", true, { switchTab("about:home#2", true, {

View File

@ -1 +1 @@
68.13.8 68.13.9

View File

@ -1 +1 @@
68.13.8b 68.13.9b

View File

@ -76,11 +76,6 @@ ChromeUtils.defineModuleGetter(
"PrivateBrowsingUtils", "PrivateBrowsingUtils",
"resource://gre/modules/PrivateBrowsingUtils.jsm" "resource://gre/modules/PrivateBrowsingUtils.jsm"
); );
ChromeUtils.defineModuleGetter(
this,
"PermissionUITelemetry",
"resource:///modules/PermissionUITelemetry.jsm"
);
XPCOMUtils.defineLazyServiceGetter( XPCOMUtils.defineLazyServiceGetter(
this, this,
@ -170,17 +165,6 @@ var PermissionPromptPrototype = {
return undefined; return undefined;
}, },
/**
* A string that needs to be set to include this prompt in
* experimental event telemetry collection.
*
* This needs to conform to event telemetry string rules,
* i.e. it needs to be an alphabetic string under 20 characters.
*/
get permissionTelemetryKey() {
return undefined;
},
/** /**
* If true, user permissions will be read from and written to. * If true, user permissions will be read from and written to.
* When this is false, we still provide integration with * When this is false, we still provide integration with
@ -445,8 +429,6 @@ var PermissionPromptPrototype = {
return; return;
} }
this._buttonAction = null;
// Transform the PermissionPrompt actions into PopupNotification actions. // Transform the PermissionPrompt actions into PopupNotification actions.
let popupNotificationActions = []; let popupNotificationActions = [];
for (let promptAction of this.promptActions) { for (let promptAction of this.promptActions) {
@ -489,16 +471,9 @@ var PermissionPromptPrototype = {
} }
// Grant permission if action is ALLOW. // Grant permission if action is ALLOW.
// Record buttonAction for telemetry.
if (promptAction.action == SitePermissions.ALLOW) { if (promptAction.action == SitePermissions.ALLOW) {
this._buttonAction = "accept";
this.allow(); this.allow();
} else { } else {
if (promptAction.scope == SitePermissions.SCOPE_PERSISTENT) {
this._buttonAction = "never";
} else {
this._buttonAction = "deny";
}
this.cancel(); this.cancel();
} }
} else if (this.permissionKey) { } else if (this.permissionKey) {
@ -596,20 +571,6 @@ var PermissionPromptPrototype = {
let options = this.popupOptions; let options = this.popupOptions;
let telemetryData = null;
if (this.request && this.permissionTelemetryKey) {
telemetryData = {
permissionTelemetryKey: this.permissionTelemetryKey,
permissionKey: this.permissionKey,
principal: this.principal,
documentDOMContentLoadedTimestamp: this.request
.documentDOMContentLoadedTimestamp,
isHandlingUserInput: this.request.isHandlingUserInput,
userHadInteractedWithDocument: this.request
.userHadInteractedWithDocument,
};
}
if (!options.hasOwnProperty("displayURI") || options.displayURI) { if (!options.hasOwnProperty("displayURI") || options.displayURI) {
options.displayURI = this.principal.URI; options.displayURI = this.principal.URI;
} }
@ -641,13 +602,6 @@ var PermissionPromptPrototype = {
// You can remove this restriction if you need it, but be // You can remove this restriction if you need it, but be
// mindful of other consumers. // mindful of other consumers.
if (topic == "removed" && !postPrompt) { if (topic == "removed" && !postPrompt) {
if (telemetryData) {
PermissionUITelemetry.onRemoved(
telemetryData,
this._buttonAction,
nextRemovalReason
);
}
this.onAfterShow(); this.onAfterShow();
} }
return false; return false;
@ -670,9 +624,6 @@ var PermissionPromptPrototype = {
secondaryActions, secondaryActions,
options options
); );
if (telemetryData) {
PermissionUITelemetry.onShow(telemetryData);
}
} }
}, },
}; };
@ -733,10 +684,6 @@ GeolocationPermissionPrompt.prototype = {
return "geo"; return "geo";
}, },
get permissionTelemetryKey() {
return "geo";
},
get popupOptions() { get popupOptions() {
let pref = "browser.geolocation.warning.infoURL"; let pref = "browser.geolocation.warning.infoURL";
let options = { let options = {
@ -836,10 +783,6 @@ DesktopNotificationPermissionPrompt.prototype = {
return "desktop-notification"; return "desktop-notification";
}, },
get permissionTelemetryKey() {
return "notifications";
},
get popupOptions() { get popupOptions() {
let learnMoreURL = let learnMoreURL =
Services.urlFormatter.formatURLPref("app.support.baseURL") + "push"; Services.urlFormatter.formatURLPref("app.support.baseURL") + "push";
@ -1120,7 +1063,7 @@ StorageAccessPermissionPrompt.prototype = {
prettifyHostPort(uri) { prettifyHostPort(uri) {
try { try {
uri = Services.uriFixup.createExposableURI(uri); uri = Services.io.createExposableURI(uri);
} catch (e) { } catch (e) {
// ignore, since we can't do anything better // ignore, since we can't do anything better
} }

View File

@ -1,178 +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/. */
"use strict";
var EXPORTED_SYMBOLS = ["PermissionUITelemetry"];
ChromeUtils.defineModuleGetter(
this,
"Services",
"resource://gre/modules/Services.jsm"
);
ChromeUtils.defineModuleGetter(
this,
"CryptoUtils",
"resource://services-crypto/utils.js"
);
const TELEMETRY_STAT_REMOVAL_LEAVE_PAGE = 6;
var PermissionUITelemetry = {
// Returns a hash of the host name in combination with a unique local user id.
// This allows us to track duplicate prompts on sites while not revealing the user's
// browsing history.
_uniqueHostHash(host) {
// Gets a unique user ID as salt, that needs to stay local to this profile and not be
// sent to any server!
let salt = Services.prefs.getStringPref(
"permissions.eventTelemetry.salt",
null
);
if (!salt) {
salt = Cc["@mozilla.org/uuid-generator;1"]
.getService(Ci.nsIUUIDGenerator)
.generateUUID()
.toString();
Services.prefs.setStringPref("permissions.eventTelemetry.salt", salt);
}
let domain;
try {
domain = Services.eTLD.getBaseDomainFromHost(host);
} catch (e) {
domain = host;
}
return CryptoUtils.sha256(domain + salt);
},
_previousVisitCount(host) {
let historyService = Cc[
"@mozilla.org/browser/nav-history-service;1"
].getService(Ci.nsINavHistoryService);
let options = historyService.getNewQueryOptions();
options.resultType = options.RESULTS_AS_VISIT;
// Search for visits to this host before today
let query = historyService.getNewQuery();
query.endTimeReference = query.TIME_RELATIVE_TODAY;
query.endTime = 0;
query.domain = host;
let result = historyService.executeQuery(query, options);
result.root.containerOpen = true;
let cc = result.root.childCount;
result.root.containerOpen = false;
return cc;
},
_collectExtraKeys(prompt) {
let lastInteraction = 0;
// "storageAccessAPI" is the name of the permission that tells us whether the
// user has interacted with a particular site in the first-party context before.
let interactionPermission = Services.perms.getPermissionObject(
prompt.principal,
"storageAccessAPI",
false
);
if (interactionPermission) {
lastInteraction = interactionPermission.modificationTime;
}
let allPermsDenied = 0;
let allPermsGranted = 0;
let thisPermDenied = 0;
let thisPermGranted = 0;
let commonPermissions = [
"geo",
"desktop-notification",
"camera",
"microphone",
"screen",
];
for (let perm of Services.perms.all) {
if (!commonPermissions.includes(perm.type)) {
continue;
}
if (perm.capability == Services.perms.ALLOW_ACTION) {
allPermsGranted++;
if (perm.type == prompt.permissionKey) {
thisPermGranted++;
}
}
if (perm.capability == Services.perms.DENY_ACTION) {
allPermsDenied++;
if (perm.type == prompt.permissionKey) {
thisPermDenied++;
}
}
}
let promptHost = prompt.principal.URI.host;
return {
previousVisits: this._previousVisitCount(promptHost).toString(),
timeOnPage: (
Date.now() - prompt.documentDOMContentLoadedTimestamp
).toString(),
hasUserInput: prompt.isHandlingUserInput.toString(),
docHasUserInput: prompt.userHadInteractedWithDocument.toString(),
lastInteraction: lastInteraction.toString(),
allPermsDenied: allPermsDenied.toString(),
allPermsGranted: allPermsGranted.toString(),
thisPermDenied: thisPermDenied.toString(),
thisPermGranted: thisPermGranted.toString(),
};
},
onShow(prompt) {
let object = prompt.permissionTelemetryKey;
if (!object) {
return;
}
let extraKeys = this._collectExtraKeys(prompt);
let hostHash = this._uniqueHostHash(prompt.principal.URI.host);
Services.telemetry.recordEvent(
"security.ui.permissionprompt",
"show",
object,
hostHash,
extraKeys
);
},
onRemoved(prompt, buttonAction, telemetryReason) {
let object = prompt.permissionTelemetryKey;
if (!object) {
return;
}
let method = "other";
if (buttonAction == "accept") {
method = "accept";
} else if (buttonAction == "deny") {
method = "deny";
} else if (buttonAction == "never") {
method = "never";
} else if (telemetryReason == TELEMETRY_STAT_REMOVAL_LEAVE_PAGE) {
method = "leave";
}
let extraKeys = this._collectExtraKeys(prompt);
let hostHash = this._uniqueHostHash(prompt.principal.URI.host);
Services.telemetry.recordEvent(
"security.ui.permissionprompt",
method,
object,
hostHash,
extraKeys
);
},
};

View File

@ -766,7 +766,7 @@ class PrincipalsCollector {
async getAllPrincipalsInternal(progress) { async getAllPrincipalsInternal(progress) {
progress.step = "principals-quota-manager"; progress.step = "principals-quota-manager";
let principals = await new Promise(resolve => { let principals = await new Promise(resolve => {
quotaManagerService.listOrigins(request => { quotaManagerService.listOrigins().callback = request => {
progress.step = "principals-quota-manager-listOrigins"; progress.step = "principals-quota-manager-listOrigins";
if (request.resultCode != Cr.NS_OK) { if (request.resultCode != Cr.NS_OK) {
// We are probably shutting down. We don't want to propagate the // We are probably shutting down. We don't want to propagate the
@ -776,9 +776,9 @@ class PrincipalsCollector {
} }
let list = []; let list = [];
for (let item of request.result) { for (const origin of request.result) {
let principal = Services.scriptSecurityManager.createCodebasePrincipalFromOrigin( let principal = Services.scriptSecurityManager.createCodebasePrincipalFromOrigin(
item.origin origin
); );
let uri = principal.URI; let uri = principal.URI;
if (isSupportedURI(uri)) { if (isSupportedURI(uri)) {
@ -788,7 +788,7 @@ class PrincipalsCollector {
progress.step = "principals-quota-manager-completed"; progress.step = "principals-quota-manager-completed";
resolve(list); resolve(list);
}); };
}).catch(ex => { }).catch(ex => {
Cu.reportError("QuotaManagerService promise failed: " + ex); Cu.reportError("QuotaManagerService promise failed: " + ex);
return []; return [];

View File

@ -77,9 +77,6 @@ with Files("OpenInTabsUtils.jsm"):
with Files("PermissionUI.jsm"): with Files("PermissionUI.jsm"):
BUG_COMPONENT = ("Firefox", "Site Identity and Permission Panels") BUG_COMPONENT = ("Firefox", "Site Identity and Permission Panels")
with Files("PermissionUITelemetry.jsm"):
BUG_COMPONENT = ("Firefox", "Site Identity and Permission Panels")
with Files("ProcessHangMonitor.jsm"): with Files("ProcessHangMonitor.jsm"):
BUG_COMPONENT = ("Core", "DOM: Content Processes") BUG_COMPONENT = ("Core", "DOM: Content Processes")
@ -150,7 +147,6 @@ EXTRA_JS_MODULES += [
'OpenInTabsUtils.jsm', 'OpenInTabsUtils.jsm',
'PageActions.jsm', 'PageActions.jsm',
'PermissionUI.jsm', 'PermissionUI.jsm',
'PermissionUITelemetry.jsm',
'ProcessHangMonitor.jsm', 'ProcessHangMonitor.jsm',
'ReaderParent.jsm', 'ReaderParent.jsm',
'RemotePrompt.jsm', 'RemotePrompt.jsm',

View File

@ -87,9 +87,7 @@ function makeMockPermissionRequest(browser) {
types.appendElement(type); types.appendElement(type);
let result = { let result = {
types, types,
documentDOMContentLoadedTimestamp: 0,
isHandlingUserInput: false, isHandlingUserInput: false,
userHadInteractedWithDocument: false,
principal: browser.contentPrincipal, principal: browser.contentPrincipal,
topLevelPrincipal: browser.contentPrincipal, topLevelPrincipal: browser.contentPrincipal,
requester: null, requester: null,

View File

@ -31,6 +31,7 @@
border: 1px solid @fieldBorderColor@; border: 1px solid @fieldBorderColor@;
border-radius: var(--toolbarbutton-border-radius); border-radius: var(--toolbarbutton-border-radius);
box-shadow: 0 1px 4px rgba(0,0,0,.05); box-shadow: 0 1px 4px rgba(0,0,0,.05);
outline: none;
padding: 0; padding: 0;
margin: 3px 5px; margin: 3px 5px;
min-height: 30px; min-height: 30px;

View File

@ -55,13 +55,11 @@
void CanRunScriptChecker::registerMatchers(MatchFinder *AstMatcher) { void CanRunScriptChecker::registerMatchers(MatchFinder *AstMatcher) {
auto Refcounted = qualType(hasDeclaration(cxxRecordDecl(isRefCounted()))); auto Refcounted = qualType(hasDeclaration(cxxRecordDecl(isRefCounted())));
auto StackSmartPtr = auto StackSmartPtr =
ignoreTrivials( ignoreTrivials(declRefExpr(to(varDecl(hasAutomaticStorageDuration(),
declRefExpr(to(varDecl(hasAutomaticStorageDuration())), hasType(isSmartPtrToRefCounted())))));
hasType(isSmartPtrToRefCounted())));
auto ConstMemberOfThisSmartPtr = auto ConstMemberOfThisSmartPtr =
memberExpr(hasType(isSmartPtrToRefCounted()), memberExpr(hasType(isSmartPtrToRefCounted()), hasType(isConstQualified()),
hasType(isConstQualified()), hasObjectExpression(cxxThisExpr()));
hasObjectExpression(cxxThisExpr()));
// A smartptr can be known-live for three reasons: // A smartptr can be known-live for three reasons:
// 1) It's declared on the stack. // 1) It's declared on the stack.
// 2) It's a const member of "this". We know "this" is alive (recursively) // 2) It's a const member of "this". We know "this" is alive (recursively)
@ -70,15 +68,14 @@ void CanRunScriptChecker::registerMatchers(MatchFinder *AstMatcher) {
// 3) It's an immediate temporary being constructed at the point where the // 3) It's an immediate temporary being constructed at the point where the
// call is happening. // call is happening.
auto KnownLiveSmartPtr = anyOf( auto KnownLiveSmartPtr = anyOf(
StackSmartPtr, StackSmartPtr, ConstMemberOfThisSmartPtr,
ConstMemberOfThisSmartPtr, ignoreTrivials(cxxConstructExpr(hasType(isSmartPtrToRefCounted()))));
ignoreTrivials(cxxConstructExpr(hasType(isSmartPtrToRefCounted()))));
auto MozKnownLiveCall = auto MozKnownLiveCall =
ignoreTrivials(callExpr(callee(functionDecl(hasName("MOZ_KnownLive"))))); ignoreTrivials(callExpr(callee(functionDecl(hasName("MOZ_KnownLive")))));
// Params of the calling function are presumed live, because it itself should be // Params of the calling function are presumed live, because it itself should
// MOZ_CAN_RUN_SCRIPT. Note that this is subject to // be MOZ_CAN_RUN_SCRIPT. Note that this is subject to
// https://bugzilla.mozilla.org/show_bug.cgi?id=1537656 a the moment. // https://bugzilla.mozilla.org/show_bug.cgi?id=1537656 a the moment.
auto KnownLiveParam = anyOf( auto KnownLiveParam = anyOf(
// "this" is OK // "this" is OK
@ -108,15 +105,12 @@ void CanRunScriptChecker::registerMatchers(MatchFinder *AstMatcher) {
// return non-live objects (e.g. consider "live_pointer->foo()" as an // return non-live objects (e.g. consider "live_pointer->foo()" as an
// example). For purposes of this analysis we are assuming the method // example). For purposes of this analysis we are assuming the method
// calls on smart ptrs all just return the pointer inside, // calls on smart ptrs all just return the pointer inside,
cxxMemberCallExpr(on( cxxMemberCallExpr(
allOf(hasType(isSmartPtrToRefCounted()), on(allOf(hasType(isSmartPtrToRefCounted()), KnownLiveBase))),
KnownLiveBase))),
// operator* or operator-> on a thing that is already known to be live. // operator* or operator-> on a thing that is already known to be live.
cxxOperatorCallExpr( cxxOperatorCallExpr(anyOf(hasOverloadedOperatorName("*"),
anyOf(hasOverloadedOperatorName("*"), hasOverloadedOperatorName("->")),
hasOverloadedOperatorName("->")), hasAnyArgument(KnownLiveBase), argumentCountIs(1)),
hasAnyArgument(KnownLiveBase),
argumentCountIs(1)),
// A dereference on a thing that is known to be live. This is _not_ // A dereference on a thing that is known to be live. This is _not_
// caught by the "operator* or operator->" clause above, because // caught by the "operator* or operator->" clause above, because
// cxxOperatorCallExpr() only catches cases when a class defines // cxxOperatorCallExpr() only catches cases when a class defines
@ -139,47 +133,36 @@ void CanRunScriptChecker::registerMatchers(MatchFinder *AstMatcher) {
// does not guarantee liveness; in fact the callee could modify those // does not guarantee liveness; in fact the callee could modify those
// things! In practice they would be the wrong type anyway, though, so // things! In practice they would be the wrong type anyway, though, so
// it's hard to add a test for this. // it's hard to add a test for this.
unaryOperator( unaryOperator(hasOperatorName("&"),
hasOperatorName("&"), hasUnaryOperand(allOf(anyOf(hasType(references(Refcounted)),
hasUnaryOperand(allOf( hasType(Refcounted)),
anyOf( ignoreTrivials(KnownLiveBase)))));
hasType(references(Refcounted)),
hasType(Refcounted)),
ignoreTrivials(KnownLiveBase))))
);
auto KnownLive = anyOf( auto KnownLive = anyOf(
// Anything above, of course. // Anything above, of course.
KnownLiveSimple, KnownLiveSimple,
// Conditional operators where both arms are live. // Conditional operators where both arms are live.
conditionalOperator( conditionalOperator(hasFalseExpression(ignoreTrivials(KnownLiveSimple)),
hasFalseExpression(ignoreTrivials(KnownLiveSimple)), hasTrueExpression(ignoreTrivials(KnownLiveSimple)))
hasTrueExpression(ignoreTrivials(KnownLiveSimple)))
// We're not handling cases like a dereference of a conditional operator, // We're not handling cases like a dereference of a conditional operator,
// mostly because handling a dereference in general is so ugly. I // mostly because handling a dereference in general is so ugly. I
// _really_ wish I could just write a recursive matcher here easily. // _really_ wish I could just write a recursive matcher here easily.
); );
auto InvalidArg = auto InvalidArg = ignoreTrivialsConditional(
ignoreTrivialsConditional( // We want to consider things if there is anything refcounted involved,
// We want to consider things if there is anything refcounted involved, // including in any of the trivials that we otherwise strip off.
// including in any of the trivials that we otherwise strip off. anyOf(hasType(Refcounted), hasType(pointsTo(Refcounted)),
anyOf( hasType(references(Refcounted)), hasType(isSmartPtrToRefCounted())),
hasType(Refcounted), // We want to find any expression,
hasType(pointsTo(Refcounted)), expr(
hasType(references(Refcounted)),
hasType(isSmartPtrToRefCounted())
),
// We want to find any expression,
expr(
// which is not known live, // which is not known live,
unless(KnownLive), unless(KnownLive),
// and which is not a default arg with value nullptr, since those are // and which is not a default arg with value nullptr, since those are
// always safe, // always safe,
unless(cxxDefaultArgExpr(isNullDefaultArg())), unless(cxxDefaultArgExpr(isNullDefaultArg())),
// and which is not a literal nullptr, // and which is not a literal nullptr,
unless(cxxNullPtrLiteralExpr()), unless(cxxNullPtrLiteralExpr()), expr().bind("invalidArg")));
expr().bind("invalidArg")));
// A matcher which will mark the first invalid argument it finds invalid, but // A matcher which will mark the first invalid argument it finds invalid, but
// will always match, even if it finds no invalid arguments, so it doesn't // will always match, even if it finds no invalid arguments, so it doesn't
@ -203,11 +186,7 @@ void CanRunScriptChecker::registerMatchers(MatchFinder *AstMatcher) {
// which optionally has an invalid arg, // which optionally has an invalid arg,
OptionalInvalidExplicitArg, OptionalInvalidExplicitArg,
// or which optionally has an invalid this argument, // or which optionally has an invalid this argument,
anyOf( anyOf(on(InvalidArg), anything()), expr().bind("callExpr")),
on(InvalidArg),
anything()
),
expr().bind("callExpr")),
// or a regular call expression, // or a regular call expression,
callExpr( callExpr(
// which optionally has an invalid arg. // which optionally has an invalid arg.
@ -238,10 +217,9 @@ namespace {
/// any) also have the annotation. /// any) also have the annotation.
class FuncSetCallback : public MatchFinder::MatchCallback { class FuncSetCallback : public MatchFinder::MatchCallback {
public: public:
FuncSetCallback(CanRunScriptChecker& Checker, FuncSetCallback(CanRunScriptChecker &Checker,
std::unordered_set<const FunctionDecl *> &FuncSet) std::unordered_set<const FunctionDecl *> &FuncSet)
: CanRunScriptFuncs(FuncSet), : CanRunScriptFuncs(FuncSet), Checker(Checker) {}
Checker(Checker) {}
void run(const MatchFinder::MatchResult &Result) override; void run(const MatchFinder::MatchResult &Result) override;
@ -277,14 +255,13 @@ void FuncSetCallback::checkOverriddenMethods(const CXXMethodDecl *Method) {
const char *ErrorNonCanRunScriptOverridden = const char *ErrorNonCanRunScriptOverridden =
"functions marked as MOZ_CAN_RUN_SCRIPT cannot override functions " "functions marked as MOZ_CAN_RUN_SCRIPT cannot override functions "
"that are not marked MOZ_CAN_RUN_SCRIPT"; "that are not marked MOZ_CAN_RUN_SCRIPT";
const char* NoteNonCanRunScriptOverridden = const char *NoteNonCanRunScriptOverridden =
"overridden function declared here"; "overridden function declared here";
Checker.diag(Method->getLocation(), ErrorNonCanRunScriptOverridden, Checker.diag(Method->getLocation(), ErrorNonCanRunScriptOverridden,
DiagnosticIDs::Error); DiagnosticIDs::Error);
Checker.diag(OverriddenMethod->getLocation(), Checker.diag(OverriddenMethod->getLocation(),
NoteNonCanRunScriptOverridden, NoteNonCanRunScriptOverridden, DiagnosticIDs::Note);
DiagnosticIDs::Note);
} }
} }
} }
@ -300,9 +277,7 @@ void CanRunScriptChecker::buildFuncSet(ASTContext *Context) {
Finder.addMatcher( Finder.addMatcher(
functionDecl(hasCanRunScriptAnnotation()).bind("canRunScriptFunction"), functionDecl(hasCanRunScriptAnnotation()).bind("canRunScriptFunction"),
&Callback); &Callback);
Finder.addMatcher( Finder.addMatcher(lambdaExpr().bind("lambda"), &Callback);
lambdaExpr().bind("lambda"),
&Callback);
// We start the analysis, given the ASTContext our main checker is in. // We start the analysis, given the ASTContext our main checker is in.
Finder.matchAST(*Context); Finder.matchAST(*Context);
} }
@ -327,7 +302,7 @@ void CanRunScriptChecker::check(const MatchFinder::MatchResult &Result) {
const char *NoteNonCanRunScriptParent = "caller function declared here"; const char *NoteNonCanRunScriptParent = "caller function declared here";
const Expr *InvalidArg; const Expr *InvalidArg;
if (const CXXDefaultArgExpr* defaultArg = if (const CXXDefaultArgExpr *defaultArg =
Result.Nodes.getNodeAs<CXXDefaultArgExpr>("invalidArg")) { Result.Nodes.getNodeAs<CXXDefaultArgExpr>("invalidArg")) {
InvalidArg = defaultArg->getExpr(); InvalidArg = defaultArg->getExpr();
} else { } else {
@ -383,11 +358,9 @@ void CanRunScriptChecker::check(const MatchFinder::MatchResult &Result) {
// If we have an invalid argument in the call, we emit the diagnostic to // If we have an invalid argument in the call, we emit the diagnostic to
// signal it. // signal it.
if (InvalidArg) { if (InvalidArg) {
const std::string invalidArgText = const std::string invalidArgText = Lexer::getSourceText(
Lexer::getSourceText( CharSourceRange::getTokenRange(InvalidArg->getSourceRange()),
CharSourceRange::getTokenRange(InvalidArg->getSourceRange()), Result.Context->getSourceManager(), Result.Context->getLangOpts());
Result.Context->getSourceManager(),
Result.Context->getLangOpts());
diag(InvalidArg->getExprLoc(), ErrorInvalidArg, DiagnosticIDs::Error) diag(InvalidArg->getExprLoc(), ErrorInvalidArg, DiagnosticIDs::Error)
<< InvalidArg->getSourceRange() << invalidArgText; << InvalidArg->getSourceRange() << invalidArgText;
} }

View File

@ -2,10 +2,10 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <algorithm>
#include "CustomAttributes.h" #include "CustomAttributes.h"
#include "plugin.h" #include "plugin.h"
#include "clang/Frontend/FrontendPluginRegistry.h" #include "clang/Frontend/FrontendPluginRegistry.h"
#include <algorithm>
/* Having annotations in the AST unexpectedly impacts codegen. /* Having annotations in the AST unexpectedly impacts codegen.
* Ideally, we'd avoid having annotations at all, by using an API such as * Ideally, we'd avoid having annotations at all, by using an API such as
@ -26,37 +26,34 @@
using namespace clang; using namespace clang;
using namespace llvm; using namespace llvm;
static DenseMap<const Decl*, CustomAttributesSet> AttributesCache; static DenseMap<const Decl *, CustomAttributesSet> AttributesCache;
static CustomAttributesSet CacheAttributes(const Decl* D) static CustomAttributesSet CacheAttributes(const Decl *D) {
{
CustomAttributesSet attrs = {}; CustomAttributesSet attrs = {};
for (auto Attr : D->specific_attrs<AnnotateAttr>()) { for (auto Attr : D->specific_attrs<AnnotateAttr>()) {
auto annotation = Attr->getAnnotation(); auto annotation = Attr->getAnnotation();
#define ATTR(a) \ #define ATTR(a) \
if (annotation == #a) { \ if (annotation == #a) { \
attrs.has_ ## a = true; \ attrs.has_##a = true; \
} else } else
#include "CustomAttributes.inc" #include "CustomAttributes.inc"
#undef ATTR #undef ATTR
{} {}
} }
const_cast<Decl*>(D)->dropAttr<AnnotateAttr>(); const_cast<Decl *>(D)->dropAttr<AnnotateAttr>();
AttributesCache.insert(std::make_pair(D, attrs)); AttributesCache.insert(std::make_pair(D, attrs));
return attrs; return attrs;
} }
static void Report(const Decl* D, const char* message) static void Report(const Decl *D, const char *message) {
{ ASTContext &Context = D->getASTContext();
ASTContext& Context = D->getASTContext(); DiagnosticsEngine &Diag = Context.getDiagnostics();
DiagnosticsEngine& Diag = Context.getDiagnostics(); unsigned ID =
unsigned ID = Diag.getDiagnosticIDs()->getCustomDiagID( Diag.getDiagnosticIDs()->getCustomDiagID(DiagnosticIDs::Warning, message);
DiagnosticIDs::Warning, message);
Diag.Report(D->getBeginLoc(), ID); Diag.Report(D->getBeginLoc(), ID);
} }
CustomAttributesSet GetAttributes(const Decl* D) CustomAttributesSet GetAttributes(const Decl *D) {
{
CustomAttributesSet attrs = {}; CustomAttributesSet attrs = {};
if (D->hasAttr<AnnotateAttr>()) { if (D->hasAttr<AnnotateAttr>()) {
Report(D, "Declaration has unhandled annotations."); Report(D, "Declaration has unhandled annotations.");
@ -70,22 +67,22 @@ CustomAttributesSet GetAttributes(const Decl* D)
return attrs; return attrs;
} }
bool hasCustomAttribute(const clang::Decl* D, CustomAttributes A) bool hasCustomAttribute(const clang::Decl *D, CustomAttributes A) {
{
CustomAttributesSet attrs = GetAttributes(D); CustomAttributesSet attrs = GetAttributes(D);
switch (A) { switch (A) {
#define ATTR(a) case a: return attrs.has_ ## a; #define ATTR(a) \
case a: \
return attrs.has_##a;
#include "CustomAttributes.inc" #include "CustomAttributes.inc"
#undef ATTR #undef ATTR
} }
return false; return false;
} }
class CustomAttributesMatcher : public ast_matchers::MatchFinder::MatchCallback { class CustomAttributesMatcher
: public ast_matchers::MatchFinder::MatchCallback {
public: public:
virtual void void run(const ast_matchers::MatchFinder::MatchResult &Result) final {
run(const ast_matchers::MatchFinder::MatchResult &Result) final
{
if (auto D = Result.Nodes.getNodeAs<Decl>("decl")) { if (auto D = Result.Nodes.getNodeAs<Decl>("decl")) {
CacheAttributes(D); CacheAttributes(D);
} else if (auto L = Result.Nodes.getNodeAs<LambdaExpr>("lambda")) { } else if (auto L = Result.Nodes.getNodeAs<LambdaExpr>("lambda")) {
@ -99,9 +96,10 @@ class CustomAttributesAction : public PluginASTAction {
public: public:
ASTConsumerPtr CreateASTConsumer(CompilerInstance &CI, ASTConsumerPtr CreateASTConsumer(CompilerInstance &CI,
StringRef FileName) override { StringRef FileName) override {
auto& Context = CI.getASTContext(); auto &Context = CI.getASTContext();
auto AstMatcher = new (Context.Allocate<MatchFinder>()) MatchFinder(); auto AstMatcher = new (Context.Allocate<MatchFinder>()) MatchFinder();
auto Matcher = new (Context.Allocate<CustomAttributesMatcher>()) CustomAttributesMatcher(); auto Matcher = new (Context.Allocate<CustomAttributesMatcher>())
CustomAttributesMatcher();
AstMatcher->addMatcher(decl().bind("decl"), Matcher); AstMatcher->addMatcher(decl().bind("decl"), Matcher);
AstMatcher->addMatcher(lambdaExpr().bind("lambda"), Matcher); AstMatcher->addMatcher(lambdaExpr().bind("lambda"), Matcher);
return AstMatcher->newASTConsumer(); return AstMatcher->newASTConsumer();
@ -112,11 +110,8 @@ public:
return true; return true;
} }
ActionType getActionType() override { ActionType getActionType() override { return AddBeforeMainAction; }
return AddBeforeMainAction;
}
}; };
static FrontendPluginRegistry::Add<CustomAttributesAction> X( static FrontendPluginRegistry::Add<CustomAttributesAction>
"moz-custom-attributes", X("moz-custom-attributes", "prepare custom attributes for moz-check");
"prepare custom attributes for moz-check");

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