This commit is contained in:
Richard Newman 2012-11-27 21:24:41 -08:00
Родитель 202b8e6595 de8060e941
Коммит 311ea9597c
397 изменённых файлов: 12962 добавлений и 5377 удалений

Просмотреть файл

@ -34,6 +34,7 @@ SHARED_LIBRARY_LIBS = \
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
SHARED_LIBRARY_LIBS += \
../src/windows/ia2/$(LIB_PREFIX)accessibility_toolkit_ia2_s.$(LIB_SUFFIX) \
../src/windows/sdn/$(LIB_PREFIX)accessibility_toolkit_sdn_s.$(LIB_SUFFIX) \
../src/windows/uia/$(LIB_PREFIX)accessibility_toolkit_uia_s.$(LIB_SUFFIX) \
$(NULL)
endif

Просмотреть файл

@ -901,26 +901,9 @@ nsAccessibilityService::GetOrCreateAccessible(nsINode* aNode,
newAcc = CreateHTMLAccessibleByMarkup(frame, content, aDoc,
legalPartOfHTMLTable);
if (!newAcc && (!partOfHTMLTable || legalPartOfHTMLTable)) {
// Do not create accessible object subtrees for non-rendered table
// captions. This could not be done in
// nsTableCaptionFrame::GetAccessible() because the descendants of
// the table caption would still be created. By setting
// *aIsSubtreeHidden = true we ensure that no descendant accessibles
// are created.
if (frame->GetType() == nsGkAtoms::tableCaptionFrame &&
frame->GetRect().IsEmpty()) {
// XXX This is not the ideal place for this code, but right now there
// is no better place:
if (aIsSubtreeHidden)
*aIsSubtreeHidden = true;
return nullptr;
}
// Try using frame to do it.
// Try using frame to do it.
if (!newAcc && (!partOfHTMLTable || legalPartOfHTMLTable))
newAcc = CreateAccessibleByFrameType(frame, content, aDoc);
}
}
}

Просмотреть файл

@ -54,22 +54,7 @@ nsAccessiblePivot::nsAccessiblePivot(Accessible* aRoot) :
////////////////////////////////////////////////////////////////////////////////
// nsISupports
NS_IMPL_CYCLE_COLLECTION_CLASS(nsAccessiblePivot)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsAccessiblePivot)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRoot)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPosition)
uint32_t i, length = tmp->mObservers.Length();
for (i = 0; i < length; ++i) {
cb.NoteXPCOMChild(tmp->mObservers[i]);
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsAccessiblePivot)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mRoot)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mPosition)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mObservers)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_3(nsAccessiblePivot, mRoot, mPosition, mObservers)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsAccessiblePivot)
NS_INTERFACE_MAP_ENTRY(nsIAccessiblePivot)

Просмотреть файл

