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
browser/components/translation/cld2/.*
browser/extensions/mortar/ppapi/.*
db/sqlite3/src/.*
devtools/client/shared/sourceeditor/codemirror/.*
devtools/client/shared/sourceeditor/tern/.*
dom/canvas/test/webgl-conf/checkout/closure-library/.*

View File

@ -145,23 +145,6 @@ module.exports = {
"no-redeclare": "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": [
"netwerk/cookie/test/browser/**",

View File

@ -22,4 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# 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",
"media/mp4parse-rust/mp4parse",
"media/mp4parse-rust/mp4parse_capi",
"media/mp4parse-rust/mp4parse_fallible",
"xpcom/rust/gkrust_utils",
]

View File

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

View File

@ -186,7 +186,7 @@ class AccessibleNode : public nsISupports, public nsWrapperCache {
if (!aValue) {
mRelationProperties.Remove(static_cast<int>(aProperty));
} 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 "States.h"
#include "mozilla/EventStateManager.h"
#include "mozilla/dom/Selection.h"
#include "mozilla/dom/UserActivation.h"
using namespace mozilla;
using namespace mozilla::a11y;
@ -30,7 +30,7 @@ AccEvent::AccEvent(uint32_t aEventType, Accessible* aAccessible,
EIsFromUserInput aIsFromUserInput, EEventRule aEventRule)
: mEventType(aEventType), mEventRule(aEventRule), mAccessible(aAccessible) {
if (aIsFromUserInput == eAutoDetect)
mIsFromUserInput = EventStateManager::IsHandlingUserInput();
mIsFromUserInput = dom::UserActivation::IsHandlingUserInput();
else
mIsFromUserInput = aIsFromUserInput == eFromUserInput ? true : false;
}

View File

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

View File

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

View File

@ -30,7 +30,9 @@ bool EventQueue::PushEvent(AccEvent* aEvent) {
aEvent->Document() == mDocument,
"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.
CoalesceEvents();

View File

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

View File

@ -392,7 +392,7 @@ MARKUPMAP(
[](Element* aElement, Accessible* aContext) -> Accessible* {
return new HTMLOutputAccessible(aElement, aContext->Document());
},
roles::SECTION, Attr(live, polite))
roles::STATUSBAR, Attr(live, polite))
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());
MOZ_ASSERT((addr & 0x3) == 0, "accessible is not 4 byte aligned");
addr |= type;
mTable.Put(addr, aEvent);
mTable.Put(addr, RefPtr{aEvent});
}
AccTreeMutationEvent* NotificationController::EventMap::GetEvent(

View File

@ -197,7 +197,10 @@ class NotificationController final : public EventQueue,
* Pend an accessible subtree relocation.
*/
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();
}
}
@ -233,9 +236,13 @@ class NotificationController final : public EventQueue,
RefPtr<Notification> notification =
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();
}
}
/**
* Schedule the generic notification to process asynchronously.
@ -248,9 +255,13 @@ class NotificationController final : public EventQueue,
Class* aInstance, typename TNotification<Class>::Callback aMethod) {
RefPtr<Notification> notification =
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();
}
}
template <class Class, class Arg>
inline void ScheduleNotification(
@ -258,7 +269,10 @@ class NotificationController final : public EventQueue,
Arg* aArg) {
RefPtr<Notification> notification =
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();
}
}

View File

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

View File

@ -19,15 +19,12 @@ StyleInfo::StyleInfo(dom::Element* aElement) : mElement(aElement) {
void StyleInfo::Display(nsAString& aValue) {
aValue.Truncate();
Servo_GetPropertyValue(mComputedStyle, eCSSProperty_display, &aValue);
mComputedStyle->GetComputedPropertyValue(eCSSProperty_display, aValue);
}
void StyleInfo::TextAlign(nsAString& aValue) {
aValue.Truncate();
AppendASCIItoUTF16(
nsCSSProps::ValueToKeyword(mComputedStyle->StyleText()->mTextAlign,
nsCSSProps::kTextAlignKTable),
aValue);
mComputedStyle->GetComputedPropertyValue(eCSSProperty_text_align, aValue);
}
void StyleInfo::TextIndent(nsAString& aValue) {
@ -72,7 +69,23 @@ void StyleInfo::FormatColor(const nscolor& aValue, nsString& aFormattedValue) {
void StyleInfo::FormatTextDecorationStyle(uint8_t aValue,
nsAString& aFormattedValue) {
nsCSSKeyword keyword = nsCSSProps::ValueToKeywordEnum(
aValue, nsCSSProps::kTextDecorationStyleKTable);
AppendUTF8toUTF16(nsCSSKeywords::GetStringValue(keyword), aFormattedValue);
// TODO: When these are enum classes that rust also understands we should just
// make an FFI call here.
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 "mozilla/a11y/PDocAccessibleChild.h"
#include "mozilla/dom/Element.h"
#include "nsAccessibilityService.h"
using namespace mozilla;
using namespace mozilla::a11y;
@ -137,7 +138,11 @@ void nsAccUtils::SetLiveContainerAttributes(
live);
} else if (role) {
GetLiveAttrValue(role->liveAttRule, live);
} else if (nsStaticAtom* value = GetAccService()->MarkupAttribute(
ancestor, nsGkAtoms::live)) {
value->ToString(live);
}
if (!live.IsEmpty()) {
SetAccAttr(aAttributes, nsGkAtoms::containerLive, live);
if (role) {
@ -487,6 +492,9 @@ bool nsAccUtils::IsARIALive(const Accessible* aAccessible) {
docLive);
} else if (role) {
GetLiveAttrValue(role->liveAttRule, docLive);
} else if (nsStaticAtom* value = GetAccService()->MarkupAttribute(
ancestor, nsGkAtoms::live)) {
value->ToString(docLive);
}
if (!docLive.IsEmpty()) {
live = docLive;

View File

@ -335,6 +335,25 @@ void nsAccessibilityService::FireAccessibleEvent(uint32_t aEvent,
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(
PresShell* aPresShell, bool aCanCreate) {
PresShell* presShell = aPresShell;
@ -343,7 +362,7 @@ Accessible* nsAccessibilityService::GetRootDocumentAccessible(
nsCOMPtr<nsIDocShellTreeItem> treeItem(documentNode->GetDocShell());
if (treeItem) {
nsCOMPtr<nsIDocShellTreeItem> rootTreeItem;
treeItem->GetRootTreeItem(getter_AddRefs(rootTreeItem));
treeItem->GetInProcessRootTreeItem(getter_AddRefs(rootTreeItem));
if (treeItem != rootTreeItem) {
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(rootTreeItem));
presShell = docShell->GetPresShell();

View File

@ -222,6 +222,15 @@ class nsAccessibilityService final : public mozilla::a11y::DocManager,
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
/**
@ -246,6 +255,25 @@ class nsAccessibilityService final : public mozilla::a11y::DocManager,
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.
*/

