mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 19:35:51 +00:00
Merge m-c to s-c.
This commit is contained in:
commit
311ea9597c
@ -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)
|
||||
|
||||
|
35
accessible/src/windows/sdn/Makefile.in
Normal file
35
accessible/src/windows/sdn/Makefile.in
Normal file
@ -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)
|
36
accessible/src/windows/sdn/sdnAccessible-inl.h
Normal file
36
accessible/src/windows/sdn/sdnAccessible-inl.h
Normal file
@ -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_
|
537
accessible/src/windows/sdn/sdnAccessible.cpp
Normal file
537
accessible/src/windows/sdn/sdnAccessible.cpp
Normal file
@ -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
|
||||
}
|
113
accessible/src/windows/sdn/sdnAccessible.h
Normal file
113
accessible/src/windows/sdn/sdnAccessible.h
Normal file
@ -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
|
||||
|
||||
|
20
b2g/config/otoro/config.json
Normal file
20
b2g/config/otoro/config.json
Normal file
@ -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"}
|
||||
}
|
8
b2g/config/otoro/releng-otoro.tt
Normal file
8
b2g/config/otoro/releng-otoro.tt
Normal file
@ -0,0 +1,8 @@
|
||||
[
|
||||
{
|
||||
"size": 868355892,
|
||||
"digest": "0ccae39ee8910947fe3cf51fa3a45e820d2ff11571f6ccec29d9b3e5ae7f7709c1ad657210fbfea98baadd032c3d6a58e00ddbb2e93acafd751089869a72fed6",
|
||||
"algorithm": "sha512",
|
||||
"filename": "gonk.tar.xz"
|
||||
}
|
||||
]
|
108
b2g/config/otoro/sources.xml
Normal file
108
b2g/config/otoro/sources.xml
Normal file
@ -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 += \
|
||||
|
11
browser/base/content/test/blockPluginVulnerableNoUpdate.xml
Normal file
11
browser/base/content/test/blockPluginVulnerableNoUpdate.xml
Normal file
@ -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>
|
11
browser/base/content/test/blockPluginVulnerableUpdatable.xml
Normal file
11
browser/base/content/test/blockPluginVulnerableUpdatable.xml
Normal file
@ -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>
|
81
browser/base/content/test/browser_bug812562.js
Normal file
81
browser/base/content/test/browser_bug812562.js
Normal file
@ -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.
|
||||
|
18
configure.in
18
configure.in
@ -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
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user