@ -17,6 +17,7 @@
#include "Relation.h"
#include "Role.h"
#include "RootAccessible.h"
#include "sdnAccessible.h"
#include "States.h"
#include "uiaRawElmProvider.h"
@ -93,6 +94,12 @@ __try {
*ppv = static_cast<IServiceProvider*>(this);
else if (IID_IAccessible2 == iid && !Compatibility::IsIA2Off())
*ppv = static_cast<IAccessible2*>(this);
else if (IID_ISimpleDOMNode == iid) {
if (IsDefunct() || !HasOwnContent() && !IsDoc())
return E_NOINTERFACE;
*ppv = new sdnAccessible(GetNode());
}
if (NULL == *ppv) {
HRESULT hr = ia2AccessibleComponent::QueryInterface(iid, ppv);
@ -113,7 +120,7 @@ __try {
}
if (NULL == *ppv)
return nsAccessNodeWrap::QueryInterface(iid, ppv);
return E_NOINTERFACE;
(reinterpret_cast<IUnknown*>(*ppv))->AddRef();
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }

Просмотреть файл

@ -67,6 +67,7 @@ LOCAL_INCLUDES += \
-I$(srcdir)/../xpcom \
-I$(srcdir)/../xul \
-I$(srcdir)/../windows/ia2 \
-I$(srcdir)/../windows/sdn \
-I$(srcdir)/../windows/uia \
-I$(srcdir)/../../../content/base/src \
-I$(srcdir)/../../../content/events/src \

Просмотреть файл

@ -7,7 +7,7 @@
#include "AccessibleApplication.h"
#include "ApplicationAccessibleWrap.h"
#include "ISimpleDOMNode_i.c"
#include "sdnAccessible.h"
#include "Compatibility.h"
#include "nsAccessibilityService.h"
@ -60,24 +60,17 @@ nsAccessNodeWrap::QueryNativeInterface(REFIID aIID, void** aInstancePtr)
return static_cast<nsresult>(QueryInterface(aIID, aInstancePtr));
}
//-----------------------------------------------------
// IUnknown interface methods - see iunknown.h for documentation
//-----------------------------------------------------
STDMETHODIMP nsAccessNodeWrap::QueryInterface(REFIID iid, void** ppv)
{
*ppv = nullptr;
if (IID_IUnknown == iid) {
*ppv = static_cast<ISimpleDOMNode*>(this);
} else if (IID_ISimpleDOMNode == iid) {
statistics::ISimpleDOMUsed();
*ppv = static_cast<ISimpleDOMNode*>(this);
*ppv = static_cast<IUnknown*>(this);
} else {
return E_NOINTERFACE; //iid not supported.
return E_NOINTERFACE; //iid not supported.
}
(reinterpret_cast<IUnknown*>(*ppv))->AddRef();
(reinterpret_cast<IUnknown*>(*ppv))->AddRef();
return S_OK;
}
@ -161,389 +154,6 @@ nsAccessNodeWrap::QueryService(REFGUID guidService, REFIID iid, void** ppv)
return E_INVALIDARG;
}
//-----------------------------------------------------
// ISimpleDOMNode methods
//-----------------------------------------------------
STDMETHODIMP nsAccessNodeWrap::get_nodeInfo(
/* [out] */ BSTR __RPC_FAR *aNodeName,
/* [out] */ short __RPC_FAR *aNameSpaceID,
/* [out] */ BSTR __RPC_FAR *aNodeValue,
/* [out] */ unsigned int __RPC_FAR *aNumChildren,
/* [out] */ unsigned int __RPC_FAR *aUniqueID,
/* [out] */ unsigned short __RPC_FAR *aNodeType)
{
__try{
*aNodeName = nullptr;
*aNodeValue = nullptr;
nsINode* node = GetNode();
if (!node)
return E_FAIL;
nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(node));
uint16_t nodeType = 0;
DOMNode->GetNodeType(&nodeType);
*aNodeType=static_cast<unsigned short>(nodeType);
if (*aNodeType != NODETYPE_TEXT) {
nsAutoString nodeName;
DOMNode->GetNodeName(nodeName);
*aNodeName = ::SysAllocString(nodeName.get());
}
nsAutoString nodeValue;
DOMNode->GetNodeValue(nodeValue);
*aNodeValue = ::SysAllocString(nodeValue.get());
*aNameSpaceID = IsContent() ?
static_cast<short>(mContent->GetNameSpaceID()) : 0;
// This is a unique ID for every content node. The 3rd party
// accessibility application can compare this to the childID we
// return for events such as focus events, to correlate back to
// data nodes in their internal object model.
*aUniqueID = - NS_PTR_TO_INT32(UniqueID());
*aNumChildren = node->GetChildCount();
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
return S_OK;
}
STDMETHODIMP nsAccessNodeWrap::get_attributes(
/* [in] */ unsigned short aMaxAttribs,
/* [length_is][size_is][out] */ BSTR __RPC_FAR *aAttribNames,
/* [length_is][size_is][out] */ short __RPC_FAR *aNameSpaceIDs,
/* [length_is][size_is][out] */ BSTR __RPC_FAR *aAttribValues,
/* [out] */ unsigned short __RPC_FAR *aNumAttribs)
{
__try{
*aNumAttribs = 0;
if (!mContent || IsDocumentNode())
return E_FAIL;
uint32_t numAttribs = mContent->GetAttrCount();
if (numAttribs > aMaxAttribs)
numAttribs = aMaxAttribs;
*aNumAttribs = static_cast<unsigned short>(numAttribs);
for (uint32_t index = 0; index < numAttribs; index++) {
aNameSpaceIDs[index] = 0; aAttribValues[index] = aAttribNames[index] = nullptr;
nsAutoString attributeValue;
const nsAttrName* name = mContent->GetAttrNameAt(index);
aNameSpaceIDs[index] = static_cast<short>(name->NamespaceID());
aAttribNames[index] = ::SysAllocString(name->LocalName()->GetUTF16String());
mContent->GetAttr(name->NamespaceID(), name->LocalName(), attributeValue);
aAttribValues[index] = ::SysAllocString(attributeValue.get());
}
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
return S_OK;
}
STDMETHODIMP nsAccessNodeWrap::get_attributesForNames(
/* [in] */ unsigned short aNumAttribs,
/* [length_is][size_is][in] */ BSTR __RPC_FAR *aAttribNames,
/* [length_is][size_is][in] */ short __RPC_FAR *aNameSpaceID,
/* [length_is][size_is][retval] */ BSTR __RPC_FAR *aAttribValues)
{
__try {
if (!mContent || !IsElement())
return E_FAIL;
nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(mContent));
nsCOMPtr<nsINameSpaceManager> nameSpaceManager =
do_GetService(NS_NAMESPACEMANAGER_CONTRACTID);
int32_t index;
for (index = 0; index < aNumAttribs; index++) {
aAttribValues[index] = nullptr;
if (aAttribNames[index]) {
nsAutoString attributeValue, nameSpaceURI;
nsAutoString attributeName(nsDependentString(static_cast<PRUnichar*>(aAttribNames[index])));
nsresult rv;
if (aNameSpaceID[index]>0 &&
NS_SUCCEEDED(nameSpaceManager->GetNameSpaceURI(aNameSpaceID[index], nameSpaceURI)))
rv = domElement->GetAttributeNS(nameSpaceURI, attributeName, attributeValue);
else
rv = domElement->GetAttribute(attributeName, attributeValue);
if (NS_SUCCEEDED(rv))
aAttribValues[index] = ::SysAllocString(attributeValue.get());
}
}
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
return S_OK;
}
/* To do: use media type if not null */
STDMETHODIMP nsAccessNodeWrap::get_computedStyle(
/* [in] */ unsigned short aMaxStyleProperties,
/* [in] */ boolean aUseAlternateView,
/* [length_is][size_is][out] */ BSTR __RPC_FAR *aStyleProperties,
/* [length_is][size_is][out] */ BSTR __RPC_FAR *aStyleValues,
/* [out] */ unsigned short __RPC_FAR *aNumStyleProperties)
{
__try{
*aNumStyleProperties = 0;
if (!mContent || IsDocumentNode())
return E_FAIL;
nsCOMPtr<nsIDOMCSSStyleDeclaration> cssDecl =
nsWinUtils::GetComputedStyleDeclaration(mContent);
NS_ENSURE_TRUE(cssDecl, E_FAIL);
uint32_t length;
cssDecl->GetLength(&length);
uint32_t index, realIndex;
for (index = realIndex = 0; index < length && realIndex < aMaxStyleProperties; index ++) {
nsAutoString property, value;
if (NS_SUCCEEDED(cssDecl->Item(index, property)) && property.CharAt(0) != '-') // Ignore -moz-* properties
cssDecl->GetPropertyValue(property, value); // Get property value
if (!value.IsEmpty()) {
aStyleProperties[realIndex] = ::SysAllocString(property.get());
aStyleValues[realIndex] = ::SysAllocString(value.get());
++realIndex;
}
}
*aNumStyleProperties = static_cast<unsigned short>(realIndex);
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
return S_OK;
}
STDMETHODIMP nsAccessNodeWrap::get_computedStyleForProperties(
/* [in] */ unsigned short aNumStyleProperties,
/* [in] */ boolean aUseAlternateView,
/* [length_is][size_is][in] */ BSTR __RPC_FAR *aStyleProperties,
/* [length_is][size_is][out] */ BSTR __RPC_FAR *aStyleValues)
{
__try {
if (!mContent || IsDocumentNode())
return E_FAIL;
nsCOMPtr<nsIDOMCSSStyleDeclaration> cssDecl =
nsWinUtils::GetComputedStyleDeclaration(mContent);
NS_ENSURE_TRUE(cssDecl, E_FAIL);
uint32_t index;
for (index = 0; index < aNumStyleProperties; index ++) {
nsAutoString value;
if (aStyleProperties[index])
cssDecl->GetPropertyValue(nsDependentString(static_cast<PRUnichar*>(aStyleProperties[index])), value); // Get property value
aStyleValues[index] = ::SysAllocString(value.get());
}
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
return S_OK;
}
STDMETHODIMP nsAccessNodeWrap::scrollTo(/* [in] */ boolean aScrollTopLeft)
{
__try {
uint32_t scrollType =
aScrollTopLeft ? nsIAccessibleScrollType::SCROLL_TYPE_TOP_LEFT :
nsIAccessibleScrollType::SCROLL_TYPE_BOTTOM_RIGHT;
nsCoreUtils::ScrollTo(mDoc->PresShell(), mContent, scrollType);
return S_OK;
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
return E_FAIL;
}
ISimpleDOMNode*
nsAccessNodeWrap::MakeAccessNode(nsINode *aNode)
{
if (!aNode)
return NULL;
nsAccessNodeWrap *newNode = NULL;
ISimpleDOMNode *iNode = NULL;
Accessible* acc = mDoc->GetAccessible(aNode);
if (acc) {
IAccessible *msaaAccessible = nullptr;
acc->GetNativeInterface((void**)&msaaAccessible); // addrefs
msaaAccessible->QueryInterface(IID_ISimpleDOMNode, (void**)&iNode); // addrefs
msaaAccessible->Release(); // Release IAccessible
}
else {
nsCOMPtr<nsIContent> content(do_QueryInterface(aNode));
if (!content) {
NS_NOTREACHED("The node is a document which is not accessible!");
return NULL;
}
newNode = new nsAccessNodeWrap(content, mDoc);
if (!newNode)
return NULL;
iNode = static_cast<ISimpleDOMNode*>(newNode);
iNode->AddRef();
}
return iNode;
}
STDMETHODIMP nsAccessNodeWrap::get_parentNode(ISimpleDOMNode __RPC_FAR *__RPC_FAR *aNode)
{
__try {
nsINode* node = GetNode();
if (!node)
return E_FAIL;
*aNode = MakeAccessNode(node->GetParentNode());
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
return S_OK;
}
STDMETHODIMP nsAccessNodeWrap::get_firstChild(ISimpleDOMNode __RPC_FAR *__RPC_FAR *aNode)
{
__try {
nsINode* node = GetNode();
if (!node)
return E_FAIL;
*aNode = MakeAccessNode(node->GetFirstChild());
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
return S_OK;
}
STDMETHODIMP nsAccessNodeWrap::get_lastChild(ISimpleDOMNode __RPC_FAR *__RPC_FAR *aNode)
{
__try {
nsINode* node = GetNode();
if (!node)
return E_FAIL;
*aNode = MakeAccessNode(node->GetLastChild());
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
return S_OK;
}
STDMETHODIMP nsAccessNodeWrap::get_previousSibling(ISimpleDOMNode __RPC_FAR *__RPC_FAR *aNode)
{
__try {
nsINode* node = GetNode();
if (!node)
return E_FAIL;
*aNode = MakeAccessNode(node->GetPreviousSibling());
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
return S_OK;
}
STDMETHODIMP nsAccessNodeWrap::get_nextSibling(ISimpleDOMNode __RPC_FAR *__RPC_FAR *aNode)
{
__try {
nsINode* node = GetNode();
if (!node)
return E_FAIL;
*aNode = MakeAccessNode(node->GetNextSibling());
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
return S_OK;
}
STDMETHODIMP
nsAccessNodeWrap::get_childAt(unsigned aChildIndex,
ISimpleDOMNode __RPC_FAR *__RPC_FAR *aNode)
{
__try {
*aNode = nullptr;
nsINode* node = GetNode();
if (!node)
return E_FAIL;
*aNode = MakeAccessNode(node->GetChildAt(aChildIndex));
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
return S_OK;
}
STDMETHODIMP
nsAccessNodeWrap::get_innerHTML(BSTR __RPC_FAR *aInnerHTML)
{
__try {
*aInnerHTML = nullptr;
nsCOMPtr<nsIDOMHTMLElement> htmlElement = do_QueryInterface(GetNode());
if (!htmlElement)
return E_FAIL; // Node already shut down
nsAutoString innerHTML;
htmlElement->GetInnerHTML(innerHTML);
if (innerHTML.IsEmpty())
return S_FALSE;
*aInnerHTML = ::SysAllocStringLen(innerHTML.get(), innerHTML.Length());
if (!*aInnerHTML)
return E_OUTOFMEMORY;
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
return S_OK;
}
STDMETHODIMP
nsAccessNodeWrap::get_language(BSTR __RPC_FAR *aLanguage)
{
__try {
*aLanguage = NULL;
nsAutoString language;
Language(language);
if (language.IsEmpty())
return S_FALSE;
*aLanguage = ::SysAllocStringLen(language.get(), language.Length());
if (!*aLanguage)
return E_OUTOFMEMORY;
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
return S_OK;
}
STDMETHODIMP
nsAccessNodeWrap::get_localInterface(
/* [out] */ void __RPC_FAR *__RPC_FAR *localInterface)
{
__try {
*localInterface = static_cast<nsAccessNode*>(this);
NS_ADDREF_THIS();
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
return S_OK;
}
void nsAccessNodeWrap::InitAccessibility()
{

Просмотреть файл

@ -21,7 +21,6 @@
#include "nsIAccessible.h"
#include "nsIAccessibleEvent.h"
#include "nsIWinAccessNode.h"
#include "ISimpleDOMNode.h"
#include "nsIDOMElement.h"
#include "nsIContent.h"
#include "nsAccessNode.h"
@ -50,7 +49,6 @@ class AccTextChangeEvent;
class nsAccessNodeWrap : public nsAccessNode,
public nsIWinAccessNode,
public ISimpleDOMNode,
public IServiceProvider
{
public:
@ -70,59 +68,6 @@ public: // construction, destruction
REFIID aIID,
void** aInstancePtr);
// ISimpleDOMNode
virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_nodeInfo(
/* [out] */ BSTR __RPC_FAR *tagName,
/* [out] */ short __RPC_FAR *nameSpaceID,
/* [out] */ BSTR __RPC_FAR *nodeValue,
/* [out] */ unsigned int __RPC_FAR *numChildren,
/* [out] */ unsigned int __RPC_FAR *aUniqueID,
/* [out][retval] */ unsigned short __RPC_FAR *nodeType);
virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_attributes(
/* [in] */ unsigned short maxAttribs,
/* [length_is][size_is][out] */ BSTR __RPC_FAR *attribNames,
/* [length_is][size_is][out] */ short __RPC_FAR *nameSpaceID,
/* [length_is][size_is][out] */ BSTR __RPC_FAR *attribValues,
/* [out][retval] */ unsigned short __RPC_FAR *numAttribs);
virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_attributesForNames(
/* [in] */ unsigned short maxAttribs,
/* [length_is][size_is][in] */ BSTR __RPC_FAR *attribNames,
/* [length_is][size_is][in] */ short __RPC_FAR *nameSpaceID,
/* [length_is][size_is][retval] */ BSTR __RPC_FAR *attribValues);
virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_computedStyle(
/* [in] */ unsigned short maxStyleProperties,
/* [in] */ boolean useAlternateView,
/* [length_is][size_is][out] */ BSTR __RPC_FAR *styleProperties,
/* [length_is][size_is][out] */ BSTR __RPC_FAR *styleValues,
/* [out][retval] */ unsigned short __RPC_FAR *numStyleProperties);
virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_computedStyleForProperties(
/* [in] */ unsigned short numStyleProperties,
/* [in] */ boolean useAlternateView,
/* [length_is][size_is][in] */ BSTR __RPC_FAR *styleProperties,
/* [length_is][size_is][out][retval] */ BSTR __RPC_FAR *styleValues);
virtual HRESULT STDMETHODCALLTYPE scrollTo(/* [in] */ boolean scrollTopLeft);
virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_parentNode(ISimpleDOMNode __RPC_FAR *__RPC_FAR *node);
virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_firstChild(ISimpleDOMNode __RPC_FAR *__RPC_FAR *node);
virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_lastChild(ISimpleDOMNode __RPC_FAR *__RPC_FAR *node);
virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_previousSibling(ISimpleDOMNode __RPC_FAR *__RPC_FAR *node);
virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_nextSibling(ISimpleDOMNode __RPC_FAR *__RPC_FAR *node);
virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_childAt(unsigned childIndex,
ISimpleDOMNode __RPC_FAR *__RPC_FAR *node);
virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_innerHTML(
/* [out][retval] */ BSTR __RPC_FAR *innerHTML);
virtual /* [local][propget] */ HRESULT STDMETHODCALLTYPE get_localInterface(
/* [retval][out] */ void __RPC_FAR *__RPC_FAR *localInterface);
virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_language(
/* [out][retval] */ BSTR __RPC_FAR *language);
static void InitAccessibility();
static void ShutdownAccessibility();
@ -136,14 +81,6 @@ public: // construction, destruction
protected:
/**
* Return ISimpleDOMNode instance for existing accessible object or
* creates new nsAccessNode instance if the accessible doesn't exist.
*
* @note ISimpleDOMNode is returned addrefed
*/
ISimpleDOMNode *MakeAccessNode(nsINode *aNode);
/**
* It is used in HyperTextAccessibleWrap for IA2::newText/oldText
* implementation.

Просмотреть файл

@ -12,6 +12,7 @@ include $(DEPTH)/config/autoconf.mk
DIRS += \
ia2 \
sdn \
uia \
$(null)

Просмотреть файл

@ -0,0 +1,35 @@
# 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/.
DEPTH = @DEPTH@
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = accessibility
LIBRARY_NAME = accessibility_toolkit_sdn_s
EXPORT_LIBRARY = 1
LIBXUL_LIBRARY = 1
CPPSRCS += \
sdnAccessible.cpp \
$(NULL)
# we don't want the shared lib, but we want to force the creation of a static lib.
FORCE_STATIC_LIB = 1
include $(topsrcdir)/config/config.mk
include $(topsrcdir)/config/rules.mk
LOCAL_INCLUDES += \
-I$(srcdir) \
-I$(srcdir)/../../base \
-I$(srcdir)/../../generic \
-I$(srcdir)/../../html \
-I$(srcdir)/../../msaa \
-I$(srcdir)/../../xpcom \
-I$(srcdir)/../../xul \
$(NULL)

Просмотреть файл

@ -0,0 +1,36 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* 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_sdnAccessible_inl_h_
#define mozilla_a11y_sdnAccessible_inl_h_
#include "sdnAccessible.h"
#include "DocAccessible.h"
#include "nsAccessibilityService.h"
namespace mozilla {
namespace a11y {
inline DocAccessible*
sdnAccessible::GetDocument() const
{
DocManager* docMgr = GetAccService();
return docMgr ?
docMgr->GetDocAccessibleFromCache(mNode->OwnerDoc()) : nullptr;
}
inline Accessible*
sdnAccessible::GetAccessible() const
{
DocAccessible* document = GetDocument();
return document ? document->GetAccessible(mNode) : nullptr;
}
} // namespace a11y
} // namespace mozilla
#endif // mozilla_a11y_sdnAccessible_inl_h_

Просмотреть файл

@ -0,0 +1,537 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* 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 "sdnAccessible-inl.h"
#include "ISimpleDOMNode_i.c"
#include "nsAccessNodeWrap.h"
#include "DocAccessibleWrap.h"
#include "nsAttrName.h"
#include "nsCoreUtils.h"
#include "nsIDOMHTMLElement.h"
#include "nsIDOMCSSStyleDeclaration.h"
#include "nsServiceManagerUtils.h"
#include "nsWinUtils.h"
#include "nsAutoPtr.h"
#include "mozilla/dom/Element.h"
using namespace mozilla;
using namespace mozilla::a11y;
STDMETHODIMP
sdnAccessible::QueryInterface(REFIID aREFIID, void** aInstancePtr)
{
A11Y_TRYBLOCK_BEGIN
if (!aInstancePtr)
return E_FAIL;
*aInstancePtr = NULL;
if (aREFIID == IID_ISimpleDOMNode) {
*aInstancePtr = this;
AddRef();
return S_OK;
}
AccessibleWrap* accessible = static_cast<AccessibleWrap*>(GetAccessible());
if (accessible)
return accessible->QueryInterface(aREFIID, aInstancePtr);
// IUnknown* is the canonical one if and only if this accessible doesn't have
// an accessible.
if (aREFIID == IID_IUnknown) {
*aInstancePtr = this;
AddRef();
return S_OK;
}
return E_NOINTERFACE;
A11Y_TRYBLOCK_END
}
STDMETHODIMP
sdnAccessible::get_nodeInfo(BSTR __RPC_FAR* aNodeName,
short __RPC_FAR* aNameSpaceID,
BSTR __RPC_FAR* aNodeValue,
unsigned int __RPC_FAR* aNumChildren,
unsigned int __RPC_FAR* aUniqueID,
unsigned short __RPC_FAR* aNodeType)
{
A11Y_TRYBLOCK_BEGIN
if (!aNodeName || !aNameSpaceID || !aNodeValue || !aNumChildren ||
!aUniqueID || !aNodeType)
return E_INVALIDARG;
*aNodeName = NULL;
*aNameSpaceID = 0;
*aNodeValue = NULL;
*aNumChildren = 0;
*aUniqueID = 0;
*aNodeType = 0;
if (IsDefunct())
return CO_E_OBJNOTCONNECTED;
nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mNode));
uint16_t nodeType = 0;
DOMNode->GetNodeType(&nodeType);
*aNodeType = static_cast<unsigned short>(nodeType);
if (*aNodeType != NODETYPE_TEXT) {
nsAutoString nodeName;
DOMNode->GetNodeName(nodeName);
*aNodeName = ::SysAllocString(nodeName.get());
}
nsAutoString nodeValue;
DOMNode->GetNodeValue(nodeValue);
*aNodeValue = ::SysAllocString(nodeValue.get());
*aNameSpaceID = mNode->IsNodeOfType(nsINode::eCONTENT) ?
static_cast<short>(mNode->AsContent()->GetNameSpaceID()) : 0;
// This is a unique ID for every content node. The 3rd party accessibility
// application can compare this to the childID we return for events such as
// focus events, to correlate back to data nodes in their internal object
// model.
Accessible* accessible = GetAccessible();
*aUniqueID = - NS_PTR_TO_INT32(accessible ? accessible->UniqueID() :
static_cast<void*>(this));
*aNumChildren = mNode->GetChildCount();
return S_OK;
A11Y_TRYBLOCK_END
}
STDMETHODIMP
sdnAccessible::get_attributes(unsigned short aMaxAttribs,
BSTR __RPC_FAR* aAttribNames,
short __RPC_FAR* aNameSpaceIDs,
BSTR __RPC_FAR* aAttribValues,
unsigned short __RPC_FAR* aNumAttribs)
{
A11Y_TRYBLOCK_BEGIN
if (!aAttribNames || !aNameSpaceIDs || !aAttribValues || !aNumAttribs)
return E_INVALIDARG;
*aNumAttribs = 0;
if (IsDefunct())
return CO_E_OBJNOTCONNECTED;
if (!mNode->IsElement())
return S_FALSE;
dom::Element* elm = mNode->AsElement();
uint32_t numAttribs = elm->GetAttrCount();
if (numAttribs > aMaxAttribs)
numAttribs = aMaxAttribs;
*aNumAttribs = static_cast<unsigned short>(numAttribs);
for (uint32_t index = 0; index < numAttribs; index++) {
aNameSpaceIDs[index] = 0;
aAttribValues[index] = aAttribNames[index] = NULL;
nsAutoString attributeValue;
const nsAttrName* name = elm->GetAttrNameAt(index);
aNameSpaceIDs[index] = static_cast<short>(name->NamespaceID());
aAttribNames[index] = ::SysAllocString(name->LocalName()->GetUTF16String());
elm->GetAttr(name->NamespaceID(), name->LocalName(), attributeValue);
aAttribValues[index] = ::SysAllocString(attributeValue.get());
}
return S_OK;
A11Y_TRYBLOCK_END
}
STDMETHODIMP
sdnAccessible::get_attributesForNames(unsigned short aMaxAttribs,
BSTR __RPC_FAR* aAttribNames,
short __RPC_FAR* aNameSpaceID,
BSTR __RPC_FAR* aAttribValues)
{
A11Y_TRYBLOCK_BEGIN
if (!aAttribNames || !aNameSpaceID || !aAttribValues)
return E_INVALIDARG;
if (IsDefunct())
return CO_E_OBJNOTCONNECTED;
if (!mNode->IsElement())
return S_FALSE;
nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(mNode));
nsCOMPtr<nsINameSpaceManager> nameSpaceManager =
do_GetService(NS_NAMESPACEMANAGER_CONTRACTID);
int32_t index = 0;
for (index = 0; index < aMaxAttribs; index++) {
aAttribValues[index] = NULL;
if (aAttribNames[index]) {
nsAutoString attributeValue, nameSpaceURI;
nsAutoString attributeName(nsDependentString(
static_cast<PRUnichar*>(aAttribNames[index])));
nsresult rv = NS_OK;
if (aNameSpaceID[index]>0 &&
NS_SUCCEEDED(nameSpaceManager->GetNameSpaceURI(aNameSpaceID[index],
nameSpaceURI))) {
rv = domElement->GetAttributeNS(nameSpaceURI, attributeName,
attributeValue);
} else {
rv = domElement->GetAttribute(attributeName, attributeValue);
}
if (NS_SUCCEEDED(rv))
aAttribValues[index] = ::SysAllocString(attributeValue.get());
}
}
return S_OK;
A11Y_TRYBLOCK_END
}
STDMETHODIMP
sdnAccessible::get_computedStyle(unsigned short aMaxStyleProperties,
boolean aUseAlternateView,
BSTR __RPC_FAR* aStyleProperties,
BSTR __RPC_FAR* aStyleValues,
unsigned short __RPC_FAR* aNumStyleProperties)
{
A11Y_TRYBLOCK_BEGIN
if (!aStyleProperties || aStyleValues || !aNumStyleProperties)
return E_INVALIDARG;
if (IsDefunct())
return CO_E_OBJNOTCONNECTED;
*aNumStyleProperties = 0;
if (mNode->IsNodeOfType(nsINode::eDOCUMENT))
return S_FALSE;
nsCOMPtr<nsIDOMCSSStyleDeclaration> cssDecl =
nsWinUtils::GetComputedStyleDeclaration(mNode->AsContent());
NS_ENSURE_TRUE(cssDecl, E_FAIL);
uint32_t length = 0;
cssDecl->GetLength(&length);
uint32_t index = 0, realIndex = 0;
for (index = realIndex = 0; index < length && realIndex < aMaxStyleProperties;
index ++) {
nsAutoString property, value;
// Ignore -moz-* properties.
if (NS_SUCCEEDED(cssDecl->Item(index, property)) && property.CharAt(0) != '-')
cssDecl->GetPropertyValue(property, value); // Get property value
if (!value.IsEmpty()) {
aStyleProperties[realIndex] = ::SysAllocString(property.get());
aStyleValues[realIndex] = ::SysAllocString(value.get());
++realIndex;
}
}
*aNumStyleProperties = static_cast<unsigned short>(realIndex);
return S_OK;
A11Y_TRYBLOCK_END
}
STDMETHODIMP
sdnAccessible::get_computedStyleForProperties(unsigned short aNumStyleProperties,
boolean aUseAlternateView,
BSTR __RPC_FAR* aStyleProperties,
BSTR __RPC_FAR* aStyleValues)
{
A11Y_TRYBLOCK_BEGIN
if (!aStyleProperties || !aStyleValues)
return E_INVALIDARG;
if (IsDefunct())
return CO_E_OBJNOTCONNECTED;
if (mNode->IsNodeOfType(nsINode::eDOCUMENT))
return S_FALSE;
nsCOMPtr<nsIDOMCSSStyleDeclaration> cssDecl =
nsWinUtils::GetComputedStyleDeclaration(mNode->AsContent());
NS_ENSURE_TRUE(cssDecl, E_FAIL);
uint32_t index = 0;
for (index = 0; index < aNumStyleProperties; index++) {
nsAutoString value;
if (aStyleProperties[index])
cssDecl->GetPropertyValue(nsDependentString(static_cast<PRUnichar*>(
aStyleProperties[index])), value); // Get property value
aStyleValues[index] = ::SysAllocString(value.get());
}
return S_OK;
A11Y_TRYBLOCK_END
}
STDMETHODIMP
sdnAccessible::scrollTo(boolean aScrollTopLeft)
{
A11Y_TRYBLOCK_BEGIN
DocAccessible* document = GetDocument();
if (!document) // that's IsDefunct check
return CO_E_OBJNOTCONNECTED;
if (!mNode->IsContent())
return S_FALSE;
uint32_t scrollType =
aScrollTopLeft ? nsIAccessibleScrollType::SCROLL_TYPE_TOP_LEFT :
nsIAccessibleScrollType::SCROLL_TYPE_BOTTOM_RIGHT;
nsCoreUtils::ScrollTo(document->PresShell(), mNode->AsContent(), scrollType);
return S_OK;
A11Y_TRYBLOCK_END
}
STDMETHODIMP
sdnAccessible::get_parentNode(ISimpleDOMNode __RPC_FAR *__RPC_FAR* aNode)
{
A11Y_TRYBLOCK_BEGIN
if (!aNode)
return E_INVALIDARG;
*aNode = NULL;
if (IsDefunct())
return CO_E_OBJNOTCONNECTED;
nsINode* resultNode = mNode->GetParentNode();
if (resultNode) {
*aNode = new sdnAccessible(resultNode);
(*aNode)->AddRef();
}
return S_OK;
A11Y_TRYBLOCK_END
}
STDMETHODIMP
sdnAccessible::get_firstChild(ISimpleDOMNode __RPC_FAR *__RPC_FAR* aNode)
{
A11Y_TRYBLOCK_BEGIN
if (!aNode)
return E_INVALIDARG;
*aNode = NULL;
if (IsDefunct())
return CO_E_OBJNOTCONNECTED;
nsINode* resultNode = mNode->GetFirstChild();
if (resultNode) {
*aNode = new sdnAccessible(resultNode);
(*aNode)->AddRef();
}
return S_OK;
A11Y_TRYBLOCK_END
}
STDMETHODIMP
sdnAccessible::get_lastChild(ISimpleDOMNode __RPC_FAR *__RPC_FAR* aNode)
{
A11Y_TRYBLOCK_BEGIN
if (!aNode)
return E_INVALIDARG;
*aNode = NULL;
if (IsDefunct())
return CO_E_OBJNOTCONNECTED;
nsINode* resultNode = mNode->GetLastChild();
if (resultNode) {
*aNode = new sdnAccessible(resultNode);
(*aNode)->AddRef();
}
return S_OK;
A11Y_TRYBLOCK_END
}
STDMETHODIMP
sdnAccessible::get_previousSibling(ISimpleDOMNode __RPC_FAR *__RPC_FAR* aNode)
{
A11Y_TRYBLOCK_BEGIN
if (!aNode)
return E_INVALIDARG;
*aNode = NULL;
if (IsDefunct())
return CO_E_OBJNOTCONNECTED;
nsINode* resultNode = mNode->GetPreviousSibling();
if (resultNode) {
*aNode = new sdnAccessible(resultNode);
(*aNode)->AddRef();
}
return S_OK;
A11Y_TRYBLOCK_END
}
STDMETHODIMP
sdnAccessible::get_nextSibling(ISimpleDOMNode __RPC_FAR *__RPC_FAR* aNode)
{
A11Y_TRYBLOCK_BEGIN
if (!aNode)
return E_INVALIDARG;
*aNode = NULL;
if (IsDefunct())
return CO_E_OBJNOTCONNECTED;
nsINode* resultNode = mNode->GetNextSibling();
if (resultNode) {
*aNode = new sdnAccessible(resultNode);
(*aNode)->AddRef();
}
return S_OK;
A11Y_TRYBLOCK_END
}
STDMETHODIMP
sdnAccessible::get_childAt(unsigned aChildIndex,
ISimpleDOMNode __RPC_FAR *__RPC_FAR* aNode)
{
A11Y_TRYBLOCK_BEGIN
if (!aNode)
return E_INVALIDARG;
*aNode = NULL;
if (IsDefunct())
return CO_E_OBJNOTCONNECTED;
nsINode* resultNode = mNode->GetChildAt(aChildIndex);
if (resultNode) {
*aNode = new sdnAccessible(resultNode);
(*aNode)->AddRef();
}
return S_OK;
A11Y_TRYBLOCK_END
}
STDMETHODIMP
sdnAccessible::get_innerHTML(BSTR __RPC_FAR* aInnerHTML)
{
A11Y_TRYBLOCK_BEGIN
if (!aInnerHTML)
return E_INVALIDARG;
*aInnerHTML = NULL;
if (IsDefunct())
return CO_E_OBJNOTCONNECTED;
nsCOMPtr<nsIDOMHTMLElement> htmlElement = do_QueryInterface(mNode);
if (!htmlElement)
return S_FALSE;
nsAutoString innerHTML;
htmlElement->GetInnerHTML(innerHTML);
if (innerHTML.IsEmpty())
return S_FALSE;
*aInnerHTML = ::SysAllocStringLen(innerHTML.get(), innerHTML.Length());
if (!*aInnerHTML)
return E_OUTOFMEMORY;
return S_OK;
A11Y_TRYBLOCK_END
}
STDMETHODIMP
sdnAccessible::get_localInterface(void __RPC_FAR *__RPC_FAR* aLocalInterface)
{
A11Y_TRYBLOCK_BEGIN
if (!aLocalInterface)
return E_INVALIDARG;
*aLocalInterface = NULL;
if (IsDefunct())
return CO_E_OBJNOTCONNECTED;
*aLocalInterface = this;
AddRef();
return S_OK;
A11Y_TRYBLOCK_END
}
STDMETHODIMP
sdnAccessible::get_language(BSTR __RPC_FAR* aLanguage)
{
A11Y_TRYBLOCK_BEGIN
if (!aLanguage)
return E_INVALIDARG;
*aLanguage = NULL;
if (IsDefunct())
return CO_E_OBJNOTCONNECTED;
nsAutoString language;
if (mNode->IsElement())
nsCoreUtils::GetLanguageFor(mNode->AsElement(), nullptr, language);
if (language.IsEmpty()) { // Nothing found, so use document's language
mNode->OwnerDoc()->GetHeaderData(nsGkAtoms::headerContentLanguage,
language);
}
if (language.IsEmpty())
return S_FALSE;
*aLanguage = ::SysAllocStringLen(language.get(), language.Length());
if (!*aLanguage)
return E_OUTOFMEMORY;
return S_OK;
A11Y_TRYBLOCK_END
}

Просмотреть файл

@ -0,0 +1,113 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* 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_sdnAccessible_h_
#define mozilla_a11y_sdnAccessible_h_
#include "ISimpleDOMNode.h"
#include "AccessibleWrap.h"
#include "mozilla/Attributes.h"
namespace mozilla {
namespace a11y {
class sdnAccessible : public ISimpleDOMNode
{
public:
sdnAccessible(nsINode* aNode) : mNode(aNode) { }
~sdnAccessible() { }
/**
* Retrun if the object is defunct.
*/
bool IsDefunct() const { return !GetDocument(); }
/**
* Return a document accessible it belongs to if any.
*/
DocAccessible* GetDocument() const;
/*
* Return associated accessible if any.
*/
Accessible* GetAccessible() const;
//IUnknown
DECL_IUNKNOWN
virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_nodeInfo(
/* [out] */ BSTR __RPC_FAR* aNodeName,
/* [out] */ short __RPC_FAR* aNameSpaceID,
/* [out] */ BSTR __RPC_FAR* aNodeValue,
/* [out] */ unsigned int __RPC_FAR* aNumChildren,
/* [out] */ unsigned int __RPC_FAR* aUniqueID,
/* [out][retval] */ unsigned short __RPC_FAR* aNodeType);
virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_attributes(
/* [in] */ unsigned short aMaxAttribs,
/* [length_is][size_is][out] */ BSTR __RPC_FAR* aAttribNames,
/* [length_is][size_is][out] */ short __RPC_FAR* aNameSpaceIDs,
/* [length_is][size_is][out] */ BSTR __RPC_FAR* aAttribValues,
/* [out][retval] */ unsigned short __RPC_FAR* aNumAttribs);
virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_attributesForNames(
/* [in] */ unsigned short aMaxAttribs,
/* [length_is][size_is][in] */ BSTR __RPC_FAR* aAttribNames,
/* [length_is][size_is][in] */ short __RPC_FAR* aNameSpaceID,
/* [length_is][size_is][retval] */ BSTR __RPC_FAR* aAttribValues);
virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_computedStyle(
/* [in] */ unsigned short aMaxStyleProperties,
/* [in] */ boolean aUseAlternateView,
/* [length_is][size_is][out] */ BSTR __RPC_FAR* aStyleProperties,
/* [length_is][size_is][out] */ BSTR __RPC_FAR* aStyleValues,
/* [out][retval] */ unsigned short __RPC_FAR* aNumStyleProperties);
virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_computedStyleForProperties(
/* [in] */ unsigned short aNumStyleProperties,
/* [in] */ boolean aUseAlternateView,
/* [length_is][size_is][in] */ BSTR __RPC_FAR* aStyleProperties,
/* [length_is][size_is][out][retval] */ BSTR __RPC_FAR* aStyleValues);
virtual HRESULT STDMETHODCALLTYPE scrollTo(/* [in] */ boolean aScrollTopLeft);
virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_parentNode(
/* [out][retval] */ ISimpleDOMNode __RPC_FAR *__RPC_FAR* aNode);
virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_firstChild(
/* [out][retval] */ ISimpleDOMNode __RPC_FAR *__RPC_FAR* aNode);
virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_lastChild(
/* [out][retval] */ ISimpleDOMNode __RPC_FAR *__RPC_FAR* aNode);
virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_previousSibling(
/* [out][retval] */ ISimpleDOMNode __RPC_FAR *__RPC_FAR* aNode);
virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_nextSibling(
/* [out][retval] */ ISimpleDOMNode __RPC_FAR *__RPC_FAR* aNode);
virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_childAt(
/* [in] */ unsigned aChildIndex,
/* [out][retval] */ ISimpleDOMNode __RPC_FAR *__RPC_FAR* aNode);
virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_innerHTML(
/* [out][retval] */ BSTR __RPC_FAR* aInnerHTML);
virtual /* [local][propget] */ HRESULT STDMETHODCALLTYPE get_localInterface(
/* [retval][out] */ void __RPC_FAR *__RPC_FAR* aLocalInterface);
virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_language(
/* [out][retval] */ BSTR __RPC_FAR* aLanguage);
private:
nsCOMPtr<nsINode> mNode;
};
} // namespace a11y
} // namespace mozilla
#endif // mozilla_a11y_sdnAccessible_h_

Просмотреть файл

@ -17,68 +17,76 @@
function doTest()
{
//////////////////////////////////////////////////////////////////////////
// table1
// tables having captions
var accTree = {
role: ROLE_TABLE,
children: [
{
role: ROLE_CAPTION,
children: [
{
role: ROLE_TEXT_LEAF
}
]
},
{
role: ROLE_ROW,
children: [
{
role: ROLE_COLUMNHEADER
},
{
role: ROLE_COLUMNHEADER
}
]
},
{
role: ROLE_ROW,
children: [
{
role: ROLE_CELL
},
{
role: ROLE_CELL
}
]
},
{
role: ROLE_ROW,
children: [
{
role: ROLE_CELL
},
{
role: ROLE_CELL
}
]
},
{
role: ROLE_ROW,
children: [
{
role: ROLE_CELL
},
{
role: ROLE_CELL
}
]
}
]
};
// Two captions, first is used, second is ignored.
var accTree =
{ TABLE: [
{ CAPTION: [
{
role: ROLE_TEXT_LEAF,
name: "caption"
}
] },
{ ROW: [
{ COLUMNHEADER: [ { TEXT_LEAF: [ ] } ] },
{ COLUMNHEADER: [ { TEXT_LEAF: [ ] } ] }
] },
{ ROW: [
{ CELL: [ { TEXT_LEAF: [ ] } ] },
{ CELL: [ { TEXT_LEAF: [ ] } ] }
] },
{ ROW: [
{ CELL: [ { TEXT_LEAF: [ ] } ] },
{ CELL: [ { TEXT_LEAF: [ ] } ] }
] },
{ ROW: [
{ CELL: [ { TEXT_LEAF: [ ] } ] },
{ CELL: [ { TEXT_LEAF: [ ] } ] }
] }
] };
testAccessibleTree("table", accTree);
// One caption, empty text, caption is ignored.
accTree =
{ TABLE: [
{ ROW: [
{ CELL: [ { TEXT_LEAF: [ ] } ] },
{ CELL: [ { TEXT_LEAF: [ ] } ] }
] }
] };
testAccessibleTree("table_caption_empty", accTree);
// Two captions, first has empty text, both are ignored.
accTree =
{ TABLE: [
{ ROW: [
{ CELL: [ { TEXT_LEAF: [ ] } ] },
{ CELL: [ { TEXT_LEAF: [ ] } ] }
] }
] };
testAccessibleTree("table_caption_firstempty", accTree);
// One caption, placed in the end of table. In use.
accTree =
{ TABLE: [
{ CAPTION: [
{
role: ROLE_TEXT_LEAF,
name: "caption"
}
] },
{ ROW: [
{ CELL: [ { TEXT_LEAF: [ ] } ] },
{ CELL: [ { TEXT_LEAF: [ ] } ] }
] }
] };
testAccessibleTree("table_caption_intheend", accTree);
//////////////////////////////////////////////////////////////////////////
// table2 (consist of one column)
@ -187,6 +195,28 @@
</tfoot>
</table>
<table id="table_caption_empty">
<caption></caption>
<tr>
<td>cell1</td><td>cell2</td>
</tr>
</table>
<table id="table_caption_firstempty">
<caption></caption>
<tr>
<td>cell1</td><td>cell2</td>
</tr>
<caption>caption</caption>
</table>
<table id="table_caption_intheend">
<tr>
<td>cell1</td><td>cell2</td>
</tr>
<caption>caption</caption>
</table>
<table id="table2">
<thead>
<tr>

Просмотреть файл

@ -414,10 +414,6 @@ pref("dom.mozTCPSocket.enabled", true);
// by bug 710563.
pref("layout.frame_rate.precise", true);
// Temporary remote js console hack
pref("b2g.remote-js.enabled", true);
pref("b2g.remote-js.port", 9999);
// Handle hardware buttons in the b2g chrome package
pref("b2g.keys.menu.enabled", true);

Просмотреть файл

@ -121,7 +121,9 @@ SettingsListener.observe('language.current', 'en-US', function(value) {
Services.prefs.setCharPref(prefName, value + ', ' + intl);
}
shell.start();
if (shell.hasStarted() == false) {
shell.start();
}
});
// =================== RIL ====================

Просмотреть файл

@ -81,6 +81,13 @@ var shell = {
return this.CrashSubmit;
},
onlineForCrashReport: function shell_onlineForCrashReport() {
let wifiManager = navigator.mozWifiManager;
let onWifi = (wifiManager &&
(wifiManager.connection.status == 'connected'));
return !Services.io.offline && onWifi;
},
reportCrash: function shell_reportCrash(isChrome, aCrashID) {
let crashID = aCrashID;
try {
@ -113,16 +120,19 @@ var shell = {
// This function submits a crash when we're online.
submitCrash: function shell_submitCrash(aCrashID) {
if (!Services.io.offline) {
if (this.onlineForCrashReport()) {
this.CrashSubmit.submit(aCrashID);
return;
}
Services.obs.addObserver(function observer(subject, topic, state) {
if (state == 'online') {
let network = subject.QueryInterface(Ci.nsINetworkInterface);
if (network.state == Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED
&& network.type == Ci.nsINetworkInterface.NETWORK_TYPE_WIFI) {
shell.CrashSubmit.submit(aCrashID);
Services.obs.removeObserver(observer, topic);
}
}, "network:offline-status-changed", false);
}, "network-interface-state-changed", false);
},
get contentBrowser() {
@ -142,9 +152,16 @@ var shell = {
get manifestURL() {
return Services.prefs.getCharPref('browser.manifestURL');
},
},
_started: false,
hasStarted: function shell_hasStarted() {
return this._started;
},
start: function shell_start() {
this._started = true;
// This forces the initialization of the cookie service before we hit the
// network.
// See bug 810209
@ -551,57 +568,6 @@ Services.obs.addObserver(function onBluetoothVolumeChange(subject, topic, data)
});
}, 'bluetooth-volume-change', false);
(function Repl() {
if (!Services.prefs.getBoolPref('b2g.remote-js.enabled')) {
return;
}
const prompt = 'JS> ';
let output;
let reader = {
onInputStreamReady : function repl_readInput(input) {
let sin = Cc['@mozilla.org/scriptableinputstream;1']
.createInstance(Ci.nsIScriptableInputStream);
sin.init(input);
try {
let val = eval(sin.read(sin.available()));
let ret = (typeof val === 'undefined') ? 'undefined\n' : val + '\n';
output.write(ret, ret.length);
// TODO: check if socket has been closed
} catch (e) {
if (e.result === Cr.NS_BASE_STREAM_CLOSED ||
(typeof e === 'object' && e.result === Cr.NS_BASE_STREAM_CLOSED)) {
return;
}
let message = (typeof e === 'object') ? e.message + '\n' : e + '\n';
output.write(message, message.length);
}
output.write(prompt, prompt.length);
input.asyncWait(reader, 0, 0, Services.tm.mainThread);
}
}
let listener = {
onSocketAccepted: function repl_acceptConnection(serverSocket, clientSocket) {
dump('Accepted connection on ' + clientSocket.host + '\n');
let input = clientSocket.openInputStream(Ci.nsITransport.OPEN_BLOCKING, 0, 0)
.QueryInterface(Ci.nsIAsyncInputStream);
output = clientSocket.openOutputStream(Ci.nsITransport.OPEN_BLOCKING, 0, 0);
output.write(prompt, prompt.length);
input.asyncWait(reader, 0, 0, Services.tm.mainThread);
},
onStopListening: function repl_onStopListening() {
if (output) {
output.close();
}
}
}
let serverPort = Services.prefs.getIntPref('b2g.remote-js.port');
let serverSocket = Cc['@mozilla.org/network/server-socket;1']
.createInstance(Ci.nsIServerSocket);
serverSocket.init(serverPort, true, -1);
dump('Opened socket on ' + serverSocket.port + '\n');
serverSocket.asyncListen(listener);
})();
var CustomEventManager = {
init: function custevt_init() {
window.addEventListener("ContentStart", (function(evt) {

Просмотреть файл

@ -152,7 +152,10 @@ UpdatePrompt.prototype = {
},
showUpdateHistory: function UP_showUpdateHistory(aParent) { },
showUpdateInstalled: function UP_showUpdateInstalled() { },
showUpdateInstalled: function UP_showUpdateInstalled() {
let lock = Services.settings.createLock();
lock.set("deviceinfo.last_updated", Date.now(), null, null);
},
// Custom functions

Просмотреть файл

@ -0,0 +1,20 @@
{
"config_version": 1,
"tooltool_manifest": "releng-otoro.tt",
"mock_target": "mozilla-centos6-i386",
"mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel"],
"mock_files": [["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"]],
"build_targets": [],
"upload_files": [
"{workdir}/out/target/product/otoro/*.img",
"{objdir}/dist/b2g-update/*.mar",
"{objdir}/dist/b2g-*.tar.gz",
"{objdir}/dist/b2g-*.crashreporter-symbols.zip",
"{workdir}/sources.xml"
],
"env": {
"VARIANT": "user",
"B2GUPDATER": "1"
},
"gaia": {"vcs": "hgtool", "repo": "http://hg.mozilla.org/projects/gaia"}
}

Просмотреть файл

@ -0,0 +1,8 @@
[
{
"size": 868355892,
"digest": "0ccae39ee8910947fe3cf51fa3a45e820d2ff11571f6ccec29d9b3e5ae7f7709c1ad657210fbfea98baadd032c3d6a58e00ddbb2e93acafd751089869a72fed6",
"algorithm": "sha512",
"filename": "gonk.tar.xz"
}
]

Просмотреть файл

@ -0,0 +1,108 @@
<?xml version="1.0" ?><manifest>
<!-- This is only a record of which revisions were pulled to generate the
gonk.tar.xz snapshot referred to by releng-otoro.tt -->
<remote fetch="https://android.googlesource.com/" name="aosp"/>
<remote fetch="git://github.com/mozilla-b2g/" name="b2g"/>
<remote fetch="git://github.com/mozilla/" name="mozilla"/>
<remote fetch="git://codeaurora.org/" name="caf"/>
<remote fetch="git://android.git.linaro.org/" name="linaro"/>
<default remote="caf" revision="ics_chocolate_rb4.2" sync-j="4"/>
<!-- Gonk specific things and forks -->
<project name="platform_build" path="build" remote="b2g" revision="273ba23d5c6c9f6a34995a3cc429804d1449ca9f">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2f4377622f4c40275546c7816c0d4b21e800b4c6"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="32106d4ea635ebe17a1610b643b398db639b8b97"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="b7911c064a71a5c18e2c92f869f6364a798b46cd"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="6ee1f8987ef36d688f97064c003ad57849dfadf2"/>
<!-- Stock Android things -->
<!-- Information: platform/abi/cpp is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.117 --><project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
<!-- Information: platform/bionic is tagged with M8960AAAAANLYA100715A --><project name="platform/bionic" path="bionic" revision="cd5dfce80bc3f0139a56b58aca633202ccaee7f8"/>
<!-- Information: platform/bootable/recovery is tagged with M8960AAAAANLYA100715A --><project name="platform/bootable/recovery" path="bootable/recovery" revision="e0a9ac010df3afaa47ba107192c05ac8b5516435"/>
<!-- Information: platform/development is tagged with M8960AAAAANLYA100715A --><project name="platform/development" path="development" revision="a384622f5fcb1d2bebb9102591ff7ae91fe8ed2d"/>
<!-- Information: device/common is tagged with M8960AAAAANLYA1005304 --><project name="device/common" path="device/common" revision="7c65ea240157763b8ded6154a17d3c033167afb7"/>
<!-- Information: device/sample is tagged with M8960AAAAANLYA100715A --><project name="device/sample" path="device/sample" revision="c328f3d4409db801628861baa8d279fb8855892f"/>
<!-- Information: platform/external/apache-http is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.117 --><project name="platform/external/apache-http" path="external/apache-http" revision="6c9d8c58d3ed710f87c26820d903bb8aad81754f"/>
<!-- Information: platform/external/bluetooth/bluez is tagged with M76XXUSNEKNLYA2040 --><project name="platform/external/bluetooth/bluez" path="external/bluetooth/bluez" revision="1023c91c66e9c3bd1132480051993bf7827770f6"/>
<!-- Information: platform/external/bluetooth/glib is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.117 --><project name="platform/external/bluetooth/glib" path="external/bluetooth/glib" revision="c6b49241cc1a8950723a5f74f8f4b4f4c3fa970e"/>
<!-- Information: platform/external/bluetooth/hcidump is tagged with M8960AAAAANLYA1005304 --><project name="platform/external/bluetooth/hcidump" path="external/bluetooth/hcidump" revision="02b1eb24fbb3d0135a81edb4a2175b1397308d7d"/>
<!-- Information: platform/external/bsdiff is tagged with A8064AAAAANLYA1334 --><project name="platform/external/bsdiff" path="external/bsdiff" revision="81872540236d9bb15cccf963d05b9de48baa5375"/>
<!-- Information: platform/external/bzip2 is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.117 --><project name="platform/external/bzip2" path="external/bzip2" revision="048dacdca43eed1534689ececcf2781c63e1e4ba"/>
<!-- Information: platform/external/dbus is tagged with M8960AAAAANLYA100715A --><project name="platform/external/dbus" path="external/dbus" revision="c7517b6195dc6926728352113e6cc335da3f9c9e"/>
<!-- Information: platform/external/dhcpcd is tagged with M8960AAAAANLYA100715A --><project name="platform/external/dhcpcd" path="external/dhcpcd" revision="1e00fb67022d0921af0fead263f81762781b9ffa"/>
<!-- Information: platform/external/dnsmasq is tagged with A8064AAAAANLYA1334 --><project name="platform/external/dnsmasq" path="external/dnsmasq" revision="f621afad94df46204c25fc2593a19d704d2637f5"/>
<!-- Information: platform/external/e2fsprogs is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.117 --><project name="platform/external/e2fsprogs" path="external/e2fsprogs" revision="d5f550bb2f556c5d287f7c8d2b77223654bcec37"/>
<!-- Information: platform/external/expat is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.117 --><project name="platform/external/expat" path="external/expat" revision="6df134250feab71edb5915ecaa6268210bca76c5"/>
<!-- Information: platform/external/fdlibm is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.117 --><project name="platform/external/fdlibm" path="external/fdlibm" revision="988ffeb12a6e044ae3504838ef1fee3fe0716934"/>
<!-- Information: platform/external/flac is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.117 --><project name="platform/external/flac" path="external/flac" revision="5893fbe890f5dab8e4146d2baa4bd2691c0739e0"/>
<!-- Information: platform/external/freetype is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.117 --><project name="platform/external/freetype" path="external/freetype" revision="aeb407daf3711a10a27f3bc2223c5eb05158076e"/>
<!-- Information: platform/external/giflib is tagged with A8064AAAAANLYA1334 --><project name="platform/external/giflib" path="external/giflib" revision="b2597268aef084202a8c349d1cc072c03c6e22eb"/>
<!-- Information: platform/external/gtest is tagged with android-4.2_r1 --><project name="platform/external/gtest" path="external/gtest" remote="linaro" revision="344e5f3db17615cc853073a02968a603efd39109"/>
<!-- Information: platform/external/harfbuzz is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.117 --><project name="platform/external/harfbuzz" path="external/harfbuzz" revision="116610d63a859521dacf00fb6818ee9ab2e666f6"/>
<!-- Information: platform/external/icu4c is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.117 --><project name="platform/external/icu4c" path="external/icu4c" revision="0fa67b93b831c6636ca18b152a1b1b14cc99b034"/>
<!-- Information: platform/external/iptables is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.117 --><project name="platform/external/iptables" path="external/iptables" revision="3b2deb17f065c5664bb25e1a28489e5792eb63ff"/>
<!-- Information: platform/external/jhead is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.117 --><project name="platform/external/jhead" path="external/jhead" revision="754078052c687f6721536009c816644c73e4f145"/>
<!-- Information: platform/external/jpeg is tagged with M8960AAAAANLYA1005304 --><project name="platform/external/jpeg" path="external/jpeg" revision="a62e464d672a4623233180e4023034bf825f066e"/>
<!-- Information: platform/external/libgsm is tagged with A8064AAAAANLYA1334 --><project name="platform/external/libgsm" path="external/libgsm" revision="5e4516958690b9a1b2c98f88eeecba3edd2dbda4"/>
<!-- Information: platform/external/liblzf is tagged with A8064AAAAANLYA1334 --><project name="platform/external/liblzf" path="external/liblzf" revision="6946aa575b0949d045722794850896099d937cbb"/>
<!-- Information: platform/external/libnfc-nxp is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.117 --><project name="platform/external/libnfc-nxp" path="external/libnfc-nxp" revision="3a912b065a31a72c63ad56ac224cfeaa933423b6"/>
<!-- Information: platform/external/libnl-headers is tagged with A8064AAAAANLYA1334 --><project name="platform/external/libnl-headers" path="external/libnl-headers" revision="6ccf7349d61f73ac26a0675d735d903ab919c658"/>
<!-- Information: platform/external/libphonenumber is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.117 --><project name="platform/external/libphonenumber" path="external/libphonenumber" revision="8d22c9a05eda1935c6dc27d188158e6ee38dc016"/>
<!-- Information: platform/external/libpng is tagged with M8960AAAAANLYA100715A --><project name="platform/external/libpng" path="external/libpng" revision="9c3730f0efa69f580f03463c237cd928f3196404"/>
<!-- Information: platform/external/libvpx is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.117 --><project name="platform/external/libvpx" path="external/libvpx" revision="3a40da0d96da5c520e7707aa14f48a80956e20d7"/>
<!-- Information: platform/external/llvm is tagged with M8960AAAAANLYA1005304 --><project name="platform/external/llvm" path="external/llvm" revision="bff5923831940309f7d8ddbff5826ca6ed2dc050"/>
<!-- Information: platform/external/mksh is tagged with M8960AAAAANLYA1005304 --><project name="platform/external/mksh" path="external/mksh" revision="ec646e8f5e7dac9a77d1de549c6ed92c04d0cd4b"/>
<project name="platform_external_opensans" path="external/opensans" remote="b2g" revision="b5b4c226ca1d71e936153cf679dda6d3d60e2354"/>
<!-- Information: platform/external/openssl is tagged with AU_LINUX_ANDROID_ICS.04.00.04.00.110 --><project name="platform/external/openssl" path="external/openssl" revision="27d333cce9a31c806b4bfa042925f045c727aecd"/>
<!-- Information: platform/external/protobuf is tagged with A8064AAAAANLYA1334 --><project name="platform/external/protobuf" path="external/protobuf" revision="e217977611c52bccde7f7c78e1d3c790c6357431"/>
<!-- Information: platform/external/safe-iop is tagged with A8064AAAAANLYA1334 --><project name="platform/external/safe-iop" path="external/safe-iop" revision="07073634e2e3aa4f518e36ed5dec3aabc549d5fb"/>
<project name="screencap-gonk" path="external/screencap-gonk" remote="b2g" revision="e6403c71e9eca8cb943739d5a0a192deac60fc51"/>
<!-- Information: platform/external/skia is tagged with M8960AAAAANLYA100715A --><project name="platform/external/skia" path="external/skia" revision="7d90c85f2c0e3b747f7c7eff8bc9253b0063b439"/>
<!-- Information: platform/external/sonivox is tagged with M8960AAAAANLYA1005304 --><project name="platform/external/sonivox" path="external/sonivox" revision="7c967779dfc61ac1f346e972de91d4bfce7dccbb"/>
<!-- Information: platform/external/speex is tagged with A8064AAAAANLYA1334 --><project name="platform/external/speex" path="external/speex" revision="ebe6230a7f7c69f5a4389f2b09b7b19ef9e94f32"/>
<project name="platform/external/sqlite" path="external/sqlite" revision="fb30e613139b8836fdc8e81e166cf3a76e5fa17f"/>
<!-- Information: platform/external/stlport is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.117 --><project name="platform/external/stlport" path="external/stlport" revision="a6734e0645fce81c9610de0488b729207bfa576e"/>
<!-- Information: platform/external/strace is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.117 --><project name="platform/external/strace" path="external/strace" revision="c9fd2e5ef7d002e12e7cf2512506c84a9414b0fd"/>
<!-- Information: platform/external/tagsoup is tagged with A8064AAAAANLYA1334 --><project name="platform/external/tagsoup" path="external/tagsoup" revision="68c2ec9e0acdb3214b7fb91dbab8c9fab8736817"/>
<!-- Information: platform/external/tinyalsa is tagged with M8960AAAAANLYA1005304 --><project name="platform/external/tinyalsa" path="external/tinyalsa" revision="06cc244ee512c1352215e543615738bc8ac82814"/>
<!-- Information: platform/external/tremolo is tagged with A8064AAAAANLYA1334 --><project name="platform/external/tremolo" path="external/tremolo" revision="25bd78d2392dbdc879ae53382cde9d019f79cf6f"/>
<project name="unbootimg" path="external/unbootimg" remote="b2g" revision="9464623d92eb8668544916dc5a8f4f6337d0bc08"/>
<!-- Information: platform/external/webp is tagged with A8064AAAAANLYA1334 --><project name="platform/external/webp" path="external/webp" revision="88fe2b83c4b9232cd08729556fd0485d6a6a92cd"/>
<!-- Information: platform/external/webrtc is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.117 --><project name="platform/external/webrtc" path="external/webrtc" revision="137024dc8a2e9251a471e20518a9c3ae06f81f23"/>
<!-- Information: platform/external/wpa_supplicant is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.117 --><project name="platform/external/wpa_supplicant" path="external/wpa_supplicant" revision="a01d37870bbf9892d43e792e5de0683ca41c5497"/>
<!-- Information: platform/external/hostap is tagged with M8960AAAAANLYA1047 --><project name="platform/external/hostap" path="external/hostap" revision="bf04b0faadbdeb4b7943f2e2c4c5aa59df872bb1"/>
<!-- Information: platform/external/zlib is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.117 --><project name="platform/external/zlib" path="external/zlib" revision="f96a1d1ebfdf1cd582210fd09c23d8f59e0ae094"/>
<!-- Information: platform/external/yaffs2 is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.117 --><project name="platform/external/yaffs2" path="external/yaffs2" revision="0afa916204c664b3114429637b63af1321a0aeca"/>
<!-- Information: platform/frameworks/base is tagged with M76XXUSNEKNLYA2040 --><project name="platform/frameworks/base" path="frameworks/base" revision="eb2bc75803ca179353c24c364a9c8a8ce23e8b78"/>
<!-- Information: platform/frameworks/opt/emoji is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.117 --><project name="platform/frameworks/opt/emoji" path="frameworks/opt/emoji" revision="a95d8db002770469d72dfaf59ff37ac96db29a87"/>
<!-- Information: platform/frameworks/support is tagged with M8960AAAAANLYA1005304 --><project name="platform/frameworks/support" path="frameworks/support" revision="27208692b001981f1806f4f396434f4eac78b909"/>
<!-- Information: platform/hardware/libhardware is tagged with M8960AAAAANLYA1049B --><project name="platform/hardware/libhardware" path="hardware/libhardware" revision="4a619901847621f8a7305edf42dd07347a140484"/>
<!-- Information: platform/hardware/libhardware_legacy is tagged with M8960AAAAANLYA153611 --><project name="platform/hardware/libhardware_legacy" path="hardware/libhardware_legacy" revision="87b4d7afa8f854b445e2d0d95091f6f6069f2b30"/>
<!-- Information: platform/libcore is tagged with M8960AAAAANLYA100715A --><project name="platform/libcore" path="libcore" revision="30841f9fba9ccd5c54f4f079f495994db97f283e"/>
<!-- Information: platform/ndk is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.117 --><project name="platform/ndk" path="ndk" revision="9f555971e1481854d5b4dc11b3e6af9fff4f241f"/>
<!-- Information: platform/prebuilt is tagged with M8960AAAAANLYA1005304 --><project name="platform/prebuilt" path="prebuilt" revision="447ea790fcc957dde59730ecc2a65ca263bdc733"/>
<!-- Information: platform/system/bluetooth is tagged with M8960AAAAANLYA100703 --><project name="platform/system/bluetooth" path="system/bluetooth" revision="7772cad4823f1f427ce1d4df84a55982386d6d18"/>
<!-- Information: platform/system/core is tagged with M76XXUSNEKNLYA2040 --><project name="platform/system/core" path="system/core" revision="bf1970408676ce570b8f4dc3efa038e47552137f"/>
<!-- Information: platform/system/extras is tagged with M8960AAAAANLYA1005304 --><project name="platform/system/extras" path="system/extras" revision="01db6c1254e1407740a543f24317fc540fc4c049"/>
<!-- Information: platform/system/media is tagged with M8960AAAAANLYA1005304 --><project name="platform/system/media" path="system/media" revision="7f71c7fd362bbd992ff2e0e80f7af5859ad116ad"/>
<!-- Information: platform/system/netd is tagged with M8960AAAAANLYA1049 --><project name="platform/system/netd" path="system/netd" revision="306e765248e3900041bf2737e9f57b1b5694a4ce"/>
<!-- Information: platform/system/vold is tagged with M8960AAAAANLYA100715A --><project name="platform/system/vold" path="system/vold" revision="99fff257d53cc045d1460841edca5d901dacfcf5"/>
<!-- Otoro/Unagi specific things -->
<!-- Information: device/qcom/common is tagged with M8960AAAAANLYA100715A --><project name="device/qcom/common" path="device/qcom/common" revision="b9cdab8e1e1a215a8c65b8d5816f666bec7be205"/>
<!-- Information: platform/vendor/qcom/msm7627a is tagged with M8960AAAAANLYA100715A --><project name="platform/vendor/qcom/msm7627a" path="device/qcom/msm7627a" revision="d920a502ba17cf4d716f8b1a615f07e796b0501a"/>
<project name="android-device-otoro" path="device/qcom/otoro" remote="b2g" revision="e3e99b264dd0230108aa78f2b653db4ce0e494fb"/>
<project name="android-device-unagi" path="device/qcom/unagi" remote="b2g" revision="f8ca54267ed2ceabefadf96b6953814ac89c5056"/>
<project name="codeaurora_kernel_msm" path="kernel" remote="b2g" revision="0a01247e4b0880f93424b27251cd3a1f6b19dbb2"/>
<!-- Information: platform/hardware/qcom/camera is tagged with M76XXUSNEKNLYA2040 --><project name="platform/hardware/qcom/camera" path="hardware/qcom/camera" revision="1acf77a75e30f3fc8b1eed2057c97adf1cb1633f"/>
<project name="hardware_qcom_display" path="hardware/qcom/display" remote="b2g" revision="6405d30f2fac7d8a1f2cb17b99fb7dd0a8bcfdac"/>
<!-- Information: platform/hardware/qcom/media is tagged with M8960AAAAANLYA100715A --><project name="platform/hardware/qcom/media" path="hardware/qcom/media" revision="552c3ddb7174a01f3508782d40c4d8c845ab441a"/>
<!-- Information: platform/hardware/qcom/gps is tagged with M8960AAAAANLYA100705 --><project name="platform/hardware/qcom/gps" path="hardware/qcom/gps" revision="23d5707b320d7fc69f8ba3b7d84d78a1c5681708"/>
<!-- Information: platform/hardware/msm7k is tagged with AU_LINUX_GECKO_ICS_STRAWBERRY.01.00.00.19.117 --><project name="platform/hardware/msm7k" path="hardware/msm7k" revision="8892d46805c5639b55dd07547745c5180da861e7"/>
<!-- Information: platform/vendor/qcom-opensource/omx/mm-core is tagged with M8960AAAAANLYA100715A --><project name="platform/vendor/qcom-opensource/omx/mm-core" path="vendor/qcom/opensource/omx/mm-core" revision="ab17ac9a074b4bb69986a8436336bdfbbaf9cd39"/>
<!-- Information: platform/hardware/ril is tagged with M76XXUSNEKNLYA1610 --><project name="platform/hardware/ril" path="hardware/ril" remote="caf" revision="fe9a3f63922143b57e79ed570bab2328df8c83a5"/>
</manifest>

Просмотреть файл

@ -91,7 +91,7 @@ const gXPInstallObserver = {
action, null, options);
break;
case "addon-install-started":
function needsDownload(aInstall) {
var needsDownload = function needsDownload(aInstall) {
return aInstall.state != AddonManager.STATE_DOWNLOADED;
}
// If all installs have already been downloaded then there is no need to

Просмотреть файл

@ -358,7 +358,7 @@ var FullScreen = {
Services.perms.ALLOW_ACTION,
Services.perms.EXPIRE_SESSION);
let host = uri.host;
function onFullscreenchange(event) {
var onFullscreenchange = function onFullscreenchange(event) {
if (event.target == document && document.mozFullScreenElement == null) {
// The chrome document has left fullscreen. Remove the temporary permission grant.
Services.perms.remove(host, "fullscreen");
@ -545,7 +545,7 @@ var FullScreen = {
el.setAttribute("inFullscreen", true);
}
else {
function restoreAttr(attrName) {
var restoreAttr = function restoreAttr(attrName) {
var savedAttr = "saved-" + attrName;
if (el.hasAttribute(savedAttr)) {
el.setAttribute(attrName, el.getAttribute(savedAttr));

Просмотреть файл

@ -505,7 +505,8 @@
accesskey="&addons.accesskey;"
key="key_openAddons"
command="Tools:Addons"/>
<menu id="menu_socialAmbientMenu">
<menu id="menu_socialAmbientMenu"
observes="socialActiveBroadcaster">
<menupopup id="menu_social-statusarea-popup">
<menuitem class="social-statusarea-user menuitem-iconic" pack="start" align="center"
observes="socialBroadcaster_userDetails"
@ -534,6 +535,12 @@
command="Social:ToggleNotifications"
label="&social.toggleNotifications.label;"
accesskey="&social.toggleNotifications.accesskey;"/>
<menuitem id="menu_focusChatBar"
label="&social.chatBar.label;"
accesskey="&social.chatBar.accesskey;"
key="focusChatBar"
command="Social:FocusChat"
class="show-only-for-keyboard"/>
<menuseparator class="social-statusarea-separator"/>
<menuitem class="social-toggle-menuitem" command="Social:Toggle"/>
<menuitem class="social-remove-menuitem" command="Social:Remove"/>

Просмотреть файл

@ -116,7 +116,7 @@ var gPluginHandler = {
// Helper to get the binding handler type from a plugin object
_getBindingType : function(plugin) {
if (!(plugin instanceof Ci.nsIObjectLoadingContent))
return;
return null;
switch (plugin.pluginFallbackType) {
case Ci.nsIObjectLoadingContent.PLUGIN_UNSUPPORTED:
@ -137,7 +137,7 @@ var gPluginHandler = {
return "PluginPlayPreview";
default:
// Not all states map to a handler
return;
return null;
}
},
@ -238,7 +238,16 @@ var gPluginHandler = {
},
canActivatePlugin: function PH_canActivatePlugin(objLoadingContent) {
let pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
let pluginPermission = Ci.nsIPermissionManager.UNKNOWN_ACTION;
if (objLoadingContent.actualType) {
let permissionString = pluginHost.getPermissionStringForType(objLoadingContent.actualType);
let browser = gBrowser.getBrowserForDocument(objLoadingContent.ownerDocument.defaultView.top.document);
pluginPermission = Services.perms.testPermission(browser.currentURI, permissionString);
}
return !objLoadingContent.activated &&
pluginPermission != Ci.nsIPermissionManager.DENY_ACTION &&
objLoadingContent.pluginFallbackType !== Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW;
},
@ -351,19 +360,26 @@ var gPluginHandler = {
_handleClickToPlayEvent: function PH_handleClickToPlayEvent(aPlugin) {
let doc = aPlugin.ownerDocument;
let browser = gBrowser.getBrowserForDocument(doc.defaultView.top.document);
let pluginsPermission = Services.perms.testPermission(browser.currentURI, "plugins");
let pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
let pluginPermission = Ci.nsIPermissionManager.UNKNOWN_ACTION;
let objLoadingContent = aPlugin.QueryInterface(Ci.nsIObjectLoadingContent);
if (objLoadingContent.actualType) {
let permissionString = pluginHost.getPermissionStringForType(objLoadingContent.actualType);
pluginPermission = Services.perms.testPermission(browser.currentURI, permissionString);
}
let overlay = doc.getAnonymousElementByAttribute(aPlugin, "class", "mainBox");
if (browser._clickToPlayPluginsActivated) {
let objLoadingContent = aPlugin.QueryInterface(Ci.nsIObjectLoadingContent);
objLoadingContent.playPlugin();
return;
} else if (pluginsPermission == Ci.nsIPermissionManager.DENY_ACTION) {
if (pluginPermission == Ci.nsIPermissionManager.DENY_ACTION) {
if (overlay)
overlay.style.visibility = "hidden";
return;
}
if (browser._clickToPlayPluginsActivated) {
objLoadingContent.playPlugin();
return;
}
if (overlay) {
overlay.addEventListener("click", function(aEvent) {
// Have to check that the target is not the link to update the plugin
@ -416,15 +432,7 @@ var gPluginHandler = {
},
reshowClickToPlayNotification: function PH_reshowClickToPlayNotification() {
if (!Services.prefs.getBoolPref("plugins.click_to_play"))
return;
let browser = gBrowser.selectedBrowser;
let pluginsPermission = Services.perms.testPermission(browser.currentURI, "plugins");
if (pluginsPermission == Ci.nsIPermissionManager.DENY_ACTION)
return;
if (gPluginHandler._pluginNeedsActivationExceptThese([]))
gPluginHandler._showClickToPlayNotification(browser);
},
@ -517,7 +525,19 @@ var gPluginHandler = {
}
return centerActions;
},
},
_setPermissionForPlugins: function PH_setPermissionForPlugins(aBrowser, aPermission, aPluginList) {
let pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
for (let plugin of aPluginList) {
let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
if (gPluginHandler.canActivatePlugin(objLoadingContent) &&
objLoadingContent.actualType) {
let permissionString = pluginHost.getPermissionStringForType(objLoadingContent.actualType);
Services.perms.add(aBrowser.currentURI, permissionString, aPermission);
}
}
},
_showClickToPlayNotification: function PH_showClickToPlayNotification(aBrowser) {
aBrowser._clickToPlayDoorhangerShown = true;
@ -545,14 +565,14 @@ var gPluginHandler = {
label: gNavigatorBundle.getString("activatePluginsMessage.always"),
accessKey: gNavigatorBundle.getString("activatePluginsMessage.always.accesskey"),
callback: function () {
Services.perms.add(aBrowser.currentURI, "plugins", Ci.nsIPermissionManager.ALLOW_ACTION);
gPluginHandler._setPermissionForPlugins(aBrowser, Ci.nsIPermissionManager.ALLOW_ACTION, cwu.plugins);
gPluginHandler.activatePlugins(contentWindow);
}
},{
label: gNavigatorBundle.getString("activatePluginsMessage.never"),
accessKey: gNavigatorBundle.getString("activatePluginsMessage.never.accesskey"),
callback: function () {
Services.perms.add(aBrowser.currentURI, "plugins", Ci.nsIPermissionManager.DENY_ACTION);
gPluginHandler._setPermissionForPlugins(aBrowser, Ci.nsIPermissionManager.DENY_ACTION, cwu.plugins);
let notification = PopupNotifications.getNotification("click-to-play-plugins", aBrowser);
if (notification)
notification.remove();
@ -571,7 +591,9 @@ var gPluginHandler = {
.getInterface(Ci.nsIDOMWindowUtils);
for (let plugin of cwu.plugins) {
let overlay = doc.getAnonymousElementByAttribute(plugin, "class", "mainBox");
overlay.style.visibility = "hidden";
// for already activated plugins, there will be no overlay
if (overlay)
overlay.style.visibility = "hidden";
}
},

Просмотреть файл

@ -112,10 +112,11 @@
<command id="History:UndoCloseTab" oncommand="undoCloseTab();"/>
<command id="History:UndoCloseWindow" oncommand="undoCloseWindow();"/>
<command id="Browser:ToggleAddonBar" oncommand="toggleAddonBar();"/>
<command id="Social:SharePage" oncommand="SocialShareButton.sharePage();"/>
<command id="Social:SharePage" oncommand="SocialShareButton.sharePage();" disabled="true"/>
<command id="Social:UnsharePage" oncommand="SocialShareButton.unsharePage();"/>
<command id="Social:ToggleSidebar" oncommand="Social.toggleSidebar();"/>
<command id="Social:ToggleNotifications" oncommand="Social.toggleNotifications();"/>
<command id="Social:FocusChat" oncommand="SocialChatBar.focus();" hidden="true" disabled="true"/>
<command id="Social:Toggle" oncommand="Social.toggle();" hidden="true"/>
<command id="Social:Remove" oncommand="SocialUI.disableWithConfirmation();"/>
</commandset>
@ -193,6 +194,7 @@
#endif
<broadcaster id="workOfflineMenuitemState"/>
<broadcaster id="socialSidebarBroadcaster" hidden="true"/>
<broadcaster id="socialActiveBroadcaster" hidden="true"/>
<!-- DevTools broadcasters -->
<broadcaster id="devtoolsMenuBroadcaster_DevToolbar"
@ -414,7 +416,7 @@
#endif
<key id="sharePage" key="&sharePageCmd.commandkey;" command="Social:SharePage" modifiers="accel,shift"/>
<key id="focusChatBar" key="&social.chatBar.commandkey;" oncommand="SocialChatBar.focus();" modifiers="accel,shift"/>
<key id="focusChatBar" key="&social.chatBar.commandkey;" command="Social:FocusChat" modifiers="accel,shift"/>
# don't use |command="Browser:Stop"|, ESC is being used to freeze animated gifs,
# even if the stop button and menuitem are disabled (see Bug 284140)

Просмотреть файл

@ -17,6 +17,7 @@ let SocialUI = {
Services.prefs.addObserver("social.sidebar.open", this, false);
Services.prefs.addObserver("social.toast-notifications.enabled", this, false);
Services.prefs.addObserver("social.active", this, false);
gBrowser.addEventListener("ActivateSocialFeature", this._activationEventHandler, true, true);
@ -26,6 +27,7 @@ let SocialUI = {
SocialChatBar.update();
});
this.updateActiveBroadcaster();
Social.init(this._providerReady.bind(this));
},
@ -39,6 +41,7 @@ let SocialUI = {
Services.prefs.removeObserver("social.sidebar.open", this);
Services.prefs.removeObserver("social.toast-notifications.enabled", this);
Services.prefs.removeObserver("social.active", this);
},
showProfile: function SocialUI_showProfile() {
@ -62,6 +65,7 @@ let SocialUI = {
SocialSidebar.update();
SocialChatBar.update();
SocialFlyout.unload();
SocialMenu.populate();
} catch (e) {
Components.utils.reportError(e);
throw e;
@ -86,6 +90,8 @@ let SocialUI = {
}
break;
case "nsPref:changed":
this.updateActiveBroadcaster();
this.updateToggleCommand();
SocialSidebar.update();
SocialToolbar.updateButton();
SocialMenu.populate();
@ -130,6 +136,11 @@ let SocialUI = {
toggleCommand.setAttribute("hidden", Social.active ? "false" : "true");
},
updateActiveBroadcaster: function SocialUI_updateActiveBroadcaster() {
let broadcaster = document.getElementById("socialActiveBroadcaster");
broadcaster.hidden = !Social.active;
},
// This handles "ActivateSocialFeature" events fired against content documents
// in this window.
_activationEventHandler: function SocialUI_activationHandler(e) {
@ -247,11 +258,14 @@ let SocialChatBar = {
this.chatbar.openChat(aProvider, aURL, aCallback, aMode);
},
update: function() {
if (!this.isAvailable)
let command = document.getElementById("Social:FocusChat");
if (!this.isAvailable) {
this.chatbar.removeAll();
else {
this.chatbar.hidden = document.mozFullScreen;
command.hidden = true;
} else {
this.chatbar.hidden = command.hidden = document.mozFullScreen;
}
command.setAttribute("disabled", command.hidden ? "true" : "false");
},
focus: function SocialChatBar_focus() {
this.chatbar.focus();
@ -385,8 +399,10 @@ let SocialFlyout = {
iframe.addEventListener("load", function panelBrowserOnload(e) {
iframe.removeEventListener("load", panelBrowserOnload, true);
setTimeout(function() {
SocialFlyout._dynamicResizer.start(panel, iframe);
SocialFlyout.dispatchPanelEvent("socialFrameShow");
if (SocialFlyout._dynamicResizer) { // may go null if hidden quickly
SocialFlyout._dynamicResizer.start(panel, iframe);
SocialFlyout.dispatchPanelEvent("socialFrameShow");
}
}, 0);
}, true);
}
@ -497,6 +513,10 @@ let SocialShareButton = {
shareButton.hidden = !Social.uiVisible || Social.provider.recommendInfo == null ||
!SocialUI.haveLoggedInUser() ||
!this.canSharePage(gBrowser.currentURI);
// also update the relevent command's disabled state so the keyboard
// shortcut only works when available.
let cmd = document.getElementById("Social:SharePage");
cmd.setAttribute("disabled", shareButton.hidden ? "true" : "false");
},
onClick: function SSB_onClick(aEvent) {
@ -592,7 +612,6 @@ let SocialShareButton = {
var SocialMenu = {
populate: function SocialMenu_populate() {
// This menu is only accessible through keyboard navigation.
let submenu = document.getElementById("menu_social-statusarea-popup");
let ambientMenuItems = submenu.getElementsByClassName("ambient-menuitem");
while (ambientMenuItems.length)
@ -601,7 +620,7 @@ var SocialMenu = {
let separator = document.getElementById("socialAmbientMenuSeparator");
separator.hidden = true;
let provider = Social.provider;
if (Social.active && provider) {
if (provider && provider.enabled) {
let iconNames = Object.keys(provider.ambientNotificationIcons);
for (let name of iconNames) {
let icon = provider.ambientNotificationIcons[name];
@ -645,7 +664,6 @@ var SocialToolbar = {
updateButtonHiddenState: function SocialToolbar_updateButtonHiddenState() {
let tbi = document.getElementById("social-toolbar-item");
tbi.hidden = !Social.active;
let socialEnabled = Social.enabled;
for (let className of ["social-statusarea-separator", "social-statusarea-user"]) {
for (let element of document.getElementsByClassName(className))

Просмотреть файл

@ -105,6 +105,7 @@ XPCOMUtils.defineLazyGetter(this, "PopupNotifications", function () {
document.getElementById("notification-popup-box"));
} catch (ex) {
Cu.reportError(ex);
return null;
}
});
@ -135,6 +136,7 @@ XPCOMUtils.defineLazyGetter(this, "Tilt", function() {
XPCOMUtils.defineLazyModuleGetter(this, "Social",
"resource:///modules/Social.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PageThumbs",
"resource:///modules/PageThumbs.jsm");
@ -3310,7 +3312,7 @@ const BrowserSearch = {
win.BrowserSearch.webSearch();
} else {
// If there are no open browser windows, open a new one
function observer(subject, topic, data) {
var observer = function observer(subject, topic, data) {
if (subject == win) {
BrowserSearch.webSearch();
Services.obs.removeObserver(observer, "browser-delayed-startup-finished");
@ -4156,12 +4158,12 @@ var XULBrowserWindow = {
}
// Utility functions for disabling find
function shouldDisableFind(aDocument) {
var shouldDisableFind = function shouldDisableFind(aDocument) {
let docElt = aDocument.documentElement;
return docElt && docElt.getAttribute("disablefastfind") == "true";
}
function disableFindCommands(aDisable) {
var disableFindCommands = function disableFindCommands(aDisable) {
let findCommands = [document.getElementById("cmd_find"),
document.getElementById("cmd_findAgain"),
document.getElementById("cmd_findPrevious")];
@ -4173,7 +4175,7 @@ var XULBrowserWindow = {
}
}
function onContentRSChange(e) {
var onContentRSChange = function onContentRSChange(e) {
if (e.target.readyState != "interactive" && e.target.readyState != "complete")
return;
@ -5153,7 +5155,7 @@ function getBrowserSelection(aCharLen) {
// try getting a selected text in text input.
if (!selection) {
let element = commandDispatcher.focusedElement;
function isOnTextInput(elem) {
var isOnTextInput = function isOnTextInput(elem) {
// we avoid to return a value if a selection is in password field.
// ref. bug 565717
return elem instanceof HTMLTextAreaElement ||
@ -6276,7 +6278,7 @@ function BrowserOpenAddonsMgr(aView) {
let emWindow;
let browserWindow;
function receivePong(aSubject, aTopic, aData) {
var receivePong = function receivePong(aSubject, aTopic, aData) {
let browserWin = aSubject.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShellTreeItem)
@ -7454,6 +7456,7 @@ XPCOMUtils.defineLazyGetter(this, "HUDConsoleUI", function () {
}
catch (ex) {
Components.utils.reportError(ex);
return null;
}
});

Просмотреть файл

@ -662,7 +662,8 @@
class="chromeclass-toolbar-additional"
removable="false"
title="&socialToolbar.title;"
hidden="true">
hidden="true"
observes="socialActiveBroadcaster">
<toolbarbutton id="social-provider-button"
class="toolbarbutton-1"
type="menu">

Просмотреть файл

@ -269,6 +269,9 @@ _BROWSER_FILES = \
browser_tabDrop.js \
browser_lastAccessedTab.js \
browser_bug734076.js \
browser_bug812562.js \
blockPluginVulnerableUpdatable.xml \
blockPluginVulnerableNoUpdate.xml \
browser_social.js \
browser_social_toolbar.js \
browser_social_shareButton.js \
@ -304,7 +307,7 @@ ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING
_BROWSER_FILES += \
browser_bug763468_perwindowpb.js \
browser_private_browsing_window.js \
$(filter disabled-until-bug-722850, browser_save_link-perwindowpb.js) \
browser_save_link-perwindowpb.js \
$(NULL)
else
_BROWSER_FILES += \

Просмотреть файл

@ -0,0 +1,11 @@
<?xml version="1.0"?>
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1336406310000">
<emItems>
</emItems>
<pluginItems>
<pluginItem blockID="p9999">
<match name="filename" exp="libnptest\.so|nptest\.dll|Test\.plugin" />
<versionRange severity="0" vulnerabilitystatus="2"></versionRange>
</pluginItem>
</pluginItems>
</blocklist>

Просмотреть файл

@ -0,0 +1,11 @@
<?xml version="1.0"?>
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1336406310000">
<emItems>
</emItems>
<pluginItems>
<pluginItem blockID="p9999">
<match name="filename" exp="libnptest\.so|nptest\.dll|Test\.plugin" />
<versionRange severity="0" vulnerabilitystatus="1"></versionRange>
</pluginItem>
</pluginItems>
</blocklist>

Просмотреть файл

@ -0,0 +1,81 @@
var gHttpTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
var gTestBrowser = null;
var gNextTest = null;
Components.utils.import("resource://gre/modules/Services.jsm");
function test() {
waitForExplicitFinish();
registerCleanupFunction(function() {
Services.prefs.clearUserPref("plugins.click_to_play");
});
Services.prefs.setBoolPref("plugins.click_to_play", false);
var newTab = gBrowser.addTab();
gBrowser.selectedTab = newTab;
gTestBrowser = gBrowser.selectedBrowser;
gTestBrowser.addEventListener("load", pageLoad, true);
setAndUpdateBlocklist(gHttpTestRoot + "blockPluginVulnerableUpdatable.xml",
function() {
prepareTest(testPart1, gHttpTestRoot + "plugin_test.html");
});
}
function finishTest() {
gTestBrowser.removeEventListener("load", pageLoad, true);
gBrowser.removeCurrentTab();
window.focus();
resetBlocklist(finish);
}
function pageLoad(aEvent) {
// The plugin events are async dispatched and can come after the load event
// This just allows the events to fire before we then go on to test the states
if (gNextTest != null)
executeSoon(gNextTest);
}
function prepareTest(nextTest, url) {
gNextTest = nextTest;
gTestBrowser.contentWindow.location = url;
}
// Tests that the going back will reshow the notification for click-to-play
// blocklisted plugins (part 1/4)
function testPart1() {
var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(popupNotification, "test part 1: Should have a click-to-play notification");
var plugin = gTestBrowser.contentDocument.getElementById("test");
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
is(objLoadingContent.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_UPDATABLE, "test part 1: plugin fallback type should be PLUGIN_VULNERABLE_UPDATABLE");
ok(!objLoadingContent.activated, "test part 1: plugin should not be activated");
prepareTest(testPart2, "about:blank");
}
function testPart2() {
var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(!popupNotification, "test part 2: Should not have a click-to-play notification");
var plugin = gTestBrowser.contentDocument.getElementById("test");
ok(!plugin, "test part 2: Should not have a plugin in this page");
Services.obs.addObserver(testPart3, "PopupNotifications-updateNotShowing", false);
gTestBrowser.contentWindow.history.back();
}
function testPart3() {
Services.obs.removeObserver(testPart3, "PopupNotifications-updateNotShowing", false);
var condition = function() PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
waitForCondition(condition, testPart4, "test part 3: waited too long for click-to-play-plugin notification");
}
function testPart4() {
var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(popupNotification, "test part 4: Should have a click-to-play notification");
var plugin = gTestBrowser.contentDocument.getElementById("test");
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
is(objLoadingContent.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_UPDATABLE, "test part 4: plugin fallback type should be PLUGIN_VULNERABLE_UPDATABLE");
ok(!objLoadingContent.activated, "test part 4: plugin should not be activated");
finishTest();
}

Просмотреть файл

@ -402,9 +402,26 @@ function test12c() {
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(objLoadingContent.activated, "Test 12c, Plugin should be activated");
prepareTest(test12d, gHttpTestRoot + "plugin_two_types.html");
}
// Test that the "Always" permission, when set for just the Test plugin,
// does not also allow the Second Test plugin.
function test12d() {
var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(popupNotification, "Test 12d, Should have a click-to-play notification");
var test = gTestBrowser.contentDocument.getElementById("test");
var secondtestA = gTestBrowser.contentDocument.getElementById("secondtestA");
var secondtestB = gTestBrowser.contentDocument.getElementById("secondtestB");
var objLoadingContent = test.QueryInterface(Ci.nsIObjectLoadingContent);
ok(objLoadingContent.activated, "Test 12d, Test plugin should be activated");
var objLoadingContent = secondtestA.QueryInterface(Ci.nsIObjectLoadingContent);
ok(!objLoadingContent.activated, "Test 12d, Second Test plugin (A) should not be activated");
var objLoadingContent = secondtestB.QueryInterface(Ci.nsIObjectLoadingContent);
ok(!objLoadingContent.activated, "Test 12d, Second Test plugin (B) should not be activated");
Services.perms.removeAll();
gNextTest = test13a;
gTestBrowser.reload();
prepareTest(test13a, gHttpTestRoot + "plugin_clickToPlayDeny.html");
}
// Tests that the "Deny Always" permission works for click-to-play plugins (part 1/3)
@ -444,6 +461,55 @@ function test13c() {
var overlay = gTestBrowser.contentDocument.getAnonymousElementByAttribute(plugin, "class", "mainBox");
ok(overlay.style.visibility == "hidden", "Test 13c, Plugin should not have visible overlay");
prepareTest(test13d, gHttpTestRoot + "plugin_two_types.html");
}
// Test that the "Deny Always" permission, when set for just the Test plugin,
// does not also block the Second Test plugin (i.e. it gets an overlay and
// there's a notification and everything).
function test13d() {
var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(popupNotification, "Test 13d, Should have a click-to-play notification");
var test = gTestBrowser.contentDocument.getElementById("test");
var objLoadingContent = test.QueryInterface(Ci.nsIObjectLoadingContent);
var overlay = gTestBrowser.contentDocument.getAnonymousElementByAttribute(test, "class", "mainBox");
ok(overlay.style.visibility == "hidden", "Test 13d, Test plugin should not have visible overlay");
ok(!objLoadingContent.activated, "Test 13d, Test plugin should not be activated");
var secondtestA = gTestBrowser.contentDocument.getElementById("secondtestA");
var objLoadingContent = secondtestA.QueryInterface(Ci.nsIObjectLoadingContent);
var overlay = gTestBrowser.contentDocument.getAnonymousElementByAttribute(secondtestA, "class", "mainBox");
ok(overlay.style.visibility != "hidden", "Test 13d, Test plugin should have visible overlay");
ok(!objLoadingContent.activated, "Test 13d, Second Test plugin (A) should not be activated");
var secondtestB = gTestBrowser.contentDocument.getElementById("secondtestB");
var objLoadingContent = secondtestB.QueryInterface(Ci.nsIObjectLoadingContent);
var overlay = gTestBrowser.contentDocument.getAnonymousElementByAttribute(secondtestB, "class", "mainBox");
ok(overlay.style.visibility != "hidden", "Test 13d, Test plugin should have visible overlay");
ok(!objLoadingContent.activated, "Test 13d, Second Test plugin (B) should not be activated");
var condition = function() objLoadingContent.activated;
// "click" "Activate All Plugins"
popupNotification.mainAction.callback();
waitForCondition(condition, test13e, "Test 13d, Waited too long for plugin to activate");
}
// Test that clicking "Activate All Plugins" won't activate plugins that
// have previously been "Deny Always"-ed.
function test13e() {
var test = gTestBrowser.contentDocument.getElementById("test");
var objLoadingContent = test.QueryInterface(Ci.nsIObjectLoadingContent);
ok(!objLoadingContent.activated, "Test 13e, Test plugin should not be activated");
var secondtestA = gTestBrowser.contentDocument.getElementById("secondtestA");
var objLoadingContent = secondtestA.QueryInterface(Ci.nsIObjectLoadingContent);
ok(objLoadingContent.activated, "Test 13e, Second Test plugin (A) should be activated");
var secondtestB = gTestBrowser.contentDocument.getElementById("secondtestB");
var objLoadingContent = secondtestB.QueryInterface(Ci.nsIObjectLoadingContent);
ok(objLoadingContent.activated, "Test 13e, Second Test plugin (B) should be activated");
Services.perms.removeAll();
Services.prefs.setBoolPref("plugins.click_to_play", false);
prepareTest(test14, gTestRoot + "plugin_test2.html");
@ -527,53 +593,10 @@ function test17() {
var missingNotification = PopupNotifications.getNotification("missing-plugins", gTestBrowser);
ok(!missingNotification, "Test 17, Should not have a missing plugin notification");
registerFakeBlocklistService(Ci.nsIBlocklistService.STATE_VULNERABLE_UPDATE_AVAILABLE);
prepareTest(test18a, gHttpTestRoot + "plugin_test.html");
}
const Cr = Components.results;
const Cm = Components.manager;
const Cc = Components.classes;
const gReg = Cm.QueryInterface(Ci.nsIComponentRegistrar);
const gRealBlocklistServiceCID = Cc["@mozilla.org/extensions/blocklist;1"];
const gFakeBlocklistServiceCID = Components.ID("{614b68a0-3c53-4ec0-8146-28cc1e25f8a1}");
var gFactory = null;
function registerFakeBlocklistService(blockState) {
var BlocklistService = {
getPluginBlocklistState: function(plugin, appVersion, toolkitVersion) {
return blockState;
},
classID: gFakeBlocklistServiceCID,
QueryInterface: XPCOMUtils.generateQI([Ci.nsIBlocklistService])
};
gFactory = {
createInstance: function(outer, iid) {
if (outer != null)
throw Cr.NS_ERROR_NO_AGGREGATION;
return BlocklistService.QueryInterface(iid);
}
};
gReg.registerFactory(gFakeBlocklistServiceCID,
"Fake Blocklist Service",
"@mozilla.org/extensions/blocklist;1",
gFactory);
}
function unregisterFakeBlocklistService() {
if (gFactory != null ) {
gReg.unregisterFactory(gFakeBlocklistServiceCID, gFactory);
gFactory = null;
// This should restore the original blocklist service:
gReg.registerFactory(gRealBlocklistServiceCID,
"Blocklist Service",
"@mozilla.org/extensions/blocklist;1",
null);
}
setAndUpdateBlocklist(gHttpTestRoot + "blockPluginVulnerableUpdatable.xml",
function() {
prepareTest(test18a, gHttpTestRoot + "plugin_test.html");
});
}
// Tests a vulnerable, updatable plugin
@ -613,9 +636,10 @@ function test18b() {
var overlay = doc.getAnonymousElementByAttribute(plugin, "class", "mainBox");
ok(overlay.style.visibility != "hidden", "Test 18b, Plugin overlay should exist, not be hidden");
unregisterFakeBlocklistService();
registerFakeBlocklistService(Ci.nsIBlocklistService.STATE_VULNERABLE_NO_UPDATE);
prepareTest(test18c, gHttpTestRoot + "plugin_test.html");
setAndUpdateBlocklist(gHttpTestRoot + "blockPluginVulnerableNoUpdate.xml",
function() {
prepareTest(test18c, gHttpTestRoot + "plugin_test.html");
});
}
// Tests a vulnerable plugin with no update
@ -658,10 +682,10 @@ function test18e() {
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(objLoadingContent.activated, "Test 18e, Plugin should be activated");
unregisterFakeBlocklistService();
Services.perms.removeAll();
prepareTest(test19a, gTestRoot + "plugin_test.html");
resetBlocklist(function () {
prepareTest(test19a, gTestRoot + "plugin_test.html");
});
}
// Tests that clicking the icon of the overlay activates the plugin
@ -974,5 +998,123 @@ function test23() {
is(objLoadingContent.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY, "Test 23, Plugin should be click-to-play");
ok(!pluginNode.activated, "Test 23, plugin node should not be activated");
prepareTest(test24a, gHttpTestRoot + "plugin_test.html");
}
// Test that "always allow"-ing a plugin will not allow it when it becomes
// blocklisted.
function test24a() {
var notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(notification, "Test 24a, Should have a click-to-play notification");
var plugin = gTestBrowser.contentDocument.getElementById("test");
ok(plugin, "Test 24a, Found plugin in page");
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
is(objLoadingContent.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY, "Test 24a, Plugin should be click-to-play");
ok(!objLoadingContent.activated, "Test 24a, plugin should not be activated");
// simulate "always allow"
notification.secondaryActions[0].callback();
prepareTest(test24b, gHttpTestRoot + "plugin_test.html");
}
// did the "always allow" work as intended?
function test24b() {
var notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(!notification, "Test 24b, Should not have a click-to-play notification");
var plugin = gTestBrowser.contentDocument.getElementById("test");
ok(plugin, "Test 24b, Found plugin in page");
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(objLoadingContent.activated, "Test 24b, plugin should be activated");
setAndUpdateBlocklist(gHttpTestRoot + "blockPluginVulnerableUpdatable.xml",
function() {
prepareTest(test24c, gHttpTestRoot + "plugin_test.html");
});
}
// the plugin is now blocklisted, so it should not automatically load
function test24c() {
var notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(notification, "Test 24c, Should have a click-to-play notification");
var plugin = gTestBrowser.contentDocument.getElementById("test");
ok(plugin, "Test 24c, Found plugin in page");
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
is(objLoadingContent.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_UPDATABLE, "Test 24c, Plugin should be vulnerable/updatable");
ok(!objLoadingContent.activated, "Test 24c, plugin should not be activated");
// simulate "always allow"
notification.secondaryActions[0].callback();
prepareTest(test24d, gHttpTestRoot + "plugin_test.html");
}
// We should still be able to always allow a plugin after we've seen that it's
// blocklisted.
function test24d() {
var notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(!notification, "Test 24d, Should not have a click-to-play notification");
var plugin = gTestBrowser.contentDocument.getElementById("test");
ok(plugin, "Test 24d, Found plugin in page");
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(objLoadingContent.activated, "Test 24d, plugin should be activated");
Services.perms.removeAll();
resetBlocklist(function () {
prepareTest(test25a, gHttpTestRoot + "plugin_test.html");
});
}
// Test that clicking "always allow" or "always deny" doesn't affect plugins
// that already have permission given to them
function test25a() {
var notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(notification, "Test 25a, Should have a click-to-play notification");
var plugin = gTestBrowser.contentDocument.getElementById("test");
ok(plugin, "Test 25a, Found plugin in page");
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(!objLoadingContent.activated, "Test 25a, plugin should not be activated");
// simulate "always allow"
notification.secondaryActions[0].callback();
prepareTest(test25b, gHttpTestRoot + "plugin_two_types.html");
}
function test25b() {
var notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(notification, "Test 25b, Should have a click-to-play notification");
var test = gTestBrowser.contentDocument.getElementById("test");
ok(test, "Test 25b, Found test plugin in page");
var objLoadingContent = test.QueryInterface(Ci.nsIObjectLoadingContent);
ok(objLoadingContent.activated, "Test 25b, test plugin should be activated");
var secondtest = gTestBrowser.contentDocument.getElementById("secondtestA");
ok(secondtest, "Test 25b, Found second test plugin in page");
var objLoadingContent = secondtest.QueryInterface(Ci.nsIObjectLoadingContent);
ok(!objLoadingContent.activated, "Test 25b, second test plugin should not be activated");
// simulate "always deny"
notification.secondaryActions[1].callback();
prepareTest(test25c, gHttpTestRoot + "plugin_two_types.html");
}
// we should have one plugin allowed to activate and the other plugin(s) denied
// (so it should have an invisible overlay)
function test25c() {
var notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(!notification, "Test 25c, Should not have a click-to-play notification");
var test = gTestBrowser.contentDocument.getElementById("test");
ok(test, "Test 25c, Found test plugin in page");
var objLoadingContent = test.QueryInterface(Ci.nsIObjectLoadingContent);
ok(objLoadingContent.activated, "Test 25c, test plugin should be activated");
var secondtest = gTestBrowser.contentDocument.getElementById("secondtestA");
ok(secondtest, "Test 25c, Found second test plugin in page");
var objLoadingContent = secondtest.QueryInterface(Ci.nsIObjectLoadingContent);
ok(!objLoadingContent.activated, "Test 25c, second test plugin should not be activated");
var overlay = gTestBrowser.contentDocument.getAnonymousElementByAttribute(secondtest, "class", "mainBox");
ok(overlay.style.visibility == "hidden", "Test 25c, second test plugin should not have visible overlay");
Services.perms.removeAll();
finishTest();
}

Просмотреть файл

@ -46,7 +46,7 @@ var tests = {
toolsPopup.removeEventListener("popupshown", ontoolspopupshownNoAmbient);
let socialToggleMore = document.getElementById("menu_socialAmbientMenu");
ok(socialToggleMore, "Keyboard accessible social menu should exist");
is(socialToggleMore.querySelectorAll("menuitem").length, 5, "The minimum number of menuitems is two when there are no ambient notifications.");
is(socialToggleMore.querySelectorAll("menuitem").length, 6, "The minimum number of menuitems is two when there are no ambient notifications.");
is(socialToggleMore.hidden, false, "Menu should be visible since we show some non-ambient notifications in the menu.");
toolsPopup.hidePopup();
next();
@ -104,7 +104,7 @@ var tests = {
toolsPopup.removeEventListener("popupshown", ontoolspopupshownAmbient);
let socialToggleMore = document.getElementById("menu_socialAmbientMenu");
ok(socialToggleMore, "Keyboard accessible social menu should exist");
is(socialToggleMore.querySelectorAll("menuitem").length, 8, "The number of menuitems is minimum plus three ambient notification menuitems.");
is(socialToggleMore.querySelectorAll("menuitem").length, 9, "The number of menuitems is minimum plus three ambient notification menuitems.");
is(socialToggleMore.hidden, false, "Menu is visible when ambient notifications have label & menuURL");
let menuitem = socialToggleMore.querySelector(".ambient-menuitem");
is(menuitem.getAttribute("label"), "Test Ambient 1", "Keyboard accessible ambient menuitem should have specified label");

Просмотреть файл

@ -201,6 +201,27 @@ function runSocialTests(tests, cbPreTest, cbPostTest, cbFinish) {
runNextTest();
}
function updateBlocklist(aCallback) {
var blocklistNotifier = Cc["@mozilla.org/extensions/blocklist;1"]
.getService(Ci.nsITimerCallback);
var observer = function() {
aCallback();
Services.obs.removeObserver(observer, "blocklist-updated");
};
Services.obs.addObserver(observer, "blocklist-updated", false);
blocklistNotifier.notify(null);
}
function setAndUpdateBlocklist(aURL, aCallback) {
Services.prefs.setCharPref("extensions.blocklist.url", aURL);
updateBlocklist(aCallback);
}
function resetBlocklist(aCallback) {
Services.prefs.clearUserPref("extensions.blocklist.url");
updateBlocklist(aCallback);
}
function whenNewWindowLoaded(aOptions, aCallback) {
let win = OpenBrowserWindow(aOptions);
win.addEventListener("load", function onLoad() {

Просмотреть файл

@ -10,19 +10,29 @@ relativesrcdir = @relativesrcdir@
include $(DEPTH)/config/autoconf.mk
MOCHITEST_BROWSER_FILES = browser_405664.js \
browser_addEngine.js \
browser_contextmenu.js \
testEngine.xml \
testEngine_mozsearch.xml \
testEngine.src \
browser_426329.js \
426329.xml \
browser_483086.js \
483086-1.xml \
483086-2.xml \
test.html \
browser_private_search.js \
$(NULL)
MOCHITEST_BROWSER_FILES = \
browser_405664.js \
browser_addEngine.js \
browser_contextmenu.js \
testEngine.xml \
testEngine_mozsearch.xml \
testEngine.src \
browser_426329.js \
426329.xml \
browser_483086.js \
483086-1.xml \
483086-2.xml \
test.html \
$(NULL)
ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING
MOCHITEST_BROWSER_FILES += \
browser_private_search_perwindowpb.js \
$(NULL)
else
MOCHITEST_BROWSER_FILES += \
browser_private_search.js \
$(NULL)
endif
include $(topsrcdir)/config/rules.mk

Просмотреть файл

@ -22,7 +22,7 @@ function doPrivateTest(searchBar) {
popup.addEventListener("popupshowing", function showing() {
let entries = getMenuEntries(searchBar);
for (var i = 0; i < entries.length; i++)
isnot(entries[0], "private test", "shouldn't see private autocomplete entries");
isnot(entries[i], "private test", "shouldn't see private autocomplete entries");
popup.removeEventListener("popupshowing", showing, false);
searchBar.textbox.toggleHistoryPopup();

Просмотреть файл

@ -0,0 +1,115 @@
// This test performs a search in a public window, then a different
// search in a private window, and then checks in the public window
// whether there is an autocomplete entry for the private search.
function test() {
waitForExplicitFinish();
let engineURL =
"http://mochi.test:8888/browser/browser/components/search/test/";
let windowsToClose = [];
registerCleanupFunction(function() {
let engine = Services.search.getEngineByName("Bug 426329");
Services.search.removeEngine(engine);
windowsToClose.forEach(function(win) {
win.close();
});
});
function onPageLoad(aWin, aCallback) {
aWin.gBrowser.addEventListener("DOMContentLoaded", function load(aEvent) {
let doc = aEvent.originalTarget;
info(doc.location.href);
if (doc.location.href.indexOf(engineURL) != -1) {
aWin.gBrowser.removeEventListener("DOMContentLoaded", load, false);
aCallback();
}
}, false);
}
function performSearch(aWin, aIsPrivate, aCallback) {
let searchBar = aWin.BrowserSearch.searchBar;
ok(searchBar, "got search bar");
onPageLoad(aWin, aCallback);
searchBar.value = aIsPrivate ? "private test" : "public test";
searchBar.focus();
EventUtils.synthesizeKey("VK_RETURN", {}, aWin);
}
function addEngine(aCallback) {
function observer(aSub, aTopic, aData) {
switch (aData) {
case "engine-current":
ok(Services.search.currentEngine.name == "Bug 426329",
"currentEngine set");
aCallback();
break;
}
}
Services.obs.addObserver(observer, "browser-search-engine-modified", false);
Services.search.addEngine(
engineURL + "426329.xml", Ci.nsISearchEngine.DATA_XML,
"data:image/x-icon,%00", false);
}
function testOnWindow(aIsPrivate, aCallback) {
let win = OpenBrowserWindow({ private: aIsPrivate });
win.addEventListener("load", function onLoad() {
win.removeEventListener("load", onLoad, false);
windowsToClose.push(win);
executeSoon(function() aCallback(win));
}, false);
}
addEngine(function() {
testOnWindow(false, function(win) {
performSearch(win, false, function() {
testOnWindow(true, function(win) {
performSearch(win, true, function() {
testOnWindow(false, function(win) {
checkSearchPopup(win, finish);
});
});
});
});
});
});
}
function checkSearchPopup(aWin, aCallback) {
let searchBar = aWin.BrowserSearch.searchBar;
searchBar.value = "p";
searchBar.focus();
let popup = searchBar.textbox.popup;
popup.addEventListener("popupshowing", function showing() {
popup.removeEventListener("popupshowing", showing, false);
let entries = getMenuEntries(searchBar);
for (let i = 0; i < entries.length; i++) {
isnot(entries[i], "private test",
"shouldn't see private autocomplete entries");
}
searchBar.textbox.toggleHistoryPopup();
searchBar.value = "";
aCallback();
}, false);
searchBar.textbox.showHistoryPopup();
}
function getMenuEntries(searchBar) {
let entries = [];
let autocompleteMenu = searchBar.textbox.popup;
// Could perhaps pull values directly from the controller, but it seems
// more reliable to test the values that are actually in the tree?
let column = autocompleteMenu.tree.columns[0];
let numRows = autocompleteMenu.tree.view.rowCount;
for (let i = 0; i < numRows; i++) {
entries.push(autocompleteMenu.tree.view.getValueAt(i, column));
}
return entries;
}

Просмотреть файл

@ -509,7 +509,7 @@ StackFrames.prototype = {
// If an error was thrown during the evaluation of the watch expressions,
// then at least one expression evaluation could not be performed.
if (this.currentEvaluation.throw) {
DebuggerView.WatchExpressions.removeExpression(0);
DebuggerView.WatchExpressions.removeExpressionAt(0);
DebuggerController.StackFrames.syncWatchExpressions();
return;
}
@ -600,11 +600,15 @@ StackFrames.prototype = {
// If watch expressions evaluation results are available, create a scope
// to contain all the values.
if (watchExpressionsEvaluation) {
if (this.syncedWatchExpressions && watchExpressionsEvaluation) {
let label = L10N.getStr("watchExpressionsScopeLabel");
let arrow = L10N.getStr("watchExpressionsSeparatorLabel");
let scope = DebuggerView.Variables.addScope(label);
scope.separator = arrow;
scope.allowNameInput = true;
scope.allowDeletion = true;
scope.switch = DebuggerView.WatchExpressions.switchExpression;
scope.delete = DebuggerView.WatchExpressions.deleteExpression;
// The evaluation hasn't thrown, so display the returned results and
// always expand the watch expressions scope by default.
@ -939,6 +943,7 @@ StackFrames.prototype = {
this.syncedWatchExpressions =
this.currentWatchExpressions = null;
}
this.currentFrame = null;
this._onFrames();
},
@ -1321,11 +1326,10 @@ Breakpoints.prototype = {
this.activeThread.setBreakpoint(aLocation, function(aResponse, aBreakpointClient) {
let { url, line } = aResponse.actualLocation || aLocation;
// Prevent this new breakpoint from being repositioned on top of an
// already existing one.
// If the response contains a breakpoint that exists in the cache, prevent
// it from being shown in the source editor at an incorrect position.
if (this.getBreakpoint(url, line)) {
this._hideBreakpoint(aBreakpointClient);
aBreakpointClient.remove();
return;
}

Просмотреть файл

@ -945,6 +945,8 @@ create({ constructor: BreakpointsView, proto: MenuContainer.prototype }, {
function WatchExpressionsView() {
dumpn("WatchExpressionsView was instantiated");
MenuContainer.call(this);
this.switchExpression = this.switchExpression.bind(this);
this.deleteExpression = this.deleteExpression.bind(this);
this._createItemView = this._createItemView.bind(this);
this._onClick = this._onClick.bind(this);
this._onClose = this._onClose.bind(this);
@ -1028,11 +1030,54 @@ create({ constructor: WatchExpressionsView, proto: MenuContainer.prototype }, {
* @param number aIndex
* The index used to identify the watch expression.
*/
removeExpression: function DVWE_removeExpression(aIndex) {
removeExpressionAt: function DVWE_removeExpressionAt(aIndex) {
this.remove(this._cache[aIndex]);
this._cache.splice(aIndex, 1);
},
/**
* Changes the watch expression corresponding to the specified variable item.
*
* @param Variable aVar
* The variable representing the watch expression evaluation.
* @param string aExpression
* The new watch expression text.
*/
switchExpression: function DVWE_switchExpression(aVar, aExpression) {
let expressionItem =
[i for (i of this._cache) if (i.attachment.expression == aVar.name)][0];
// Remove the watch expression if it's going to be a duplicate.
if (!aExpression || this.getExpressions().indexOf(aExpression) != -1) {
this.deleteExpression(aVar);
return;
}
// Save the watch expression code string.
expressionItem.attachment.expression = aExpression;
expressionItem.target.inputNode.value = aExpression;
// Synchronize with the controller's watch expressions store.
DebuggerController.StackFrames.syncWatchExpressions();
},
/**
* Removes the watch expression corresponding to the specified variable item.
*
* @param Variable aVar
* The variable representing the watch expression evaluation.
*/
deleteExpression: function DVWE_deleteExpression(aVar) {
let expressionItem =
[i for (i of this._cache) if (i.attachment.expression == aVar.name)][0];
// Remove the watch expression at its respective index.
this.removeExpressionAt(this._cache.indexOf(expressionItem));
// Synchronize with the controller's watch expressions store.
DebuggerController.StackFrames.syncWatchExpressions();
},
/**
* Gets the watch expression code string for an item in this container.
*
@ -1101,7 +1146,7 @@ create({ constructor: WatchExpressionsView, proto: MenuContainer.prototype }, {
*/
_onClose: function DVWE__onClose(e) {
let expressionItem = this.getItemForElement(e.target);
this.removeExpression(this._cache.indexOf(expressionItem));
this.removeExpressionAt(this._cache.indexOf(expressionItem));
// Synchronize with the controller's watch expressions store.
DebuggerController.StackFrames.syncWatchExpressions();
@ -1116,15 +1161,15 @@ create({ constructor: WatchExpressionsView, proto: MenuContainer.prototype }, {
_onBlur: function DVWE__onBlur({ target: textbox }) {
let expressionItem = this.getItemForElement(textbox);
let oldExpression = expressionItem.attachment.expression;
let newExpression = textbox.value;
let newExpression = textbox.value.trim();
// Remove the watch expression if it's empty.
if (!newExpression) {
this.removeExpression(this._cache.indexOf(expressionItem));
this.removeExpressionAt(this._cache.indexOf(expressionItem));
}
// Remove the watch expression if it's a duplicate.
else if (!oldExpression && this.getExpressions().indexOf(newExpression) != -1) {
this.removeExpression(this._cache.indexOf(expressionItem));
this.removeExpressionAt(this._cache.indexOf(expressionItem));
}
// Expression is eligible.
else {

Просмотреть файл

@ -34,10 +34,10 @@ ToolbarView.prototype = {
this._chromeGlobals = document.getElementById("chrome-globals");
this._scripts = document.getElementById("sources");
let resumeKey = LayoutHelpers.prettyKey(document.getElementById("resumeKey"));
let stepOverKey = LayoutHelpers.prettyKey(document.getElementById("stepOverKey"));
let stepInKey = LayoutHelpers.prettyKey(document.getElementById("stepInKey"));
let stepOutKey = LayoutHelpers.prettyKey(document.getElementById("stepOutKey"));
let resumeKey = LayoutHelpers.prettyKey(document.getElementById("resumeKey"), true);
let stepOverKey = LayoutHelpers.prettyKey(document.getElementById("stepOverKey"), true);
let stepInKey = LayoutHelpers.prettyKey(document.getElementById("stepInKey"), true);
let stepOutKey = LayoutHelpers.prettyKey(document.getElementById("stepOutKey"), true);
this._resumeTooltip = L10N.getFormatStr("resumeButtonTooltip", [resumeKey]);
this._pauseTooltip = L10N.getFormatStr("pauseButtonTooltip", [resumeKey]);
this._stepOverTooltip = L10N.getFormatStr("stepOverTooltip", [stepOverKey]);
@ -370,6 +370,20 @@ create({ constructor: SourcesView, proto: MenuContainer.prototype }, {
this._container.removeEventListener("click", this._onClick, false);
},
/**
* Sets the preferred source url to be displayed in this container.
* @param string aValue
*/
set preferredSource(aValue) {
this._preferredValue = aValue;
// Selects the element with the specified value in this container,
// if already inserted.
if (this.containsValue(aValue)) {
this.selectedValue = aValue;
}
},
/**
* The select listener for the sources container.
*/
@ -577,11 +591,11 @@ FilterView.prototype = {
this._variableOperatorButton = document.getElementById("variable-operator-button");
this._variableOperatorLabel = document.getElementById("variable-operator-label");
this._globalSearchKey = LayoutHelpers.prettyKey(document.getElementById("globalSearchKey"));
this._fileSearchKey = LayoutHelpers.prettyKey(document.getElementById("fileSearchKey"));
this._lineSearchKey = LayoutHelpers.prettyKey(document.getElementById("lineSearchKey"));
this._tokenSearchKey = LayoutHelpers.prettyKey(document.getElementById("tokenSearchKey"));
this._variableSearchKey = LayoutHelpers.prettyKey(document.getElementById("variableSearchKey"));
this._fileSearchKey = LayoutHelpers.prettyKey(document.getElementById("fileSearchKey"), true);
this._globalSearchKey = LayoutHelpers.prettyKey(document.getElementById("globalSearchKey"), true);
this._tokenSearchKey = LayoutHelpers.prettyKey(document.getElementById("tokenSearchKey"), true);
this._lineSearchKey = LayoutHelpers.prettyKey(document.getElementById("lineSearchKey"), true);
this._variableSearchKey = LayoutHelpers.prettyKey(document.getElementById("variableSearchKey"), true);
this._searchbox.addEventListener("click", this._onClick, false);
this._searchbox.addEventListener("select", this._onSearch, false);
@ -879,7 +893,7 @@ FilterView.prototype = {
// Perform a global search based on the specified operator.
if (isGlobal) {
if (isReturnKey && isDifferentToken) {
if (isReturnKey && (isDifferentToken || DebuggerView.GlobalSearch.hidden)) {
DebuggerView.GlobalSearch.performSearch(token);
} else {
DebuggerView.GlobalSearch[["focusNextMatch", "focusPrevMatch"][action]]();
@ -934,10 +948,10 @@ FilterView.prototype = {
},
/**
* Called when the source line filter key sequence was pressed.
* Called when the global search filter key sequence was pressed.
*/
_doLineSearch: function DVF__doLineSearch() {
this._doSearch(SEARCH_LINE_FLAG);
_doGlobalSearch: function DVF__doGlobalSearch() {
this._doSearch(SEARCH_GLOBAL_FLAG);
this._searchboxPanel.hidePopup();
},
@ -950,10 +964,10 @@ FilterView.prototype = {
},
/**
* Called when the global search filter key sequence was pressed.
* Called when the source line filter key sequence was pressed.
*/
_doGlobalSearch: function DVF__doGlobalSearch() {
this._doSearch(SEARCH_GLOBAL_FLAG);
_doLineSearch: function DVF__doLineSearch() {
this._doSearch(SEARCH_LINE_FLAG);
this._searchboxPanel.hidePopup();
},
@ -974,10 +988,13 @@ FilterView.prototype = {
_tokenOperatorLabel: null,
_lineOperatorButton: null,
_lineOperatorLabel: null,
_globalSearchKey: "",
_variableOperatorButton: null,
_variableOperatorLabel: null,
_fileSearchKey: "",
_lineSearchKey: "",
_globalSearchKey: "",
_tokenSearchKey: "",
_lineSearchKey: "",
_variableSearchKey: "",
_target: null,
_prevSearchedFile: "",
_prevSearchedLine: -1,

Просмотреть файл

@ -15,8 +15,8 @@ const GLOBAL_SEARCH_LINE_MAX_LENGTH = 300; // chars
const GLOBAL_SEARCH_EXPAND_MAX_RESULTS = 50;
const GLOBAL_SEARCH_ACTION_MAX_DELAY = 1500; // ms
const SEARCH_GLOBAL_FLAG = "!";
const SEARCH_LINE_FLAG = ":";
const SEARCH_TOKEN_FLAG = "#";
const SEARCH_LINE_FLAG = ":";
const SEARCH_VARIABLE_FLAG = "*";
/**

Просмотреть файл

@ -35,12 +35,12 @@
oncommand="DebuggerView.Toolbar._onStepOutPressed()"/>
<command id="fileSearchCommand"
oncommand="DebuggerView.Filtering._doFileSearch()"/>
<command id="lineSearchCommand"
oncommand="DebuggerView.Filtering._doLineSearch()"/>
<command id="tokenSearchCommand"
oncommand="DebuggerView.Filtering._doTokenSearch()"/>
<command id="globalSearchCommand"
oncommand="DebuggerView.Filtering._doGlobalSearch()"/>
<command id="tokenSearchCommand"
oncommand="DebuggerView.Filtering._doTokenSearch()"/>
<command id="lineSearchCommand"
oncommand="DebuggerView.Filtering._doLineSearch()"/>
<command id="variableSearchCommand"
oncommand="DebuggerView.Filtering._doVariableSearch()"/>
<command id="addBreakpointCommand"
@ -73,10 +73,33 @@
<menuseparator/>
<menuitem id="se-cMenu-selectAll"/>
<menuseparator/>
<menuitem id="se-cMenu-find"/>
<menuitem id="se-cMenu-findAgain"/>
<menuitem id="se-dbg-cMenu-findFile"
label="&debuggerUI.searchFile;"
accesskey="&debuggerUI.searchFile.key;"
key="fileSearchKey"
command="fileSearchCommand"/>
<menuitem id="se-dbg-cMenu-findGlobal"
label="&debuggerUI.searchGlobal;"
accesskey="&debuggerUI.searchGlobal.key;"
key="globalSearchKey"
command="globalSearchCommand"/>
<menuseparator/>
<menuitem id="se-cMenu-gotoLine"/>
<menuitem id="se-dbg-cMenu-findToken"
label="&debuggerUI.searchToken;"
accesskey="&debuggerUI.searchToken.key;"
key="tokenSearchKey"
command="tokenSearchCommand"/>
<menuitem id="se-dbg-cMenu-findLine"
label="&debuggerUI.searchLine;"
accesskey="&debuggerUI.searchLine.key;"
key="lineSearchKey"
command="lineSearchCommand"/>
<menuseparator/>
<menuitem id="se-dbg-cMenu-findVariable"
label="&debuggerUI.searchVariable;"
accesskey="&debuggerUI.searchVariable.key;"
key="variableSearchKey"
command="variableSearchCommand"/>
</menupopup>
<menupopup id="debuggerPrefsContextMenu"
position="before_end"
@ -105,48 +128,46 @@
</menupopup>
</popupset>
<keyset id="sourceEditorKeys"/>
<keyset id="debuggerKeys">
<key id="resumeKey"
keycode="VK_F6"
keycode="&debuggerUI.stepping.resume;"
command="resumeCommand"/>
<key id="stepOverKey"
keycode="VK_F7"
keycode="&debuggerUI.stepping.stepOver;"
command="stepOverCommand"/>
<key id="stepInKey"
keycode="VK_F8"
keycode="&debuggerUI.stepping.stepIn;"
command="stepInCommand"/>
<key id="stepOutKey"
keycode="VK_F8"
keycode="&debuggerUI.stepping.stepOut;"
modifiers="shift"
command="stepOutCommand"/>
<key id="fileSearchKey"
key="P"
modifiers="control shift"
key="&debuggerUI.searchFile.key;"
modifiers="accel"
command="fileSearchCommand"/>
<key id="lineSearchKey"
key="G"
modifiers="control shift"
command="lineSearchCommand"/>
<key id="tokenSearchKey"
key="T"
modifiers="control shift"
command="tokenSearchCommand"/>
<key id="globalSearchKey"
key="F"
modifiers="control shift"
key="&debuggerUI.searchGlobal.key;"
modifiers="accel alt"
command="globalSearchCommand"/>
<key id="tokenSearchKey"
key="&debuggerUI.searchToken.key;"
modifiers="accel"
command="tokenSearchCommand"/>
<key id="lineSearchKey"
key="&debuggerUI.searchLine.key;"
modifiers="accel"
command="lineSearchCommand"/>
<key id="variableSearchKey"
key="V"
modifiers="control shift"
key="&debuggerUI.searchVariable.key;"
modifiers="accel alt"
command="variableSearchCommand"/>
<key id="addBreakpointKey"
key="B"
key="&debuggerUI.seMenuBreak.key;"
modifiers="accel"
command="addBreakpointCommand"/>
<key id="addConditionalBreakpointKey"
key="B"
key="&debuggerUI.seMenuCondBreak.key;"
modifiers="accel shift"
command="addConditionalBreakpointCommand"/>
</keyset>
@ -181,6 +202,7 @@
<spacer flex="1"/>
<toolbarbutton id="toggle-panes"
class="devtools-toolbarbutton"
tooltiptext="&debuggerUI.panesButton.tooltip;"
tabindex="0"/>
<toolbarbutton id="debugger-options"
class="devtools-option-toolbarbutton"

Просмотреть файл

@ -33,6 +33,7 @@ MOCHITEST_BROWSER_TESTS = \
browser_dbg_propertyview-09.js \
browser_dbg_propertyview-10.js \
browser_dbg_propertyview-edit.js \
browser_dbg_propertyview-edit-watch.js \
browser_dbg_propertyview-data.js \
browser_dbg_propertyview-filter-01.js \
browser_dbg_propertyview-filter-02.js \
@ -44,6 +45,7 @@ MOCHITEST_BROWSER_TESTS = \
browser_dbg_propertyview-filter-08.js \
browser_dbg_propertyview-reexpand.js \
browser_dbg_reload-same-script.js \
browser_dbg_reload-preferred-script.js \
browser_dbg_pane-collapse.js \
browser_dbg_panesize.js \
browser_dbg_panesize-inner.js \

Просмотреть файл

@ -52,6 +52,20 @@ function test()
is(gWatch.getExpressions().length, 1,
"Duplicate watch expressions are automatically removed");
addAndCheckExpressions(2, 0, "a\t", true);
addAndCheckExpressions(2, 0, "a\r", true);
addAndCheckExpressions(2, 0, "a\n", true);
gDebugger.editor.focus();
is(gWatch.getExpressions().length, 1,
"Duplicate watch expressions are automatically removed");
addAndCheckExpressions(2, 0, "\ta", true);
addAndCheckExpressions(2, 0, "\ra", true);
addAndCheckExpressions(2, 0, "\na", true);
gDebugger.editor.focus();
is(gWatch.getExpressions().length, 1,
"Duplicate watch expressions are automatically removed");
addAndCheckCustomExpression(2, 0, "bazΩΩka");
addAndCheckCustomExpression(3, 0, "bambøøcha");
@ -194,7 +208,7 @@ function test()
}
function removeAndCheckExpression(total, index, string) {
gWatch.removeExpression(index);
gWatch.removeExpressionAt(index);
is(gWatch.getExpressions().length, total,
"There should be " + total + " watch expressions available (1)");

Просмотреть файл

@ -97,8 +97,6 @@ function test()
"#editMenuKeys not found");
ok(document.getElementById("sourceEditorCommands"),
"#sourceEditorCommands found");
ok(document.getElementById("sourceEditorKeys"),
"#sourceEditorKeys found");
// Map command ids to their expected disabled state.
let commands = {"se-cmd-undo": true, "se-cmd-redo": true,

Просмотреть файл

@ -0,0 +1,502 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
/**
* Make sure that the editing or removing watch expressions works properly.
*/
const TAB_URL = EXAMPLE_URL + "browser_dbg_watch-expressions.html";
var gPane = null;
var gTab = null;
var gDebuggee = null;
var gDebugger = null;
var gWatch = null;
var gVars = null;
requestLongerTimeout(2);
function test() {
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
gTab = aTab;
gDebuggee = aDebuggee;
gPane = aPane;
gDebugger = gPane.contentWindow;
gWatch = gDebugger.DebuggerView.WatchExpressions;
gVars = gDebugger.DebuggerView.Variables;
gDebugger.DebuggerController.StackFrames.autoScopeExpand = true;
gDebugger.DebuggerView.Variables.nonEnumVisible = false;
testFrameEval();
});
}
function testFrameEval() {
gDebugger.addEventListener("Debugger:FetchedWatchExpressions", function test() {
gDebugger.removeEventListener("Debugger:FetchedWatchExpressions", test, false);
Services.tm.currentThread.dispatch({ run: function() {
is(gDebugger.DebuggerController.activeThread.state, "paused",
"Should only be getting stack frames while paused.");
var localScope = gDebugger.DebuggerView.Variables._list.querySelectorAll(".scope")[1],
localNodes = localScope.querySelector(".details").childNodes,
aArg = localNodes[1],
varT = localNodes[3];
is(aArg.querySelector(".name").getAttribute("value"), "aArg",
"Should have the right name for 'aArg'.");
is(varT.querySelector(".name").getAttribute("value"), "t",
"Should have the right name for 't'.");
is(aArg.querySelector(".value").getAttribute("value"), "undefined",
"Should have the right initial value for 'aArg'.");
is(varT.querySelector(".value").getAttribute("value"), "\"Browser Debugger Watch Expressions Test\"",
"Should have the right initial value for 't'.");
is(gWatch._container._parent.querySelectorAll(".dbg-expression[hidden=true]").length, 5,
"There should be 5 hidden nodes in the watch expressions container");
is(gWatch._container._parent.querySelectorAll(".dbg-expression:not([hidden=true])").length, 0,
"There should be 0 visible nodes in the watch expressions container");
let label = gDebugger.L10N.getStr("watchExpressionsScopeLabel");
let scope = gVars._currHierarchy.get(label);
ok(scope, "There should be a wach expressions scope in the variables view");
is(scope._store.size, 5, "There should be 5 evaluations availalble");
is(scope.get("this")._isShown, true,
"Should have the right visibility state for 'this'.");
is(scope.get("this").target.querySelectorAll(".dbg-variables-delete").length, 1,
"Should have the one close button visible for 'this'.");
is(scope.get("this").name, "this",
"Should have the right name for 'this'.");
is(scope.get("this").value.type, "object",
"Should have the right value type for 'this'.");
is(scope.get("this").value.class, "Proxy",
"Should have the right value type for 'this'.");
is(scope.get("ermahgerd")._isShown, true,
"Should have the right visibility state for 'ermahgerd'.");
is(scope.get("ermahgerd").target.querySelectorAll(".dbg-variables-delete").length, 1,
"Should have the one close button visible for 'ermahgerd'.");
is(scope.get("ermahgerd").name, "ermahgerd",
"Should have the right name for 'ermahgerd'.");
is(scope.get("ermahgerd").value.type, "object",
"Should have the right value type for 'ermahgerd'.");
is(scope.get("ermahgerd").value.class, "Function",
"Should have the right value type for 'ermahgerd'.");
is(scope.get("aArg")._isShown, true,
"Should have the right visibility state for 'aArg'.");
is(scope.get("aArg").target.querySelectorAll(".dbg-variables-delete").length, 1,
"Should have the one close button visible for 'aArg'.");
is(scope.get("aArg").name, "aArg",
"Should have the right name for 'aArg'.");
is(scope.get("aArg").value, undefined,
"Should have the right value for 'aArg'.");
is(scope.get("document.title")._isShown, true,
"Should have the right visibility state for 'document.title'.");
is(scope.get("document.title").target.querySelectorAll(".dbg-variables-delete").length, 1,
"Should have the one close button visible for 'document.title'.");
is(scope.get("document.title").name, "document.title",
"Should have the right name for 'document.title'.");
is(scope.get("document.title").value, "42",
"Should have the right value for 'document.title'.");
is(typeof scope.get("document.title").value, "string",
"Should have the right value type for 'document.title'.");
is(scope.get("document.title = 42")._isShown, true,
"Should have the right visibility state for 'document.title = 42'.");
is(scope.get("document.title = 42").target.querySelectorAll(".dbg-variables-delete").length, 1,
"Should have the one close button visible for 'document.title = 42'.");
is(scope.get("document.title = 42").name, "document.title = 42",
"Should have the right name for 'document.title = 42'.");
is(scope.get("document.title = 42").value, 42,
"Should have the right value for 'document.title = 42'.");
is(typeof scope.get("document.title = 42").value, "number",
"Should have the right value type for 'document.title = 42'.");
testModification(scope.get("document.title = 42").target, test1, function(scope) {
testModification(scope.get("aArg").target, test2, function(scope) {
testModification(scope.get("aArg = 44").target, test3, function(scope) {
testModification(scope.get("document.title = 43").target, test4, function(scope) {
testModification(scope.get("document.title").target, test5, function(scope) {
testExprDeletion(scope.get("this").target, test6, function(scope) {
testExprDeletion(scope.get("ermahgerd").target, test7, function(scope) {
resumeAndFinish();
}, 44, 0, true);
}, 44);
}, " \t\r\n", "\"43\"", 44, 1, true);
}, " \t\r\ndocument.title \t\r\n", "\"43\"", 44);
}, " \t\r\ndocument.title \t\r\n", "\"43\"", 44);
}, "aArg = 44", 44, 44);
}, "document.title = 43", 43, "undefined");
}}, 0);
}, false);
addWatchExpression("this");
addWatchExpression("ermahgerd");
addWatchExpression("aArg");
addWatchExpression("document.title");
addWatchExpression("document.title = 42");
executeSoon(function() {
gDebuggee.ermahgerd(); // ermahgerd!!
});
}
function testModification(aVar, aTest, aCallback, aNewValue, aNewResult, aArgResult,
aLocalScopeIndex = 1, aDeletionFlag = null)
{
function makeChangesAndExitInputMode() {
EventUtils.sendString(aNewValue);
EventUtils.sendKey("RETURN");
}
EventUtils.sendMouseEvent({ type: "dblclick" },
aVar.querySelector(".name"),
gDebugger);
executeSoon(function() {
ok(aVar.querySelector(".element-name-input"),
"There should be an input element created.");
let testContinued = false;
let fetchedVariables = false;
let fetchedExpressions = false;
let countV = 0;
gDebugger.addEventListener("Debugger:FetchedVariables", function testV() {
// We expect 2 Debugger:FetchedVariables events, one from the global
// object scope and the regular one.
if (++countV < 2) {
info("Number of received Debugger:FetchedVariables events: " + countV);
return;
}
gDebugger.removeEventListener("Debugger:FetchedVariables", testV, false);
fetchedVariables = true;
executeSoon(continueTest);
}, false);
let countE = 0;
gDebugger.addEventListener("Debugger:FetchedWatchExpressions", function testE() {
// We expect only one Debugger:FetchedWatchExpressions event, since all
// expressions are evaluated at the same time.
if (++countE < 1) {
info("Number of received Debugger:FetchedWatchExpressions events: " + countE);
return;
}
gDebugger.removeEventListener("Debugger:FetchedWatchExpressions", testE, false);
fetchedExpressions = true;
executeSoon(continueTest);
}, false);
function continueTest() {
if (testContinued || !fetchedVariables || !fetchedExpressions) {
return;
}
testContinued = true;
// Get the variable reference anew, since the old ones were discarded when
// we resumed.
var localScope = gDebugger.DebuggerView.Variables._list.querySelectorAll(".scope")[aLocalScopeIndex],
localNodes = localScope.querySelector(".details").childNodes,
aArg = localNodes[1];
is(aArg.querySelector(".value").getAttribute("value"), aArgResult,
"Should have the right value for 'aArg'.");
let label = gDebugger.L10N.getStr("watchExpressionsScopeLabel");
let scope = gVars._currHierarchy.get(label);
info("Found the watch expressions scope: " + scope);
let aExp = scope.get(aVar.querySelector(".name").getAttribute("value"));
info("Found the watch expression variable: " + aExp);
if (aDeletionFlag) {
ok(fetchedVariables, "The variables should have been fetched.");
ok(fetchedExpressions, "The variables should have been fetched.");
is(aExp, undefined, "The watch expression should not have been found.");
performCallback(scope);
return;
}
is(aExp.target.querySelector(".name").getAttribute("value"), aNewValue.trim(),
"Should have the right name for '" + aNewValue + "'.");
is(aExp.target.querySelector(".value").getAttribute("value"), aNewResult,
"Should have the right value for '" + aNewValue + "'.");
performCallback(scope);
}
makeChangesAndExitInputMode();
});
function performCallback(scope) {
executeSoon(function() {
aTest(scope);
aCallback(scope);
});
}
}
function testExprDeletion(aVar, aTest, aCallback, aArgResult,
aLocalScopeIndex = 1, aFinalFlag = null)
{
let testContinued = false;
let fetchedVariables = false;
let fetchedExpressions = false;
let countV = 0;
gDebugger.addEventListener("Debugger:FetchedVariables", function testV() {
// We expect 2 Debugger:FetchedVariables events, one from the global
// object scope and the regular one.
if (++countV < 2) {
info("Number of received Debugger:FetchedVariables events: " + countV);
return;
}
gDebugger.removeEventListener("Debugger:FetchedVariables", testV, false);
fetchedVariables = true;
executeSoon(continueTest);
}, false);
let countE = 0;
gDebugger.addEventListener("Debugger:FetchedWatchExpressions", function testE() {
// We expect only one Debugger:FetchedWatchExpressions event, since all
// expressions are evaluated at the same time.
if (++countE < 1) {
info("Number of received Debugger:FetchedWatchExpressions events: " + countE);
return;
}
gDebugger.removeEventListener("Debugger:FetchedWatchExpressions", testE, false);
fetchedExpressions = true;
executeSoon(continueTest);
}, false);
function continueTest() {
if ((testContinued || !fetchedVariables || !fetchedExpressions) && !aFinalFlag) {
return;
}
testContinued = true;
// Get the variable reference anew, since the old ones were discarded when
// we resumed.
var localScope = gDebugger.DebuggerView.Variables._list.querySelectorAll(".scope")[aLocalScopeIndex],
localNodes = localScope.querySelector(".details").childNodes,
aArg = localNodes[1];
is(aArg.querySelector(".value").getAttribute("value"), aArgResult,
"Should have the right value for 'aArg'.");
let label = gDebugger.L10N.getStr("watchExpressionsScopeLabel");
let scope = gVars._currHierarchy.get(label);
info("Found the watch expressions scope: " + scope);
if (aFinalFlag) {
ok(fetchedVariables, "The variables should have been fetched.");
ok(!fetchedExpressions, "The variables should never have been fetched.");
is(scope, undefined, "The watch expressions scope should not have been found.");
performCallback(scope);
return;
}
let aExp = scope.get(aVar.querySelector(".name").getAttribute("value"));
info("Found the watch expression variable: " + aExp);
is(aExp, undefined, "Should not have found the watch expression after deletion.");
performCallback(scope);
}
function performCallback(scope) {
executeSoon(function() {
aTest(scope);
aCallback(scope);
});
}
EventUtils.sendMouseEvent({ type: "click" },
aVar.querySelector(".dbg-variables-delete"),
gDebugger);
}
function test1(scope) {
is(gWatch._container._parent.querySelectorAll(".dbg-expression[hidden=true]").length, 5,
"There should be 5 hidden nodes in the watch expressions container");
is(gWatch._container._parent.querySelectorAll(".dbg-expression:not([hidden=true])").length, 0,
"There should be 0 visible nodes in the watch expressions container");
ok(scope, "There should be a wach expressions scope in the variables view");
is(scope._store.size, 5, "There should be 5 evaluations availalble");
is(gWatch._cache[0].target.inputNode.value, "document.title = 43",
"The first textbox input value is not the correct one");
is(gWatch._cache[0].attachment.expression, "document.title = 43",
"The first textbox input value is not the correct one");
is(gWatch._cache[1].target.inputNode.value, "document.title",
"The second textbox input value is not the correct one");
is(gWatch._cache[1].attachment.expression, "document.title",
"The second textbox input value is not the correct one");
is(gWatch._cache[2].target.inputNode.value, "aArg",
"The third textbox input value is not the correct one");
is(gWatch._cache[2].attachment.expression, "aArg",
"The third textbox input value is not the correct one");
is(gWatch._cache[3].target.inputNode.value, "ermahgerd",
"The fourth textbox input value is not the correct one");
is(gWatch._cache[3].attachment.expression, "ermahgerd",
"The fourth textbox input value is not the correct one");
is(gWatch._cache[4].target.inputNode.value, "this",
"The fifth textbox input value is not the correct one");
is(gWatch._cache[4].attachment.expression, "this",
"The fifth textbox input value is not the correct one");
}
function test2(scope) {
is(gWatch._container._parent.querySelectorAll(".dbg-expression[hidden=true]").length, 5,
"There should be 5 hidden nodes in the watch expressions container");
is(gWatch._container._parent.querySelectorAll(".dbg-expression:not([hidden=true])").length, 0,
"There should be 0 visible nodes in the watch expressions container");
ok(scope, "There should be a wach expressions scope in the variables view");
is(scope._store.size, 5, "There should be 5 evaluations availalble");
is(gWatch._cache[0].target.inputNode.value, "document.title = 43",
"The first textbox input value is not the correct one");
is(gWatch._cache[0].attachment.expression, "document.title = 43",
"The first textbox input value is not the correct one");
is(gWatch._cache[1].target.inputNode.value, "document.title",
"The second textbox input value is not the correct one");
is(gWatch._cache[1].attachment.expression, "document.title",
"The second textbox input value is not the correct one");
is(gWatch._cache[2].target.inputNode.value, "aArg = 44",
"The third textbox input value is not the correct one");
is(gWatch._cache[2].attachment.expression, "aArg = 44",
"The third textbox input value is not the correct one");
is(gWatch._cache[3].target.inputNode.value, "ermahgerd",
"The fourth textbox input value is not the correct one");
is(gWatch._cache[3].attachment.expression, "ermahgerd",
"The fourth textbox input value is not the correct one");
is(gWatch._cache[4].target.inputNode.value, "this",
"The fifth textbox input value is not the correct one");
is(gWatch._cache[4].attachment.expression, "this",
"The fifth textbox input value is not the correct one");
}
function test3(scope) {
is(gWatch._container._parent.querySelectorAll(".dbg-expression[hidden=true]").length, 4,
"There should be 4 hidden nodes in the watch expressions container");
is(gWatch._container._parent.querySelectorAll(".dbg-expression:not([hidden=true])").length, 0,
"There should be 0 visible nodes in the watch expressions container");
ok(scope, "There should be a wach expressions scope in the variables view");
is(scope._store.size, 4, "There should be 4 evaluations availalble");
is(gWatch._cache[0].target.inputNode.value, "document.title = 43",
"The first textbox input value is not the correct one");
is(gWatch._cache[0].attachment.expression, "document.title = 43",
"The first textbox input value is not the correct one");
is(gWatch._cache[1].target.inputNode.value, "document.title",
"The second textbox input value is not the correct one");
is(gWatch._cache[1].attachment.expression, "document.title",
"The second textbox input value is not the correct one");
is(gWatch._cache[2].target.inputNode.value, "ermahgerd",
"The third textbox input value is not the correct one");
is(gWatch._cache[2].attachment.expression, "ermahgerd",
"The third textbox input value is not the correct one");
is(gWatch._cache[3].target.inputNode.value, "this",
"The fourth textbox input value is not the correct one");
is(gWatch._cache[3].attachment.expression, "this",
"The fourth textbox input value is not the correct one");
}
function test4(scope) {
is(gWatch._container._parent.querySelectorAll(".dbg-expression[hidden=true]").length, 3,
"There should be 3 hidden nodes in the watch expressions container");
is(gWatch._container._parent.querySelectorAll(".dbg-expression:not([hidden=true])").length, 0,
"There should be 0 visible nodes in the watch expressions container");
ok(scope, "There should be a wach expressions scope in the variables view");
is(scope._store.size, 3, "There should be 3 evaluations availalble");
is(gWatch._cache[0].target.inputNode.value, "document.title",
"The first textbox input value is not the correct one");
is(gWatch._cache[0].attachment.expression, "document.title",
"The first textbox input value is not the correct one");
is(gWatch._cache[1].target.inputNode.value, "ermahgerd",
"The second textbox input value is not the correct one");
is(gWatch._cache[1].attachment.expression, "ermahgerd",
"The second textbox input value is not the correct one");
is(gWatch._cache[2].target.inputNode.value, "this",
"The third textbox input value is not the correct one");
is(gWatch._cache[2].attachment.expression, "this",
"The third textbox input value is not the correct one");
}
function test5(scope) {
is(gWatch._container._parent.querySelectorAll(".dbg-expression[hidden=true]").length, 2,
"There should be 2 hidden nodes in the watch expressions container");
is(gWatch._container._parent.querySelectorAll(".dbg-expression:not([hidden=true])").length, 0,
"There should be 0 visible nodes in the watch expressions container");
ok(scope, "There should be a wach expressions scope in the variables view");
is(scope._store.size, 2, "There should be 2 evaluations availalble");
is(gWatch._cache[0].target.inputNode.value, "ermahgerd",
"The second textbox input value is not the correct one");
is(gWatch._cache[0].attachment.expression, "ermahgerd",
"The second textbox input value is not the correct one");
is(gWatch._cache[1].target.inputNode.value, "this",
"The third textbox input value is not the correct one");
is(gWatch._cache[1].attachment.expression, "this",
"The third textbox input value is not the correct one");
}
function test6(scope) {
is(gWatch._container._parent.querySelectorAll(".dbg-expression[hidden=true]").length, 1,
"There should be 1 hidden nodes in the watch expressions container");
is(gWatch._container._parent.querySelectorAll(".dbg-expression:not([hidden=true])").length, 0,
"There should be 0 visible nodes in the watch expressions container");
ok(scope, "There should be a wach expressions scope in the variables view");
is(scope._store.size, 1, "There should be 1 evaluation availalble");
is(gWatch._cache[0].target.inputNode.value, "ermahgerd",
"The third textbox input value is not the correct one");
is(gWatch._cache[0].attachment.expression, "ermahgerd",
"The third textbox input value is not the correct one");
}
function test7(scope) {
is(gWatch._container._parent.querySelectorAll(".dbg-expression[hidden=true]").length, 0,
"There should be 0 hidden nodes in the watch expressions container");
is(gWatch._container._parent.querySelectorAll(".dbg-expression:not([hidden=true])").length, 0,
"There should be 0 visible nodes in the watch expressions container");
is(scope, undefined, "There should be no watch expressions scope available.");
is(gWatch._cache.length, 0, "The watch expressions cache should be empty.");
}
function addWatchExpression(string) {
gWatch.addExpression(string);
gDebugger.editor.focus();
}
function resumeAndFinish() {
gDebugger.DebuggerController.activeThread.resume(function() {
closeDebuggerAndFinish();
});
}
registerCleanupFunction(function() {
removeTab(gTab);
gPane = null;
gTab = null;
gDebuggee = null;
gDebugger = null;
gWatch = null;
gVars = null;
});

Просмотреть файл

@ -4,6 +4,10 @@
* http://creativecommons.org/publicdomain/zero/1.0/
*/
/**
* Make sure that the editing variables or properties values works properly.
*/
const TAB_URL = EXAMPLE_URL + "browser_dbg_frame-parameters.html";
var gPane = null;
@ -70,7 +74,7 @@ function testModification(aVar, aCallback, aNewValue, aNewResult) {
gDebugger);
executeSoon(function() {
ok(aVar.querySelector(".element-input"),
ok(aVar.querySelector(".element-value-input"),
"There should be an input element created.");
let count = 0;

Просмотреть файл

@ -0,0 +1,79 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests if the preferred script is shown when a page is loaded.
*/
const TAB_URL = EXAMPLE_URL + "browser_dbg_script-switching.html";
let gPane = null;
let gTab = null;
let gDebuggee = null;
let gDebugger = null;
let gView = null;
requestLongerTimeout(2);
function test()
{
let expectedScript = "test-script-switching-02.js";
let expectedScriptShown = false;
let scriptShownUrl = null;
let resumed = false;
let testStarted = false;
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
gTab = aTab;
gDebuggee = aDebuggee;
gPane = aPane;
gDebugger = gPane.contentWindow;
gView = gDebugger.DebuggerView;
resumed = true;
gView.Sources.preferredSource = EXAMPLE_URL + expectedScript;
startTest();
});
function onScriptShown(aEvent)
{
expectedScriptShown = aEvent.detail.url.indexOf(expectedScript) != -1;
scriptShownUrl = aEvent.detail.url;
startTest();
}
window.addEventListener("Debugger:SourceShown", onScriptShown);
function startTest()
{
if (expectedScriptShown && resumed && !testStarted) {
window.removeEventListener("Debugger:SourceShown", onScriptShown);
testStarted = true;
Services.tm.currentThread.dispatch({ run: performTest }, 0);
}
}
function performTest()
{
info("Currently preferred script: " + gView.Sources.preferredValue);
info("Currently selected script: " + gView.Sources.selectedValue);
isnot(gView.Sources.preferredValue.indexOf(expectedScript), -1,
"The preferred script url wasn't set correctly.");
isnot(gView.Sources.selectedValue.indexOf(expectedScript), -1,
"The selected script isn't the correct one.");
is(gView.Sources.selectedValue, scriptShownUrl,
"The shown script is not the the correct one.");
closeDebuggerAndFinish();
}
registerCleanupFunction(function() {
removeTab(gTab);
gPane = null;
gTab = null;
gDebuggee = null;
gDebugger = null;
gView = null;
});
}

Просмотреть файл

@ -6,7 +6,8 @@
<!-- Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ -->
<script type="text/javascript">
function ermahgerd() {
function ermahgerd(aArg) {
var t = document.title;
debugger;
(function() {
var a = undefined;

Просмотреть файл

@ -326,10 +326,12 @@ this.LayoutHelpers = LayoutHelpers = {
*
* @param Node aElemKey
* The key element to get the modifiers from.
* @param boolean aAllowCloverleaf
* Pass true to use the cloverleaf symbol instead of a descriptive string.
* @return string
* A prettified and properly separated modifier keys string.
*/
prettyKey: function LH_prettyKey(aElemKey)
prettyKey: function LH_prettyKey(aElemKey, aAllowCloverleaf)
{
let elemString = "";
let elemMod = aElemKey.getAttribute("modifiers");
@ -338,9 +340,12 @@ this.LayoutHelpers = LayoutHelpers = {
if (Services.appinfo.OS == "Darwin") {
// XXX bug 779642 Use "Cmd-" literal vs. cloverleaf meta-key until
// Orion adds variable height lines.
// elemString += PlatformKeys.GetStringFromName("VK_META") +
// PlatformKeys.GetStringFromName("MODIFIER_SEPARATOR");
elemString += "Cmd-";
if (!aAllowCloverleaf) {
elemString += "Cmd-";
} else {
elemString += PlatformKeys.GetStringFromName("VK_META") +
PlatformKeys.GetStringFromName("MODIFIER_SEPARATOR");
}
} else {
elemString += PlatformKeys.GetStringFromName("VK_CONTROL") +
PlatformKeys.GetStringFromName("MODIFIER_SEPARATOR");

Просмотреть файл

@ -20,7 +20,9 @@ this.EXPORTED_SYMBOLS = ["VariablesView", "create"];
* Requires the devtools common.css and debugger.css skin stylesheets.
*
* To allow replacing variable or property values in this view, provide an
* "eval" function property.
* "eval" function property. To allow replacing variable or property values,
* provide a "switch" function. To handle deleting variables or properties,
* provide a "delete" function.
*
* @param nsIDOMNode aParentNode
* The parent node to hold this view.
@ -415,6 +417,8 @@ function Scope(aView, aName, aFlags = {}) {
this.ownerView = aView;
this.eval = aView.eval;
this.switch = aView.switch;
this.delete = aView.delete;
this._store = new Map();
this._init(aName.trim(), aFlags);
@ -635,6 +639,24 @@ Scope.prototype = {
*/
set twisty(aFlag) aFlag ? this.showArrow() : this.hideArrow(),
/**
* Specifies if editing variable or property names is allowed.
* This flag applies non-recursively to the current scope.
*/
allowNameInput: false,
/**
* Specifies if editing variable or property values is allowed.
* This flag applies non-recursively to the current scope.
*/
allowValueInput: true,
/**
* Specifies if removing variables or properties values is allowed.
* This flag applies non-recursively to the current scope.
*/
allowDeletion: false,
/**
* Gets the id associated with this item.
* @return string
@ -917,11 +939,14 @@ Scope.prototype = {
* The variable's descriptor.
*/
function Variable(aScope, aName, aDescriptor) {
this._onClose = this._onClose.bind(this);
this._displayTooltip = this._displayTooltip.bind(this);
this._activateInput = this._activateInput.bind(this);
this._deactivateInput = this._deactivateInput.bind(this);
this._saveInput = this._saveInput.bind(this);
this._onInputKeyPress = this._onInputKeyPress.bind(this);
this._activateNameInput = this._activateNameInput.bind(this);
this._activateValueInput = this._activateValueInput.bind(this);
this._deactivateNameInput = this._deactivateNameInput.bind(this);
this._deactivateValueInput = this._deactivateValueInput.bind(this);
this._onNameInputKeyPress = this._onNameInputKeyPress.bind(this);
this._onValueInputKeyPress = this._onValueInputKeyPress.bind(this);
Scope.call(this, aScope, aName, aDescriptor);
this._setGrip(aDescriptor.value);
@ -1180,6 +1205,12 @@ create({ constructor: Variable, proto: Scope.prototype }, {
separatorLabel.hidden = true;
valueLabel.hidden = true;
}
if (this.ownerView.allowDeletion) {
let closeNode = this._closeNode = document.createElement("toolbarbutton");
closeNode.className = "dbg-variables-delete plain devtools-closebutton";
closeNode.addEventListener("click", this._onClose, false);
this._title.appendChild(closeNode);
}
},
/**
@ -1215,6 +1246,16 @@ create({ constructor: Variable, proto: Scope.prototype }, {
this._target.appendChild(tooltip);
this._target.setAttribute("tooltip", tooltip.id);
if (this.ownerView.allowNameInput) {
this._name.setAttribute("tooltiptext", L10N.getStr("variablesEditableNameTooltip"));
}
if (this.ownerView.allowValueInput) {
this._valueLabel.setAttribute("tooltiptext", L10N.getStr("variablesEditableValueTooltip"));
}
if (this.ownerView.allowDeletion) {
this._closeNode.setAttribute("tooltiptext", L10N.getStr("variablesCloseButtonTooltip"));
}
},
/**
@ -1255,44 +1296,54 @@ create({ constructor: Variable, proto: Scope.prototype }, {
_addEventListeners: function V__addEventListeners() {
this._arrow.addEventListener("mousedown", this.toggle, false);
this._name.addEventListener("mousedown", this.toggle, false);
this._valueLabel.addEventListener("click", this._activateInput, false);
this._name.addEventListener("dblclick", this._activateNameInput, false);
this._valueLabel.addEventListener("click", this._activateValueInput, false);
},
/**
* Makes this variable's value editable.
* The click listener for the close button.
*/
_activateInput: function V__activateInput(e) {
if (!this.eval) {
return;
}
let window = this.window;
let document = this.document;
_onClose: function V__onClose() {
this.hide();
let title = this._title;
let valueLabel = this._valueLabel;
let initialString = this._valueLabel.getAttribute("value");
if (this.delete) {
this.delete(this);
}
},
/**
* Creates a textbox node in place of a label.
*
* @param nsIDOMNode aLabel
* The label to be replaced with a textbox.
* @param string aClassName
* The class to be applied to the textbox.
* @param object aCallbacks
* An object containing the onKeypress and onBlur callbacks.
*/
_activateInput: function V__activateInput(aLabel, aClassName, aCallbacks) {
let initialString = aLabel.getAttribute("value");
// Create a texbox input element which will be shown in the current
// element's value location.
// element's specified label location.
let input = this.document.createElement("textbox");
input.setAttribute("value", initialString);
input.className = "plain element-input";
input.className = "plain " + aClassName;
input.width = this._target.clientWidth;
title.removeChild(valueLabel);
title.appendChild(input);
aLabel.parentNode.replaceChild(input, aLabel);
input.select();
// When the value is a string (displayed as "value"), then we probably want
// to change it to another string in the textbox, so to avoid typing the ""
// again, tackle with the selection bounds just a bit.
if (valueLabel.getAttribute("value").match(/^"[^"]*"$/)) {
if (aLabel.getAttribute("value").match(/^"[^"]*"$/)) {
input.selectionEnd--;
input.selectionStart++;
}
input.addEventListener("keypress", this._onInputKeyPress, false);
input.addEventListener("blur", this._deactivateInput, false);
input.addEventListener("keypress", aCallbacks.onKeypress, false);
input.addEventListener("blur", aCallbacks.onBlur, false);
this._prevExpandable = this.twisty;
this._prevExpanded = this.expanded;
@ -1302,18 +1353,17 @@ create({ constructor: Variable, proto: Scope.prototype }, {
},
/**
* Deactivates this variable's editable mode.
* Removes the textbox node in place of a label.
*
* @param nsIDOMNode aLabel
* The label which was replaced with a textbox.
* @param object aCallbacks
* An object containing the onKeypress and onBlur callbacks.
*/
_deactivateInput: function V__deactivateInput(e) {
let input = e.target;
let title = this._title;
let valueLabel = this._valueLabel;
title.removeChild(input);
title.appendChild(valueLabel);
input.removeEventListener("keypress", this._onInputKeyPress, false);
input.removeEventListener("blur", this._deactivateInput, false);
_deactivateInput: function V__deactivateInput(aLabel, aInput, aCallbacks) {
aInput.parentNode.replaceChild(aLabel, aInput);
aInput.removeEventListener("keypress", aCallbacks.onKeypress, false);
aInput.removeEventListener("blur", aCallbacks.onBlur, false);
this._locked = false;
this.twisty = this._prevExpandable;
@ -1321,37 +1371,123 @@ create({ constructor: Variable, proto: Scope.prototype }, {
},
/**
* Deactivates this variable's editable mode and evaluates a new value.
* Makes this variable's name editable.
*/
_saveInput: function V__saveInput(e) {
let input = e.target;
let valueLabel = this._valueLabel;
let initialString = this._valueLabel.getAttribute("value");
let currentString = input.value;
_activateNameInput: function V__activateNameInput() {
if (!this.ownerView.allowNameInput || !this.switch) {
return;
}
this._activateInput(this._name, "element-name-input", {
onKeypress: this._onNameInputKeyPress,
onBlur: this._deactivateNameInput
});
this._separatorLabel.hidden = true;
this._valueLabel.hidden = true;
},
this._deactivateInput(e);
/**
* Deactivates this variable's editable name mode.
*/
_deactivateNameInput: function V__deactivateNameInput(e) {
this._deactivateInput(this._name, e.target, {
onKeypress: this._onNameInputKeyPress,
onBlur: this._deactivateNameInput
});
this._separatorLabel.hidden = false;
this._valueLabel.hidden = false;
},
/**
* Makes this variable's value editable.
*/
_activateValueInput: function V__activateValueInput() {
if (!this.ownerView.allowValueInput || !this.eval) {
return;
}
this._activateInput(this._valueLabel, "element-value-input", {
onKeypress: this._onValueInputKeyPress,
onBlur: this._deactivateValueInput
});
},
/**
* Deactivates this variable's editable value mode.
*/
_deactivateValueInput: function V__deactivateValueInput(e) {
this._deactivateInput(this._valueLabel, e.target, {
onKeypress: this._onValueInputKeyPress,
onBlur: this._deactivateValueInput
});
},
/**
* Disables this variable prior to a new name switch or value evaluation.
*/
_disable: function V__disable() {
this.twisty = false;
this._separatorLabel.hidden = true;
this._valueLabel.hidden = true;
this._enum.hidden = true;
this._nonenum.hidden = true;
},
/**
* Deactivates this variable's editable mode and callbacks the new name.
*/
_saveNameInput: function V__saveNameInput(e) {
let input = e.target;
let initialString = this._name.getAttribute("value");
let currentString = input.value.trim();
this._deactivateNameInput(e);
if (initialString != currentString) {
this._arrow.setAttribute("invisible", "");
this._separatorLabel.hidden = true;
this._valueLabel.hidden = true;
this._enum.hidden = true;
this._nonenum.hidden = true;
this.eval("(" + this._symbolicName + "=" + currentString + ")");
this._disable();
this._name.value = currentString;
this.switch(this, currentString);
}
},
/**
* The key press listener for this variable's editable mode textbox.
* Deactivates this variable's editable mode and evaluates the new value.
*/
_onInputKeyPress: function V__onInputKeyPress(e) {
_saveValueInput: function V__saveValueInput(e) {
let input = e.target;
let initialString = this._valueLabel.getAttribute("value");
let currentString = input.value.trim();
this._deactivateValueInput(e);
if (initialString != currentString) {
this._disable();
this.eval(this._symbolicName + "=" + currentString);
}
},
/**
* The key press listener for this variable's editable name textbox.
*/
_onNameInputKeyPress: function V__onNameInputKeyPress(e) {
switch(e.keyCode) {
case e.DOM_VK_RETURN:
case e.DOM_VK_ENTER:
this._saveInput(e);
this._saveNameInput(e);
return;
case e.DOM_VK_ESCAPE:
this._deactivateInput(e);
this._deactivateNameInput(e);
return;
}
},
/**
* The key press listener for this variable's editable value textbox.
*/
_onValueInputKeyPress: function V__onValueInputKeyPress(e) {
switch(e.keyCode) {
case e.DOM_VK_RETURN:
case e.DOM_VK_ENTER:
this._saveValueInput(e);
return;
case e.DOM_VK_ESCAPE:
this._deactivateValueInput(e);
return;
}
},
@ -1361,6 +1497,7 @@ create({ constructor: Variable, proto: Scope.prototype }, {
_initialDescriptor: null,
_separatorLabel: null,
_valueLabel: null,
_closeNode: null,
_tooltip: null,
_valueGrip: null,
_valueString: "",
@ -1700,6 +1837,7 @@ XPCOMUtils.defineLazyGetter(L10N, "stringBundle", function() {
/**
* The separator label between the variables or properties name and value.
* This property applies non-recursively to the current scope.
*/
Scope.prototype.separator = L10N.getStr("variablesSeparatorLabel");

Просмотреть файл

@ -35,7 +35,7 @@
!define BETA_UPDATE_CHANNEL
!endif
!define BaseURLStubPing "http://download-stats.mozilla.org/stub/v3/"
!define BaseURLStubPing "http://download-stats.mozilla.org/stub/v4/"
# NO_INSTDIR_FROM_REG is defined for pre-releases which have a PreReleaseSuffix
# (e.g. Alpha X, Beta X, etc.) to prevent finding a non-default installation

Просмотреть файл

@ -68,8 +68,10 @@ Var TmpVal
Var InstallCounterStep
Var ExitCode
Var DownloadStartTime
Var SecondsToDownload
Var StartTickCount
Var DownloadTickCount
Var InstallTickCount
Var FinishTickCount
Var ExistingProfile
Var ExistingInstall
Var DownloadedAmount
@ -289,11 +291,11 @@ Function .onInit
Abort
${EndUnless}
SetShellVarContext all ; Set SHCTX to HKLM
SetShellVarContext all ; Set SHCTX to HKLM
${GetSingleInstallPath} "Software\Mozilla\${BrandFullNameInternal}" $R9
${If} "$R9" == "false"
SetShellVarContext current ; Set SHCTX to HKCU
SetShellVarContext current ; Set SHCTX to HKCU
${GetSingleInstallPath} "Software\Mozilla\${BrandFullNameInternal}" $R9
${EndIf}
@ -317,8 +319,8 @@ Function .onInit
${EndIf}
StrCpy $IsDownloadFinished ""
StrCpy $FirefoxLaunch 0
StrCpy $ExitCode ${ERR_UNKNOWN}
StrCpy $FirefoxLaunch "0"
StrCpy $ExitCode "${ERR_UNKNOWN}"
CreateFont $FontBlurb "$(^Font)" "12" "500"
CreateFont $FontNormal "$(^Font)" "11" "500"
@ -350,23 +352,43 @@ FunctionEnd
!endif
Function .onGUIEnd
; The value of $IsDownloadFinished will be false if the download was attempted
; and wasn't completed. Get the seconds elapsed trying to download.
${If} $IsDownloadFinished == "false"
Call GetSecondsToDownload
${EndIf}
; Try to send a ping if a download was attempted
${If} $IsDownloadFinished != ""
${AndIf} $CheckboxSendPing == 1
${If} $IsDownloadFinished == "false"
; When the value of $IsDownloadFinished is false the download was started
; but didn't finish and GetTickCount needs to be called to determine how
; long the download was in progress.
System::Call "kernel32::GetTickCount()l .s"
Pop $DownloadTickCount
StrCpy $1 "0"
StrCpy $2 "0"
; Cancel the download in progress
InetBgDL::Get /RESET /END
${Else}
; Get the tick count for when the installer closes.
System::Call "kernel32::GetTickCount()l .s"
Pop $FinishTickCount
; Get the time from the end of the install to close the installer.
${GetSecondsElapsed} "$InstallTickCount" "$FinishTickCount" $2
; Get the time from the end of the download to the completion of the
; installation.
${GetSecondsElapsed} "$DownloadTickCount" "$InstallTickCount" $1
${EndIf}
; Get the time from the start of the download to the end of the download.
${GetSecondsElapsed} "$StartTickCount" "$DownloadTickCount" $0
System::Int64Op $DownloadedAmount / 1024
Pop $DownloadedAmount
InetBgDL::Get "${BaseURLStubPing}${Channel}/${AB_CD}/$ExitCode/$FirefoxLaunch/$SecondsToDownload/$DownloadedAmount/$ExistingProfile/$ExistingInstall/" \
"$PLUGINSDIR\_temp" /END
InetBgDL::Get "${BaseURLStubPing}${Channel}/${AB_CD}/$ExitCode/$FirefoxLaunch/$DownloadedAmount/$0/$1/$2/$ExistingProfile/$ExistingInstall/" \
"$PLUGINSDIR\_temp" /END
${ElseIf} $IsDownloadFinished == "false"
; Cancel the download in progress
InetBgDL::Get /RESET /END
${EndIf}
${UnloadUAC}
@ -391,14 +413,14 @@ FunctionEnd
Function createIntro
; If Back is clicked on the options page reset variables
StrCpy $INSTDIR "$InitialInstallDir"
StrCpy $CheckboxShortcutOnBar 1
StrCpy $CheckboxShortcutInStartMenu 1
StrCpy $CheckboxShortcutOnDesktop 1
StrCpy $CheckboxSendPing 1
StrCpy $CheckboxShortcutOnBar "1"
StrCpy $CheckboxShortcutInStartMenu "1"
StrCpy $CheckboxShortcutOnDesktop "1"
StrCpy $CheckboxSendPing "1"
!ifdef MOZ_MAINTENANCE_SERVICE
StrCpy $CheckboxInstallMaintSvc 1
StrCpy $CheckboxInstallMaintSvc "1"
!else
StrCpy $CheckboxInstallMaintSvc 0
StrCpy $CheckboxInstallMaintSvc "0"
!endif
nsDialogs::Create /NOUNLOAD 1018
@ -471,7 +493,7 @@ FunctionEnd
Function leaveIntro
LockWindow on
SetShellVarContext all ; Set SHCTX to All Users
SetShellVarContext all ; Set SHCTX to All Users
; If the user doesn't have write access to the installation directory set
; the installation directory to a subdirectory of the All Users application
; directory and if the user can't write to that location set the installation
@ -593,9 +615,9 @@ Function createOptions
${GetTextExtent} "$(SPACE_REQUIRED)" $FontItalic $0 $1
${GetTextExtent} "$(SPACE_AVAILABLE)" $FontItalic $2 $3
${If} $1 > $3
StrCpy $HEIGHT_PX $1
StrCpy $HEIGHT_PX "$1"
${Else}
StrCpy $HEIGHT_PX $3
StrCpy $HEIGHT_PX "$3"
${EndIf}
IntOp $0 $0 + 8 ; Add padding to the control's width
@ -613,7 +635,7 @@ Function createOptions
; Use the widest label for aligning the labels next to them
${If} $0 > $2
StrCpy $6 $5
StrCpy $6 "$5"
${EndIf}
FindWindow $1 "#32770" "" $HWNDPARENT
${GetDlgItemEndPX} $6 $CTL_RIGHT_PX
@ -874,26 +896,21 @@ Function createInstall
StrCpy $IsDownloadFinished "false"
StrCpy $DownloadReset "false"
StrCpy $ExitCode ${ERR_CANCEL_DOWNLOAD}
StrCpy $ExitCode "${ERR_CANCEL_DOWNLOAD}"
${If} ${FileExists} "$INSTDIR\${FileMainEXE}"
StrCpy $ExistingInstall 1
StrCpy $ExistingInstall "1"
${Else}
StrCpy $ExistingInstall 0
StrCpy $ExistingInstall "0"
${EndIf}
${If} ${FileExists} "$LOCALAPPDATA\Mozilla\Firefox"
StrCpy $ExistingProfile 1
StrCpy $ExistingProfile "1"
${Else}
StrCpy $ExistingProfile 0
StrCpy $ExistingProfile "0"
${EndIf}
GetTempFileName $2
GetFileTime $2 $1 $0
Delete $2
System::Int64Op $1 * 0x100000000
Pop $1
System::Int64Op $1 + $0
Pop $DownloadStartTime
System::Call "kernel32::GetTickCount()l .s"
Pop $StartTickCount
${NSD_CreateTimer} StartDownload ${DownloadIntervalMS}
@ -911,22 +928,6 @@ Function leaveInstall
# Need a ping?
FunctionEnd
; GetSecondsToDownload calculates the amount of time between $DownloadStartTime
; and now, and stores the results into $SecondsToDownload.
Function GetSecondsToDownload
GetTempFileName $2
GetFileTime $2 $1 $0
Delete $2
System::Int64Op $1 * 0x100000000
Pop $1
System::Int64Op $1 + $0
Pop $0
System::Int64Op $0 - $DownloadStartTime
Pop $4
System::Int64Op $4 / 10000000
Pop $SecondsToDownload
FunctionEnd
Function StartDownload
${NSD_KillTimer} StartDownload
InetBgDL::Get "${URLStubDownload}" "$PLUGINSDIR\download.exe" \
@ -950,7 +951,7 @@ Function OnDownload
${If} $0 > 299
${NSD_KillTimer} OnDownload
${If} "$DownloadReset" != "true"
StrCpy $DownloadedAmount 0
StrCpy $DownloadedAmount "0"
${NSD_AddStyle} $ProgressbarDownload ${PBS_MARQUEE}
SendMessage $ProgressbarDownload ${PBM_SETMARQUEE} 1 10 ; start=1|stop=0 interval(ms)=+N
${EndIf}
@ -967,7 +968,7 @@ Function OnDownload
${If} $DownloadSize == ""
${AndIf} $4 != ""
StrCpy $DownloadSize $4
StrCpy $DownloadSize "$4"
System::Int64Op $4 / 2
Pop $HalfOfDownload
SendMessage $ProgressbarDownload ${PBM_SETMARQUEE} 0 0 ; start=1|stop=0 interval(ms)=+N
@ -988,9 +989,10 @@ Function OnDownload
; The first step of the install progress bar is determined by the
; InstallProgressFirstStep define and provides the user with immediate
; feedback.
StrCpy $InstallCounterStep ${InstallProgressFirstStep}
Call GetSecondsToDownload
StrCpy $DownloadedAmount $DownloadSize
StrCpy $InstallCounterStep "${InstallProgressFirstStep}"
System::Call "kernel32::GetTickCount()l .s"
Pop $DownloadTickCount
StrCpy $DownloadedAmount "$DownloadSize"
LockWindow on
; Update the progress bars first in the UI change so they take affect
; before other UI changes.
@ -1018,7 +1020,7 @@ Function OnDownload
StrCpy $HandleDownload "$R9"
${If} $HandleDownload == ${INVALID_HANDLE_VALUE}
StrCpy $ExitCode ${ERR_INVALID_HANDLE}
StrCpy $ExitCode "${ERR_INVALID_HANDLE}"
StrCpy $0 "0"
StrCpy $1 "0"
${Else}
@ -1029,11 +1031,11 @@ Function OnDownload
Pop $1
${If} $0 == 0
${AndIf} $1 == 0
StrCpy $ExitCode ${ERR_CERT_UNTRUSTED_AND_ATTRIBUTES}
StrCpy $ExitCode "${ERR_CERT_UNTRUSTED_AND_ATTRIBUTES}"
${ElseIf} $0 == 0
StrCpy $ExitCode ${ERR_CERT_UNTRUSTED}
StrCpy $ExitCode "${ERR_CERT_UNTRUSTED}"
${ElseIf} $1 == 0
StrCpy $ExitCode ${ERR_CERT_ATTRIBUTES}
StrCpy $ExitCode "${ERR_CERT_ATTRIBUTES}"
${EndIf}
${EndIf}
@ -1105,7 +1107,7 @@ Function OnDownload
ShowWindow $BitmapBlurb2 ${SW_SHOW}
LockWindow off
${EndIf}
StrCpy $DownloadedAmount $3
StrCpy $DownloadedAmount "$3"
SendMessage $ProgressbarDownload ${PBM_SETPOS} $3 0
${EndIf}
${EndIf}
@ -1129,7 +1131,7 @@ Function CheckInstall
${NSD_KillTimer} CheckInstall
; Close the handle that prevents modification of the full installer
System::Call 'kernel32::CloseHandle(i $HandleDownload)'
StrCpy $ExitCode ${ERR_CHECK_INSTALL_TIMEOUT}
StrCpy $ExitCode "${ERR_CHECK_INSTALL_TIMEOUT}"
; Use a timer so the UI has a chance to update
${NSD_CreateTimer} DisplayDownloadError ${InstallIntervalMS}
Return
@ -1152,6 +1154,8 @@ Function CheckInstall
Rename "$INSTDIR\install.tmp" "$INSTDIR\install.log"
Delete "$PLUGINSDIR\download.exe"
Delete "$PLUGINSDIR\${CONFIG_INI}"
System::Call "kernel32::GetTickCount()l .s"
Pop $InstallTickCount
${NSD_CreateTimer} FinishInstall ${InstallIntervalMS}
${EndUnless}
${EndIf}
@ -1160,7 +1164,7 @@ FunctionEnd
Function FinishInstall
; The full installer has complete but we still need to finish the progress
; bar so increase the size of the step
IntOp $InstallCounterStep $InstallCounterStep + 10
IntOp $InstallCounterStep $InstallCounterStep + 20
${If} ${InstallProgresSteps} < $InstallCounterStep
StrCpy $InstallCounterStep "${InstallProgresSteps}"
${EndIf}
@ -1204,19 +1208,19 @@ Function FinishInstall
Rename "$INSTDIR\${FileMainEXE}.moz-upgrade" "$INSTDIR\${FileMainEXE}"
${EndIf}
StrCpy $ExitCode ${ERR_SUCCESS}
StrCpy $ExitCode "${ERR_SUCCESS}"
Call LaunchApp
; The following will exit the installer
SetAutoClose true
StrCpy $R9 2
StrCpy $R9 "2"
Call RelativeGotoPage
FunctionEnd
Function OnBack
StrCpy $WasOptionsButtonClicked "true"
StrCpy $R9 1 ; Goto the next page
StrCpy $R9 "1" ; Goto the next page
Call RelativeGotoPage
; The call to Abort prevents NSIS from trying to move to the previous or the
; next page.
@ -1296,7 +1300,7 @@ FunctionEnd
Function OnChange_DirRequest
Pop $0
System::Call 'user32::GetWindowTextW(i $DirRequest, w .r0, i ${NSIS_MAX_STRLEN})'
StrCpy $INSTDIR $0
StrCpy $INSTDIR "$0"
Call UpdateFreeSpaceLabel
FunctionEnd
@ -1420,13 +1424,15 @@ FunctionEnd
Function LaunchApp
FindWindow $0 "${WindowClass}"
${If} $0 <> 0 ; integer comparison
StrCpy $FirefoxLaunch 1
StrCpy $FirefoxLaunch "1"
MessageBox MB_OK|MB_ICONQUESTION "$(WARN_MANUALLY_CLOSE_APP_LAUNCH)"
Return
${EndIf}
StrCpy $FirefoxLaunch 2
StrCpy $FirefoxLaunch "2"
; Set the current working directory to the installation directory
SetOutPath "$INSTDIR"
ClearErrors
${GetParameters} $0
${GetOptions} "$0" "/UAC:" $1
@ -1444,6 +1450,9 @@ Function LaunchAppFromElevatedProcess
${StrFilter} "${FileMainEXE}" "+" "" "" $R9
ReadRegStr $0 HKLM "Software\Clients\StartMenuInternet\$R9\DefaultIcon" ""
${GetPathFromString} "$0" $0
; Set the current working directory to the installation directory
${GetParent} "$0" $1
SetOutPath "$1"
Exec "$\"$0$\""
FunctionEnd
@ -1466,7 +1475,7 @@ Function DisplayDownloadError
${EndIf}
SetAutoClose true
StrCpy $R9 2
StrCpy $R9 "2"
Call RelativeGotoPage
FunctionEnd

Просмотреть файл

@ -659,3 +659,5 @@ toolbar button -->
<!ENTITY social.activated.undobutton.accesskey "U">
<!ENTITY social.chatBar.commandkey "c">
<!ENTITY social.chatBar.label "Focus chats">
<!ENTITY social.chatBar.accesskey "c">

Просмотреть файл

@ -35,6 +35,10 @@
- the button that closes the debugger UI. -->
<!ENTITY debuggerUI.closeButton.tooltip "Close">
<!-- LOCALIZATION NOTE (debuggerUI.panesButton.tooltip): This is the tooltip for
- the button that toggles the panes visible or hidden in the debugger UI. -->
<!ENTITY debuggerUI.panesButton.tooltip "Toggle panes">
<!-- LOCALIZATION NOTE (debuggerUI.optsButton.tooltip): This is the tooltip for
- the button that opens up an options context menu for the debugger UI. -->
<!ENTITY debuggerUI.optsButton.tooltip "Debugger Options">
@ -64,6 +68,31 @@
- appears in the filter panel popup as a description. -->
<!ENTITY debuggerUI.searchPanelTitle "Operators">
<!-- LOCALIZATION NOTE (debuggerUI.searchFile): This is the text that appears
- in the source editor's context menu for the scripts search operation. -->
<!ENTITY debuggerUI.searchFile "Filter scripts">
<!ENTITY debuggerUI.searchFile.key "P">
<!-- LOCALIZATION NOTE (debuggerUI.searchGlobal): This is the text that appears
- in the source editor's context menu for the global search operation. -->
<!ENTITY debuggerUI.searchGlobal "Search in all files">
<!ENTITY debuggerUI.searchGlobal.key "F">
<!-- LOCALIZATION NOTE (debuggerUI.searchToken): This is the text that appears
- in the source editor's context menu for the token search operation. -->
<!ENTITY debuggerUI.searchToken "Find">
<!ENTITY debuggerUI.searchToken.key "F">
<!-- LOCALIZATION NOTE (debuggerUI.searchLine): This is the text that appears
- in the source editor's context menu for the line search operation. -->
<!ENTITY debuggerUI.searchLine "Jump to line...">
<!ENTITY debuggerUI.searchLine.key "J">
<!-- LOCALIZATION NOTE (debuggerUI.searchVariable): This is the text that appears
- in the source editor's context menu for the variables search operation. -->
<!ENTITY debuggerUI.searchVariable "Filter variables">
<!ENTITY debuggerUI.searchVariable.key "V">
<!-- LOCALIZATION NOTE (debuggerUI.condBreakPanelTitle): This is the text that
- appears in the conditional breakpoint panel popup as a description. -->
<!ENTITY debuggerUI.condBreakPanelTitle "This breakpoint will stop execution only if the following expression is true">
@ -71,8 +100,19 @@
<!-- LOCALIZATION NOTE (debuggerUI.seMenuBreak): This is the text that
- appears in the source editor context menu for adding a breakpoint. -->
<!ENTITY debuggerUI.seMenuBreak "Add breakpoint">
<!ENTITY debuggerUI.seMenuBreak.key "B">
<!-- LOCALIZATION NOTE (debuggerUI.seMenuCondBreak): This is the text that
- appears in the source editor context menu for adding a conditional
- breakpoint. -->
<!ENTITY debuggerUI.seMenuCondBreak "Add conditional breakpoint">
<!ENTITY debuggerUI.seMenuCondBreak.key "B">
<!-- LOCALIZATION NOTE (debuggerUI.stepping): These are the keycodes that
- control the stepping commands in the debugger (continue, step over,
- step in and step out). -->
<!ENTITY debuggerUI.stepping.resume "VK_F6">
<!ENTITY debuggerUI.stepping.stepOver "VK_F7">
<!ENTITY debuggerUI.stepping.stepIn "VK_F8">
<!ENTITY debuggerUI.stepping.stepOut "VK_F8">

Просмотреть файл

@ -173,6 +173,18 @@ watchExpressionsScopeLabel=Watch expressions
# the global scope.
globalScopeLabel=Global
# LOCALIZATION NOTE (variablesEditableNameTooltip): The text that is displayed
# in the variables list on an item with an editable name.
variablesEditableNameTooltip=Double click to edit
# LOCALIZATION NOTE (variablesEditableValueTooltip): The text that is displayed
# in the variables list on an item with an editable name.
variablesEditableValueTooltip=Click to change value
# LOCALIZATION NOTE (variablesCloseButtonTooltip): The text that is displayed
# in the variables list on an item with which can be removed.
variablesCloseButtonTooltip=Click to remove
# LOCALIZATION NOTE (variablesSeparatorLabel): The text that is displayed
# in the variables list as a separator between the name and value.
variablesSeparatorLabel=:

Просмотреть файл

@ -71,8 +71,8 @@ this.Social = {
return Services.prefs.getBoolPref("social.active");
},
set active(val) {
Services.prefs.setBoolPref("social.active", !!val);
this.enabled = !!val;
Services.prefs.setBoolPref("social.active", !!val);
},
toggle: function Social_toggle() {

Просмотреть файл

@ -161,6 +161,10 @@
font-weight: 600;
}
.dbg-stackframe-details {
-moz-padding-start: 4px;
}
/**
* Breakpoints view
*/
@ -209,10 +213,6 @@
-moz-padding-start: 8px;
}
.dbg-expression:last-child {
margin-bottom: 4px;
}
.dbg-expression-arrow {
width: 10px;
height: auto;
@ -236,6 +236,11 @@
min-height: 10px;
}
.dbg-variables-delete:not(:hover) {
-moz-image-region: rect(0, 32px, 16px, 16px);
opacity: 0.5;
}
/**
* Scope element
*/
@ -278,6 +283,7 @@
.variable > .title > .value {
-moz-padding-start: 6px;
-moz-padding-end: 4px;
}
.variable:not([non-header]) > .details {
@ -304,6 +310,7 @@
.property > .title > .value {
-moz-padding-start: 6px;
-moz-padding-end: 4px;
}
.property:not([non-header]) > .details {
@ -373,10 +380,16 @@
* Variables and properties editing
*/
#variables .element-input {
#variables .element-value-input {
-moz-margin-start: 5px !important;
}
#variables .element-name-input {
-moz-margin-start: -1px !important;
color: #048;
font-weight: 600;
}
/**
* Variables and properties searching
*/

Просмотреть файл

@ -163,6 +163,10 @@
font-weight: 600;
}
.dbg-stackframe-details {
-moz-padding-start: 4px;
}
/**
* Breakpoints view
*/
@ -211,10 +215,6 @@
-moz-padding-start: 8px;
}
.dbg-expression:last-child {
margin-bottom: 4px;
}
.dbg-expression-arrow {
width: 10px;
height: auto;
@ -238,6 +238,11 @@
min-height: 10px;
}
.dbg-variables-delete:not(:hover) {
-moz-image-region: rect(0, 32px, 16px, 16px);
opacity: 0.5;
}
/**
* Scope element
*/
@ -280,6 +285,7 @@
.variable > .title > .value {
-moz-padding-start: 6px;
-moz-padding-end: 4px;
}
.variable:not([non-header]) > .details {
@ -306,6 +312,7 @@
.property > .title > .value {
-moz-padding-start: 6px;
-moz-padding-end: 4px;
}
.property:not([non-header]) > .details {
@ -375,10 +382,16 @@
* Variables and properties editing
*/
#variables .element-input {
#variables .element-value-input {
-moz-margin-start: 5px !important;
}
#variables .element-name-input {
-moz-margin-start: -1px !important;
color: #048;
font-weight: 600;
}
/**
* Variables and properties searching
*/

Просмотреть файл

@ -169,6 +169,10 @@
font-weight: 600;
}
.dbg-stackframe-details {
-moz-padding-start: 4px;
}
/**
* Breakpoints view
*/
@ -217,10 +221,6 @@
-moz-padding-start: 8px;
}
.dbg-expression:last-child {
margin-bottom: 4px;
}
.dbg-expression-arrow {
width: 10px;
height: auto;
@ -244,6 +244,11 @@
min-height: 10px;
}
.dbg-variables-delete:not(:hover) {
-moz-image-region: rect(0, 32px, 16px, 16px);
opacity: 0.5;
}
/**
* Scope element
*/
@ -286,6 +291,7 @@
.variable > .title > .value {
-moz-padding-start: 6px;
-moz-padding-end: 4px;
}
.variable:not([non-header]) > .details {
@ -312,6 +318,7 @@
.property > .title > .value {
-moz-padding-start: 6px;
-moz-padding-end: 4px;
}
.property:not([non-header]) > .details {
@ -381,10 +388,16 @@
* Variables and properties editing
*/
#variables .element-input {
#variables .element-value-input {
-moz-margin-start: 5px !important;
}
#variables .element-name-input {
-moz-margin-start: -1px !important;
color: #048;
font-weight: 600;
}
/**
* Variables and properties searching
*/

Просмотреть файл

@ -7,7 +7,8 @@
%undef WINSTRIPE_AERO
@media (-moz-windows-default-theme) {
#downloadsPanel[hasdownloads] #downloadsHistory {
#downloadsPanel[hasdownloads] > #downloadsHistory,
#downloadsSummary {
background-color: #f1f5fb;
}

Просмотреть файл

@ -65,6 +65,9 @@ def build_dict(env=os.environ):
# crashreporter
d["crashreporter"] = 'MOZ_CRASHREPORTER' in env and env['MOZ_CRASHREPORTER'] == '1'
# per-window private browsing
d["perwindowprivatebrowsing"] = 'MOZ_PER_WINDOW_PRIVATE_BROWSING' in env and env['MOZ_PER_WINDOW_PRIVATE_BROWSING'] == '1'
return d
#TODO: replace this with the json module when Python >= 2.6 is a requirement.

Просмотреть файл

@ -5618,11 +5618,25 @@ dnl ========================================================
dnl If using sydneyaudio with Linux, ensure that the alsa library is available
if test -n "$MOZ_SYDNEYAUDIO" -a "$OS_TARGET" = "Linux"; then
MOZ_ALSA=1
fi
MOZ_ARG_ENABLE_BOOL(alsa,
[ --enable-alsa Enable Alsa support (default on Linux)],
MOZ_ALSA=1,
MOZ_ALSA=)
if test -n "$MOZ_ALSA"; then
AC_DEFINE(MOZ_CUBEB)
PKG_CHECK_MODULES(MOZ_ALSA, alsa, ,
[echo "$MOZ_ALSA_PKG_ERRORS"
AC_MSG_ERROR([Need alsa for Ogg, Wave or WebM decoding on Linux. Disable with --disable-ogg --disable-wave --disable-webm. (On Ubuntu, you might try installing the package libasound2-dev.)])])
fi
AC_SUBST(MOZ_ALSA)
AC_SUBST(MOZ_ALSA_CFLAGS)
AC_SUBST(MOZ_ALSA_LIBS)
dnl ========================================================
dnl = Enable PulseAudio
dnl ========================================================
@ -6704,6 +6718,7 @@ AC_SUBST(MOZ_GL_PROVIDER)
AC_DEFINE_UNQUOTED(MOZ_GL_PROVIDER, GLContextProvider$MOZ_GL_PROVIDER)
fi
AC_SUBST(MOZ_GL_DEFAULT_PROVIDER)
AC_DEFINE_UNQUOTED(GL_PROVIDER_$MOZ_GL_DEFAULT_PROVIDER)
dnl ========================================================
dnl = faststripe theme
@ -8633,8 +8648,6 @@ AC_SUBST(MOZ_VP8_ERROR_CONCEALMENT)
AC_SUBST(MOZ_VP8_ENCODER)
AC_SUBST(MOZ_VP8)
AC_SUBST(MOZ_OGG)
AC_SUBST(MOZ_ALSA_LIBS)
AC_SUBST(MOZ_ALSA_CFLAGS)
AC_SUBST(VPX_AS)
AC_SUBST(VPX_ASFLAGS)
AC_SUBST(VPX_DASH_C_FLAG)
@ -8885,6 +8898,7 @@ MOZ_DEBUG=${MOZ_DEBUG} \
MOZ_WIDGET_TOOLKIT=${MOZ_WIDGET_TOOLKIT} \
UNIVERSAL_BINARY=${UNIVERSAL_BINARY} \
MOZ_CRASHREPORTER=${MOZ_CRASHREPORTER} \
MOZ_PER_WINDOW_PRIVATE_BROWSING=${MOZ_PER_WINDOW_PRIVATE_BROWSING} \
$PYTHON ${_topsrcdir}/config/writemozinfo.py ./mozinfo.json.tmp
if cmp -s ./mozinfo.json.tmp ./mozinfo.json; then
rm ./mozinfo.json.tmp

Просмотреть файл

@ -246,24 +246,17 @@ public:
NS_ASSERTION(mFile, "must have file");
}
// Create as a blob
nsDOMFileFile(nsIFile *aFile, const nsAString& aContentType,
nsISupports *aCacheToken)
: nsDOMFile(aContentType, UINT64_MAX),
mFile(aFile), mWholeFile(true), mStoredFile(false),
mCacheToken(aCacheToken)
{
NS_ASSERTION(mFile, "must have file");
}
// Create as a file with custom name
nsDOMFileFile(nsIFile *aFile, const nsAString& aName)
: nsDOMFile(aName, EmptyString(), UINT64_MAX, UINT64_MAX),
nsDOMFileFile(nsIFile *aFile, const nsAString& aName,
const nsAString& aContentType)
: nsDOMFile(aName, aContentType, UINT64_MAX, UINT64_MAX),
mFile(aFile), mWholeFile(true), mStoredFile(false)
{
NS_ASSERTION(mFile, "must have file");
// Lazily get the content type and size
mContentType.SetIsVoid(true);
if (aContentType.IsEmpty()) {
// Lazily get the content type and size
mContentType.SetIsVoid(true);
}
}
// Create as a stored file
@ -324,7 +317,7 @@ protected:
const nsAString& aContentType)
: nsDOMFile(aContentType, aOther->mStart + aStart, aLength),
mFile(aOther->mFile), mWholeFile(false),
mStoredFile(aOther->mStoredFile), mCacheToken(aOther->mCacheToken)
mStoredFile(aOther->mStoredFile)
{
NS_ASSERTION(mFile, "must have file");
mImmutable = aOther->mImmutable;
@ -363,7 +356,6 @@ protected:
nsCOMPtr<nsIFile> mFile;
bool mWholeFile;
bool mStoredFile;
nsCOMPtr<nsISupports> mCacheToken;
};
class nsDOMMemoryFile : public nsDOMFile

Просмотреть файл

@ -60,8 +60,6 @@ namespace JS {
class Value;
}
inline void SetDOMStringToNull(nsAString& aString);
#define NODE_FLAG_BIT(n_) (1U << (n_))
enum {
@ -1494,10 +1492,7 @@ public:
{
SetNodeValueInternal(aNodeValue, aError);
}
virtual void GetNodeValueInternal(nsAString& aNodeValue)
{
SetDOMStringToNull(aNodeValue);
}
virtual void GetNodeValueInternal(nsAString& aNodeValue);
virtual void SetNodeValueInternal(const nsAString& aNodeValue,
mozilla::ErrorResult& aError)
{
@ -1592,10 +1587,7 @@ protected:
return IsEditableInternal();
}
virtual void GetTextContentInternal(nsAString& aTextContent)
{
SetDOMStringToNull(aTextContent);
}
virtual void GetTextContentInternal(nsAString& aTextContent);
virtual void SetTextContentInternal(const nsAString& aTextContent,
mozilla::ErrorResult& aError)
{

Просмотреть файл

@ -324,6 +324,12 @@ nsINode::ChildNodes()
return slots->mChildNodes;
}
void
nsINode::GetTextContentInternal(nsAString& aTextContent)
{
SetDOMStringToNull(aTextContent);
}
#ifdef DEBUG
void
nsINode::CheckNotNativeAnonymous() const
@ -423,6 +429,12 @@ nsINode::GetOwnerDocument(nsIDOMDocument** aOwnerDocument)
return ownerDoc ? CallQueryInterface(ownerDoc, aOwnerDocument) : NS_OK;
}
void
nsINode::GetNodeValueInternal(nsAString& aNodeValue)
{
SetDOMStringToNull(aNodeValue);
}
nsINode*
nsINode::RemoveChild(nsINode& aOldChild, ErrorResult& aError)
{

Просмотреть файл

@ -131,7 +131,7 @@ nsNodeInfoManager::~nsNodeInfoManager()
NS_IMPL_CYCLE_COLLECTION_NATIVE_CLASS(nsNodeInfoManager)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NATIVE_0(nsNodeInfoManager)
NS_IMPL_CYCLE_COLLECTION_UNLINK_0(nsNodeInfoManager)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsNodeInfoManager)
if (tmp->mDocument &&
nsCCUncollectableMarker::InGeneration(cb,

Просмотреть файл

@ -2561,9 +2561,12 @@ nsObjectLoadingContent::ShouldPlay(FallbackType &aReason)
// the system principal, i.e. in chrome pages. That way the click-to-play
// code here wouldn't matter at all. Bug 775301 is tracking this.
if (!nsContentUtils::IsSystemPrincipal(topDoc->NodePrincipal())) {
nsAutoCString permissionString;
rv = pluginHost->GetPermissionStringForType(mContentType, permissionString);
NS_ENSURE_SUCCESS(rv, false);
uint32_t permission;
rv = permissionManager->TestPermissionFromPrincipal(topDoc->NodePrincipal(),
"plugins",
permissionString.Data(),
&permission);
NS_ENSURE_SUCCESS(rv, false);
allowPerm = permission == nsIPermissionManager::ALLOW_ACTION;

Просмотреть файл

@ -1077,18 +1077,6 @@ nsXMLHttpRequest::SetResponseType(nsXMLHttpRequest::ResponseTypeEnum aResponseTy
// Set the responseType attribute's value to the given value.
mResponseType = aResponseType;
// If the state is OPENED, SetCacheAsFile would have no effect here
// because the channel hasn't initialized the cache entry yet.
// SetCacheAsFile will be called from OnStartRequest.
// If the state is HEADERS_RECEIVED, however, we need to call
// it immediately because OnStartRequest is already dispatched.
if (mState & XML_HTTP_REQUEST_HEADERS_RECEIVED) {
nsCOMPtr<nsICachingChannel> cc(do_QueryInterface(mChannel));
if (cc) {
cc->SetCacheAsFile(mResponseType == XML_HTTP_RESPONSE_TYPE_BLOB ||
mResponseType == XML_HTTP_RESPONSE_TYPE_MOZ_BLOB);
}
}
}
/* readonly attribute jsval response; */
@ -1965,37 +1953,22 @@ nsXMLHttpRequest::StreamReaderFunc(nsIInputStream* in,
bool nsXMLHttpRequest::CreateDOMFile(nsIRequest *request)
{
nsCOMPtr<nsIFile> file;
nsCOMPtr<nsICachingChannel> cc(do_QueryInterface(request));
if (cc) {
cc->GetCacheFile(getter_AddRefs(file));
} else {
nsCOMPtr<nsIFileChannel> fc = do_QueryInterface(request);
if (fc) {
fc->GetFile(getter_AddRefs(file));
}
nsCOMPtr<nsIFileChannel> fc = do_QueryInterface(request);
if (fc) {
fc->GetFile(getter_AddRefs(file));
}
bool fromFile = false;
if (file) {
nsAutoCString contentType;
mChannel->GetContentType(contentType);
nsCOMPtr<nsISupports> cacheToken;
if (cc) {
cc->GetCacheToken(getter_AddRefs(cacheToken));
// We need to call IsFromCache to determine whether the response is
// fully cached (i.e. whether we can skip reading the response).
cc->IsFromCache(&fromFile);
} else {
// If the response is coming from the local resource, we can skip
// reading the response unconditionally.
fromFile = true;
}
mDOMFile =
new nsDOMFileFile(file, NS_ConvertASCIItoUTF16(contentType), cacheToken);
mBlobSet = nullptr;
NS_ASSERTION(mResponseBody.IsEmpty(), "mResponseBody should be empty");
}
return fromFile;
if (!file)
return false;
nsAutoCString contentType;
mChannel->GetContentType(contentType);
mDOMFile =
new nsDOMFileFile(file, EmptyString(), NS_ConvertASCIItoUTF16(contentType));
mBlobSet = nullptr;
NS_ASSERTION(mResponseBody.IsEmpty(), "mResponseBody should be empty");
return true;
}
NS_IMETHODIMP
@ -2127,14 +2100,6 @@ nsXMLHttpRequest::OnStartRequest(nsIRequest *request, nsISupports *ctxt)
mState &= ~XML_HTTP_REQUEST_MPART_HEADERS;
ChangeState(XML_HTTP_REQUEST_HEADERS_RECEIVED);
if (mResponseType == XML_HTTP_RESPONSE_TYPE_BLOB ||
mResponseType == XML_HTTP_RESPONSE_TYPE_MOZ_BLOB) {
nsCOMPtr<nsICachingChannel> cc(do_QueryInterface(mChannel));
if (cc) {
cc->SetCacheAsFile(true);
}
}
ResetResponse();
if (!mOverrideMimeType.IsEmpty()) {

Просмотреть файл

@ -596,8 +596,7 @@ protected:
// but is also explicitly set in OnStopRequest.
nsCOMPtr<nsIDOMBlob> mResponseBlob;
// Non-null only when we are able to get a os-file representation of the
// response, i.e. when loading from a file, or when the http-stream
// caches into a file or is reading from a cached file.
// response, i.e. when loading from a file.
nsRefPtr<nsDOMFile> mDOMFile;
// We stream data to mBlobSet when response type is "blob" or "moz-blob"
// and mDOMFile is null.

Просмотреть файл

@ -150,12 +150,17 @@ NS_IMPL_CYCLE_COLLECTION_NATIVE_CLASS(nsEventListenerManager)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(nsEventListenerManager, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(nsEventListenerManager, Release)
inline void
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
nsListenerStruct& aField,
const char* aName,
unsigned aFlags)
{
CycleCollectionNoteChild(aCallback, aField.mListener.get(), aName, aFlags);
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsEventListenerManager)
uint32_t count = tmp->mListeners.Length();
for (uint32_t i = 0; i < count; i++) {
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mListeners[i] mListener");
cb.NoteXPCOMChild(tmp->mListeners.ElementAt(i).mListener.get());
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mListeners)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsEventListenerManager)

Просмотреть файл

@ -1927,6 +1927,9 @@ nsEventStateManager::FireContextClick()
}
}
nsIDocument* doc = mGestureDownContent->GetCurrentDoc();
nsAutoHandlingUserInputStatePusher userInpStatePusher(true, &event, doc);
// dispatch to DOM
nsEventDispatcher::Dispatch(mGestureDownContent, mPresContext, &event,
nullptr, &status);

Просмотреть файл

@ -1204,6 +1204,19 @@ nsHTMLInputElement::GetStepBase() const
{
double stepBase = GetMinAsDouble();
// If @min is not a double, we should use defaultValue.
if (MOZ_DOUBLE_IS_NaN(stepBase)) {
nsAutoString stringValue;
GetAttr(kNameSpaceID_None, nsGkAtoms::value, stringValue);
nsresult ec;
stepBase = stringValue.ToDouble(&ec);
if (NS_FAILED(ec)) {
stepBase = MOZ_DOUBLE_NaN();
}
}
return MOZ_DOUBLE_IS_NaN(stepBase) ? kDefaultStepBase : stepBase;
}

Просмотреть файл

@ -45,8 +45,11 @@ var types = [
[ 'button', false ],
];
var input = document.createElement("input");
document.getElementById('content').appendChild(input);
function getFreshElement(type) {
var elmt = document.createElement('input');
elmt.type = type;
return elmt;
}
function checkValidity(aElement, aValidity, aApply, aData)
{
@ -74,7 +77,7 @@ function checkValidity(aElement, aValidity, aApply, aData)
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({'set': [["dom.experimental_forms", true]]}, function() {
for each (var data in types) {
input.type = data[0];
var input = getFreshElement(data[0]);
var apply = data[1];
if (data[2]) {
@ -227,10 +230,35 @@ for each (var data in types) {
input.max = '10';
input.value = '-9';
checkValidity(input, false, apply, {low: -10, high: -8});
// If there is a value defined but no min, the step base is the value.
input = getFreshElement(data[0]);
input.setAttribute('value', '1');
input.step = 2;
checkValidity(input, true, apply);
input.value = 3;
checkValidity(input, true, apply);
input.value = 2;
checkValidity(input, false, apply, {low: 1, high: 3});
// Should also work with defaultValue.
input = getFreshElement(data[0]);
input.defaultValue = 1;
input.step = 2;
checkValidity(input, true, apply);
input.value = 3;
checkValidity(input, true, apply);
input.value = 2;
checkValidity(input, false, apply, {low: 1, high: 3});
}
if (input.type == 'number') {
// Check that when the higher value is higher than max, we don't show it.
input = getFreshElement(data[0]);
input.step = '2';
input.min = '1';
input.max = '10.9';
@ -240,12 +268,6 @@ for each (var data in types) {
"The nearest valid value is 9.",
"The validation message should not include the higher value.");
}
// Cleaning up,
input.removeAttribute('step');
input.removeAttribute('max');
input.removeAttribute('min');
input.value = '';
}
SimpleTest.finish();

Просмотреть файл

@ -124,8 +124,6 @@ function checkStepDownForNumber()
[ '1', null, null, null, 1.1, '0', false ],
// With step values.
[ '1', '0.5', null, null, null, '0.5', false ],
[ null, '0.5', null, null, null, '0', false ],
[ null, '0.5', null, null, null, '-0.5', false ],
[ '1', '0.25', null, null, 4, '0', false ],
// step = 0 isn't allowed (-> step = 1).
[ '1', '0', null, null, null, '0', false ],
@ -147,21 +145,21 @@ function checkStepDownForNumber()
[ '1', null, null, '-10', null, '-10', false ],
[ '1', null, null, '1', null, '0', false ],
[ '5', null, null, '3', '3', '2', false ],
[ '5', '2', null, '3', '2', '2', false ],
[ '5', '2', '-6', '3', '2', '2', false ],
[ '-3', '5', '-10', '-3', null, '-5', false ],
// Step mismatch.
[ '1', '2', '-2', null, null, '0', false ],
[ '3', '2', '-2', null, null, '2', false ],
[ '3', '2', '-2', null, '2', '0', false ],
[ '3', '2', '-2', null, '-2', '6', false ],
[ '1', '2', null, null, null, '0', false ],
[ '1', '2', '-6', null, null, '0', false ],
[ '1', '2', '-2', null, null, '0', false ],
[ '1', '3', null, null, null, '0', false ],
[ '2', '3', null, null, null, '0', false ],
[ '1', '3', '-6', null, null, '0', false ],
[ '2', '3', '-6', null, null, '0', false ],
[ '2', '3', '1', null, null, '1', false ],
[ '5', '3', '1', null, null, '4', false ],
[ '3', '2', null, null, null, '2', false ],
[ '5', '2', null, null, null, '4', false ],
[ '3', '2', '-6', null, null, '2', false ],
[ '5', '2', '-6', null, null, '4', false ],
[ '6', '2', '1', null, null, '5', false ],
[ '8', '3', '1', null, null, '7', false ],
[ '9', '2', '-10', null, null, '8', false ],
@ -178,13 +176,16 @@ function checkStepDownForNumber()
[ '0', 'ANY', null, null, 1, null, true ],
[ '0', 'AnY', null, null, 1, null, true ],
[ '0', 'aNy', null, null, 1, null, true ],
// With @value = step base.
[ '1', '2', null, null, null, '-1', false ],
];
var element = document.createElement("input");
element.type = 'number';
for each (var data in testData) {
var element = document.createElement("input");
element.type = 'number';
if (data[0] != null) {
element.value = data[0];
element.setAttribute('value', data[0]);
}
if (data[1] != null) {
@ -216,10 +217,6 @@ function checkStepDownForNumber()
} finally {
is(exceptionCaught, data[6], "exception status should be " + data[6]);
}
element.removeAttribute('step');
element.removeAttribute('min');
element.removeAttribute('max');
}
}
@ -240,8 +237,6 @@ function checkStepUpForNumber()
[ '1', null, null, null, 1.1, '2', false ],
// With step values.
[ '1', '0.5', null, null, null, '1.5', false ],
[ null, '0.5', null, null, null, '2', false ],
[ null, '0.5', null, null, null, '2.5', false ],
[ '1', '0.25', null, null, 4, '2', false ],
// step = 0 isn't allowed (-> step = 1).
[ '1', '0', null, null, null, '2', false ],
@ -269,7 +264,7 @@ function checkStepUpForNumber()
[ '1', '2', '0', null, null, '2', false ],
[ '1', '2', '0', null, '2', '4', false ],
[ '8', '2', null, '9', null, '8', false ],
[ '-3', '2', null, null, null, '-2', false ],
[ '-3', '2', '-6', null, null, '-2', false ],
[ '9', '3', '-10', null, null, '11', false ],
[ '7', '3', '-10', null, null, '8', false ],
[ '7', '3', '5', null, null, '8', false ],
@ -282,8 +277,8 @@ function checkStepUpForNumber()
[ '-9', '3', '-8', '-1', '5', '-2', false ],
[ '-9', '3', '8', '15', '15', '14', false ],
[ '-1', '3', '-1', '4', '3', '2', false ],
[ '-3', '2', null, '-2', null, '-2', false ],
[ '-3', '2', null, '-1', null, '-2', false ],
[ '-3', '2', '-6', '-2', null, '-2', false ],
[ '-3', '2', '-6', '-1', null, '-2', false ],
// value = "" (NaN).
[ '', null, null, null, null, '', false ],
// With step = 'any'.
@ -291,13 +286,16 @@ function checkStepUpForNumber()
[ '0', 'ANY', null, null, 1, null, true ],
[ '0', 'AnY', null, null, 1, null, true ],
[ '0', 'aNy', null, null, 1, null, true ],
// With @value = step base.
[ '1', '2', null, null, null, '3', false ],
];
var element = document.createElement("input");
element.type = 'number';
for each (var data in testData) {
var element = document.createElement("input");
element.type = 'number';
if (data[0] != null) {
element.value = data[0];
element.setAttribute('value', data[0]);
}
if (data[1] != null) {
@ -329,10 +327,6 @@ function checkStepUpForNumber()
} finally {
is(exceptionCaught, data[6], "exception status should be " + data[6]);
}
element.removeAttribute('step');
element.removeAttribute('min');
element.removeAttribute('max');
}
}

Просмотреть файл

@ -10,6 +10,9 @@
#ifdef MOZ_MEDIA_PLUGINS
#include "MediaPluginHost.h"
#endif
#ifdef MOZ_GSTREAMER
#include "mozilla/Preferences.h"
#endif
namespace mozilla
{

Просмотреть файл

@ -17,6 +17,7 @@ LIBXUL_LIBRARY = 1
EXPORTS += \
GStreamerDecoder.h \
GStreamerReader.h \
$(NULL)
CPPSRCS = \

Просмотреть файл

@ -18,6 +18,7 @@ LIBXUL_LIBRARY = 1
EXPORTS += \
OggDecoder.h \
OggCodecState.h \
OggReader.h \
$(NULL)
CPPSRCS = \

Просмотреть файл

@ -194,7 +194,7 @@ void OggCodecState::ReleasePacket(ogg_packet* aPacket) {
delete aPacket;
}
void PacketQueue::Append(ogg_packet* aPacket) {
void OggPacketQueue::Append(ogg_packet* aPacket) {
nsDeque::Push(aPacket);
}

Просмотреть файл

@ -38,7 +38,7 @@
namespace mozilla {
// Deallocates a packet, used in PacketQueue below.
// Deallocates a packet, used in OggPacketQueue below.
class OggPacketDeallocator : public nsDequeFunctor {
virtual void* operator() (void* aPacket) {
ogg_packet* p = static_cast<ogg_packet*>(aPacket);
@ -58,10 +58,10 @@ class OggPacketDeallocator : public nsDequeFunctor {
// frames/samples, reducing the amount of frames/samples we must decode to
// determine start-time at a particular offset, and gives us finer control
// over memory usage.
class PacketQueue : private nsDeque {
class OggPacketQueue : private nsDeque {
public:
PacketQueue() : nsDeque(new OggPacketDeallocator()) {}
~PacketQueue() { Erase(); }
OggPacketQueue() : nsDeque(new OggPacketDeallocator()) {}
~OggPacketQueue() { Erase(); }
bool IsEmpty() { return nsDeque::GetSize() == 0; }
void Append(ogg_packet* aPacket);
ogg_packet* PopFront() { return static_cast<ogg_packet*>(nsDeque::PopFront()); }
@ -167,7 +167,7 @@ public:
// Queue of as yet undecoded packets. Packets are guaranteed to have
// a valid granulepos.
PacketQueue mPackets;
OggPacketQueue mPackets;
// Is the bitstream active; whether we're decoding and playing this bitstream.
bool mActive;

Просмотреть файл

@ -24,6 +24,7 @@ struct VideoFrame {
int64_t mTimeUs;
int64_t mEndTimeUs;
bool mKeyFrame;
bool mShouldSkip;
void *mData;
size_t mSize;
int32_t mStride;

Просмотреть файл

@ -15,6 +15,7 @@ LIBXUL_LIBRARY = 1
EXPORTS += \
MediaOmxDecoder.h \
MediaOmxReader.h \
$(NULL)
CPPSRCS = \

Просмотреть файл

@ -14,6 +14,8 @@
#include "MediaOmxDecoder.h"
#include "AbstractMediaDecoder.h"
#define MAX_DROPPED_FRAMES 25
using namespace android;
namespace mozilla {
@ -25,7 +27,8 @@ MediaOmxReader::MediaOmxReader(AbstractMediaDecoder *aDecoder) :
mHasAudio(false),
mVideoSeekTimeUs(-1),
mAudioSeekTimeUs(-1),
mLastVideoFrame(nullptr)
mLastVideoFrame(nullptr),
mSkipCount(0)
{
}
@ -142,6 +145,7 @@ bool MediaOmxReader::DecodeVideoFrame(bool &aKeyframeSkip,
while (true) {
MPAPI::VideoFrame frame;
frame.mGraphicBuffer = nullptr;
frame.mShouldSkip = false;
if (!mOmxDecoder->ReadVideo(&frame, aTimeThreshold, aKeyframeSkip, doSeek)) {
// We reached the end of the video stream. If we have a buffered
// video frame, push it the video queue using the total duration
@ -159,6 +163,14 @@ bool MediaOmxReader::DecodeVideoFrame(bool &aKeyframeSkip,
return false;
}
parsed++;
if (frame.mShouldSkip && mSkipCount < MAX_DROPPED_FRAMES) {
mSkipCount++;
return true;
}
mSkipCount = 0;
mVideoSeekTimeUs = -1;
doSeek = aKeyframeSkip = false;
@ -229,7 +241,6 @@ bool MediaOmxReader::DecodeVideoFrame(bool &aKeyframeSkip,
return false;
}
parsed++;
decoded++;
NS_ASSERTION(decoded <= parsed, "Expect to decode fewer frames than parsed in MediaPlugin...");

Просмотреть файл

@ -28,6 +28,7 @@ class MediaOmxReader : public MediaDecoderReader
int64_t mVideoSeekTimeUs;
int64_t mAudioSeekTimeUs;
VideoData *mLastVideoFrame;
int32_t mSkipCount;
public:
MediaOmxReader(AbstractMediaDecoder* aDecoder);
~MediaOmxReader();

Просмотреть файл

@ -458,10 +458,9 @@ bool OmxDecoder::ReadVideo(VideoFrame *aFrame, int64_t aTimeUs,
status_t err;
if (aDoSeek || aKeyframeSkip) {
if (aDoSeek) {
MediaSource::ReadOptions options;
options.setSeekTo(aTimeUs, aDoSeek ? MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC :
MediaSource::ReadOptions::SEEK_NEXT_SYNC);
options.setSeekTo(aTimeUs, MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC);
err = mVideoSource->read(&mVideoBuffer, &options);
} else {
err = mVideoSource->read(&mVideoBuffer);
@ -514,6 +513,10 @@ bool OmxDecoder::ReadVideo(VideoFrame *aFrame, int64_t aTimeUs,
aFrame->mEndTimeUs = timeUs + durationUs;
}
if (aKeyframeSkip && timeUs < aTimeUs) {
aFrame->mShouldSkip = true;
}
}
else if (err == INFO_FORMAT_CHANGED) {
// If the format changed, update our cached info.
@ -571,6 +574,11 @@ bool OmxDecoder::ReadAudio(AudioFrame *aFrame, int64_t aSeekTimeUs)
return ReadAudio(aFrame, aSeekTimeUs);
}
}
else if (err == ERROR_END_OF_STREAM) {
if (aFrame->mSize == 0) {
return false;
}
}
return true;
}

Просмотреть файл

@ -17,6 +17,7 @@ EXPORTS += \
MPAPI.h \
MediaPluginHost.h \
MediaPluginDecoder.h \
MediaPluginReader.h \
$(NULL)
CPPSRCS = \

Просмотреть файл

@ -16,7 +16,7 @@ MediaPluginDecoder::MediaPluginDecoder(const nsACString& aType) : mType(aType)
MediaDecoderStateMachine* MediaPluginDecoder::CreateStateMachine()
{
return new MediaDecoderStateMachine(this, new MediaPluginReader(this));
return new MediaDecoderStateMachine(this, new MediaPluginReader(this, mType));
}
} // namespace mozilla

Просмотреть файл

@ -15,8 +15,10 @@
namespace mozilla {
MediaPluginReader::MediaPluginReader(AbstractMediaDecoder *aDecoder) :
MediaPluginReader::MediaPluginReader(AbstractMediaDecoder *aDecoder,
const nsACString& aContentType) :
MediaDecoderReader(aDecoder),
mType(aContentType),
mPlugin(NULL),
mHasAudio(false),
mHasVideo(false),
@ -24,7 +26,6 @@ MediaPluginReader::MediaPluginReader(AbstractMediaDecoder *aDecoder) :
mAudioSeekTimeUs(-1),
mLastVideoFrame(NULL)
{
static_cast<MediaPluginDecoder *>(aDecoder)->GetContentType(mType);
}
MediaPluginReader::~MediaPluginReader()

Просмотреть файл

@ -11,6 +11,8 @@
#include "MPAPI.h"
class nsACString;
namespace mozilla {
class AbstractMediaDecoder;
@ -27,7 +29,8 @@ class MediaPluginReader : public MediaDecoderReader
int64_t mAudioSeekTimeUs;
VideoData *mLastVideoFrame;
public:
MediaPluginReader(AbstractMediaDecoder* aDecoder);
MediaPluginReader(AbstractMediaDecoder* aDecoder,
const nsACString& aContentType);
~MediaPluginReader();
virtual nsresult Init(MediaDecoderReader* aCloneDonor);

Просмотреть файл

@ -17,6 +17,7 @@ LIBXUL_LIBRARY = 1
EXPORTS += \
WaveDecoder.h \
WaveReader.h \
$(NULL)
CPPSRCS = \

Просмотреть файл

@ -32,14 +32,10 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(AudioContext)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindow)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDestination)
// Cannot use NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR since AudioListener
// does not inherit from nsISupports.
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mListener)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_NATIVE_BEGIN(AudioContext)
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(AudioContext)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(AudioContext, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(AudioContext, Release)
@ -64,7 +60,7 @@ AudioContext::WrapObject(JSContext* aCx, JSObject* aScope,
/* static */ already_AddRefed<AudioContext>
AudioContext::Constructor(nsISupports* aGlobal, ErrorResult& aRv)
{
nsCOMPtr<nsIDOMWindow> window = do_QueryInterface(aGlobal);
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aGlobal);
if (!window) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
@ -72,6 +68,7 @@ AudioContext::Constructor(nsISupports* aGlobal, ErrorResult& aRv)
AudioContext* object = new AudioContext(window);
NS_ADDREF(object);
window->AddAudioContext(object);
return object;
}

Просмотреть файл

@ -49,6 +49,8 @@ public:
return mWindow;
}
void Shutdown() {}
virtual JSObject* WrapObject(JSContext* aCx, JSObject* aScope,
bool* aTriedToWrap);

Просмотреть файл

@ -25,9 +25,8 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(AudioListener)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_NATIVE_BEGIN(AudioListener)
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(AudioListener)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(AudioListener, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(AudioListener, Release)

Просмотреть файл

@ -22,9 +22,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(AudioParam)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mContext)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_NATIVE_BEGIN(AudioParam)
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(AudioParam)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(AudioParam, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(AudioParam, Release)

Просмотреть файл

@ -35,6 +35,7 @@ EXPORTS_NAMESPACES := mozilla/dom
EXPORTS_mozilla/dom := \
AudioBuffer.h \
AudioBufferSourceNode.h \
AudioContext.h \
AudioDestinationNode.h \
AudioListener.h \
AudioNode.h \

Просмотреть файл

@ -7,6 +7,7 @@ topsrcdir := @top_srcdir@
srcdir := @srcdir@
VPATH := @srcdir@
relativesrcdir := @relativesrcdir@
FAIL_ON_WARNINGS = 1
include $(DEPTH)/config/autoconf.mk

Просмотреть файл

@ -195,16 +195,16 @@ void TestEventReplacement()
ErrorResultMock rv;
is(timeline.GetEventCount(), 0, "No events yet");
is(timeline.GetEventCount(), 0u, "No events yet");
timeline.SetValueAtTime(10.0f, 0.1, rv);
is(timeline.GetEventCount(), 1, "One event scheduled now");
is(timeline.GetEventCount(), 1u, "One event scheduled now");
timeline.SetValueAtTime(20.0f, 0.1, rv);
is(rv, NS_OK, "Event scheduling should be successful");
is(timeline.GetEventCount(), 1, "Event should be replaced");
is(timeline.GetEventCount(), 1u, "Event should be replaced");
is(timeline.GetValueAtTime(0.1f), 20.0f, "The first event should be overwritten");
timeline.LinearRampToValueAtTime(30.0f, 0.1, rv);
is(rv, NS_OK, "Event scheduling should be successful");
is(timeline.GetEventCount(), 2, "Different event type should be appended");
is(timeline.GetEventCount(), 2u, "Different event type should be appended");
is(timeline.GetValueAtTime(0.1f), 30.0f, "The first event should be overwritten");
}
@ -218,13 +218,13 @@ void TestEventRemoval()
timeline.SetValueAtTime(15.0f, 0.15, rv);
timeline.SetValueAtTime(20.0f, 0.2, rv);
timeline.LinearRampToValueAtTime(30.0f, 0.3, rv);
is(timeline.GetEventCount(), 4, "Should have three events initially");
is(timeline.GetEventCount(), 4u, "Should have three events initially");
timeline.CancelScheduledValues(0.4);
is(timeline.GetEventCount(), 4, "Trying to delete past the end of the array should have no effect");
is(timeline.GetEventCount(), 4u, "Trying to delete past the end of the array should have no effect");
timeline.CancelScheduledValues(0.3);
is(timeline.GetEventCount(), 3, "Should successfully delete one event");
is(timeline.GetEventCount(), 3u, "Should successfully delete one event");
timeline.CancelScheduledValues(0.12);
is(timeline.GetEventCount(), 1, "Should successfully delete two events");
is(timeline.GetEventCount(), 1u, "Should successfully delete two events");
}
void TestBeforeFirstEvent()

Просмотреть файл

@ -17,6 +17,7 @@ LIBXUL_LIBRARY = 1
EXPORTS += \
WebMDecoder.h \
WebMReader.h \
$(NULL)
CPPSRCS = \

Просмотреть файл

@ -526,11 +526,11 @@ nsReturnRef<NesteggPacketHolder> WebMReader::NextPacket(TrackType aTrackType)
{
// The packet queue that packets will be pushed on if they
// are not the type we are interested in.
PacketQueue& otherPackets =
WebMPacketQueue& otherPackets =
aTrackType == VIDEO ? mAudioPackets : mVideoPackets;
// The packet queue for the type that we are interested in.
PacketQueue &packets =
WebMPacketQueue &packets =
aTrackType == VIDEO ? mVideoPackets : mAudioPackets;
// Flag to indicate that we do need to playback these types of

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше