mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-22 09:45:41 +00:00
Merge mozilla-central to fx-team
This commit is contained in:
commit
b3ea5e55df
@ -122,6 +122,7 @@ devtools/server/actors/**
|
||||
devtools/server/performance/**
|
||||
devtools/server/tests/**
|
||||
devtools/shared/*.js
|
||||
!devtools/shared/async-storage.js
|
||||
!devtools/shared/async-utils.js
|
||||
!devtools/shared/css-lexer.js
|
||||
!devtools/shared/defer.js
|
||||
|
@ -89,6 +89,16 @@ void
|
||||
DocManager::NotifyOfDocumentShutdown(DocAccessible* aDocument,
|
||||
nsIDocument* aDOMDocument)
|
||||
{
|
||||
// We need to remove listeners in both cases, when document is being shutdown
|
||||
// or when accessibility service is being shut down as well.
|
||||
RemoveListeners(aDOMDocument);
|
||||
|
||||
// Document will already be removed when accessibility service is shutting
|
||||
// down so we do not need to remove it twice.
|
||||
if (nsAccessibilityService::IsShutdown()) {
|
||||
return;
|
||||
}
|
||||
|
||||
xpcAccessibleDocument* xpcDoc = mXPCDocumentCache.GetWeak(aDocument);
|
||||
if (xpcDoc) {
|
||||
xpcDoc->Shutdown();
|
||||
@ -96,7 +106,6 @@ DocManager::NotifyOfDocumentShutdown(DocAccessible* aDocument,
|
||||
}
|
||||
|
||||
mDocAccessibleCache.Remove(aDOMDocument);
|
||||
RemoveListeners(aDOMDocument);
|
||||
}
|
||||
|
||||
void
|
||||
@ -530,9 +539,6 @@ DocManager::CreateDocOrRootAccessible(nsIDocument* aDocument)
|
||||
void
|
||||
DocManager::ClearDocCache()
|
||||
{
|
||||
// This unusual do-one-element-per-iterator approach is required because each
|
||||
// DocAccessible is removed elsewhere upon its Shutdown() method being
|
||||
// called, which invalidates the existing iterator.
|
||||
while (mDocAccessibleCache.Count() > 0) {
|
||||
auto iter = mDocAccessibleCache.Iter();
|
||||
MOZ_ASSERT(!iter.Done());
|
||||
@ -542,6 +548,22 @@ DocManager::ClearDocCache()
|
||||
if (docAcc) {
|
||||
docAcc->Shutdown();
|
||||
}
|
||||
|
||||
iter.Remove();
|
||||
}
|
||||
|
||||
// Ensure that all xpcom accessible documents are shut down as well.
|
||||
while (mXPCDocumentCache.Count() > 0) {
|
||||
auto iter = mXPCDocumentCache.Iter();
|
||||
MOZ_ASSERT(!iter.Done());
|
||||
xpcAccessibleDocument* xpcDoc = iter.UserData();
|
||||
NS_ASSERTION(xpcDoc, "No xpc doc for the object in xpc doc cache!");
|
||||
|
||||
if (xpcDoc) {
|
||||
xpcDoc->Shutdown();
|
||||
}
|
||||
|
||||
iter.Remove();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -219,24 +219,6 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime)
|
||||
if (!(mDocument->mDocFlags & DocAccessible::eScrollInitialized))
|
||||
mDocument->AddScrollListener();
|
||||
|
||||
// Process content inserted notifications to update the tree. Process other
|
||||
// notifications like DOM events and then flush event queue. If any new
|
||||
// notifications are queued during this processing then they will be processed
|
||||
// on next refresh. If notification processing queues up new events then they
|
||||
// are processed in this refresh. If events processing queues up new events
|
||||
// then new events are processed on next refresh.
|
||||
// Note: notification processing or event handling may shut down the owning
|
||||
// document accessible.
|
||||
|
||||
// Process only currently queued content inserted notifications.
|
||||
for (auto iter = mContentInsertions.ConstIter(); !iter.Done(); iter.Next()) {
|
||||
mDocument->ProcessContentInserted(iter.Key(), iter.UserData());
|
||||
if (!mDocument) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
mContentInsertions.Clear();
|
||||
|
||||
// Process rendered text change notifications.
|
||||
for (auto iter = mTextHash.Iter(); !iter.Done(); iter.Next()) {
|
||||
nsCOMPtrHashKey<nsIContent>* entry = iter.Get();
|
||||
@ -311,17 +293,27 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime)
|
||||
}
|
||||
#endif
|
||||
|
||||
// Make sure the text node is in accessible document still.
|
||||
Accessible* container = mDocument->AccessibleOrTrueContainer(containerNode);
|
||||
MOZ_ASSERT(container,
|
||||
"Text node having rendered text hasn't accessible document!");
|
||||
if (container) {
|
||||
mDocument->ProcessContentInserted(container, textNode);
|
||||
nsTArray<nsCOMPtr<nsIContent>>* list =
|
||||
mContentInsertions.LookupOrAdd(container);
|
||||
list->AppendElement(textNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
mTextHash.Clear();
|
||||
|
||||
// Process content inserted notifications to update the tree.
|
||||
for (auto iter = mContentInsertions.ConstIter(); !iter.Done(); iter.Next()) {
|
||||
mDocument->ProcessContentInserted(iter.Key(), iter.UserData());
|
||||
if (!mDocument) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
mContentInsertions.Clear();
|
||||
|
||||
// Bind hanging child documents.
|
||||
uint32_t hangingDocCnt = mHangingChildDocuments.Length();
|
||||
nsTArray<RefPtr<DocAccessible>> newChildDocs;
|
||||
|
@ -20,7 +20,6 @@
|
||||
#include "HTMLTableAccessibleWrap.h"
|
||||
#include "HyperTextAccessibleWrap.h"
|
||||
#include "RootAccessible.h"
|
||||
#include "nsAccessiblePivot.h"
|
||||
#include "nsAccUtils.h"
|
||||
#include "nsArrayUtils.h"
|
||||
#include "nsAttrName.h"
|
||||
@ -265,6 +264,7 @@ nsAccessibilityService *nsAccessibilityService::gAccessibilityService = nullptr;
|
||||
ApplicationAccessible* nsAccessibilityService::gApplicationAccessible = nullptr;
|
||||
xpcAccessibleApplication* nsAccessibilityService::gXPCApplicationAccessible = nullptr;
|
||||
bool nsAccessibilityService::gIsShutdown = true;
|
||||
bool nsAccessibilityService::gIsPlatformCaller = false;
|
||||
|
||||
nsAccessibilityService::nsAccessibilityService() :
|
||||
DocManager(), FocusManager(), mMarkupMaps(ArrayLength(sMarkupMapList))
|
||||
@ -340,8 +340,6 @@ nsAccessibilityService::ListenersChanged(nsIArray* aEventChanges)
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED(nsAccessibilityService,
|
||||
DocManager,
|
||||
nsIAccessibilityService,
|
||||
nsIAccessibleRetrieval,
|
||||
nsIObserver,
|
||||
nsIListenerChangeListener,
|
||||
nsISelectionListener) // from SelectionManager
|
||||
@ -359,7 +357,6 @@ nsAccessibilityService::Observe(nsISupports *aSubject, const char *aTopic,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsIAccessibilityService
|
||||
void
|
||||
nsAccessibilityService::NotifyOfAnchorJumpTo(nsIContent* aTargetNode)
|
||||
{
|
||||
@ -371,7 +368,6 @@ nsAccessibilityService::NotifyOfAnchorJumpTo(nsIContent* aTargetNode)
|
||||
}
|
||||
}
|
||||
|
||||
// nsIAccessibilityService
|
||||
void
|
||||
nsAccessibilityService::FireAccessibleEvent(uint32_t aEvent,
|
||||
Accessible* aTarget)
|
||||
@ -379,9 +375,6 @@ nsAccessibilityService::FireAccessibleEvent(uint32_t aEvent,
|
||||
nsEventShell::FireEvent(aEvent, aTarget);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIAccessibilityService
|
||||
|
||||
Accessible*
|
||||
nsAccessibilityService::GetRootDocumentAccessible(nsIPresShell* aPresShell,
|
||||
bool aCanCreate)
|
||||
@ -737,58 +730,26 @@ nsAccessibilityService::RecreateAccessible(nsIPresShell* aPresShell,
|
||||
document->RecreateAccessible(aContent);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIAccessibleRetrieval
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAccessibilityService::GetApplicationAccessible(nsIAccessible** aAccessibleApplication)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aAccessibleApplication);
|
||||
|
||||
NS_IF_ADDREF(*aAccessibleApplication = XPCApplicationAcc());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAccessibilityService::GetAccessibleFor(nsIDOMNode *aNode,
|
||||
nsIAccessible **aAccessible)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aAccessible);
|
||||
*aAccessible = nullptr;
|
||||
if (!aNode)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsINode> node(do_QueryInterface(aNode));
|
||||
if (!node)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
DocAccessible* document = GetDocAccessible(node->OwnerDoc());
|
||||
if (document)
|
||||
NS_IF_ADDREF(*aAccessible = ToXPC(document->GetAccessible(node)));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
void
|
||||
nsAccessibilityService::GetStringRole(uint32_t aRole, nsAString& aString)
|
||||
{
|
||||
#define ROLE(geckoRole, stringRole, atkRole, \
|
||||
macRole, msaaRole, ia2Role, nameRule) \
|
||||
case roles::geckoRole: \
|
||||
CopyUTF8toUTF16(stringRole, aString); \
|
||||
return NS_OK;
|
||||
return;
|
||||
|
||||
switch (aRole) {
|
||||
#include "RoleMap.h"
|
||||
default:
|
||||
aString.AssignLiteral("unknown");
|
||||
return NS_OK;
|
||||
return;
|
||||
}
|
||||
|
||||
#undef ROLE
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
void
|
||||
nsAccessibilityService::GetStringStates(uint32_t aState, uint32_t aExtraState,
|
||||
nsISupports **aStringStates)
|
||||
{
|
||||
@ -797,113 +758,159 @@ nsAccessibilityService::GetStringStates(uint32_t aState, uint32_t aExtraState,
|
||||
uint64_t state = nsAccUtils::To64State(aState, aExtraState);
|
||||
|
||||
// states
|
||||
if (state & states::UNAVAILABLE)
|
||||
if (state & states::UNAVAILABLE) {
|
||||
stringStates->Add(NS_LITERAL_STRING("unavailable"));
|
||||
if (state & states::SELECTED)
|
||||
}
|
||||
if (state & states::SELECTED) {
|
||||
stringStates->Add(NS_LITERAL_STRING("selected"));
|
||||
if (state & states::FOCUSED)
|
||||
}
|
||||
if (state & states::FOCUSED) {
|
||||
stringStates->Add(NS_LITERAL_STRING("focused"));
|
||||
if (state & states::PRESSED)
|
||||
}
|
||||
if (state & states::PRESSED) {
|
||||
stringStates->Add(NS_LITERAL_STRING("pressed"));
|
||||
if (state & states::CHECKED)
|
||||
}
|
||||
if (state & states::CHECKED) {
|
||||
stringStates->Add(NS_LITERAL_STRING("checked"));
|
||||
if (state & states::MIXED)
|
||||
}
|
||||
if (state & states::MIXED) {
|
||||
stringStates->Add(NS_LITERAL_STRING("mixed"));
|
||||
if (state & states::READONLY)
|
||||
}
|
||||
if (state & states::READONLY) {
|
||||
stringStates->Add(NS_LITERAL_STRING("readonly"));
|
||||
if (state & states::HOTTRACKED)
|
||||
}
|
||||
if (state & states::HOTTRACKED) {
|
||||
stringStates->Add(NS_LITERAL_STRING("hottracked"));
|
||||
if (state & states::DEFAULT)
|
||||
}
|
||||
if (state & states::DEFAULT) {
|
||||
stringStates->Add(NS_LITERAL_STRING("default"));
|
||||
if (state & states::EXPANDED)
|
||||
}
|
||||
if (state & states::EXPANDED) {
|
||||
stringStates->Add(NS_LITERAL_STRING("expanded"));
|
||||
if (state & states::COLLAPSED)
|
||||
}
|
||||
if (state & states::COLLAPSED) {
|
||||
stringStates->Add(NS_LITERAL_STRING("collapsed"));
|
||||
if (state & states::BUSY)
|
||||
}
|
||||
if (state & states::BUSY) {
|
||||
stringStates->Add(NS_LITERAL_STRING("busy"));
|
||||
if (state & states::FLOATING)
|
||||
}
|
||||
if (state & states::FLOATING) {
|
||||
stringStates->Add(NS_LITERAL_STRING("floating"));
|
||||
if (state & states::ANIMATED)
|
||||
}
|
||||
if (state & states::ANIMATED) {
|
||||
stringStates->Add(NS_LITERAL_STRING("animated"));
|
||||
if (state & states::INVISIBLE)
|
||||
}
|
||||
if (state & states::INVISIBLE) {
|
||||
stringStates->Add(NS_LITERAL_STRING("invisible"));
|
||||
if (state & states::OFFSCREEN)
|
||||
}
|
||||
if (state & states::OFFSCREEN) {
|
||||
stringStates->Add(NS_LITERAL_STRING("offscreen"));
|
||||
if (state & states::SIZEABLE)
|
||||
}
|
||||
if (state & states::SIZEABLE) {
|
||||
stringStates->Add(NS_LITERAL_STRING("sizeable"));
|
||||
if (state & states::MOVEABLE)
|
||||
}
|
||||
if (state & states::MOVEABLE) {
|
||||
stringStates->Add(NS_LITERAL_STRING("moveable"));
|
||||
if (state & states::SELFVOICING)
|
||||
}
|
||||
if (state & states::SELFVOICING) {
|
||||
stringStates->Add(NS_LITERAL_STRING("selfvoicing"));
|
||||
if (state & states::FOCUSABLE)
|
||||
}
|
||||
if (state & states::FOCUSABLE) {
|
||||
stringStates->Add(NS_LITERAL_STRING("focusable"));
|
||||
if (state & states::SELECTABLE)
|
||||
}
|
||||
if (state & states::SELECTABLE) {
|
||||
stringStates->Add(NS_LITERAL_STRING("selectable"));
|
||||
if (state & states::LINKED)
|
||||
}
|
||||
if (state & states::LINKED) {
|
||||
stringStates->Add(NS_LITERAL_STRING("linked"));
|
||||
if (state & states::TRAVERSED)
|
||||
}
|
||||
if (state & states::TRAVERSED) {
|
||||
stringStates->Add(NS_LITERAL_STRING("traversed"));
|
||||
if (state & states::MULTISELECTABLE)
|
||||
}
|
||||
if (state & states::MULTISELECTABLE) {
|
||||
stringStates->Add(NS_LITERAL_STRING("multiselectable"));
|
||||
if (state & states::EXTSELECTABLE)
|
||||
}
|
||||
if (state & states::EXTSELECTABLE) {
|
||||
stringStates->Add(NS_LITERAL_STRING("extselectable"));
|
||||
if (state & states::PROTECTED)
|
||||
}
|
||||
if (state & states::PROTECTED) {
|
||||
stringStates->Add(NS_LITERAL_STRING("protected"));
|
||||
if (state & states::HASPOPUP)
|
||||
}
|
||||
if (state & states::HASPOPUP) {
|
||||
stringStates->Add(NS_LITERAL_STRING("haspopup"));
|
||||
if (state & states::REQUIRED)
|
||||
}
|
||||
if (state & states::REQUIRED) {
|
||||
stringStates->Add(NS_LITERAL_STRING("required"));
|
||||
if (state & states::ALERT)
|
||||
}
|
||||
if (state & states::ALERT) {
|
||||
stringStates->Add(NS_LITERAL_STRING("alert"));
|
||||
if (state & states::INVALID)
|
||||
}
|
||||
if (state & states::INVALID) {
|
||||
stringStates->Add(NS_LITERAL_STRING("invalid"));
|
||||
if (state & states::CHECKABLE)
|
||||
}
|
||||
if (state & states::CHECKABLE) {
|
||||
stringStates->Add(NS_LITERAL_STRING("checkable"));
|
||||
}
|
||||
|
||||
// extraStates
|
||||
if (state & states::SUPPORTS_AUTOCOMPLETION)
|
||||
if (state & states::SUPPORTS_AUTOCOMPLETION) {
|
||||
stringStates->Add(NS_LITERAL_STRING("autocompletion"));
|
||||
if (state & states::DEFUNCT)
|
||||
}
|
||||
if (state & states::DEFUNCT) {
|
||||
stringStates->Add(NS_LITERAL_STRING("defunct"));
|
||||
if (state & states::SELECTABLE_TEXT)
|
||||
}
|
||||
if (state & states::SELECTABLE_TEXT) {
|
||||
stringStates->Add(NS_LITERAL_STRING("selectable text"));
|
||||
if (state & states::EDITABLE)
|
||||
}
|
||||
if (state & states::EDITABLE) {
|
||||
stringStates->Add(NS_LITERAL_STRING("editable"));
|
||||
if (state & states::ACTIVE)
|
||||
}
|
||||
if (state & states::ACTIVE) {
|
||||
stringStates->Add(NS_LITERAL_STRING("active"));
|
||||
if (state & states::MODAL)
|
||||
}
|
||||
if (state & states::MODAL) {
|
||||
stringStates->Add(NS_LITERAL_STRING("modal"));
|
||||
if (state & states::MULTI_LINE)
|
||||
}
|
||||
if (state & states::MULTI_LINE) {
|
||||
stringStates->Add(NS_LITERAL_STRING("multi line"));
|
||||
if (state & states::HORIZONTAL)
|
||||
}
|
||||
if (state & states::HORIZONTAL) {
|
||||
stringStates->Add(NS_LITERAL_STRING("horizontal"));
|
||||
if (state & states::OPAQUE1)
|
||||
}
|
||||
if (state & states::OPAQUE1) {
|
||||
stringStates->Add(NS_LITERAL_STRING("opaque"));
|
||||
if (state & states::SINGLE_LINE)
|
||||
}
|
||||
if (state & states::SINGLE_LINE) {
|
||||
stringStates->Add(NS_LITERAL_STRING("single line"));
|
||||
if (state & states::TRANSIENT)
|
||||
}
|
||||
if (state & states::TRANSIENT) {
|
||||
stringStates->Add(NS_LITERAL_STRING("transient"));
|
||||
if (state & states::VERTICAL)
|
||||
}
|
||||
if (state & states::VERTICAL) {
|
||||
stringStates->Add(NS_LITERAL_STRING("vertical"));
|
||||
if (state & states::STALE)
|
||||
}
|
||||
if (state & states::STALE) {
|
||||
stringStates->Add(NS_LITERAL_STRING("stale"));
|
||||
if (state & states::ENABLED)
|
||||
}
|
||||
if (state & states::ENABLED) {
|
||||
stringStates->Add(NS_LITERAL_STRING("enabled"));
|
||||
if (state & states::SENSITIVE)
|
||||
}
|
||||
if (state & states::SENSITIVE) {
|
||||
stringStates->Add(NS_LITERAL_STRING("sensitive"));
|
||||
if (state & states::EXPANDABLE)
|
||||
}
|
||||
if (state & states::EXPANDABLE) {
|
||||
stringStates->Add(NS_LITERAL_STRING("expandable"));
|
||||
}
|
||||
|
||||
//unknown states
|
||||
if (!stringStates->Length())
|
||||
if (!stringStates->Length()) {
|
||||
stringStates->Add(NS_LITERAL_STRING("unknown"));
|
||||
}
|
||||
|
||||
stringStates.forget(aStringStates);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsIAccessibleRetrieval::getStringEventType()
|
||||
NS_IMETHODIMP
|
||||
void
|
||||
nsAccessibilityService::GetStringEventType(uint32_t aEventType,
|
||||
nsAString& aString)
|
||||
{
|
||||
@ -912,105 +919,34 @@ nsAccessibilityService::GetStringEventType(uint32_t aEventType,
|
||||
|
||||
if (aEventType >= ArrayLength(kEventTypeNames)) {
|
||||
aString.AssignLiteral("unknown");
|
||||
return NS_OK;
|
||||
return;
|
||||
}
|
||||
|
||||
CopyUTF8toUTF16(kEventTypeNames[aEventType], aString);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsIAccessibleRetrieval::getStringRelationType()
|
||||
NS_IMETHODIMP
|
||||
void
|
||||
nsAccessibilityService::GetStringRelationType(uint32_t aRelationType,
|
||||
nsAString& aString)
|
||||
{
|
||||
NS_ENSURE_ARG(aRelationType <= static_cast<uint32_t>(RelationType::LAST));
|
||||
NS_ENSURE_TRUE_VOID(aRelationType <= static_cast<uint32_t>(RelationType::LAST));
|
||||
|
||||
#define RELATIONTYPE(geckoType, geckoTypeName, atkType, msaaType, ia2Type) \
|
||||
case RelationType::geckoType: \
|
||||
aString.AssignLiteral(geckoTypeName); \
|
||||
return NS_OK;
|
||||
return;
|
||||
|
||||
RelationType relationType = static_cast<RelationType>(aRelationType);
|
||||
switch (relationType) {
|
||||
#include "RelationTypeMap.h"
|
||||
default:
|
||||
aString.AssignLiteral("unknown");
|
||||
return NS_OK;
|
||||
return;
|
||||
}
|
||||
|
||||
#undef RELATIONTYPE
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAccessibilityService::GetAccessibleFromCache(nsIDOMNode* aNode,
|
||||
nsIAccessible** aAccessible)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aAccessible);
|
||||
*aAccessible = nullptr;
|
||||
if (!aNode)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsINode> node(do_QueryInterface(aNode));
|
||||
if (!node)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
// Search for an accessible in each of our per document accessible object
|
||||
// caches. If we don't find it, and the given node is itself a document, check
|
||||
// our cache of document accessibles (document cache). Note usually shutdown
|
||||
// document accessibles are not stored in the document cache, however an
|
||||
// "unofficially" shutdown document (i.e. not from DocManager) can still
|
||||
// exist in the document cache.
|
||||
Accessible* accessible = FindAccessibleInCache(node);
|
||||
if (!accessible) {
|
||||
nsCOMPtr<nsIDocument> document(do_QueryInterface(node));
|
||||
if (document)
|
||||
accessible = GetExistingDocAccessible(document);
|
||||
}
|
||||
|
||||
NS_IF_ADDREF(*aAccessible = ToXPC(accessible));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAccessibilityService::CreateAccessiblePivot(nsIAccessible* aRoot,
|
||||
nsIAccessiblePivot** aPivot)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aPivot);
|
||||
NS_ENSURE_ARG(aRoot);
|
||||
*aPivot = nullptr;
|
||||
|
||||
Accessible* accessibleRoot = aRoot->ToInternalAccessible();
|
||||
NS_ENSURE_TRUE(accessibleRoot, NS_ERROR_INVALID_ARG);
|
||||
|
||||
nsAccessiblePivot* pivot = new nsAccessiblePivot(accessibleRoot);
|
||||
NS_ADDREF(*aPivot = pivot);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAccessibilityService::SetLogging(const nsACString& aModules)
|
||||
{
|
||||
#ifdef A11Y_LOG
|
||||
logging::Enable(PromiseFlatCString(aModules));
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAccessibilityService::IsLogged(const nsAString& aModule, bool* aIsLogged)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aIsLogged);
|
||||
*aIsLogged = false;
|
||||
|
||||
#ifdef A11Y_LOG
|
||||
*aIsLogged = logging::IsEnabled(aModule);
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsAccessibilityService public
|
||||
|
||||
@ -1327,6 +1263,7 @@ nsAccessibilityService::Init()
|
||||
#endif
|
||||
|
||||
gAccessibilityService = this;
|
||||
NS_ADDREF(gAccessibilityService); // will release in Shutdown()
|
||||
|
||||
if (XRE_IsParentProcess())
|
||||
gApplicationAccessible = new ApplicationAccessibleWrap();
|
||||
@ -1359,6 +1296,15 @@ nsAccessibilityService::Init()
|
||||
void
|
||||
nsAccessibilityService::Shutdown()
|
||||
{
|
||||
// Application is going to be closed, shutdown accessibility and mark
|
||||
// accessibility service as shutdown to prevent calls of its methods.
|
||||
// Don't null accessibility service static member at this point to be safe
|
||||
// if someone will try to operate with it.
|
||||
|
||||
MOZ_ASSERT(!gIsShutdown, "Accessibility was shutdown already");
|
||||
|
||||
gIsShutdown = true;
|
||||
|
||||
// Remove observers.
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
mozilla::services::GetObserverService();
|
||||
@ -1384,15 +1330,6 @@ nsAccessibilityService::Shutdown()
|
||||
sPluginTimers = nullptr;
|
||||
#endif
|
||||
|
||||
// Application is going to be closed, shutdown accessibility and mark
|
||||
// accessibility service as shutdown to prevent calls of its methods.
|
||||
// Don't null accessibility service static member at this point to be safe
|
||||
// if someone will try to operate with it.
|
||||
|
||||
NS_ASSERTION(!gIsShutdown, "Accessibility was shutdown already");
|
||||
|
||||
gIsShutdown = true;
|
||||
|
||||
if (XRE_IsParentProcess())
|
||||
PlatformShutdown();
|
||||
|
||||
@ -1402,6 +1339,10 @@ nsAccessibilityService::Shutdown()
|
||||
|
||||
NS_IF_RELEASE(gXPCApplicationAccessible);
|
||||
gXPCApplicationAccessible = nullptr;
|
||||
|
||||
NS_RELEASE(gAccessibilityService);
|
||||
gAccessibilityService = nullptr;
|
||||
gIsPlatformCaller = false;
|
||||
}
|
||||
|
||||
already_AddRefed<Accessible>
|
||||
@ -1756,9 +1697,6 @@ nsAccessibilityService::MarkupAttributes(const nsIContent* aContent,
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIAccessibilityService (DON'T put methods here)
|
||||
|
||||
Accessible*
|
||||
nsAccessibilityService::AddNativeRootAccessible(void* aAtkAccessible)
|
||||
{
|
||||
@ -1802,38 +1740,6 @@ nsAccessibilityService::HasAccessible(nsIDOMNode* aDOMNode)
|
||||
return document->HasAccessible(node);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// NS_GetAccessibilityService
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Return accessibility service; creating one if necessary.
|
||||
*/
|
||||
nsresult
|
||||
NS_GetAccessibilityService(nsIAccessibilityService** aResult)
|
||||
{
|
||||
NS_ENSURE_TRUE(aResult, NS_ERROR_NULL_POINTER);
|
||||
*aResult = nullptr;
|
||||
|
||||
if (nsAccessibilityService::gAccessibilityService) {
|
||||
NS_ADDREF(*aResult = nsAccessibilityService::gAccessibilityService);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
RefPtr<nsAccessibilityService> service = new nsAccessibilityService();
|
||||
NS_ENSURE_TRUE(service, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
if (!service->Init()) {
|
||||
service->Shutdown();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
statistics::A11yInitialized();
|
||||
|
||||
NS_ADDREF(*aResult = service);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsAccessibilityService private (DON'T put methods here)
|
||||
|
||||
@ -1869,6 +1775,38 @@ nsAccessibilityService::CreateAccessibleForXULTree(nsIContent* aContent,
|
||||
}
|
||||
#endif
|
||||
|
||||
nsAccessibilityService*
|
||||
GetOrCreateAccService(bool aIsPlatformCaller)
|
||||
{
|
||||
if (aIsPlatformCaller) {
|
||||
nsAccessibilityService::gIsPlatformCaller = aIsPlatformCaller;
|
||||
}
|
||||
|
||||
if (!nsAccessibilityService::gAccessibilityService) {
|
||||
RefPtr<nsAccessibilityService> service = new nsAccessibilityService();
|
||||
if (!service->Init()) {
|
||||
service->Shutdown();
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_ASSERT(nsAccessibilityService::gAccessibilityService,
|
||||
"Accessible service is not initialized.");
|
||||
return nsAccessibilityService::gAccessibilityService;
|
||||
}
|
||||
|
||||
bool
|
||||
CanShutdownAccService()
|
||||
{
|
||||
nsAccessibilityService* accService = nsAccessibilityService::gAccessibilityService;
|
||||
if (!accService) {
|
||||
return false;
|
||||
}
|
||||
return !xpcAccessibilityService::IsInUse() &&
|
||||
!accService->IsPlatformCaller() && !accService->IsShutdown() &&
|
||||
!nsCoreUtils::AccEventObserversExist();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Services
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -6,8 +6,6 @@
|
||||
#ifndef __nsAccessibilityService_h__
|
||||
#define __nsAccessibilityService_h__
|
||||
|
||||
#include "nsIAccessibilityService.h"
|
||||
|
||||
#include "mozilla/a11y/DocManager.h"
|
||||
#include "mozilla/a11y/FocusManager.h"
|
||||
#include "mozilla/a11y/Role.h"
|
||||
@ -15,7 +13,9 @@
|
||||
#include "mozilla/Preferences.h"
|
||||
|
||||
#include "nsIObserver.h"
|
||||
#include "nsIAccessibleEvent.h"
|
||||
#include "nsIEventListenerService.h"
|
||||
#include "xpcAccessibilityService.h"
|
||||
|
||||
class nsImageFrame;
|
||||
class nsIArray;
|
||||
@ -68,7 +68,6 @@ struct MarkupMapInfo {
|
||||
class nsAccessibilityService final : public mozilla::a11y::DocManager,
|
||||
public mozilla::a11y::FocusManager,
|
||||
public mozilla::a11y::SelectionManager,
|
||||
public nsIAccessibilityService,
|
||||
public nsIListenerChangeListener,
|
||||
public nsIObserver
|
||||
{
|
||||
@ -80,16 +79,14 @@ public:
|
||||
NS_IMETHOD ListenersChanged(nsIArray* aEventChanges) override;
|
||||
|
||||
protected:
|
||||
virtual ~nsAccessibilityService();
|
||||
~nsAccessibilityService();
|
||||
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIACCESSIBLERETRIEVAL
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
// nsIAccessibilityService
|
||||
virtual Accessible* GetRootDocumentAccessible(nsIPresShell* aPresShell,
|
||||
bool aCanCreate) override;
|
||||
Accessible* GetRootDocumentAccessible(nsIPresShell* aPresShell,
|
||||
bool aCanCreate);
|
||||
already_AddRefed<Accessible>
|
||||
CreatePluginAccessible(nsPluginFrame* aFrame, nsIContent* aContent,
|
||||
Accessible* aContext);
|
||||
@ -98,10 +95,31 @@ public:
|
||||
* Adds/remove ATK root accessible for gtk+ native window to/from children
|
||||
* of the application accessible.
|
||||
*/
|
||||
virtual Accessible* AddNativeRootAccessible(void* aAtkAccessible) override;
|
||||
virtual void RemoveNativeRootAccessible(Accessible* aRootAccessible) override;
|
||||
Accessible* AddNativeRootAccessible(void* aAtkAccessible);
|
||||
void RemoveNativeRootAccessible(Accessible* aRootAccessible);
|
||||
|
||||
virtual bool HasAccessible(nsIDOMNode* aDOMNode) override;
|
||||
bool HasAccessible(nsIDOMNode* aDOMNode);
|
||||
|
||||
/**
|
||||
* Get a string equivalent for an accessilbe role value.
|
||||
*/
|
||||
void GetStringRole(uint32_t aRole, nsAString& aString);
|
||||
|
||||
/**
|
||||
* Get a string equivalent for an accessible state/extra state.
|
||||
*/
|
||||
void GetStringStates(uint32_t aState, uint32_t aExtraState,
|
||||
nsISupports **aStringStates);
|
||||
|
||||
/**
|
||||
* Get a string equivalent for an accessible event value.
|
||||
*/
|
||||
void GetStringEventType(uint32_t aEventType, nsAString& aString);
|
||||
|
||||
/**
|
||||
* Get a string equivalent for an accessible relation type.
|
||||
*/
|
||||
void GetStringRelationType(uint32_t aRelationType, nsAString& aString);
|
||||
|
||||
// nsAccesibilityService
|
||||
/**
|
||||
@ -123,7 +141,7 @@ public:
|
||||
*/
|
||||
void ContentRemoved(nsIPresShell* aPresShell, nsIContent* aChild);
|
||||
|
||||
virtual void UpdateText(nsIPresShell* aPresShell, nsIContent* aContent);
|
||||
void UpdateText(nsIPresShell* aPresShell, nsIContent* aContent);
|
||||
|
||||
/**
|
||||
* Update XUL:tree accessible tree when treeview is changed.
|
||||
@ -139,7 +157,7 @@ public:
|
||||
/**
|
||||
* Update list bullet accessible.
|
||||
*/
|
||||
virtual void UpdateListBullet(nsIPresShell* aPresShell,
|
||||
void UpdateListBullet(nsIPresShell* aPresShell,
|
||||
nsIContent* aHTMLListItemContent,
|
||||
bool aHasBullet);
|
||||
|
||||
@ -163,14 +181,14 @@ public:
|
||||
/**
|
||||
* Notify that presshell is activated.
|
||||
*/
|
||||
virtual void PresShellActivated(nsIPresShell* aPresShell);
|
||||
void PresShellActivated(nsIPresShell* aPresShell);
|
||||
|
||||
/**
|
||||
* Recreate an accessible for the given content node in the presshell.
|
||||
*/
|
||||
void RecreateAccessible(nsIPresShell* aPresShell, nsIContent* aContent);
|
||||
|
||||
virtual void FireAccessibleEvent(uint32_t aEvent, Accessible* aTarget) override;
|
||||
void FireAccessibleEvent(uint32_t aEvent, Accessible* aTarget);
|
||||
|
||||
// nsAccessibiltiyService
|
||||
|
||||
@ -179,6 +197,11 @@ public:
|
||||
*/
|
||||
static bool IsShutdown() { return gIsShutdown; }
|
||||
|
||||
/**
|
||||
* Return true if accessibility service has been initialized by platform.
|
||||
*/
|
||||
static bool IsPlatformCaller() { return gIsPlatformCaller; };
|
||||
|
||||
/**
|
||||
* Creates an accessible for the given DOM node.
|
||||
*
|
||||
@ -205,7 +228,7 @@ public:
|
||||
|
||||
private:
|
||||
// nsAccessibilityService creation is controlled by friend
|
||||
// NS_GetAccessibilityService, keep constructors private.
|
||||
// GetOrCreateAccService, keep constructors private.
|
||||
nsAccessibilityService();
|
||||
nsAccessibilityService(const nsAccessibilityService&);
|
||||
nsAccessibilityService& operator =(const nsAccessibilityService&);
|
||||
@ -258,15 +281,21 @@ private:
|
||||
*/
|
||||
static bool gIsShutdown;
|
||||
|
||||
/**
|
||||
* Indicates whether accessibility service was initialized by platform.
|
||||
*/
|
||||
static bool gIsPlatformCaller;
|
||||
|
||||
nsDataHashtable<nsPtrHashKey<const nsIAtom>, const mozilla::a11y::MarkupMapInfo*> mMarkupMaps;
|
||||
|
||||
friend nsAccessibilityService* GetAccService();
|
||||
friend nsAccessibilityService* GetOrCreateAccService(bool);
|
||||
friend bool CanShutdownAccService();
|
||||
friend mozilla::a11y::FocusManager* mozilla::a11y::FocusMgr();
|
||||
friend mozilla::a11y::SelectionManager* mozilla::a11y::SelectionMgr();
|
||||
friend mozilla::a11y::ApplicationAccessible* mozilla::a11y::ApplicationAcc();
|
||||
friend mozilla::a11y::xpcAccessibleApplication* mozilla::a11y::XPCApplicationAcc();
|
||||
|
||||
friend nsresult NS_GetAccessibilityService(nsIAccessibilityService** aResult);
|
||||
friend class xpcAccessibilityService;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -278,6 +307,16 @@ GetAccService()
|
||||
return nsAccessibilityService::gAccessibilityService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return accessibility service instance; creating one if necessary.
|
||||
*/
|
||||
nsAccessibilityService* GetOrCreateAccService(bool aIsPlatformCaller = true);
|
||||
|
||||
/**
|
||||
* Return a flag indicating if accessibility service can be shutdown.
|
||||
*/
|
||||
bool CanShutdownAccService();
|
||||
|
||||
/**
|
||||
* Return true if we're in a content process and not B2G.
|
||||
*/
|
||||
@ -294,7 +333,7 @@ IPCAccessibilityActive()
|
||||
|
||||
/**
|
||||
* Map nsIAccessibleEvents constants to strings. Used by
|
||||
* nsIAccessibleRetrieval::getStringEventType() method.
|
||||
* nsAccessibilityService::GetStringEventType() method.
|
||||
*/
|
||||
static const char kEventTypeNames[][40] = {
|
||||
"unknown", //
|
||||
@ -387,5 +426,4 @@ static const char kEventTypeNames[][40] = {
|
||||
"text value change", // EVENT_TEXT_VALUE_CHANGE
|
||||
};
|
||||
|
||||
#endif /* __nsIAccessibilityService_h__ */
|
||||
|
||||
#endif
|
||||
|
@ -8,6 +8,7 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows' and CONFIG['COMPILE_ENVIRONMENT']:
|
||||
DIRS += ['msaa', 'ia2']
|
||||
|
||||
XPIDL_SOURCES += [
|
||||
'nsIAccessibilityService.idl',
|
||||
'nsIAccessible.idl',
|
||||
'nsIAccessibleApplication.idl',
|
||||
'nsIAccessibleCaretMoveEvent.idl',
|
||||
@ -21,7 +22,6 @@ XPIDL_SOURCES += [
|
||||
'nsIAccessibleObjectAttributeChangedEvent.idl',
|
||||
'nsIAccessiblePivot.idl',
|
||||
'nsIAccessibleRelation.idl',
|
||||
'nsIAccessibleRetrieval.idl',
|
||||
'nsIAccessibleRole.idl',
|
||||
'nsIAccessibleSelectable.idl',
|
||||
'nsIAccessibleStateChangeEvent.idl',
|
||||
@ -38,8 +38,3 @@ XPIDL_SOURCES += [
|
||||
]
|
||||
|
||||
XPIDL_MODULE = 'accessibility'
|
||||
|
||||
EXPORTS += [
|
||||
'nsIAccessibilityService.h',
|
||||
]
|
||||
|
||||
|
@ -1,79 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef _nsIAccessibilityService_h_
|
||||
#define _nsIAccessibilityService_h_
|
||||
|
||||
#include "nsIAccessibleRetrieval.h"
|
||||
#include "nsIAccessibleEvent.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
class Accessible;
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
class nsIPresShell;
|
||||
|
||||
// 0e7e6879-854b-4260-bc6e-525b5fb5cf34
|
||||
#define NS_IACCESSIBILITYSERVICE_IID \
|
||||
{ 0x0e7e6879, 0x854b, 0x4260, \
|
||||
{ 0xbc, 0x6e, 0x52, 0x5b, 0x5f, 0xb5, 0xcf, 0x34 } }
|
||||
|
||||
class nsIAccessibilityService : public nsIAccessibleRetrieval
|
||||
{
|
||||
public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IACCESSIBILITYSERVICE_IID)
|
||||
|
||||
/**
|
||||
* Return root document accessible that is or contains a document accessible
|
||||
* for the given presshell.
|
||||
*
|
||||
* @param aPresShell [in] the presshell
|
||||
* @param aCanCreate [in] points whether the root document accessible
|
||||
* should be returned from the cache or can be created
|
||||
*/
|
||||
virtual mozilla::a11y::Accessible*
|
||||
GetRootDocumentAccessible(nsIPresShell* aPresShell, bool aCanCreate) = 0;
|
||||
|
||||
/**
|
||||
* Adds/remove ATK root accessible for gtk+ native window to/from children
|
||||
* of the application accessible.
|
||||
*/
|
||||
virtual mozilla::a11y::Accessible*
|
||||
AddNativeRootAccessible(void* aAtkAccessible) = 0;
|
||||
virtual void
|
||||
RemoveNativeRootAccessible(mozilla::a11y::Accessible* aRootAccessible) = 0;
|
||||
|
||||
/**
|
||||
* Fire accessible event of the given type for the given target.
|
||||
*
|
||||
* @param aEvent [in] accessible event type
|
||||
* @param aTarget [in] target of accessible event
|
||||
*/
|
||||
virtual void FireAccessibleEvent(uint32_t aEvent,
|
||||
mozilla::a11y::Accessible* aTarget) = 0;
|
||||
|
||||
/**
|
||||
* Return true if the given DOM node has accessible object.
|
||||
*/
|
||||
virtual bool HasAccessible(nsIDOMNode* aDOMNode) = 0;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIAccessibilityService,
|
||||
NS_IACCESSIBILITYSERVICE_IID)
|
||||
|
||||
// for component registration
|
||||
// {DE401C37-9A7F-4278-A6F8-3DE2833989EF}
|
||||
#define NS_ACCESSIBILITY_SERVICE_CID \
|
||||
{ 0xde401c37, 0x9a7f, 0x4278, { 0xa6, 0xf8, 0x3d, 0xe2, 0x83, 0x39, 0x89, 0xef } }
|
||||
|
||||
extern nsresult
|
||||
NS_GetAccessibilityService(nsIAccessibilityService** aResult);
|
||||
|
||||
#endif
|
@ -16,8 +16,8 @@ interface nsIAccessiblePivot;
|
||||
* nsIAccessible for a given DOM node. More documentation at:
|
||||
* http://www.mozilla.org/projects/ui/accessibility
|
||||
*/
|
||||
[scriptable, builtinclass, uuid(17f86615-1a3d-4021-b227-3a2ef5cbffd8)]
|
||||
interface nsIAccessibleRetrieval : nsISupports
|
||||
[scriptable, builtinclass, uuid(9a6f80fe-25cc-405c-9f8f-25869bc9f94e)]
|
||||
interface nsIAccessibilityService : nsISupports
|
||||
{
|
||||
/**
|
||||
* Return application accessible.
|
||||
@ -99,12 +99,10 @@ interface nsIAccessibleRetrieval : nsISupports
|
||||
boolean isLogged(in AString aModule);
|
||||
};
|
||||
|
||||
|
||||
%{ C++
|
||||
|
||||
// for component registration
|
||||
// {663CA4A8-D219-4000-925D-D8F66406B626}
|
||||
#define NS_ACCESSIBLE_RETRIEVAL_CID \
|
||||
{ 0x663ca4a8, 0xd219, 0x4000, { 0x92, 0x5d, 0xd8, 0xf6, 0x64, 0x6, 0xb6, 0x26 } }
|
||||
|
||||
%}
|
||||
/**
|
||||
* @deprecated, use nsIAccessibilityService instead.
|
||||
*/
|
||||
[scriptable, builtinclass, uuid(d85e0cbe-47ce-490c-8488-f821dd2be0c2)]
|
||||
interface nsIAccessibleRetrieval : nsIAccessibilityService
|
||||
{
|
||||
};
|
@ -6,6 +6,7 @@
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'nsAccessibleRelation.cpp',
|
||||
'xpcAccessibilityService.cpp',
|
||||
'xpcAccessible.cpp',
|
||||
'xpcAccessibleApplication.cpp',
|
||||
'xpcAccessibleDocument.cpp',
|
||||
@ -26,6 +27,7 @@ SOURCES += [
|
||||
|
||||
EXPORTS += [
|
||||
'!xpcAccEvents.h',
|
||||
'xpcAccessibilityService.h',
|
||||
]
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
|
249
accessible/xpcom/xpcAccessibilityService.cpp
Normal file
249
accessible/xpcom/xpcAccessibilityService.cpp
Normal file
@ -0,0 +1,249 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "xpcAccessibilityService.h"
|
||||
|
||||
#include "nsAccessiblePivot.h"
|
||||
#include "nsAccessibilityService.h"
|
||||
|
||||
#ifdef A11Y_LOG
|
||||
#include "Logging.h"
|
||||
#endif
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::a11y;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
xpcAccessibilityService *xpcAccessibilityService::gXPCAccessibilityService = nullptr;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsISupports
|
||||
|
||||
void
|
||||
xpcAccessibilityService::ShutdownCallback(nsITimer* aTimer, void* aClosure)
|
||||
{
|
||||
if (CanShutdownAccService()) {
|
||||
GetAccService()->Shutdown();
|
||||
}
|
||||
|
||||
xpcAccessibilityService* xpcAccService =
|
||||
reinterpret_cast<xpcAccessibilityService*>(aClosure);
|
||||
|
||||
if (xpcAccService->mShutdownTimer) {
|
||||
xpcAccService->mShutdownTimer->Cancel();
|
||||
xpcAccService->mShutdownTimer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(MozExternalRefCountType)
|
||||
xpcAccessibilityService::AddRef(void)
|
||||
{
|
||||
MOZ_ASSERT_TYPE_OK_FOR_REFCOUNTING(xpcAccessibilityService)
|
||||
MOZ_ASSERT(int32_t(mRefCnt) >= 0, "illegal refcnt");
|
||||
if (!mRefCnt.isThreadSafe)
|
||||
NS_ASSERT_OWNINGTHREAD(xpcAccessibilityService);
|
||||
nsrefcnt count = ++mRefCnt;
|
||||
NS_LOG_ADDREF(this, count, "xpcAccessibilityService", sizeof(*this));
|
||||
|
||||
if (mRefCnt > 1) {
|
||||
GetOrCreateAccService(false);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(MozExternalRefCountType)
|
||||
xpcAccessibilityService::Release(void)
|
||||
{
|
||||
MOZ_ASSERT(int32_t(mRefCnt) > 0, "dup release");
|
||||
|
||||
if (!mRefCnt.isThreadSafe) {
|
||||
NS_ASSERT_OWNINGTHREAD(xpcAccessibilityService);
|
||||
}
|
||||
|
||||
nsrefcnt count = --mRefCnt;
|
||||
NS_LOG_RELEASE(this, count, "xpcAccessibilityService");
|
||||
|
||||
if (count == 0) {
|
||||
if (!mRefCnt.isThreadSafe) {
|
||||
NS_ASSERT_OWNINGTHREAD(xpcAccessibilityService);
|
||||
}
|
||||
|
||||
mRefCnt = 1; /* stabilize */
|
||||
delete (this);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// When ref count goes down to 1 (held internally as a static reference),
|
||||
// it means that there are no more external references to the
|
||||
// xpcAccessibilityService and we can attempt to shut down acceessiblity
|
||||
// service.
|
||||
if (count == 1 && !mShutdownTimer) {
|
||||
mShutdownTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
|
||||
if (mShutdownTimer) {
|
||||
mShutdownTimer->InitWithFuncCallback(ShutdownCallback, this, 100,
|
||||
nsITimer::TYPE_ONE_SHOT);
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
NS_IMPL_QUERY_INTERFACE(xpcAccessibilityService, nsIAccessibilityService,
|
||||
nsIAccessibleRetrieval)
|
||||
|
||||
NS_IMETHODIMP
|
||||
xpcAccessibilityService::GetApplicationAccessible(nsIAccessible** aAccessibleApplication)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aAccessibleApplication);
|
||||
|
||||
NS_IF_ADDREF(*aAccessibleApplication = XPCApplicationAcc());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
xpcAccessibilityService::GetAccessibleFor(nsIDOMNode *aNode,
|
||||
nsIAccessible **aAccessible)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aAccessible);
|
||||
*aAccessible = nullptr;
|
||||
if (!aNode) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsINode> node(do_QueryInterface(aNode));
|
||||
if (!node) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
DocAccessible* document = GetAccService()->GetDocAccessible(node->OwnerDoc());
|
||||
if (document) {
|
||||
NS_IF_ADDREF(*aAccessible = ToXPC(document->GetAccessible(node)));
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
xpcAccessibilityService::GetStringRole(uint32_t aRole, nsAString& aString)
|
||||
{
|
||||
GetAccService()->GetStringRole(aRole, aString);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
xpcAccessibilityService::GetStringStates(uint32_t aState, uint32_t aExtraState,
|
||||
nsISupports **aStringStates)
|
||||
{
|
||||
GetAccService()->GetStringStates(aState, aExtraState, aStringStates);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
xpcAccessibilityService::GetStringEventType(uint32_t aEventType,
|
||||
nsAString& aString)
|
||||
{
|
||||
GetAccService()->GetStringEventType(aEventType, aString);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
xpcAccessibilityService::GetStringRelationType(uint32_t aRelationType,
|
||||
nsAString& aString)
|
||||
{
|
||||
GetAccService()->GetStringRelationType(aRelationType, aString);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
xpcAccessibilityService::GetAccessibleFromCache(nsIDOMNode* aNode,
|
||||
nsIAccessible** aAccessible)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aAccessible);
|
||||
*aAccessible = nullptr;
|
||||
if (!aNode) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsINode> node(do_QueryInterface(aNode));
|
||||
if (!node) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
// Search for an accessible in each of our per document accessible object
|
||||
// caches. If we don't find it, and the given node is itself a document, check
|
||||
// our cache of document accessibles (document cache). Note usually shutdown
|
||||
// document accessibles are not stored in the document cache, however an
|
||||
// "unofficially" shutdown document (i.e. not from DocManager) can still
|
||||
// exist in the document cache.
|
||||
Accessible* accessible = GetAccService()->FindAccessibleInCache(node);
|
||||
if (!accessible) {
|
||||
nsCOMPtr<nsIDocument> document(do_QueryInterface(node));
|
||||
if (document) {
|
||||
accessible = mozilla::a11y::GetExistingDocAccessible(document);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IF_ADDREF(*aAccessible = ToXPC(accessible));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
xpcAccessibilityService::CreateAccessiblePivot(nsIAccessible* aRoot,
|
||||
nsIAccessiblePivot** aPivot)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aPivot);
|
||||
NS_ENSURE_ARG(aRoot);
|
||||
*aPivot = nullptr;
|
||||
|
||||
Accessible* accessibleRoot = aRoot->ToInternalAccessible();
|
||||
NS_ENSURE_TRUE(accessibleRoot, NS_ERROR_INVALID_ARG);
|
||||
|
||||
nsAccessiblePivot* pivot = new nsAccessiblePivot(accessibleRoot);
|
||||
NS_ADDREF(*aPivot = pivot);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
xpcAccessibilityService::SetLogging(const nsACString& aModules)
|
||||
{
|
||||
#ifdef A11Y_LOG
|
||||
logging::Enable(PromiseFlatCString(aModules));
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
xpcAccessibilityService::IsLogged(const nsAString& aModule, bool* aIsLogged)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aIsLogged);
|
||||
*aIsLogged = false;
|
||||
|
||||
#ifdef A11Y_LOG
|
||||
*aIsLogged = logging::IsEnabled(aModule);
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// NS_GetAccessibilityService
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsresult
|
||||
NS_GetAccessibilityService(nsIAccessibilityService** aResult)
|
||||
{
|
||||
NS_ENSURE_TRUE(aResult, NS_ERROR_NULL_POINTER);
|
||||
*aResult = nullptr;
|
||||
|
||||
GetOrCreateAccService(false);
|
||||
|
||||
xpcAccessibilityService* service = new xpcAccessibilityService();
|
||||
NS_ENSURE_TRUE(service, NS_ERROR_OUT_OF_MEMORY);
|
||||
xpcAccessibilityService::gXPCAccessibilityService = service;
|
||||
NS_ADDREF(*aResult = service);
|
||||
|
||||
return NS_OK;
|
||||
}
|
66
accessible/xpcom/xpcAccessibilityService.h
Normal file
66
accessible/xpcom/xpcAccessibilityService.h
Normal file
@ -0,0 +1,66 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_a11y_xpcAccessibilityService_h_
|
||||
#define mozilla_a11y_xpcAccessibilityService_h_
|
||||
|
||||
#include "nsIAccessibilityService.h"
|
||||
|
||||
class xpcAccessibilityService : public nsIAccessibleRetrieval
|
||||
{
|
||||
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIACCESSIBILITYSERVICE
|
||||
NS_DECL_NSIACCESSIBLERETRIEVAL
|
||||
|
||||
/**
|
||||
* Return true if xpc accessibility service is in use.
|
||||
*/
|
||||
static bool IsInUse() {
|
||||
// When ref count goes down to 1 (held internally as a static reference),
|
||||
// it means that there are no more external references and thus it is not in
|
||||
// use.
|
||||
return gXPCAccessibilityService ? gXPCAccessibilityService->mRefCnt > 1 : false;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~xpcAccessibilityService() {
|
||||
if (mShutdownTimer) {
|
||||
mShutdownTimer->Cancel();
|
||||
mShutdownTimer = nullptr;
|
||||
}
|
||||
gXPCAccessibilityService = nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
// xpcAccessibilityService creation is controlled by friend
|
||||
// NS_GetAccessibilityService, keep constructor private.
|
||||
xpcAccessibilityService() { };
|
||||
|
||||
nsCOMPtr<nsITimer> mShutdownTimer;
|
||||
|
||||
/**
|
||||
* Reference for xpc accessibility service instance.
|
||||
*/
|
||||
static xpcAccessibilityService* gXPCAccessibilityService;
|
||||
|
||||
/**
|
||||
* Used to shutdown nsAccessibilityService if xpcom accessible service is not
|
||||
* in use any more.
|
||||
*/
|
||||
static void ShutdownCallback(nsITimer* aTimer, void* aClosure);
|
||||
|
||||
friend nsresult NS_GetAccessibilityService(nsIAccessibilityService** aResult);
|
||||
};
|
||||
|
||||
// for component registration
|
||||
// {3b265b69-f813-48ff-880d-d88d101af404}
|
||||
#define NS_ACCESSIBILITY_SERVICE_CID \
|
||||
{ 0x3b265b69, 0xf813, 0x48ff, { 0x88, 0x0d, 0xd8, 0x8d, 0x10, 0x1a, 0xf4, 0x04 } }
|
||||
|
||||
extern nsresult
|
||||
NS_GetAccessibilityService(nsIAccessibilityService** aResult);
|
||||
|
||||
#endif
|
@ -26,6 +26,7 @@ support-files =
|
||||
[browser_newtab_disable.js]
|
||||
[browser_newtab_drag_drop.js]
|
||||
[browser_newtab_drag_drop_ext.js]
|
||||
subsuite = clipboard # temporary until determine why more intermittent on VM
|
||||
[browser_newtab_drop_preview.js]
|
||||
[browser_newtab_enhanced.js]
|
||||
[browser_newtab_focus.js]
|
||||
|
@ -24,3 +24,4 @@ tags = openwindow
|
||||
[browser_broadcastchannel.js]
|
||||
[browser_blobUrl.js]
|
||||
[browser_middleClick.js]
|
||||
[browser_imageCache.js]
|
||||
|
@ -15,7 +15,6 @@ let css = Cc["@mozilla.org/netwerk/cache-storage-service;1"]
|
||||
const USER_CONTEXTS = [
|
||||
"default",
|
||||
"personal",
|
||||
"work",
|
||||
];
|
||||
const TEST_HOST = "example.com";
|
||||
const TEST_URL = "http://" + TEST_HOST + "/browser/browser/components/contextualidentity/test/browser/";
|
||||
@ -133,7 +132,7 @@ function* test_cookie_cleared() {
|
||||
let tabs = [];
|
||||
|
||||
for (let userContextId of Object.keys(USER_CONTEXTS)) {
|
||||
// Load the page in 3 different contexts and set a cookie
|
||||
// Load the page in 2 different contexts and set a cookie
|
||||
// which should only be visible in that context.
|
||||
let value = USER_CONTEXTS[userContextId];
|
||||
|
||||
@ -212,8 +211,10 @@ function* test_image_cache_cleared() {
|
||||
yield BrowserTestUtils.removeTab(tabs[userContextId].tab);
|
||||
}
|
||||
|
||||
let expectedHits = USER_CONTEXTS.length;
|
||||
|
||||
// Check that image cache works with the userContextId.
|
||||
todo_is(gHits, 3, "The image should be loaded three times. This test should be enabled after the bug 1270680 landed");
|
||||
is(gHits, expectedHits, "The image should be loaded" + expectedHits + "times.");
|
||||
|
||||
// Reset the cache count.
|
||||
gHits = 0;
|
||||
@ -229,14 +230,14 @@ function* test_image_cache_cleared() {
|
||||
yield BrowserTestUtils.removeTab(tabs[userContextId].tab);
|
||||
}
|
||||
|
||||
// Check that image cache was cleared and the server gets another three hits.
|
||||
todo_is(gHits, 3, "The image should be loaded three times. This test should be enabled after the bug 1270680 landed");
|
||||
// Check that image cache was cleared and the server gets another two hits.
|
||||
is(gHits, expectedHits, "The image should be loaded" + expectedHits + "times.");
|
||||
}
|
||||
|
||||
// Offline Storage
|
||||
function* test_storage_cleared() {
|
||||
for (let userContextId of Object.keys(USER_CONTEXTS)) {
|
||||
// Load the page in 3 different contexts and set the local storage
|
||||
// Load the page in 2 different contexts and set the local storage
|
||||
// which should only be visible in that context.
|
||||
let value = USER_CONTEXTS[userContextId];
|
||||
|
||||
|
@ -0,0 +1,59 @@
|
||||
let Cu = Components.utils;
|
||||
let {HttpServer} = Cu.import("resource://testing-common/httpd.js", {});
|
||||
|
||||
const NUM_USER_CONTEXTS = 3;
|
||||
|
||||
let gHits = 0;
|
||||
|
||||
let server = new HttpServer();
|
||||
server.registerPathHandler('/image.png', imageHandler);
|
||||
server.registerPathHandler('/file.html', fileHandler);
|
||||
server.start(-1);
|
||||
|
||||
let BASE_URI = 'http://localhost:' + server.identity.primaryPort;
|
||||
let IMAGE_URI = BASE_URI + '/image.png';
|
||||
let FILE_URI = BASE_URI + '/file.html';
|
||||
|
||||
function imageHandler(metadata, response) {
|
||||
gHits++;
|
||||
response.setHeader("Cache-Control", "max-age=10000", false);
|
||||
response.setStatusLine(metadata.httpVersion, 200, "OK");
|
||||
response.setHeader("Content-Type", "image/png", false);
|
||||
var body = "iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAIAAADZSiLoAAAAEUlEQVQImWP4z8AAQTAamQkAhpcI+DeMzFcAAAAASUVORK5CYII=";
|
||||
response.bodyOutputStream.write(body, body.length);
|
||||
}
|
||||
|
||||
function fileHandler(metadata, response) {
|
||||
response.setStatusLine(metadata.httpVersion, 200, "OK");
|
||||
response.setHeader("Content-Type", "text/html", false);
|
||||
let body = `<html><body><image src=${IMAGE_URI}></body></html>`;
|
||||
response.bodyOutputStream.write(body, body.length);
|
||||
}
|
||||
|
||||
add_task(function* setup() {
|
||||
// make sure userContext is enabled.
|
||||
yield SpecialPowers.pushPrefEnv({"set": [["privacy.userContext.enabled", true]]});
|
||||
});
|
||||
|
||||
// opens `uri' in a new tab with the provided userContextId and focuses it.
|
||||
// returns the newly opened tab
|
||||
function* openTabInUserContext(uri, userContextId) {
|
||||
// open the tab in the correct userContextId
|
||||
let tab = gBrowser.addTab(uri, {userContextId});
|
||||
|
||||
// select tab and make sure its browser is focused
|
||||
gBrowser.selectedTab = tab;
|
||||
tab.ownerDocument.defaultView.focus();
|
||||
|
||||
let browser = gBrowser.getBrowserForTab(tab);
|
||||
yield BrowserTestUtils.browserLoaded(browser);
|
||||
return tab;
|
||||
}
|
||||
|
||||
add_task(function* test() {
|
||||
for (let userContextId = 0; userContextId < NUM_USER_CONTEXTS; userContextId++) {
|
||||
let tab = yield* openTabInUserContext(FILE_URI, userContextId);
|
||||
gBrowser.removeTab(tab);
|
||||
}
|
||||
is(gHits, NUM_USER_CONTEXTS, "should get an image request for each user contexts");
|
||||
});
|
@ -216,14 +216,18 @@ class BasePopup {
|
||||
// Resizes the browser to match the preferred size of the content (debounced).
|
||||
resizeBrowser() {
|
||||
if (this.resizeTimeout == null) {
|
||||
this.resizeTimeout = this.window.setTimeout(() => {
|
||||
try {
|
||||
this._resizeBrowser();
|
||||
this.resizeTimeout = this.window.setTimeout(this._resizeBrowser.bind(this), RESIZE_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
_resizeBrowser() {
|
||||
} finally {
|
||||
this.resizeTimeout = null;
|
||||
}
|
||||
}, RESIZE_TIMEOUT);
|
||||
this._resizeBrowser(false);
|
||||
}
|
||||
}
|
||||
|
||||
_resizeBrowser(clearTimeout = true) {
|
||||
if (!this.browser) {
|
||||
return;
|
||||
}
|
||||
|
@ -42,6 +42,7 @@
|
||||
{
|
||||
"namespace": "browserAction",
|
||||
"description": "Use browser actions to put icons in the main browser toolbar, to the right of the address bar. In addition to its icon, a browser action can also have a tooltip, a badge, and a popup.",
|
||||
"permissions": ["manifest:browser_action"],
|
||||
"types": [
|
||||
{
|
||||
"id": "ColorArray",
|
||||
|
@ -42,6 +42,7 @@
|
||||
{
|
||||
"namespace": "pageAction",
|
||||
"description": "Use the <code>browser.pageAction</code> API to put icons inside the address bar. Page actions represent actions that can be taken on the current page, but that aren't applicable to all pages.",
|
||||
"permissions": ["manifest:page_action"],
|
||||
"types": [
|
||||
{
|
||||
"id": "ImageDataType",
|
||||
|
@ -3,20 +3,6 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
[
|
||||
{
|
||||
"namespace": "manifest",
|
||||
"types": [
|
||||
{
|
||||
"$extend": "Permission",
|
||||
"choices": [{
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"windows"
|
||||
]
|
||||
}]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"namespace": "windows",
|
||||
"description": "Use the <code>browser.windows</code> API to interact with browser windows. You can use this API to create, modify, and rearrange windows in the browser.",
|
||||
|
@ -21,11 +21,6 @@ add_task(function* tabsSendMessageReply() {
|
||||
if (msg == "content-script-ready") {
|
||||
let tabId = sender.tab.id;
|
||||
|
||||
browser.tabs.sendMessage(tabId, "respond-never", response => {
|
||||
browser.test.fail(`Got unexpected response callback: ${response}`);
|
||||
browser.test.notifyFail("sendMessage");
|
||||
});
|
||||
|
||||
Promise.all([
|
||||
promiseResponse,
|
||||
|
||||
@ -34,12 +29,15 @@ add_task(function* tabsSendMessageReply() {
|
||||
new Promise(resolve => browser.tabs.sendMessage(tabId, "respond-soon", resolve)),
|
||||
browser.tabs.sendMessage(tabId, "respond-promise"),
|
||||
browser.tabs.sendMessage(tabId, "respond-never"),
|
||||
new Promise(resolve => {
|
||||
browser.runtime.sendMessage("respond-never", response => { resolve(response); });
|
||||
}),
|
||||
|
||||
browser.tabs.sendMessage(tabId, "respond-error").catch(error => Promise.resolve({error})),
|
||||
browser.tabs.sendMessage(tabId, "throw-error").catch(error => Promise.resolve({error})),
|
||||
|
||||
browser.tabs.sendMessage(firstTab, "no-listener").catch(error => Promise.resolve({error})),
|
||||
]).then(([response, respondNow, respondNow2, respondSoon, respondPromise, respondNever, respondError, throwError, noListener]) => {
|
||||
]).then(([response, respondNow, respondNow2, respondSoon, respondPromise, respondNever, respondNever2, respondError, throwError, noListener]) => {
|
||||
browser.test.assertEq("expected-response", response, "Content script got the expected response");
|
||||
|
||||
browser.test.assertEq("respond-now", respondNow, "Got the expected immediate response");
|
||||
@ -47,6 +45,7 @@ add_task(function* tabsSendMessageReply() {
|
||||
browser.test.assertEq("respond-soon", respondSoon, "Got the expected delayed response");
|
||||
browser.test.assertEq("respond-promise", respondPromise, "Got the expected promise response");
|
||||
browser.test.assertEq(undefined, respondNever, "Got the expected no-response resolution");
|
||||
browser.test.assertEq(undefined, respondNever2, "Got the expected no-response resolution");
|
||||
|
||||
browser.test.assertEq("respond-error", respondError.error.message, "Got the expected error response");
|
||||
browser.test.assertEq("throw-error", throwError.error.message, "Got the expected thrown error response");
|
||||
|
@ -0,0 +1,57 @@
|
||||
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set sts=2 sw=2 et tw=80: */
|
||||
"use strict";
|
||||
|
||||
/* globals chrome */
|
||||
|
||||
function* testPermission(options) {
|
||||
function background(options) {
|
||||
browser.test.sendMessage("typeof-namespace", {
|
||||
browser: typeof browser[options.namespace],
|
||||
chrome: typeof chrome[options.namespace],
|
||||
});
|
||||
}
|
||||
|
||||
let extensionDetails = {
|
||||
background: `(${background})(${JSON.stringify(options)})`,
|
||||
};
|
||||
|
||||
let extension = ExtensionTestUtils.loadExtension(extensionDetails);
|
||||
|
||||
yield extension.startup();
|
||||
|
||||
let types = yield extension.awaitMessage("typeof-namespace");
|
||||
equal(types.browser, "undefined", `Type of browser.${options.namespace} without manifest entry`);
|
||||
equal(types.chrome, "undefined", `Type of chrome.${options.namespace} without manifest entry`);
|
||||
|
||||
yield extension.unload();
|
||||
|
||||
extensionDetails.manifest = options.manifest;
|
||||
extension = ExtensionTestUtils.loadExtension(extensionDetails);
|
||||
|
||||
yield extension.startup();
|
||||
|
||||
types = yield extension.awaitMessage("typeof-namespace");
|
||||
equal(types.browser, "object", `Type of browser.${options.namespace} with manifest entry`);
|
||||
equal(types.chrome, "object", `Type of chrome.${options.namespace} with manifest entry`);
|
||||
|
||||
yield extension.unload();
|
||||
}
|
||||
|
||||
add_task(function* test_browserAction() {
|
||||
yield testPermission({
|
||||
namespace: "browserAction",
|
||||
manifest: {
|
||||
browser_action: {},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
add_task(function* test_pageAction() {
|
||||
yield testPermission({
|
||||
namespace: "pageAction",
|
||||
manifest: {
|
||||
page_action: {},
|
||||
},
|
||||
});
|
||||
});
|
@ -6,3 +6,4 @@ firefox-appdir = browser
|
||||
[test_ext_bookmarks.js]
|
||||
[test_ext_history.js]
|
||||
[test_ext_manifest_commands.js]
|
||||
[test_ext_manifest_permissions.js]
|
||||
|
@ -1703,12 +1703,12 @@ toolbarbutton.chevron > .toolbarbutton-icon {
|
||||
|
||||
#ctrlTab-panel {
|
||||
-moz-appearance: none;
|
||||
background: rgba(27%,27%,27%,.7);
|
||||
background: hsla(0,0%,33%,.85);
|
||||
color: white;
|
||||
border-style: none;
|
||||
padding: 20px 10px 10px;
|
||||
font-weight: bold;
|
||||
text-shadow: 0 0 1px rgb(27%,27%,27%), 0 0 2px rgb(27%,27%,27%);
|
||||
text-shadow: 0 0 1px hsl(0,0%,12%), 0 0 2px hsl(0,0%,12%);
|
||||
}
|
||||
|
||||
.ctrlTab-favicon[src] {
|
||||
|
@ -1,46 +0,0 @@
|
||||
<?xml version="1.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/. -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 16 16">
|
||||
<style>
|
||||
use:not(:target) {
|
||||
display: none;
|
||||
}
|
||||
use {
|
||||
fill: menutext;
|
||||
}
|
||||
use[id$="-active"] {
|
||||
fill: -moz-menuhovertext;
|
||||
}
|
||||
use[id$="-disabled"] {
|
||||
fill: graytext;
|
||||
}
|
||||
</style>
|
||||
<defs>
|
||||
<path id="back-shape" fill-rule="evenodd" d="M1.192,8.893L2.21,9.964c0.064,0.065,0.136,0.117,0.214,0.159 l5.199,5.301c0.607,0.63,1.465,0.764,1.915,0.297l1.02-1.082c0.449-0.467,0.32-1.357-0.288-1.99l-2.116-2.158h5.705 c0.671,0,1.215-0.544,1.215-1.215v-2.43c0-0.671-0.544-1.215-1.215-1.215H8.094l2.271-2.309c0.609-0.626,0.737-1.512,0.288-1.974 L9.635,0.278C9.184-0.188,8.327-0.055,7.718,0.575L2.479,5.901C2.38,5.946,2.289,6.008,2.21,6.089L1.192,7.171 c-0.21,0.219-0.293,0.53-0.26,0.864C0.899,8.367,0.981,8.676,1.192,8.893z"/>
|
||||
<path id="forward-shape" fill-rule="evenodd" d="M14.808,7.107L13.79,6.036c-0.064-0.065-0.136-0.117-0.214-0.159 L8.377,0.576C7.77-0.054,6.912-0.189,6.461,0.278L5.441,1.36c-0.449,0.467-0.32,1.357,0.288,1.99l2.116,2.158H2.14 c-0.671,0-1.215,0.544-1.215,1.215v2.43c0,0.671,0.544,1.215,1.215,1.215h5.765l-2.271,2.309c-0.609,0.626-0.737,1.512-0.288,1.974 l1.019,1.072c0.451,0.465,1.308,0.332,1.917-0.297l5.238-5.326c0.1-0.045,0.191-0.107,0.269-0.188l1.019-1.082 c0.21-0.219,0.293-0.53,0.26-0.864C15.101,7.633,15.019,7.324,14.808,7.107z"/>
|
||||
<path id="reload-shape" fill-rule="evenodd" d="M15.429,8h-8l3.207-3.207C9.889,4.265,8.986,3.947,8,3.947 c-2.554,0-4.625,2.071-4.625,4.625S5.446,13.196,8,13.196c1.638,0,3.069-0.857,3.891-2.141l2.576,1.104 C13.199,14.439,10.794,16,8,16c-4.103,0-7.429-3.326-7.429-7.429S3.897,1.143,8,1.143c1.762,0,3.366,0.624,4.631,1.654L15.429,0V8z"/>
|
||||
<polygon id="stop-shape" points="16,2.748 13.338,0.079 8.038,5.391 2.661,0 0,2.669 5.377,8.059 0.157,13.292 2.819,15.961 8.039,10.728 13.298,16 15.959,13.331 10.701,8.06"/>
|
||||
<path id="bookmark-shape" d="M8.008,3.632l0.986,2.012l0.452,0.922l1.014,0.169l2.326,0.389l-1.719,1.799l-0.676,0.708l0.145,0.967 L10.896,13l-1.959-1.039l-0.937-0.497l-0.937,0.497l-1.957,1.038L5.468,10.6l0.146-0.968L4.937,8.924L3.219,7.126l2.351-0.39 l1.023-0.17l0.45-0.934L8.008,3.632 M8,0C7.72,0,7.44,0.217,7.228,0.65L5.242,4.766L0.907,5.485c-0.958,0.159-1.195,0.861-0.53,1.56 l3.113,3.258l-0.69,4.583c-0.105,0.689,0.172,1.092,0.658,1.092c0.185,0,0.399-0.058,0.635-0.181l3.906-2.072l3.906,2.072 c0.236,0.123,0.45,0.181,0.635,0.181c0.486,0,0.762-0.403,0.659-1.092l-0.687-4.583l3.109-3.255c0.666-0.702,0.428-1.404-0.53-1.564 l-4.303-0.719L8.772,0.65C8.56,0.217,8.28,0,8,0L8,0z"/>
|
||||
<path id="bookmarked-shape" d="M8,0C7.719,0,7.438,0.217,7.225,0.651L5.233,4.773l-4.35,0.72c-0.961,0.159-1.199,0.862-0.531,1.562 l3.124,3.262l-0.692,4.589C2.679,15.596,2.957,16,3.444,16c0.185,0,0.401-0.058,0.637-0.181L8,13.744l3.919,2.075 C12.156,15.942,12.372,16,12.557,16c0.487,0,0.764-0.404,0.661-1.094l-0.69-4.589l3.12-3.259c0.668-0.703,0.43-1.406-0.532-1.566 l-4.317-0.72L8.775,0.651C8.562,0.217,8.281,0,8,0L8,0z"/>
|
||||
</defs>
|
||||
<use id="back" xlink:href="#back-shape"/>
|
||||
<use id="back-active" xlink:href="#back-shape"/>
|
||||
<use id="back-disabled" xlink:href="#back-shape"/>
|
||||
<use id="forward" xlink:href="#forward-shape"/>
|
||||
<use id="forward-active" xlink:href="#forward-shape"/>
|
||||
<use id="forward-disabled" xlink:href="#forward-shape"/>
|
||||
<use id="reload" xlink:href="#reload-shape"/>
|
||||
<use id="reload-active" xlink:href="#reload-shape"/>
|
||||
<use id="reload-disabled" xlink:href="#reload-shape"/>
|
||||
<use id="stop" xlink:href="#stop-shape"/>
|
||||
<use id="stop-active" xlink:href="#stop-shape"/>
|
||||
<use id="stop-disabled" xlink:href="#stop-shape"/>
|
||||
<use id="bookmark" xlink:href="#bookmark-shape"/>
|
||||
<use id="bookmark-active" xlink:href="#bookmark-shape"/>
|
||||
<use id="bookmark-disabled" xlink:href="#bookmark-shape"/>
|
||||
<use id="bookmarked" xlink:href="#bookmarked-shape"/>
|
||||
<use id="bookmarked-active" xlink:href="#bookmarked-shape"/>
|
||||
<use id="bookmarked-disabled" xlink:href="#bookmarked-shape"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 4.2 KiB |
@ -5,7 +5,7 @@
|
||||
%include ../../shared/customizableui/panelUI.inc.css
|
||||
|
||||
.panel-subviews {
|
||||
background-color: -moz-dialog;
|
||||
background-color: var(--panel-arrowcontent-background);
|
||||
}
|
||||
|
||||
#BMB_bookmarksPopup > menuitem[type="checkbox"] {
|
||||
|
@ -15,7 +15,6 @@ browser.jar:
|
||||
* skin/classic/browser/devedition.css
|
||||
* skin/classic/browser/browser-lightweightTheme.css
|
||||
skin/classic/browser/click-to-play-warning-stripes.png
|
||||
skin/classic/browser/content-contextmenu.svg
|
||||
skin/classic/browser/Info.png
|
||||
skin/classic/browser/menuPanel.png
|
||||
skin/classic/browser/menuPanel@2x.png
|
||||
|
@ -3116,11 +3116,11 @@ menulist.translate-infobar-element > .menulist-dropmarker {
|
||||
#ctrlTab-panel {
|
||||
-moz-appearance: none;
|
||||
-moz-window-shadow: none;
|
||||
background: rgba(27%,27%,27%,.7);
|
||||
background: hsla(0,0%,33%,.85);
|
||||
color: white;
|
||||
border-style: none;
|
||||
padding: 20px 10px 10px;
|
||||
text-shadow: 0 0 1px rgb(27%,27%,27%), 0 0 2px rgb(27%,27%,27%);
|
||||
text-shadow: 0 0 1px hsl(0,0%,12%), 0 0 2px hsl(0,0%,12%);
|
||||
}
|
||||
|
||||
.ctrlTab-favicon[src] {
|
||||
|
@ -1,46 +0,0 @@
|
||||
<?xml version="1.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/. -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 16 16">
|
||||
<style>
|
||||
use:not(:target) {
|
||||
display: none;
|
||||
}
|
||||
use {
|
||||
fill: menutext;
|
||||
}
|
||||
use[id$="-active"] {
|
||||
fill: -moz-mac-menutextselect;
|
||||
}
|
||||
use[id$="-disabled"] {
|
||||
fill: -moz-mac-menutextdisable;
|
||||
}
|
||||
</style>
|
||||
<defs>
|
||||
<path id="back-shape" fill-rule="evenodd" d="M1.192,8.893L2.21,9.964c0.064,0.065,0.136,0.117,0.214,0.159 l5.199,5.301c0.607,0.63,1.465,0.764,1.915,0.297l1.02-1.082c0.449-0.467,0.32-1.357-0.288-1.99l-2.116-2.158h5.705 c0.671,0,1.215-0.544,1.215-1.215v-2.43c0-0.671-0.544-1.215-1.215-1.215H8.094l2.271-2.309c0.609-0.626,0.737-1.512,0.288-1.974 L9.635,0.278C9.184-0.188,8.327-0.055,7.718,0.575L2.479,5.901C2.38,5.946,2.289,6.008,2.21,6.089L1.192,7.171 c-0.21,0.219-0.293,0.53-0.26,0.864C0.899,8.367,0.981,8.676,1.192,8.893z"/>
|
||||
<path id="forward-shape" fill-rule="evenodd" d="M14.808,7.107L13.79,6.036c-0.064-0.065-0.136-0.117-0.214-0.159 L8.377,0.576C7.77-0.054,6.912-0.189,6.461,0.278L5.441,1.36c-0.449,0.467-0.32,1.357,0.288,1.99l2.116,2.158H2.14 c-0.671,0-1.215,0.544-1.215,1.215v2.43c0,0.671,0.544,1.215,1.215,1.215h5.765l-2.271,2.309c-0.609,0.626-0.737,1.512-0.288,1.974 l1.019,1.072c0.451,0.465,1.308,0.332,1.917-0.297l5.238-5.326c0.1-0.045,0.191-0.107,0.269-0.188l1.019-1.082 c0.21-0.219,0.293-0.53,0.26-0.864C15.101,7.633,15.019,7.324,14.808,7.107z"/>
|
||||
<path id="reload-shape" fill-rule="evenodd" d="M15.429,8h-8l3.207-3.207C9.889,4.265,8.986,3.947,8,3.947 c-2.554,0-4.625,2.071-4.625,4.625S5.446,13.196,8,13.196c1.638,0,3.069-0.857,3.891-2.141l2.576,1.104 C13.199,14.439,10.794,16,8,16c-4.103,0-7.429-3.326-7.429-7.429S3.897,1.143,8,1.143c1.762,0,3.366,0.624,4.631,1.654L15.429,0V8z"/>
|
||||
<polygon id="stop-shape" points="16,2.748 13.338,0.079 8.038,5.391 2.661,0 0,2.669 5.377,8.059 0.157,13.292 2.819,15.961 8.039,10.728 13.298,16 15.959,13.331 10.701,8.06"/>
|
||||
<path id="bookmark-shape" d="M8.008,3.632l0.986,2.012l0.452,0.922l1.014,0.169l2.326,0.389l-1.719,1.799l-0.676,0.708l0.145,0.967 L10.896,13l-1.959-1.039l-0.937-0.497l-0.937,0.497l-1.957,1.038L5.468,10.6l0.146-0.968L4.937,8.924L3.219,7.126l2.351-0.39 l1.023-0.17l0.45-0.934L8.008,3.632 M8,0C7.72,0,7.44,0.217,7.228,0.65L5.242,4.766L0.907,5.485c-0.958,0.159-1.195,0.861-0.53,1.56 l3.113,3.258l-0.69,4.583c-0.105,0.689,0.172,1.092,0.658,1.092c0.185,0,0.399-0.058,0.635-0.181l3.906-2.072l3.906,2.072 c0.236,0.123,0.45,0.181,0.635,0.181c0.486,0,0.762-0.403,0.659-1.092l-0.687-4.583l3.109-3.255c0.666-0.702,0.428-1.404-0.53-1.564 l-4.303-0.719L8.772,0.65C8.56,0.217,8.28,0,8,0L8,0z"/>
|
||||
<path id="bookmarked-shape" d="M8,0C7.719,0,7.438,0.217,7.225,0.651L5.233,4.773l-4.35,0.72c-0.961,0.159-1.199,0.862-0.531,1.562 l3.124,3.262l-0.692,4.589C2.679,15.596,2.957,16,3.444,16c0.185,0,0.401-0.058,0.637-0.181L8,13.744l3.919,2.075 C12.156,15.942,12.372,16,12.557,16c0.487,0,0.764-0.404,0.661-1.094l-0.69-4.589l3.12-3.259c0.668-0.703,0.43-1.406-0.532-1.566 l-4.317-0.72L8.775,0.651C8.562,0.217,8.281,0,8,0L8,0z"/>
|
||||
</defs>
|
||||
<use id="back" xlink:href="#back-shape"/>
|
||||
<use id="back-active" xlink:href="#back-shape"/>
|
||||
<use id="back-disabled" xlink:href="#back-shape"/>
|
||||
<use id="forward" xlink:href="#forward-shape"/>
|
||||
<use id="forward-active" xlink:href="#forward-shape"/>
|
||||
<use id="forward-disabled" xlink:href="#forward-shape"/>
|
||||
<use id="reload" xlink:href="#reload-shape"/>
|
||||
<use id="reload-active" xlink:href="#reload-shape"/>
|
||||
<use id="reload-disabled" xlink:href="#reload-shape"/>
|
||||
<use id="stop" xlink:href="#stop-shape"/>
|
||||
<use id="stop-active" xlink:href="#stop-shape"/>
|
||||
<use id="stop-disabled" xlink:href="#stop-shape"/>
|
||||
<use id="bookmark" xlink:href="#bookmark-shape"/>
|
||||
<use id="bookmark-active" xlink:href="#bookmark-shape"/>
|
||||
<use id="bookmark-disabled" xlink:href="#bookmark-shape"/>
|
||||
<use id="bookmarked" xlink:href="#bookmarked-shape"/>
|
||||
<use id="bookmarked-active" xlink:href="#bookmarked-shape"/>
|
||||
<use id="bookmarked-disabled" xlink:href="#bookmarked-shape"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 4.2 KiB |
@ -15,7 +15,6 @@ browser.jar:
|
||||
* skin/classic/browser/devedition.css
|
||||
* skin/classic/browser/browser-lightweightTheme.css
|
||||
skin/classic/browser/click-to-play-warning-stripes.png
|
||||
skin/classic/browser/content-contextmenu.svg
|
||||
skin/classic/browser/Info.png
|
||||
skin/classic/browser/keyhole-circle.png
|
||||
skin/classic/browser/keyhole-circle@2x.png
|
||||
|
18
browser/themes/shared/content-contextmenu.svg
Normal file
18
browser/themes/shared/content-contextmenu.svg
Normal file
@ -0,0 +1,18 @@
|
||||
<?xml version="1.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/. -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||
<style>
|
||||
path:not(:target),
|
||||
polygon:not(:target) {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
<path id="back" fill-rule="evenodd" d="M1.192,8.893L2.21,9.964c0.064,0.065,0.136,0.117,0.214,0.159 l5.199,5.301c0.607,0.63,1.465,0.764,1.915,0.297l1.02-1.082c0.449-0.467,0.32-1.357-0.288-1.99l-2.116-2.158h5.705 c0.671,0,1.215-0.544,1.215-1.215v-2.43c0-0.671-0.544-1.215-1.215-1.215H8.094l2.271-2.309c0.609-0.626,0.737-1.512,0.288-1.974 L9.635,0.278C9.184-0.188,8.327-0.055,7.718,0.575L2.479,5.901C2.38,5.946,2.289,6.008,2.21,6.089L1.192,7.171 c-0.21,0.219-0.293,0.53-0.26,0.864C0.899,8.367,0.981,8.676,1.192,8.893z"/>
|
||||
<path id="forward" fill-rule="evenodd" d="M14.808,7.107L13.79,6.036c-0.064-0.065-0.136-0.117-0.214-0.159 L8.377,0.576C7.77-0.054,6.912-0.189,6.461,0.278L5.441,1.36c-0.449,0.467-0.32,1.357,0.288,1.99l2.116,2.158H2.14 c-0.671,0-1.215,0.544-1.215,1.215v2.43c0,0.671,0.544,1.215,1.215,1.215h5.765l-2.271,2.309c-0.609,0.626-0.737,1.512-0.288,1.974 l1.019,1.072c0.451,0.465,1.308,0.332,1.917-0.297l5.238-5.326c0.1-0.045,0.191-0.107,0.269-0.188l1.019-1.082 c0.21-0.219,0.293-0.53,0.26-0.864C15.101,7.633,15.019,7.324,14.808,7.107z"/>
|
||||
<path id="reload" fill-rule="evenodd" d="M15.429,8h-8l3.207-3.207C9.889,4.265,8.986,3.947,8,3.947 c-2.554,0-4.625,2.071-4.625,4.625S5.446,13.196,8,13.196c1.638,0,3.069-0.857,3.891-2.141l2.576,1.104 C13.199,14.439,10.794,16,8,16c-4.103,0-7.429-3.326-7.429-7.429S3.897,1.143,8,1.143c1.762,0,3.366,0.624,4.631,1.654L15.429,0V8z"/>
|
||||
<polygon id="stop" points="16,2.748 13.338,0.079 8.038,5.391 2.661,0 0,2.669 5.377,8.059 0.157,13.292 2.819,15.961 8.039,10.728 13.298,16 15.959,13.331 10.701,8.06"/>
|
||||
<path id="bookmark" d="M8.008,3.632l0.986,2.012l0.452,0.922l1.014,0.169l2.326,0.389l-1.719,1.799l-0.676,0.708l0.145,0.967 L10.896,13l-1.959-1.039l-0.937-0.497l-0.937,0.497l-1.957,1.038L5.468,10.6l0.146-0.968L4.937,8.924L3.219,7.126l2.351-0.39 l1.023-0.17l0.45-0.934L8.008,3.632 M8,0C7.72,0,7.44,0.217,7.228,0.65L5.242,4.766L0.907,5.485c-0.958,0.159-1.195,0.861-0.53,1.56 l3.113,3.258l-0.69,4.583c-0.105,0.689,0.172,1.092,0.658,1.092c0.185,0,0.399-0.058,0.635-0.181l3.906-2.072l3.906,2.072 c0.236,0.123,0.45,0.181,0.635,0.181c0.486,0,0.762-0.403,0.659-1.092l-0.687-4.583l3.109-3.255c0.666-0.702,0.428-1.404-0.53-1.564 l-4.303-0.719L8.772,0.65C8.56,0.217,8.28,0,8,0L8,0z"/>
|
||||
<path id="bookmarked" d="M8,0C7.719,0,7.438,0.217,7.225,0.651L5.233,4.773l-4.35,0.72c-0.961,0.159-1.199,0.862-0.531,1.562 l3.124,3.262l-0.692,4.589C2.679,15.596,2.957,16,3.444,16c0.185,0,0.401-0.058,0.637-0.181L8,13.744l3.919,2.075 C12.156,15.942,12.372,16,12.557,16c0.487,0,0.764-0.404,0.661-1.094l-0.69-4.589l3.12-3.259c0.668-0.703,0.43-1.406-0.532-1.566 l-4.317-0.72L8.775,0.651C8.562,0.217,8.281,0,8,0L8,0z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 3.0 KiB |
@ -8,90 +8,44 @@
|
||||
-moz-appearance: none;
|
||||
}
|
||||
|
||||
#context-navigation > .menuitem-iconic > .menu-iconic-left > .menu-iconic-icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin: 7px;
|
||||
filter: url(chrome://browser/skin/filters.svg#fill);
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
#context-back {
|
||||
list-style-image: url("chrome://browser/skin/content-contextmenu.svg#back");
|
||||
}
|
||||
|
||||
#context-back[_moz-menuactive=true] {
|
||||
list-style-image: url("chrome://browser/skin/content-contextmenu.svg#back-active");
|
||||
}
|
||||
|
||||
#context-back[disabled=true] {
|
||||
list-style-image: url("chrome://browser/skin/content-contextmenu.svg#back-disabled");
|
||||
}
|
||||
|
||||
#context-forward {
|
||||
list-style-image: url("chrome://browser/skin/content-contextmenu.svg#forward");
|
||||
}
|
||||
|
||||
#context-forward[_moz-menuactive=true] {
|
||||
list-style-image: url("chrome://browser/skin/content-contextmenu.svg#forward-active");
|
||||
}
|
||||
|
||||
#context-forward[disabled=true] {
|
||||
list-style-image: url("chrome://browser/skin/content-contextmenu.svg#forward-disabled");
|
||||
}
|
||||
|
||||
#context-reload {
|
||||
list-style-image: url("chrome://browser/skin/content-contextmenu.svg#reload");
|
||||
}
|
||||
|
||||
#context-reload[_moz-menuactive=true] {
|
||||
list-style-image: url("chrome://browser/skin/content-contextmenu.svg#reload-active");
|
||||
}
|
||||
|
||||
#context-reload[disabled=true] {
|
||||
list-style-image: url("chrome://browser/skin/content-contextmenu.svg#reload-disabled");
|
||||
}
|
||||
|
||||
#context-stop {
|
||||
list-style-image: url("chrome://browser/skin/content-contextmenu.svg#stop");
|
||||
}
|
||||
|
||||
#context-stop[_moz-menuactive=true] {
|
||||
list-style-image: url("chrome://browser/skin/content-contextmenu.svg#stop-active");
|
||||
}
|
||||
|
||||
#context-stop[disabled=true] {
|
||||
list-style-image: url("chrome://browser/skin/content-contextmenu.svg#stop-disabled");
|
||||
}
|
||||
|
||||
#context-bookmarkpage {
|
||||
list-style-image: url("chrome://browser/skin/content-contextmenu.svg#bookmark");
|
||||
}
|
||||
|
||||
#context-bookmarkpage[_moz-menuactive=true] {
|
||||
list-style-image: url("chrome://browser/skin/content-contextmenu.svg#bookmark-active");
|
||||
}
|
||||
|
||||
#context-bookmarkpage[disabled=true] {
|
||||
list-style-image: url("chrome://browser/skin/content-contextmenu.svg#bookmark-disabled");
|
||||
}
|
||||
|
||||
#context-bookmarkpage[starred=true] {
|
||||
list-style-image: url("chrome://browser/skin/content-contextmenu.svg#bookmarked");
|
||||
}
|
||||
|
||||
#context-bookmarkpage[starred=true][_moz-menuactive=true] {
|
||||
list-style-image: url("chrome://browser/skin/content-contextmenu.svg#bookmarked-active");
|
||||
}
|
||||
|
||||
#context-bookmarkpage[starred=true][disabled=true] {
|
||||
list-style-image: url("chrome://browser/skin/content-contextmenu.svg#bookmarked-disabled");
|
||||
}
|
||||
|
||||
#context-back:-moz-locale-dir(rtl),
|
||||
#context-forward:-moz-locale-dir(rtl),
|
||||
#context-reload:-moz-locale-dir(rtl) {
|
||||
transform: scaleX(-1);
|
||||
}
|
||||
|
||||
#context-navigation > .menuitem-iconic > .menu-iconic-left > .menu-iconic-icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin: 7px;
|
||||
}
|
||||
|
||||
#context-media-eme-learnmore {
|
||||
list-style-image: url("chrome://browser/skin/drm-icon.svg#chains");
|
||||
}
|
||||
|
@ -52,7 +52,7 @@
|
||||
.downloadsPanelFooterButton {
|
||||
-moz-appearance: none;
|
||||
background-color: transparent;
|
||||
color: black;
|
||||
color: inherit;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
min-height: 40px;
|
||||
|
@ -15,6 +15,7 @@
|
||||
skin/classic/browser/aboutSocialError.css (../shared/aboutSocialError.css)
|
||||
skin/classic/browser/aboutTabCrashed.css (../shared/aboutTabCrashed.css)
|
||||
skin/classic/browser/aboutWelcomeBack.css (../shared/aboutWelcomeBack.css)
|
||||
skin/classic/browser/content-contextmenu.svg (../shared/content-contextmenu.svg)
|
||||
skin/classic/browser/addons/addon-install-blocked.svg (../shared/addons/addon-install-blocked.svg)
|
||||
skin/classic/browser/addons/addon-install-confirm.svg (../shared/addons/addon-install-confirm.svg)
|
||||
skin/classic/browser/addons/addon-install-downloading.svg (../shared/addons/addon-install-downloading.svg)
|
||||
|
@ -332,13 +332,6 @@
|
||||
color: white;
|
||||
}
|
||||
|
||||
@media (-moz-os-version: windows-vista),
|
||||
(-moz-os-version: windows-win7),{
|
||||
#toolbar-menubar:not(:-moz-lwtheme) {
|
||||
text-shadow: 0 0 .5em white, 0 0 .5em white, 0 1px 0 rgba(255,255,255,.4);
|
||||
}
|
||||
}
|
||||
|
||||
/* Show borders on vista through win8, but not on win10 and later: */
|
||||
@media (-moz-os-version: windows-vista),
|
||||
(-moz-os-version: windows-win7),
|
||||
@ -376,15 +369,26 @@
|
||||
#appcontent:not(:-moz-lwtheme) {
|
||||
background-color: -moz-dialog;
|
||||
}
|
||||
}
|
||||
|
||||
@media (-moz-windows-glass) {
|
||||
#main-window[sizemode=normal] #nav-bar {
|
||||
border-top-left-radius: 2.5px;
|
||||
border-top-right-radius: 2.5px;
|
||||
}
|
||||
|
||||
#main-window[sizemode=fullscreen]:not(:-moz-lwtheme) {
|
||||
-moz-appearance: none;
|
||||
background-color: #556;
|
||||
}
|
||||
|
||||
#toolbar-menubar:not(:-moz-lwtheme) {
|
||||
text-shadow: 0 0 .5em white, 0 0 .5em white, 0 1px 0 rgba(255,255,255,.4);
|
||||
}
|
||||
|
||||
#main-menubar:not(:-moz-lwtheme):not(:-moz-window-inactive) {
|
||||
background-color: rgba(255,255,255,.5);
|
||||
color: black;
|
||||
}
|
||||
|
||||
@media (-moz-os-version: windows-vista),
|
||||
(-moz-os-version: windows-win7) {
|
||||
#main-menubar:not(:-moz-lwtheme):not(:-moz-window-inactive) {
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
@ -398,19 +402,6 @@
|
||||
#main-window[sizemode="normal"] > #tab-view-deck > #browser-panel:-moz-lwtheme:-moz-window-inactive {
|
||||
-moz-border-top-colors: @glassInactiveBorderColor@ rgba(255,255,255,.6);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (-moz-windows-glass) {
|
||||
#main-window[sizemode=normal] #nav-bar {
|
||||
border-top-left-radius: 2.5px;
|
||||
border-top-right-radius: 2.5px;
|
||||
}
|
||||
|
||||
#main-window[sizemode=fullscreen]:not(:-moz-lwtheme) {
|
||||
-moz-appearance: none;
|
||||
background-color: #556;
|
||||
}
|
||||
|
||||
/* Glass Fog */
|
||||
|
||||
|
@ -2353,12 +2353,12 @@ notification[value="translation"] {
|
||||
|
||||
#ctrlTab-panel {
|
||||
-moz-appearance: none;
|
||||
background: rgba(27%,27%,27%,.7);
|
||||
background: hsla(0,0%,33%,.85);
|
||||
color: white;
|
||||
border-style: none;
|
||||
padding: 20px 10px 10px;
|
||||
font-weight: bold;
|
||||
text-shadow: 0 0 1px rgb(27%,27%,27%), 0 0 2px rgb(27%,27%,27%);
|
||||
text-shadow: 0 0 1px hsl(0,0%,12%), 0 0 2px hsl(0,0%,12%);
|
||||
}
|
||||
|
||||
.ctrlTab-favicon[src] {
|
||||
|
@ -5,7 +5,7 @@
|
||||
%include ../../shared/customizableui/panelUI.inc.css
|
||||
|
||||
.panel-subviews {
|
||||
background-color: -moz-field;
|
||||
background-color: var(--panel-arrowcontent-background);
|
||||
}
|
||||
|
||||
#PanelUI-contents #zoom-out-btn {
|
||||
|
@ -17,7 +17,6 @@ browser.jar:
|
||||
* skin/classic/browser/browser-lightweightTheme.css
|
||||
skin/classic/browser/caption-buttons.svg
|
||||
skin/classic/browser/click-to-play-warning-stripes.png
|
||||
skin/classic/browser/content-contextmenu.svg
|
||||
skin/classic/browser/Info.png
|
||||
skin/classic/browser/Info-XP.png
|
||||
skin/classic/browser/keyhole-forward-mask.svg
|
||||
|
@ -49,34 +49,11 @@ AC_DEFUN([MOZ_CROSS_COMPILER],
|
||||
[
|
||||
echo "cross compiling from $host to $target"
|
||||
|
||||
_SAVE_CC="$CC"
|
||||
_SAVE_CFLAGS="$CFLAGS"
|
||||
_SAVE_LDFLAGS="$LDFLAGS"
|
||||
|
||||
if test -z "$HOST_AR_FLAGS"; then
|
||||
HOST_AR_FLAGS="$AR_FLAGS"
|
||||
fi
|
||||
AC_CHECK_PROGS(HOST_RANLIB, $HOST_RANLIB ranlib, ranlib, :)
|
||||
AC_CHECK_PROGS(HOST_AR, $HOST_AR ar, ar, :)
|
||||
CC="$HOST_CC"
|
||||
CFLAGS="$HOST_CFLAGS"
|
||||
LDFLAGS="$HOST_LDFLAGS"
|
||||
|
||||
AC_MSG_CHECKING([whether the host c compiler ($HOST_CC $HOST_CFLAGS $HOST_LDFLAGS) works])
|
||||
AC_TRY_COMPILE([], [return(0);],
|
||||
[ac_cv_prog_hostcc_works=1 AC_MSG_RESULT([yes])],
|
||||
AC_MSG_ERROR([installation or configuration problem: host compiler $HOST_CC cannot create executables.]) )
|
||||
|
||||
CC="$HOST_CXX"
|
||||
CFLAGS="$HOST_CXXFLAGS"
|
||||
AC_MSG_CHECKING([whether the host c++ compiler ($HOST_CXX $HOST_CXXFLAGS $HOST_LDFLAGS) works])
|
||||
AC_TRY_COMPILE([], [return(0);],
|
||||
[ac_cv_prog_hostcxx_works=1 AC_MSG_RESULT([yes])],
|
||||
AC_MSG_ERROR([installation or configuration problem: host compiler $HOST_CXX cannot create executables.]) )
|
||||
|
||||
CC=$_SAVE_CC
|
||||
CFLAGS=$_SAVE_CFLAGS
|
||||
LDFLAGS=$_SAVE_LDFLAGS
|
||||
|
||||
dnl AC_CHECK_PROGS manually goes through $PATH, and as such fails to handle
|
||||
dnl absolute or relative paths. Relative paths wouldn't work anyways, but
|
||||
|
@ -60,7 +60,7 @@ def checking(what, callback=None):
|
||||
log.info('no')
|
||||
else:
|
||||
log.info(display_ret)
|
||||
if error:
|
||||
if error is not None:
|
||||
die(error)
|
||||
return ret
|
||||
return wrapped
|
||||
|
@ -18,47 +18,14 @@
|
||||
# - `check_msg` is the message to be printed to accompany compiling the test
|
||||
# program.
|
||||
@template
|
||||
@imports('textwrap')
|
||||
def try_compile(includes=None, body='', language='C++', flags=None, check_msg=None):
|
||||
includes = includes or []
|
||||
source_lines = ['#include <%s>' % f for f in includes]
|
||||
source = '\n'.join(source_lines) + '\n'
|
||||
source += textwrap.dedent('''\
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
%s
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
''' % body)
|
||||
|
||||
if check_msg:
|
||||
def checking_fn(fn):
|
||||
return checking(check_msg, callback=lambda r: r is not None)(fn)
|
||||
else:
|
||||
def checking_fn(fn):
|
||||
return fn
|
||||
|
||||
def get_flags():
|
||||
if flags:
|
||||
return flags[:]
|
||||
|
||||
@depends(cxx_compiler, c_compiler, extra_toolchain_flags)
|
||||
@checking_fn
|
||||
def check(cxx_info, c_info, extra_flags):
|
||||
flags = get_flags() or []
|
||||
flags += extra_flags
|
||||
flags.append('-c')
|
||||
|
||||
info = {
|
||||
'C': c_info,
|
||||
'C++': cxx_info,
|
||||
compiler = {
|
||||
'C': c_compiler,
|
||||
'C++': cxx_compiler,
|
||||
}[language]
|
||||
return try_invoke_compiler(info.wrapper + [info.compiler] + info.flags,
|
||||
language, source, flags,
|
||||
onerror=lambda: None)
|
||||
return check
|
||||
|
||||
return compiler.try_compile(includes, body, flags, check_msg)
|
||||
|
||||
|
||||
# Checks for the presence of the given header on the target system by compiling
|
||||
# a test program including that header. The return value of the template is a
|
||||
|
65
build/moz.configure/compilers-util.configure
Normal file
65
build/moz.configure/compilers-util.configure
Normal file
@ -0,0 +1,65 @@
|
||||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
@template
|
||||
@imports('textwrap')
|
||||
@imports(_from='mozbuild.configure', _import='DependsFunction')
|
||||
def compiler_class(compiler):
|
||||
class Compiler(DependsFunction):
|
||||
# Generates a test program and attempts to compile it. In case of
|
||||
# failure, the resulting check will return None. If the test program
|
||||
# succeeds, it will return the output of the test program.
|
||||
# - `includes` are the includes (as file names) that will appear at the
|
||||
# top of the generated test program.
|
||||
# - `body` is the code that will appear in the main function of the
|
||||
# generated test program. `return 0;` is appended to the function
|
||||
# body automatically.
|
||||
# - `flags` are the flags to be passed to the compiler, in addition to
|
||||
# `-c`.
|
||||
# - `check_msg` is the message to be printed to accompany compiling the
|
||||
# test program.
|
||||
def try_compile(self, includes=None, body='', flags=None,
|
||||
check_msg=None, onerror=lambda: None):
|
||||
includes = includes or []
|
||||
source_lines = ['#include <%s>' % f for f in includes]
|
||||
source = '\n'.join(source_lines) + '\n'
|
||||
source += textwrap.dedent('''\
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
%s
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
''' % body)
|
||||
|
||||
if check_msg:
|
||||
def checking_fn(fn):
|
||||
return checking(check_msg,
|
||||
callback=lambda r: r is not None)(fn)
|
||||
else:
|
||||
def checking_fn(fn):
|
||||
return fn
|
||||
|
||||
def get_flags():
|
||||
if flags:
|
||||
return flags[:]
|
||||
|
||||
@depends(self, extra_toolchain_flags)
|
||||
@checking_fn
|
||||
def func(compiler, extra_flags):
|
||||
flags = get_flags() or []
|
||||
flags += extra_flags
|
||||
flags.append('-c')
|
||||
|
||||
return try_invoke_compiler(
|
||||
compiler.wrapper + [compiler.compiler] + compiler.flags,
|
||||
compiler.language, source, flags, onerror=onerror)
|
||||
|
||||
return func
|
||||
|
||||
compiler.__class__ = Compiler
|
||||
return compiler
|
@ -171,6 +171,8 @@ add_old_configure_assignment('TOOLCHAIN_PREFIX', toolchain_prefix)
|
||||
|
||||
# Compilers
|
||||
# ==============================================================
|
||||
include('compilers-util.configure')
|
||||
|
||||
def try_preprocess(compiler, language, source):
|
||||
return try_invoke_compiler(compiler, language, source, ['-E'])
|
||||
|
||||
@ -533,7 +535,7 @@ def compiler(language, host_or_target, c_compiler=None, other_compiler=None,
|
||||
'C++': lambda: default_cxx_compilers(c_compiler),
|
||||
}[language]()
|
||||
|
||||
what='the %s %s compiler' % (host_or_target_str, language),
|
||||
what='the %s %s compiler' % (host_or_target_str, language)
|
||||
|
||||
option(env=var, nargs=1, help='Path to %s' % what)
|
||||
|
||||
@ -697,6 +699,7 @@ def compiler(language, host_or_target, c_compiler=None, other_compiler=None,
|
||||
flags=flags,
|
||||
type=info.type,
|
||||
version=info.version,
|
||||
language=language,
|
||||
)
|
||||
|
||||
@depends(valid_compiler)
|
||||
@ -735,6 +738,15 @@ def compiler(language, host_or_target, c_compiler=None, other_compiler=None,
|
||||
add_old_configure_assignment(
|
||||
'%s_VERSION' % var, delayed_getattr(valid_compiler, 'version'))
|
||||
|
||||
valid_compiler = compiler_class(valid_compiler)
|
||||
|
||||
def compiler_error():
|
||||
raise FatalCheckError('Failed compiling a simple %s source with %s'
|
||||
% (language, what))
|
||||
|
||||
valid_compiler.try_compile(check_msg='%s works' % what,
|
||||
onerror=compiler_error)
|
||||
|
||||
return valid_compiler
|
||||
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
"dump": true,
|
||||
"exports": true,
|
||||
"isWorker": true,
|
||||
"indexedDB": true,
|
||||
"loader": true,
|
||||
"module": true,
|
||||
"reportError": true,
|
||||
|
@ -11,7 +11,6 @@ const {Ci} = require("chrome");
|
||||
/* eslint-enable mozilla/reject-some-requires */
|
||||
const Services = require("Services");
|
||||
const promise = require("promise");
|
||||
const FocusManager = Services.focus;
|
||||
|
||||
const ELLIPSIS = Services.prefs.getComplexValue(
|
||||
"intl.ellipsis",
|
||||
@ -356,8 +355,6 @@ HTMLBreadcrumbs.prototype = {
|
||||
|
||||
this.shortcuts.on("Right", this.handleShortcut);
|
||||
this.shortcuts.on("Left", this.handleShortcut);
|
||||
this.shortcuts.on("Tab", this.handleShortcut);
|
||||
this.shortcuts.on("Shift+Tab", this.handleShortcut);
|
||||
|
||||
// We will save a list of already displayed nodes in this array.
|
||||
this.nodeHierarchy = [];
|
||||
@ -365,6 +362,9 @@ HTMLBreadcrumbs.prototype = {
|
||||
// Last selected node in nodeHierarchy.
|
||||
this.currentIndex = -1;
|
||||
|
||||
// Used to build a unique breadcrumb button Id.
|
||||
this.breadcrumbsWidgetItemId = 0;
|
||||
|
||||
this.update = this.update.bind(this);
|
||||
this.updateSelectors = this.updateSelectors.bind(this);
|
||||
this.selection.on("new-node-front", this.update);
|
||||
@ -487,20 +487,18 @@ HTMLBreadcrumbs.prototype = {
|
||||
},
|
||||
|
||||
/**
|
||||
* Focus event handler. When breadcrumbs container gets focus, if there is an
|
||||
* already selected breadcrumb, move focus to it.
|
||||
* Focus event handler. When breadcrumbs container gets focus,
|
||||
* aria-activedescendant needs to be updated to currently selected
|
||||
* breadcrumb. Ensures that the focus stays on the container at all times.
|
||||
* @param {DOMEvent} event.
|
||||
*/
|
||||
handleFocus: function (event) {
|
||||
let control = this.container.querySelector(
|
||||
".breadcrumbs-widget-item[checked]");
|
||||
if (!this.suspendFocus && control && control !== event.target) {
|
||||
// If we already have a selected breadcrumb and focus target is not it,
|
||||
// move focus to selected breadcrumb
|
||||
event.preventDefault();
|
||||
control.focus();
|
||||
}
|
||||
this.suspendFocus = false;
|
||||
event.stopPropagation();
|
||||
|
||||
this.outer.setAttribute("aria-activedescendant",
|
||||
this.nodeHierarchy[this.currentIndex].button.id);
|
||||
|
||||
this.outer.focus();
|
||||
},
|
||||
|
||||
/**
|
||||
@ -508,10 +506,6 @@ HTMLBreadcrumbs.prototype = {
|
||||
* @param {DOMEvent} event.
|
||||
*/
|
||||
handleClick: function (event) {
|
||||
// When clicking a button temporarily suspend the behaviour that refocuses
|
||||
// the currently selected button, to prevent flicking back to that button
|
||||
// See Bug 1272011
|
||||
this.suspendFocus = true;
|
||||
let target = event.originalTarget;
|
||||
if (target.tagName == "button") {
|
||||
target.onBreadcrumbsClick();
|
||||
@ -554,28 +548,17 @@ HTMLBreadcrumbs.prototype = {
|
||||
event.stopPropagation();
|
||||
|
||||
this.keyPromise = (this.keyPromise || promise.resolve(null)).then(() => {
|
||||
let currentnode;
|
||||
if (name === "Left" && this.currentIndex != 0) {
|
||||
let node = this.nodeHierarchy[this.currentIndex - 1].node;
|
||||
return this.selection.setNodeFront(node, "breadcrumbs");
|
||||
currentnode = this.nodeHierarchy[this.currentIndex - 1];
|
||||
} else if (name === "Right" && this.currentIndex < this.nodeHierarchy.length - 1) {
|
||||
let node = this.nodeHierarchy[this.currentIndex + 1].node;
|
||||
return this.selection.setNodeFront(node, "breadcrumbs");
|
||||
} else if (name === "Tab") {
|
||||
// To move focus to next element following the breadcrumbs, relative
|
||||
// element needs to be the last element in breadcrumbs' subtree.
|
||||
let last = this.container.lastChild;
|
||||
while (last && last.lastChild) {
|
||||
last = last.lastChild;
|
||||
}
|
||||
FocusManager.moveFocus(this.chromeWin, last, FocusManager.MOVEFOCUS_FORWARD, 0);
|
||||
} else if (name === "Shift+Tab") {
|
||||
// Tabbing when breadcrumbs or its contents are focused should move focus to
|
||||
// previous focusable element relative to breadcrumbs themselves.
|
||||
let elt = this.container;
|
||||
FocusManager.moveFocus(this.chromeWin, elt, FocusManager.MOVEFOCUS_BACKWARD, 0);
|
||||
currentnode = this.nodeHierarchy[this.currentIndex + 1];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
this.outer.setAttribute("aria-activedescendant", currentnode.button.id);
|
||||
return this.selection.setNodeFront(currentnode.node, "breadcrumbs");
|
||||
});
|
||||
},
|
||||
|
||||
@ -671,7 +654,9 @@ HTMLBreadcrumbs.prototype = {
|
||||
let button = this.chromeDoc.createElementNS(NS_XHTML, "button");
|
||||
button.appendChild(this.prettyPrintNodeAsXHTML(node));
|
||||
button.className = "breadcrumbs-widget-item";
|
||||
button.id = "breadcrumbs-widget-item-" + this.breadcrumbsWidgetItemId++;
|
||||
|
||||
button.setAttribute("tabindex", "-1");
|
||||
button.setAttribute("title", this.prettyPrintNodeAsText(node));
|
||||
|
||||
button.onclick = () => {
|
||||
|
@ -54,7 +54,8 @@
|
||||
<vbox flex="1" id="markup-box">
|
||||
</vbox>
|
||||
<html:div id="inspector-breadcrumbs-toolbar" class="devtools-toolbar">
|
||||
<html:div id="inspector-breadcrumbs" class="breadcrumbs-widget-container"/>
|
||||
<html:div id="inspector-breadcrumbs" class="breadcrumbs-widget-container"
|
||||
role="group" aria-label="&inspectorBreadcrumbsGroup;" tabindex="0" />
|
||||
</html:div>
|
||||
</vbox>
|
||||
<splitter class="devtools-side-splitter"/>
|
||||
|
@ -62,6 +62,9 @@ add_task(function* () {
|
||||
let newNodeFront = yield getNodeFront(newSelection, inspector);
|
||||
is(newNodeFront, inspector.selection.nodeFront,
|
||||
"The current selection is correct");
|
||||
is(container.getAttribute("aria-activedescendant"),
|
||||
container.querySelector("button[checked]").id,
|
||||
"aria-activedescendant is set correctly");
|
||||
|
||||
currentSelection = newSelection;
|
||||
}
|
||||
|
@ -61,7 +61,9 @@ add_task(function* () {
|
||||
yield onHighlight;
|
||||
|
||||
// Ensure a breadcrumb is focused.
|
||||
is(doc.activeElement, button, "Focus is on selected breadcrumb");
|
||||
is(doc.activeElement, container, "Focus is on selected breadcrumb");
|
||||
is(container.getAttribute("aria-activedescendant"), button.id,
|
||||
"aria-activedescendant is set correctly");
|
||||
|
||||
for (let { desc, focused, key, options } of TEST_DATA) {
|
||||
info(desc);
|
||||
@ -71,9 +73,11 @@ add_task(function* () {
|
||||
yield breadcrumbs.keyPromise;
|
||||
|
||||
if (focused) {
|
||||
is(doc.activeElement, button, "Focus is on selected breadcrumb");
|
||||
is(doc.activeElement, container, "Focus is on selected breadcrumb");
|
||||
} else {
|
||||
ok(!containsFocus(doc, container), "Focus is outside of breadcrumbs");
|
||||
}
|
||||
is(container.getAttribute("aria-activedescendant"), button.id,
|
||||
"aria-activedescendant is set correctly");
|
||||
}
|
||||
});
|
||||
|
@ -20,3 +20,8 @@
|
||||
<!-- LOCALIZATION NOTE (inspectorEyeDropper.label): A string displayed as the tooltip of
|
||||
a button in the inspector which toggles the Eyedropper tool -->
|
||||
<!ENTITY inspectorEyeDropper.label "Grab a color from the page">
|
||||
|
||||
<!-- LOCALIZATION NOTE (inspectorBreadcrumbsGroup): A string visible only to a
|
||||
screen reader and is used to label (using aria-label attribute) a container
|
||||
for inspector breadcrumbs -->
|
||||
<!ENTITY inspectorBreadcrumbsGroup "Breadcrumbs">
|
||||
|
@ -179,16 +179,6 @@ inspectorPasteOuterHTML.accesskey=O
|
||||
inspectorPasteInnerHTML.label=Inner HTML
|
||||
inspectorPasteInnerHTML.accesskey=I
|
||||
|
||||
# LOCALIZATION NOTE (inspectorHTMLPasteExtraSubmenu.label): This is the label
|
||||
# shown in the inspector contextual-menu for the sub-menu of the other Paste
|
||||
# items, which allow to paste HTML:
|
||||
# - before the current node
|
||||
# - after the current node
|
||||
# - as the first child of the current node
|
||||
# - as the last child of the current node
|
||||
inspectorHTMLPasteExtraSubmenu.label=Paste…
|
||||
inspectorHTMLPasteExtraSubmenu.accesskey=t
|
||||
|
||||
# LOCALIZATION NOTE (inspectorHTMLPasteBefore.label): This is the label shown
|
||||
# in the inspector contextual-menu for the item that lets users paste
|
||||
# the HTML before the current node
|
||||
@ -240,11 +230,6 @@ inspectorAttributesSubmenu.accesskey=A
|
||||
inspectorAddAttribute.label=Add Attribute
|
||||
inspectorAddAttribute.accesskey=A
|
||||
|
||||
# LOCALIZATION NOTE (inspectorSearchHTML.label2): This is the label shown as
|
||||
# the placeholder in inspector search box
|
||||
inspectorSearchHTML.label2=Search with CSS Selectors
|
||||
inspectorSearchHTML.key=F
|
||||
|
||||
# LOCALIZATION NOTE (inspectorSearchHTML.label3): This is the label that is
|
||||
# shown as the placeholder for the markup view search in the inspector.
|
||||
inspectorSearchHTML.label3=Search HTML
|
||||
|
@ -249,15 +249,6 @@
|
||||
color: hsl(210,30%,85%);
|
||||
}
|
||||
|
||||
.breadcrumbs-widget-item:-moz-focusring {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.breadcrumbs-widget-item[checked]:-moz-focusring > .button-box {
|
||||
outline: var(--theme-focus-outline);
|
||||
outline-offset: -1px;
|
||||
}
|
||||
|
||||
.breadcrumbs-widget-item > .button-box {
|
||||
border: none;
|
||||
padding-top: 0;
|
||||
|
@ -8,6 +8,7 @@ DIRS += [
|
||||
'components',
|
||||
'reducers',
|
||||
'selectors',
|
||||
'test',
|
||||
'utils',
|
||||
]
|
||||
|
||||
|
@ -29,6 +29,9 @@ let ReactDOM = browserRequire("devtools/client/shared/vendor/react-dom");
|
||||
let React = browserRequire("devtools/client/shared/vendor/react");
|
||||
var TestUtils = React.addons.TestUtils;
|
||||
|
||||
const { stubConsoleMessages } = require("devtools/client/webconsole/new-console-output/test/stubs");
|
||||
|
||||
// @TODO Remove this.
|
||||
let testCommands = new Map();
|
||||
testCommands.set("console.log()", {
|
||||
command: "console.log('foobar', 'test')",
|
||||
|
@ -0,0 +1,8 @@
|
||||
# vim: set filetype=python:
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
DevToolsModules(
|
||||
'stubs.js',
|
||||
)
|
@ -58,20 +58,6 @@ add_task(function* () {
|
||||
"Non-repeated messages aren't clobbered");
|
||||
});
|
||||
|
||||
/**
|
||||
* Test getRepeatId().
|
||||
*/
|
||||
add_task(function* () {
|
||||
const message1 = prepareMessage(packet);
|
||||
let message2 = prepareMessage(packet);
|
||||
equal(getRepeatId(message1), getRepeatId(message2),
|
||||
"getRepeatId() returns same repeat id for objects with the same values");
|
||||
|
||||
message2 = message2.set("parameters", ["new args"]);
|
||||
notEqual(getRepeatId(message1), getRepeatId(message2),
|
||||
"getRepeatId() returns different repeat ids for different values");
|
||||
});
|
||||
|
||||
/**
|
||||
* Test adding a console.clear message to the store.
|
||||
*/
|
||||
@ -122,7 +108,7 @@ add_task(function* () {
|
||||
|
||||
let newPacket = Object.assign({}, packet);
|
||||
for (let i = 1; i <= userSetLimit + 1; i++) {
|
||||
newPacket.message.parameters = [i];
|
||||
newPacket.message.arguments = [i];
|
||||
dispatch(actions.messageAdd(newPacket));
|
||||
}
|
||||
|
||||
|
99
devtools/client/webconsole/new-console-output/test/stubs.js
Normal file
99
devtools/client/webconsole/new-console-output/test/stubs.js
Normal file
@ -0,0 +1,99 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const {
|
||||
MESSAGE_SOURCE,
|
||||
MESSAGE_TYPE,
|
||||
MESSAGE_LEVEL,
|
||||
// Legacy
|
||||
CATEGORY_WEBDEV,
|
||||
SEVERITY_LOG,
|
||||
} = require("devtools/client/webconsole/new-console-output/constants");
|
||||
|
||||
const { ConsoleMessage } = require("devtools/client/webconsole/new-console-output/types");
|
||||
|
||||
exports.stubConsoleMessages = new Map([
|
||||
[
|
||||
"console.log('foobar', 'test')",
|
||||
new ConsoleMessage({
|
||||
allowRepeating: true,
|
||||
source: MESSAGE_SOURCE.CONSOLE_API,
|
||||
type: MESSAGE_TYPE.LOG,
|
||||
level: MESSAGE_LEVEL.LOG,
|
||||
messageText: null,
|
||||
parameters: ["foobar", "test"],
|
||||
repeat: 1,
|
||||
repeatId: null,
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
})
|
||||
],
|
||||
[
|
||||
"console.warn('danger, will robinson!')",
|
||||
new ConsoleMessage({
|
||||
allowRepeating: true,
|
||||
source: MESSAGE_SOURCE.CONSOLE_API,
|
||||
type: MESSAGE_TYPE.LOG,
|
||||
level: MESSAGE_LEVEL.WARN,
|
||||
messageText: null,
|
||||
parameters: ["danger, will robinson!"],
|
||||
repeat: 1,
|
||||
repeatId: null,
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
})
|
||||
],
|
||||
[
|
||||
"console.log(undefined)",
|
||||
new ConsoleMessage({
|
||||
allowRepeating: true,
|
||||
source: MESSAGE_SOURCE.CONSOLE_API,
|
||||
type: MESSAGE_TYPE.LOG,
|
||||
level: MESSAGE_LEVEL.LOG,
|
||||
messageText: null,
|
||||
parameters: [
|
||||
{ type: "undefined" }
|
||||
],
|
||||
repeat: 1,
|
||||
repeatId: null,
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
})
|
||||
],
|
||||
[
|
||||
"console.log(NaN)",
|
||||
new ConsoleMessage({
|
||||
allowRepeating: true,
|
||||
source: MESSAGE_SOURCE.CONSOLE_API,
|
||||
type: MESSAGE_TYPE.LOG,
|
||||
level: MESSAGE_LEVEL.LOG,
|
||||
messageText: null,
|
||||
parameters: [
|
||||
{ type: "NaN" }
|
||||
],
|
||||
repeat: 1,
|
||||
repeatId: null,
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
})
|
||||
],
|
||||
[
|
||||
"console.log(null)",
|
||||
new ConsoleMessage({
|
||||
allowRepeating: true,
|
||||
source: MESSAGE_SOURCE.CONSOLE_API,
|
||||
type: MESSAGE_TYPE.LOG,
|
||||
level: MESSAGE_LEVEL.LOG,
|
||||
messageText: null,
|
||||
parameters: [
|
||||
{ type: "null" }
|
||||
],
|
||||
repeat: 1,
|
||||
repeatId: null,
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
})
|
||||
],
|
||||
]);
|
@ -13,47 +13,43 @@
|
||||
|
||||
<script type="text/javascript;version=1.8">
|
||||
window.onload = Task.async(function* () {
|
||||
const {
|
||||
prepareMessage,
|
||||
getRepeatId
|
||||
} = require("devtools/client/webconsole/new-console-output/utils/messages");
|
||||
const { getRepeatId } = require("devtools/client/webconsole/new-console-output/utils/messages");
|
||||
|
||||
yield testDuplicateValues();
|
||||
yield testDifferentValues();
|
||||
yield testDifferentSeverities();
|
||||
yield testFalsyValues();
|
||||
yield testConsoleVsJSTerm();
|
||||
|
||||
SimpleTest.finish();
|
||||
|
||||
function testDuplicateValues() {
|
||||
const {message: message1} = yield getPacket("console.log('same')", "consoleAPICall");
|
||||
const {message: message2} = yield getPacket("console.log('same')", "consoleAPICall");
|
||||
const message1 = stubConsoleMessages.get("console.log('foobar', 'test')");
|
||||
const message2 = message1.set("repeat", 3);
|
||||
|
||||
is(getRepeatId(message1), getRepeatId(message2),
|
||||
"getRepeatId() returns same repeat id for objects with the same values");
|
||||
}
|
||||
|
||||
function testDifferentValues() {
|
||||
const {message: message1} = yield getPacket("console.log('same')", "consoleAPICall");
|
||||
const {message: message2} = yield getPacket("console.log('diff')", "consoleAPICall");
|
||||
const message1 = stubConsoleMessages.get("console.log('foobar', 'test')");
|
||||
const message2 = message1.set("parameters", ["funny", "monkey"]);
|
||||
|
||||
isnot(getRepeatId(message1), getRepeatId(message2),
|
||||
"getRepeatId() returns different repeat ids for different values");
|
||||
}
|
||||
|
||||
function testDifferentSeverities() {
|
||||
const {message: message1} = yield getPacket("console.log('test')", "consoleAPICall");
|
||||
const {message: message2} = yield getPacket("console.warn('test')", "consoleAPICall");
|
||||
const message1 = stubConsoleMessages.get("console.log('foobar', 'test')");
|
||||
const message2 = message1.set("level", "error");
|
||||
|
||||
isnot(getRepeatId(message1), getRepeatId(message2),
|
||||
"getRepeatId() returns different repeat ids for different severities");
|
||||
}
|
||||
|
||||
function testFalsyValues() {
|
||||
const {message: messageNaN} = yield getPacket("console.log(NaN)", "consoleAPICall");
|
||||
const {message: messageUnd} = yield getPacket("console.log(undefined)", "consoleAPICall");
|
||||
const {message: messageNul} = yield getPacket("console.log(null)", "consoleAPICall");
|
||||
const messageNaN = stubConsoleMessages.get("console.log(NaN)");
|
||||
const messageUnd = stubConsoleMessages.get("console.log(undefined)");
|
||||
const messageNul = stubConsoleMessages.get("console.log(null)");
|
||||
|
||||
const repeatIds = new Set([
|
||||
getRepeatId(messageNaN),
|
||||
@ -62,25 +58,6 @@ window.onload = Task.async(function* () {
|
||||
);
|
||||
is(repeatIds.size, 3,
|
||||
"getRepeatId() handles falsy values distinctly");
|
||||
|
||||
const {message: messageNaN2} = yield getPacket("console.log(NaN)", "consoleAPICall");
|
||||
const {message: messageUnd2} = yield getPacket("console.log(undefined)", "consoleAPICall");
|
||||
const {message: messageNul2} = yield getPacket("console.log(null)", "consoleAPICall");
|
||||
|
||||
is(getRepeatId(messageNaN), getRepeatId(messageNaN2),
|
||||
"getRepeatId() handles NaN values");
|
||||
is(getRepeatId(messageUnd), getRepeatId(messageUnd2),
|
||||
"getRepeatId() handles undefined values");
|
||||
is(getRepeatId(messageNul), getRepeatId(messageNul2),
|
||||
"getRepeatId() handles null values");
|
||||
}
|
||||
|
||||
function testConsoleVsJSTerm() {
|
||||
const {message: message1} = yield getPacket("console.log(undefined)", "consoleAPICall");
|
||||
const {result: message2} = yield getPacket("undefined");
|
||||
|
||||
isnot(getRepeatId(message1), getRepeatId(message2),
|
||||
"getRepeatId() returns different repeat ids for console vs JSTerm");
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
@ -8,6 +8,7 @@
|
||||
const Immutable = require("devtools/client/shared/vendor/immutable");
|
||||
|
||||
exports.ConsoleCommand = Immutable.Record({
|
||||
id: null,
|
||||
allowRepeating: false,
|
||||
messageText: null,
|
||||
source: null,
|
||||
@ -17,6 +18,7 @@ exports.ConsoleCommand = Immutable.Record({
|
||||
});
|
||||
|
||||
exports.ConsoleMessage = Immutable.Record({
|
||||
id: null,
|
||||
allowRepeating: true,
|
||||
source: null,
|
||||
type: null,
|
||||
@ -27,5 +29,4 @@ exports.ConsoleMessage = Immutable.Record({
|
||||
repeatId: null,
|
||||
category: "output",
|
||||
severity: "log",
|
||||
id: null,
|
||||
});
|
||||
|
@ -30,11 +30,14 @@ function getNextMessageId() {
|
||||
|
||||
function prepareMessage(packet) {
|
||||
// This packet is already in the expected packet structure. Simply return.
|
||||
if (packet.source) {
|
||||
return packet;
|
||||
if (!packet.source) {
|
||||
packet = transformPacket(packet);
|
||||
}
|
||||
|
||||
return transformPacket(packet);
|
||||
if (packet.allowRepeating) {
|
||||
packet = packet.set("repeatId", getRepeatId(packet));
|
||||
}
|
||||
return packet.set("id", getNextMessageId());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -77,10 +80,8 @@ function transformPacket(packet) {
|
||||
level,
|
||||
parameters,
|
||||
messageText,
|
||||
repeatId: getRepeatId(message),
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: level,
|
||||
id: getNextMessageId(),
|
||||
});
|
||||
}
|
||||
|
||||
@ -97,10 +98,8 @@ function transformPacket(packet) {
|
||||
source: MESSAGE_SOURCE.JAVASCRIPT,
|
||||
type: MESSAGE_TYPE.LOG,
|
||||
messageText: pageError.errorMessage,
|
||||
repeatId: getRepeatId(pageError),
|
||||
category: CATEGORY_JS,
|
||||
severity: level,
|
||||
id: getNextMessageId(),
|
||||
});
|
||||
}
|
||||
|
||||
@ -113,10 +112,8 @@ function transformPacket(packet) {
|
||||
type: MESSAGE_TYPE.RESULT,
|
||||
level: MESSAGE_LEVEL.LOG,
|
||||
parameters: result,
|
||||
repeatId: getRepeatId(result),
|
||||
category: CATEGORY_OUTPUT,
|
||||
severity: SEVERITY_LOG,
|
||||
id: getNextMessageId(),
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -124,10 +121,9 @@ function transformPacket(packet) {
|
||||
|
||||
// Helpers
|
||||
function getRepeatId(message) {
|
||||
let clonedMessage = JSON.parse(JSON.stringify(message));
|
||||
delete clonedMessage.id;
|
||||
delete clonedMessage.timeStamp;
|
||||
return JSON.stringify(clonedMessage);
|
||||
message = message.toJS();
|
||||
delete message.repeat;
|
||||
return JSON.stringify(message);
|
||||
}
|
||||
|
||||
function convertCachedPacket(packet) {
|
||||
|
@ -8,7 +8,6 @@ const promise = require("promise");
|
||||
const EventEmitter = require("devtools/shared/event-emitter");
|
||||
const {generateUUID} = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator);
|
||||
const {FileUtils} = Cu.import("resource://gre/modules/FileUtils.jsm", {});
|
||||
const {indexedDB} = require("sdk/indexed-db");
|
||||
|
||||
/**
|
||||
* IndexedDB wrapper that just save project objects
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
const {Cc, Ci} = require("chrome");
|
||||
const {Cc, Ci, Cu, CC} = require("chrome");
|
||||
const events = require("sdk/event/core");
|
||||
const protocol = require("devtools/shared/protocol");
|
||||
const {LongStringActor} = require("devtools/server/actors/string");
|
||||
@ -18,6 +18,20 @@ const { Task } = require("devtools/shared/task");
|
||||
loader.lazyImporter(this, "OS", "resource://gre/modules/osfile.jsm");
|
||||
loader.lazyImporter(this, "Sqlite", "resource://gre/modules/Sqlite.jsm");
|
||||
|
||||
// We give this a funny name to avoid confusion with the global
|
||||
// indexedDB.
|
||||
loader.lazyGetter(this, "indexedDBForStorage", () => {
|
||||
// On xpcshell, we can't instantiate indexedDB without crashing
|
||||
try {
|
||||
let sandbox
|
||||
= Cu.Sandbox(CC("@mozilla.org/systemprincipal;1", "nsIPrincipal")(),
|
||||
{wantGlobalProperties: ["indexedDB"]});
|
||||
return sandbox.indexedDB;
|
||||
} catch (e) {
|
||||
return {};
|
||||
}
|
||||
});
|
||||
|
||||
var gTrackedMessageManager = new Map();
|
||||
|
||||
// Maximum number of cookies/local storage key-value-pairs that can be sent
|
||||
@ -1736,12 +1750,12 @@ var indexedDBHelpers = {
|
||||
* database `name`.
|
||||
*/
|
||||
openWithPrincipal(principal, name) {
|
||||
return require("indexedDB").openForPrincipal(principal, name);
|
||||
return indexedDBForStorage.openForPrincipal(principal, name);
|
||||
},
|
||||
|
||||
removeDB: Task.async(function* (host, principal, name) {
|
||||
let result = new promise(resolve => {
|
||||
let request = require("indexedDB").deleteForPrincipal(principal, name);
|
||||
let request = indexedDBForStorage.deleteForPrincipal(principal, name);
|
||||
|
||||
request.onsuccess = () => {
|
||||
resolve({});
|
||||
|
@ -39,25 +39,23 @@
|
||||
* DOM elements, but they may include things like Blobs and typed arrays.
|
||||
*
|
||||
*/
|
||||
const {Cc, Ci, Cu, Cr} = require("chrome");
|
||||
const {indexedDB} = require("sdk/indexed-db");
|
||||
|
||||
"use strict";
|
||||
|
||||
const Promise = require("promise");
|
||||
|
||||
module.exports = (function () {
|
||||
"use strict";
|
||||
const DBNAME = "devtools-async-storage";
|
||||
const DBVERSION = 1;
|
||||
const STORENAME = "keyvaluepairs";
|
||||
var db = null;
|
||||
|
||||
var DBNAME = "devtools-async-storage";
|
||||
var DBVERSION = 1;
|
||||
var STORENAME = "keyvaluepairs";
|
||||
var db = null;
|
||||
|
||||
function withStore(type, onsuccess, onerror) {
|
||||
function withStore(type, onsuccess, onerror) {
|
||||
if (db) {
|
||||
var transaction = db.transaction(STORENAME, type);
|
||||
var store = transaction.objectStore(STORENAME);
|
||||
let transaction = db.transaction(STORENAME, type);
|
||||
let store = transaction.objectStore(STORENAME);
|
||||
onsuccess(store);
|
||||
} else {
|
||||
var openreq = indexedDB.open(DBNAME, DBVERSION);
|
||||
let openreq = indexedDB.open(DBNAME, DBVERSION);
|
||||
openreq.onerror = function withStoreOnError() {
|
||||
onerror();
|
||||
};
|
||||
@ -67,71 +65,71 @@ module.exports = (function () {
|
||||
};
|
||||
openreq.onsuccess = function withStoreOnSuccess() {
|
||||
db = openreq.result;
|
||||
var transaction = db.transaction(STORENAME, type);
|
||||
var store = transaction.objectStore(STORENAME);
|
||||
let transaction = db.transaction(STORENAME, type);
|
||||
let store = transaction.objectStore(STORENAME);
|
||||
onsuccess(store);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getItem(key) {
|
||||
function getItem(itemKey) {
|
||||
return new Promise((resolve, reject) => {
|
||||
var req;
|
||||
let req;
|
||||
withStore("readonly", (store) => {
|
||||
store.transaction.oncomplete = function onComplete() {
|
||||
var value = req.result;
|
||||
let value = req.result;
|
||||
if (value === undefined) {
|
||||
value = null;
|
||||
}
|
||||
resolve(value);
|
||||
};
|
||||
req = store.get(key);
|
||||
req = store.get(itemKey);
|
||||
req.onerror = function getItemOnError() {
|
||||
reject("Error in asyncStorage.getItem(): ", req.error.name);
|
||||
};
|
||||
}, reject);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function setItem(key, value) {
|
||||
function setItem(itemKey, value) {
|
||||
return new Promise((resolve, reject) => {
|
||||
withStore("readwrite", (store) => {
|
||||
store.transaction.oncomplete = resolve;
|
||||
var req = store.put(value, key);
|
||||
let req = store.put(value, itemKey);
|
||||
req.onerror = function setItemOnError() {
|
||||
reject("Error in asyncStorage.setItem(): ", req.error.name);
|
||||
};
|
||||
}, reject);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function removeItem(key) {
|
||||
function removeItem(itemKey) {
|
||||
return new Promise((resolve, reject) => {
|
||||
withStore("readwrite", (store) => {
|
||||
store.transaction.oncomplete = resolve;
|
||||
var req = store.delete(key);
|
||||
let req = store.delete(itemKey);
|
||||
req.onerror = function removeItemOnError() {
|
||||
reject("Error in asyncStorage.removeItem(): ", req.error.name);
|
||||
};
|
||||
}, reject);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function clear() {
|
||||
function clear() {
|
||||
return new Promise((resolve, reject) => {
|
||||
withStore("readwrite", (store) => {
|
||||
store.transaction.oncomplete = resolve;
|
||||
var req = store.clear();
|
||||
let req = store.clear();
|
||||
req.onerror = function clearOnError() {
|
||||
reject("Error in asyncStorage.clear(): ", req.error.name);
|
||||
};
|
||||
}, reject);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function length() {
|
||||
function length() {
|
||||
return new Promise((resolve, reject) => {
|
||||
var req;
|
||||
let req;
|
||||
withStore("readonly", (store) => {
|
||||
store.transaction.oncomplete = function onComplete() {
|
||||
resolve(req.result);
|
||||
@ -142,25 +140,25 @@ module.exports = (function () {
|
||||
};
|
||||
}, reject);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function key(n) {
|
||||
function key(n) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (n < 0) {
|
||||
resolve(null);
|
||||
return;
|
||||
}
|
||||
|
||||
var req;
|
||||
let req;
|
||||
withStore("readonly", (store) => {
|
||||
store.transaction.oncomplete = function onComplete() {
|
||||
var cursor = req.result;
|
||||
let cursor = req.result;
|
||||
resolve(cursor ? cursor.key : null);
|
||||
};
|
||||
var advanced = false;
|
||||
let advanced = false;
|
||||
req = store.openCursor();
|
||||
req.onsuccess = function keyOnSuccess() {
|
||||
var cursor = req.result;
|
||||
let cursor = req.result;
|
||||
if (!cursor) {
|
||||
// this means there weren"t enough keys
|
||||
return;
|
||||
@ -180,14 +178,11 @@ module.exports = (function () {
|
||||
};
|
||||
}, reject);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
getItem: getItem,
|
||||
setItem: setItem,
|
||||
removeItem: removeItem,
|
||||
clear: clear,
|
||||
length: length,
|
||||
key: key
|
||||
};
|
||||
}());
|
||||
exports.getItem = getItem;
|
||||
exports.setItem = setItem;
|
||||
exports.removeItem = removeItem;
|
||||
exports.clear = clear;
|
||||
exports.length = length;
|
||||
exports.key = key;
|
||||
|
@ -204,19 +204,6 @@ defineLazyGetter(exports.modules, "xpcInspector", () => {
|
||||
return Cc["@mozilla.org/jsinspector;1"].getService(Ci.nsIJSInspector);
|
||||
});
|
||||
|
||||
defineLazyGetter(exports.modules, "indexedDB", () => {
|
||||
// On xpcshell, we can't instantiate indexedDB without crashing
|
||||
try {
|
||||
let sandbox
|
||||
= Cu.Sandbox(CC("@mozilla.org/systemprincipal;1", "nsIPrincipal")(),
|
||||
{wantGlobalProperties: ["indexedDB"]});
|
||||
return sandbox.indexedDB;
|
||||
|
||||
} catch (e) {
|
||||
return {};
|
||||
}
|
||||
});
|
||||
|
||||
defineLazyGetter(exports.modules, "FileReader", () => {
|
||||
let sandbox
|
||||
= Cu.Sandbox(CC("@mozilla.org/systemprincipal;1", "nsIPrincipal")(),
|
||||
@ -295,3 +282,4 @@ defineLazyGetter(globals, "CSS", () => {
|
||||
defineLazyGetter(globals, "WebSocket", () => {
|
||||
return Services.appShell.hiddenDOMWindow.WebSocket;
|
||||
});
|
||||
lazyRequireGetter(globals, "indexedDB", "sdk/indexed-db", true);
|
||||
|
@ -40,7 +40,7 @@ enum class ListAllowance { eDisallow, eAllow };
|
||||
|
||||
/**
|
||||
* A comparator to sort nsCSSProperty values such that longhands are sorted
|
||||
* before shorthands, and shorthands with less components are sorted before
|
||||
* before shorthands, and shorthands with fewer components are sorted before
|
||||
* shorthands with more components.
|
||||
*
|
||||
* Using this allows us to prioritize values specified by longhands (or smaller
|
||||
|
@ -291,6 +291,55 @@ Element::UpdateEditableState(bool aNotify)
|
||||
}
|
||||
}
|
||||
|
||||
int32_t
|
||||
Element::TabIndex()
|
||||
{
|
||||
const nsAttrValue* attrVal = mAttrsAndChildren.GetAttr(nsGkAtoms::tabindex);
|
||||
if (attrVal && attrVal->Type() == nsAttrValue::eInteger) {
|
||||
return attrVal->GetIntegerValue();
|
||||
}
|
||||
|
||||
return TabIndexDefault();
|
||||
}
|
||||
|
||||
void
|
||||
Element::Focus(mozilla::ErrorResult& aError)
|
||||
{
|
||||
nsCOMPtr<nsIDOMElement> domElement = do_QueryInterface(this);
|
||||
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
|
||||
if (fm && domElement) {
|
||||
aError = fm->SetFocus(domElement, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Element::SetTabIndex(int32_t aTabIndex, mozilla::ErrorResult& aError)
|
||||
{
|
||||
nsAutoString value;
|
||||
value.AppendInt(aTabIndex);
|
||||
|
||||
SetAttr(nsGkAtoms::tabindex, value, aError);
|
||||
}
|
||||
|
||||
void
|
||||
Element::Blur(mozilla::ErrorResult& aError)
|
||||
{
|
||||
if (!ShouldBlur(this)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsIDocument* doc = GetComposedDoc();
|
||||
if (!doc) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsPIDOMWindowOuter* win = doc->GetWindow();
|
||||
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
|
||||
if (win && fm) {
|
||||
aError = fm->ClearFocus(win);
|
||||
}
|
||||
}
|
||||
|
||||
EventStates
|
||||
Element::StyleStateFromLocks() const
|
||||
{
|
||||
|
@ -193,6 +193,31 @@ public:
|
||||
*/
|
||||
void UpdateLinkState(EventStates aState);
|
||||
|
||||
virtual int32_t TabIndexDefault()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tabIndex of this element. If not found, return TabIndexDefault.
|
||||
*/
|
||||
int32_t TabIndex();
|
||||
|
||||
/**
|
||||
* Set tabIndex value to this element.
|
||||
*/
|
||||
void SetTabIndex(int32_t aTabIndex, mozilla::ErrorResult& aError);
|
||||
|
||||
/**
|
||||
* Make focus on this element.
|
||||
*/
|
||||
virtual void Focus(mozilla::ErrorResult& aError);
|
||||
|
||||
/**
|
||||
* Show blur and clear focus.
|
||||
*/
|
||||
virtual void Blur(mozilla::ErrorResult& aError);
|
||||
|
||||
/**
|
||||
* The style state of this element. This is the real state of the element
|
||||
* with any style locks applied for pseudo-class inspecting.
|
||||
|
@ -812,4 +812,22 @@ AutoSafeJSContext::AutoSafeJSContext(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_IN_IMP
|
||||
"returned null, and inited correctly otherwise!");
|
||||
}
|
||||
|
||||
AutoSlowOperation::AutoSlowOperation(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_IN_IMPL)
|
||||
: AutoJSAPI()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
|
||||
Init();
|
||||
}
|
||||
|
||||
void
|
||||
AutoSlowOperation::CheckForInterrupt()
|
||||
{
|
||||
// JS_CheckForInterrupt expects us to be in a compartment.
|
||||
JSAutoCompartment ac(cx(), xpc::UnprivilegedJunkScope());
|
||||
JS_CheckForInterrupt(cx());
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -443,6 +443,23 @@ private:
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
};
|
||||
|
||||
/**
|
||||
* Use AutoSlowOperation when native side calls many JS callbacks in a row
|
||||
* and slow script dialog should be activated if too much time is spent going
|
||||
* through those callbacks.
|
||||
* AutoSlowOperation puts a JSAutoRequest on the stack so that we don't continue
|
||||
* to reset the watchdog and CheckForInterrupt can be then used to check whether
|
||||
* JS execution should be interrupted.
|
||||
*/
|
||||
class MOZ_RAII AutoSlowOperation : public dom::AutoJSAPI
|
||||
{
|
||||
public:
|
||||
explicit AutoSlowOperation(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM);
|
||||
void CheckForInterrupt();
|
||||
private:
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_ScriptSettings_h
|
||||
|
@ -885,10 +885,7 @@ nsDOMMutationObserver::HandleMutationsInternal()
|
||||
return;
|
||||
}
|
||||
|
||||
// We need the AutoSafeJSContext to ensure the slow script dialog is
|
||||
// triggered. AutoSafeJSContext does that by pushing JSAutoRequest to stack.
|
||||
// This needs to be outside the while loop.
|
||||
AutoSafeJSContext cx;
|
||||
AutoSlowOperation aso;
|
||||
|
||||
nsTArray<RefPtr<nsDOMMutationObserver> >* suppressedObservers = nullptr;
|
||||
|
||||
@ -910,7 +907,7 @@ nsDOMMutationObserver::HandleMutationsInternal()
|
||||
}
|
||||
}
|
||||
delete observers;
|
||||
JS_CheckForInterrupt(cx);
|
||||
aso.CheckForInterrupt();
|
||||
}
|
||||
|
||||
if (suppressedObservers) {
|
||||
|
@ -100,7 +100,7 @@ function getXHRLoadHandler(expectedResult, expectedLength, testName) {
|
||||
"[XHR] Length of result in test " + testName);
|
||||
ok(convertedData == expectedResult,
|
||||
"[XHR] Content of result in test " + testName);
|
||||
is(event.lengthComputable, true,
|
||||
is(event.lengthComputable, event.total != 0,
|
||||
"[XHR] lengthComputable in test " + testName);
|
||||
is(event.loaded, expectedLength,
|
||||
"[XHR] Loaded length in test " + testName);
|
||||
|
@ -24,6 +24,7 @@ var upload = null;
|
||||
var currentEvents = null;
|
||||
var expectedResponseText = null;
|
||||
var uploadTotal = 0;
|
||||
var currentProgress = -1;
|
||||
|
||||
function logEvent(evt) {
|
||||
var i = 0;
|
||||
@ -33,20 +34,41 @@ function logEvent(evt) {
|
||||
!(evt.target instanceof currentEvents[i].target))) {
|
||||
++i;
|
||||
}
|
||||
|
||||
if (evt.target instanceof XMLHttpRequestUpload) {
|
||||
if (evt.type == "loadstart") {
|
||||
uploadTotal = evt.total
|
||||
} else {
|
||||
if (evt.type == "progress") {
|
||||
ok(evt.lengthComputable, "event(" + evt.type + ").lengthComputable should be true.");
|
||||
is(evt.lengthComputable, evt.total != 0, "event(" + evt.type + ").lengthComputable should be " + (evt.total != 0 ? true : false) + ".");
|
||||
}
|
||||
is(evt.total, uploadTotal, "event(" + evt.type + ").total should not change during upload.");
|
||||
if (evt.total != uploadTotal && evt.total != 0) {
|
||||
ok(false, "event(" + evt.type + ").total should not change during upload except to become 0 on error/abort/timeout.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// There can be any number of repeated progress events, so special-case this.
|
||||
if (evt.type == "progress") {
|
||||
// Progress events can repeat, but their "loaded" value must increase.
|
||||
if (currentProgress >= 0) {
|
||||
ok(currentProgress < evt.loaded, "Progress should increase, got " +
|
||||
evt.loaded + " after " + currentProgress);
|
||||
currentProgress = evt.loaded;
|
||||
return; // stay at the currentEvent, since we got progress instead of it.
|
||||
}
|
||||
// Starting a new progress event group.
|
||||
currentProgress = evt.loaded;
|
||||
} else {
|
||||
// Reset the progress indicator on any other event type.
|
||||
currentProgress = -1;
|
||||
}
|
||||
|
||||
ok(i != currentEvents.length, "Extra or wrong event?");
|
||||
is(evt.type, currentEvents[i].type, "Wrong event!")
|
||||
ok(evt.target instanceof currentEvents[i].target,
|
||||
"Wrong event target [" + evt.target + "," + evt.type + "]!");
|
||||
|
||||
// If we handled non-optional event, remove all optional events before the
|
||||
// handled event and then the non-optional event from the list.
|
||||
if (!currentEvents[i].optional) {
|
||||
@ -84,6 +106,7 @@ function start(obj) {
|
||||
upload = xhr.upload;
|
||||
currentEvents = obj.expectedEvents;
|
||||
expectedResponseText = obj.withUpload;
|
||||
currentProgress = -1;
|
||||
xhr.onload =
|
||||
function(evt) {
|
||||
if (expectedResponseText) {
|
||||
@ -189,11 +212,12 @@ var tests =
|
||||
[
|
||||
{ method: "GET", withUpload: none, testAbort: false, testRedirectError: false, testNetworkError: false,
|
||||
expectedEvents: [{target: XHR, type: "loadstart", optional: false},
|
||||
{target: XHR, type: "progress", optional: true},
|
||||
{target: XHR, type: "progress", optional: false},
|
||||
{target: XHR, type: "load", optional: false},
|
||||
{target: XHR, type: "loadend", optional: false}]},
|
||||
{ method: "GET", withUpload: none, testAbort: true, testRedirectError: false, testNetworkError: false,
|
||||
expectedEvents: [{target: XHR, type: "loadstart", optional: false},
|
||||
{target: XHR, type: "progress", optional: false},
|
||||
{target: XHR, type: "abort", optional: false},
|
||||
{target: XHR, type: "loadend", optional: false}]},
|
||||
{ method: "GET", withUpload: none, testAbort: false, testRedirectError: true, testNetworkError: false,
|
||||
@ -207,11 +231,12 @@ var tests =
|
||||
|
||||
{ method: "GET", withUpload: small, testAbort: false, testRedirectError: false, testNetworkError: false,
|
||||
expectedEvents: [{target: XHR, type: "loadstart", optional: false},
|
||||
{target: XHR, type: "progress", optional: true},
|
||||
{target: XHR, type: "progress", optional: false},
|
||||
{target: XHR, type: "load", optional: false},
|
||||
{target: XHR, type: "loadend", optional: false}]},
|
||||
{ method: "GET", withUpload: small, testAbort: true, testRedirectError: false, testNetworkError: false,
|
||||
expectedEvents: [{target: XHR, type: "loadstart", optional: false},
|
||||
{target: XHR, type: "progress", optional: false},
|
||||
{target: XHR, type: "abort", optional: false},
|
||||
{target: XHR, type: "loadend", optional: false}]},
|
||||
{ method: "GET", withUpload: small, testAbort: false, testRedirectError: true, testNetworkError: false,
|
||||
@ -225,11 +250,12 @@ var tests =
|
||||
|
||||
{ method: "GET", withUpload: mid, testAbort: false, testRedirectError: false, testNetworkError: false,
|
||||
expectedEvents: [{target: XHR, type: "loadstart", optional: false},
|
||||
{target: XHR, type: "progress", optional: true},
|
||||
{target: XHR, type: "progress", optional: false},
|
||||
{target: XHR, type: "load", optional: false},
|
||||
{target: XHR, type: "loadend", optional: false}]},
|
||||
{ method: "GET", withUpload: mid, testAbort: true, testRedirectError: false, testNetworkError: false,
|
||||
expectedEvents: [{target: XHR, type: "loadstart", optional: false},
|
||||
{target: XHR, type: "progress", optional: false},
|
||||
{target: XHR, type: "abort", optional: false},
|
||||
{target: XHR, type: "loadend", optional: false}]},
|
||||
{ method: "GET", withUpload: mid, testAbort: false, testRedirectError: true, testNetworkError: false,
|
||||
@ -243,11 +269,12 @@ var tests =
|
||||
|
||||
{ method: "GET", withUpload: large, testAbort: false, testRedirectError: false, testNetworkError: false,
|
||||
expectedEvents: [{target: XHR, type: "loadstart", optional: false},
|
||||
{target: XHR, type: "progress", optional: true},
|
||||
{target: XHR, type: "progress", optional: false},
|
||||
{target: XHR, type: "load", optional: false},
|
||||
{target: XHR, type: "loadend", optional: false}]},
|
||||
{ method: "GET", withUpload: large, testAbort: true, testRedirectError: false, testNetworkError: false,
|
||||
expectedEvents: [{target: XHR, type: "loadstart", optional: false},
|
||||
{target: XHR, type: "progress", optional: false},
|
||||
{target: XHR, type: "abort", optional: false},
|
||||
{target: XHR, type: "loadend", optional: false}]},
|
||||
{ method: "GET", withUpload: large, testAbort: false, testRedirectError: true, testNetworkError: false,
|
||||
@ -261,11 +288,12 @@ var tests =
|
||||
|
||||
{ method: "POST", withUpload: none, testAbort: false, testRedirectError: false, testNetworkError: false,
|
||||
expectedEvents: [{target: XHR, type: "loadstart", optional: false},
|
||||
{target: XHR, type: "progress", optional: true},
|
||||
{target: XHR, type: "progress", optional: false},
|
||||
{target: XHR, type: "load", optional: false},
|
||||
{target: XHR, type: "loadend", optional: false}]},
|
||||
{ method: "POST", withUpload: none, testAbort: true, testRedirectError: false, testNetworkError: false,
|
||||
expectedEvents: [{target: XHR, type: "loadstart", optional: false},
|
||||
{target: XHR, type: "progress", optional: false},
|
||||
{target: XHR, type: "abort", optional: false},
|
||||
{target: XHR, type: "loadend", optional: false}]},
|
||||
{ method: "POST", withUpload: none, testAbort: false, testRedirectError: true, testNetworkError: false,
|
||||
@ -280,101 +308,104 @@ var tests =
|
||||
{ method: "POST", withUpload: small, testAbort: false, testRedirectError: false, testNetworkError: false,
|
||||
expectedEvents: [{target: XHR, type: "loadstart", optional: false},
|
||||
{target: UPLOAD, type: "loadstart", optional: false},
|
||||
{target: UPLOAD, type: "progress", optional: true},
|
||||
{target: UPLOAD, type: "progress", optional: false},
|
||||
{target: UPLOAD, type: "load", optional: false},
|
||||
{target: UPLOAD, type: "loadend", optional: false},
|
||||
{target: XHR, type: "progress", optional: true},
|
||||
{target: XHR, type: "progress", optional: false},
|
||||
{target: XHR, type: "load", optional: false},
|
||||
{target: XHR, type: "loadend", optional: false}]},
|
||||
{ method: "POST", withUpload: small, testAbort: true, testRedirectError: false, testNetworkError: false,
|
||||
expectedEvents: [{target: XHR, type: "loadstart", optional: false},
|
||||
{target: UPLOAD, type: "loadstart", optional: false},
|
||||
{target: XHR, type: "abort", optional: false},
|
||||
{target: XHR, type: "loadend", optional: false},
|
||||
{target: UPLOAD, type: "progress", optional: false},
|
||||
{target: UPLOAD, type: "abort", optional: false},
|
||||
{target: UPLOAD, type: "loadend", optional: false}]},
|
||||
{target: UPLOAD, type: "loadend", optional: false},
|
||||
{target: XHR, type: "progress", optional: false},
|
||||
{target: XHR, type: "abort", optional: false},
|
||||
{target: XHR, type: "loadend", optional: false}]},
|
||||
{ method: "POST", withUpload: small, testAbort: false, testRedirectError: true, testNetworkError: false,
|
||||
expectedEvents: [{target: XHR, type: "loadstart", optional: false},
|
||||
{target: UPLOAD, type: "loadstart", optional: false},
|
||||
{target: UPLOAD, type: "progress", optional: true},
|
||||
{target: XHR, type: "error", optional: false},
|
||||
{target: XHR, type: "loadend", optional: false},
|
||||
{target: UPLOAD, type: "error", optional: false},
|
||||
{target: UPLOAD, type: "loadend", optional: false}]},
|
||||
{target: UPLOAD, type: "loadend", optional: false},
|
||||
{target: XHR, type: "error", optional: false},
|
||||
{target: XHR, type: "loadend", optional: false}]},
|
||||
{ method: "POST", withUpload: small, testAbort: false, testRedirectError: false, testNetworkError: true,
|
||||
expectedEvents: [{target: XHR, type: "loadstart", optional: false},
|
||||
{target: UPLOAD, type: "loadstart", optional: false},
|
||||
{target: UPLOAD, type: "progress", optional: true},
|
||||
{target: XHR, type: "error", optional: false},
|
||||
{target: XHR, type: "loadend", optional: false},
|
||||
{target: UPLOAD, type: "error", optional: false},
|
||||
{target: UPLOAD, type: "loadend", optional: false}]},
|
||||
{target: UPLOAD, type: "loadend", optional: false},
|
||||
{target: XHR, type: "error", optional: false},
|
||||
{target: XHR, type: "loadend", optional: false}]},
|
||||
|
||||
{ method: "POST", withUpload: mid, testAbort: false, testRedirectError: false, testNetworkError: false,
|
||||
expectedEvents: [{target: XHR, type: "loadstart", optional: false},
|
||||
{target: UPLOAD, type: "loadstart", optional: false},
|
||||
{target: UPLOAD, type: "progress", optional: true},
|
||||
{target: UPLOAD, type: "progress", optional: false},
|
||||
{target: UPLOAD, type: "load", optional: false},
|
||||
{target: UPLOAD, type: "loadend", optional: false},
|
||||
{target: XHR, type: "progress", optional: true},
|
||||
{target: XHR, type: "progress", optional: false},
|
||||
{target: XHR, type: "load", optional: false},
|
||||
{target: XHR, type: "loadend", optional: false}]},
|
||||
{ method: "POST", withUpload: mid, testAbort: true, testRedirectError: false, testNetworkError: false,
|
||||
expectedEvents: [{target: XHR, type: "loadstart", optional: false},
|
||||
{target: UPLOAD, type: "loadstart", optional: false},
|
||||
{target: XHR, type: "abort", optional: false},
|
||||
{target: XHR, type: "loadend", optional: false},
|
||||
{target: UPLOAD, type: "progress", optional: false},
|
||||
{target: UPLOAD, type: "abort", optional: false},
|
||||
{target: UPLOAD, type: "loadend", optional: false}]},
|
||||
{target: UPLOAD, type: "loadend", optional: false},
|
||||
{target: XHR, type: "progress", optional: false},
|
||||
{target: XHR, type: "abort", optional: false},
|
||||
{target: XHR, type: "loadend", optional: false}]},
|
||||
{ method: "POST", withUpload: mid, testAbort: false, testRedirectError: true, testNetworkError: false,
|
||||
expectedEvents: [{target: XHR, type: "loadstart", optional: false},
|
||||
{target: UPLOAD, type: "loadstart", optional: false},
|
||||
{target: UPLOAD, type: "progress", optional: true},
|
||||
{target: XHR, type: "error", optional: false},
|
||||
{target: XHR, type: "loadend", optional: false},
|
||||
{target: UPLOAD, type: "error", optional: false},
|
||||
{target: UPLOAD, type: "loadend", optional: false}]},
|
||||
{target: UPLOAD, type: "loadend", optional: false},
|
||||
{target: XHR, type: "error", optional: false},
|
||||
{target: XHR, type: "loadend", optional: false}]},
|
||||
{ method: "POST", withUpload: mid, testAbort: false, testRedirectError: false, testNetworkError: true,
|
||||
expectedEvents: [{target: XHR, type: "loadstart", optional: false},
|
||||
{target: UPLOAD, type: "loadstart", optional: false},
|
||||
{target: UPLOAD, type: "progress", optional: true},
|
||||
{target: XHR, type: "error", optional: false},
|
||||
{target: XHR, type: "loadend", optional: false},
|
||||
{target: UPLOAD, type: "error", optional: false},
|
||||
{target: UPLOAD, type: "loadend", optional: false}]},
|
||||
{target: UPLOAD, type: "loadend", optional: false},
|
||||
{target: XHR, type: "error", optional: false},
|
||||
{target: XHR, type: "loadend", optional: false}]},
|
||||
|
||||
{ method: "POST", withUpload: large, testAbort: false, testRedirectError: false, testNetworkError: false,
|
||||
expectedEvents: [{target: XHR, type: "loadstart", optional: false},
|
||||
{target: UPLOAD, type: "loadstart", optional: false},
|
||||
{target: UPLOAD, type: "progress", optional: true},
|
||||
{target: UPLOAD, type: "progress", optional: false},
|
||||
{target: UPLOAD, type: "load", optional: false},
|
||||
{target: UPLOAD, type: "loadend", optional: false},
|
||||
{target: XHR, type: "progress", optional: true},
|
||||
{target: XHR, type: "progress", optional: false},
|
||||
{target: XHR, type: "load", optional: false},
|
||||
{target: XHR, type: "loadend", optional: false}]},
|
||||
{ method: "POST", withUpload: large, testAbort: true, testRedirectError: false, testNetworkError: false,
|
||||
expectedEvents: [{target: XHR, type: "loadstart", optional: false},
|
||||
{target: UPLOAD, type: "loadstart", optional: false},
|
||||
{target: XHR, type: "abort", optional: false},
|
||||
{target: XHR, type: "loadend", optional: false},
|
||||
{target: UPLOAD, type: "progress", optional: false},
|
||||
{target: UPLOAD, type: "abort", optional: false},
|
||||
{target: UPLOAD, type: "loadend", optional: false}]},
|
||||
{target: UPLOAD, type: "loadend", optional: false},
|
||||
{target: XHR, type: "progress", optional: false},
|
||||
{target: XHR, type: "abort", optional: false},
|
||||
{target: XHR, type: "loadend", optional: false}]},
|
||||
{ method: "POST", withUpload: large, testAbort: false, testRedirectError: true, testNetworkError: false,
|
||||
expectedEvents: [{target: XHR, type: "loadstart", optional: false},
|
||||
{target: UPLOAD, type: "loadstart", optional: false},
|
||||
{target: UPLOAD, type: "progress", optional: true},
|
||||
{target: XHR, type: "error", optional: false},
|
||||
{target: XHR, type: "loadend", optional: false},
|
||||
{target: UPLOAD, type: "error", optional: false},
|
||||
{target: UPLOAD, type: "loadend", optional: false}]},
|
||||
{target: UPLOAD, type: "loadend", optional: false},
|
||||
{target: XHR, type: "error", optional: false},
|
||||
{target: XHR, type: "loadend", optional: false}]},
|
||||
{ method: "POST", withUpload: large, testAbort: false, testRedirectError: false, testNetworkError: true,
|
||||
expectedEvents: [{target: XHR, type: "loadstart", optional: false},
|
||||
{target: UPLOAD, type: "loadstart", optional: false},
|
||||
{target: UPLOAD, type: "progress", optional: true},
|
||||
{target: XHR, type: "error", optional: false},
|
||||
{target: XHR, type: "loadend", optional: false},
|
||||
{target: UPLOAD, type: "error", optional: false},
|
||||
{target: UPLOAD, type: "loadend", optional: false}]},
|
||||
{target: UPLOAD, type: "loadend", optional: false},
|
||||
{target: XHR, type: "error", optional: false},
|
||||
{target: XHR, type: "loadend", optional: false}]},
|
||||
];
|
||||
|
||||
function runTest() {
|
||||
@ -383,7 +414,7 @@ function runTest() {
|
||||
}
|
||||
|
||||
function nextTest() {
|
||||
if (tests.length > 1) {
|
||||
if (tests.length) {
|
||||
setTimeout("runTest()", 0);
|
||||
} else {
|
||||
SimpleTest.finish();
|
||||
|
@ -41,10 +41,6 @@ const unsigned kFirstAxis = 0x30;
|
||||
const unsigned kDesktopUsagePage = 0x1;
|
||||
const unsigned kButtonUsagePage = 0x9;
|
||||
|
||||
// Arbitrary. In practice 10 buttons/6 axes is the near maximum.
|
||||
const unsigned kMaxButtons = 32;
|
||||
const unsigned kMaxAxes = 32;
|
||||
|
||||
// Multiple devices-changed notifications can be sent when a device
|
||||
// is connected, because USB devices consist of multiple logical devices.
|
||||
// Therefore, we wait a bit after receiving one before looking for
|
||||
@ -104,7 +100,8 @@ WindowsGamepadService* MOZ_NON_OWNING_REF gService = nullptr;
|
||||
nsCOMPtr<nsIThread> gMonitorThread = nullptr;
|
||||
static bool sIsShutdown = false;
|
||||
|
||||
struct Gamepad {
|
||||
class Gamepad {
|
||||
public:
|
||||
GamepadType type;
|
||||
|
||||
// Handle to raw input device
|
||||
@ -120,20 +117,38 @@ struct Gamepad {
|
||||
// WindowsGamepadService::mGamepads.
|
||||
int id;
|
||||
|
||||
|
||||
// Information about the physical device.
|
||||
unsigned numAxes;
|
||||
unsigned numButtons;
|
||||
bool hasDpad;
|
||||
HIDP_VALUE_CAPS dpadCaps;
|
||||
|
||||
bool buttons[kMaxButtons];
|
||||
struct {
|
||||
nsTArray<bool> buttons;
|
||||
struct axisValue {
|
||||
HIDP_VALUE_CAPS caps;
|
||||
double value;
|
||||
} axes[kMaxAxes];
|
||||
};
|
||||
nsTArray<axisValue> axes;
|
||||
|
||||
// Used during rescan to find devices that were disconnected.
|
||||
bool present;
|
||||
|
||||
Gamepad(uint32_t aNumAxes,
|
||||
uint32_t aNumButtons,
|
||||
bool aHasDpad,
|
||||
GamepadType aType) :
|
||||
numAxes(aNumAxes),
|
||||
numButtons(aNumButtons),
|
||||
hasDpad(aHasDpad),
|
||||
type(aType),
|
||||
present(true)
|
||||
{
|
||||
buttons.SetLength(numButtons);
|
||||
axes.SetLength(numAxes);
|
||||
}
|
||||
private:
|
||||
Gamepad() {}
|
||||
};
|
||||
|
||||
// Drop this in favor of decltype when we require a new enough SDK.
|
||||
@ -212,7 +227,7 @@ ScaleAxis(ULONG value, LONG min, LONG max)
|
||||
* represent it as 4 buttons, one for each cardinal direction.
|
||||
*/
|
||||
void
|
||||
UnpackDpad(LONG dpad_value, const Gamepad* gamepad, bool buttons[kMaxButtons])
|
||||
UnpackDpad(LONG dpad_value, const Gamepad* gamepad, nsTArray<bool>& buttons)
|
||||
{
|
||||
const unsigned kUp = gamepad->numButtons - 4;
|
||||
const unsigned kDown = gamepad->numButtons - 3;
|
||||
@ -449,13 +464,12 @@ WindowsGamepadService::ScanForXInputDevices()
|
||||
}
|
||||
|
||||
// Not already present, add it.
|
||||
Gamepad gamepad = {};
|
||||
gamepad.type = kXInputGamepad;
|
||||
gamepad.present = true;
|
||||
gamepad.state = state;
|
||||
Gamepad gamepad(kStandardGamepadAxes,
|
||||
kStandardGamepadButtons,
|
||||
true,
|
||||
kXInputGamepad);
|
||||
gamepad.userIndex = i;
|
||||
gamepad.numButtons = kStandardGamepadButtons;
|
||||
gamepad.numAxes = kStandardGamepadAxes;
|
||||
gamepad.state = state;
|
||||
gamepad.id = service->AddGamepad("xinput",
|
||||
GamepadMappingType::Standard,
|
||||
kStandardGamepadButtons,
|
||||
@ -621,8 +635,6 @@ WindowsGamepadService::GetRawGamepad(HANDLE handle)
|
||||
return false;
|
||||
}
|
||||
|
||||
Gamepad gamepad = {};
|
||||
|
||||
// Device name is a mostly-opaque string.
|
||||
if (GetRawInputDeviceInfo(handle, RIDI_DEVICENAME, nullptr, &size) == kRawInputError) {
|
||||
return false;
|
||||
@ -689,12 +701,12 @@ WindowsGamepadService::GetRawGamepad(HANDLE handle)
|
||||
!= HIDP_STATUS_SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
uint32_t numButtons = 0;
|
||||
for (unsigned i = 0; i < count; i++) {
|
||||
// Each buttonCaps is typically a range of buttons.
|
||||
gamepad.numButtons +=
|
||||
numButtons +=
|
||||
buttonCaps[i].Range.UsageMax - buttonCaps[i].Range.UsageMin + 1;
|
||||
}
|
||||
gamepad.numButtons = std::min(gamepad.numButtons, kMaxButtons);
|
||||
|
||||
// Enumerate value caps, which represent axes and d-pads.
|
||||
count = caps.NumberInputValueCaps;
|
||||
@ -706,36 +718,41 @@ WindowsGamepadService::GetRawGamepad(HANDLE handle)
|
||||
}
|
||||
nsTArray<HIDP_VALUE_CAPS> axes;
|
||||
// Sort the axes by usagePage and usage to expose a consistent ordering.
|
||||
bool hasDpad;
|
||||
HIDP_VALUE_CAPS dpadCaps;
|
||||
|
||||
HidValueComparator comparator;
|
||||
for (unsigned i = 0; i < count; i++) {
|
||||
if (valueCaps[i].UsagePage == kDesktopUsagePage
|
||||
&& valueCaps[i].Range.UsageMin == kUsageDpad
|
||||
// Don't know how to handle d-pads that return weird values.
|
||||
&& valueCaps[i].LogicalMax - valueCaps[i].LogicalMin == 7
|
||||
// Can't overflow buttons
|
||||
&& gamepad.numButtons + 4 < kMaxButtons) {
|
||||
&& valueCaps[i].LogicalMax - valueCaps[i].LogicalMin == 7) {
|
||||
// d-pad gets special handling.
|
||||
// Ostensibly HID devices can expose multiple d-pads, but this
|
||||
// doesn't happen in practice.
|
||||
gamepad.hasDpad = true;
|
||||
gamepad.dpadCaps = valueCaps[i];
|
||||
hasDpad = true;
|
||||
dpadCaps = valueCaps[i];
|
||||
// Expose d-pad as 4 additional buttons.
|
||||
gamepad.numButtons += 4;
|
||||
numButtons += 4;
|
||||
} else {
|
||||
axes.InsertElementSorted(valueCaps[i], comparator);
|
||||
}
|
||||
}
|
||||
|
||||
gamepad.numAxes = std::min<size_t>(axes.Length(), kMaxAxes);
|
||||
uint32_t numAxes = axes.Length();
|
||||
|
||||
// Not already present, add it.
|
||||
Gamepad gamepad(numAxes,
|
||||
numButtons,
|
||||
true,
|
||||
kRawInputGamepad);
|
||||
|
||||
gamepad.handle = handle;
|
||||
|
||||
for (unsigned i = 0; i < gamepad.numAxes; i++) {
|
||||
if (i >= kMaxAxes) {
|
||||
break;
|
||||
}
|
||||
gamepad.axes[i].caps = axes[i];
|
||||
}
|
||||
gamepad.type = kRawInputGamepad;
|
||||
gamepad.handle = handle;
|
||||
gamepad.present = true;
|
||||
|
||||
gamepad.id = service->AddGamepad(gamepad_id,
|
||||
GamepadMappingType::_empty,
|
||||
gamepad.numButtons,
|
||||
@ -753,8 +770,8 @@ WindowsGamepadService::HandleRawInput(HRAWINPUT handle)
|
||||
|
||||
RefPtr<GamepadPlatformService> service =
|
||||
GamepadPlatformService::GetParentService();
|
||||
if (service) {
|
||||
return true;
|
||||
if (!service) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// First, get data from the handle
|
||||
@ -798,8 +815,11 @@ WindowsGamepadService::HandleRawInput(HRAWINPUT handle)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool buttons[kMaxButtons] = { false };
|
||||
usageLength = std::min<ULONG>(usageLength, kMaxButtons);
|
||||
nsTArray<bool> buttons(gamepad->numButtons);
|
||||
buttons.SetLength(gamepad->numButtons);
|
||||
// If we don't zero out the buttons array first, sometimes it can reuse values.
|
||||
memset(buttons.Elements(), 0, gamepad->numButtons * sizeof(bool));
|
||||
|
||||
for (unsigned i = 0; i < usageLength; i++) {
|
||||
buttons[usages[i] - 1] = true;
|
||||
}
|
||||
|
@ -1145,6 +1145,7 @@ HTMLInputElement::HTMLInputElement(already_AddRefed<mozilla::dom::NodeInfo>& aNo
|
||||
, mAutocompleteAttrState(nsContentUtils::eAutocompleteAttrState_Unknown)
|
||||
, mDisabledChanged(false)
|
||||
, mValueChanged(false)
|
||||
, mLastValueChangeWasInteractive(false)
|
||||
, mCheckedChanged(false)
|
||||
, mChecked(false)
|
||||
, mHandlingSelectEvent(false)
|
||||
@ -1326,6 +1327,7 @@ HTMLInputElement::Clone(mozilla::dom::NodeInfo* aNodeInfo, nsINode** aResult) co
|
||||
break;
|
||||
}
|
||||
|
||||
it->mLastValueChangeWasInteractive = mLastValueChangeWasInteractive;
|
||||
it.forget(aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
@ -3071,7 +3073,8 @@ HTMLInputElement::SetValueInternal(const nsAString& aValue, uint32_t aFlags)
|
||||
}
|
||||
}
|
||||
if (!mParserCreating) {
|
||||
OnValueChanged(true);
|
||||
OnValueChanged(/* aNotify = */ true,
|
||||
/* aWasInteractiveUserChange = */ false);
|
||||
}
|
||||
// else DoneCreatingElement calls us again once mParserCreating is false
|
||||
}
|
||||
@ -6065,6 +6068,7 @@ HTMLInputElement::Reset()
|
||||
// We should be able to reset all dirty flags regardless of the type.
|
||||
SetCheckedChanged(false);
|
||||
SetValueChanged(false);
|
||||
mLastValueChangeWasInteractive = false;
|
||||
|
||||
switch (GetValueMode()) {
|
||||
case VALUE_MODE_VALUE:
|
||||
@ -6917,9 +6921,10 @@ HTMLInputElement::SetCustomValidity(const nsAString& aError)
|
||||
bool
|
||||
HTMLInputElement::IsTooLong()
|
||||
{
|
||||
if (!MaxLengthApplies() ||
|
||||
!HasAttr(kNameSpaceID_None, nsGkAtoms::maxlength) ||
|
||||
!mValueChanged) {
|
||||
if (!mValueChanged ||
|
||||
!mLastValueChangeWasInteractive ||
|
||||
!MaxLengthApplies() ||
|
||||
!HasAttr(kNameSpaceID_None, nsGkAtoms::maxlength)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -7192,10 +7197,7 @@ HTMLInputElement::HasBadInput() const
|
||||
void
|
||||
HTMLInputElement::UpdateTooLongValidityState()
|
||||
{
|
||||
// TODO: this code will be re-enabled with bug 613016 and bug 613019.
|
||||
#if 0
|
||||
SetValidityState(VALIDITY_STATE_TOO_LONG, IsTooLong());
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
@ -7735,8 +7737,10 @@ HTMLInputElement::InitializeKeyboardEventListeners()
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(void)
|
||||
HTMLInputElement::OnValueChanged(bool aNotify)
|
||||
HTMLInputElement::OnValueChanged(bool aNotify, bool aWasInteractiveUserChange)
|
||||
{
|
||||
mLastValueChangeWasInteractive = aWasInteractiveUserChange;
|
||||
|
||||
UpdateAllValidityStates(aNotify);
|
||||
|
||||
if (HasDirAuto()) {
|
||||
|
@ -229,7 +229,7 @@ public:
|
||||
NS_IMETHOD_(void) UpdatePlaceholderVisibility(bool aNotify) override;
|
||||
NS_IMETHOD_(bool) GetPlaceholderVisibility() override;
|
||||
NS_IMETHOD_(void) InitializeKeyboardEventListeners() override;
|
||||
NS_IMETHOD_(void) OnValueChanged(bool aNotify) override;
|
||||
NS_IMETHOD_(void) OnValueChanged(bool aNotify, bool aWasInteractiveUserChange) override;
|
||||
NS_IMETHOD_(bool) HasCachedSelection() override;
|
||||
|
||||
void GetDisplayFileName(nsAString& aFileName) const;
|
||||
@ -1449,6 +1449,7 @@ protected:
|
||||
nsContentUtils::AutocompleteAttrState mAutocompleteAttrState;
|
||||
bool mDisabledChanged : 1;
|
||||
bool mValueChanged : 1;
|
||||
bool mLastValueChangeWasInteractive : 1;
|
||||
bool mCheckedChanged : 1;
|
||||
bool mChecked : 1;
|
||||
bool mHandlingSelectEvent : 1;
|
||||
|
@ -55,6 +55,7 @@ HTMLTextAreaElement::HTMLTextAreaElement(already_AddRefed<mozilla::dom::NodeInfo
|
||||
FromParser aFromParser)
|
||||
: nsGenericHTMLFormElementWithState(aNodeInfo),
|
||||
mValueChanged(false),
|
||||
mLastValueChangeWasInteractive(false),
|
||||
mHandlingSelect(false),
|
||||
mDoneAddingChildren(!aFromParser),
|
||||
mInhibitStateRestoration(!!(aFromParser & FROM_PARSER_FRAGMENT)),
|
||||
@ -1344,7 +1345,9 @@ HTMLTextAreaElement::SetCustomValidity(const nsAString& aError)
|
||||
bool
|
||||
HTMLTextAreaElement::IsTooLong()
|
||||
{
|
||||
if (!HasAttr(kNameSpaceID_None, nsGkAtoms::maxlength) || !mValueChanged) {
|
||||
if (!mValueChanged ||
|
||||
!mLastValueChangeWasInteractive ||
|
||||
!HasAttr(kNameSpaceID_None, nsGkAtoms::maxlength)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1375,10 +1378,7 @@ HTMLTextAreaElement::IsValueMissing() const
|
||||
void
|
||||
HTMLTextAreaElement::UpdateTooLongValidityState()
|
||||
{
|
||||
// TODO: this code will be re-enabled with bug 613016 and bug 613019.
|
||||
#if 0
|
||||
SetValidityState(VALIDITY_STATE_TOO_LONG, IsTooLong());
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
@ -1525,8 +1525,10 @@ HTMLTextAreaElement::InitializeKeyboardEventListeners()
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(void)
|
||||
HTMLTextAreaElement::OnValueChanged(bool aNotify)
|
||||
HTMLTextAreaElement::OnValueChanged(bool aNotify, bool aWasInteractiveUserChange)
|
||||
{
|
||||
mLastValueChangeWasInteractive = aWasInteractiveUserChange;
|
||||
|
||||
// Update the validity state
|
||||
bool validBefore = IsValid();
|
||||
UpdateTooLongValidityState();
|
||||
|
@ -106,7 +106,7 @@ public:
|
||||
NS_IMETHOD_(void) UpdatePlaceholderVisibility(bool aNotify) override;
|
||||
NS_IMETHOD_(bool) GetPlaceholderVisibility() override;
|
||||
NS_IMETHOD_(void) InitializeKeyboardEventListeners() override;
|
||||
NS_IMETHOD_(void) OnValueChanged(bool aNotify) override;
|
||||
NS_IMETHOD_(void) OnValueChanged(bool aNotify, bool aWasInteractiveUserChange) override;
|
||||
NS_IMETHOD_(bool) HasCachedSelection() override;
|
||||
|
||||
// nsIContent
|
||||
@ -293,6 +293,8 @@ protected:
|
||||
nsCOMPtr<nsIControllers> mControllers;
|
||||
/** Whether or not the value has changed since its default value was given. */
|
||||
bool mValueChanged;
|
||||
/** Whether or not the last change to the value was made interactively by the user. */
|
||||
bool mLastValueChangeWasInteractive;
|
||||
/** Whether or not we are already handling select event. */
|
||||
bool mHandlingSelect;
|
||||
/** Whether or not we are done adding children (always true if not
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "nsIObserver.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsMappedAttributes.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsRuleData.h"
|
||||
@ -73,15 +74,72 @@ static constexpr nsAttrValue::EnumTable kKindTable[] = {
|
||||
// at all is specified, it's treated as "subtitles" in GetKind
|
||||
static constexpr const nsAttrValue::EnumTable* kKindTableInvalidValueDefault = &kKindTable[4];
|
||||
|
||||
class WindowDestroyObserver final : public nsIObserver
|
||||
{
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
public:
|
||||
explicit WindowDestroyObserver(HTMLTrackElement* aElement, uint64_t aWinID)
|
||||
: mTrackElement(aElement)
|
||||
, mInnerID(aWinID)
|
||||
{
|
||||
RegisterWindowDestroyObserver();
|
||||
}
|
||||
void RegisterWindowDestroyObserver()
|
||||
{
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
if (obs) {
|
||||
obs->AddObserver(this, "inner-window-destroyed", false);
|
||||
}
|
||||
}
|
||||
void UnRegisterWindowDestroyObserver()
|
||||
{
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
if (obs) {
|
||||
obs->RemoveObserver(this, "inner-window-destroyed");
|
||||
}
|
||||
mTrackElement = nullptr;
|
||||
}
|
||||
NS_IMETHODIMP Observe(nsISupports *aSubject, const char *aTopic, const char16_t *aData) override
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
if (strcmp(aTopic, "inner-window-destroyed") == 0) {
|
||||
nsCOMPtr<nsISupportsPRUint64> wrapper = do_QueryInterface(aSubject);
|
||||
NS_ENSURE_TRUE(wrapper, NS_ERROR_FAILURE);
|
||||
uint64_t innerID;
|
||||
nsresult rv = wrapper->GetData(&innerID);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (innerID == mInnerID) {
|
||||
if (mTrackElement) {
|
||||
mTrackElement->NotifyShutdown();
|
||||
}
|
||||
UnRegisterWindowDestroyObserver();
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
~WindowDestroyObserver() {};
|
||||
HTMLTrackElement* mTrackElement;
|
||||
uint64_t mInnerID;
|
||||
};
|
||||
NS_IMPL_ISUPPORTS(WindowDestroyObserver, nsIObserver);
|
||||
|
||||
/** HTMLTrackElement */
|
||||
HTMLTrackElement::HTMLTrackElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
|
||||
: nsGenericHTMLElement(aNodeInfo)
|
||||
, mLoadResourceDispatched(false)
|
||||
, mWindowDestroyObserver(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
HTMLTrackElement::~HTMLTrackElement()
|
||||
{
|
||||
if (mWindowDestroyObserver) {
|
||||
mWindowDestroyObserver->UnRegisterWindowDestroyObserver();
|
||||
}
|
||||
NotifyShutdown();
|
||||
}
|
||||
|
||||
NS_IMPL_ELEMENT_CLONE(HTMLTrackElement)
|
||||
@ -263,6 +321,10 @@ HTMLTrackElement::LoadResource()
|
||||
NS_ENSURE_TRUE_VOID(NS_SUCCEEDED(rv));
|
||||
|
||||
mChannel = channel;
|
||||
nsISupports* parentObject = OwnerDoc()->GetParentObject();
|
||||
NS_ENSURE_TRUE_VOID(parentObject);
|
||||
nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(parentObject);
|
||||
mWindowDestroyObserver = new WindowDestroyObserver(this, window->WindowID());
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -371,5 +433,15 @@ HTMLTrackElement::DropChannel()
|
||||
mChannel = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
HTMLTrackElement::NotifyShutdown()
|
||||
{
|
||||
if (mChannel) {
|
||||
mChannel->Cancel(NS_BINDING_ABORTED);
|
||||
}
|
||||
mChannel = nullptr;
|
||||
mListener = nullptr;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
@ -24,6 +24,7 @@ namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class WebVTTListener;
|
||||
class WindowDestroyObserver;
|
||||
|
||||
class HTMLTrackElement final : public nsGenericHTMLElement
|
||||
{
|
||||
@ -113,6 +114,8 @@ public:
|
||||
|
||||
void DropChannel();
|
||||
|
||||
void NotifyShutdown();
|
||||
|
||||
protected:
|
||||
virtual ~HTMLTrackElement();
|
||||
|
||||
@ -136,6 +139,8 @@ protected:
|
||||
private:
|
||||
void DispatchLoadResource();
|
||||
bool mLoadResourceDispatched;
|
||||
|
||||
RefPtr<WindowDestroyObserver> mWindowDestroyObserver;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
@ -2582,34 +2582,6 @@ nsGenericHTMLFormElement::IsLabelable() const
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
void
|
||||
nsGenericHTMLElement::Blur(mozilla::ErrorResult& aError)
|
||||
{
|
||||
if (!ShouldBlur(this)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsIDocument* doc = GetComposedDoc();
|
||||
if (!doc) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsPIDOMWindowOuter* win = doc->GetWindow();
|
||||
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
|
||||
if (win && fm) {
|
||||
aError = fm->ClearFocus(win);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsGenericHTMLElement::Focus(ErrorResult& aError)
|
||||
{
|
||||
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
|
||||
if (fm) {
|
||||
aError = fm->SetFocus(this, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsGenericHTMLElement::Click()
|
||||
{
|
||||
|
@ -51,6 +51,8 @@ class nsGenericHTMLElement : public nsGenericHTMLElementBase,
|
||||
public nsIDOMHTMLElement
|
||||
{
|
||||
public:
|
||||
using Element::SetTabIndex;
|
||||
using Element::Focus;
|
||||
explicit nsGenericHTMLElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
|
||||
: nsGenericHTMLElementBase(aNodeInfo)
|
||||
{
|
||||
@ -103,20 +105,6 @@ public:
|
||||
SetHTMLBoolAttr(nsGkAtoms::hidden, aHidden, aError);
|
||||
}
|
||||
virtual void Click();
|
||||
virtual int32_t TabIndexDefault()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
int32_t TabIndex()
|
||||
{
|
||||
return GetIntAttr(nsGkAtoms::tabindex, TabIndexDefault());
|
||||
}
|
||||
void SetTabIndex(int32_t aTabIndex, mozilla::ErrorResult& aError)
|
||||
{
|
||||
SetHTMLIntAttr(nsGkAtoms::tabindex, aTabIndex, aError);
|
||||
}
|
||||
virtual void Focus(mozilla::ErrorResult& aError);
|
||||
virtual void Blur(mozilla::ErrorResult& aError);
|
||||
void GetAccessKey(nsString& aAccessKey)
|
||||
{
|
||||
GetHTMLAttr(nsGkAtoms::accesskey, aAccessKey);
|
||||
|
@ -169,7 +169,7 @@ public:
|
||||
/**
|
||||
* Callback called whenever the value is changed.
|
||||
*/
|
||||
NS_IMETHOD_(void) OnValueChanged(bool aNotify) = 0;
|
||||
NS_IMETHOD_(void) OnValueChanged(bool aNotify, bool aWasInteractiveUserChange) = 0;
|
||||
|
||||
static const int32_t DEFAULT_COLS = 20;
|
||||
static const int32_t DEFAULT_ROWS = 1;
|
||||
|
@ -978,7 +978,8 @@ nsTextInputListener::EditAction()
|
||||
}
|
||||
|
||||
if (!mSettingValue) {
|
||||
mTxtCtrlElement->OnValueChanged(true);
|
||||
mTxtCtrlElement->OnValueChanged(/* aNotify = */ true,
|
||||
/* aWasInteractiveUserChange = */ true);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@ -2182,7 +2183,8 @@ nsTextEditorState::SetValue(const nsAString& aValue, uint32_t aFlags)
|
||||
// can assume that it's safe to notify.
|
||||
ValueWasChanged(!!mRootNode);
|
||||
|
||||
mTextCtrlElement->OnValueChanged(!!mRootNode);
|
||||
mTextCtrlElement->OnValueChanged(/* aNotify = */ !!mRootNode,
|
||||
/* aWasInteractiveUserChange = */ false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -368,6 +368,7 @@ skip-if = buildapp == 'mulet' # TC: Bug 1144079 - Re-enable Mulet mochitests and
|
||||
skip-if = buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android' # b2g(form control not selected/checked with synthesizeMouse, also fails on Android) b2g-debug(form control not selected/checked with synthesizeMouse, also fails on Android) b2g-desktop(form control not selected/checked with synthesizeMouse, also fails on Android)
|
||||
[test_bug613113.html]
|
||||
skip-if = buildapp == 'b2g' # b2g(bug 587671, need an invalidformsubmit observer) b2g-debug(bug 587671, need an invalidformsubmit observer) b2g-desktop(bug 587671, need an invalidformsubmit observer)
|
||||
[test_bug613019.html]
|
||||
[test_bug613722.html]
|
||||
[test_bug613979.html]
|
||||
[test_bug615595.html]
|
||||
|
58
dom/html/test/test_bug613019.html
Normal file
58
dom/html/test/test_bug613019.html
Normal file
@ -0,0 +1,58 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=613019
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 613019</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=613019">Mozilla Bug 613019</a>
|
||||
<div id="content">
|
||||
<input type="text" maxlength="2" style="width:200px" value="Test">
|
||||
<textarea maxlength="2" style="width:200px">Test</textarea>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
/** Test for Bug 613019 **/
|
||||
|
||||
function testInteractivityOfValidityStates(elem) {
|
||||
// verify that user interactivity is necessary for validity state to apply.
|
||||
is(elem.value, "Test", "Element has incorrect starting value.");
|
||||
is(elem.validity.tooLong, false, "Element should not be tooLong.");
|
||||
|
||||
elem.focus();
|
||||
|
||||
synthesizeKey("VK_BACK_SPACE", {});
|
||||
is(elem.value, "Tes", "Element value was not changed correctly.");
|
||||
is(elem.validity.tooLong, true, "Element should still be tooLong.");
|
||||
|
||||
synthesizeKey("VK_BACK_SPACE", {});
|
||||
is(elem.value, "Te", "Element value was not changed correctly.");
|
||||
is(elem.validity.tooLong, false, "Element should no longer be tooLong.");
|
||||
|
||||
elem.value = "Test";
|
||||
is(elem.validity.tooLong, false,
|
||||
"Element should not be tooLong after non-interactive value change.");
|
||||
}
|
||||
|
||||
function test() {
|
||||
window.getSelection().removeAllRanges();
|
||||
testInteractivityOfValidityStates(document.querySelector("input[type=text]"));
|
||||
testInteractivityOfValidityStates(document.querySelector("textarea"));
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
window.onload = function() {
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
setTimeout(test, 0);
|
||||
};
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -164,7 +164,7 @@
|
||||
#endif
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
#include "nsIAccessibilityService.h"
|
||||
#include "nsAccessibilityService.h"
|
||||
#endif
|
||||
|
||||
#ifndef MOZ_SIMPLEPUSH
|
||||
@ -2469,8 +2469,7 @@ ContentChild::RecvActivateA11y()
|
||||
#ifdef ACCESSIBILITY
|
||||
// Start accessibility in content process if it's running in chrome
|
||||
// process.
|
||||
nsCOMPtr<nsIAccessibilityService> accService =
|
||||
services::GetAccessibilityService();
|
||||
GetOrCreateAccService();
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
@ -89,6 +89,7 @@ NS_IMETHODIMP
|
||||
WebVTTListener::OnStartRequest(nsIRequest* aRequest,
|
||||
nsISupports* aContext)
|
||||
{
|
||||
VTT_LOG("WebVTTListener::OnStartRequest\n");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -97,6 +98,7 @@ WebVTTListener::OnStopRequest(nsIRequest* aRequest,
|
||||
nsISupports* aContext,
|
||||
nsresult aStatus)
|
||||
{
|
||||
VTT_LOG("WebVTTListener::OnStopRequest\n");
|
||||
if (NS_FAILED(aStatus)) {
|
||||
mElement->SetReadyState(TextTrackReadyState::FailedToLoad);
|
||||
}
|
||||
@ -136,6 +138,7 @@ WebVTTListener::OnDataAvailable(nsIRequest* aRequest,
|
||||
uint64_t aOffset,
|
||||
uint32_t aCount)
|
||||
{
|
||||
VTT_LOG("WebVTTListener::OnDataAvailable\n");
|
||||
uint32_t count = aCount;
|
||||
while (count > 0) {
|
||||
uint32_t read;
|
||||
|
@ -304,7 +304,7 @@ D3D9DXVA2Manager::Init(nsACString& aFailureReason)
|
||||
D3DPRESENT_PARAMETERS params = {0};
|
||||
params.BackBufferWidth = 1;
|
||||
params.BackBufferHeight = 1;
|
||||
params.BackBufferFormat = D3DFMT_UNKNOWN;
|
||||
params.BackBufferFormat = D3DFMT_A8R8G8B8;
|
||||
params.BackBufferCount = 1;
|
||||
params.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
||||
params.hDeviceWindow = nullptr;
|
||||
|
@ -89,13 +89,13 @@ class VideoPuppeteer(object):
|
||||
self.video = videos_found[0]
|
||||
self.marionette.execute_script("log('video element obtained');")
|
||||
if autostart:
|
||||
self.start();
|
||||
self.start()
|
||||
|
||||
def start(self):
|
||||
# To get an accurate expected_duration, playback must have started
|
||||
wait = Wait(self, timeout=self.timeout)
|
||||
verbose_until(wait, self, lambda v: v.current_time > 0,
|
||||
"Check if video current_time > 0")
|
||||
verbose_until(wait, self, playback_started,
|
||||
"Check if video has played some range")
|
||||
self._start_time = self.current_time
|
||||
self._start_wall_time = clock()
|
||||
self.update_expected_duration()
|
||||
@ -173,6 +173,20 @@ class VideoPuppeteer(object):
|
||||
"""
|
||||
return self.expected_duration - self.current_time
|
||||
|
||||
@property
|
||||
def played(self):
|
||||
"""
|
||||
:return: A TimeRanges objected containing the played time ranges.
|
||||
"""
|
||||
raw_time_ranges = self.execute_video_script(
|
||||
'var played = arguments[0].wrappedJSObject.played;'
|
||||
'var timeRanges = [];'
|
||||
'for (var i = 0; i < played.length; i++) {'
|
||||
'timeRanges.push([played.start(i), played.end(i)]);'
|
||||
'}'
|
||||
'return [played.length, timeRanges];')
|
||||
return TimeRanges(raw_time_ranges[0], raw_time_ranges[1])
|
||||
|
||||
@property
|
||||
def video_src(self):
|
||||
"""
|
||||
@ -277,6 +291,26 @@ class VideoException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class TimeRanges:
|
||||
"""
|
||||
Class to represent the TimeRanges data returned by played(). Exposes a
|
||||
similar interface to the JavaScript TimeRanges object.
|
||||
"""
|
||||
def __init__(self, length, ranges):
|
||||
self.length = length
|
||||
self.ranges = [(pair[0], pair[1]) for pair in ranges]
|
||||
|
||||
def __repr__(self):
|
||||
return 'TimeRanges: length: {}, ranges: {}'\
|
||||
.format(self.length, self.ranges)
|
||||
|
||||
def start(self, index):
|
||||
return self.ranges[index][0]
|
||||
|
||||
def end(self, index):
|
||||
return self.ranges[index][1]
|
||||
|
||||
|
||||
def playback_started(video):
|
||||
"""
|
||||
Determine if video has started
|
||||
@ -286,9 +320,12 @@ def playback_started(video):
|
||||
:return: True if is playing; False otherwise
|
||||
"""
|
||||
try:
|
||||
return video.current_time > video._start_time
|
||||
played_ranges = video.played
|
||||
return played_ranges.length > 0 and \
|
||||
played_ranges.start(0) < played_ranges.end(0) and \
|
||||
played_ranges.end(0) > 0.0
|
||||
except Exception as e:
|
||||
print ('Got exception %s' % e)
|
||||
print ('Got exception {}'.format(e))
|
||||
return False
|
||||
|
||||
|
||||
|
@ -23,8 +23,8 @@ class TestBasicYouTubePlayback(MediaTestCase):
|
||||
interval=1)
|
||||
try:
|
||||
verbose_until(wait, youtube,
|
||||
lambda y: y.video_src.startswith('mediasource'),
|
||||
"Failed to find 'mediasource' in video src url.")
|
||||
lambda y: y.video_src.startswith('blob'),
|
||||
"Failed to find 'blob' in video src url.")
|
||||
except TimeoutException as e:
|
||||
raise self.failureException(e)
|
||||
|
||||
|
2
dom/media/test/external/requirements.txt
vendored
2
dom/media/test/external/requirements.txt
vendored
@ -17,4 +17,4 @@ mozversion==1.4
|
||||
wptserve==1.3.0
|
||||
marionette-client==3.1.0
|
||||
marionette-driver==2.0.0
|
||||
firefox-puppeteer >= 50.0.0, <51.0.0
|
||||
firefox-puppeteer >= 51.0.0, <52.0.0
|
||||
|
@ -25,7 +25,7 @@ support-files =
|
||||
|
||||
[test_a_noOp.html]
|
||||
[test_dataChannel_basicAudio.html]
|
||||
skip-if = toolkit == 'gonk' || buildapp == 'mulet' # Bug 962984 for debug, bug 963244 for opt
|
||||
skip-if = toolkit == 'gonk' || buildapp == 'mulet' || (android_version == '18' && debug) # Bug 962984 for debug, bug 963244 for opt
|
||||
[test_dataChannel_basicAudioVideo.html]
|
||||
skip-if = toolkit == 'gonk' || buildapp == 'mulet' || android_version == '18' # b2g(Bug 960442, video support for WebRTC is disabled on b2g), android(Bug 1189784, timeouts on 4.3 emulator)
|
||||
[test_dataChannel_basicAudioVideoNoBundle.html]
|
||||
@ -85,7 +85,7 @@ skip-if = (toolkit == 'gonk' || buildapp == 'mulet' && debug) # copied from basi
|
||||
skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g(Bug 1021776, too --ing slow on b2g)
|
||||
[test_peerConnection_addIceCandidate.html]
|
||||
[test_peerConnection_addtrack_removetrack_events.html]
|
||||
skip-if = toolkit == 'gonk' || buildapp == 'mulet' || (android_version == '18' && debug) # b2g(Bug 960442, video support for WebRTC is disabled on b2g), android(Bug 1189784, timeouts on 4.3 emulator)
|
||||
skip-if = toolkit == 'gonk' || buildapp == 'mulet' || android_version == '18' # b2g(Bug 960442, video support for WebRTC is disabled on b2g), android(Bug 1189784, timeouts on 4.3 emulator)
|
||||
[test_peerConnection_basicAudio.html]
|
||||
skip-if = toolkit == 'gonk' # B2G emulator is too slow to handle a two-way audio call reliably
|
||||
[test_peerConnection_basicAudioNATSrflx.html]
|
||||
@ -204,9 +204,9 @@ skip-if = toolkit == 'gonk' || buildapp == 'mulet' || (android_version == '18' &
|
||||
skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
|
||||
[test_peerConnection_toJSON.html]
|
||||
[test_peerConnection_trackDisabling_clones.html]
|
||||
skip-if = toolkit == 'gonk' || buildapp == 'mulet' || (android_version == '18' && debug) # b2g(Bug 960442, video support for WebRTC is disabled on b2g), android(Bug 1189784, timeouts on 4.3 emulator)
|
||||
skip-if = toolkit == 'gonk' || buildapp == 'mulet' || android_version == '18' # b2g(Bug 960442, video support for WebRTC is disabled on b2g), android(Bug 1189784, timeouts on 4.3 emulator)
|
||||
[test_peerConnection_trackDisabling.html]
|
||||
skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
|
||||
skip-if = toolkit == 'gonk' || buildapp == 'mulet' || android_version == '18' # b2g(Bug 960442, video support for WebRTC is disabled on b2g), android(Bug 1189784, timeouts on 4.3 emulator)
|
||||
[test_peerConnection_twoAudioStreams.html]
|
||||
skip-if = toolkit == 'gonk' || buildapp == 'mulet' || (android_version == '18' && debug) # b2g (Bug 1059867), android(Bug 1189784, timeouts on 4.3 emulator)
|
||||
[test_peerConnection_twoAudioTracksInOneStream.html]
|
||||
@ -227,13 +227,13 @@ skip-if = toolkit == 'gonk' || buildapp == 'mulet' || os == "android"
|
||||
# B2G emulator is too slow to finish a renegotiation test in under 5 minutes, android(Bug 1189784, timeouts on 4.3 emulator)
|
||||
skip-if = toolkit == 'gonk' || (android_version == '18' && debug)
|
||||
[test_peerConnection_addSecondAudioStream.html]
|
||||
skip-if = toolkit == 'gonk' # B2G emulator is too slow to finish a renegotiation test in under 5 minutes
|
||||
skip-if = toolkit == 'gonk' || (android_version == '18' && debug) # emulator is too slow to finish a renegotiation test in under 5 minutes
|
||||
[test_peerConnection_answererAddSecondAudioStream.html]
|
||||
skip-if = toolkit == 'gonk' # B2G emulator is too slow to finish a renegotiation test in under 5 minutes
|
||||
skip-if = toolkit == 'gonk' || (android_version == '18' && debug) # emulator is too slow to finish a renegotiation test in under 5 minutes
|
||||
[test_peerConnection_removeAudioTrack.html]
|
||||
skip-if = toolkit == 'gonk' || (android_version == '18' && debug) # B2G emulator is too slow to finish a renegotiation test in under 5 minutes, android(Bug 1189784, timeouts on 4.3 emulator)
|
||||
skip-if = toolkit == 'gonk' || (android_version == '18' && debug) # emulator is too slow to finish a renegotiation test in under 5 minutes, android(Bug 1189784, timeouts on 4.3 emulator)
|
||||
[test_peerConnection_removeThenAddAudioTrack.html]
|
||||
skip-if = toolkit == 'gonk' || (android_version == '18' && debug) # B2G emulator is too slow to finish a renegotiation test in under 5 minutes, android(Bug 1189784, timeouts on 4.3 emulator)
|
||||
skip-if = toolkit == 'gonk' || (android_version == '18' && debug) # emulator is too slow to finish a renegotiation test in under 5 minutes, android(Bug 1189784, timeouts on 4.3 emulator)
|
||||
[test_peerConnection_addSecondVideoStream.html]
|
||||
# B2G emulator is too slow to finish a renegotiation test in under 5 minutes, Bug 1180000 for Linux debug e10s, android(Bug 1189784, timeouts on 4.3 emulator)
|
||||
skip-if = toolkit == 'gonk' || android_version == '18'
|
||||
@ -257,12 +257,12 @@ skip-if = toolkit == 'gonk' || android_version == '18'
|
||||
# B2G emulator is too slow to finish a renegotiation test in under 5 minutes, Bug 1180000 for Linux debug e10s, android(Bug 1189784, timeouts on 4.3 emulator)
|
||||
skip-if = toolkit == 'gonk' || android_version == '18'
|
||||
[test_peerConnection_addDataChannel.html]
|
||||
skip-if = toolkit == 'gonk' # B2G emulator seems to be so slow that DTLS cannot establish properly
|
||||
skip-if = toolkit == 'gonk' || (android_version == '18' && debug) # emulator seems to be so slow that DTLS cannot establish properly, android(bug 1240256, intermittent ICE failures starting w/bug 1232082, possibly from timeout)
|
||||
[test_peerConnection_addDataChannelNoBundle.html]
|
||||
# b2g(Bug 960442, video support for WebRTC is disabled on b2g), android(Bug 1189784, timeouts on 4.3 emulator)
|
||||
skip-if = toolkit == 'gonk' || (android_version == '18' && debug) # b2g(emulator seems to be so slow that DTLS cannot establish properly), android(bug 1240256, intermittent ICE failures starting w/bug 1232082, possibly from timeout)
|
||||
[test_peerConnection_verifyAudioAfterRenegotiation.html]
|
||||
skip-if = toolkit == 'gonk' || (android_version == '18' && debug) # B2G emulator is too slow to finish a renegotiation test in under 5 minutes, android(Bug 1189784, timeouts on 4.3 emulator)
|
||||
skip-if = toolkit == 'gonk' || android_version == '18' # B2G emulator is too slow to finish a renegotiation test in under 5 minutes, android(Bug 1189784, timeouts on 4.3 emulator)
|
||||
[test_peerConnection_verifyVideoAfterRenegotiation.html]
|
||||
# B2G emulator is too slow to finish a renegotiation test in under 5 minutes, Bug 1180000 for Linux debug e10s, android(Bug 1189784, timeouts on 4.3 emulator)
|
||||
skip-if = toolkit == 'gonk' || android_version == '18'
|
||||
@ -274,7 +274,7 @@ skip-if = toolkit == 'gonk' || android_version == '18'
|
||||
skip-if = toolkit == 'gonk' || android_version == '18'
|
||||
[test_peerConnection_webAudio.html]
|
||||
tags = webaudio webrtc
|
||||
skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g (Bug 1059867)
|
||||
skip-if = toolkit == 'gonk' || buildapp == 'mulet' || android_version == '18' # b2g (Bug 1059867), android(Bug 1189784, timeouts on 4.3 emulator)
|
||||
[test_peerConnection_localRollback.html]
|
||||
skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g (Bug 1059867)
|
||||
[test_peerConnection_localReofferRollback.html]
|
||||
@ -282,7 +282,7 @@ skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g (Bug 1059867)
|
||||
[test_peerConnection_remoteRollback.html]
|
||||
skip-if = toolkit == 'gonk' || (android_version == '18' && debug) # b2g (Bug 1059867), android(Bug 1189784, timeouts on 4.3 emulator)
|
||||
[test_peerConnection_remoteReofferRollback.html]
|
||||
skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g (Bug 1059867)
|
||||
skip-if = toolkit == 'gonk' || buildapp == 'mulet' || (android_version == '18' && debug) # b2g (Bug 1059867), android(Bug 1189784, timeouts on 4.3 emulator)
|
||||
[test_selftest.html]
|
||||
# Bug 1227781: Crash with bogus TURN server.
|
||||
[test_peerConnection_bug1227781.html]
|
||||
|
@ -1460,10 +1460,10 @@ PeerConnectionWrapper.prototype = {
|
||||
|
||||
info("Checking RTP packet flow for track " + track.id);
|
||||
|
||||
var retry = () => this._pc.getStats(track)
|
||||
var retry = (delay) => this._pc.getStats(track)
|
||||
.then(stats => hasFlow(stats)? ok(true, "RTP flowing for track " + track.id) :
|
||||
wait(200).then(retry));
|
||||
return retry();
|
||||
wait(delay).then(retry(1000)));
|
||||
return retry(200);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -125,9 +125,6 @@ MediaEngineWebRTC::MediaEngineWebRTC(MediaEnginePrefs &aPrefs)
|
||||
#endif
|
||||
// XXX
|
||||
gFarendObserver = new AudioOutputObserver();
|
||||
|
||||
NS_NewNamedThread("AudioGUM", getter_AddRefs(mThread));
|
||||
MOZ_ASSERT(mThread);
|
||||
}
|
||||
|
||||
void
|
||||
@ -409,7 +406,7 @@ MediaEngineWebRTC::EnumerateAudioDevices(dom::MediaSourceEnum aMediaSource,
|
||||
// XXX Small window where the device list/index could change!
|
||||
audioinput = new mozilla::AudioInputCubeb(mVoiceEngine, i);
|
||||
}
|
||||
aSource = new MediaEngineWebRTCMicrophoneSource(mThread, mVoiceEngine, audioinput,
|
||||
aSource = new MediaEngineWebRTCMicrophoneSource(mVoiceEngine, audioinput,
|
||||
i, deviceName, uniqueId);
|
||||
mAudioSources.Put(uuid, aSource); // Hashtable takes ownership.
|
||||
aASources->AppendElement(aSource);
|
||||
@ -450,11 +447,6 @@ MediaEngineWebRTC::Shutdown()
|
||||
|
||||
mozilla::camera::Shutdown();
|
||||
AudioInputCubeb::CleanupGlobalData();
|
||||
|
||||
if (mThread) {
|
||||
mThread->Shutdown();
|
||||
mThread = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -419,8 +419,7 @@ class MediaEngineWebRTCMicrophoneSource : public MediaEngineAudioSource,
|
||||
{
|
||||
typedef MediaEngineAudioSource Super;
|
||||
public:
|
||||
MediaEngineWebRTCMicrophoneSource(nsIThread* aThread,
|
||||
webrtc::VoiceEngine* aVoiceEnginePtr,
|
||||
MediaEngineWebRTCMicrophoneSource(webrtc::VoiceEngine* aVoiceEnginePtr,
|
||||
mozilla::AudioInput* aAudioInput,
|
||||
int aIndex,
|
||||
const char* name,
|
||||
@ -543,7 +542,6 @@ private:
|
||||
nsTArray<RefPtr<SourceMediaStream>> mSources;
|
||||
nsTArray<PrincipalHandle> mPrincipalHandles; // Maps to mSources.
|
||||
|
||||
nsCOMPtr<nsIThread> mThread;
|
||||
int mCapIndex;
|
||||
int mChannel;
|
||||
TrackID mTrackID;
|
||||
|
@ -184,7 +184,6 @@ AudioOutputObserver::InsertFarEnd(const AudioDataValue *aBuffer, uint32_t aFrame
|
||||
}
|
||||
|
||||
MediaEngineWebRTCMicrophoneSource::MediaEngineWebRTCMicrophoneSource(
|
||||
nsIThread* aThread,
|
||||
webrtc::VoiceEngine* aVoiceEnginePtr,
|
||||
mozilla::AudioInput* aAudioInput,
|
||||
int aIndex,
|
||||
@ -194,7 +193,6 @@ MediaEngineWebRTCMicrophoneSource::MediaEngineWebRTCMicrophoneSource(
|
||||
, mVoiceEngine(aVoiceEnginePtr)
|
||||
, mAudioInput(aAudioInput)
|
||||
, mMonitor("WebRTCMic.Monitor")
|
||||
, mThread(aThread)
|
||||
, mCapIndex(aIndex)
|
||||
, mChannel(-1)
|
||||
, mStarted(false)
|
||||
@ -616,11 +614,7 @@ MediaEngineWebRTCMicrophoneSource::InsertInGraph(const T* aBuffer,
|
||||
mPrincipalHandles[i]);
|
||||
segment->GetStartTime(insertTime);
|
||||
|
||||
RUN_ON_THREAD(mThread,
|
||||
WrapRunnable(mSources[i], &SourceMediaStream::AppendToTrack,
|
||||
mTrackID, segment,
|
||||
static_cast<AudioSegment*>(nullptr)),
|
||||
NS_DISPATCH_NORMAL);
|
||||
mSources[i]->AppendToTrack(mTrackID, segment);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -954,8 +954,9 @@ PluginInstanceParent::RecvShow(const NPRect& updatedRect,
|
||||
updatedRect.bottom - updatedRect.top);
|
||||
surface->MarkDirty(ur);
|
||||
|
||||
bool isPlugin = true;
|
||||
RefPtr<gfx::SourceSurface> sourceSurface =
|
||||
gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(nullptr, surface);
|
||||
gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(nullptr, surface, isPlugin);
|
||||
RefPtr<SourceSurfaceImage> image = new SourceSurfaceImage(surface->GetSize(), sourceSurface);
|
||||
|
||||
AutoTArray<ImageContainer::NonOwningImage,1> imageList;
|
||||
|
@ -992,7 +992,7 @@ Promise::PerformMicroTaskCheckpoint()
|
||||
return false;
|
||||
}
|
||||
|
||||
AutoSafeJSContext cx;
|
||||
AutoSlowOperation aso;
|
||||
|
||||
do {
|
||||
nsCOMPtr<nsIRunnable> runnable = microtaskQueue.front().forget();
|
||||
@ -1004,7 +1004,7 @@ Promise::PerformMicroTaskCheckpoint()
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return false;
|
||||
}
|
||||
JS_CheckForInterrupt(cx);
|
||||
aso.CheckForInterrupt();
|
||||
runtime->AfterProcessMicrotask();
|
||||
} while (!microtaskQueue.empty());
|
||||
|
||||
|
@ -759,8 +759,10 @@ function runTest() {
|
||||
"wrong responseXML in test for " + test.toSource());
|
||||
is(res.responseText, "",
|
||||
"wrong responseText in test for " + test.toSource());
|
||||
var expectedProgressCount = 0;
|
||||
if (!res.sendThrew) {
|
||||
if (test.username) {
|
||||
expectedProgressCount = 1;
|
||||
is(res.events.join(","),
|
||||
"opening,rs1,sending,loadstart,rs4,error,loadend",
|
||||
"wrong events in test for " + test.toSource());
|
||||
@ -770,7 +772,7 @@ function runTest() {
|
||||
"wrong events in test for " + test.toSource());
|
||||
}
|
||||
}
|
||||
is(res.progressEvents, 0,
|
||||
is(res.progressEvents, expectedProgressCount,
|
||||
"wrong events in test for " + test.toSource());
|
||||
if (test.responseHeaders) {
|
||||
for (header in test.responseHeaders) {
|
||||
|
@ -154,12 +154,12 @@ var _fromToTestLists = {
|
||||
],
|
||||
URIsAndNone: [
|
||||
new AnimTestcaseFromTo("url(#idA)", "url(#idB)",
|
||||
{ fromComp: "url(\"" + document.URL + "#idA\")",
|
||||
toComp: "url(\"" + document.URL + "#idB\")"}),
|
||||
{ fromComp: "url(\"#idA\")",
|
||||
toComp: "url(\"#idB\")"}),
|
||||
new AnimTestcaseFromTo("none", "url(#idB)",
|
||||
{ toComp: "url(\"" + document.URL + "#idB\")"}),
|
||||
{ toComp: "url(\"#idB\")"}),
|
||||
new AnimTestcaseFromTo("url(#idB)", "inherit",
|
||||
{ fromComp: "url(\"" + document.URL + "#idB\")",
|
||||
{ fromComp: "url(\"#idB\")",
|
||||
toComp: "none"}),
|
||||
],
|
||||
};
|
||||
|
@ -194,6 +194,9 @@ SVGAElement::IsFocusableInternal(int32_t *aTabIndex, bool aWithMouse)
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (nsSVGElement::IsFocusableInternal(aTabIndex, aWithMouse)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (aTabIndex) {
|
||||
*aTabIndex = -1;
|
||||
|
@ -610,6 +610,9 @@ nsSVGElement::ParseAttribute(int32_t aNamespaceID,
|
||||
didSetResult = true;
|
||||
}
|
||||
foundMatch = true;
|
||||
} else if (aAttribute == nsGkAtoms::tabindex) {
|
||||
didSetResult = aResult.ParseIntValue(aValue);
|
||||
foundMatch = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1120,6 +1123,19 @@ nsSVGElement::ClassName()
|
||||
return mClassAttribute.ToDOMAnimatedString(this);
|
||||
}
|
||||
|
||||
bool
|
||||
nsSVGElement::IsFocusableInternal(int32_t* aTabIndex, bool)
|
||||
{
|
||||
int32_t index = TabIndex();
|
||||
|
||||
if (index == -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*aTabIndex = index;
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Helper class: MappedAttrParser, for parsing values of mapped attributes
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user