View File

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

View File

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

View File

@ -65,7 +65,6 @@
#include "mozilla/Assertions.h"
#include "mozilla/BasicEvents.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/EventStateManager.h"
#include "mozilla/EventStates.h"
#include "mozilla/FloatingPoint.h"
#include "mozilla/MouseEvents.h"
@ -79,6 +78,7 @@
#include "mozilla/dom/HTMLBodyElement.h"
#include "mozilla/dom/KeyboardEventBinding.h"
#include "mozilla/dom/TreeWalker.h"
#include "mozilla/dom/UserActivation.h"
using namespace mozilla;
using namespace mozilla::a11y;
@ -736,7 +736,7 @@ void Accessible::TakeFocus() const {
nsFocusManager* fm = nsFocusManager::GetFocusManager();
if (fm) {
AutoHandlingUserInputStatePusher inputStatePusher(true);
dom::AutoHandlingUserInputStatePusher inputStatePusher(true);
// XXXbz: Can we actually have a non-element content here?
RefPtr<Element> element =
focusContent->IsElement() ? focusContent->AsElement() : nullptr;
@ -2074,7 +2074,7 @@ RootAccessible* Accessible::RootAccessible() const {
}
nsCOMPtr<nsIDocShellTreeItem> root;
docShell->GetRootTreeItem(getter_AddRefs(root));
docShell->GetInProcessRootTreeItem(getter_AddRefs(root));
NS_ASSERTION(root, "No root content tree item");
if (!root) {
return nullptr;
@ -2106,10 +2106,13 @@ bool Accessible::InsertChildAt(uint32_t aIndex, Accessible* aChild) {
if (!aChild) return false;
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 {
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");

View File

@ -110,8 +110,10 @@ inline void DocAccessible::NotifyOfLoad(uint32_t aLoadEventType) {
}
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);
}
}
inline Accessible* DocAccessible::GetAccessibleEvenIfNotInMapOrContainer(

View File

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

View File

@ -432,7 +432,10 @@ class DocAccessible : public HyperTextAccessibleWrap,
* accessibles.
*/
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 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;
} else if (mContent->IsHTMLElement(nsGkAtoms::article)) {
@ -324,7 +324,7 @@ static nsIContent* GetElementAsContentOf(nsINode* aNode) {
bool HyperTextAccessible::OffsetsToDOMRange(int32_t aStartOffset,
int32_t aEndOffset,
nsRange* aRange) {
nsRange* aRange) const {
DOMPoint startPoint = OffsetToDOMPoint(aStartOffset);
if (!startPoint.node) return false;
@ -357,7 +357,7 @@ bool HyperTextAccessible::OffsetsToDOMRange(int32_t aStartOffset,
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
// is empty so return a DOM point for editor root element.
if (aOffset == 0) {
@ -404,7 +404,7 @@ DOMPoint HyperTextAccessible::OffsetToDOMPoint(int32_t aOffset) {
}
DOMPoint HyperTextAccessible::ClosestNotGeneratedDOMPoint(
const DOMPoint& aDOMPoint, nsIContent* aElementContent) {
const DOMPoint& aDOMPoint, nsIContent* aElementContent) const {
MOZ_ASSERT(aDOMPoint.node, "The node must not be null");
// ::before pseudo element
@ -521,8 +521,10 @@ uint32_t HyperTextAccessible::FindOffset(uint32_t aOffset,
nsresult rv = frameAtOffset->PeekOffset(&pos);
// PeekOffset fails on last/first lines of the text in certain cases.
bool fallBackToSelectEndLine = false;
if (NS_FAILED(rv) && aAmount == eSelectLine) {
pos.mAmount = (aDirection == eDirNext) ? eSelectEndLine : eSelectBeginLine;
fallBackToSelectEndLine = aDirection == eDirNext;
pos.mAmount = fallBackToSelectEndLine ? eSelectEndLine : eSelectBeginLine;
frameAtOffset->PeekOffset(&pos);
}
if (!pos.mResultContent) {
@ -534,6 +536,14 @@ uint32_t HyperTextAccessible::FindOffset(uint32_t aOffset,
uint32_t hyperTextOffset = DOMPointToOffset(
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 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
@ -1260,13 +1270,15 @@ nsresult HyperTextAccessible::SetSelectionRange(int32_t aStartPos,
// some input controls
if (isFocusable) TakeFocus();
dom::Selection* domSel = DOMSelection();
RefPtr<dom::Selection> domSel = DOMSelection();
NS_ENSURE_STATE(domSel);
// Set up the selection.
for (int32_t idx = domSel->RangeCount() - 1; idx > 0; idx--)
domSel->RemoveRangeAndUnselectFramesAndNotifyListeners(
*domSel->GetRangeAt(idx), IgnoreErrors());
for (int32_t idx = domSel->RangeCount() - 1; idx > 0; idx--) {
RefPtr<nsRange> range{domSel->GetRangeAt(idx)};
domSel->RemoveRangeAndUnselectFramesAndNotifyListeners(*range,
IgnoreErrors());
}
SetSelectionBoundsAt(0, aStartPos, aEndPos);
// Make sure it is visible
@ -1552,15 +1564,16 @@ bool HyperTextAccessible::SetSelectionBoundsAt(int32_t aSelectionNum,
return false;
}
dom::Selection* domSel = DOMSelection();
RefPtr<dom::Selection> domSel = DOMSelection();
if (!domSel) return false;
RefPtr<nsRange> range;
uint32_t rangeCount = domSel->RangeCount();
if (aSelectionNum == static_cast<int32_t>(rangeCount))
range = new nsRange(mContent);
else
if (aSelectionNum == static_cast<int32_t>(rangeCount)) {
range = nsRange::Create(mContent);
} else {
range = domSel->GetRangeAt(aSelectionNum);
}
if (!range) return false;
@ -1589,22 +1602,23 @@ bool HyperTextAccessible::SetSelectionBoundsAt(int32_t aSelectionNum,
}
bool HyperTextAccessible::RemoveFromSelection(int32_t aSelectionNum) {
dom::Selection* domSel = DOMSelection();
RefPtr<dom::Selection> domSel = DOMSelection();
if (!domSel) return false;
if (aSelectionNum < 0 ||
aSelectionNum >= static_cast<int32_t>(domSel->RangeCount()))
return false;
domSel->RemoveRangeAndUnselectFramesAndNotifyListeners(
*domSel->GetRangeAt(aSelectionNum), IgnoreErrors());
const RefPtr<nsRange> range{domSel->GetRangeAt(aSelectionNum)};
domSel->RemoveRangeAndUnselectFramesAndNotifyListeners(*range,
IgnoreErrors());
return true;
}
void HyperTextAccessible::ScrollSubstringTo(int32_t aStartOffset,
int32_t aEndOffset,
uint32_t aScrollType) {
RefPtr<nsRange> range = new nsRange(mContent);
RefPtr<nsRange> range = nsRange::Create(mContent);
if (OffsetsToDOMRange(aStartOffset, aEndOffset, range))
nsCoreUtils::ScrollSubstringTo(GetFrame(), range, aScrollType);
}
@ -1619,7 +1633,7 @@ void HyperTextAccessible::ScrollSubstringToPoint(int32_t aStartOffset,
nsIntPoint coords =
nsAccUtils::ConvertToScreenCoords(aX, aY, aCoordinateType, this);
RefPtr<nsRange> range = new nsRange(mContent);
RefPtr<nsRange> range = nsRange::Create(mContent);
if (!OffsetsToDOMRange(aStartOffset, aEndOffset, range)) return;
nsPresContext* presContext = frame->PresContext();
@ -1683,7 +1697,7 @@ void HyperTextAccessible::SelectionRanges(
aRanges->SetCapacity(sel->RangeCount());
for (uint32_t idx = 0; idx < sel->RangeCount(); idx++) {
nsRange* DOMRange = sel->GetRangeAt(idx);
const nsRange* DOMRange = sel->GetRangeAt(idx);
HyperTextAccessible* startContainer =
nsAccUtils::GetTextContainer(DOMRange->GetStartContainer());
HyperTextAccessible* endContainer =
@ -2003,7 +2017,7 @@ void HyperTextAccessible::GetSpellTextAttr(
uint32_t startOffset = 0, endOffset = 0;
for (int32_t idx = 0; idx < rangeCount; idx++) {
nsRange* range = domSel->GetRangeAt(idx);
const nsRange* range = domSel->GetRangeAt(idx);
if (range->Collapsed()) continue;
// 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);
if (idx > 0) {
nsRange* prevRange = domSel->GetRangeAt(idx - 1);
const nsRange* prevRange = domSel->GetRangeAt(idx - 1);
startOffset = DOMPointToOffset(prevRange->GetEndContainer(),
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,
// and that we should use the end offset of the last range to compute the
// start offset of the text attribute range.
nsRange* prevRange = domSel->GetRangeAt(rangeCount - 1);
const nsRange* prevRange = domSel->GetRangeAt(rangeCount - 1);
startOffset =
DOMPointToOffset(prevRange->GetEndContainer(), prevRange->EndOffset());

View File

@ -142,7 +142,7 @@ class HyperTextAccessible : public AccessibleWrap {
* @return true if conversion was successful
*/
bool OffsetsToDOMRange(int32_t aStartOffset, int32_t aEndOffset,
nsRange* aRange);
nsRange* aRange) const;
/**
* 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
* (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
@ -340,7 +340,9 @@ class HyperTextAccessible : public AccessibleWrap {
* Changes the start and end offset of the specified selection.
* @return true if succeeded
*/
bool SetSelectionBoundsAt(int32_t aSelectionNum, int32_t aStartOffset,
// TODO: annotate this with `MOZ_CAN_RUN_SCRIPT` instead.
MOZ_CAN_RUN_SCRIPT_BOUNDARY bool SetSelectionBoundsAt(int32_t aSelectionNum,
int32_t aStartOffset,
int32_t aEndOffset);
/**
@ -353,7 +355,8 @@ class HyperTextAccessible : public AccessibleWrap {
* Removes the specified selection.
* @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.
@ -507,7 +510,9 @@ class HyperTextAccessible : public AccessibleWrap {
void GetSelectionDOMRanges(SelectionType aSelectionType,
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.
@ -524,7 +529,7 @@ class HyperTextAccessible : public AccessibleWrap {
* contents.
*/
DOMPoint ClosestNotGeneratedDOMPoint(const DOMPoint& aDOMPoint,
nsIContent* aElementContent);
nsIContent* aElementContent) const;
// Helpers
nsresult GetDOMPointByFrameOffset(nsIFrame* aFrame, int32_t aOffset,

View File

@ -47,13 +47,30 @@ uint64_t ImageAccessible::NativeState() const {
content->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
getter_AddRefs(imageRequest));
if (imageRequest) {
nsCOMPtr<imgIContainer> imgContainer;
if (imageRequest) imageRequest->GetImage(getter_AddRefs(imgContainer));
imageRequest->GetImage(getter_AddRefs(imgContainer));
if (imgContainer) {
bool animated = false;
imgContainer->GetAnimated(&animated);
if (animated) state |= states::ANIMATED;
if (animated) {
state |= states::ANIMATED;
}
}
nsIFrame* frame = GetFrame();
MOZ_ASSERT(!frame || frame->AccessibleType() == eImageType ||
frame->AccessibleType() == a11y::eHTMLImageMapType);
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;

View File

@ -459,7 +459,7 @@ Accessible* HTMLFileInputAccessible::CurrentItem() const {
role HTMLSpinnerAccessible::NativeRole() const { return roles::SPINBUTTON; }
void HTMLSpinnerAccessible::Value(nsString& aValue) const {
AccessibleWrap::Value(aValue);
HTMLTextFieldAccessible::Value(aValue);
if (!aValue.IsEmpty()) return;
// 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 value = AccessibleWrap::MaxValue();
double value = HTMLTextFieldAccessible::MaxValue();
if (!IsNaN(value)) return value;
return HTMLInputElement::FromNode(mContent)->GetMaximum().toDouble();
}
double HTMLSpinnerAccessible::MinValue() const {
double value = AccessibleWrap::MinValue();
double value = HTMLTextFieldAccessible::MinValue();
if (!IsNaN(value)) return value;
return HTMLInputElement::FromNode(mContent)->GetMinimum().toDouble();
}
double HTMLSpinnerAccessible::Step() const {
double value = AccessibleWrap::Step();
double value = HTMLTextFieldAccessible::Step();
if (!IsNaN(value)) return value;
return HTMLInputElement::FromNode(mContent)->GetStep().toDouble();
}
double HTMLSpinnerAccessible::CurValue() const {
double value = AccessibleWrap::CurValue();
double value = HTMLTextFieldAccessible::CurValue();
if (!IsNaN(value)) return value;
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
* other HTML text controls.
*/
class HTMLTextFieldAccessible final : public HyperTextAccessibleWrap {
class HTMLTextFieldAccessible : public HyperTextAccessibleWrap {
public:
enum { eAction_Click = 0 };
@ -128,10 +128,10 @@ class HTMLFileInputAccessible : public HyperTextAccessibleWrap {
/**
* Used for HTML input@type="number".
*/
class HTMLSpinnerAccessible : public AccessibleWrap {
class HTMLSpinnerAccessible final : public HTMLTextFieldAccessible {
public:
HTMLSpinnerAccessible(nsIContent* aContent, DocAccessible* aDoc)
: AccessibleWrap(aContent, aDoc) {
: HTMLTextFieldAccessible(aContent, aDoc) {
mStateFlags |= eHasNumericValue;
}

View File

@ -9,7 +9,7 @@
#include "Role.h"
#include "States.h"
#include "nsContainerFrame.h"
#include "nsBulletFrame.h"
#include "nsLayoutUtils.h"
using namespace mozilla;
@ -36,11 +36,15 @@ HTMLLIAccessible::HTMLLIAccessible(nsIContent* aContent, DocAccessible* aDoc)
: HyperTextAccessibleWrap(aContent, aDoc), mBullet(nullptr) {
mType = eHTMLLiType;
if (nsLayoutUtils::GetMarkerFrame(aContent)) {
if (nsBulletFrame* bulletFrame =
do_QueryFrame(nsLayoutUtils::GetMarkerFrame(aContent))) {
const nsStyleList* styleList = bulletFrame->StyleList();
if (styleList->GetListStyleImage() || !styleList->mCounterStyle.IsNone()) {
mBullet = new HTMLListBulletAccessible(mContent, mDoc);
Document()->BindToDocument(mBullet, nullptr);
AppendChild(mBullet);
}
}
}
void HTMLLIAccessible::Shutdown() {
@ -123,10 +127,20 @@ ENameValueFlag HTMLListBulletAccessible::Name(nsString& aName) const {
aName.Truncate();
// Native anonymous content, ARIA can't be used. Get list bullet text.
if (nsContainerFrame* frame = do_QueryFrame(mContent->GetPrimaryFrame())) {
frame->GetSpokenMarkerText(aName);
nsBulletFrame* frame = do_QueryFrame(GetFrame());
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;
}

View File

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

View File

@ -14,7 +14,7 @@ class nsTableCellFrame;
namespace mozilla {
enum class TableSelection : uint32_t;
enum class TableSelectionMode : uint32_t;
namespace a11y {
@ -176,7 +176,8 @@ class HTMLTableAccessible : public HyperTextAccessibleWrap,
* @param aTarget [in] indicates what should be selected, either row or
* 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.
@ -188,7 +189,7 @@ class HTMLTableAccessible : public HyperTextAccessibleWrap,
* should be unselected only
*/
nsresult RemoveRowsOrColumnsFromSelection(int32_t aIndex,
TableSelection aTarget,
TableSelectionMode aTarget,
bool aIsOuter);
#ifdef SHOW_LAYOUT_HEURISTIC

View File

@ -25,7 +25,7 @@ class ProxyAccessible : public ProxyAccessibleBase<ProxyAccessible> {
MOZ_COUNT_CTOR(ProxyAccessible);
}
~ProxyAccessible() { MOZ_COUNT_DTOR(ProxyAccessible); }
MOZ_COUNTED_DTOR(ProxyAccessible)
#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
# 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']:
IPDL_SOURCES += ['PDocAccessible.ipdl']
EXPORTS.mozilla.a11y += [
'DocAccessibleChild.h',
'ProxyAccessible.h',

View File

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

View File

@ -8,15 +8,9 @@ if CONFIG['COMPILE_ENVIRONMENT'] and CONFIG['ACCESSIBILITY']:
'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']:
IPDL_SOURCES += ['PDocAccessible.ipdl']
if not CONFIG['HAVE_64BIT_BUILD']:
EXPORTS += [
'IAccessible32.manifest',
@ -27,6 +21,7 @@ if CONFIG['ACCESSIBILITY']:
]
EXPORTS.mozilla.a11y += [
'COMPtrTypes.h',
'DocAccessibleChild.h',
'HandlerProvider.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("timerChild", {"container-live": "off"}, true);
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
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("tel", {"text-input-type": "tel"}, 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
testAttrs("searchbox", {"text-input-type": "search"}, true);
@ -166,6 +169,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=558036
<pre id="test">
</pre>
<!-- container live -->
<output id="containerLiveOutput"><div id="containerLiveOutput1"><div id="containerLiveOutput2">Test</div></div></output>
<!-- aria -->
<div id="atomic" aria-atomic="true">live region</div>
<div id="atomic_false" aria-atomic="false">live region</div>

View File

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

View File

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

View File

@ -112,12 +112,12 @@
two words
</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
two words
</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
two words

View File

@ -84,7 +84,7 @@
testTextAtOffset(2, nsIAccessibleText.BOUNDARY_CHAR, "o", 2, 3, "testbr",
kOk, kOk, kOk);
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",
0, 4, "testbr", kTodo, kOk, kTodo);

View File

@ -106,10 +106,10 @@
testTextAtOffset([ getAccessible("ht_2").firstChild.firstChild ],
BOUNDARY_LINE_START,
[ [ 0, 3, "foo", 0, 3 ] ]);
[ [ 0, 3, "foo\n", 0, 4 ] ]);
testTextAtOffset([ getAccessible("ht_3").firstChild.firstChild ],
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)
@ -211,12 +211,12 @@
two words
</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
two words
</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
two words

View File

@ -305,12 +305,12 @@
two words
</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
two words
</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
two words

View File

@ -126,6 +126,12 @@
];
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 range = document.createRange();
range.setStart(getNode(aNodeID1), aNodeOffset1);

View File

@ -199,7 +199,11 @@ function doTest() {
{ TEXT_LEAF: [] }, // text
], // end children 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
children: [
{ TEXT_LEAF: [] }, // text

View File

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

View File

@ -166,6 +166,63 @@
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();
}
@ -266,5 +323,32 @@
<div><dt>item2</td><dd>description</dd></div>
</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>
</html>

View File

@ -115,7 +115,7 @@ sdnTextAccessible::scrollToSubstring(unsigned int aStartIndex,
unsigned int aEndIndex) {
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)))
return E_FAIL;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -365,13 +365,6 @@ pref("permissions.default.shortcuts", 0);
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
pref("permissions.delegation.enable", true);
#else
@ -1400,11 +1393,6 @@ pref("identity.fxaccounts.commands.enabled", true);
// Default is 24 hours.
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
// decode H.264.
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);
#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.neverForLanguages", "");
// 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).
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.
pref("toolkit.coverage.enabled", false);
pref("toolkit.coverage.endpoint.base", "data:text/plain,");

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -2,3 +2,5 @@
[browser_principalSerialization_version1.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");
});
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() {
/*
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() {
// Push the state before maximizing the window and clicking below.
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();
@ -32,23 +20,16 @@ add_task(async function() {
var yPixel = boundingRect.top + Math.floor(boundingRect.height / 2);
var xPixel = 0; // Use the first pixel of the screen since it is maximized.
let resultLocation = await new Promise(resolve => {
window.messageManager.addMessageListener(
"Test:PopStateOccurred",
function statePopped(message) {
window.messageManager.removeMessageListener(
"Test:PopStateOccurred",
statePopped
let popStatePromise = BrowserTestUtils.waitForContentEvent(
gBrowser.selectedBrowser,
"popstate",
true
);
resolve(message.data.location);
}
);
EventUtils.synthesizeMouseAtPoint(xPixel, yPixel, {}, window);
});
await popStatePromise;
is(
resultLocation,
gBrowser.selectedBrowser.currentURI.spec,
firstLocation,
"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.
*/
add_task(async function test_new_tab() {
await SpecialPowers.pushPrefEnv({
set: [["domsecurity.skip_html_fragment_assertion", true]],
});
let normalWindow = await BrowserTestUtils.openNewBrowserWindow({
remote: true,
});
@ -84,6 +88,10 @@ add_task(async function test_new_tab() {
* window. Also tests with a private browsing window.
*/
add_task(async function test_new_window() {
await SpecialPowers.pushPrefEnv({
set: [["domsecurity.skip_html_fragment_assertion", true]],
});
let normalWindow = await BrowserTestUtils.openNewBrowserWindow(
{
remote: true,

View File

@ -49,11 +49,8 @@ function testFirstPartyDomain(pageInfo) {
}
// 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 loadingPrincipal = serial.deserializeObject(loadingPrincipalStr);
let loadingPrincipal = E10SUtils.deserializePrincipal(loadingPrincipalStr);
Assert.equal(
loadingPrincipal.originAttributes.firstPartyDomain,
EXPECTED_DOMAIN,

View File

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

View File

@ -6,7 +6,6 @@ support-files=
[browser_canvas_fingerprinting_resistance.js]
skip-if = debug || os == "linux" && asan # Bug 1522069
[browser_permissions.js]
[browser_permissions_event_telemetry.js]
[browser_permissions_postPrompt.js]
support-files=
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", {
pluginName: "",
pluginDumpID: "",
browserDumpID: "",
submittedCrashReport: false,
bubbles: true,
cancelable: true,
@ -247,7 +246,6 @@ add_task(async function testContentHearsCrashFirst() {
let event = new content.PluginCrashedEvent("PluginCrashed", {
pluginName: "",
pluginDumpID: "",
browserDumpID: "",
submittedCrashReport: false,
bubbles: true,
cancelable: true,

View File

@ -35,7 +35,7 @@ let whitelist = [
isFromDevTools: false,
},
{
sourceName: /\b(html|mathml|ua)\.css$/i,
sourceName: /\b(minimal-xul|html|mathml|ua)\.css$/i,
errorMessage: /Unknown property.*-moz-/i,
isFromDevTools: false,
},
@ -57,7 +57,7 @@ let whitelist = [
platforms: ["linux"],
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.
// 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")) {
whitelist.push({
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")) {
whitelist.push({
sourceName: /webconsole\.css$/i,

View File

@ -1,4 +1,5 @@
const PREF_MULTISELECT_TABS = "browser.tabs.multiselect";
const PREF_DELAY_AUTOPLAY = "media.block-autoplay-until-in-foreground";
const PAGE =
"https://example.com/browser/browser/base/content/test/tabs/file_mediaPlayback.html";
@ -19,7 +20,7 @@ async function addMediaTab() {
add_task(async function setPref() {
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 {
// Only copy exposable URIs
try {
aURI = Services.uriFixup.createExposableURI(aURI);
aURI = Services.io.createExposableURI(aURI);
} catch (ex) {}
}
return aURI;

View File

@ -1028,10 +1028,6 @@ BrowserGlue.prototype = {
os.removeObserver(this, "xpi-signature-changed");
os.removeObserver(this, "sync-ui-state:update");
Services.prefs.removeObserver(
"permissions.eventTelemetry.enabled",
this._togglePermissionPromptTelemetry
);
Services.prefs.removeObserver(
"privacy.trackingprotection",
this._matchCBCategory
@ -1590,24 +1586,6 @@ BrowserGlue.prototype = {
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() {
let recordIdentityPopupEvents = Services.prefs.getBoolPref(
"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(() => {
this._recordContentBlockingTelemetry();
});

View File

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

View File

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

View File

@ -39,7 +39,11 @@ add_task(async function() {
Ci.nsIDragService
);
ds.startDragSession();
ds.startDragSessionForTests(
Ci.nsIDragService.DRAGDROP_ACTION_MOVE |
Ci.nsIDragService.DRAGDROP_ACTION_COPY |
Ci.nsIDragService.DRAGDROP_ACTION_LINK
);
try {
var [result, dataTransfer] = EventUtils.synthesizeDragOver(
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`.
# Example Activity Stream `health` log
## Example Activity Stream `health` log
```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
{
@ -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
{
@ -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
{
@ -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
{
@ -124,7 +124,7 @@ Schema definitions/validations that can be used for tests can be found in `syste
"date": "2016-03-07"
}
```
# Example Activity Stream `impression_stats` Logs
## Example Activity Stream `impression_stats` Logs
```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
{
@ -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
{

View File

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

View File

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

View File

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

View File

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

View File

@ -5,10 +5,6 @@
* Ensure that we can restore old style favicon and principals.
*/
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
// loading immediately and override the icon.
await SpecialPowers.pushPrefEnv({
@ -24,7 +20,7 @@ add_task(async function test_label_and_icon() {
await promiseBrowserLoaded(browser);
let contentPrincipal = browser.contentPrincipal;
let serializedPrincipal = helper.serializeToString(contentPrincipal);
let serializedPrincipal = E10SUtils.serializePrincipal(contentPrincipal);
// Retrieve the tab state.
await TabStateFlusher.flush(browser);

View File

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

View File

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

View File

@ -210,8 +210,8 @@ class UrlbarInput {
this._compositionState = UrlbarUtils.COMPOSITION.NONE;
this._compositionClosedPopup = false;
this.editor.QueryInterface(Ci.nsIPlaintextEditor).newlineHandling =
Ci.nsIPlaintextEditor.eNewlinesStripSurroundingWhitespace;
this.editor.newlineHandling =
Ci.nsIEditor.eNewlinesStripSurroundingWhitespace;
}
/**
@ -328,7 +328,7 @@ class UrlbarInput {
}
try {
return Services.uriFixup.createExposableURI(uri);
return Services.io.createExposableURI(uri);
} catch (ex) {}
return uri;
@ -1567,9 +1567,8 @@ class UrlbarInput {
}
_on_overflow(event) {
const targetIsPlaceholder = !event.originalTarget.classList.contains(
"anonymous-div"
);
const targetIsPlaceholder =
event.originalTarget.implementedPseudoElement == "::placeholder";
// We only care about the non-placeholder text.
// This shouldn't be needed, see bug 1487036.
if (targetIsPlaceholder) {
@ -1580,9 +1579,8 @@ class UrlbarInput {
}
_on_underflow(event) {
const targetIsPlaceholder = !event.originalTarget.classList.contains(
"anonymous-div"
);
const targetIsPlaceholder =
event.originalTarget.implementedPseudoElement == "::placeholder";
// We only care about the non-placeholder text.
// This shouldn't be needed, see bug 1487036.
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
// want UnifiedComplete to reuse results.
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) {
params.push("private-window");
if (!PrivateBrowsingUtils.permanentPrivateBrowsing) {
@ -285,10 +282,7 @@ function makeUrlbarResult(tokens, info) {
if (!title) {
// 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.
title = Services.textToSubURI.unEscapeURIForUI(
"UTF-8",
action.params.url
);
title = Services.textToSubURI.unEscapeURIForUI(action.params.url);
} else if (tokens && tokens.length > 1) {
title = bundle.formatStringFromName(
"bookmarkKeywordSearch",

View File

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

View File

@ -17,7 +17,7 @@ add_task(async function test_ignoreFragment() {
tabRefAboutHome.linkedBrowser,
null,
async function() {
await ContentTaskUtils.waitForEvent(this, "hashchange", false);
await ContentTaskUtils.waitForEvent(this, "hashchange", 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",
"resource://gre/modules/PrivateBrowsingUtils.jsm"
);
ChromeUtils.defineModuleGetter(
this,
"PermissionUITelemetry",
"resource:///modules/PermissionUITelemetry.jsm"
);
XPCOMUtils.defineLazyServiceGetter(
this,
@ -170,17 +165,6 @@ var PermissionPromptPrototype = {
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.
* When this is false, we still provide integration with
@ -445,8 +429,6 @@ var PermissionPromptPrototype = {
return;
}
this._buttonAction = null;
// Transform the PermissionPrompt actions into PopupNotification actions.
let popupNotificationActions = [];
for (let promptAction of this.promptActions) {
@ -489,16 +471,9 @@ var PermissionPromptPrototype = {
}
// Grant permission if action is ALLOW.
// Record buttonAction for telemetry.
if (promptAction.action == SitePermissions.ALLOW) {
this._buttonAction = "accept";
this.allow();
} else {
if (promptAction.scope == SitePermissions.SCOPE_PERSISTENT) {
this._buttonAction = "never";
} else {
this._buttonAction = "deny";
}
this.cancel();
}
} else if (this.permissionKey) {
@ -596,20 +571,6 @@ var PermissionPromptPrototype = {
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) {
options.displayURI = this.principal.URI;
}
@ -641,13 +602,6 @@ var PermissionPromptPrototype = {
// You can remove this restriction if you need it, but be
// mindful of other consumers.
if (topic == "removed" && !postPrompt) {
if (telemetryData) {
PermissionUITelemetry.onRemoved(
telemetryData,
this._buttonAction,
nextRemovalReason
);
}
this.onAfterShow();
}
return false;
@ -670,9 +624,6 @@ var PermissionPromptPrototype = {
secondaryActions,
options
);
if (telemetryData) {
PermissionUITelemetry.onShow(telemetryData);
}
}
},
};
@ -733,10 +684,6 @@ GeolocationPermissionPrompt.prototype = {
return "geo";
},
get permissionTelemetryKey() {
return "geo";
},
get popupOptions() {
let pref = "browser.geolocation.warning.infoURL";
let options = {
@ -836,10 +783,6 @@ DesktopNotificationPermissionPrompt.prototype = {
return "desktop-notification";
},
get permissionTelemetryKey() {
return "notifications";
},
get popupOptions() {
let learnMoreURL =
Services.urlFormatter.formatURLPref("app.support.baseURL") + "push";
@ -1120,7 +1063,7 @@ StorageAccessPermissionPrompt.prototype = {
prettifyHostPort(uri) {
try {
uri = Services.uriFixup.createExposableURI(uri);
uri = Services.io.createExposableURI(uri);
} catch (e) {
// 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) {
progress.step = "principals-quota-manager";
let principals = await new Promise(resolve => {
quotaManagerService.listOrigins(request => {
quotaManagerService.listOrigins().callback = request => {
progress.step = "principals-quota-manager-listOrigins";
if (request.resultCode != Cr.NS_OK) {
// We are probably shutting down. We don't want to propagate the
@ -776,9 +776,9 @@ class PrincipalsCollector {
}
let list = [];
for (let item of request.result) {
for (const origin of request.result) {
let principal = Services.scriptSecurityManager.createCodebasePrincipalFromOrigin(
item.origin
origin
);
let uri = principal.URI;
if (isSupportedURI(uri)) {
@ -788,7 +788,7 @@ class PrincipalsCollector {
progress.step = "principals-quota-manager-completed";
resolve(list);
});
};
}).catch(ex => {
Cu.reportError("QuotaManagerService promise failed: " + ex);
return [];

View File

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

View File

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

View File

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

View File

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

View File

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

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