зеркало из https://github.com/mozilla/gecko-dev.git
merge mozilla-central to tracemonkey
This commit is contained in:
Коммит
cc61a33126
|
@ -37,10 +37,12 @@
|
||||||
|
|
||||||
#include "AccIterator.h"
|
#include "AccIterator.h"
|
||||||
|
|
||||||
|
#include "nsAccessibilityService.h"
|
||||||
#include "nsAccessible.h"
|
#include "nsAccessible.h"
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// nsAccIterator
|
// AccIterator
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
AccIterator::AccIterator(nsAccessible *aAccessible,
|
AccIterator::AccIterator(nsAccessible *aAccessible,
|
||||||
filters::FilterFuncPtr aFilterFunc,
|
filters::FilterFuncPtr aFilterFunc,
|
||||||
|
@ -93,3 +95,45 @@ AccIterator::IteratorState::IteratorState(nsAccessible *aParent,
|
||||||
mParent(aParent), mIndex(0), mParentState(mParentState)
|
mParent(aParent), mIndex(0), mParentState(mParentState)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// RelatedAccIterator
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
RelatedAccIterator::
|
||||||
|
RelatedAccIterator(nsDocAccessible* aDocument, nsIContent* aDependentContent,
|
||||||
|
nsIAtom* aRelAttr) :
|
||||||
|
mRelAttr(aRelAttr), mProviders(nsnull), mBindingParent(nsnull), mIndex(0)
|
||||||
|
{
|
||||||
|
mBindingParent = aDependentContent->GetBindingParent();
|
||||||
|
nsIAtom* IDAttr = mBindingParent ?
|
||||||
|
nsAccessibilityAtoms::anonid : aDependentContent->GetIDAttributeName();
|
||||||
|
|
||||||
|
nsAutoString id;
|
||||||
|
if (aDependentContent->GetAttr(kNameSpaceID_None, IDAttr, id))
|
||||||
|
mProviders = aDocument->mDependentIDsHash.Get(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsAccessible*
|
||||||
|
RelatedAccIterator::Next()
|
||||||
|
{
|
||||||
|
if (!mProviders)
|
||||||
|
return nsnull;
|
||||||
|
|
||||||
|
while (mIndex < mProviders->Length()) {
|
||||||
|
nsDocAccessible::AttrRelProvider* provider = (*mProviders)[mIndex++];
|
||||||
|
|
||||||
|
// Return related accessible for the given attribute and if the provider
|
||||||
|
// content is in the same binding in the case of XBL usage.
|
||||||
|
if (provider->mRelAttr == mRelAttr &&
|
||||||
|
(!mBindingParent ||
|
||||||
|
mBindingParent == provider->mContent->GetBindingParent())) {
|
||||||
|
nsAccessible* related = GetAccService()->GetAccessible(provider->mContent);
|
||||||
|
if (related)
|
||||||
|
return related;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nsnull;
|
||||||
|
}
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
|
|
||||||
#include "filters.h"
|
#include "filters.h"
|
||||||
#include "nscore.h"
|
#include "nscore.h"
|
||||||
|
#include "nsDocAccessible.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allows to iterate through accessible children or subtree complying with
|
* Allows to iterate through accessible children or subtree complying with
|
||||||
|
@ -93,4 +94,41 @@ private:
|
||||||
IteratorState *mState;
|
IteratorState *mState;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows to traverse through related accessibles that are pointing to the given
|
||||||
|
* dependent accessible by relation attribute.
|
||||||
|
*/
|
||||||
|
class RelatedAccIterator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param aDocument [in] the document accessible the related
|
||||||
|
* & accessibles belong to.
|
||||||
|
* @param aDependentContent [in] the content of dependent accessible that
|
||||||
|
* relations were requested for
|
||||||
|
* @param aRelAttr [in] relation attribute that relations are
|
||||||
|
* pointed by
|
||||||
|
*/
|
||||||
|
RelatedAccIterator(nsDocAccessible* aDocument, nsIContent* aDependentContent,
|
||||||
|
nsIAtom* aRelAttr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return next related accessible for the given dependent accessible.
|
||||||
|
*/
|
||||||
|
nsAccessible* Next();
|
||||||
|
|
||||||
|
private:
|
||||||
|
RelatedAccIterator();
|
||||||
|
RelatedAccIterator(const RelatedAccIterator&);
|
||||||
|
RelatedAccIterator& operator = (const RelatedAccIterator&);
|
||||||
|
|
||||||
|
nsIAtom* mRelAttr;
|
||||||
|
nsDocAccessible::AttrRelProviderArray* mProviders;
|
||||||
|
nsIContent* mBindingParent;
|
||||||
|
PRUint32 mIndex;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -844,15 +844,11 @@ static PRBool HasRelatedContent(nsIContent *aContent)
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIAtom *relationAttrs[] = {nsAccessibilityAtoms::aria_labelledby,
|
// If the given ID is referred by relation attribute then create an accessible
|
||||||
nsAccessibilityAtoms::aria_describedby,
|
// for it. Take care of HTML elements only for now.
|
||||||
nsAccessibilityAtoms::aria_owns,
|
if (aContent->IsHTML() &&
|
||||||
nsAccessibilityAtoms::aria_controls,
|
nsAccUtils::GetDocAccessibleFor(aContent)->IsDependentID(id))
|
||||||
nsAccessibilityAtoms::aria_flowto};
|
|
||||||
if (nsCoreUtils::FindNeighbourPointingToNode(aContent, relationAttrs,
|
|
||||||
NS_ARRAY_LENGTH(relationAttrs))) {
|
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
|
||||||
|
|
||||||
nsIContent *ancestorContent = aContent;
|
nsIContent *ancestorContent = aContent;
|
||||||
while ((ancestorContent = ancestorContent->GetParent()) != nsnull) {
|
while ((ancestorContent = ancestorContent->GetParent()) != nsnull) {
|
||||||
|
|
|
@ -2037,25 +2037,28 @@ nsAccessible::GetRelationByType(PRUint32 aRelationType,
|
||||||
|
|
||||||
// Relationships are defined on the same content node that the role would be
|
// Relationships are defined on the same content node that the role would be
|
||||||
// defined on.
|
// defined on.
|
||||||
nsresult rv;
|
nsresult rv = NS_OK_NO_RELATION_TARGET;
|
||||||
switch (aRelationType)
|
switch (aRelationType)
|
||||||
{
|
{
|
||||||
case nsIAccessibleRelation::RELATION_LABEL_FOR:
|
case nsIAccessibleRelation::RELATION_LABEL_FOR:
|
||||||
{
|
{
|
||||||
|
RelatedAccIterator iter(GetDocAccessible(), mContent,
|
||||||
|
nsAccessibilityAtoms::aria_labelledby);
|
||||||
|
|
||||||
|
nsAccessible* related = nsnull;
|
||||||
|
while ((related = iter.Next())) {
|
||||||
|
rv = nsRelUtils::AddTarget(aRelationType, aRelation, related);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
}
|
||||||
|
|
||||||
if (mContent->Tag() == nsAccessibilityAtoms::label) {
|
if (mContent->Tag() == nsAccessibilityAtoms::label) {
|
||||||
nsIAtom *IDAttr = mContent->IsHTML() ?
|
nsIAtom *IDAttr = mContent->IsHTML() ?
|
||||||
nsAccessibilityAtoms::_for : nsAccessibilityAtoms::control;
|
nsAccessibilityAtoms::_for : nsAccessibilityAtoms::control;
|
||||||
rv = nsRelUtils::
|
rv = nsRelUtils::
|
||||||
AddTargetFromIDRefAttr(aRelationType, aRelation, mContent, IDAttr);
|
AddTargetFromIDRefAttr(aRelationType, aRelation, mContent, IDAttr);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
if (rv != NS_OK_NO_RELATION_TARGET)
|
|
||||||
return NS_OK; // XXX bug 381599, avoid performance problems
|
|
||||||
}
|
}
|
||||||
|
return rv;
|
||||||
return nsRelUtils::
|
|
||||||
AddTargetFromNeighbour(aRelationType, aRelation, mContent,
|
|
||||||
nsAccessibilityAtoms::aria_labelledby);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case nsIAccessibleRelation::RELATION_LABELLED_BY:
|
case nsIAccessibleRelation::RELATION_LABELLED_BY:
|
||||||
|
@ -2091,13 +2094,14 @@ nsAccessible::GetRelationByType(PRUint32 aRelationType,
|
||||||
|
|
||||||
case nsIAccessibleRelation::RELATION_DESCRIPTION_FOR:
|
case nsIAccessibleRelation::RELATION_DESCRIPTION_FOR:
|
||||||
{
|
{
|
||||||
rv = nsRelUtils::
|
RelatedAccIterator iter(GetDocAccessible(), mContent,
|
||||||
AddTargetFromNeighbour(aRelationType, aRelation, mContent,
|
nsAccessibilityAtoms::aria_describedby);
|
||||||
nsAccessibilityAtoms::aria_describedby);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
if (rv != NS_OK_NO_RELATION_TARGET)
|
nsAccessible* related = nsnull;
|
||||||
return NS_OK; // XXX bug 381599, avoid performance problems
|
while ((related = iter.Next())) {
|
||||||
|
rv = nsRelUtils::AddTarget(aRelationType, aRelation, related);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
}
|
||||||
|
|
||||||
if (mContent->Tag() == nsAccessibilityAtoms::description &&
|
if (mContent->Tag() == nsAccessibilityAtoms::description &&
|
||||||
mContent->IsXUL()) {
|
mContent->IsXUL()) {
|
||||||
|
@ -2109,18 +2113,23 @@ nsAccessible::GetRelationByType(PRUint32 aRelationType,
|
||||||
nsAccessibilityAtoms::control);
|
nsAccessibilityAtoms::control);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
case nsIAccessibleRelation::RELATION_NODE_CHILD_OF:
|
case nsIAccessibleRelation::RELATION_NODE_CHILD_OF:
|
||||||
{
|
{
|
||||||
rv = nsRelUtils::
|
RelatedAccIterator iter(GetDocAccessible(), mContent,
|
||||||
AddTargetFromNeighbour(aRelationType, aRelation, mContent,
|
nsAccessibilityAtoms::aria_owns);
|
||||||
nsAccessibilityAtoms::aria_owns);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
|
nsAccessible* related = nsnull;
|
||||||
|
while ((related = iter.Next())) {
|
||||||
|
rv = nsRelUtils::AddTarget(aRelationType, aRelation, related);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Got relation from aria-owns, don't calculate it from native markup.
|
||||||
if (rv != NS_OK_NO_RELATION_TARGET)
|
if (rv != NS_OK_NO_RELATION_TARGET)
|
||||||
return NS_OK; // XXX bug 381599, avoid performance problems
|
return NS_OK;
|
||||||
|
|
||||||
// This is an ARIA tree or treegrid that doesn't use owns, so we need to
|
// This is an ARIA tree or treegrid that doesn't use owns, so we need to
|
||||||
// get the parent the hard way.
|
// get the parent the hard way.
|
||||||
|
@ -2153,14 +2162,20 @@ nsAccessible::GetRelationByType(PRUint32 aRelationType,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
case nsIAccessibleRelation::RELATION_CONTROLLED_BY:
|
case nsIAccessibleRelation::RELATION_CONTROLLED_BY:
|
||||||
{
|
{
|
||||||
return nsRelUtils::
|
RelatedAccIterator iter(GetDocAccessible(), mContent,
|
||||||
AddTargetFromNeighbour(aRelationType, aRelation, mContent,
|
nsAccessibilityAtoms::aria_controls);
|
||||||
nsAccessibilityAtoms::aria_controls);
|
|
||||||
|
nsAccessible* related = nsnull;
|
||||||
|
while ((related = iter.Next())) {
|
||||||
|
rv = nsRelUtils::AddTarget(aRelationType, aRelation, related);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
case nsIAccessibleRelation::RELATION_CONTROLLER_FOR:
|
case nsIAccessibleRelation::RELATION_CONTROLLER_FOR:
|
||||||
|
@ -2188,9 +2203,15 @@ nsAccessible::GetRelationByType(PRUint32 aRelationType,
|
||||||
|
|
||||||
case nsIAccessibleRelation::RELATION_FLOWS_FROM:
|
case nsIAccessibleRelation::RELATION_FLOWS_FROM:
|
||||||
{
|
{
|
||||||
return nsRelUtils::
|
RelatedAccIterator iter(GetDocAccessible(), mContent,
|
||||||
AddTargetFromNeighbour(aRelationType, aRelation, mContent,
|
nsAccessibilityAtoms::aria_flowto);
|
||||||
nsAccessibilityAtoms::aria_flowto);
|
|
||||||
|
nsAccessible* related = nsnull;
|
||||||
|
while ((related = iter.Next())) {
|
||||||
|
rv = nsRelUtils::AddTarget(aRelationType, aRelation, related);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
case nsIAccessibleRelation::RELATION_DEFAULT_BUTTON:
|
case nsIAccessibleRelation::RELATION_DEFAULT_BUTTON:
|
||||||
|
@ -3169,8 +3190,17 @@ nsAccessible::EnsureChildren()
|
||||||
|
|
||||||
// State is embedded children until text leaf accessible is appended.
|
// State is embedded children until text leaf accessible is appended.
|
||||||
mChildrenFlags = eEmbeddedChildren; // Prevent reentry
|
mChildrenFlags = eEmbeddedChildren; // Prevent reentry
|
||||||
|
|
||||||
|
// Notify the document about caching status.
|
||||||
|
nsDocAccessible* document = GetDocAccessible();
|
||||||
|
if (document)
|
||||||
|
document->NotifyOfCachingStart(this);
|
||||||
|
|
||||||
CacheChildren();
|
CacheChildren();
|
||||||
|
|
||||||
|
if (document)
|
||||||
|
document->NotifyOfCachingEnd(this);
|
||||||
|
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,6 @@
|
||||||
#include "nsStringGlue.h"
|
#include "nsStringGlue.h"
|
||||||
#include "nsTArray.h"
|
#include "nsTArray.h"
|
||||||
#include "nsRefPtrHashtable.h"
|
#include "nsRefPtrHashtable.h"
|
||||||
#include "nsDataHashtable.h"
|
|
||||||
|
|
||||||
class AccGroupInfo;
|
class AccGroupInfo;
|
||||||
class EmbeddedObjCollector;
|
class EmbeddedObjCollector;
|
||||||
|
@ -67,8 +66,6 @@ class nsIView;
|
||||||
|
|
||||||
typedef nsRefPtrHashtable<nsVoidPtrHashKey, nsAccessible>
|
typedef nsRefPtrHashtable<nsVoidPtrHashKey, nsAccessible>
|
||||||
nsAccessibleHashtable;
|
nsAccessibleHashtable;
|
||||||
typedef nsDataHashtable<nsPtrHashKey<const nsINode>, nsAccessible*>
|
|
||||||
NodeToAccessibleMap;
|
|
||||||
|
|
||||||
// see nsAccessible::GetAttrValue
|
// see nsAccessible::GetAttrValue
|
||||||
#define NS_OK_NO_ARIA_VALUE \
|
#define NS_OK_NO_ARIA_VALUE \
|
||||||
|
|
|
@ -47,7 +47,6 @@
|
||||||
#include "nsIDOM3Node.h"
|
#include "nsIDOM3Node.h"
|
||||||
#include "nsIDOMDocument.h"
|
#include "nsIDOMDocument.h"
|
||||||
#include "nsIDOMDocumentView.h"
|
#include "nsIDOMDocumentView.h"
|
||||||
#include "nsIDOMDocumentXBL.h"
|
|
||||||
#include "nsIDOMHTMLDocument.h"
|
#include "nsIDOMHTMLDocument.h"
|
||||||
#include "nsIDOMHTMLElement.h"
|
#include "nsIDOMHTMLElement.h"
|
||||||
#include "nsIDOMNodeList.h"
|
#include "nsIDOMNodeList.h"
|
||||||
|
@ -805,67 +804,6 @@ nsCoreUtils::GetLanguageFor(nsIContent *aContent, nsIContent *aRootContent,
|
||||||
walkUp = walkUp->GetParent();
|
walkUp = walkUp->GetParent();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
nsCoreUtils::GetElementsByIDRefsAttr(nsIContent *aContent, nsIAtom *aAttr,
|
|
||||||
nsIArray **aRefElements)
|
|
||||||
{
|
|
||||||
*aRefElements = nsnull;
|
|
||||||
|
|
||||||
nsAutoString ids;
|
|
||||||
if (!aContent->GetAttr(kNameSpaceID_None, aAttr, ids))
|
|
||||||
return;
|
|
||||||
|
|
||||||
ids.CompressWhitespace(PR_TRUE, PR_TRUE);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMDocument> document = do_QueryInterface(aContent->GetOwnerDoc());
|
|
||||||
NS_ASSERTION(document, "The given node is not in document!");
|
|
||||||
if (!document)
|
|
||||||
return;
|
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMDocumentXBL> xblDocument;
|
|
||||||
if (aContent->IsInAnonymousSubtree())
|
|
||||||
xblDocument = do_QueryInterface(document);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIMutableArray> refElms = do_CreateInstance(NS_ARRAY_CONTRACTID);
|
|
||||||
|
|
||||||
while (!ids.IsEmpty()) {
|
|
||||||
nsAutoString id;
|
|
||||||
PRInt32 idLength = ids.FindChar(' ');
|
|
||||||
NS_ASSERTION(idLength != 0,
|
|
||||||
"Should not be 0 because of CompressWhitespace() call above");
|
|
||||||
|
|
||||||
if (idLength == kNotFound) {
|
|
||||||
id = ids;
|
|
||||||
ids.Truncate();
|
|
||||||
} else {
|
|
||||||
id = Substring(ids, 0, idLength);
|
|
||||||
ids.Cut(0, idLength + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If content is anonymous subtree then use "anonid" attribute to get
|
|
||||||
// elements, otherwise search elements in DOM by ID attribute.
|
|
||||||
nsCOMPtr<nsIDOMElement> refElement;
|
|
||||||
if (xblDocument) {
|
|
||||||
nsCOMPtr<nsIDOMElement> elm =
|
|
||||||
do_QueryInterface(aContent->GetBindingParent());
|
|
||||||
xblDocument->GetAnonymousElementByAttribute(elm,
|
|
||||||
NS_LITERAL_STRING("anonid"),
|
|
||||||
id,
|
|
||||||
getter_AddRefs(refElement));
|
|
||||||
} else {
|
|
||||||
document->GetElementById(id, getter_AddRefs(refElement));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!refElement)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
refElms->AppendElement(refElement, PR_FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_ADDREF(*aRefElements = refElms);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
nsCoreUtils::GetElementsHavingIDRefsAttr(nsIContent *aRootContent,
|
nsCoreUtils::GetElementsHavingIDRefsAttr(nsIContent *aRootContent,
|
||||||
nsIContent *aContent,
|
nsIContent *aContent,
|
||||||
|
@ -1165,3 +1103,78 @@ nsAccessibleDOMStringList::Contains(const nsAString& aString, PRBool *aResult)
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// IDRefsIterator
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
IDRefsIterator::IDRefsIterator(nsIContent* aContent, nsIAtom* aIDRefsAttr) :
|
||||||
|
mCurrIdx(0)
|
||||||
|
{
|
||||||
|
if (!aContent->IsInDoc() ||
|
||||||
|
!aContent->GetAttr(kNameSpaceID_None, aIDRefsAttr, mIDs))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (aContent->IsInAnonymousSubtree()) {
|
||||||
|
mXBLDocument = do_QueryInterface(aContent->GetOwnerDoc());
|
||||||
|
mBindingParent = do_QueryInterface(aContent->GetBindingParent());
|
||||||
|
} else {
|
||||||
|
mDocument = aContent->GetOwnerDoc();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const nsDependentSubstring
|
||||||
|
IDRefsIterator::NextID()
|
||||||
|
{
|
||||||
|
for (; mCurrIdx < mIDs.Length(); mCurrIdx++) {
|
||||||
|
if (!NS_IsAsciiWhitespace(mIDs[mCurrIdx]))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mCurrIdx >= mIDs.Length())
|
||||||
|
return nsDependentSubstring();
|
||||||
|
|
||||||
|
nsAString::index_type idStartIdx = mCurrIdx;
|
||||||
|
while (++mCurrIdx < mIDs.Length()) {
|
||||||
|
if (NS_IsAsciiWhitespace(mIDs[mCurrIdx]))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Substring(mIDs, idStartIdx, mCurrIdx++ - idStartIdx);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsIContent*
|
||||||
|
IDRefsIterator::NextElem()
|
||||||
|
{
|
||||||
|
while (true) {
|
||||||
|
const nsDependentSubstring id = NextID();
|
||||||
|
if (id.IsEmpty())
|
||||||
|
break;
|
||||||
|
|
||||||
|
nsIContent* refContent = GetElem(id);
|
||||||
|
if (refContent)
|
||||||
|
return refContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsIContent*
|
||||||
|
IDRefsIterator::GetElem(const nsDependentSubstring& aID)
|
||||||
|
{
|
||||||
|
if (mXBLDocument) {
|
||||||
|
// If content is anonymous subtree then use "anonid" attribute to get
|
||||||
|
// elements, otherwise search elements in DOM by ID attribute.
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMElement> refElm;
|
||||||
|
mXBLDocument->GetAnonymousElementByAttribute(mBindingParent,
|
||||||
|
NS_LITERAL_STRING("anonid"),
|
||||||
|
aID,
|
||||||
|
getter_AddRefs(refElm));
|
||||||
|
nsCOMPtr<nsIContent> refContent = do_QueryInterface(refElm);
|
||||||
|
return refContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mDocument->GetElementById(aID);
|
||||||
|
}
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
|
|
||||||
#include "nsAccessibilityAtoms.h"
|
#include "nsAccessibilityAtoms.h"
|
||||||
|
|
||||||
|
#include "nsIDOMDocumentXBL.h"
|
||||||
#include "nsIDOMNode.h"
|
#include "nsIDOMNode.h"
|
||||||
#include "nsIContent.h"
|
#include "nsIContent.h"
|
||||||
#include "nsIBoxObject.h"
|
#include "nsIBoxObject.h"
|
||||||
|
@ -304,17 +305,6 @@ public:
|
||||||
static void GetLanguageFor(nsIContent *aContent, nsIContent *aRootContent,
|
static void GetLanguageFor(nsIContent *aContent, nsIContent *aRootContent,
|
||||||
nsAString& aLanguage);
|
nsAString& aLanguage);
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the array of elements the given node is referred to by its
|
|
||||||
* IDRefs attribute.
|
|
||||||
*
|
|
||||||
* @param aContent [in] the given node
|
|
||||||
* @param aAttr [in] IDRefs attribute on the given node
|
|
||||||
* @param aRefElements [out] result array of elements
|
|
||||||
*/
|
|
||||||
static void GetElementsByIDRefsAttr(nsIContent *aContent, nsIAtom *aAttr,
|
|
||||||
nsIArray **aRefElements);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the array of elements having IDRefs that points to the given node.
|
* Return the array of elements having IDRefs that points to the given node.
|
||||||
*
|
*
|
||||||
|
@ -515,5 +505,39 @@ private:
|
||||||
nsTArray<nsString> mNames;
|
nsTArray<nsString> mNames;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to iterate through IDs or elements pointed by IDRefs attribute. Note,
|
||||||
|
* any method used to iterate through IDs or elements moves iterator to next
|
||||||
|
* position.
|
||||||
|
*/
|
||||||
|
class IDRefsIterator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IDRefsIterator(nsIContent* aContent, nsIAtom* aIDRefsAttr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return next ID.
|
||||||
|
*/
|
||||||
|
const nsDependentSubstring NextID();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return next element.
|
||||||
|
*/
|
||||||
|
nsIContent* NextElem();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the element with the given ID.
|
||||||
|
*/
|
||||||
|
nsIContent* GetElem(const nsDependentSubstring& aID);
|
||||||
|
|
||||||
|
private:
|
||||||
|
nsString mIDs;
|
||||||
|
nsAString::index_type mCurrIdx;
|
||||||
|
|
||||||
|
nsIDocument* mDocument;
|
||||||
|
nsCOMPtr<nsIDOMDocumentXBL> mXBLDocument;
|
||||||
|
nsCOMPtr<nsIDOMElement> mBindingParent;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -85,6 +85,16 @@ namespace dom = mozilla::dom;
|
||||||
|
|
||||||
PRUint32 nsDocAccessible::gLastFocusedAccessiblesState = 0;
|
PRUint32 nsDocAccessible::gLastFocusedAccessiblesState = 0;
|
||||||
|
|
||||||
|
static nsIAtom** kRelationAttrs[] =
|
||||||
|
{
|
||||||
|
&nsAccessibilityAtoms::aria_labelledby,
|
||||||
|
&nsAccessibilityAtoms::aria_describedby,
|
||||||
|
&nsAccessibilityAtoms::aria_owns,
|
||||||
|
&nsAccessibilityAtoms::aria_controls,
|
||||||
|
&nsAccessibilityAtoms::aria_flowto
|
||||||
|
};
|
||||||
|
|
||||||
|
static const PRUint32 kRelationAttrsLen = NS_ARRAY_LENGTH(kRelationAttrs);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Constructor/desctructor
|
// Constructor/desctructor
|
||||||
|
@ -93,8 +103,10 @@ nsDocAccessible::
|
||||||
nsDocAccessible(nsIDocument *aDocument, nsIContent *aRootContent,
|
nsDocAccessible(nsIDocument *aDocument, nsIContent *aRootContent,
|
||||||
nsIWeakReference *aShell) :
|
nsIWeakReference *aShell) :
|
||||||
nsHyperTextAccessibleWrap(aRootContent, aShell),
|
nsHyperTextAccessibleWrap(aRootContent, aShell),
|
||||||
mDocument(aDocument), mScrollPositionChangedTicks(0), mIsLoaded(PR_FALSE)
|
mDocument(aDocument), mScrollPositionChangedTicks(0), mIsLoaded(PR_FALSE),
|
||||||
|
mCacheRoot(nsnull), mIsPostCacheProcessing(PR_FALSE)
|
||||||
{
|
{
|
||||||
|
mDependentIDsHash.Init();
|
||||||
// XXX aaronl should we use an algorithm for the initial cache size?
|
// XXX aaronl should we use an algorithm for the initial cache size?
|
||||||
mAccessibleCache.Init(kDefaultCacheSize);
|
mAccessibleCache.Init(kDefaultCacheSize);
|
||||||
mNodeToAccessibleMap.Init(kDefaultCacheSize);
|
mNodeToAccessibleMap.Init(kDefaultCacheSize);
|
||||||
|
@ -134,6 +146,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDocAccessible, nsAccessible)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDocAccessible, nsAccessible)
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mEventQueue)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mEventQueue)
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSTARRAY(mChildDocuments)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSTARRAY(mChildDocuments)
|
||||||
|
tmp->mDependentIDsHash.Clear();
|
||||||
tmp->mNodeToAccessibleMap.Clear();
|
tmp->mNodeToAccessibleMap.Clear();
|
||||||
ClearCache(tmp->mAccessibleCache);
|
ClearCache(tmp->mAccessibleCache);
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||||
|
@ -155,8 +168,7 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsDocAccessible)
|
||||||
// However at some point we may push <body> to implement the interfaces and
|
// However at some point we may push <body> to implement the interfaces and
|
||||||
// return nsDocAccessible to inherit from nsAccessibleWrap.
|
// return nsDocAccessible to inherit from nsAccessibleWrap.
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMXULDocument> xulDoc(do_QueryInterface(mDocument));
|
if (mDocument && mDocument->IsXUL())
|
||||||
if (xulDoc)
|
|
||||||
status = nsAccessible::QueryInterface(aIID, (void**)&foundInterface);
|
status = nsAccessible::QueryInterface(aIID, (void**)&foundInterface);
|
||||||
else
|
else
|
||||||
status = nsHyperTextAccessible::QueryInterface(aIID,
|
status = nsHyperTextAccessible::QueryInterface(aIID,
|
||||||
|
@ -664,6 +676,7 @@ nsDocAccessible::Shutdown()
|
||||||
|
|
||||||
mWeakShell = nsnull; // Avoid reentrancy
|
mWeakShell = nsnull; // Avoid reentrancy
|
||||||
|
|
||||||
|
mDependentIDsHash.Clear();
|
||||||
mNodeToAccessibleMap.Clear();
|
mNodeToAccessibleMap.Clear();
|
||||||
ClearCache(mAccessibleCache);
|
ClearCache(mAccessibleCache);
|
||||||
|
|
||||||
|
@ -929,10 +942,19 @@ nsDocAccessible::AttributeWillChange(nsIDocument *aDocument,
|
||||||
PRInt32 aNameSpaceID,
|
PRInt32 aNameSpaceID,
|
||||||
nsIAtom* aAttribute, PRInt32 aModType)
|
nsIAtom* aAttribute, PRInt32 aModType)
|
||||||
{
|
{
|
||||||
// XXX TODO: bugs 381599 467143 472142 472143
|
// XXX TODO: bugs 381599 (partially fixed by 573469), 467143, 472142, 472143.
|
||||||
// Here we will want to cache whatever state we are potentially interested in,
|
// Here we will want to cache whatever state we are potentially interested in,
|
||||||
// such as the existence of aria-pressed for button (so we know if we need to
|
// such as the existence of aria-pressed for button (so we know if we need to
|
||||||
// newly expose it as a toggle button) etc.
|
// newly expose it as a toggle button) etc.
|
||||||
|
|
||||||
|
// Update dependent IDs cache.
|
||||||
|
if (aModType == nsIDOMMutationEvent::MODIFICATION ||
|
||||||
|
aModType == nsIDOMMutationEvent::REMOVAL) {
|
||||||
|
nsAccessible* accessible =
|
||||||
|
GetAccService()->GetAccessibleInWeakShell(aElement, mWeakShell);
|
||||||
|
if (accessible)
|
||||||
|
RemoveDependentIDsFor(accessible, aAttribute);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -943,6 +965,16 @@ nsDocAccessible::AttributeChanged(nsIDocument *aDocument,
|
||||||
{
|
{
|
||||||
AttributeChangedImpl(aElement, aNameSpaceID, aAttribute);
|
AttributeChangedImpl(aElement, aNameSpaceID, aAttribute);
|
||||||
|
|
||||||
|
// Update dependent IDs cache.
|
||||||
|
if (aModType == nsIDOMMutationEvent::MODIFICATION ||
|
||||||
|
aModType == nsIDOMMutationEvent::ADDITION) {
|
||||||
|
nsAccessible* accessible =
|
||||||
|
GetAccService()->GetAccessibleInWeakShell(aElement, mWeakShell);
|
||||||
|
|
||||||
|
if (accessible)
|
||||||
|
AddDependentIDsFor(accessible, aAttribute);
|
||||||
|
}
|
||||||
|
|
||||||
// If it was the focused node, cache the new state
|
// If it was the focused node, cache the new state
|
||||||
if (aElement == gLastFocusedNode) {
|
if (aElement == gLastFocusedNode) {
|
||||||
nsAccessible *focusedAccessible = GetAccService()->GetAccessible(aElement);
|
nsAccessible *focusedAccessible = GetAccService()->GetAccessible(aElement);
|
||||||
|
@ -1362,6 +1394,7 @@ nsDocAccessible::BindToDocument(nsAccessible* aAccessible,
|
||||||
}
|
}
|
||||||
|
|
||||||
aAccessible->SetRoleMapEntry(aRoleMapEntry);
|
aAccessible->SetRoleMapEntry(aRoleMapEntry);
|
||||||
|
AddDependentIDsFor(aAccessible);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1373,6 +1406,8 @@ nsDocAccessible::UnbindFromDocument(nsAccessible* aAccessible)
|
||||||
mNodeToAccessibleMap.Get(aAccessible->GetNode()) == aAccessible)
|
mNodeToAccessibleMap.Get(aAccessible->GetNode()) == aAccessible)
|
||||||
mNodeToAccessibleMap.Remove(aAccessible->GetNode());
|
mNodeToAccessibleMap.Remove(aAccessible->GetNode());
|
||||||
|
|
||||||
|
RemoveDependentIDsFor(aAccessible);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
NS_ASSERTION(mAccessibleCache.GetWeak(aAccessible->UniqueID()),
|
NS_ASSERTION(mAccessibleCache.GetWeak(aAccessible->UniqueID()),
|
||||||
"Unbinding the unbound accessible!");
|
"Unbinding the unbound accessible!");
|
||||||
|
@ -1554,9 +1589,130 @@ nsDocAccessible::RecreateAccessible(nsINode* aNode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsDocAccessible::NotifyOfCachingStart(nsAccessible* aAccessible)
|
||||||
|
{
|
||||||
|
if (!mCacheRoot)
|
||||||
|
mCacheRoot = aAccessible;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsDocAccessible::NotifyOfCachingEnd(nsAccessible* aAccessible)
|
||||||
|
{
|
||||||
|
if (mCacheRoot == aAccessible && !mIsPostCacheProcessing) {
|
||||||
|
// Allow invalidation list insertions while container children are recached.
|
||||||
|
mIsPostCacheProcessing = PR_TRUE;
|
||||||
|
|
||||||
|
// Invalidate children of container accessible for each element in
|
||||||
|
// invalidation list.
|
||||||
|
for (PRUint32 idx = 0; idx < mInvalidationList.Length(); idx++) {
|
||||||
|
nsIContent* content = mInvalidationList[idx];
|
||||||
|
nsAccessible* container =
|
||||||
|
GetAccService()->GetCachedContainerAccessible(content);
|
||||||
|
container->InvalidateChildren();
|
||||||
|
|
||||||
|
// Make sure we keep children updated. While we're inside of caching loop
|
||||||
|
// then we must exist it with cached children.
|
||||||
|
container->EnsureChildren();
|
||||||
|
}
|
||||||
|
mInvalidationList.Clear();
|
||||||
|
|
||||||
|
mCacheRoot = nsnull;
|
||||||
|
mIsPostCacheProcessing = PR_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Protected members
|
// Protected members
|
||||||
|
|
||||||
|
void
|
||||||
|
nsDocAccessible::AddDependentIDsFor(nsAccessible* aRelProvider,
|
||||||
|
nsIAtom* aRelAttr)
|
||||||
|
{
|
||||||
|
for (PRUint32 idx = 0; idx < kRelationAttrsLen; idx++) {
|
||||||
|
nsIAtom* relAttr = *kRelationAttrs[idx];
|
||||||
|
if (aRelAttr && aRelAttr != relAttr)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
IDRefsIterator iter(aRelProvider->GetContent(), relAttr);
|
||||||
|
while (true) {
|
||||||
|
const nsDependentSubstring id = iter.NextID();
|
||||||
|
if (id.IsEmpty())
|
||||||
|
break;
|
||||||
|
|
||||||
|
AttrRelProviderArray* providers = mDependentIDsHash.Get(id);
|
||||||
|
if (!providers) {
|
||||||
|
providers = new AttrRelProviderArray();
|
||||||
|
if (providers) {
|
||||||
|
if (!mDependentIDsHash.Put(id, providers)) {
|
||||||
|
delete providers;
|
||||||
|
providers = nsnull;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (providers) {
|
||||||
|
AttrRelProvider* provider =
|
||||||
|
new AttrRelProvider(relAttr, aRelProvider->GetContent());
|
||||||
|
if (provider) {
|
||||||
|
providers->AppendElement(provider);
|
||||||
|
|
||||||
|
// We've got here during the children caching. If the referenced
|
||||||
|
// content is not accessible then store it to pend its container
|
||||||
|
// children invalidation (this happens immediately after the caching
|
||||||
|
// is finished).
|
||||||
|
nsIContent* dependentContent = iter.GetElem(id);
|
||||||
|
if (dependentContent && !GetCachedAccessible(dependentContent)) {
|
||||||
|
mInvalidationList.AppendElement(dependentContent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the relation attribute is given then we don't have anything else to
|
||||||
|
// check.
|
||||||
|
if (aRelAttr)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsDocAccessible::RemoveDependentIDsFor(nsAccessible* aRelProvider,
|
||||||
|
nsIAtom* aRelAttr)
|
||||||
|
{
|
||||||
|
for (PRUint32 idx = 0; idx < kRelationAttrsLen; idx++) {
|
||||||
|
nsIAtom* relAttr = *kRelationAttrs[idx];
|
||||||
|
if (aRelAttr && aRelAttr != *kRelationAttrs[idx])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
IDRefsIterator iter(aRelProvider->GetContent(), relAttr);
|
||||||
|
while (true) {
|
||||||
|
const nsDependentSubstring id = iter.NextID();
|
||||||
|
if (id.IsEmpty())
|
||||||
|
break;
|
||||||
|
|
||||||
|
AttrRelProviderArray* providers = mDependentIDsHash.Get(id);
|
||||||
|
if (providers) {
|
||||||
|
for (PRUint32 jdx = 0; jdx < providers->Length(); ) {
|
||||||
|
AttrRelProvider* provider = (*providers)[jdx];
|
||||||
|
if (provider->mRelAttr == relAttr &&
|
||||||
|
provider->mContent == aRelProvider->GetContent())
|
||||||
|
providers->RemoveElement(provider);
|
||||||
|
else
|
||||||
|
jdx++;
|
||||||
|
}
|
||||||
|
if (providers->Length() == 0)
|
||||||
|
mDependentIDsHash.Remove(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the relation attribute is given then we don't have anything else to
|
||||||
|
// check.
|
||||||
|
if (aRelAttr)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsDocAccessible::FireValueChangeForTextFields(nsAccessible *aAccessible)
|
nsDocAccessible::FireValueChangeForTextFields(nsAccessible *aAccessible)
|
||||||
{
|
{
|
||||||
|
|
|
@ -44,6 +44,8 @@
|
||||||
#include "nsHyperTextAccessibleWrap.h"
|
#include "nsHyperTextAccessibleWrap.h"
|
||||||
#include "nsEventShell.h"
|
#include "nsEventShell.h"
|
||||||
|
|
||||||
|
#include "nsClassHashtable.h"
|
||||||
|
#include "nsDataHashtable.h"
|
||||||
#include "nsIDocument.h"
|
#include "nsIDocument.h"
|
||||||
#include "nsIDocumentObserver.h"
|
#include "nsIDocumentObserver.h"
|
||||||
#include "nsIEditor.h"
|
#include "nsIEditor.h"
|
||||||
|
@ -210,6 +212,16 @@ public:
|
||||||
*/
|
*/
|
||||||
nsAccessible* GetCachedAccessibleByUniqueIDInSubtree(void* aUniqueID);
|
nsAccessible* GetCachedAccessibleByUniqueIDInSubtree(void* aUniqueID);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if the given ID is referred by relation attribute.
|
||||||
|
*
|
||||||
|
* @note Different elements may share the same ID if they are hosted inside
|
||||||
|
* XBL bindings. Be careful the result of this method may be senseless
|
||||||
|
* while it's called for XUL elements (where XBL is used widely).
|
||||||
|
*/
|
||||||
|
PRBool IsDependentID(const nsAString& aID) const
|
||||||
|
{ return mDependentIDsHash.Get(aID, nsnull); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the newly created accessible and put it into document caches.
|
* Initialize the newly created accessible and put it into document caches.
|
||||||
*
|
*
|
||||||
|
@ -241,6 +253,17 @@ public:
|
||||||
*/
|
*/
|
||||||
void RecreateAccessible(nsINode* aNode);
|
void RecreateAccessible(nsINode* aNode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to notify the document that the accessible caching is started or
|
||||||
|
* finished.
|
||||||
|
*
|
||||||
|
* While children are cached we may encounter the case there's no accessible
|
||||||
|
* for referred content by related accessible. Keep the caching root and
|
||||||
|
* these related nodes to invalidate their containers after root caching.
|
||||||
|
*/
|
||||||
|
void NotifyOfCachingStart(nsAccessible* aAccessible);
|
||||||
|
void NotifyOfCachingEnd(nsAccessible* aAccessible);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual void GetBoundsRect(nsRect& aRect, nsIFrame** aRelativeFrame);
|
virtual void GetBoundsRect(nsRect& aRect, nsIFrame** aRelativeFrame);
|
||||||
|
@ -267,6 +290,28 @@ protected:
|
||||||
mChildDocuments.RemoveElement(aChildDocument);
|
mChildDocuments.RemoveElement(aChildDocument);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add dependent IDs pointed by accessible element by relation attribute to
|
||||||
|
* cache. If the relation attribute is missed then all relation attributes
|
||||||
|
* are checked.
|
||||||
|
*
|
||||||
|
* @param aRelProvider [in] accessible that element has relation attribute
|
||||||
|
* @param aRelAttr [in, optional] relation attribute
|
||||||
|
*/
|
||||||
|
void AddDependentIDsFor(nsAccessible* aRelProvider,
|
||||||
|
nsIAtom* aRelAttr = nsnull);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove dependent IDs pointed by accessible element by relation attribute
|
||||||
|
* from cache. If the relation attribute is absent then all relation
|
||||||
|
* attributes are checked.
|
||||||
|
*
|
||||||
|
* @param aRelProvider [in] accessible that element has relation attribute
|
||||||
|
* @param aRelAttr [in, optional] relation attribute
|
||||||
|
*/
|
||||||
|
void RemoveDependentIDsFor(nsAccessible* aRelProvider,
|
||||||
|
nsIAtom* aRelAttr = nsnull);
|
||||||
|
|
||||||
static void ScrollTimerCallback(nsITimer *aTimer, void *aClosure);
|
static void ScrollTimerCallback(nsITimer *aTimer, void *aClosure);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -299,14 +344,6 @@ protected:
|
||||||
CharacterDataChangeInfo* aInfo,
|
CharacterDataChangeInfo* aInfo,
|
||||||
PRBool aIsInserted);
|
PRBool aIsInserted);
|
||||||
|
|
||||||
/**
|
|
||||||
* Used to define should the event be fired on a delay.
|
|
||||||
*/
|
|
||||||
enum EEventFiringType {
|
|
||||||
eNormalEvent,
|
|
||||||
eDelayedEvent
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fire a value change event for the the given accessible if it is a text
|
* Fire a value change event for the the given accessible if it is a text
|
||||||
* field (has a ROLE_ENTRY).
|
* field (has a ROLE_ENTRY).
|
||||||
|
@ -347,7 +384,8 @@ protected:
|
||||||
* Cache of accessibles within this document accessible.
|
* Cache of accessibles within this document accessible.
|
||||||
*/
|
*/
|
||||||
nsAccessibleHashtable mAccessibleCache;
|
nsAccessibleHashtable mAccessibleCache;
|
||||||
NodeToAccessibleMap mNodeToAccessibleMap;
|
nsDataHashtable<nsPtrHashKey<const nsINode>, nsAccessible*>
|
||||||
|
mNodeToAccessibleMap;
|
||||||
|
|
||||||
nsCOMPtr<nsIDocument> mDocument;
|
nsCOMPtr<nsIDocument> mDocument;
|
||||||
nsCOMPtr<nsITimer> mScrollWatchTimer;
|
nsCOMPtr<nsITimer> mScrollWatchTimer;
|
||||||
|
@ -366,9 +404,46 @@ protected:
|
||||||
static nsIAtom *gLastFocusedFrameType;
|
static nsIAtom *gLastFocusedFrameType;
|
||||||
|
|
||||||
nsTArray<nsRefPtr<nsDocAccessible> > mChildDocuments;
|
nsTArray<nsRefPtr<nsDocAccessible> > mChildDocuments;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A storage class for pairing content with one of its relation attributes.
|
||||||
|
*/
|
||||||
|
class AttrRelProvider
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AttrRelProvider(nsIAtom* aRelAttr, nsIContent* aContent) :
|
||||||
|
mRelAttr(aRelAttr), mContent(aContent) { }
|
||||||
|
|
||||||
|
nsIAtom* mRelAttr;
|
||||||
|
nsIContent* mContent;
|
||||||
|
|
||||||
|
private:
|
||||||
|
AttrRelProvider();
|
||||||
|
AttrRelProvider(const AttrRelProvider&);
|
||||||
|
AttrRelProvider& operator =(const AttrRelProvider&);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The cache of IDs pointed by relation attributes.
|
||||||
|
*/
|
||||||
|
typedef nsTArray<nsAutoPtr<AttrRelProvider> > AttrRelProviderArray;
|
||||||
|
nsClassHashtable<nsStringHashKey, AttrRelProviderArray> mDependentIDsHash;
|
||||||
|
|
||||||
|
friend class RelatedAccIterator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used for our caching algorithm. We store the root of the tree that needs
|
||||||
|
* caching, the list of nodes that should be invalidated, and whether we are
|
||||||
|
* processing the invalidation list.
|
||||||
|
*
|
||||||
|
* @see NotifyOfCachingStart/NotifyOfCachingEnd
|
||||||
|
*/
|
||||||
|
nsAccessible* mCacheRoot;
|
||||||
|
nsTArray<nsIContent*> mInvalidationList;
|
||||||
|
PRBool mIsPostCacheProcessing;
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsDocAccessible,
|
NS_DEFINE_STATIC_IID_ACCESSOR(nsDocAccessible,
|
||||||
NS_DOCACCESSIBLE_IMPL_CID)
|
NS_DOCACCESSIBLE_IMPL_CID)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -134,27 +134,16 @@ nsRelUtils::AddTargetFromIDRefsAttr(PRUint32 aRelationType,
|
||||||
nsIAccessibleRelation **aRelation,
|
nsIAccessibleRelation **aRelation,
|
||||||
nsIContent *aContent, nsIAtom *aAttr)
|
nsIContent *aContent, nsIAtom *aAttr)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIArray> refElms;
|
nsresult rv = NS_OK_NO_RELATION_TARGET;
|
||||||
nsCoreUtils::GetElementsByIDRefsAttr(aContent, aAttr, getter_AddRefs(refElms));
|
|
||||||
|
|
||||||
if (!refElms)
|
nsIContent* refElm = nsnull;
|
||||||
return NS_OK_NO_RELATION_TARGET;
|
IDRefsIterator iter(aContent, aAttr);
|
||||||
|
while ((refElm = iter.NextElem())) {
|
||||||
PRUint32 count = 0;
|
rv = AddTargetFromContent(aRelationType, aRelation, refElm);
|
||||||
nsresult rv = refElms->GetLength(&count);
|
|
||||||
if (NS_FAILED(rv) || count == 0)
|
|
||||||
return NS_OK_NO_RELATION_TARGET;
|
|
||||||
|
|
||||||
nsCOMPtr<nsIContent> content;
|
|
||||||
for (PRUint32 idx = 0; idx < count; idx++) {
|
|
||||||
content = do_QueryElementAt(refElms, idx, &rv);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
rv = AddTargetFromContent(aRelationType, aRelation, content);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
|
|
|
@ -92,26 +92,14 @@ nsTextEquivUtils::GetTextEquivFromIDRefs(nsAccessible *aAccessible,
|
||||||
if (!content)
|
if (!content)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
||||||
nsCOMPtr<nsIArray> refElms;
|
nsIContent* refContent = nsnull;
|
||||||
nsCoreUtils::GetElementsByIDRefsAttr(content, aIDRefsAttr,
|
IDRefsIterator iter(content, aIDRefsAttr);
|
||||||
getter_AddRefs(refElms));
|
while ((refContent = iter.NextElem())) {
|
||||||
|
|
||||||
if (!refElms)
|
|
||||||
return NS_OK;
|
|
||||||
|
|
||||||
PRUint32 count = 0;
|
|
||||||
nsresult rv = refElms->GetLength(&count);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIContent> refContent;
|
|
||||||
for (PRUint32 idx = 0; idx < count; idx++) {
|
|
||||||
refContent = do_QueryElementAt(refElms, idx, &rv);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
if (!aTextEquiv.IsEmpty())
|
if (!aTextEquiv.IsEmpty())
|
||||||
aTextEquiv += ' ';
|
aTextEquiv += ' ';
|
||||||
|
|
||||||
rv = AppendTextEquivFromContent(aAccessible, refContent, &aTextEquiv);
|
nsresult rv = AppendTextEquivFromContent(aAccessible, refContent,
|
||||||
|
&aTextEquiv);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -308,34 +308,27 @@ nsHTMLTableCellAccessible::GetHeaderCells(PRInt32 aRowOrColumnHeaderCell,
|
||||||
nsIArray **aHeaderCells)
|
nsIArray **aHeaderCells)
|
||||||
{
|
{
|
||||||
// Get header cells from @header attribute.
|
// Get header cells from @header attribute.
|
||||||
nsCOMPtr<nsIArray> headerCellElms;
|
IDRefsIterator iter(mContent, nsAccessibilityAtoms::headers);
|
||||||
nsCoreUtils::GetElementsByIDRefsAttr(mContent, nsAccessibilityAtoms::headers,
|
nsIContent* headerCellElm = iter.NextElem();
|
||||||
getter_AddRefs(headerCellElms));
|
if (headerCellElm) {
|
||||||
|
|
||||||
if (headerCellElms) {
|
|
||||||
nsresult rv = NS_OK;
|
nsresult rv = NS_OK;
|
||||||
nsCOMPtr<nsIMutableArray> headerCells =
|
nsCOMPtr<nsIMutableArray> headerCells =
|
||||||
do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
|
do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
PRUint32 count = 0;
|
do {
|
||||||
rv = headerCellElms->GetLength(&count);
|
nsAccessible* headerCell =
|
||||||
if (NS_SUCCEEDED(rv) && count > 0) {
|
GetAccService()->GetAccessibleInWeakShell(headerCellElm, mWeakShell);
|
||||||
nsCOMPtr<nsIContent> headerCellContent;
|
|
||||||
for (PRUint32 idx = 0; idx < count; idx++) {
|
|
||||||
headerCellContent = do_QueryElementAt(headerCellElms, idx, &rv);
|
|
||||||
nsAccessible *headerCell =
|
|
||||||
GetAccService()->GetAccessibleInWeakShell(headerCellContent, mWeakShell);
|
|
||||||
|
|
||||||
if (headerCell &&
|
if (headerCell &&
|
||||||
(aRowOrColumnHeaderCell == nsAccUtils::eRowHeaderCells &&
|
(aRowOrColumnHeaderCell == nsAccUtils::eRowHeaderCells &&
|
||||||
headerCell->Role() == nsIAccessibleRole::ROLE_ROWHEADER ||
|
headerCell->Role() == nsIAccessibleRole::ROLE_ROWHEADER ||
|
||||||
aRowOrColumnHeaderCell == nsAccUtils::eColumnHeaderCells &&
|
aRowOrColumnHeaderCell == nsAccUtils::eColumnHeaderCells &&
|
||||||
headerCell->Role() == nsIAccessibleRole::ROLE_COLUMNHEADER))
|
headerCell->Role() == nsIAccessibleRole::ROLE_COLUMNHEADER)) {
|
||||||
headerCells->AppendElement(static_cast<nsIAccessible*>(headerCell),
|
headerCells->AppendElement(static_cast<nsIAccessible*>(headerCell),
|
||||||
PR_FALSE);
|
PR_FALSE);
|
||||||
}
|
}
|
||||||
}
|
} while ((headerCellElm = iter.NextElem()));
|
||||||
|
|
||||||
NS_ADDREF(*aHeaderCells = headerCells);
|
NS_ADDREF(*aHeaderCells = headerCells);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
|
@ -50,6 +50,7 @@ _TEST_FILES =\
|
||||||
test_general.xul \
|
test_general.xul \
|
||||||
test_tabbrowser.xul \
|
test_tabbrowser.xul \
|
||||||
test_tree.xul \
|
test_tree.xul \
|
||||||
|
test_update.html \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
libs:: $(_TEST_FILES)
|
libs:: $(_TEST_FILES)
|
||||||
|
|
|
@ -65,6 +65,9 @@
|
||||||
testRelation(iframeDocAcc, RELATION_NODE_CHILD_OF, iframeAcc);
|
testRelation(iframeDocAcc, RELATION_NODE_CHILD_OF, iframeAcc);
|
||||||
|
|
||||||
// aria-controls
|
// aria-controls
|
||||||
|
getAccessible("tab");
|
||||||
|
todo(false,
|
||||||
|
"Getting an accessible tab, otherwise relations for tabpanel aren't cached. Bug 606924 will fix that.");
|
||||||
testRelation("tabpanel", RELATION_CONTROLLED_BY, "tab");
|
testRelation("tabpanel", RELATION_CONTROLLED_BY, "tab");
|
||||||
testRelation("tab", RELATION_CONTROLLER_FOR, "tabpanel");
|
testRelation("tab", RELATION_CONTROLLER_FOR, "tabpanel");
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,9 @@
|
||||||
testRelation(iframeDocAcc, RELATION_NODE_CHILD_OF, iframeAcc);
|
testRelation(iframeDocAcc, RELATION_NODE_CHILD_OF, iframeAcc);
|
||||||
|
|
||||||
// aria-controls
|
// aria-controls
|
||||||
|
getAccessible("tab");
|
||||||
|
todo(false,
|
||||||
|
"Getting an accessible tab, otherwise relations for tabpanel aren't cached. Bug 606924 will fix that.");
|
||||||
testRelation("tabpanel", RELATION_CONTROLLED_BY, "tab");
|
testRelation("tabpanel", RELATION_CONTROLLED_BY, "tab");
|
||||||
testRelation("tab", RELATION_CONTROLLER_FOR, "tabpanel");
|
testRelation("tab", RELATION_CONTROLLER_FOR, "tabpanel");
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,162 @@
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>Test updating of accessible relations</title>
|
||||||
|
<link rel="stylesheet" type="text/css"
|
||||||
|
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||||
|
|
||||||
|
<script type="application/javascript"
|
||||||
|
src="chrome://mochikit/content/MochiKit/packed.js"></script>
|
||||||
|
<script type="application/javascript"
|
||||||
|
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||||
|
|
||||||
|
<script type="application/javascript"
|
||||||
|
src="../common.js"></script>
|
||||||
|
<script type="application/javascript"
|
||||||
|
src="../relations.js"></script>
|
||||||
|
<script type="application/javascript"
|
||||||
|
src="../role.js"></script>
|
||||||
|
<script type="application/javascript"
|
||||||
|
src="../events.js"></script>
|
||||||
|
|
||||||
|
<script type="application/javascript">
|
||||||
|
function testRelated(aRelAttr, aHostRelation, aDependentRelation)
|
||||||
|
{
|
||||||
|
// no attribute
|
||||||
|
testRelation("dependent1", aDependentRelation, null);
|
||||||
|
testRelation("dependent2", aDependentRelation, null);
|
||||||
|
if (aHostRelation)
|
||||||
|
testRelation("host", aHostRelation, null);
|
||||||
|
|
||||||
|
// set attribute
|
||||||
|
getNode("host").setAttribute(aRelAttr, "dependent1");
|
||||||
|
testRelation("dependent1", aDependentRelation, "host");
|
||||||
|
testRelation("dependent2", aDependentRelation, null);
|
||||||
|
if (aHostRelation)
|
||||||
|
testRelation("host", aHostRelation, "dependent1");
|
||||||
|
|
||||||
|
// change attribute
|
||||||
|
getNode("host").setAttribute(aRelAttr, "dependent2");
|
||||||
|
testRelation("dependent1", aDependentRelation, null);
|
||||||
|
testRelation("dependent2", aDependentRelation, "host");
|
||||||
|
if (aHostRelation)
|
||||||
|
testRelation("host", aHostRelation, "dependent2");
|
||||||
|
|
||||||
|
// remove attribute
|
||||||
|
getNode("host").removeAttribute(aRelAttr);
|
||||||
|
testRelation("dependent1", aDependentRelation, null);
|
||||||
|
testRelation("dependent2", aDependentRelation, null);
|
||||||
|
if (aHostRelation)
|
||||||
|
testRelation("host", aHostRelation, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
function insertRelated(aHostRelAttr, aDependentID, aInsertHostFirst,
|
||||||
|
aHostRelation, aDependentRelation)
|
||||||
|
{
|
||||||
|
this.eventSeq = [
|
||||||
|
new invokerChecker(EVENT_REORDER, document)
|
||||||
|
];
|
||||||
|
|
||||||
|
this.invoke = function insertRelated_invoke()
|
||||||
|
{
|
||||||
|
this.hostNode = document.createElement("div");
|
||||||
|
this.hostNode.setAttribute(aHostRelAttr, aDependentID);
|
||||||
|
|
||||||
|
this.dependentNode = document.createElement("div");
|
||||||
|
this.dependentNode.setAttribute("id", aDependentID);
|
||||||
|
|
||||||
|
if (aInsertHostFirst) {
|
||||||
|
document.body.appendChild(this.hostNode);
|
||||||
|
document.body.appendChild(this.dependentNode);
|
||||||
|
} else {
|
||||||
|
document.body.appendChild(this.dependentNode);
|
||||||
|
document.body.appendChild(this.hostNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.finalCheck = function insertRelated_finalCheck()
|
||||||
|
{
|
||||||
|
testRelation(this.dependentNode, aDependentRelation, this.hostNode);
|
||||||
|
if (aHostRelation)
|
||||||
|
testRelation(this.hostNode, aHostRelation, this.dependentNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.getID = function insertRelated_getID()
|
||||||
|
{
|
||||||
|
return "Insert " + aHostRelAttr + "='" + aDependentID + "' node" +
|
||||||
|
(aInsertHostFirst ? " before" : "after") + " dependent node";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var gQueue = null;
|
||||||
|
|
||||||
|
function doTest()
|
||||||
|
{
|
||||||
|
// Relation updates on ARIA attribute changes.
|
||||||
|
testRelated("aria-labelledby", RELATION_LABELLED_BY, RELATION_LABEL_FOR);
|
||||||
|
testRelated("aria-describedby",
|
||||||
|
RELATION_DESCRIBED_BY, RELATION_DESCRIPTION_FOR);
|
||||||
|
testRelated("aria-owns", null, RELATION_NODE_CHILD_OF);
|
||||||
|
testRelated("aria-controls",
|
||||||
|
RELATION_CONTROLLER_FOR, RELATION_CONTROLLED_BY);
|
||||||
|
testRelated("aria-flowto", RELATION_FLOWS_TO, RELATION_FLOWS_FROM);
|
||||||
|
|
||||||
|
// Insert related accessibles into tree.
|
||||||
|
gQueue = new eventQueue();
|
||||||
|
gQueue.push(new insertRelated("aria-labelledby", "dependent3", true,
|
||||||
|
RELATION_LABELLED_BY, RELATION_LABEL_FOR));
|
||||||
|
gQueue.push(new insertRelated("aria-labelledby", "dependent4", false,
|
||||||
|
RELATION_LABELLED_BY, RELATION_LABEL_FOR));
|
||||||
|
|
||||||
|
gQueue.push(new insertRelated("aria-describedby", "dependent5", true,
|
||||||
|
RELATION_DESCRIBED_BY,
|
||||||
|
RELATION_DESCRIPTION_FOR));
|
||||||
|
gQueue.push(new insertRelated("aria-describedby", "dependent6", false,
|
||||||
|
RELATION_DESCRIBED_BY,
|
||||||
|
RELATION_DESCRIPTION_FOR));
|
||||||
|
|
||||||
|
gQueue.push(new insertRelated("aria-owns", "dependent7", true,
|
||||||
|
null, RELATION_NODE_CHILD_OF));
|
||||||
|
gQueue.push(new insertRelated("aria-owns", "dependent8", false,
|
||||||
|
null, RELATION_NODE_CHILD_OF));
|
||||||
|
|
||||||
|
gQueue.push(new insertRelated("aria-controls", "dependent9", true,
|
||||||
|
RELATION_CONTROLLER_FOR,
|
||||||
|
RELATION_CONTROLLED_BY));
|
||||||
|
gQueue.push(new insertRelated("aria-controls", "dependent10", false,
|
||||||
|
RELATION_CONTROLLER_FOR,
|
||||||
|
RELATION_CONTROLLED_BY));
|
||||||
|
|
||||||
|
gQueue.push(new insertRelated("aria-flowto", "dependent11", true,
|
||||||
|
RELATION_FLOWS_TO, RELATION_FLOWS_FROM));
|
||||||
|
gQueue.push(new insertRelated("aria-flowto", "dependent12", false,
|
||||||
|
RELATION_FLOWS_TO, RELATION_FLOWS_FROM));
|
||||||
|
|
||||||
|
gQueue.invoke(); // will call SimpleTest.finish()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
addA11yLoadEvent(doTest);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<a target="_blank"
|
||||||
|
href="https://bugzilla.mozilla.org/show_bug.cgi?id=573469"
|
||||||
|
title="Cache relations defined by ARIA attributes">
|
||||||
|
Mozilla Bug 573469
|
||||||
|
</a>
|
||||||
|
<p id="display"></p>
|
||||||
|
<div id="content" style="display: none"></div>
|
||||||
|
<pre id="test">
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<div id="dependent1">label</div>
|
||||||
|
<div id="dependent2">label2</div>
|
||||||
|
<div role="checkbox" id="host"></div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -166,35 +166,46 @@ html|*.urlbar-input {
|
||||||
|
|
||||||
/* over-link in location bar */
|
/* over-link in location bar */
|
||||||
|
|
||||||
.urlbar-over-link-layer[overlinkstate="fade-in"],
|
|
||||||
.urlbar-textbox-container:not([overlinkstate]) {
|
|
||||||
-moz-transition-property: color;
|
|
||||||
-moz-transition-duration: 150ms;
|
|
||||||
-moz-transition-timing-function: cubic-bezier(0.0, 0.6, 1.0, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
.urlbar-textbox-container[overlinkstate="fade-in"],
|
.urlbar-textbox-container[overlinkstate="fade-in"],
|
||||||
.urlbar-over-link-layer:not([overlinkstate]) {
|
.urlbar-over-link-layer[overlinkstate="fade-out"] {
|
||||||
-moz-transition-property: color;
|
-moz-transition-property: color;
|
||||||
-moz-transition-duration: 150ms;
|
-moz-transition-duration: 150ms;
|
||||||
-moz-transition-timing-function: linear;
|
|
||||||
color: transparent;
|
color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.urlbar-over-link-box[overlinkstate="fade-in"],
|
.urlbar-over-link-layer[overlinkstate="fade-in"],
|
||||||
.urlbar-textbox-container-children:not([overlinkstate]) {
|
.urlbar-textbox-container[overlinkstate="fade-out"] {
|
||||||
|
-moz-transition-property: color;
|
||||||
|
-moz-transition-duration: 150ms;
|
||||||
|
-moz-transition-timing-function: cubic-bezier(0.0, 1.0, 1.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.urlbar-over-link-box[overlinkstate="fade-in"] {
|
||||||
-moz-transition-property: opacity;
|
-moz-transition-property: opacity;
|
||||||
-moz-transition-duration: 150ms;
|
-moz-transition-duration: 150ms;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.urlbar-textbox-container-children[overlinkstate="fade-in"],
|
.urlbar-over-link-box[overlinkstate="fade-out"] {
|
||||||
.urlbar-over-link-box:not([overlinkstate]) {
|
-moz-transition-property: opacity;
|
||||||
|
-moz-transition-duration: 150ms;
|
||||||
|
-moz-transition-timing-function: cubic-bezier(0.0, 1.0, 1.0, 1.0);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.urlbar-textbox-container-children[overlinkstate="fade-in"] {
|
||||||
-moz-transition-property: opacity;
|
-moz-transition-property: opacity;
|
||||||
-moz-transition-duration: 150ms;
|
-moz-transition-duration: 150ms;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.urlbar-textbox-container-children[overlinkstate="fade-out"] {
|
||||||
|
-moz-transition-property: opacity;
|
||||||
|
-moz-transition-duration: 150ms;
|
||||||
|
-moz-transition-timing-function: cubic-bezier(0.0, 1.0, 1.0, 1.0);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
.urlbar-textbox-container[overlinkstate="showing"] {
|
.urlbar-textbox-container[overlinkstate="showing"] {
|
||||||
color: transparent;
|
color: transparent;
|
||||||
}
|
}
|
||||||
|
@ -207,6 +218,14 @@ html|*.urlbar-input {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.urlbar-over-link-layer:not([overlinkstate]) {
|
||||||
|
color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.urlbar-over-link-box:not([overlinkstate]) {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* For results that are actions, their description text is shown instead of
|
/* For results that are actions, their description text is shown instead of
|
||||||
the URL - this needs to follow the locale's direction, unlike URLs. */
|
the URL - this needs to follow the locale's direction, unlike URLs. */
|
||||||
richlistitem[type~="action"]:-moz-locale-dir(rtl) > .ac-url-box {
|
richlistitem[type~="action"]:-moz-locale-dir(rtl) > .ac-url-box {
|
||||||
|
|
|
@ -3994,14 +3994,16 @@ var XULBrowserWindow = {
|
||||||
this.defaultStatus = status;
|
this.defaultStatus = status;
|
||||||
},
|
},
|
||||||
|
|
||||||
setOverLink: function (link) {
|
setOverLink: function (url, anchorElt) {
|
||||||
// Encode bidirectional formatting characters.
|
if (gURLBar) {
|
||||||
// (RFC 3987 sections 3.2 and 4.1 paragraph 6)
|
// Encode bidirectional formatting characters.
|
||||||
link = link.replace(/[\u200e\u200f\u202a\u202b\u202c\u202d\u202e]/g,
|
// (RFC 3987 sections 3.2 and 4.1 paragraph 6)
|
||||||
|
url = url.replace(/[\u200e\u200f\u202a\u202b\u202c\u202d\u202e]/g,
|
||||||
encodeURIComponent);
|
encodeURIComponent);
|
||||||
gURLBar.setOverLink(link);
|
gURLBar.setOverLink(url);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// Called before links are navigated to to allow us to retarget them if needed.
|
// Called before links are navigated to to allow us to retarget them if needed.
|
||||||
onBeforeLinkTraversal: function(originalTarget, linkURI, linkNode, isAppTab) {
|
onBeforeLinkTraversal: function(originalTarget, linkURI, linkNode, isAppTab) {
|
||||||
// Don't modify non-default targets or targets that aren't in top-level app
|
// Don't modify non-default targets or targets that aren't in top-level app
|
||||||
|
@ -4198,7 +4200,9 @@ var XULBrowserWindow = {
|
||||||
else
|
else
|
||||||
this.isImage.setAttribute('disabled', 'true');
|
this.isImage.setAttribute('disabled', 'true');
|
||||||
|
|
||||||
|
this.hideOverLinkImmediately = true;
|
||||||
this.setOverLink("", null);
|
this.setOverLink("", null);
|
||||||
|
this.hideOverLinkImmediately = false;
|
||||||
|
|
||||||
// We should probably not do this if the value has changed since the user
|
// We should probably not do this if the value has changed since the user
|
||||||
// searched
|
// searched
|
||||||
|
|
|
@ -444,10 +444,12 @@
|
||||||
</button>
|
</button>
|
||||||
</hbox>
|
</hbox>
|
||||||
<spacer id="titlebar-spacer" flex="1"/>
|
<spacer id="titlebar-spacer" flex="1"/>
|
||||||
<hbox id="titlebar-buttonbox" align="start">
|
<hbox id="titlebar-buttonbox-container" align="start">
|
||||||
<toolbarbutton class="titlebar-button" id="titlebar-min" oncommand="window.minimize();"/>
|
<hbox id="titlebar-buttonbox">
|
||||||
<toolbarbutton class="titlebar-button" id="titlebar-max" oncommand="onTitlebarMaxClick();"/>
|
<toolbarbutton class="titlebar-button" id="titlebar-min" oncommand="window.minimize();"/>
|
||||||
<toolbarbutton class="titlebar-button" id="titlebar-close" command="cmd_closeWindow"/>
|
<toolbarbutton class="titlebar-button" id="titlebar-max" oncommand="onTitlebarMaxClick();"/>
|
||||||
|
<toolbarbutton class="titlebar-button" id="titlebar-close" command="cmd_closeWindow"/>
|
||||||
|
</hbox>
|
||||||
</hbox>
|
</hbox>
|
||||||
</hbox>
|
</hbox>
|
||||||
</vbox>
|
</vbox>
|
||||||
|
|
|
@ -43,9 +43,17 @@
|
||||||
// The Drag that's currently in process.
|
// The Drag that's currently in process.
|
||||||
var drag = {
|
var drag = {
|
||||||
info: null,
|
info: null,
|
||||||
zIndex: 100
|
zIndex: 100,
|
||||||
|
lastMoveTime: 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//----------
|
||||||
|
//Variable: resize
|
||||||
|
//The resize (actually a Drag) that is currently in process
|
||||||
|
var resize = {
|
||||||
|
info: null,
|
||||||
|
lastMoveTime: 0
|
||||||
|
};
|
||||||
|
|
||||||
// ##########
|
// ##########
|
||||||
// Class: Drag (formerly DragInfo)
|
// Class: Drag (formerly DragInfo)
|
||||||
|
|
|
@ -564,17 +564,25 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
||||||
this._sendToSubscribers("close");
|
this._sendToSubscribers("close");
|
||||||
this.removeTrenches();
|
this.removeTrenches();
|
||||||
|
|
||||||
iQ(this.container).animate({
|
if (this.hidden) {
|
||||||
opacity: 0,
|
iQ(this.container).remove();
|
||||||
"-moz-transform": "scale(.3)",
|
if (this.$undoContainer) {
|
||||||
}, {
|
this.$undoContainer.remove();
|
||||||
duration: 170,
|
this.$undoContainer = null;
|
||||||
complete: function() {
|
}
|
||||||
iQ(this).remove();
|
Items.unsquish();
|
||||||
Items.unsquish();
|
} else {
|
||||||
}
|
iQ(this.container).animate({
|
||||||
});
|
opacity: 0,
|
||||||
|
"-moz-transform": "scale(.3)",
|
||||||
|
}, {
|
||||||
|
duration: 170,
|
||||||
|
complete: function() {
|
||||||
|
iQ(this).remove();
|
||||||
|
Items.unsquish();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
this.deleteData();
|
this.deleteData();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -607,10 +615,107 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
||||||
UI.setActiveTab( UI.getClosestTab(closeCenter) );
|
UI.setActiveTab( UI.getClosestTab(closeCenter) );
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
// Function: _unhide
|
||||||
|
// Shows the hidden group.
|
||||||
|
_unhide: function GroupItem__unhide() {
|
||||||
|
let self = this;
|
||||||
|
|
||||||
|
this._cancelFadeAwayUndoButtonTimer();
|
||||||
|
this.hidden = false;
|
||||||
|
this.$undoContainer.remove();
|
||||||
|
this.$undoContainer = null;
|
||||||
|
|
||||||
|
iQ(this.container).show().animate({
|
||||||
|
"-moz-transform": "scale(1)",
|
||||||
|
"opacity": 1
|
||||||
|
}, {
|
||||||
|
duration: 170,
|
||||||
|
complete: function() {
|
||||||
|
self._children.forEach(function(child) {
|
||||||
|
iQ(child.container).show();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
self._sendToSubscribers("groupShown", { groupItemId: self.id });
|
||||||
|
},
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
// Function: closeHidden
|
||||||
|
// Removes the group item, its children and its container.
|
||||||
|
closeHidden: function GroupItem_closeHidden() {
|
||||||
|
let self = this;
|
||||||
|
|
||||||
|
this._cancelFadeAwayUndoButtonTimer();
|
||||||
|
|
||||||
|
// when "TabClose" event is fired, the browser tab is about to close and our
|
||||||
|
// item "close" event is fired. And then, the browser tab gets closed.
|
||||||
|
// In other words, the group "close" event is fired before all browser
|
||||||
|
// tabs in the group are closed. The below code would fire the group "close"
|
||||||
|
// event only after all browser tabs in that group are closed.
|
||||||
|
let shouldRemoveTabItems = [];
|
||||||
|
let toClose = this._children.concat();
|
||||||
|
toClose.forEach(function(child) {
|
||||||
|
child.removeSubscriber(self, "close");
|
||||||
|
|
||||||
|
let removed = child.close();
|
||||||
|
if (removed) {
|
||||||
|
shouldRemoveTabItems.push(child);
|
||||||
|
} else {
|
||||||
|
// child.removeSubscriber() must be called before child.close(),
|
||||||
|
// therefore we call child.addSubscriber() if the tab is not removed.
|
||||||
|
child.addSubscriber(self, "close", function() {
|
||||||
|
self.remove(child);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (shouldRemoveTabItems.length != toClose.length) {
|
||||||
|
// remove children without the assiciated tab and show the group item
|
||||||
|
shouldRemoveTabItems.forEach(function(child) {
|
||||||
|
self.remove(child, { dontArrange: true });
|
||||||
|
});
|
||||||
|
|
||||||
|
this.$undoContainer.fadeOut(function() { self._unhide() });
|
||||||
|
} else {
|
||||||
|
this.close();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
// Function: _fadeAwayUndoButton
|
||||||
|
// Fades away the undo button
|
||||||
|
_fadeAwayUndoButton: function GroupItem__fadeAwayUdoButton() {
|
||||||
|
let self = this;
|
||||||
|
|
||||||
|
if (this.$undoContainer) {
|
||||||
|
// if there is one or more orphan tabs or there is more than one group
|
||||||
|
// and other groupS are not empty, fade away the undo button.
|
||||||
|
let shouldFadeAway = GroupItems.getOrphanedTabs().length > 0;
|
||||||
|
|
||||||
|
if (!shouldFadeAway && GroupItems.groupItems.length > 1) {
|
||||||
|
shouldFadeAway =
|
||||||
|
GroupItems.groupItems.some(function(groupItem) {
|
||||||
|
return (groupItem != self && groupItem.getChildren().length > 0);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (shouldFadeAway) {
|
||||||
|
self.$undoContainer.animate({
|
||||||
|
color: "transparent",
|
||||||
|
opacity: 0
|
||||||
|
}, {
|
||||||
|
duration: this._fadeAwayUndoButtonDuration,
|
||||||
|
complete: function() { self.closeHidden(); }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
// Function: _createUndoButton
|
// Function: _createUndoButton
|
||||||
// Makes the affordance for undo a close group action
|
// Makes the affordance for undo a close group action
|
||||||
_createUndoButton: function() {
|
_createUndoButton: function GroupItem__createUndoButton() {
|
||||||
let self = this;
|
let self = this;
|
||||||
this.$undoContainer = iQ("<div/>")
|
this.$undoContainer = iQ("<div/>")
|
||||||
.addClass("undo")
|
.addClass("undo")
|
||||||
|
@ -629,6 +734,7 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
||||||
});
|
});
|
||||||
this.hidden = true;
|
this.hidden = true;
|
||||||
|
|
||||||
|
// hide group item and show undo container.
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
self.$undoContainer.animate({
|
self.$undoContainer.animate({
|
||||||
"-moz-transform": "scale(1)",
|
"-moz-transform": "scale(1)",
|
||||||
|
@ -642,36 +748,17 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
||||||
});
|
});
|
||||||
}, 50);
|
}, 50);
|
||||||
|
|
||||||
|
// add click handlers
|
||||||
this.$undoContainer.click(function(e) {
|
this.$undoContainer.click(function(e) {
|
||||||
// Only do this for clicks on this actual element.
|
// Only do this for clicks on this actual element.
|
||||||
if (e.target.nodeName != self.$undoContainer[0].nodeName)
|
if (e.target.nodeName != self.$undoContainer[0].nodeName)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
self.$undoContainer.fadeOut(function() {
|
self.$undoContainer.fadeOut(function() { self._unhide(); });
|
||||||
iQ(this).remove();
|
|
||||||
self.hidden = false;
|
|
||||||
self._cancelFadeAwayUndoButtonTimer();
|
|
||||||
self.$undoContainer = null;
|
|
||||||
|
|
||||||
iQ(self.container).show().animate({
|
|
||||||
"-moz-transform": "scale(1)",
|
|
||||||
"opacity": 1
|
|
||||||
}, {
|
|
||||||
duration: 170,
|
|
||||||
complete: function() {
|
|
||||||
self._children.forEach(function(child) {
|
|
||||||
iQ(child.container).show();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
self._sendToSubscribers("groupShown", { groupItemId: self.id });
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
undoClose.click(function() {
|
undoClose.click(function() {
|
||||||
self._cancelFadeAwayUndoButtonTimer();
|
self.$undoContainer.fadeOut(function() { self.closeHidden(); });
|
||||||
self.$undoContainer.fadeOut(function() { self._removeHiddenGroupItem(); });
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.setupFadeAwayUndoButtonTimer();
|
this.setupFadeAwayUndoButtonTimer();
|
||||||
|
@ -704,60 +791,6 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
||||||
this._undoButtonTimeoutId = null;
|
this._undoButtonTimeoutId = null;
|
||||||
},
|
},
|
||||||
|
|
||||||
// ----------
|
|
||||||
// Fades away the undo button
|
|
||||||
_fadeAwayUndoButton: function() {
|
|
||||||
let self = this;
|
|
||||||
|
|
||||||
if (this.$undoContainer) {
|
|
||||||
// if there is one or more orphan tabs or there is more than one group
|
|
||||||
// and other groupS are not empty, fade away the undo button.
|
|
||||||
let shouldFadeAway = GroupItems.getOrphanedTabs().length > 0;
|
|
||||||
|
|
||||||
if (!shouldFadeAway && GroupItems.groupItems.length > 1) {
|
|
||||||
shouldFadeAway =
|
|
||||||
GroupItems.groupItems.some(function(groupItem) {
|
|
||||||
return (groupItem != self && groupItem.getChildren().length > 0);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (shouldFadeAway) {
|
|
||||||
self.$undoContainer.animate({
|
|
||||||
color: "transparent",
|
|
||||||
opacity: 0
|
|
||||||
}, {
|
|
||||||
duration: this.fadeAwayUndoButtonDuration,
|
|
||||||
complete: function() { self._removeHiddenGroupItem(); }
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// ----------
|
|
||||||
// Removes the group item, its children and its container.
|
|
||||||
_removeHiddenGroupItem: function() {
|
|
||||||
let self = this;
|
|
||||||
|
|
||||||
// close all children
|
|
||||||
let toClose = this._children.concat();
|
|
||||||
toClose.forEach(function(child) {
|
|
||||||
child.removeSubscriber(self, "close");
|
|
||||||
child.close();
|
|
||||||
});
|
|
||||||
|
|
||||||
// remove all children
|
|
||||||
this.removeAll();
|
|
||||||
GroupItems.unregister(this);
|
|
||||||
this._sendToSubscribers("close");
|
|
||||||
this.removeTrenches();
|
|
||||||
|
|
||||||
iQ(this.container).remove();
|
|
||||||
this.$undoContainer.remove();
|
|
||||||
this.$undoContainer = null;
|
|
||||||
Items.unsquish();
|
|
||||||
|
|
||||||
this.deleteData();
|
|
||||||
},
|
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
// Function: add
|
// Function: add
|
||||||
// Adds an item to the groupItem.
|
// Adds an item to the groupItem.
|
||||||
|
@ -1047,6 +1080,10 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
||||||
// Parameters:
|
// Parameters:
|
||||||
// options - passed to <Items.arrange> or <_stackArrange>
|
// options - passed to <Items.arrange> or <_stackArrange>
|
||||||
arrange: function GroupItem_arrange(options) {
|
arrange: function GroupItem_arrange(options) {
|
||||||
|
if (GroupItems._arrangePaused) {
|
||||||
|
GroupItems.pushArrange(this, options);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (this.expanded) {
|
if (this.expanded) {
|
||||||
this.topChild = null;
|
this.topChild = null;
|
||||||
var box = new Rect(this.expanded.bounds);
|
var box = new Rect(this.expanded.bounds);
|
||||||
|
@ -1490,6 +1527,9 @@ let GroupItems = {
|
||||||
_activeGroupItem: null,
|
_activeGroupItem: null,
|
||||||
_activeOrphanTab: null,
|
_activeOrphanTab: null,
|
||||||
_cleanupFunctions: [],
|
_cleanupFunctions: [],
|
||||||
|
_arrangePaused: false,
|
||||||
|
_arrangesPending: [],
|
||||||
|
_removingHiddenGroups: false,
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
// Function: init
|
// Function: init
|
||||||
|
@ -1521,6 +1561,51 @@ let GroupItems = {
|
||||||
this.groupItems = null;
|
this.groupItems = null;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
// Function: pauseArrange
|
||||||
|
// Bypass arrange() calls and collect for resolution in
|
||||||
|
// resumeArrange()
|
||||||
|
pauseArrange: function GroupItems_pauseArrange() {
|
||||||
|
Utils.assert(this._arrangePaused == false,
|
||||||
|
"pauseArrange has been called while already paused");
|
||||||
|
Utils.assert(this._arrangesPending.length == 0,
|
||||||
|
"There are bypassed arrange() calls that haven't been resolved");
|
||||||
|
this._arrangePaused = true;
|
||||||
|
},
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
// Function: pushArrange
|
||||||
|
// Push an arrange() call and its arguments onto an array
|
||||||
|
// to be resolved in resumeArrange()
|
||||||
|
pushArrange: function GroupItems_pushArrange(groupItem, options) {
|
||||||
|
Utils.assert(this._arrangePaused,
|
||||||
|
"Ensure pushArrange() called while arrange()s aren't paused");
|
||||||
|
let i;
|
||||||
|
for (i = 0; i < this._arrangesPending.length; i++)
|
||||||
|
if (this._arrangesPending[i].groupItem === groupItem)
|
||||||
|
break;
|
||||||
|
let arrangeInfo = {
|
||||||
|
groupItem: groupItem,
|
||||||
|
options: options
|
||||||
|
};
|
||||||
|
if (i < this._arrangesPending.length)
|
||||||
|
this._arrangesPending[i] = arrangeInfo;
|
||||||
|
else
|
||||||
|
this._arrangesPending.push(arrangeInfo);
|
||||||
|
},
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
// Function: resumeArrange
|
||||||
|
// Resolve bypassed and collected arrange() calls
|
||||||
|
resumeArrange: function GroupItems_resumeArrange() {
|
||||||
|
for (let i = 0; i < this._arrangesPending.length; i++) {
|
||||||
|
let g = this._arrangesPending[i];
|
||||||
|
g.groupItem.arrange(g.options);
|
||||||
|
}
|
||||||
|
this._arrangesPending = [];
|
||||||
|
this._arrangePaused = false;
|
||||||
|
},
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
// Function: _handleAttrModified
|
// Function: _handleAttrModified
|
||||||
// watch for icon changes on app tabs
|
// watch for icon changes on app tabs
|
||||||
|
@ -2107,19 +2192,16 @@ let GroupItems = {
|
||||||
// Function: removeHiddenGroups
|
// Function: removeHiddenGroups
|
||||||
// Removes all hidden groups' data and its browser tabs.
|
// Removes all hidden groups' data and its browser tabs.
|
||||||
removeHiddenGroups: function GroupItems_removeHiddenGroups() {
|
removeHiddenGroups: function GroupItems_removeHiddenGroups() {
|
||||||
iQ(".undo").remove();
|
if (this._removingHiddenGroups)
|
||||||
|
return;
|
||||||
// ToDo: encapsulate this in the group item. bug 594863
|
this._removingHiddenGroups = true;
|
||||||
this.groupItems.forEach(function(groupItem) {
|
|
||||||
if (groupItem.hidden) {
|
|
||||||
let toClose = groupItem._children.concat();
|
|
||||||
toClose.forEach(function(child) {
|
|
||||||
child.removeSubscriber(groupItem, "close");
|
|
||||||
child.close();
|
|
||||||
});
|
|
||||||
|
|
||||||
groupItem.deleteData();
|
let groupItems = this.groupItems.concat();
|
||||||
}
|
groupItems.forEach(function(groupItem) {
|
||||||
});
|
if (groupItem.hidden)
|
||||||
|
groupItem.closeHidden();
|
||||||
|
});
|
||||||
|
|
||||||
|
this._removingHiddenGroups = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -699,6 +699,7 @@ iQClass.prototype = {
|
||||||
let events = [
|
let events = [
|
||||||
'keyup',
|
'keyup',
|
||||||
'keydown',
|
'keydown',
|
||||||
|
'keypress',
|
||||||
'mouseup',
|
'mouseup',
|
||||||
'mousedown',
|
'mousedown',
|
||||||
'mouseover',
|
'mouseover',
|
||||||
|
|
|
@ -216,7 +216,6 @@ Item.prototype = {
|
||||||
|
|
||||||
// ___ resize
|
// ___ resize
|
||||||
var self = this;
|
var self = this;
|
||||||
var resizeInfo = null;
|
|
||||||
this.resizeOptions = {
|
this.resizeOptions = {
|
||||||
aspectRatio: self.keepProportional,
|
aspectRatio: self.keepProportional,
|
||||||
minWidth: 90,
|
minWidth: 90,
|
||||||
|
@ -224,16 +223,16 @@ Item.prototype = {
|
||||||
start: function(e,ui) {
|
start: function(e,ui) {
|
||||||
if (this.isAGroupItem)
|
if (this.isAGroupItem)
|
||||||
GroupItems.setActiveGroupItem(this);
|
GroupItems.setActiveGroupItem(this);
|
||||||
resizeInfo = new Drag(this, e, true); // true = isResizing
|
resize.info = new Drag(this, e, true); // true = isResizing
|
||||||
},
|
},
|
||||||
resize: function(e,ui) {
|
resize: function(e,ui) {
|
||||||
resizeInfo.snap(UI.rtl ? 'topright' : 'topleft', false, self.keepProportional);
|
resize.info.snap(UI.rtl ? 'topright' : 'topleft', false, self.keepProportional);
|
||||||
},
|
},
|
||||||
stop: function() {
|
stop: function() {
|
||||||
self.setUserSize();
|
self.setUserSize();
|
||||||
self.pushAway();
|
self.pushAway();
|
||||||
resizeInfo.stop();
|
resize.info.stop();
|
||||||
resizeInfo = null;
|
resize.info = null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -599,6 +598,9 @@ Item.prototype = {
|
||||||
|
|
||||||
// ___ mousemove
|
// ___ mousemove
|
||||||
var handleMouseMove = function(e) {
|
var handleMouseMove = function(e) {
|
||||||
|
// global drag tracking
|
||||||
|
drag.lastMoveTime = Date.now();
|
||||||
|
|
||||||
// positioning
|
// positioning
|
||||||
var mouse = new Point(e.pageX, e.pageY);
|
var mouse = new Point(e.pageX, e.pageY);
|
||||||
if (!startSent) {
|
if (!startSent) {
|
||||||
|
@ -766,6 +768,9 @@ Item.prototype = {
|
||||||
|
|
||||||
// ___ mousemove
|
// ___ mousemove
|
||||||
var handleMouseMove = function(e) {
|
var handleMouseMove = function(e) {
|
||||||
|
// global resize tracking
|
||||||
|
resize.lastMoveTime = Date.now();
|
||||||
|
|
||||||
var mouse = new Point(e.pageX, e.pageY);
|
var mouse = new Point(e.pageX, e.pageY);
|
||||||
var box = self.getBounds();
|
var box = self.getBounds();
|
||||||
if (UI.rtl) {
|
if (UI.rtl) {
|
||||||
|
|
|
@ -132,7 +132,7 @@ var TabUtils = {
|
||||||
// Function: favURLOf
|
// Function: favURLOf
|
||||||
// Given a <TabItem> or a <xul:tab> returns the URL of tab's favicon.
|
// Given a <TabItem> or a <xul:tab> returns the URL of tab's favicon.
|
||||||
faviconURLOf: function TabUtils_faviconURLOf(tab) {
|
faviconURLOf: function TabUtils_faviconURLOf(tab) {
|
||||||
return tab.image != undefined ? tab.image : tab.favEl.src;
|
return tab.image != undefined ? tab.image : tab.favImgEl.src;
|
||||||
},
|
},
|
||||||
|
|
||||||
// ---------
|
// ---------
|
||||||
|
@ -335,9 +335,9 @@ SearchEventHandlerClass.prototype = {
|
||||||
// Handles all keypresses before the search interface is brought up.
|
// Handles all keypresses before the search interface is brought up.
|
||||||
beforeSearchKeyHandler: function (event) {
|
beforeSearchKeyHandler: function (event) {
|
||||||
// Only match reasonable text-like characters for quick search.
|
// Only match reasonable text-like characters for quick search.
|
||||||
var key = String.fromCharCode(event.which);
|
|
||||||
// TODO: Also include funky chars. Bug 593904
|
// TODO: Also include funky chars. Bug 593904
|
||||||
if (!key.match(/[A-Z0-9]/) || event.altKey || event.ctrlKey || event.metaKey)
|
if (!String.fromCharCode(event.which).match(/[a-zA-Z0-9]/) || event.altKey ||
|
||||||
|
event.ctrlKey || event.metaKey)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// If we are already in an input field, allow typing as normal.
|
// If we are already in an input field, allow typing as normal.
|
||||||
|
@ -353,16 +353,17 @@ SearchEventHandlerClass.prototype = {
|
||||||
// Handles all keypresses while search mode.
|
// Handles all keypresses while search mode.
|
||||||
inSearchKeyHandler: function (event) {
|
inSearchKeyHandler: function (event) {
|
||||||
var term = iQ("#searchbox").val();
|
var term = iQ("#searchbox").val();
|
||||||
|
|
||||||
if (event.which == event.DOM_VK_ESCAPE)
|
if ((event.keyCode == event.DOM_VK_ESCAPE) ||
|
||||||
hideSearch(event);
|
(event.keyCode == event.DOM_VK_BACK_SPACE && term.length <= 1)) {
|
||||||
if (event.which == event.DOM_VK_BACK_SPACE && term.length <= 1)
|
|
||||||
hideSearch(event);
|
hideSearch(event);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var matcher = new TabMatcher(term);
|
var matcher = new TabMatcher(term);
|
||||||
var matches = matcher.matched();
|
var matches = matcher.matched();
|
||||||
var others = matcher.matchedTabsFromOtherWindows();
|
var others = matcher.matchedTabsFromOtherWindows();
|
||||||
if (event.which == event.DOM_VK_RETURN && (matches.length > 0 || others.length > 0)) {
|
if (event.keyCode == event.DOM_VK_RETURN && (matches.length > 0 || others.length > 0)) {
|
||||||
hideSearch(event);
|
hideSearch(event);
|
||||||
if (matches.length > 0)
|
if (matches.length > 0)
|
||||||
matches[0].zoomIn();
|
matches[0].zoomIn();
|
||||||
|
@ -378,9 +379,9 @@ SearchEventHandlerClass.prototype = {
|
||||||
switchToBeforeMode: function switchToBeforeMode() {
|
switchToBeforeMode: function switchToBeforeMode() {
|
||||||
var self = this;
|
var self = this;
|
||||||
if (this.currentHandler)
|
if (this.currentHandler)
|
||||||
iQ(document).unbind("keydown", this.currentHandler);
|
iQ(window).unbind("keypress", this.currentHandler);
|
||||||
this.currentHandler = function(event) self.beforeSearchKeyHandler(event);
|
this.currentHandler = function(event) self.beforeSearchKeyHandler(event);
|
||||||
iQ(document).keydown(self.currentHandler);
|
iQ(window).keypress(this.currentHandler);
|
||||||
},
|
},
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
|
@ -390,9 +391,9 @@ SearchEventHandlerClass.prototype = {
|
||||||
switchToInMode: function switchToInMode() {
|
switchToInMode: function switchToInMode() {
|
||||||
var self = this;
|
var self = this;
|
||||||
if (this.currentHandler)
|
if (this.currentHandler)
|
||||||
iQ(document).unbind("keydown", this.currentHandler);
|
iQ(window).unbind("keypress", this.currentHandler);
|
||||||
this.currentHandler = function(event) self.inSearchKeyHandler(event);
|
this.currentHandler = function(event) self.inSearchKeyHandler(event);
|
||||||
iQ(document).keydown(self.currentHandler);
|
iQ(window).keypress(this.currentHandler);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -488,13 +489,13 @@ function hideSearch(event){
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
}
|
}
|
||||||
|
|
||||||
let newEvent = document.createEvent("Events");
|
|
||||||
newEvent.initEvent("tabviewsearchdisabled", false, false);
|
|
||||||
dispatchEvent(newEvent);
|
|
||||||
|
|
||||||
// Return focus to the tab window
|
// Return focus to the tab window
|
||||||
UI.blurAll();
|
UI.blurAll();
|
||||||
gTabViewFrame.contentWindow.focus();
|
gTabViewFrame.contentWindow.focus();
|
||||||
|
|
||||||
|
let newEvent = document.createEvent("Events");
|
||||||
|
newEvent.initEvent("tabviewsearchdisabled", false, false);
|
||||||
|
dispatchEvent(newEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
function performSearch() {
|
function performSearch() {
|
||||||
|
@ -513,13 +514,13 @@ function ensureSearchShown(event){
|
||||||
var $search = iQ("#search");
|
var $search = iQ("#search");
|
||||||
var $searchbox = iQ("#searchbox");
|
var $searchbox = iQ("#searchbox");
|
||||||
iQ("#searchbutton").css({ opacity: 1 });
|
iQ("#searchbutton").css({ opacity: 1 });
|
||||||
|
|
||||||
|
|
||||||
if ($search.css("display") == "none") {
|
if (!isSearchEnabled()) {
|
||||||
$search.show();
|
$search.show();
|
||||||
var mainWindow = gWindow.document.getElementById("main-window");
|
var mainWindow = gWindow.document.getElementById("main-window");
|
||||||
mainWindow.setAttribute("activetitlebarcolor", "#717171");
|
mainWindow.setAttribute("activetitlebarcolor", "#717171");
|
||||||
|
|
||||||
// Marshal the focusing, otherwise you end up with
|
// Marshal the focusing, otherwise you end up with
|
||||||
// a race condition where only sometimes would the
|
// a race condition where only sometimes would the
|
||||||
// first keystroke be registered by the search box.
|
// first keystroke be registered by the search box.
|
||||||
|
@ -529,18 +530,20 @@ function ensureSearchShown(event){
|
||||||
$searchbox[0].focus();
|
$searchbox[0].focus();
|
||||||
$searchbox[0].val = '0';
|
$searchbox[0].val = '0';
|
||||||
$searchbox.css({"z-index":"1015"});
|
$searchbox.css({"z-index":"1015"});
|
||||||
if (event != null){
|
if (event != null)
|
||||||
var keyCode = event.which + (event.shiftKey ? 0 : 32);
|
$searchbox.val(String.fromCharCode(event.charCode));
|
||||||
$searchbox.val(String.fromCharCode(keyCode));
|
|
||||||
}
|
|
||||||
}, 0);
|
|
||||||
|
|
||||||
let newEvent = document.createEvent("Events");
|
let newEvent = document.createEvent("Events");
|
||||||
newEvent.initEvent("tabviewsearchenabled", false, false);
|
newEvent.initEvent("tabviewsearchenabled", false, false);
|
||||||
dispatchEvent(newEvent);
|
dispatchEvent(newEvent);
|
||||||
|
}, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isSearchEnabled() {
|
||||||
|
return iQ("#search").css("display") != "none";
|
||||||
|
}
|
||||||
|
|
||||||
var SearchEventHandler = new SearchEventHandlerClass();
|
var SearchEventHandler = new SearchEventHandlerClass();
|
||||||
|
|
||||||
// Features to add:
|
// Features to add:
|
||||||
|
|
|
@ -70,8 +70,10 @@ function TabItem(tab, options) {
|
||||||
|
|
||||||
this.canvasSizeForced = false;
|
this.canvasSizeForced = false;
|
||||||
this.isShowingCachedData = false;
|
this.isShowingCachedData = false;
|
||||||
this.favEl = (iQ('.favicon>img', $div))[0];
|
this.favEl = (iQ('.favicon', $div))[0];
|
||||||
|
this.favImgEl = (iQ('.favicon>img', $div))[0];
|
||||||
this.nameEl = (iQ('.tab-title', $div))[0];
|
this.nameEl = (iQ('.tab-title', $div))[0];
|
||||||
|
this.thumbEl = (iQ('.thumb', $div))[0];
|
||||||
this.canvasEl = (iQ('.thumb canvas', $div))[0];
|
this.canvasEl = (iQ('.thumb canvas', $div))[0];
|
||||||
this.cachedThumbEl = (iQ('img.cached-thumb', $div))[0];
|
this.cachedThumbEl = (iQ('img.cached-thumb', $div))[0];
|
||||||
|
|
||||||
|
@ -96,6 +98,8 @@ function TabItem(tab, options) {
|
||||||
|
|
||||||
this.bounds = $div.bounds();
|
this.bounds = $div.bounds();
|
||||||
|
|
||||||
|
this._lastTabUpdateTime = Date.now();
|
||||||
|
|
||||||
// ___ superclass setup
|
// ___ superclass setup
|
||||||
this._init($div[0]);
|
this._init($div[0]);
|
||||||
|
|
||||||
|
@ -194,6 +198,7 @@ function TabItem(tab, options) {
|
||||||
iQ("<div>")
|
iQ("<div>")
|
||||||
.addClass('close')
|
.addClass('close')
|
||||||
.appendTo($div);
|
.appendTo($div);
|
||||||
|
this.closeEl = (iQ(".close", $div))[0];
|
||||||
|
|
||||||
iQ("<div>")
|
iQ("<div>")
|
||||||
.addClass('expander')
|
.addClass('expander')
|
||||||
|
@ -322,10 +327,10 @@ TabItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
||||||
this.bounds.copy(rect);
|
this.bounds.copy(rect);
|
||||||
else {
|
else {
|
||||||
var $container = iQ(this.container);
|
var $container = iQ(this.container);
|
||||||
var $title = iQ('.tab-title', $container);
|
var $title = iQ(this.nameEl);
|
||||||
var $thumb = iQ('.thumb', $container);
|
var $thumb = iQ(this.thumbEl);
|
||||||
var $close = iQ('.close', $container);
|
var $close = iQ(this.closeEl);
|
||||||
var $fav = iQ('.favicon', $container);
|
var $fav = iQ(this.favEl);
|
||||||
var css = {};
|
var css = {};
|
||||||
|
|
||||||
const fontSizeRange = new Range(8,15);
|
const fontSizeRange = new Range(8,15);
|
||||||
|
@ -461,12 +466,20 @@ TabItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
||||||
// Function: close
|
// Function: close
|
||||||
// Closes this item (actually closes the tab associated with it, which automatically
|
// Closes this item (actually closes the tab associated with it, which automatically
|
||||||
// closes the item.
|
// closes the item.
|
||||||
|
// Returns true if this tab is removed.
|
||||||
close: function TabItem_close() {
|
close: function TabItem_close() {
|
||||||
|
// when "TabClose" event is fired, the browser tab is about to close and our
|
||||||
|
// item "close" is fired before the browser tab actually get closed.
|
||||||
|
// Therefore, we need "tabRemoved" event below.
|
||||||
gBrowser.removeTab(this.tab);
|
gBrowser.removeTab(this.tab);
|
||||||
this._sendToSubscribers("tabRemoved");
|
let tabNotClosed =
|
||||||
|
Array.some(gBrowser.tabs, function(tab) { return tab == this.tab; }, this);
|
||||||
|
if (!tabNotClosed)
|
||||||
|
this._sendToSubscribers("tabRemoved");
|
||||||
|
|
||||||
// No need to explicitly delete the tab data, becasue sessionstore data
|
// No need to explicitly delete the tab data, becasue sessionstore data
|
||||||
// associated with the tab will automatically go away
|
// associated with the tab will automatically go away
|
||||||
|
return !tabNotClosed;
|
||||||
},
|
},
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
|
@ -544,9 +557,14 @@ TabItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
||||||
function onZoomDone() {
|
function onZoomDone() {
|
||||||
UI.goToTab(tab);
|
UI.goToTab(tab);
|
||||||
|
|
||||||
if (isNewBlankTab)
|
// tab might not be selected because hideTabView() is invoked after
|
||||||
gWindow.gURLBar.focus();
|
// UI.goToTab() so we need to setup everything for the gBrowser.selectedTab
|
||||||
|
if (tab != gBrowser.selectedTab) {
|
||||||
|
UI.onTabSelect(gBrowser.selectedTab);
|
||||||
|
} else {
|
||||||
|
if (isNewBlankTab)
|
||||||
|
gWindow.gURLBar.focus();
|
||||||
|
}
|
||||||
if (childHitResult.callback)
|
if (childHitResult.callback)
|
||||||
childHitResult.callback();
|
childHitResult.callback();
|
||||||
}
|
}
|
||||||
|
@ -581,8 +599,9 @@ TabItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
||||||
onZoomDone();
|
onZoomDone();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else
|
} else {
|
||||||
setTimeout(onZoomDone, 0);
|
setTimeout(onZoomDone, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -684,10 +703,11 @@ let TabItems = {
|
||||||
items: [],
|
items: [],
|
||||||
paintingPaused: 0,
|
paintingPaused: 0,
|
||||||
_tabsWaitingForUpdate: [],
|
_tabsWaitingForUpdate: [],
|
||||||
_heartbeatOn: false,
|
_heartbeatOn: false, // see explanation at startHeartbeat() below
|
||||||
_heartbeatTiming: 100, // milliseconds between beats
|
_heartbeatTiming: 100, // milliseconds between _checkHeartbeat() calls
|
||||||
_lastUpdateTime: Date.now(),
|
_lastUpdateTime: Date.now(),
|
||||||
_eventListeners: [],
|
_eventListeners: [],
|
||||||
|
tempCanvas: null,
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
// Function: init
|
// Function: init
|
||||||
|
@ -696,6 +716,15 @@ let TabItems = {
|
||||||
Utils.assert(window.AllTabs, "AllTabs must be initialized first");
|
Utils.assert(window.AllTabs, "AllTabs must be initialized first");
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
|
let $canvas = iQ("<canvas>");
|
||||||
|
$canvas.appendTo(iQ("body"));
|
||||||
|
$canvas.hide();
|
||||||
|
this.tempCanvas = $canvas[0];
|
||||||
|
// 150 pixels is an empirical size, below which FF's drawWindow()
|
||||||
|
// algorithm breaks down
|
||||||
|
this.tempCanvas.width = 150;
|
||||||
|
this.tempCanvas.height = 150;
|
||||||
|
|
||||||
// When a tab is opened, create the TabItem
|
// When a tab is opened, create the TabItem
|
||||||
this._eventListeners["open"] = function(tab) {
|
this._eventListeners["open"] = function(tab) {
|
||||||
if (tab.ownerDocument.defaultView != gWindow || tab.pinned)
|
if (tab.ownerDocument.defaultView != gWindow || tab.pinned)
|
||||||
|
@ -774,6 +803,7 @@ let TabItems = {
|
||||||
if (shouldDefer && !isCurrentTab) {
|
if (shouldDefer && !isCurrentTab) {
|
||||||
if (this._tabsWaitingForUpdate.indexOf(tab) == -1)
|
if (this._tabsWaitingForUpdate.indexOf(tab) == -1)
|
||||||
this._tabsWaitingForUpdate.push(tab);
|
this._tabsWaitingForUpdate.push(tab);
|
||||||
|
this.startHeartbeat();
|
||||||
} else
|
} else
|
||||||
this._update(tab);
|
this._update(tab);
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
|
@ -802,8 +832,8 @@ let TabItems = {
|
||||||
if (iconUrl == null)
|
if (iconUrl == null)
|
||||||
iconUrl = Utils.defaultFaviconURL;
|
iconUrl = Utils.defaultFaviconURL;
|
||||||
|
|
||||||
if (iconUrl != tabItem.favEl.src)
|
if (iconUrl != tabItem.favImgEl.src)
|
||||||
tabItem.favEl.src = iconUrl;
|
tabItem.favImgEl.src = iconUrl;
|
||||||
|
|
||||||
// ___ URL
|
// ___ URL
|
||||||
let tabUrl = tab.linkedBrowser.currentURI.spec;
|
let tabUrl = tab.linkedBrowser.currentURI.spec;
|
||||||
|
@ -834,6 +864,9 @@ let TabItems = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._lastUpdateTime = Date.now();
|
||||||
|
tabItem._lastTabUpdateTime = this._lastUpdateTime;
|
||||||
|
|
||||||
tabItem.tabCanvas.paint();
|
tabItem.tabCanvas.paint();
|
||||||
|
|
||||||
// ___ cache
|
// ___ cache
|
||||||
|
@ -843,8 +876,6 @@ let TabItems = {
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
Utils.log(e);
|
Utils.log(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
this._lastUpdateTime = Date.now();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
|
@ -901,55 +932,64 @@ let TabItems = {
|
||||||
},
|
},
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
// Function: heartbeat
|
// Function: startHeartbeat
|
||||||
// Allows us to spreadout update calls over a period of time.
|
// Start a new heartbeat if there isn't one already started.
|
||||||
heartbeat: function TabItems_heartbeat() {
|
// The heartbeat is a chain of setTimeout calls that allows us to spread
|
||||||
if (!this._heartbeatOn)
|
// out update calls over a period of time.
|
||||||
|
// _heartbeatOn is used to make sure that we don't add multiple
|
||||||
|
// setTimeout chains.
|
||||||
|
startHeartbeat: function TabItems_startHeartbeat() {
|
||||||
|
if (!this._heartbeatOn) {
|
||||||
|
this._heartbeatOn = true;
|
||||||
|
let self = this;
|
||||||
|
setTimeout(function() {
|
||||||
|
self._checkHeartbeat();
|
||||||
|
}, this._heartbeatTiming);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
// Function: _checkHeartbeat
|
||||||
|
// This periodically checks for tabs waiting to be updated, and calls
|
||||||
|
// _update on them.
|
||||||
|
// Should only be called by startHeartbeat and resumePainting.
|
||||||
|
_checkHeartbeat: function TabItems__checkHeartbeat() {
|
||||||
|
this._heartbeatOn = false;
|
||||||
|
|
||||||
|
if (this.isPaintingPaused())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (this._tabsWaitingForUpdate.length) {
|
if (this._tabsWaitingForUpdate.length && UI.isIdle()) {
|
||||||
this._update(this._tabsWaitingForUpdate[0]);
|
this._update(this._tabsWaitingForUpdate[0]);
|
||||||
// _update will remove the tab from the waiting list
|
//_update will remove the tab from the waiting list
|
||||||
}
|
}
|
||||||
|
|
||||||
let self = this;
|
|
||||||
if (this._tabsWaitingForUpdate.length) {
|
if (this._tabsWaitingForUpdate.length) {
|
||||||
setTimeout(function() {
|
this.startHeartbeat();
|
||||||
self.heartbeat();
|
|
||||||
}, this._heartbeatTiming);
|
|
||||||
} else
|
|
||||||
this._hearbeatOn = false;
|
|
||||||
},
|
|
||||||
|
|
||||||
// ----------
|
|
||||||
// Function: pausePainting
|
|
||||||
// Tells TabItems to stop updating thumbnails (so you can do
|
|
||||||
// animations without thumbnail paints causing stutters).
|
|
||||||
// pausePainting can be called multiple times, but every call to
|
|
||||||
// pausePainting needs to be mirrored with a call to <resumePainting>.
|
|
||||||
pausePainting: function TabItems_pausePainting() {
|
|
||||||
this.paintingPaused++;
|
|
||||||
|
|
||||||
if (this.isPaintingPaused() && this._heartbeatOn)
|
|
||||||
this._heartbeatOn = false;
|
|
||||||
},
|
|
||||||
|
|
||||||
// ----------
|
|
||||||
// Function: resumePainting
|
|
||||||
// Undoes a call to <pausePainting>. For instance, if you called
|
|
||||||
// pausePainting three times in a row, you'll need to call resumePainting
|
|
||||||
// three times before TabItems will start updating thumbnails again.
|
|
||||||
resumePainting: function TabItems_resumePainting() {
|
|
||||||
this.paintingPaused--;
|
|
||||||
|
|
||||||
if (!this.isPaintingPaused() &&
|
|
||||||
this._tabsWaitingForUpdate.length &&
|
|
||||||
!this._heartbeatOn) {
|
|
||||||
this._heartbeatOn = true;
|
|
||||||
this.heartbeat();
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
// Function: pausePainting
|
||||||
|
// Tells TabItems to stop updating thumbnails (so you can do
|
||||||
|
// animations without thumbnail paints causing stutters).
|
||||||
|
// pausePainting can be called multiple times, but every call to
|
||||||
|
// pausePainting needs to be mirrored with a call to <resumePainting>.
|
||||||
|
pausePainting: function TabItems_pausePainting() {
|
||||||
|
this.paintingPaused++;
|
||||||
|
},
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
// Function: resumePainting
|
||||||
|
// Undoes a call to <pausePainting>. For instance, if you called
|
||||||
|
// pausePainting three times in a row, you'll need to call resumePainting
|
||||||
|
// three times before TabItems will start updating thumbnails again.
|
||||||
|
resumePainting: function TabItems_resumePainting() {
|
||||||
|
this.paintingPaused--;
|
||||||
|
if (!this.isPaintingPaused())
|
||||||
|
this.startHeartbeat();
|
||||||
|
},
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
// Function: isPaintingPaused
|
// Function: isPaintingPaused
|
||||||
// Returns a boolean indicating whether painting
|
// Returns a boolean indicating whether painting
|
||||||
|
@ -1106,8 +1146,6 @@ TabCanvas.prototype = {
|
||||||
// ----------
|
// ----------
|
||||||
// Function: paint
|
// Function: paint
|
||||||
paint: function TabCanvas_paint(evt) {
|
paint: function TabCanvas_paint(evt) {
|
||||||
var ctx = this.canvas.getContext("2d");
|
|
||||||
|
|
||||||
var w = this.canvas.width;
|
var w = this.canvas.width;
|
||||||
var h = this.canvas.height;
|
var h = this.canvas.height;
|
||||||
if (!w || !h)
|
if (!w || !h)
|
||||||
|
@ -1119,19 +1157,59 @@ TabCanvas.prototype = {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var scaler = w/fromWin.innerWidth;
|
let tempCanvas = TabItems.tempCanvas;
|
||||||
|
if (w < tempCanvas.width) {
|
||||||
// TODO: Potentially only redraw the dirty rect? (Is it worth it?)
|
// Small draw case where nearest-neighbor algorithm breaks down in Windows
|
||||||
|
// First draw to a larger canvas (150px wide), and then draw that image
|
||||||
ctx.save();
|
// to the destination canvas.
|
||||||
ctx.scale(scaler, scaler);
|
|
||||||
try{
|
var tempCtx = tempCanvas.getContext("2d");
|
||||||
ctx.drawWindow(fromWin, fromWin.scrollX, fromWin.scrollY, w/scaler, h/scaler, "#fff");
|
|
||||||
} catch(e) {
|
let canvW = tempCanvas.width;
|
||||||
Utils.error('paint', e);
|
let canvH = (h/w) * canvW;
|
||||||
|
|
||||||
|
var scaler = canvW/fromWin.innerWidth;
|
||||||
|
|
||||||
|
tempCtx.save();
|
||||||
|
tempCtx.clearRect(0,0,tempCanvas.width,tempCanvas.height);
|
||||||
|
tempCtx.scale(scaler, scaler);
|
||||||
|
try{
|
||||||
|
tempCtx.drawWindow(fromWin, fromWin.scrollX, fromWin.scrollY,
|
||||||
|
canvW/scaler, canvH/scaler, "#fff");
|
||||||
|
} catch(e) {
|
||||||
|
Utils.error('paint', e);
|
||||||
|
}
|
||||||
|
tempCtx.restore();
|
||||||
|
|
||||||
|
// Now copy to tabitem canvas. No save/restore necessary.
|
||||||
|
var destCtx = this.canvas.getContext("2d");
|
||||||
|
try{
|
||||||
|
// the tempcanvas is square, so draw it as a square.
|
||||||
|
destCtx.drawImage(tempCanvas, 0, 0, w, w);
|
||||||
|
} catch(e) {
|
||||||
|
Utils.error('paint', e);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// General case where nearest neighbor algorithm looks good
|
||||||
|
// Draw directly to the destination canvas
|
||||||
|
|
||||||
|
var ctx = this.canvas.getContext("2d");
|
||||||
|
|
||||||
|
var scaler = w/fromWin.innerWidth;
|
||||||
|
|
||||||
|
// TODO: Potentially only redraw the dirty rect? (Is it worth it?)
|
||||||
|
|
||||||
|
ctx.save();
|
||||||
|
ctx.scale(scaler, scaler);
|
||||||
|
try{
|
||||||
|
ctx.drawWindow(fromWin, fromWin.scrollX, fromWin.scrollY, w/scaler, h/scaler, "#fff");
|
||||||
|
} catch(e) {
|
||||||
|
Utils.error('paint', e);
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.restore();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
|
|
|
@ -88,6 +88,12 @@ let UI = {
|
||||||
// An array of functions to be called at uninit time
|
// An array of functions to be called at uninit time
|
||||||
_cleanupFunctions: [],
|
_cleanupFunctions: [],
|
||||||
|
|
||||||
|
// Constant: _maxInteractiveWait
|
||||||
|
// If the UI is in the middle of an operation, this is the max amount of
|
||||||
|
// milliseconds to wait between input events before we no longer consider
|
||||||
|
// the operation interactive.
|
||||||
|
_maxInteractiveWait: 250,
|
||||||
|
|
||||||
// Variable: _privateBrowsing
|
// Variable: _privateBrowsing
|
||||||
// Keeps track of info related to private browsing, including:
|
// Keeps track of info related to private browsing, including:
|
||||||
// transitionStage - what step we're on in entering/exiting PB
|
// transitionStage - what step we're on in entering/exiting PB
|
||||||
|
@ -171,6 +177,7 @@ let UI = {
|
||||||
|
|
||||||
// ___ Storage
|
// ___ Storage
|
||||||
|
|
||||||
|
GroupItems.pauseArrange();
|
||||||
GroupItems.init();
|
GroupItems.init();
|
||||||
|
|
||||||
let firstTime = true;
|
let firstTime = true;
|
||||||
|
@ -221,9 +228,11 @@ let UI = {
|
||||||
// initialized.
|
// initialized.
|
||||||
let event = document.createEvent("Events");
|
let event = document.createEvent("Events");
|
||||||
event.initEvent("tabviewframeinitialized", true, false);
|
event.initEvent("tabviewframeinitialized", true, false);
|
||||||
dispatchEvent(event);
|
dispatchEvent(event);
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
Utils.log(e);
|
Utils.log(e);
|
||||||
|
} finally {
|
||||||
|
GroupItems.resumeArrange();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -320,6 +329,18 @@ let UI = {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
// Function: isIdle
|
||||||
|
// Returns true if the last interaction was long enough ago to consider the
|
||||||
|
// UI idle. Used to determine whether interactivity would be sacrificed if
|
||||||
|
// the CPU was to become busy.
|
||||||
|
//
|
||||||
|
isIdle: function UI_isIdle() {
|
||||||
|
let time = Date.now();
|
||||||
|
let maxEvent = Math.max(drag.lastMoveTime, resize.lastMoveTime);
|
||||||
|
return (time - maxEvent) > this._maxInteractiveWait;
|
||||||
|
},
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
// Function: getActiveTab
|
// Function: getActiveTab
|
||||||
// Returns the currently active tab as a <TabItem>
|
// Returns the currently active tab as a <TabItem>
|
||||||
|
@ -450,6 +471,8 @@ let UI = {
|
||||||
if (!this._isTabViewVisible())
|
if (!this._isTabViewVisible())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// another tab might be select if user decides to stay on a page when
|
||||||
|
// a onclose confirmation prompts.
|
||||||
GroupItems.removeHiddenGroups();
|
GroupItems.removeHiddenGroups();
|
||||||
TabItems.pausePainting();
|
TabItems.pausePainting();
|
||||||
|
|
||||||
|
@ -678,6 +701,7 @@ let UI = {
|
||||||
},
|
},
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
|
// Function: goToTab
|
||||||
// Selects the given xul:tab in the browser.
|
// Selects the given xul:tab in the browser.
|
||||||
goToTab: function UI_goToTab(xulTab) {
|
goToTab: function UI_goToTab(xulTab) {
|
||||||
// If it's not focused, the onFocus listener would handle it.
|
// If it's not focused, the onFocus listener would handle it.
|
||||||
|
@ -710,6 +734,11 @@ let UI = {
|
||||||
if (this._isTabViewVisible())
|
if (this._isTabViewVisible())
|
||||||
this.hideTabView();
|
this.hideTabView();
|
||||||
|
|
||||||
|
// another tab might be selected when hideTabView() is invoked so a
|
||||||
|
// validation is needed.
|
||||||
|
if (this._currentTab != tab)
|
||||||
|
return;
|
||||||
|
|
||||||
let oldItem = null;
|
let oldItem = null;
|
||||||
let newItem = null;
|
let newItem = null;
|
||||||
|
|
||||||
|
@ -814,11 +843,16 @@ let UI = {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
iQ(window).keyup(function(event) {
|
iQ(window).keyup(function(event) {
|
||||||
if (!event.metaKey) Keys.meta = false;
|
if (!event.metaKey)
|
||||||
|
Keys.meta = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
iQ(window).keydown(function(event) {
|
iQ(window).keydown(function(event) {
|
||||||
if (event.metaKey) Keys.meta = true;
|
if (event.metaKey)
|
||||||
|
Keys.meta = true;
|
||||||
|
|
||||||
|
if (isSearchEnabled())
|
||||||
|
return;
|
||||||
|
|
||||||
function getClosestTabBy(norm) {
|
function getClosestTabBy(norm) {
|
||||||
if (!self.getActiveTab())
|
if (!self.getActiveTab())
|
||||||
|
@ -875,7 +909,7 @@ let UI = {
|
||||||
event.keyCode == KeyEvent.DOM_VK_ENTER) {
|
event.keyCode == KeyEvent.DOM_VK_ENTER) {
|
||||||
let activeTab = self.getActiveTab();
|
let activeTab = self.getActiveTab();
|
||||||
if (activeTab)
|
if (activeTab)
|
||||||
activeTab.zoomIn();
|
activeTab.zoomIn();
|
||||||
|
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
@ -989,11 +1023,12 @@ let UI = {
|
||||||
}
|
}
|
||||||
|
|
||||||
function collapse() {
|
function collapse() {
|
||||||
|
let center = phantom.bounds().center();
|
||||||
phantom.animate({
|
phantom.animate({
|
||||||
width: 0,
|
width: 0,
|
||||||
height: 0,
|
height: 0,
|
||||||
top: phantom.position().x + phantom.height()/2,
|
top: center.y,
|
||||||
left: phantom.position().y + phantom.width()/2
|
left: center.x
|
||||||
}, {
|
}, {
|
||||||
duration: 300,
|
duration: 300,
|
||||||
complete: function() {
|
complete: function() {
|
||||||
|
|
|
@ -3,37 +3,41 @@
|
||||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||||
**/
|
**/
|
||||||
|
|
||||||
|
var gTests = [
|
||||||
|
{
|
||||||
|
name: "normal search (search service)",
|
||||||
|
testText: "test search",
|
||||||
|
searchURL: Services.search.originalDefaultEngine.getSubmission("test search").uri.spec
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "?-prefixed search (search service)",
|
||||||
|
testText: "? foo ",
|
||||||
|
searchURL: Services.search.originalDefaultEngine.getSubmission("foo").uri.spec
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "normal search (keyword.url)",
|
||||||
|
testText: "test search",
|
||||||
|
keywordURLPref: "http://example.com/?q=",
|
||||||
|
searchURL: "http://example.com/?q=test+search"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "?-prefixed search (keyword.url)",
|
||||||
|
testText: "? foo ",
|
||||||
|
keywordURLPref: "http://example.com/?q=",
|
||||||
|
searchURL: "http://example.com/?q=foo"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "encoding test (keyword.url)",
|
||||||
|
testText: "test encoded+%/",
|
||||||
|
keywordURLPref: "http://example.com/?q=",
|
||||||
|
searchURL: "http://example.com/?q=test+encoded%2B%25%2F"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
function test() {
|
function test() {
|
||||||
waitForExplicitFinish();
|
waitForExplicitFinish();
|
||||||
|
|
||||||
let tab = gBrowser.selectedTab = gBrowser.addTab();
|
let windowObserver = {
|
||||||
let searchText = "test search";
|
|
||||||
|
|
||||||
let listener = {
|
|
||||||
onStateChange: function onLocationChange(webProgress, req, flags, status) {
|
|
||||||
ok(flags & Ci.nsIWebProgressListener.STATE_IS_DOCUMENT, "only notified for document");
|
|
||||||
|
|
||||||
// Only care about starts
|
|
||||||
if (!(flags & Ci.nsIWebProgressListener.STATE_START))
|
|
||||||
return;
|
|
||||||
|
|
||||||
ok(req instanceof Ci.nsIChannel, "req is a channel");
|
|
||||||
|
|
||||||
let searchURL = Services.search.originalDefaultEngine.getSubmission(searchText).uri.spec;
|
|
||||||
is(req.originalURI.spec, searchURL, "search URL was loaded");
|
|
||||||
info("Actual URI: " + req.URI.spec);
|
|
||||||
|
|
||||||
Services.ww.unregisterNotification(observer);
|
|
||||||
gBrowser.removeProgressListener(this);
|
|
||||||
executeSoon(function () {
|
|
||||||
gBrowser.removeTab(tab);
|
|
||||||
finish();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
gBrowser.addProgressListener(listener, Ci.nsIWebProgressListener.NOTIFY_STATE_DOCUMENT);
|
|
||||||
|
|
||||||
let observer = {
|
|
||||||
observe: function(aSubject, aTopic, aData) {
|
observe: function(aSubject, aTopic, aData) {
|
||||||
if (aTopic == "domwindowopened") {
|
if (aTopic == "domwindowopened") {
|
||||||
ok(false, "Alert window opened");
|
ok(false, "Alert window opened");
|
||||||
|
@ -42,19 +46,67 @@ function test() {
|
||||||
win.removeEventListener("load", arguments.callee, false);
|
win.removeEventListener("load", arguments.callee, false);
|
||||||
win.close();
|
win.close();
|
||||||
}, false);
|
}, false);
|
||||||
gBrowser.removeProgressListener(listener);
|
executeSoon(finish);
|
||||||
executeSoon(function () {
|
|
||||||
gBrowser.removeTab(tab);
|
|
||||||
finish();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
Services.ww.unregisterNotification(this);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Services.ww.registerNotification(observer);
|
|
||||||
|
Services.ww.registerNotification(windowObserver);
|
||||||
|
|
||||||
|
let tab = gBrowser.selectedTab = gBrowser.addTab();
|
||||||
|
|
||||||
|
let listener = {
|
||||||
|
onStateChange: function onLocationChange(webProgress, req, flags, status) {
|
||||||
|
// Only care about document starts
|
||||||
|
let docStart = Ci.nsIWebProgressListener.STATE_IS_DOCUMENT |
|
||||||
|
Ci.nsIWebProgressListener.STATE_START;
|
||||||
|
if (!(flags & docStart))
|
||||||
|
return;
|
||||||
|
|
||||||
|
info("received document start");
|
||||||
|
|
||||||
|
ok(req instanceof Ci.nsIChannel, "req is a channel");
|
||||||
|
is(req.originalURI.spec, gCurrTest.searchURL, "search URL was loaded");
|
||||||
|
info("Actual URI: " + req.URI.spec);
|
||||||
|
|
||||||
|
executeSoon(nextTest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gBrowser.addProgressListener(listener);
|
||||||
|
|
||||||
|
registerCleanupFunction(function () {
|
||||||
|
Services.ww.unregisterNotification(windowObserver);
|
||||||
|
|
||||||
|
gBrowser.removeProgressListener(listener);
|
||||||
|
gBrowser.removeTab(tab);
|
||||||
|
});
|
||||||
|
|
||||||
|
nextTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
var gCurrTest;
|
||||||
|
function nextTest() {
|
||||||
|
// Clear the pref before every test (and after the last)
|
||||||
|
try {
|
||||||
|
Services.prefs.clearUserPref("keyword.URL");
|
||||||
|
} catch(ex) {}
|
||||||
|
|
||||||
|
if (gTests.length) {
|
||||||
|
gCurrTest = gTests.shift();
|
||||||
|
doTest();
|
||||||
|
} else {
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function doTest() {
|
||||||
|
info("Running test: " + gCurrTest.name);
|
||||||
|
|
||||||
|
if (gCurrTest.keywordURLPref)
|
||||||
|
Services.prefs.setCharPref("keyword.URL", gCurrTest.keywordURLPref);
|
||||||
|
|
||||||
// Simulate a user entering search terms
|
// Simulate a user entering search terms
|
||||||
gURLBar.value = searchText;
|
gURLBar.value = gCurrTest.testText;
|
||||||
gURLBar.focus();
|
gURLBar.focus();
|
||||||
EventUtils.synthesizeKey("VK_RETURN", {});
|
EventUtils.synthesizeKey("VK_RETURN", {});
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,7 @@ _BROWSER_FILES = \
|
||||||
browser_tabview_apptabs.js \
|
browser_tabview_apptabs.js \
|
||||||
browser_tabview_bug580412.js \
|
browser_tabview_bug580412.js \
|
||||||
browser_tabview_bug587043.js \
|
browser_tabview_bug587043.js \
|
||||||
|
browser_tabview_bug587231.js \
|
||||||
browser_tabview_bug587990.js \
|
browser_tabview_bug587990.js \
|
||||||
browser_tabview_bug589324.js \
|
browser_tabview_bug589324.js \
|
||||||
browser_tabview_bug590606.js \
|
browser_tabview_bug590606.js \
|
||||||
|
@ -59,7 +60,9 @@ _BROWSER_FILES = \
|
||||||
browser_tabview_bug595804.js \
|
browser_tabview_bug595804.js \
|
||||||
browser_tabview_bug595930.js \
|
browser_tabview_bug595930.js \
|
||||||
browser_tabview_bug595943.js \
|
browser_tabview_bug595943.js \
|
||||||
|
browser_tabview_bug597399.js \
|
||||||
browser_tabview_bug598600.js \
|
browser_tabview_bug598600.js \
|
||||||
|
browser_tabview_bug599626.js \
|
||||||
browser_tabview_dragdrop.js \
|
browser_tabview_dragdrop.js \
|
||||||
browser_tabview_exit_button.js \
|
browser_tabview_exit_button.js \
|
||||||
browser_tabview_group.js \
|
browser_tabview_group.js \
|
||||||
|
@ -76,6 +79,7 @@ _BROWSER_FILES = \
|
||||||
head.js \
|
head.js \
|
||||||
search1.html \
|
search1.html \
|
||||||
search2.html \
|
search2.html \
|
||||||
|
test_bug599626.html \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
# compartments: test disabled
|
# compartments: test disabled
|
||||||
|
|
|
@ -0,0 +1,125 @@
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is tabview drag and drop test.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Mozilla Foundation.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Sean Dunn <seanedunn@yahoo.com>
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
let activeTab;
|
||||||
|
let testTab;
|
||||||
|
let testGroup;
|
||||||
|
let contentWindow;
|
||||||
|
|
||||||
|
function test() {
|
||||||
|
waitForExplicitFinish();
|
||||||
|
contentWindow = document.getElementById("tab-view").contentWindow;
|
||||||
|
|
||||||
|
// create new tab
|
||||||
|
testTab = gBrowser.addTab("http://mochi.test:8888/");
|
||||||
|
|
||||||
|
window.addEventListener("tabviewshown", onTabViewWindowLoaded, false);
|
||||||
|
TabView.toggle();
|
||||||
|
}
|
||||||
|
|
||||||
|
function onTabViewWindowLoaded() {
|
||||||
|
window.removeEventListener("tabviewshown", onTabViewWindowLoaded, false);
|
||||||
|
ok(TabView.isVisible(), "Tab View is visible");
|
||||||
|
|
||||||
|
// create group
|
||||||
|
let testGroupRect = new contentWindow.Rect(20, 20, 300, 300);
|
||||||
|
testGroup = new contentWindow.GroupItem([], { bounds: testGroupRect });
|
||||||
|
ok(testGroup.isEmpty(), "This group is empty");
|
||||||
|
|
||||||
|
// place tab in group
|
||||||
|
let testTabItem = testTab.tabItem;
|
||||||
|
|
||||||
|
if (testTabItem.parent)
|
||||||
|
testTabItem.parent.remove(testTabItem);
|
||||||
|
testGroup.add(testTabItem);
|
||||||
|
|
||||||
|
// record last update time of tab canvas
|
||||||
|
let initialUpdateTime = testTabItem._lastTabUpdateTime;
|
||||||
|
|
||||||
|
// simulate resize
|
||||||
|
let resizer = contentWindow.iQ('.iq-resizable-handle', testGroup.container)[0];
|
||||||
|
let offsetX = 100;
|
||||||
|
let offsetY = 100;
|
||||||
|
let delay = 500;
|
||||||
|
|
||||||
|
let funcChain = new Array();
|
||||||
|
funcChain.push(function() {
|
||||||
|
EventUtils.synthesizeMouse(
|
||||||
|
resizer, 1, 1, { type: "mousedown" }, contentWindow);
|
||||||
|
setTimeout(funcChain.shift(), delay);
|
||||||
|
});
|
||||||
|
// drag
|
||||||
|
for (let i = 4; i >= 0; i--) {
|
||||||
|
funcChain.push(function() {
|
||||||
|
EventUtils.synthesizeMouse(
|
||||||
|
resizer, Math.round(offsetX/4), Math.round(offsetY/4),
|
||||||
|
{ type: "mousemove" }, contentWindow);
|
||||||
|
setTimeout(funcChain.shift(), delay);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
funcChain.push(function() {
|
||||||
|
EventUtils.synthesizeMouse(resizer, 0, 0, { type: "mouseup" },
|
||||||
|
contentWindow);
|
||||||
|
setTimeout(funcChain.shift(), delay);
|
||||||
|
});
|
||||||
|
funcChain.push(function() {
|
||||||
|
// verify that update time has changed after last update
|
||||||
|
let lastTime = testTabItem._lastTabUpdateTime;
|
||||||
|
let hbTiming = contentWindow.TabItems._heartbeatTiming;
|
||||||
|
ok((lastTime - initialUpdateTime) > hbTiming, "Tab has been updated:"+lastTime+"-"+initialUpdateTime+">"+hbTiming);
|
||||||
|
|
||||||
|
// clean up
|
||||||
|
testGroup.remove(testTab.tabItem);
|
||||||
|
testTab.tabItem.close();
|
||||||
|
testGroup.close();
|
||||||
|
|
||||||
|
let currentTabs = contentWindow.TabItems.getItems();
|
||||||
|
ok(currentTabs[0], "A tab item exists to make active");
|
||||||
|
contentWindow.UI.setActiveTab(currentTabs[0]);
|
||||||
|
|
||||||
|
window.addEventListener("tabviewhidden", finishTest, false);
|
||||||
|
TabView.toggle();
|
||||||
|
});
|
||||||
|
setTimeout(funcChain.shift(), delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
function finishTest() {
|
||||||
|
window.removeEventListener("tabviewhidden", finishTest, false);
|
||||||
|
ok(!TabView.isVisible(), "Tab View is not visible");
|
||||||
|
|
||||||
|
finish();
|
||||||
|
}
|
|
@ -55,10 +55,10 @@ function onTabViewWindowLoaded() {
|
||||||
ok(searchButton, "Search button exists");
|
ok(searchButton, "Search button exists");
|
||||||
|
|
||||||
let onSearchEnabled = function() {
|
let onSearchEnabled = function() {
|
||||||
let search = contentWindow.document.getElementById("search");
|
|
||||||
ok(search.style.display != "none", "Search is enabled");
|
|
||||||
contentWindow.removeEventListener(
|
contentWindow.removeEventListener(
|
||||||
"tabviewsearchenabled", onSearchEnabled, false);
|
"tabviewsearchenabled", onSearchEnabled, false);
|
||||||
|
let search = contentWindow.document.getElementById("search");
|
||||||
|
ok(search.style.display != "none", "Search is enabled");
|
||||||
escapeTest(contentWindow);
|
escapeTest(contentWindow);
|
||||||
}
|
}
|
||||||
contentWindow.addEventListener("tabviewsearchenabled", onSearchEnabled,
|
contentWindow.addEventListener("tabviewsearchenabled", onSearchEnabled,
|
||||||
|
@ -70,21 +70,16 @@ function onTabViewWindowLoaded() {
|
||||||
|
|
||||||
function escapeTest(contentWindow) {
|
function escapeTest(contentWindow) {
|
||||||
let onSearchDisabled = function() {
|
let onSearchDisabled = function() {
|
||||||
let search = contentWindow.document.getElementById("search");
|
|
||||||
|
|
||||||
ok(search.style.display == "none", "Search is disabled");
|
|
||||||
|
|
||||||
contentWindow.removeEventListener(
|
contentWindow.removeEventListener(
|
||||||
"tabviewsearchdisabled", onSearchDisabled, false);
|
"tabviewsearchdisabled", onSearchDisabled, false);
|
||||||
|
|
||||||
|
let search = contentWindow.document.getElementById("search");
|
||||||
|
ok(search.style.display == "none", "Search is disabled");
|
||||||
toggleTabViewTest(contentWindow);
|
toggleTabViewTest(contentWindow);
|
||||||
}
|
}
|
||||||
contentWindow.addEventListener("tabviewsearchdisabled", onSearchDisabled,
|
contentWindow.addEventListener("tabviewsearchdisabled", onSearchDisabled,
|
||||||
false);
|
false);
|
||||||
// the search box focus()es in a function on the timeout queue, so we just
|
EventUtils.synthesizeKey("VK_ESCAPE", { type: "keypress" }, contentWindow);
|
||||||
// want to queue behind it.
|
|
||||||
setTimeout( function() {
|
|
||||||
EventUtils.synthesizeKey("VK_ESCAPE", {});
|
|
||||||
}, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleTabViewTest(contentWindow) {
|
function toggleTabViewTest(contentWindow) {
|
||||||
|
@ -92,14 +87,9 @@ function toggleTabViewTest(contentWindow) {
|
||||||
contentWindow.removeEventListener("tabviewhidden", onTabViewHidden, false);
|
contentWindow.removeEventListener("tabviewhidden", onTabViewHidden, false);
|
||||||
|
|
||||||
ok(!TabView.isVisible(), "Tab View is hidden");
|
ok(!TabView.isVisible(), "Tab View is hidden");
|
||||||
|
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
contentWindow.addEventListener("tabviewhidden", onTabViewHidden, false);
|
contentWindow.addEventListener("tabviewhidden", onTabViewHidden, false);
|
||||||
// When search is hidden, it focus()es on the background, so avert the
|
// Use keyboard shortcut to toggle back to browser view
|
||||||
// race condition by delaying ourselves on the timeout queue
|
EventUtils.synthesizeKey("e", { accelKey: true });
|
||||||
setTimeout( function() {
|
|
||||||
// Use keyboard shortcut to toggle back to browser view
|
|
||||||
EventUtils.synthesizeKey("e", { accelKey: true });
|
|
||||||
}, 0);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is a test for bug 597399.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Mozilla Foundation.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Raymond Lee <raymond@appcoast.com>
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
function test() {
|
||||||
|
waitForExplicitFinish();
|
||||||
|
|
||||||
|
window.addEventListener("tabviewshown", onTabViewWindowLoaded, false);
|
||||||
|
TabView.toggle();
|
||||||
|
}
|
||||||
|
|
||||||
|
function onTabViewWindowLoaded() {
|
||||||
|
window.removeEventListener("tabviewshown", onTabViewWindowLoaded, false);
|
||||||
|
|
||||||
|
let contentWindow = document.getElementById("tab-view").contentWindow;
|
||||||
|
let number = -1;
|
||||||
|
|
||||||
|
let onSearchEnabled = function() {
|
||||||
|
let searchBox = contentWindow.document.getElementById("searchbox");
|
||||||
|
is(searchBox.value, number, "The seach box matches the number: " + number);
|
||||||
|
contentWindow.hideSearch(null);
|
||||||
|
}
|
||||||
|
let onSearchDisabled = function() {
|
||||||
|
if (++number <= 9) {
|
||||||
|
EventUtils.synthesizeKey(String(number), { }, contentWindow);
|
||||||
|
} else {
|
||||||
|
contentWindow.removeEventListener(
|
||||||
|
"tabviewsearchenabled", onSearchEnabled, false);
|
||||||
|
contentWindow.removeEventListener(
|
||||||
|
"tabviewsearchdisabled", onSearchDisabled, false);
|
||||||
|
|
||||||
|
let endGame = function() {
|
||||||
|
window.removeEventListener("tabviewhidden", endGame, false);
|
||||||
|
|
||||||
|
ok(!TabView.isVisible(), "Tab View is hidden");
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
window.addEventListener("tabviewhidden", endGame, false);
|
||||||
|
TabView.toggle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
contentWindow.addEventListener(
|
||||||
|
"tabviewsearchenabled", onSearchEnabled, false);
|
||||||
|
contentWindow.addEventListener(
|
||||||
|
"tabviewsearchdisabled", onSearchDisabled, false);
|
||||||
|
|
||||||
|
onSearchDisabled();
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,194 @@
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is tabview bug 599626 test.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Mozilla Foundation.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Raymond Lee <raymond@appcoast.com>
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
let handleDialog;
|
||||||
|
|
||||||
|
function test() {
|
||||||
|
waitForExplicitFinish();
|
||||||
|
|
||||||
|
window.addEventListener("tabviewshown", onTabViewWindowLoaded, false);
|
||||||
|
TabView.toggle();
|
||||||
|
}
|
||||||
|
|
||||||
|
function onTabViewWindowLoaded() {
|
||||||
|
window.removeEventListener("tabviewshown", onTabViewWindowLoaded, false);
|
||||||
|
|
||||||
|
let contentWindow = document.getElementById("tab-view").contentWindow;
|
||||||
|
let groupItemOne = contentWindow.GroupItems.getActiveGroupItem();
|
||||||
|
|
||||||
|
// Create a group and make it active
|
||||||
|
let box = new contentWindow.Rect(10, 10, 300, 300);
|
||||||
|
let groupItemTwo = new contentWindow.GroupItem([], { bounds: box });
|
||||||
|
contentWindow.GroupItems.setActiveGroupItem(groupItemTwo);
|
||||||
|
|
||||||
|
let testTab =
|
||||||
|
gBrowser.addTab(
|
||||||
|
"http://mochi.test:8888/browser/browser/base/content/test/tabview/test_bug599626.html");
|
||||||
|
let browser = gBrowser.getBrowserForTab(testTab);
|
||||||
|
let onLoad = function() {
|
||||||
|
browser.removeEventListener("load", onLoad, true);
|
||||||
|
|
||||||
|
testStayOnPage(contentWindow, groupItemOne, groupItemTwo);
|
||||||
|
}
|
||||||
|
browser.addEventListener("load", onLoad, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testStayOnPage(contentWindow, groupItemOne, groupItemTwo) {
|
||||||
|
setupAndRun(contentWindow, groupItemOne, groupItemTwo, function(doc) {
|
||||||
|
groupItemTwo.addSubscriber(groupItemTwo, "groupShown", function() {
|
||||||
|
groupItemTwo.removeSubscriber(groupItemTwo, "groupShown");
|
||||||
|
|
||||||
|
is(gBrowser.tabs.length, 2,
|
||||||
|
"The total number of tab is 2 when staying on the page");
|
||||||
|
is(contentWindow.TabItems.getItems().length, 2,
|
||||||
|
"The total number of tab items is 2 when staying on the page");
|
||||||
|
|
||||||
|
let onTabViewShown = function() {
|
||||||
|
window.removeEventListener("tabviewshown", onTabViewShown, false);
|
||||||
|
|
||||||
|
// start the next test
|
||||||
|
testLeavePage(contentWindow, groupItemOne, groupItemTwo);
|
||||||
|
};
|
||||||
|
window.addEventListener("tabviewshown", onTabViewShown, false);
|
||||||
|
TabView.toggle();
|
||||||
|
});
|
||||||
|
// stay on page
|
||||||
|
doc.documentElement.getButton("cancel").click();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function testLeavePage(contentWindow, groupItemOne, groupItemTwo) {
|
||||||
|
setupAndRun(contentWindow, groupItemOne, groupItemTwo, function(doc) {
|
||||||
|
// clean up and finish the test
|
||||||
|
groupItemTwo.addSubscriber(groupItemTwo, "close", function() {
|
||||||
|
groupItemTwo.removeSubscriber(groupItemTwo, "close");
|
||||||
|
|
||||||
|
is(gBrowser.tabs.length, 1,
|
||||||
|
"The total number of tab is 1 after leaving the page");
|
||||||
|
is(contentWindow.TabItems.getItems().length, 1,
|
||||||
|
"The total number of tab items is 1 after leaving the page");
|
||||||
|
|
||||||
|
let endGame = function() {
|
||||||
|
window.removeEventListener("tabviewhidden", endGame, false);
|
||||||
|
finish();
|
||||||
|
};
|
||||||
|
window.addEventListener("tabviewhidden", endGame, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Leave page
|
||||||
|
doc.documentElement.getButton("accept").click();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function setupAndRun(contentWindow, groupItemOne, groupItemTwo, callback) {
|
||||||
|
let closeButton = groupItemTwo.container.getElementsByClassName("close");
|
||||||
|
ok(closeButton[0], "Group close button exists");
|
||||||
|
// click the close button
|
||||||
|
EventUtils.sendMouseEvent({ type: "click" }, closeButton[0], contentWindow);
|
||||||
|
|
||||||
|
let onTabViewHidden = function() {
|
||||||
|
window.removeEventListener("tabviewhidden", onTabViewHidden, false);
|
||||||
|
|
||||||
|
handleDialog = function(doc) {
|
||||||
|
callback(doc);
|
||||||
|
};
|
||||||
|
startCallbackTimer();
|
||||||
|
};
|
||||||
|
window.addEventListener("tabviewhidden", onTabViewHidden, false);
|
||||||
|
|
||||||
|
let tabItem = groupItemOne.getChild(0);
|
||||||
|
tabItem.zoomIn();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copied from http://mxr.mozilla.org/mozilla-central/source/toolkit/components/places/tests/mochitest/prompt_common.js
|
||||||
|
let observer = {
|
||||||
|
QueryInterface : function (iid) {
|
||||||
|
const interfaces = [Ci.nsIObserver, Ci.nsISupports, Ci.nsISupportsWeakReference];
|
||||||
|
|
||||||
|
if (!interfaces.some( function(v) { return iid.equals(v) } ))
|
||||||
|
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
observe : function (subject, topic, data) {
|
||||||
|
let doc = getDialogDoc();
|
||||||
|
if (doc)
|
||||||
|
handleDialog(doc);
|
||||||
|
else
|
||||||
|
startCallbackTimer(); // try again in a bit
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function startCallbackTimer() {
|
||||||
|
// Delay before the callback twiddles the prompt.
|
||||||
|
const dialogDelay = 10;
|
||||||
|
|
||||||
|
// Use a timer to invoke a callback to twiddle the authentication dialog
|
||||||
|
let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
||||||
|
timer.init(observer, dialogDelay, Ci.nsITimer.TYPE_ONE_SHOT);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDialogDoc() {
|
||||||
|
// Find the <browser> which contains notifyWindow, by looking
|
||||||
|
// through all the open windows and all the <browsers> in each.
|
||||||
|
let wm = Cc["@mozilla.org/appshell/window-mediator;1"].
|
||||||
|
getService(Ci.nsIWindowMediator);
|
||||||
|
let enumerator = wm.getXULWindowEnumerator(null);
|
||||||
|
|
||||||
|
while (enumerator.hasMoreElements()) {
|
||||||
|
let win = enumerator.getNext();
|
||||||
|
let windowDocShell = win.QueryInterface(Ci.nsIXULWindow).docShell;
|
||||||
|
|
||||||
|
let containedDocShells = windowDocShell.getDocShellEnumerator(
|
||||||
|
Ci.nsIDocShellTreeItem.typeChrome,
|
||||||
|
Ci.nsIDocShell.ENUMERATE_FORWARDS);
|
||||||
|
while (containedDocShells.hasMoreElements()) {
|
||||||
|
// Get the corresponding document for this docshell
|
||||||
|
let childDocShell = containedDocShells.getNext();
|
||||||
|
// We don't want it if it's not done loading.
|
||||||
|
if (childDocShell.busyFlags != Ci.nsIDocShell.BUSY_FLAGS_NONE)
|
||||||
|
continue;
|
||||||
|
let childDoc = childDocShell.QueryInterface(Ci.nsIDocShell).
|
||||||
|
contentViewer.DOMDocument;
|
||||||
|
|
||||||
|
if (childDoc.location.href == "chrome://global/content/commonDialog.xul")
|
||||||
|
return childDoc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
<html>
|
||||||
|
<script>
|
||||||
|
window.onbeforeunload = function(event){
|
||||||
|
event.returnValue = 'Confirmation? ';
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<body>
|
||||||
|
Test page
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -200,6 +200,7 @@
|
||||||
<method name="onBeforeValueSet">
|
<method name="onBeforeValueSet">
|
||||||
<parameter name="aValue"/>
|
<parameter name="aValue"/>
|
||||||
<body><![CDATA[
|
<body><![CDATA[
|
||||||
|
this._hideOverLink();
|
||||||
this._value = aValue;
|
this._value = aValue;
|
||||||
var returnValue = aValue;
|
var returnValue = aValue;
|
||||||
var action = this._parseActionUrl(aValue);
|
var action = this._parseActionUrl(aValue);
|
||||||
|
@ -642,19 +643,21 @@
|
||||||
<method name="setOverLink">
|
<method name="setOverLink">
|
||||||
<parameter name="aURL"/>
|
<parameter name="aURL"/>
|
||||||
<body><![CDATA[
|
<body><![CDATA[
|
||||||
// If the over-link is already scheduled to appear or hide, cancel it.
|
this._cancelOverLinkDelayTimer();
|
||||||
if (this._overLinkDelayTimer) {
|
|
||||||
clearTimeout(this._overLinkDelayTimer);
|
// Hide the over-link immediately if necessary.
|
||||||
this._overLinkDelayTimer = null;
|
if (!aURL && (XULBrowserWindow.hideOverLinkImmediately ||
|
||||||
|
this._hideOverLinkImmediately)) {
|
||||||
|
this._setOverLinkState(null);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hide the over-link if aURL is falsey or if the URL bar is focused.
|
// If aURL is falsey, fade it out after a delay. This happens on
|
||||||
if (!aURL || this.focused) {
|
// mouseout for example.
|
||||||
|
if (!aURL) {
|
||||||
this._overLinkDelayTimer = setTimeout(function overLinkOut(self) {
|
this._overLinkDelayTimer = setTimeout(function overLinkOut(self) {
|
||||||
self._overLinkDelayTimer = null;
|
self._overLinkDelayTimer = null;
|
||||||
let style = window.getComputedStyle(self._overLinkBox, null);
|
self._setOverLinkState("fade-out");
|
||||||
self._overLinkTransitioning = style.opacity != 0;
|
|
||||||
self.removeAttribute("overlinkstate");
|
|
||||||
}, this._overLinkOutDelay, this);
|
}, this._overLinkOutDelay, this);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -662,8 +665,7 @@
|
||||||
// If it's in transition, update and show it immediately.
|
// If it's in transition, update and show it immediately.
|
||||||
if (this._overLinkTransitioning) {
|
if (this._overLinkTransitioning) {
|
||||||
this._updateOverLink(aURL);
|
this._updateOverLink(aURL);
|
||||||
this._overLinkTransitioning = false;
|
this._setOverLinkState("showing");
|
||||||
this.setAttribute("overlinkstate", "showing");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -673,13 +675,54 @@
|
||||||
this._overLinkDelayTimer = setTimeout(function overLinkIn(self) {
|
this._overLinkDelayTimer = setTimeout(function overLinkIn(self) {
|
||||||
self._overLinkDelayTimer = null;
|
self._overLinkDelayTimer = null;
|
||||||
self._updateOverLink(aURL);
|
self._updateOverLink(aURL);
|
||||||
let style = window.getComputedStyle(self._overLinkBox, null);
|
self._setOverLinkState("fade-in");
|
||||||
self._overLinkTransitioning = style.opacity != 1;
|
|
||||||
self.setAttribute("overlinkstate", "fade-in");
|
|
||||||
}, this._overLinkInDelay, this);
|
}, this._overLinkInDelay, this);
|
||||||
]]></body>
|
]]></body>
|
||||||
</method>
|
</method>
|
||||||
|
|
||||||
|
<method name="_hideOverLink">
|
||||||
|
<body><![CDATA[
|
||||||
|
this._hideOverLinkImmediately = true;
|
||||||
|
this.setOverLink("");
|
||||||
|
this._hideOverLinkImmediately = false;
|
||||||
|
]]></body>
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<method name="_cancelOverLinkDelayTimer">
|
||||||
|
<body><![CDATA[
|
||||||
|
if (this._overLinkDelayTimer) {
|
||||||
|
clearTimeout(this._overLinkDelayTimer);
|
||||||
|
this._overLinkDelayTimer = null;
|
||||||
|
}
|
||||||
|
]]></body>
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<method name="_setOverLinkState">
|
||||||
|
<parameter name="aVal"/>
|
||||||
|
<body><![CDATA[
|
||||||
|
switch (aVal) {
|
||||||
|
case "fade-in":
|
||||||
|
var style = window.getComputedStyle(this._overLinkBox);
|
||||||
|
this._overLinkTransitioning = style.opacity != 1;
|
||||||
|
this.setAttribute("overlinkstate", aVal);
|
||||||
|
break;
|
||||||
|
case "fade-out":
|
||||||
|
style = window.getComputedStyle(this._overLinkBox);
|
||||||
|
this._overLinkTransitioning = style.opacity != 0;
|
||||||
|
this.setAttribute("overlinkstate", aVal);
|
||||||
|
break;
|
||||||
|
case "showing":
|
||||||
|
this._overLinkTransitioning = false;
|
||||||
|
this.setAttribute("overlinkstate", aVal);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
this._overLinkTransitioning = false;
|
||||||
|
this.removeAttribute("overlinkstate");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
]]></body>
|
||||||
|
</method>
|
||||||
|
|
||||||
<method name="_updateOverLink">
|
<method name="_updateOverLink">
|
||||||
<parameter name="aURL"/>
|
<parameter name="aURL"/>
|
||||||
<body><![CDATA[
|
<body><![CDATA[
|
||||||
|
@ -761,8 +804,8 @@
|
||||||
]]></handler>
|
]]></handler>
|
||||||
|
|
||||||
<handler event="focus" phase="capturing"><![CDATA[
|
<handler event="focus" phase="capturing"><![CDATA[
|
||||||
|
this._hideOverLink();
|
||||||
this._hideURLTooltip();
|
this._hideURLTooltip();
|
||||||
this.setOverLink(null);
|
|
||||||
]]></handler>
|
]]></handler>
|
||||||
|
|
||||||
<handler event="dragover" phase="capturing" action="this.onDragOver(event, this);"/>
|
<handler event="dragover" phase="capturing" action="this.onDragOver(event, this);"/>
|
||||||
|
|
|
@ -45,8 +45,8 @@ function test() {
|
||||||
const HISTORY_SIDEBAR_TREE_ID = "historyTree";
|
const HISTORY_SIDEBAR_TREE_ID = "historyTree";
|
||||||
|
|
||||||
// Initialization.
|
// Initialization.
|
||||||
let ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
|
let os = Cc["@mozilla.org/observer-service;1"].
|
||||||
getService(Ci.nsIWindowWatcher);
|
getService(Ci.nsIObserverService);
|
||||||
let bs = PlacesUtils.bookmarks;
|
let bs = PlacesUtils.bookmarks;
|
||||||
let hs = PlacesUtils.history;
|
let hs = PlacesUtils.history;
|
||||||
let sidebarBox = document.getElementById("sidebar-box");
|
let sidebarBox = document.getElementById("sidebar-box");
|
||||||
|
@ -125,22 +125,20 @@ function test() {
|
||||||
preFunc();
|
preFunc();
|
||||||
|
|
||||||
function observer(aSubject, aTopic, aData) {
|
function observer(aSubject, aTopic, aData) {
|
||||||
if (aTopic != "domwindowopened")
|
info("alert dialog observed as expected");
|
||||||
return;
|
os.removeObserver(observer, "common-dialog-loaded");
|
||||||
ww.unregisterNotification(observer);
|
os.removeObserver(observer, "tabmodal-dialog-loaded");
|
||||||
let alertDialog = aSubject.QueryInterface(Ci.nsIDOMWindow);
|
|
||||||
alertDialog.addEventListener("load", function () {
|
aSubject.Dialog.ui.button0.click();
|
||||||
alertDialog.removeEventListener("load", arguments.callee, false);
|
|
||||||
info("alert dialog observed as expected");
|
executeSoon(function () {
|
||||||
executeSoon(function () {
|
|
||||||
alertDialog.close();
|
|
||||||
toggleSidebar(currentTest.sidebarName);
|
toggleSidebar(currentTest.sidebarName);
|
||||||
currentTest.cleanup();
|
currentTest.cleanup();
|
||||||
postFunc();
|
postFunc();
|
||||||
});
|
});
|
||||||
}, false);
|
|
||||||
}
|
}
|
||||||
ww.registerNotification(observer);
|
os.addObserver(observer, "common-dialog-loaded", false);
|
||||||
|
os.addObserver(observer, "tabmodal-dialog-loaded", false);
|
||||||
|
|
||||||
// Select the inserted places item.
|
// Select the inserted places item.
|
||||||
currentTest.selectNode(tree);
|
currentTest.selectNode(tree);
|
||||||
|
@ -160,7 +158,7 @@ function test() {
|
||||||
y = y.value + height.value / 2;
|
y = y.value + height.value / 2;
|
||||||
// Simulate the click.
|
// Simulate the click.
|
||||||
EventUtils.synthesizeMouse(tree.body, x, y, {}, doc.defaultView);
|
EventUtils.synthesizeMouse(tree.body, x, y, {}, doc.defaultView);
|
||||||
// Now, wait for the domwindowopened observer to catch the alert dialog.
|
// Now, wait for the observer to catch the alert dialog.
|
||||||
// If something goes wrong, the test will time out at this stage.
|
// If something goes wrong, the test will time out at this stage.
|
||||||
// Note that for the history sidebar, the URL itself is not opened,
|
// Note that for the history sidebar, the URL itself is not opened,
|
||||||
// and Places will show the load-js-data-url-error prompt as an alert
|
// and Places will show the load-js-data-url-error prompt as an alert
|
||||||
|
|
|
@ -69,10 +69,20 @@ function runNextTest() {
|
||||||
|
|
||||||
// set an empty state & run the next test, or finish
|
// set an empty state & run the next test, or finish
|
||||||
if (tests.length) {
|
if (tests.length) {
|
||||||
|
// Enumerate windows and close everything but our primary window. We can't
|
||||||
|
// use waitForFocus() because apparently it's buggy. See bug 599253.
|
||||||
|
var windowsEnum = Services.wm.getEnumerator("navigator:browser");
|
||||||
|
while (windowsEnum.hasMoreElements()) {
|
||||||
|
var currentWindow = windowsEnum.getNext();
|
||||||
|
if (currentWindow != window) {
|
||||||
|
currentWindow.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ss.setBrowserState(JSON.stringify({ windows: [{ tabs: [{ url: 'about:blank' }] }] }));
|
ss.setBrowserState(JSON.stringify({ windows: [{ tabs: [{ url: 'about:blank' }] }] }));
|
||||||
let test = tests.shift();
|
let currentTest = tests.shift();
|
||||||
info("running " + test.name);
|
info("running " + currentTest.name);
|
||||||
executeSoon(test);
|
executeSoon(currentTest);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ss.setBrowserState(stateBackup);
|
ss.setBrowserState(stateBackup);
|
||||||
|
|
|
@ -105,7 +105,7 @@
|
||||||
margin-top: -1px;
|
margin-top: -1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#main-window[sizemode="normal"] > #titlebar > #titlebar-content > #titlebar-buttonbox:-moz-lwtheme {
|
#main-window[sizemode="normal"] #titlebar-buttonbox:-moz-lwtheme {
|
||||||
margin-top: -2px;
|
margin-top: -2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -325,7 +325,7 @@
|
||||||
-moz-appearance: -moz-window-button-box;
|
-moz-appearance: -moz-window-button-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
#main-window[sizemode="maximized"] > #titlebar > #titlebar-content > #titlebar-buttonbox {
|
#main-window[sizemode="maximized"] #titlebar-buttonbox {
|
||||||
-moz-appearance: -moz-window-button-box-maximized;
|
-moz-appearance: -moz-window-button-box-maximized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -339,7 +339,7 @@
|
||||||
-moz-appearance: -moz-window-button-maximize;
|
-moz-appearance: -moz-window-button-maximize;
|
||||||
}
|
}
|
||||||
|
|
||||||
#main-window[sizemode="maximized"] > #titlebar > #titlebar-content > #titlebar-buttonbox > #titlebar-max {
|
#main-window[sizemode="maximized"] #titlebar-max {
|
||||||
-moz-appearance: -moz-window-button-restore;
|
-moz-appearance: -moz-window-button-restore;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1412,10 +1412,6 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
|
||||||
padding-bottom: 1px;
|
padding-bottom: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tabbrowser-tabs:-moz-system-metric(touch-enabled) {
|
|
||||||
min-height: 7.3mozmm;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Tabs */
|
/* Tabs */
|
||||||
.tabbrowser-tab,
|
.tabbrowser-tab,
|
||||||
.tabs-newtab-button {
|
.tabs-newtab-button {
|
||||||
|
@ -1558,6 +1554,10 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
|
||||||
.tabs-newtab-button {
|
.tabs-newtab-button {
|
||||||
min-width: 10mozmm;
|
min-width: 10mozmm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tab-content {
|
||||||
|
min-height: -moz-calc(6.8mozmm - 7px); /* subtract borders from the desired height */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.tabbrowser-arrowscrollbox > .scrollbutton-up,
|
.tabbrowser-arrowscrollbox > .scrollbutton-up,
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
# ***** END LICENSE BLOCK *****
|
# ***** END LICENSE BLOCK *****
|
||||||
|
|
||||||
import socket
|
import socket
|
||||||
|
import SocketServer
|
||||||
import time, datetime
|
import time, datetime
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
@ -58,14 +59,14 @@ class FileError(Exception):
|
||||||
class DeviceManager:
|
class DeviceManager:
|
||||||
host = ''
|
host = ''
|
||||||
port = 0
|
port = 0
|
||||||
debug = 2
|
debug = 2
|
||||||
_redo = False
|
_redo = False
|
||||||
deviceRoot = None
|
deviceRoot = None
|
||||||
tempRoot = os.getcwd()
|
tempRoot = os.getcwd()
|
||||||
base_prompt = '\$\>'
|
base_prompt = '\$\>'
|
||||||
prompt_sep = '\x00'
|
prompt_sep = '\x00'
|
||||||
prompt_regex = '.*' + base_prompt + prompt_sep
|
prompt_regex = '.*' + base_prompt + prompt_sep
|
||||||
agentErrorRE = re.compile('^##AGENT-ERROR##.*')
|
agentErrorRE = re.compile('^##AGENT-WARNING##.*')
|
||||||
|
|
||||||
def __init__(self, host, port = 20701):
|
def __init__(self, host, port = 20701):
|
||||||
self.host = host
|
self.host = host
|
||||||
|
@ -272,7 +273,10 @@ class DeviceManager:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def mkDir(self, name):
|
def mkDir(self, name):
|
||||||
return self.sendCMD(['mkdr ' + name])
|
if (self.dirExists(name)):
|
||||||
|
return name
|
||||||
|
else:
|
||||||
|
return self.sendCMD(['mkdr ' + name])
|
||||||
|
|
||||||
# make directory structure on the device
|
# make directory structure on the device
|
||||||
def mkDirs(self, filename):
|
def mkDirs(self, filename):
|
||||||
|
@ -306,7 +310,9 @@ class DeviceManager:
|
||||||
match = ".*" + dirname + "$"
|
match = ".*" + dirname + "$"
|
||||||
dirre = re.compile(match)
|
dirre = re.compile(match)
|
||||||
data = self.sendCMD(['cd ' + dirname, 'cwd'])
|
data = self.sendCMD(['cd ' + dirname, 'cwd'])
|
||||||
if (data == None):
|
# Because this is a compound command, cd can fail while cwd can succeed,
|
||||||
|
# we should check for agent error directly
|
||||||
|
if (data == None or self.agentErrorRE.match(data) ):
|
||||||
return None
|
return None
|
||||||
retVal = self.stripPrompt(data)
|
retVal = self.stripPrompt(data)
|
||||||
data = retVal.split('\n')
|
data = retVal.split('\n')
|
||||||
|
@ -549,11 +555,12 @@ class DeviceManager:
|
||||||
# /reftest
|
# /reftest
|
||||||
# /mochitest
|
# /mochitest
|
||||||
def getDeviceRoot(self):
|
def getDeviceRoot(self):
|
||||||
if (not self.deviceRoot):
|
# This caching of deviceRoot is causing issues if things fail
|
||||||
data = self.sendCMD(['testroot'])
|
# if (not self.deviceRoot):
|
||||||
if (data == None):
|
data = self.sendCMD(['testroot'])
|
||||||
return '/tests'
|
if (data == None):
|
||||||
self.deviceRoot = self.stripPrompt(data).strip('\n') + '/tests'
|
return '/tests'
|
||||||
|
self.deviceRoot = self.stripPrompt(data).strip('\n') + '/tests'
|
||||||
|
|
||||||
if (not self.dirExists(self.deviceRoot)):
|
if (not self.dirExists(self.deviceRoot)):
|
||||||
self.mkDir(self.deviceRoot)
|
self.mkDir(self.deviceRoot)
|
||||||
|
@ -690,8 +697,8 @@ class DeviceManager:
|
||||||
Application bundle - path to the application bundle on the device
|
Application bundle - path to the application bundle on the device
|
||||||
Destination - destination directory of where application should be
|
Destination - destination directory of where application should be
|
||||||
installed to (optional)
|
installed to (optional)
|
||||||
Returns True or False depending on what we get back
|
Returns None for success, or output if known failure
|
||||||
TODO: we need a real way to know if this works or not
|
TODO: we need a better way to know if this works or not
|
||||||
"""
|
"""
|
||||||
def installApp(self, appBundlePath, destPath=None):
|
def installApp(self, appBundlePath, destPath=None):
|
||||||
cmd = 'inst ' + appBundlePath
|
cmd = 'inst ' + appBundlePath
|
||||||
|
@ -699,9 +706,13 @@ class DeviceManager:
|
||||||
cmd += ' ' + destPath
|
cmd += ' ' + destPath
|
||||||
data = self.sendCMD([cmd])
|
data = self.sendCMD([cmd])
|
||||||
if (data is None):
|
if (data is None):
|
||||||
return False
|
return None
|
||||||
else:
|
|
||||||
return True
|
f = re.compile('Failure')
|
||||||
|
for line in data.split():
|
||||||
|
if (f.match(line)):
|
||||||
|
return data
|
||||||
|
return None
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Uninstalls the named application from device and causes a reboot.
|
Uninstalls the named application from device and causes a reboot.
|
||||||
|
@ -714,9 +725,53 @@ class DeviceManager:
|
||||||
cmd = 'uninst ' + appName
|
cmd = 'uninst ' + appName
|
||||||
if installPath:
|
if installPath:
|
||||||
cmd += ' ' + installPath
|
cmd += ' ' + installPath
|
||||||
self.sendCMD([cmd])
|
data = self.sendCMD([cmd])
|
||||||
|
if (self.debug > 3): print "uninstallAppAndReboot: " + str(data)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
"""
|
||||||
|
Updates the application on the device.
|
||||||
|
Application bundle - path to the application bundle on the device
|
||||||
|
Process name of application - used to end the process if the applicaiton is
|
||||||
|
currently running
|
||||||
|
Destination - Destination directory to where the application should be
|
||||||
|
installed (optional)
|
||||||
|
ipAddr - IP address to await a callback ping to let us know that the device has updated
|
||||||
|
properly - defaults to current IP.
|
||||||
|
port - port to await a callback ping to let us know that the device has updated properly
|
||||||
|
defaults to 30000, and counts up from there if it finds a conflict
|
||||||
|
Returns True if succeeds, False if not
|
||||||
|
|
||||||
|
NOTE: We have no real way to know if the device gets updated or not due to the
|
||||||
|
reboot that the udpate call forces on us. We can't install our own heartbeat
|
||||||
|
listener here because we run the risk of racing with other heartbeat listeners.
|
||||||
|
"""
|
||||||
|
def updateApp(self, appBundlePath, processName=None, destPath=None, ipAddr=None, port=None):
|
||||||
|
status = None
|
||||||
|
cmd = 'updt '
|
||||||
|
if (processName == None):
|
||||||
|
# Then we pass '' for processName
|
||||||
|
cmd += "'' " + appBundlePath
|
||||||
|
else:
|
||||||
|
cmd += processName + ' ' + appBundlePath
|
||||||
|
|
||||||
|
if (destPath):
|
||||||
|
cmd += " " + destPath
|
||||||
|
|
||||||
|
ip, port = self.getCallbackIpAndPort(ipAddr, 30000)
|
||||||
|
|
||||||
|
cmd += " %s %s" % (ip, port)
|
||||||
|
|
||||||
|
if (self.debug > 3): print "updateApp using command: " + str(cmd)
|
||||||
|
|
||||||
|
# Set up our callback server
|
||||||
|
callbacksvr = callbackServer(ip, port, self.debug)
|
||||||
|
data = self.sendCMD([cmd])
|
||||||
|
status = callbacksvr.disconnect()
|
||||||
|
if (self.debug > 3): print "got status back: " + str(status)
|
||||||
|
|
||||||
|
return status
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return the current time on the device
|
return the current time on the device
|
||||||
"""
|
"""
|
||||||
|
@ -726,3 +781,112 @@ class DeviceManager:
|
||||||
return None
|
return None
|
||||||
return self.stripPrompt(data).strip('\n')
|
return self.stripPrompt(data).strip('\n')
|
||||||
|
|
||||||
|
"""
|
||||||
|
Connect the ipaddress and port for a callback ping. Defaults to current IP address
|
||||||
|
And ports starting at 30000.
|
||||||
|
NOTE: the detection for current IP address only works on Linux!
|
||||||
|
"""
|
||||||
|
def getCallbackIpAndPort(self, aIp, aPort):
|
||||||
|
ip = aIp
|
||||||
|
nettools = NetworkTools()
|
||||||
|
if (ip == None):
|
||||||
|
ip = nettools.getLanIp()
|
||||||
|
if (aPort != None):
|
||||||
|
port = nettools.findOpenPort(ip, aPort)
|
||||||
|
else:
|
||||||
|
port = nettools.findOpenPort(ip, 30000)
|
||||||
|
return ip, port
|
||||||
|
|
||||||
|
gCallbackData = ''
|
||||||
|
|
||||||
|
class callbackServer():
|
||||||
|
def __init__(self, ip, port, debuglevel):
|
||||||
|
self.ip = ip
|
||||||
|
self.port = port
|
||||||
|
self.connected = False
|
||||||
|
self.debug = debuglevel
|
||||||
|
if (self.debug > 3) : print "Creating server with " + str(ip) + ":" + str(port)
|
||||||
|
self.server = SocketServer.TCPServer((ip, port), self.myhandler)
|
||||||
|
self.server_thread = Thread(target=self.server.serve_forever)
|
||||||
|
self.server_thread.setDaemon(True)
|
||||||
|
self.server_thread.start()
|
||||||
|
|
||||||
|
def disconnect(self, step = 60, timeout = 600):
|
||||||
|
t = 0
|
||||||
|
if (self.debug > 3): print "Calling disconnect on callback server"
|
||||||
|
while t < timeout:
|
||||||
|
if (gCallbackData):
|
||||||
|
# Got the data back
|
||||||
|
if (self.debug > 3): print "Got data back from agent: " + str(gCallbackData)
|
||||||
|
break
|
||||||
|
time.sleep(step)
|
||||||
|
t += step
|
||||||
|
|
||||||
|
try:
|
||||||
|
if (self.debug > 3): print "Shutting down server now"
|
||||||
|
self.server.shutdown()
|
||||||
|
except:
|
||||||
|
print "Unable to shutdown callback server - check for a connection on port: " + str(self.port)
|
||||||
|
return gCallbackData
|
||||||
|
|
||||||
|
class myhandler(SocketServer.BaseRequestHandler):
|
||||||
|
def handle(self):
|
||||||
|
global gCallbackData
|
||||||
|
gCallbackData = self.request.recv(1024)
|
||||||
|
#print "Callback Handler got data: " + str(gCallbackData)
|
||||||
|
self.request.send("OK")
|
||||||
|
|
||||||
|
class NetworkTools:
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Utilities to get the local ip address
|
||||||
|
def getInterfaceIp(self, ifname):
|
||||||
|
if os.name != "nt":
|
||||||
|
import fcntl
|
||||||
|
import struct
|
||||||
|
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||||
|
return socket.inet_ntoa(fcntl.ioctl(
|
||||||
|
s.fileno(),
|
||||||
|
0x8915, # SIOCGIFADDR
|
||||||
|
struct.pack('256s', ifname[:15])
|
||||||
|
)[20:24])
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def getLanIp(self):
|
||||||
|
ip = socket.gethostbyname(socket.gethostname())
|
||||||
|
if ip.startswith("127.") and os.name != "nt":
|
||||||
|
interfaces = ["eth0","eth1","eth2","wlan0","wlan1","wifi0","ath0","ath1","ppp0"]
|
||||||
|
for ifname in interfaces:
|
||||||
|
try:
|
||||||
|
ip = self.getInterfaceIp(ifname)
|
||||||
|
break;
|
||||||
|
except IOError:
|
||||||
|
pass
|
||||||
|
return ip
|
||||||
|
|
||||||
|
# Gets an open port starting with the seed by incrementing by 1 each time
|
||||||
|
def findOpenPort(self, ip, seed):
|
||||||
|
try:
|
||||||
|
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||||
|
connected = False
|
||||||
|
if isinstance(seed, basestring):
|
||||||
|
seed = int(seed)
|
||||||
|
maxportnum = seed + 5000 # We will try at most 5000 ports to find an open one
|
||||||
|
while not connected:
|
||||||
|
try:
|
||||||
|
s.bind((ip, seed))
|
||||||
|
connected = True
|
||||||
|
s.close()
|
||||||
|
except:
|
||||||
|
if seed > maxportnum:
|
||||||
|
print "Could not find open port after checking 5000 ports"
|
||||||
|
raise
|
||||||
|
seed += 1
|
||||||
|
except:
|
||||||
|
print "Socket error trying to find open port"
|
||||||
|
|
||||||
|
return seed
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ import os
|
||||||
import socket
|
import socket
|
||||||
|
|
||||||
from automation import Automation
|
from automation import Automation
|
||||||
from devicemanager import DeviceManager
|
from devicemanager import DeviceManager, NetworkTools
|
||||||
|
|
||||||
class RemoteAutomation(Automation):
|
class RemoteAutomation(Automation):
|
||||||
_devicemanager = None
|
_devicemanager = None
|
||||||
|
@ -99,31 +99,9 @@ class RemoteAutomation(Automation):
|
||||||
# return app, ['--environ:NO_EM_RESTART=1'] + args
|
# return app, ['--environ:NO_EM_RESTART=1'] + args
|
||||||
return app, args
|
return app, args
|
||||||
|
|
||||||
# Utilities to get the local ip address
|
|
||||||
def getInterfaceIp(self, ifname):
|
|
||||||
if os.name != "nt":
|
|
||||||
import fcntl
|
|
||||||
import struct
|
|
||||||
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
||||||
return socket.inet_ntoa(fcntl.ioctl(
|
|
||||||
s.fileno(),
|
|
||||||
0x8915, # SIOCGIFADDR
|
|
||||||
struct.pack('256s', ifname[:15])
|
|
||||||
)[20:24])
|
|
||||||
else:
|
|
||||||
return None
|
|
||||||
|
|
||||||
def getLanIp(self):
|
def getLanIp(self):
|
||||||
ip = socket.gethostbyname(socket.gethostname())
|
nettools = NetworkTools()
|
||||||
if ip.startswith("127.") and os.name != "nt":
|
return nettools.getLanIp()
|
||||||
interfaces = ["eth0","eth1","eth2","wlan0","wlan1","wifi0","ath0","ath1","ppp0"]
|
|
||||||
for ifname in interfaces:
|
|
||||||
try:
|
|
||||||
ip = self.getInterfaceIp(ifname)
|
|
||||||
break;
|
|
||||||
except IOError:
|
|
||||||
pass
|
|
||||||
return ip
|
|
||||||
|
|
||||||
def Process(self, cmd, stdout = None, stderr = None, env = None, cwd = '.'):
|
def Process(self, cmd, stdout = None, stderr = None, env = None, cwd = '.'):
|
||||||
if stdout == None or stdout == -1:
|
if stdout == None or stdout == -1:
|
||||||
|
@ -176,4 +154,3 @@ class RemoteAutomation(Automation):
|
||||||
|
|
||||||
def kill(self):
|
def kill(self):
|
||||||
self.dm.killProcess(self.procName)
|
self.dm.killProcess(self.procName)
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
{
|
{
|
||||||
global:
|
global:
|
||||||
NSModule;
|
NSModule;
|
||||||
|
NSGetModule;
|
||||||
local: *;
|
local: *;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
EXPORTED {
|
EXPORTED {
|
||||||
global:
|
global:
|
||||||
NSModule;
|
NSModule;
|
||||||
|
NSGetModule;
|
||||||
local: *;
|
local: *;
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
{
|
||||||
|
global:
|
||||||
|
_malloc_postfork;
|
||||||
|
_malloc_prefork;
|
||||||
|
jemalloc_stats;
|
||||||
|
malloc_usable_size;
|
||||||
|
posix_memalign;
|
||||||
|
free;
|
||||||
|
realloc;
|
||||||
|
calloc;
|
||||||
|
malloc;
|
||||||
|
memalign;
|
||||||
|
valloc;
|
||||||
|
__free_hook;
|
||||||
|
__malloc_hook;
|
||||||
|
__realloc_hook;
|
||||||
|
__memalign_hook;
|
||||||
|
local: *;
|
||||||
|
};
|
|
@ -106,12 +106,6 @@ nsIStringBundle *nsScriptSecurityManager::sStrBundle = nsnull;
|
||||||
JSRuntime *nsScriptSecurityManager::sRuntime = 0;
|
JSRuntime *nsScriptSecurityManager::sRuntime = 0;
|
||||||
PRBool nsScriptSecurityManager::sStrictFileOriginPolicy = PR_TRUE;
|
PRBool nsScriptSecurityManager::sStrictFileOriginPolicy = PR_TRUE;
|
||||||
|
|
||||||
// Info we need about the JSClasses used by XPConnects wrapped
|
|
||||||
// natives, to avoid having to QI to nsIXPConnectWrappedNative all the
|
|
||||||
// time when doing security checks.
|
|
||||||
static JSEqualityOp sXPCWrappedNativeEqualityOps;
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////
|
///////////////////////////
|
||||||
// Convenience Functions //
|
// Convenience Functions //
|
||||||
///////////////////////////
|
///////////////////////////
|
||||||
|
@ -2414,11 +2408,8 @@ nsScriptSecurityManager::doGetObjectPrincipal(JSObject *aObj
|
||||||
do {
|
do {
|
||||||
// Note: jsClass is set before this loop, and also at the
|
// Note: jsClass is set before this loop, and also at the
|
||||||
// *end* of this loop.
|
// *end* of this loop.
|
||||||
|
|
||||||
// NOTE: These class and equality hook checks better match
|
|
||||||
// what IS_WRAPPER_CLASS() does in xpconnect!
|
|
||||||
|
|
||||||
if (jsClass->ext.equality == js::Valueify(sXPCWrappedNativeEqualityOps)) {
|
if (IS_WRAPPER_CLASS(jsClass)) {
|
||||||
result = sXPConnect->GetPrincipal(aObj,
|
result = sXPConnect->GetPrincipal(aObj,
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
aAllowShortCircuit
|
aAllowShortCircuit
|
||||||
|
@ -3423,7 +3414,6 @@ nsresult nsScriptSecurityManager::Init()
|
||||||
JS_SetRuntimeSecurityCallbacks(sRuntime, &securityCallbacks);
|
JS_SetRuntimeSecurityCallbacks(sRuntime, &securityCallbacks);
|
||||||
NS_ASSERTION(!oldcallbacks, "Someone else set security callbacks!");
|
NS_ASSERTION(!oldcallbacks, "Someone else set security callbacks!");
|
||||||
|
|
||||||
sXPConnect->GetXPCWrappedNativeJSClassInfo(&sXPCWrappedNativeEqualityOps);
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,6 @@ VPATH = @srcdir@
|
||||||
|
|
||||||
include $(DEPTH)/config/autoconf.mk
|
include $(DEPTH)/config/autoconf.mk
|
||||||
|
|
||||||
DIRS = mochitest browser
|
DIRS = mochitest
|
||||||
|
|
||||||
include $(topsrcdir)/config/rules.mk
|
include $(topsrcdir)/config/rules.mk
|
||||||
|
|
|
@ -1,54 +0,0 @@
|
||||||
#
|
|
||||||
# ***** BEGIN LICENSE BLOCK *****
|
|
||||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
|
||||||
#
|
|
||||||
# The contents of this file are subject to the Mozilla Public License Version
|
|
||||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
|
||||||
# the License. You may obtain a copy of the License at
|
|
||||||
# http://www.mozilla.org/MPL/
|
|
||||||
#
|
|
||||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
||||||
# for the specific language governing rights and limitations under the
|
|
||||||
# License.
|
|
||||||
#
|
|
||||||
# The Original Code is mozilla.org code.
|
|
||||||
#
|
|
||||||
# The Initial Developer of the Original Code is
|
|
||||||
# the Mozilla Foundation.
|
|
||||||
# Portions created by the Initial Developer are Copyright (C) 2010
|
|
||||||
# the Initial Developer. All Rights Reserved.
|
|
||||||
#
|
|
||||||
# Contributor(s):
|
|
||||||
# Justin Lebar <justin.lebar@gmail.com>
|
|
||||||
#
|
|
||||||
# Alternatively, the contents of this file may be used under the terms of
|
|
||||||
# either of the GNU General Public License Version 2 or later (the "GPL"),
|
|
||||||
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
|
||||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
|
||||||
# of those above. If you wish to allow use of your version of this file only
|
|
||||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
|
||||||
# use your version of this file under the terms of the MPL, indicate your
|
|
||||||
# decision by deleting the provisions above and replace them with the notice
|
|
||||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
|
||||||
# the provisions above, a recipient may use your version of this file under
|
|
||||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
|
||||||
#
|
|
||||||
# ***** END LICENSE BLOCK *****
|
|
||||||
|
|
||||||
DEPTH = ../../..
|
|
||||||
topsrcdir = @top_srcdir@
|
|
||||||
srcdir = @srcdir@
|
|
||||||
VPATH = @srcdir@
|
|
||||||
relativesrcdir = caps/tests/browser
|
|
||||||
|
|
||||||
include $(DEPTH)/config/autoconf.mk
|
|
||||||
|
|
||||||
include $(topsrcdir)/config/rules.mk
|
|
||||||
|
|
||||||
_BROWSER_TEST_FILES = \
|
|
||||||
browser_bug571289.js \
|
|
||||||
$(NULL)
|
|
||||||
|
|
||||||
libs:: $(_BROWSER_TEST_FILES)
|
|
||||||
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
|
|
|
@ -1,24 +0,0 @@
|
||||||
function test() {
|
|
||||||
// Access an xpcom component from off the main thread.
|
|
||||||
|
|
||||||
let threadman = Components.classes["@mozilla.org/thread-manager;1"].
|
|
||||||
getService(Ci.nsIThreadManager);
|
|
||||||
let thread = threadman.newThread(0);
|
|
||||||
|
|
||||||
thread.dispatch(
|
|
||||||
function() {
|
|
||||||
// Get another handle on the thread manager, this time from within the
|
|
||||||
// thread we created.
|
|
||||||
let threadman2 = Components.classes["@mozilla.org/thread-manager;1"].
|
|
||||||
getService(Ci.nsIThreadManager);
|
|
||||||
|
|
||||||
// Now do something with the thread manager. It doesn't really matter
|
|
||||||
// what we do.
|
|
||||||
if (threadman2.mainThread == threadman2.currentThread)
|
|
||||||
ok(false, "Shouldn't be on the main thread.");
|
|
||||||
|
|
||||||
}, 1); // dispatch sync
|
|
||||||
|
|
||||||
thread.shutdown();
|
|
||||||
ok(true, "Done!");
|
|
||||||
}
|
|
|
@ -171,6 +171,7 @@ VPX_ASM_SUFFIX = @VPX_ASM_SUFFIX@
|
||||||
VPX_X86_ASM = @VPX_X86_ASM@
|
VPX_X86_ASM = @VPX_X86_ASM@
|
||||||
VPX_ARM_ASM = @VPX_ARM_ASM@
|
VPX_ARM_ASM = @VPX_ARM_ASM@
|
||||||
NS_PRINTING = @NS_PRINTING@
|
NS_PRINTING = @NS_PRINTING@
|
||||||
|
MOZ_PDF_PRINTING = @MOZ_PDF_PRINTING@
|
||||||
MOZ_CRASHREPORTER = @MOZ_CRASHREPORTER@
|
MOZ_CRASHREPORTER = @MOZ_CRASHREPORTER@
|
||||||
MOZ_HELP_VIEWER = @MOZ_HELP_VIEWER@
|
MOZ_HELP_VIEWER = @MOZ_HELP_VIEWER@
|
||||||
MOC= @MOC@
|
MOC= @MOC@
|
||||||
|
@ -195,6 +196,7 @@ RM = rm -f
|
||||||
MOZ_UI_LOCALE = @MOZ_UI_LOCALE@
|
MOZ_UI_LOCALE = @MOZ_UI_LOCALE@
|
||||||
|
|
||||||
MOZ_COMPONENTS_VERSION_SCRIPT_LDFLAGS = @MOZ_COMPONENTS_VERSION_SCRIPT_LDFLAGS@
|
MOZ_COMPONENTS_VERSION_SCRIPT_LDFLAGS = @MOZ_COMPONENTS_VERSION_SCRIPT_LDFLAGS@
|
||||||
|
MOZ_JEMALLOC_STANDALONE_GLUE_LDOPTS = @MOZ_JEMALLOC_STANDALONE_GLUE_LDOPTS@
|
||||||
MOZ_COMPONENT_NSPR_LIBS=@MOZ_COMPONENT_NSPR_LIBS@
|
MOZ_COMPONENT_NSPR_LIBS=@MOZ_COMPONENT_NSPR_LIBS@
|
||||||
|
|
||||||
MOZ_FIX_LINK_PATHS=@MOZ_FIX_LINK_PATHS@
|
MOZ_FIX_LINK_PATHS=@MOZ_FIX_LINK_PATHS@
|
||||||
|
|
|
@ -162,6 +162,11 @@ MOZ_WIDGET_SUPPORT_LIBS = $(DIST)/lib/$(LIB_PREFIX)widgetsupport_s.$(LIB_SUFF
|
||||||
ifdef MOZ_MEMORY
|
ifdef MOZ_MEMORY
|
||||||
ifneq (,$(filter-out WINNT WINCE,$(OS_ARCH)))
|
ifneq (,$(filter-out WINNT WINCE,$(OS_ARCH)))
|
||||||
JEMALLOC_LIBS = $(MKSHLIB_FORCE_ALL) $(call EXPAND_MOZLIBNAME,jemalloc) $(MKSHLIB_UNFORCE_ALL)
|
JEMALLOC_LIBS = $(MKSHLIB_FORCE_ALL) $(call EXPAND_MOZLIBNAME,jemalloc) $(MKSHLIB_UNFORCE_ALL)
|
||||||
|
# If we are linking jemalloc into a program, we want the jemalloc symbols
|
||||||
|
# to be exported
|
||||||
|
ifneq (,$(SIMPLE_PROGRAMS)$(PROGRAM))
|
||||||
|
JEMALLOC_LIBS += $(MOZ_JEMALLOC_STANDALONE_GLUE_LDOPTS)
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
40
configure.in
40
configure.in
|
@ -301,8 +301,8 @@ if test "$target" = "arm-android-eabi" ; then
|
||||||
STRIP="$android_toolchain"/bin/arm-eabi-strip
|
STRIP="$android_toolchain"/bin/arm-eabi-strip
|
||||||
|
|
||||||
CPPFLAGS="-I$android_platform/usr/include $CPPFLAGS"
|
CPPFLAGS="-I$android_platform/usr/include $CPPFLAGS"
|
||||||
CFLAGS="-mandroid -I$android_platform/usr/include -msoft-float -fno-short-enums -fno-exceptions -march=armv5te -mthumb-interwork $CFLAGS"
|
CFLAGS="-mandroid -I$android_platform/usr/include -msoft-float -fno-short-enums -fno-exceptions $CFLAGS"
|
||||||
CXXFLAGS="-mandroid -I$android_platform/usr/include -msoft-float -fno-short-enums -fno-exceptions -march=armv5te -mthumb-interwork $CXXFLAGS"
|
CXXFLAGS="-mandroid -I$android_platform/usr/include -msoft-float -fno-short-enums -fno-exceptions $CXXFLAGS"
|
||||||
|
|
||||||
dnl Add -llog by default, since we use it all over the place.
|
dnl Add -llog by default, since we use it all over the place.
|
||||||
dnl Add --allow-shlib-undefined, because libGLESv2 links to an
|
dnl Add --allow-shlib-undefined, because libGLESv2 links to an
|
||||||
|
@ -2415,7 +2415,7 @@ ia64*-hpux*)
|
||||||
LIBXUL_LIBS='$(LIBXUL_DIST)/lib/xpcom.lib $(LIBXUL_DIST)/lib/xul.lib $(LIBXUL_DIST)/lib/mozalloc.lib'
|
LIBXUL_LIBS='$(LIBXUL_DIST)/lib/xpcom.lib $(LIBXUL_DIST)/lib/xul.lib $(LIBXUL_DIST)/lib/mozalloc.lib'
|
||||||
MOZ_COMPONENT_NSPR_LIBS='$(NSPR_LIBS)'
|
MOZ_COMPONENT_NSPR_LIBS='$(NSPR_LIBS)'
|
||||||
if test $_MSC_VER -ge 1400; then
|
if test $_MSC_VER -ge 1400; then
|
||||||
LDFLAGS="$LDFLAGS -NXCOMPAT"
|
LDFLAGS="$LDFLAGS -LARGEADDRESSAWARE -NXCOMPAT"
|
||||||
dnl For profile-guided optimization
|
dnl For profile-guided optimization
|
||||||
PROFILE_GEN_CFLAGS="-GL"
|
PROFILE_GEN_CFLAGS="-GL"
|
||||||
PROFILE_GEN_LDFLAGS="-LTCG:PGINSTRUMENT"
|
PROFILE_GEN_LDFLAGS="-LTCG:PGINSTRUMENT"
|
||||||
|
@ -2893,11 +2893,13 @@ esac
|
||||||
AC_SUBST(NO_LD_ARCHIVE_FLAGS)
|
AC_SUBST(NO_LD_ARCHIVE_FLAGS)
|
||||||
|
|
||||||
dnl ========================================================
|
dnl ========================================================
|
||||||
dnl = Flags to strip unused symbols from .so components
|
dnl = Flags to strip unused symbols from .so components and
|
||||||
|
dnl = to export jemalloc symbols when linking a program
|
||||||
dnl ========================================================
|
dnl ========================================================
|
||||||
case "$target" in
|
case "$target" in
|
||||||
*-linux*|*-kfreebsd*-gnu|*-gnu*)
|
*-linux*|*-kfreebsd*-gnu|*-gnu*)
|
||||||
MOZ_COMPONENTS_VERSION_SCRIPT_LDFLAGS='-Wl,--version-script -Wl,$(BUILD_TOOLS)/gnu-ld-scripts/components-version-script'
|
MOZ_COMPONENTS_VERSION_SCRIPT_LDFLAGS='-Wl,--version-script -Wl,$(BUILD_TOOLS)/gnu-ld-scripts/components-version-script'
|
||||||
|
MOZ_JEMALLOC_STANDALONE_GLUE_LDOPTS='-rdynamic -Wl,--version-script -Wl,$(BUILD_TOOLS)/gnu-ld-scripts/jemalloc-standalone-linkage-version-script'
|
||||||
;;
|
;;
|
||||||
*-solaris*)
|
*-solaris*)
|
||||||
if test -z "$GNU_CC"; then
|
if test -z "$GNU_CC"; then
|
||||||
|
@ -4992,6 +4994,7 @@ MOZ_XTF=1
|
||||||
MOZ_XUL=1
|
MOZ_XUL=1
|
||||||
MOZ_ZIPWRITER=1
|
MOZ_ZIPWRITER=1
|
||||||
NS_PRINTING=1
|
NS_PRINTING=1
|
||||||
|
MOZ_PDF_PRINTING=
|
||||||
MOZ_DISABLE_DOMCRYPTO=
|
MOZ_DISABLE_DOMCRYPTO=
|
||||||
NSS_DISABLE_DBM=
|
NSS_DISABLE_DBM=
|
||||||
NECKO_WIFI=1
|
NECKO_WIFI=1
|
||||||
|
@ -5031,7 +5034,6 @@ case "${target}" in
|
||||||
NSS_DISABLE_DBM=1
|
NSS_DISABLE_DBM=1
|
||||||
USE_ARM_KUSER=1
|
USE_ARM_KUSER=1
|
||||||
MOZ_INSTALLER=
|
MOZ_INSTALLER=
|
||||||
NS_PRINTING=
|
|
||||||
NECKO_WIFI=
|
NECKO_WIFI=
|
||||||
MOZ_THUMB2=1
|
MOZ_THUMB2=1
|
||||||
MOZ_THEME_FASTSTRIPE=1
|
MOZ_THEME_FASTSTRIPE=1
|
||||||
|
@ -5187,6 +5189,7 @@ cairo-windows)
|
||||||
NS_PRINTING=
|
NS_PRINTING=
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
MOZ_PDF_PRINTING=1
|
||||||
;;
|
;;
|
||||||
|
|
||||||
cairo-gtk2|cairo-gtk2-x11)
|
cairo-gtk2|cairo-gtk2-x11)
|
||||||
|
@ -5203,6 +5206,7 @@ cairo-gtk2|cairo-gtk2-x11)
|
||||||
TK_CFLAGS='$(MOZ_GTK2_CFLAGS)'
|
TK_CFLAGS='$(MOZ_GTK2_CFLAGS)'
|
||||||
TK_LIBS='$(MOZ_GTK2_LIBS)'
|
TK_LIBS='$(MOZ_GTK2_LIBS)'
|
||||||
AC_DEFINE(MOZ_WIDGET_GTK2)
|
AC_DEFINE(MOZ_WIDGET_GTK2)
|
||||||
|
MOZ_PDF_PRINTING=1
|
||||||
;;
|
;;
|
||||||
|
|
||||||
cairo-gtk2-dfb)
|
cairo-gtk2-dfb)
|
||||||
|
@ -5220,6 +5224,7 @@ cairo-gtk2-dfb)
|
||||||
AC_MSG_WARN([Disabling X when DirectFB is specified.])
|
AC_MSG_WARN([Disabling X when DirectFB is specified.])
|
||||||
no_x=yes
|
no_x=yes
|
||||||
fi
|
fi
|
||||||
|
MOZ_PDF_PRINTING=1
|
||||||
;;
|
;;
|
||||||
|
|
||||||
cairo-qt)
|
cairo-qt)
|
||||||
|
@ -5237,6 +5242,7 @@ cairo-qt)
|
||||||
TK_CFLAGS='$(MOZ_QT_CFLAGS)'
|
TK_CFLAGS='$(MOZ_QT_CFLAGS)'
|
||||||
TK_LIBS='$(MOZ_QT_LIBS)'
|
TK_LIBS='$(MOZ_QT_LIBS)'
|
||||||
AC_DEFINE(MOZ_WIDGET_QT)
|
AC_DEFINE(MOZ_WIDGET_QT)
|
||||||
|
MOZ_PDF_PRINTING=1
|
||||||
;;
|
;;
|
||||||
|
|
||||||
cairo-beos)
|
cairo-beos)
|
||||||
|
@ -5251,6 +5257,7 @@ cairo-os2)
|
||||||
USE_FC_FREETYPE=1
|
USE_FC_FREETYPE=1
|
||||||
TK_CFLAGS='$(MOZ_CAIRO_CFLAGS)'
|
TK_CFLAGS='$(MOZ_CAIRO_CFLAGS)'
|
||||||
TK_LIBS='$(MOZ_CAIRO_LIBS)'
|
TK_LIBS='$(MOZ_CAIRO_LIBS)'
|
||||||
|
MOZ_PDF_PRINTING=1
|
||||||
;;
|
;;
|
||||||
|
|
||||||
cairo-cocoa)
|
cairo-cocoa)
|
||||||
|
@ -5271,11 +5278,20 @@ cairo-cocoa)
|
||||||
cairo-android)
|
cairo-android)
|
||||||
AC_DEFINE(MOZ_WIDGET_ANDROID)
|
AC_DEFINE(MOZ_WIDGET_ANDROID)
|
||||||
MOZ_WIDGET_TOOLKIT=android
|
MOZ_WIDGET_TOOLKIT=android
|
||||||
|
TK_CFLAGS='$(MOZ_CAIRO_CFLAGS)'
|
||||||
|
TK_LIBS='$(MOZ_CAIRO_LIBS)'
|
||||||
MOZ_WEBGL=1
|
MOZ_WEBGL=1
|
||||||
|
MOZ_PDF_PRINTING=1
|
||||||
;;
|
;;
|
||||||
|
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
AC_SUBST(MOZ_PDF_PRINTING)
|
||||||
|
if test "$MOZ_PDF_PRINTING"; then
|
||||||
|
PDF_SURFACE_FEATURE="#define CAIRO_HAS_PDF_SURFACE 1"
|
||||||
|
AC_DEFINE(MOZ_PDF_PRINTING)
|
||||||
|
fi
|
||||||
|
|
||||||
if test "$MOZ_ENABLE_XREMOTE"; then
|
if test "$MOZ_ENABLE_XREMOTE"; then
|
||||||
AC_DEFINE(MOZ_ENABLE_XREMOTE)
|
AC_DEFINE(MOZ_ENABLE_XREMOTE)
|
||||||
fi
|
fi
|
||||||
|
@ -7098,6 +7114,16 @@ if test -n "$MOZ_THUMB2"; then
|
||||||
AC_MSG_ERROR([--enable-thumb2 is not supported for non-ARM CPU architectures])
|
AC_MSG_ERROR([--enable-thumb2 is not supported for non-ARM CPU architectures])
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
else
|
||||||
|
case "$target_cpu" in
|
||||||
|
arm*)
|
||||||
|
if test "$GNU_CC"; then
|
||||||
|
CFLAGS="$CFLAGS -march=armv5te -mthumb-interwork -Wa, -march=armv5te -Wa, -mthumb-interwork"
|
||||||
|
CXXFLAGS="$CXXFLAGS -march=armv5te -mthumb-interwork -Wa, -march=armv5te -Wa, -mthumb-interwork"
|
||||||
|
ASFLAGS="$ASFLAGS -march=armv5te -mthumb-interwork"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
||||||
AC_SUBST(MOZ_THUMB2)
|
AC_SUBST(MOZ_THUMB2)
|
||||||
|
@ -8499,7 +8525,6 @@ if test "$MOZ_TREE_CAIRO"; then
|
||||||
XLIB_SURFACE_FEATURE="#define CAIRO_HAS_XLIB_SURFACE 1"
|
XLIB_SURFACE_FEATURE="#define CAIRO_HAS_XLIB_SURFACE 1"
|
||||||
XLIB_XRENDER_SURFACE_FEATURE="#define CAIRO_HAS_XLIB_XRENDER_SURFACE 1"
|
XLIB_XRENDER_SURFACE_FEATURE="#define CAIRO_HAS_XLIB_XRENDER_SURFACE 1"
|
||||||
PS_SURFACE_FEATURE="#define CAIRO_HAS_PS_SURFACE 1"
|
PS_SURFACE_FEATURE="#define CAIRO_HAS_PS_SURFACE 1"
|
||||||
PDF_SURFACE_FEATURE="#define CAIRO_HAS_PDF_SURFACE 1"
|
|
||||||
FT_FONT_FEATURE="#define CAIRO_HAS_FT_FONT 1"
|
FT_FONT_FEATURE="#define CAIRO_HAS_FT_FONT 1"
|
||||||
MOZ_ENABLE_CAIRO_FT=1
|
MOZ_ENABLE_CAIRO_FT=1
|
||||||
CAIRO_FT_CFLAGS="$FT2_CFLAGS"
|
CAIRO_FT_CFLAGS="$FT2_CFLAGS"
|
||||||
|
@ -8538,12 +8563,10 @@ if test "$MOZ_TREE_CAIRO"; then
|
||||||
AC_CHECK_HEADER(d3d10.h, MOZ_ENABLE_D3D10_LAYER=1)
|
AC_CHECK_HEADER(d3d10.h, MOZ_ENABLE_D3D10_LAYER=1)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
PDF_SURFACE_FEATURE="#define CAIRO_HAS_PDF_SURFACE 1"
|
|
||||||
fi
|
fi
|
||||||
if test "$MOZ_WIDGET_TOOLKIT" = "os2"; then
|
if test "$MOZ_WIDGET_TOOLKIT" = "os2"; then
|
||||||
OS2_SURFACE_FEATURE="#define CAIRO_HAS_OS2_SURFACE 1"
|
OS2_SURFACE_FEATURE="#define CAIRO_HAS_OS2_SURFACE 1"
|
||||||
FT_FONT_FEATURE="#define CAIRO_HAS_FT_FONT 1"
|
FT_FONT_FEATURE="#define CAIRO_HAS_FT_FONT 1"
|
||||||
PDF_SURFACE_FEATURE="#define CAIRO_HAS_PDF_SURFACE 1"
|
|
||||||
MOZ_ENABLE_CAIRO_FT=1
|
MOZ_ENABLE_CAIRO_FT=1
|
||||||
CAIRO_FT_CFLAGS="-I${MZFTCFGFT2}/include"
|
CAIRO_FT_CFLAGS="-I${MZFTCFGFT2}/include"
|
||||||
CAIRO_FT_LIBS="-L${MZFTCFGFT2}/lib -lmozft -lmzfntcfg"
|
CAIRO_FT_LIBS="-L${MZFTCFGFT2}/lib -lmozft -lmzfntcfg"
|
||||||
|
@ -8924,6 +8947,7 @@ AC_SUBST(PKG_SKIP_STRIP)
|
||||||
AC_SUBST(USE_ELF_DYNSTR_GC)
|
AC_SUBST(USE_ELF_DYNSTR_GC)
|
||||||
AC_SUBST(INCREMENTAL_LINKER)
|
AC_SUBST(INCREMENTAL_LINKER)
|
||||||
AC_SUBST(MOZ_COMPONENTS_VERSION_SCRIPT_LDFLAGS)
|
AC_SUBST(MOZ_COMPONENTS_VERSION_SCRIPT_LDFLAGS)
|
||||||
|
AC_SUBST(MOZ_JEMALLOC_STANDALONE_GLUE_LDOPTS)
|
||||||
AC_SUBST(MOZ_COMPONENT_NSPR_LIBS)
|
AC_SUBST(MOZ_COMPONENT_NSPR_LIBS)
|
||||||
|
|
||||||
AC_SUBST(MOZ_FIX_LINK_PATHS)
|
AC_SUBST(MOZ_FIX_LINK_PATHS)
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
<script async src="data:">0</script>
|
|
@ -74,3 +74,4 @@ load 582601.html
|
||||||
load 575462.svg
|
load 575462.svg
|
||||||
load 595606-1.html
|
load 595606-1.html
|
||||||
load 595606-2.html
|
load 595606-2.html
|
||||||
|
load 606729-1.html
|
||||||
|
|
|
@ -42,6 +42,8 @@
|
||||||
#include "nsAString.h"
|
#include "nsAString.h"
|
||||||
#include "nsMargin.h"
|
#include "nsMargin.h"
|
||||||
|
|
||||||
|
class nsIInterfaceRequestor;
|
||||||
|
|
||||||
// {3682DD99-8560-44f4-9B8F-CCCE9D7B96FB}
|
// {3682DD99-8560-44f4-9B8F-CCCE9D7B96FB}
|
||||||
#define NS_ICONTENTUTILS_IID \
|
#define NS_ICONTENTUTILS_IID \
|
||||||
{ 0x3682dd99, 0x8560, 0x44f4, \
|
{ 0x3682dd99, 0x8560, 0x44f4, \
|
||||||
|
@ -71,4 +73,20 @@ public:
|
||||||
|
|
||||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIContentUtils, NS_ICONTENTUTILS_IID)
|
NS_DEFINE_STATIC_IID_ACCESSOR(nsIContentUtils, NS_ICONTENTUTILS_IID)
|
||||||
|
|
||||||
|
// {60083ad4-f7ed-488b-a706-bacb378fe1a5}
|
||||||
|
#define NS_ICONTENTUTILS2_IID \
|
||||||
|
{ 0x60083ad4, 0xf7ed, 0x488b, \
|
||||||
|
{ 0xa7, 0x06, 0xba, 0xcb, 0x37, 0x8f, 0xe1, 0xa5 } }
|
||||||
|
|
||||||
|
class nsIContentUtils2 : public nsISupports
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ICONTENTUTILS2_IID)
|
||||||
|
NS_DECL_ISUPPORTS
|
||||||
|
|
||||||
|
virtual nsIInterfaceRequestor* GetSameOriginChecker();
|
||||||
|
};
|
||||||
|
|
||||||
|
NS_DEFINE_STATIC_IID_ACCESSOR(nsIContentUtils2, NS_ICONTENTUTILS2_IID)
|
||||||
|
|
||||||
#endif /* nsIContentUtils_h__ */
|
#endif /* nsIContentUtils_h__ */
|
||||||
|
|
|
@ -70,6 +70,7 @@ public:
|
||||||
mFrozen(PR_FALSE),
|
mFrozen(PR_FALSE),
|
||||||
mDefer(PR_FALSE),
|
mDefer(PR_FALSE),
|
||||||
mAsync(PR_FALSE),
|
mAsync(PR_FALSE),
|
||||||
|
mExternal(PR_FALSE),
|
||||||
mParserCreated(aFromParser == mozilla::dom::FROM_PARSER_FRAGMENT ?
|
mParserCreated(aFromParser == mozilla::dom::FROM_PARSER_FRAGMENT ?
|
||||||
mozilla::dom::NOT_FROM_PARSER : aFromParser),
|
mozilla::dom::NOT_FROM_PARSER : aFromParser),
|
||||||
// Fragment parser-created scripts (if executable)
|
// Fragment parser-created scripts (if executable)
|
||||||
|
@ -126,6 +127,15 @@ public:
|
||||||
return mAsync;
|
return mAsync;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the script an external script?
|
||||||
|
*/
|
||||||
|
PRBool GetScriptExternal()
|
||||||
|
{
|
||||||
|
NS_PRECONDITION(mFrozen, "Not ready for this call yet!");
|
||||||
|
return mExternal;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns how the element was created.
|
* Returns how the element was created.
|
||||||
*/
|
*/
|
||||||
|
@ -249,6 +259,12 @@ protected:
|
||||||
*/
|
*/
|
||||||
PRPackedBool mAsync;
|
PRPackedBool mAsync;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The effective externalness. A script can be external with mUri being null
|
||||||
|
* if the src attribute contained an invalid URL string.
|
||||||
|
*/
|
||||||
|
PRPackedBool mExternal;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether this element was parser-created.
|
* Whether this element was parser-created.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,106 +0,0 @@
|
||||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
||||||
/* ***** BEGIN LICENSE BLOCK *****
|
|
||||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
|
||||||
*
|
|
||||||
* The contents of this file are subject to the Mozilla Public License Version
|
|
||||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
|
||||||
* the License. You may obtain a copy of the License at
|
|
||||||
* http://www.mozilla.org/MPL/
|
|
||||||
*
|
|
||||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
||||||
* for the specific language governing rights and limitations under the
|
|
||||||
* License.
|
|
||||||
*
|
|
||||||
* The Original Code is Mozilla.
|
|
||||||
*
|
|
||||||
* The Initial Developer of the Original Code is
|
|
||||||
* Netscape Communications.
|
|
||||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
|
||||||
* the Initial Developer. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Contributor(s):
|
|
||||||
* Vidur Apparao <vidur@netscape.com> (original author)
|
|
||||||
*
|
|
||||||
* Alternatively, the contents of this file may be used under the terms of
|
|
||||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
|
||||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
|
||||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
|
||||||
* of those above. If you wish to allow use of your version of this file only
|
|
||||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
|
||||||
* use your version of this file under the terms of the MPL, indicate your
|
|
||||||
* decision by deleting the provisions above and replace them with the notice
|
|
||||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
|
||||||
* the provisions above, a recipient may use your version of this file under
|
|
||||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
|
||||||
*
|
|
||||||
* ***** END LICENSE BLOCK ***** */
|
|
||||||
|
|
||||||
#include "nsISupports.idl"
|
|
||||||
|
|
||||||
interface nsIDocument;
|
|
||||||
interface nsIScriptElement;
|
|
||||||
interface nsIScriptLoaderObserver;
|
|
||||||
|
|
||||||
[scriptable, uuid(339a4eb5-dac6-4034-8c43-f4f8c645ce57)]
|
|
||||||
interface nsIScriptLoader : nsISupports {
|
|
||||||
/**
|
|
||||||
* Initialize loader with a document. The container of this document
|
|
||||||
* will be used for getting script evaluation information, including
|
|
||||||
* the context in which to do the evaluation. The loader maintains a
|
|
||||||
* strong reference to the document.
|
|
||||||
*
|
|
||||||
* @param aDocument The document to use as the basis for script
|
|
||||||
* processing.
|
|
||||||
*/
|
|
||||||
void init(in nsIDocument aDocument);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The loader maintains a strong reference to the document with
|
|
||||||
* which it is initialized. This call forces the reference to
|
|
||||||
* be dropped.
|
|
||||||
*/
|
|
||||||
void dropDocumentReference();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add an observer for all scripts loaded through this loader.
|
|
||||||
*
|
|
||||||
* @param aObserver observer for all script processing.
|
|
||||||
*/
|
|
||||||
void addObserver(in nsIScriptLoaderObserver aObserver);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove an observer.
|
|
||||||
*
|
|
||||||
* @param aObserver observer to be removed
|
|
||||||
*/
|
|
||||||
void removeObserver(in nsIScriptLoaderObserver aObserver);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Process a script element. This will include both loading the
|
|
||||||
* source of the element if it is not inline and evaluating
|
|
||||||
* the script itself.
|
|
||||||
*
|
|
||||||
* @param aElement The element representing the script to be loaded and
|
|
||||||
* evaluated.
|
|
||||||
* @param aObserver An observer for this script load only
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void processScriptElement(in nsIScriptElement aElement,
|
|
||||||
in nsIScriptLoaderObserver aObserver);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the currently executing script. This is useful if you want to
|
|
||||||
* generate a unique key based on the currently executing script.
|
|
||||||
*/
|
|
||||||
nsIScriptElement getCurrentScript();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether the loader is enabled or not.
|
|
||||||
* When disabled, processing of new script elements is disabled.
|
|
||||||
* Any call to processScriptElement() will fail with a return code of
|
|
||||||
* NS_ERROR_NOT_AVAILABLE. Note that this DOES NOT disable
|
|
||||||
* currently loading or executing scripts.
|
|
||||||
*/
|
|
||||||
attribute boolean enabled;
|
|
||||||
};
|
|
|
@ -592,6 +592,7 @@ nsContentUtils::InitializeEventTable() {
|
||||||
|
|
||||||
{ nsGkAtoms::onpageshow, NS_PAGE_SHOW, EventNameType_HTML, NS_EVENT },
|
{ nsGkAtoms::onpageshow, NS_PAGE_SHOW, EventNameType_HTML, NS_EVENT },
|
||||||
{ nsGkAtoms::onpagehide, NS_PAGE_HIDE, EventNameType_HTML, NS_EVENT },
|
{ nsGkAtoms::onpagehide, NS_PAGE_HIDE, EventNameType_HTML, NS_EVENT },
|
||||||
|
{ nsGkAtoms::onMozBeforeResize, NS_BEFORERESIZE_EVENT, EventNameType_None, NS_EVENT },
|
||||||
{ nsGkAtoms::onresize, NS_RESIZE_EVENT,
|
{ nsGkAtoms::onresize, NS_RESIZE_EVENT,
|
||||||
(EventNameType_HTMLXUL | EventNameType_SVGSVG), NS_EVENT },
|
(EventNameType_HTMLXUL | EventNameType_SVGSVG), NS_EVENT },
|
||||||
{ nsGkAtoms::onscroll, NS_SCROLL_EVENT,
|
{ nsGkAtoms::onscroll, NS_SCROLL_EVENT,
|
||||||
|
@ -5536,6 +5537,11 @@ nsContentUtils::WrapNative(JSContext *cx, JSObject *scope, nsISupports *native,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JSObject *wrapper = xpc_GetCachedSlimWrapper(cache, scope, vp);
|
||||||
|
if (wrapper) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
NS_ENSURE_TRUE(sXPConnect && sThreadJSContextStack, NS_ERROR_UNEXPECTED);
|
NS_ENSURE_TRUE(sXPConnect && sThreadJSContextStack, NS_ERROR_UNEXPECTED);
|
||||||
|
|
||||||
// Keep sXPConnect and sThreadJSContextStack alive. If we're on the main
|
// Keep sXPConnect and sThreadJSContextStack alive. If we're on the main
|
||||||
|
@ -6489,3 +6495,11 @@ nsIContentUtils::FindInternalContentViewer(const char* aType,
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMPL_ISUPPORTS1(nsIContentUtils2, nsIContentUtils2)
|
||||||
|
|
||||||
|
nsIInterfaceRequestor*
|
||||||
|
nsIContentUtils2::GetSameOriginChecker()
|
||||||
|
{
|
||||||
|
return nsContentUtils::GetSameOriginChecker();
|
||||||
|
}
|
||||||
|
|
|
@ -709,6 +709,7 @@ GK_ATOM(onpopupshown, "onpopupshown")
|
||||||
GK_ATOM(onreadystatechange, "onreadystatechange")
|
GK_ATOM(onreadystatechange, "onreadystatechange")
|
||||||
GK_ATOM(onRequest, "onRequest")
|
GK_ATOM(onRequest, "onRequest")
|
||||||
GK_ATOM(onreset, "onreset")
|
GK_ATOM(onreset, "onreset")
|
||||||
|
GK_ATOM(onMozBeforeResize, "onMozBeforeResize")
|
||||||
GK_ATOM(onresize, "onresize")
|
GK_ATOM(onresize, "onresize")
|
||||||
GK_ATOM(onscroll, "onscroll")
|
GK_ATOM(onscroll, "onscroll")
|
||||||
GK_ATOM(onselect, "onselect")
|
GK_ATOM(onselect, "onselect")
|
||||||
|
|
|
@ -546,10 +546,13 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
|
||||||
|
|
||||||
// Step 9. in the HTML5 spec
|
// Step 9. in the HTML5 spec
|
||||||
|
|
||||||
nsCOMPtr<nsIURI> scriptURI = aElement->GetScriptURI();
|
|
||||||
nsRefPtr<nsScriptLoadRequest> request;
|
nsRefPtr<nsScriptLoadRequest> request;
|
||||||
if (scriptURI) {
|
if (aElement->GetScriptExternal()) {
|
||||||
// external script
|
// external script
|
||||||
|
nsCOMPtr<nsIURI> scriptURI = aElement->GetScriptURI();
|
||||||
|
if (!scriptURI) {
|
||||||
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
|
}
|
||||||
nsTArray<PreloadInfo>::index_type i =
|
nsTArray<PreloadInfo>::index_type i =
|
||||||
mPreloads.IndexOf(scriptURI.get(), 0, PreloadURIComparator());
|
mPreloads.IndexOf(scriptURI.get(), 0, PreloadURIComparator());
|
||||||
if (i != nsTArray<PreloadInfo>::NoIndex) {
|
if (i != nsTArray<PreloadInfo>::NoIndex) {
|
||||||
|
|
|
@ -442,6 +442,7 @@ _TEST_FILES2 = \
|
||||||
file_bug604660-5.xml \
|
file_bug604660-5.xml \
|
||||||
file_bug604660-6.xsl \
|
file_bug604660-6.xsl \
|
||||||
test_bug605982.html \
|
test_bug605982.html \
|
||||||
|
test_bug606729.html \
|
||||||
test_treewalker_nextsibling.xml \
|
test_treewalker_nextsibling.xml \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<!--
|
||||||
|
https://bugzilla.mozilla.org/show_bug.cgi?id=606729
|
||||||
|
-->
|
||||||
|
<head>
|
||||||
|
<title>Test for Bug 606729</title>
|
||||||
|
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||||
|
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=606729">Mozilla Bug 606729</a>
|
||||||
|
<p id="display"></p>
|
||||||
|
<div id="content" style="display: none">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<pre id="test">
|
||||||
|
<script
|
||||||
|
src="data:"
|
||||||
|
onerror="ok(false, 'Script with src=data: should not fire onerror.');"
|
||||||
|
onload="ok(false, 'Script with src=data: should not fire onload.');"
|
||||||
|
>
|
||||||
|
ok(false, "Script with src=data: should not run textContent.");
|
||||||
|
</script>
|
||||||
|
<script
|
||||||
|
src="bogus:"
|
||||||
|
onerror="ok(false, 'Script with src=bogus: should not fire onerror.');"
|
||||||
|
onload="ok(false, 'Script with src=bogus: should not fire onload.');"
|
||||||
|
>
|
||||||
|
ok(false, "Script with src=bogus: should not run textContent.");
|
||||||
|
</script>
|
||||||
|
<script class="testbody" type="text/javascript">
|
||||||
|
ok(true, "Obligatory succeeding test assertion.");
|
||||||
|
</script>
|
||||||
|
</pre>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,7 @@
|
||||||
class nsHTMLCanvasElement;
|
class nsHTMLCanvasElement;
|
||||||
class gfxContext;
|
class gfxContext;
|
||||||
class gfxASurface;
|
class gfxASurface;
|
||||||
|
class nsIPropertyBag;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace layers {
|
namespace layers {
|
||||||
|
@ -115,6 +116,14 @@ public:
|
||||||
// Redraw the dirty rectangle of this canvas.
|
// Redraw the dirty rectangle of this canvas.
|
||||||
NS_IMETHOD Redraw(const gfxRect &dirty) = 0;
|
NS_IMETHOD Redraw(const gfxRect &dirty) = 0;
|
||||||
|
|
||||||
|
// Passes a generic nsIPropertyBag options argument, along with the
|
||||||
|
// previous one, if any. Optional.
|
||||||
|
NS_IMETHOD SetContextOptions(nsIPropertyBag *aNewOptions) { return NS_OK; }
|
||||||
|
|
||||||
|
//
|
||||||
|
// shmem support
|
||||||
|
//
|
||||||
|
|
||||||
// If this context can be set to use Mozilla's Shmem segments as its backing
|
// If this context can be set to use Mozilla's Shmem segments as its backing
|
||||||
// store, this will set it to that state. Note that if you have drawn
|
// store, this will set it to that state. Note that if you have drawn
|
||||||
// anything into this canvas before changing the shmem state, it will be
|
// anything into this canvas before changing the shmem state, it will be
|
||||||
|
|
|
@ -82,14 +82,14 @@ helper_isFloat32Array(JSObject *obj) {
|
||||||
* BufferData_array (int, js::TypedArray *, int)
|
* BufferData_array (int, js::TypedArray *, int)
|
||||||
*/
|
*/
|
||||||
static JSBool
|
static JSBool
|
||||||
nsICanvasRenderingContextWebGL_BufferData(JSContext *cx, uintN argc, jsval *vp)
|
nsIDOMWebGLRenderingContext_BufferData(JSContext *cx, uintN argc, jsval *vp)
|
||||||
{
|
{
|
||||||
XPC_QS_ASSERT_CONTEXT_OK(cx);
|
XPC_QS_ASSERT_CONTEXT_OK(cx);
|
||||||
JSObject *obj = JS_THIS_OBJECT(cx, vp);
|
JSObject *obj = JS_THIS_OBJECT(cx, vp);
|
||||||
if (!obj)
|
if (!obj)
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
|
|
||||||
nsICanvasRenderingContextWebGL *self;
|
nsIDOMWebGLRenderingContext *self;
|
||||||
xpc_qsSelfRef selfref;
|
xpc_qsSelfRef selfref;
|
||||||
js::AutoValueRooter tvr(cx);
|
js::AutoValueRooter tvr(cx);
|
||||||
if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
|
if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
|
||||||
|
@ -149,14 +149,14 @@ nsICanvasRenderingContextWebGL_BufferData(JSContext *cx, uintN argc, jsval *vp)
|
||||||
* BufferSubData_array (int, int, js::TypedArray *)
|
* BufferSubData_array (int, int, js::TypedArray *)
|
||||||
*/
|
*/
|
||||||
static JSBool
|
static JSBool
|
||||||
nsICanvasRenderingContextWebGL_BufferSubData(JSContext *cx, uintN argc, jsval *vp)
|
nsIDOMWebGLRenderingContext_BufferSubData(JSContext *cx, uintN argc, jsval *vp)
|
||||||
{
|
{
|
||||||
XPC_QS_ASSERT_CONTEXT_OK(cx);
|
XPC_QS_ASSERT_CONTEXT_OK(cx);
|
||||||
JSObject *obj = JS_THIS_OBJECT(cx, vp);
|
JSObject *obj = JS_THIS_OBJECT(cx, vp);
|
||||||
if (!obj)
|
if (!obj)
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
|
|
||||||
nsICanvasRenderingContextWebGL *self;
|
nsIDOMWebGLRenderingContext *self;
|
||||||
xpc_qsSelfRef selfref;
|
xpc_qsSelfRef selfref;
|
||||||
js::AutoValueRooter tvr(cx);
|
js::AutoValueRooter tvr(cx);
|
||||||
if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
|
if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
|
||||||
|
@ -215,7 +215,7 @@ nsICanvasRenderingContextWebGL_BufferSubData(JSContext *cx, uintN argc, jsval *v
|
||||||
* ReadPixels(int, int, int, int, uint, uint, ArrayBufferView)
|
* ReadPixels(int, int, int, int, uint, uint, ArrayBufferView)
|
||||||
*/
|
*/
|
||||||
static JSBool
|
static JSBool
|
||||||
nsICanvasRenderingContextWebGL_ReadPixels(JSContext *cx, uintN argc, jsval *vp)
|
nsIDOMWebGLRenderingContext_ReadPixels(JSContext *cx, uintN argc, jsval *vp)
|
||||||
{
|
{
|
||||||
XPC_QS_ASSERT_CONTEXT_OK(cx);
|
XPC_QS_ASSERT_CONTEXT_OK(cx);
|
||||||
JSObject *obj = JS_THIS_OBJECT(cx, vp);
|
JSObject *obj = JS_THIS_OBJECT(cx, vp);
|
||||||
|
@ -224,7 +224,7 @@ nsICanvasRenderingContextWebGL_ReadPixels(JSContext *cx, uintN argc, jsval *vp)
|
||||||
|
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
nsICanvasRenderingContextWebGL *self;
|
nsIDOMWebGLRenderingContext *self;
|
||||||
xpc_qsSelfRef selfref;
|
xpc_qsSelfRef selfref;
|
||||||
js::AutoValueRooter tvr(cx);
|
js::AutoValueRooter tvr(cx);
|
||||||
if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
|
if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
|
||||||
|
@ -278,7 +278,7 @@ nsICanvasRenderingContextWebGL_ReadPixels(JSContext *cx, uintN argc, jsval *vp)
|
||||||
* TexImage2D(uint, int, uint, uint, uint, ImageData)
|
* TexImage2D(uint, int, uint, uint, uint, ImageData)
|
||||||
*/
|
*/
|
||||||
static JSBool
|
static JSBool
|
||||||
nsICanvasRenderingContextWebGL_TexImage2D(JSContext *cx, uintN argc, jsval *vp)
|
nsIDOMWebGLRenderingContext_TexImage2D(JSContext *cx, uintN argc, jsval *vp)
|
||||||
{
|
{
|
||||||
XPC_QS_ASSERT_CONTEXT_OK(cx);
|
XPC_QS_ASSERT_CONTEXT_OK(cx);
|
||||||
JSObject *obj = JS_THIS_OBJECT(cx, vp);
|
JSObject *obj = JS_THIS_OBJECT(cx, vp);
|
||||||
|
@ -287,7 +287,7 @@ nsICanvasRenderingContextWebGL_TexImage2D(JSContext *cx, uintN argc, jsval *vp)
|
||||||
|
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
nsICanvasRenderingContextWebGL *self;
|
nsIDOMWebGLRenderingContext *self;
|
||||||
xpc_qsSelfRef selfref;
|
xpc_qsSelfRef selfref;
|
||||||
js::AutoValueRooter tvr(cx);
|
js::AutoValueRooter tvr(cx);
|
||||||
if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
|
if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
|
||||||
|
@ -396,7 +396,7 @@ nsICanvasRenderingContextWebGL_TexImage2D(JSContext *cx, uintN argc, jsval *vp)
|
||||||
* TexSubImage2D(uint, int, int, int, uint, uint, ImageData)
|
* TexSubImage2D(uint, int, int, int, uint, uint, ImageData)
|
||||||
*/
|
*/
|
||||||
static JSBool
|
static JSBool
|
||||||
nsICanvasRenderingContextWebGL_TexSubImage2D(JSContext *cx, uintN argc, jsval *vp)
|
nsIDOMWebGLRenderingContext_TexSubImage2D(JSContext *cx, uintN argc, jsval *vp)
|
||||||
{
|
{
|
||||||
XPC_QS_ASSERT_CONTEXT_OK(cx);
|
XPC_QS_ASSERT_CONTEXT_OK(cx);
|
||||||
JSObject *obj = JS_THIS_OBJECT(cx, vp);
|
JSObject *obj = JS_THIS_OBJECT(cx, vp);
|
||||||
|
@ -405,7 +405,7 @@ nsICanvasRenderingContextWebGL_TexSubImage2D(JSContext *cx, uintN argc, jsval *v
|
||||||
|
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
nsICanvasRenderingContextWebGL *self;
|
nsIDOMWebGLRenderingContext *self;
|
||||||
xpc_qsSelfRef selfref;
|
xpc_qsSelfRef selfref;
|
||||||
js::AutoValueRooter tvr(cx);
|
js::AutoValueRooter tvr(cx);
|
||||||
if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
|
if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
|
||||||
|
@ -504,7 +504,7 @@ nsICanvasRenderingContextWebGL_TexSubImage2D(JSContext *cx, uintN argc, jsval *v
|
||||||
|
|
||||||
/* NOTE: There is a TN version of this below, update it as well */
|
/* NOTE: There is a TN version of this below, update it as well */
|
||||||
static inline JSBool
|
static inline JSBool
|
||||||
helper_nsICanvasRenderingContextWebGL_Uniform_x_iv(JSContext *cx, uintN argc, jsval *vp, int nElements)
|
helper_nsIDOMWebGLRenderingContext_Uniform_x_iv(JSContext *cx, uintN argc, jsval *vp, int nElements)
|
||||||
{
|
{
|
||||||
XPC_QS_ASSERT_CONTEXT_OK(cx);
|
XPC_QS_ASSERT_CONTEXT_OK(cx);
|
||||||
JSObject *obj = JS_THIS_OBJECT(cx, vp);
|
JSObject *obj = JS_THIS_OBJECT(cx, vp);
|
||||||
|
@ -513,7 +513,7 @@ helper_nsICanvasRenderingContextWebGL_Uniform_x_iv(JSContext *cx, uintN argc, js
|
||||||
|
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
nsICanvasRenderingContextWebGL *self;
|
nsIDOMWebGLRenderingContext *self;
|
||||||
xpc_qsSelfRef selfref;
|
xpc_qsSelfRef selfref;
|
||||||
js::AutoValueRooter tvr(cx);
|
js::AutoValueRooter tvr(cx);
|
||||||
if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
|
if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
|
||||||
|
@ -578,7 +578,7 @@ helper_nsICanvasRenderingContextWebGL_Uniform_x_iv(JSContext *cx, uintN argc, js
|
||||||
|
|
||||||
/* NOTE: There is a TN version of this below, update it as well */
|
/* NOTE: There is a TN version of this below, update it as well */
|
||||||
static inline JSBool
|
static inline JSBool
|
||||||
helper_nsICanvasRenderingContextWebGL_Uniform_x_fv(JSContext *cx, uintN argc, jsval *vp, int nElements)
|
helper_nsIDOMWebGLRenderingContext_Uniform_x_fv(JSContext *cx, uintN argc, jsval *vp, int nElements)
|
||||||
{
|
{
|
||||||
XPC_QS_ASSERT_CONTEXT_OK(cx);
|
XPC_QS_ASSERT_CONTEXT_OK(cx);
|
||||||
JSObject *obj = JS_THIS_OBJECT(cx, vp);
|
JSObject *obj = JS_THIS_OBJECT(cx, vp);
|
||||||
|
@ -587,7 +587,7 @@ helper_nsICanvasRenderingContextWebGL_Uniform_x_fv(JSContext *cx, uintN argc, js
|
||||||
|
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
nsICanvasRenderingContextWebGL *self;
|
nsIDOMWebGLRenderingContext *self;
|
||||||
xpc_qsSelfRef selfref;
|
xpc_qsSelfRef selfref;
|
||||||
js::AutoValueRooter tvr(cx);
|
js::AutoValueRooter tvr(cx);
|
||||||
if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
|
if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
|
||||||
|
@ -652,7 +652,7 @@ helper_nsICanvasRenderingContextWebGL_Uniform_x_fv(JSContext *cx, uintN argc, js
|
||||||
|
|
||||||
/* NOTE: There is a TN version of this below, update it as well */
|
/* NOTE: There is a TN version of this below, update it as well */
|
||||||
static inline JSBool
|
static inline JSBool
|
||||||
helper_nsICanvasRenderingContextWebGL_UniformMatrix_x_fv(JSContext *cx, uintN argc, jsval *vp, int nElements)
|
helper_nsIDOMWebGLRenderingContext_UniformMatrix_x_fv(JSContext *cx, uintN argc, jsval *vp, int nElements)
|
||||||
{
|
{
|
||||||
XPC_QS_ASSERT_CONTEXT_OK(cx);
|
XPC_QS_ASSERT_CONTEXT_OK(cx);
|
||||||
JSObject *obj = JS_THIS_OBJECT(cx, vp);
|
JSObject *obj = JS_THIS_OBJECT(cx, vp);
|
||||||
|
@ -661,7 +661,7 @@ helper_nsICanvasRenderingContextWebGL_UniformMatrix_x_fv(JSContext *cx, uintN ar
|
||||||
|
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
nsICanvasRenderingContextWebGL *self;
|
nsIDOMWebGLRenderingContext *self;
|
||||||
xpc_qsSelfRef selfref;
|
xpc_qsSelfRef selfref;
|
||||||
js::AutoValueRooter tvr(cx);
|
js::AutoValueRooter tvr(cx);
|
||||||
if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
|
if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
|
||||||
|
@ -727,7 +727,7 @@ helper_nsICanvasRenderingContextWebGL_UniformMatrix_x_fv(JSContext *cx, uintN ar
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline JSBool
|
static inline JSBool
|
||||||
helper_nsICanvasRenderingContextWebGL_VertexAttrib_x_fv(JSContext *cx, uintN argc, jsval *vp, int nElements)
|
helper_nsIDOMWebGLRenderingContext_VertexAttrib_x_fv(JSContext *cx, uintN argc, jsval *vp, int nElements)
|
||||||
{
|
{
|
||||||
XPC_QS_ASSERT_CONTEXT_OK(cx);
|
XPC_QS_ASSERT_CONTEXT_OK(cx);
|
||||||
JSObject *obj = JS_THIS_OBJECT(cx, vp);
|
JSObject *obj = JS_THIS_OBJECT(cx, vp);
|
||||||
|
@ -736,7 +736,7 @@ helper_nsICanvasRenderingContextWebGL_VertexAttrib_x_fv(JSContext *cx, uintN arg
|
||||||
|
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
nsICanvasRenderingContextWebGL *self;
|
nsIDOMWebGLRenderingContext *self;
|
||||||
xpc_qsSelfRef selfref;
|
xpc_qsSelfRef selfref;
|
||||||
js::AutoValueRooter tvr(cx);
|
js::AutoValueRooter tvr(cx);
|
||||||
if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
|
if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
|
||||||
|
@ -796,104 +796,104 @@ helper_nsICanvasRenderingContextWebGL_VertexAttrib_x_fv(JSContext *cx, uintN arg
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSBool
|
static JSBool
|
||||||
nsICanvasRenderingContextWebGL_Uniform1iv(JSContext *cx, uintN argc, jsval *vp)
|
nsIDOMWebGLRenderingContext_Uniform1iv(JSContext *cx, uintN argc, jsval *vp)
|
||||||
{
|
{
|
||||||
return helper_nsICanvasRenderingContextWebGL_Uniform_x_iv(cx, argc, vp, 1);
|
return helper_nsIDOMWebGLRenderingContext_Uniform_x_iv(cx, argc, vp, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSBool
|
static JSBool
|
||||||
nsICanvasRenderingContextWebGL_Uniform2iv(JSContext *cx, uintN argc, jsval *vp)
|
nsIDOMWebGLRenderingContext_Uniform2iv(JSContext *cx, uintN argc, jsval *vp)
|
||||||
{
|
{
|
||||||
return helper_nsICanvasRenderingContextWebGL_Uniform_x_iv(cx, argc, vp, 2);
|
return helper_nsIDOMWebGLRenderingContext_Uniform_x_iv(cx, argc, vp, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSBool
|
static JSBool
|
||||||
nsICanvasRenderingContextWebGL_Uniform3iv(JSContext *cx, uintN argc, jsval *vp)
|
nsIDOMWebGLRenderingContext_Uniform3iv(JSContext *cx, uintN argc, jsval *vp)
|
||||||
{
|
{
|
||||||
return helper_nsICanvasRenderingContextWebGL_Uniform_x_iv(cx, argc, vp, 3);
|
return helper_nsIDOMWebGLRenderingContext_Uniform_x_iv(cx, argc, vp, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSBool
|
static JSBool
|
||||||
nsICanvasRenderingContextWebGL_Uniform4iv(JSContext *cx, uintN argc, jsval *vp)
|
nsIDOMWebGLRenderingContext_Uniform4iv(JSContext *cx, uintN argc, jsval *vp)
|
||||||
{
|
{
|
||||||
return helper_nsICanvasRenderingContextWebGL_Uniform_x_iv(cx, argc, vp, 4);
|
return helper_nsIDOMWebGLRenderingContext_Uniform_x_iv(cx, argc, vp, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSBool
|
static JSBool
|
||||||
nsICanvasRenderingContextWebGL_Uniform1fv(JSContext *cx, uintN argc, jsval *vp)
|
nsIDOMWebGLRenderingContext_Uniform1fv(JSContext *cx, uintN argc, jsval *vp)
|
||||||
{
|
{
|
||||||
return helper_nsICanvasRenderingContextWebGL_Uniform_x_fv(cx, argc, vp, 1);
|
return helper_nsIDOMWebGLRenderingContext_Uniform_x_fv(cx, argc, vp, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSBool
|
static JSBool
|
||||||
nsICanvasRenderingContextWebGL_Uniform2fv(JSContext *cx, uintN argc, jsval *vp)
|
nsIDOMWebGLRenderingContext_Uniform2fv(JSContext *cx, uintN argc, jsval *vp)
|
||||||
{
|
{
|
||||||
return helper_nsICanvasRenderingContextWebGL_Uniform_x_fv(cx, argc, vp, 2);
|
return helper_nsIDOMWebGLRenderingContext_Uniform_x_fv(cx, argc, vp, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSBool
|
static JSBool
|
||||||
nsICanvasRenderingContextWebGL_Uniform3fv(JSContext *cx, uintN argc, jsval *vp)
|
nsIDOMWebGLRenderingContext_Uniform3fv(JSContext *cx, uintN argc, jsval *vp)
|
||||||
{
|
{
|
||||||
return helper_nsICanvasRenderingContextWebGL_Uniform_x_fv(cx, argc, vp, 3);
|
return helper_nsIDOMWebGLRenderingContext_Uniform_x_fv(cx, argc, vp, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSBool
|
static JSBool
|
||||||
nsICanvasRenderingContextWebGL_Uniform4fv(JSContext *cx, uintN argc, jsval *vp)
|
nsIDOMWebGLRenderingContext_Uniform4fv(JSContext *cx, uintN argc, jsval *vp)
|
||||||
{
|
{
|
||||||
return helper_nsICanvasRenderingContextWebGL_Uniform_x_fv(cx, argc, vp, 4);
|
return helper_nsIDOMWebGLRenderingContext_Uniform_x_fv(cx, argc, vp, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSBool
|
static JSBool
|
||||||
nsICanvasRenderingContextWebGL_UniformMatrix2fv(JSContext *cx, uintN argc, jsval *vp)
|
nsIDOMWebGLRenderingContext_UniformMatrix2fv(JSContext *cx, uintN argc, jsval *vp)
|
||||||
{
|
{
|
||||||
return helper_nsICanvasRenderingContextWebGL_UniformMatrix_x_fv(cx, argc, vp, 2);
|
return helper_nsIDOMWebGLRenderingContext_UniformMatrix_x_fv(cx, argc, vp, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSBool
|
static JSBool
|
||||||
nsICanvasRenderingContextWebGL_UniformMatrix3fv(JSContext *cx, uintN argc, jsval *vp)
|
nsIDOMWebGLRenderingContext_UniformMatrix3fv(JSContext *cx, uintN argc, jsval *vp)
|
||||||
{
|
{
|
||||||
return helper_nsICanvasRenderingContextWebGL_UniformMatrix_x_fv(cx, argc, vp, 3);
|
return helper_nsIDOMWebGLRenderingContext_UniformMatrix_x_fv(cx, argc, vp, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSBool
|
static JSBool
|
||||||
nsICanvasRenderingContextWebGL_UniformMatrix4fv(JSContext *cx, uintN argc, jsval *vp)
|
nsIDOMWebGLRenderingContext_UniformMatrix4fv(JSContext *cx, uintN argc, jsval *vp)
|
||||||
{
|
{
|
||||||
return helper_nsICanvasRenderingContextWebGL_UniformMatrix_x_fv(cx, argc, vp, 4);
|
return helper_nsIDOMWebGLRenderingContext_UniformMatrix_x_fv(cx, argc, vp, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSBool
|
static JSBool
|
||||||
nsICanvasRenderingContextWebGL_VertexAttrib1fv(JSContext *cx, uintN argc, jsval *vp)
|
nsIDOMWebGLRenderingContext_VertexAttrib1fv(JSContext *cx, uintN argc, jsval *vp)
|
||||||
{
|
{
|
||||||
return helper_nsICanvasRenderingContextWebGL_VertexAttrib_x_fv(cx, argc, vp, 1);
|
return helper_nsIDOMWebGLRenderingContext_VertexAttrib_x_fv(cx, argc, vp, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSBool
|
static JSBool
|
||||||
nsICanvasRenderingContextWebGL_VertexAttrib2fv(JSContext *cx, uintN argc, jsval *vp)
|
nsIDOMWebGLRenderingContext_VertexAttrib2fv(JSContext *cx, uintN argc, jsval *vp)
|
||||||
{
|
{
|
||||||
return helper_nsICanvasRenderingContextWebGL_VertexAttrib_x_fv(cx, argc, vp, 2);
|
return helper_nsIDOMWebGLRenderingContext_VertexAttrib_x_fv(cx, argc, vp, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSBool
|
static JSBool
|
||||||
nsICanvasRenderingContextWebGL_VertexAttrib3fv(JSContext *cx, uintN argc, jsval *vp)
|
nsIDOMWebGLRenderingContext_VertexAttrib3fv(JSContext *cx, uintN argc, jsval *vp)
|
||||||
{
|
{
|
||||||
return helper_nsICanvasRenderingContextWebGL_VertexAttrib_x_fv(cx, argc, vp, 3);
|
return helper_nsIDOMWebGLRenderingContext_VertexAttrib_x_fv(cx, argc, vp, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSBool
|
static JSBool
|
||||||
nsICanvasRenderingContextWebGL_VertexAttrib4fv(JSContext *cx, uintN argc, jsval *vp)
|
nsIDOMWebGLRenderingContext_VertexAttrib4fv(JSContext *cx, uintN argc, jsval *vp)
|
||||||
{
|
{
|
||||||
return helper_nsICanvasRenderingContextWebGL_VertexAttrib_x_fv(cx, argc, vp, 4);
|
return helper_nsIDOMWebGLRenderingContext_VertexAttrib_x_fv(cx, argc, vp, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef JS_TRACER
|
#ifdef JS_TRACER
|
||||||
|
|
||||||
static inline void FASTCALL
|
static inline void FASTCALL
|
||||||
helper_nsICanvasRenderingContextWebGL_Uniform_x_iv_tn(JSContext *cx, JSObject *obj, JSObject *locationobj,
|
helper_nsIDOMWebGLRenderingContext_Uniform_x_iv_tn(JSContext *cx, JSObject *obj, JSObject *locationobj,
|
||||||
JSObject *arg, int nElements)
|
JSObject *arg, int nElements)
|
||||||
{
|
{
|
||||||
XPC_QS_ASSERT_CONTEXT_OK(cx);
|
XPC_QS_ASSERT_CONTEXT_OK(cx);
|
||||||
|
|
||||||
nsICanvasRenderingContextWebGL *self;
|
nsIDOMWebGLRenderingContext *self;
|
||||||
xpc_qsSelfRef selfref;
|
xpc_qsSelfRef selfref;
|
||||||
xpc_qsArgValArray<3> vp(cx);
|
xpc_qsArgValArray<3> vp(cx);
|
||||||
if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, &vp.array[0], nsnull)) {
|
if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, &vp.array[0], nsnull)) {
|
||||||
|
@ -902,7 +902,7 @@ helper_nsICanvasRenderingContextWebGL_Uniform_x_iv_tn(JSContext *cx, JSObject *o
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!arg) {
|
if (!arg) {
|
||||||
xpc_qsThrowMethodFailedWithDetails(cx, NS_ERROR_FAILURE, "nsICanvasRenderingContextWebGL", "uniformNiv");
|
xpc_qsThrowMethodFailedWithDetails(cx, NS_ERROR_FAILURE, "nsIDOMWebGLRenderingContext", "uniformNiv");
|
||||||
js_SetTraceableNativeFailed(cx);
|
js_SetTraceableNativeFailed(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -932,7 +932,7 @@ helper_nsICanvasRenderingContextWebGL_Uniform_x_iv_tn(JSContext *cx, JSObject *o
|
||||||
*obj_tvr.jsval_addr() = OBJECT_TO_JSVAL(nobj);
|
*obj_tvr.jsval_addr() = OBJECT_TO_JSVAL(nobj);
|
||||||
wa = js::TypedArray::fromJSObject(nobj);
|
wa = js::TypedArray::fromJSObject(nobj);
|
||||||
} else {
|
} else {
|
||||||
xpc_qsThrowMethodFailedWithDetails(cx, NS_ERROR_FAILURE, "nsICanvasRenderingContextWebGL", "uniformNiv");
|
xpc_qsThrowMethodFailedWithDetails(cx, NS_ERROR_FAILURE, "nsIDOMWebGLRenderingContext", "uniformNiv");
|
||||||
js_SetTraceableNativeFailed(cx);
|
js_SetTraceableNativeFailed(cx);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -950,18 +950,18 @@ helper_nsICanvasRenderingContextWebGL_Uniform_x_iv_tn(JSContext *cx, JSObject *o
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
xpc_qsThrowMethodFailedWithDetails(cx, rv, "nsICanvasRenderingContextWebGL", "uniformNiv");
|
xpc_qsThrowMethodFailedWithDetails(cx, rv, "nsIDOMWebGLRenderingContext", "uniformNiv");
|
||||||
js_SetTraceableNativeFailed(cx);
|
js_SetTraceableNativeFailed(cx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void FASTCALL
|
static inline void FASTCALL
|
||||||
helper_nsICanvasRenderingContextWebGL_Uniform_x_fv_tn(JSContext *cx, JSObject *obj, JSObject *locationobj,
|
helper_nsIDOMWebGLRenderingContext_Uniform_x_fv_tn(JSContext *cx, JSObject *obj, JSObject *locationobj,
|
||||||
JSObject *arg, int nElements)
|
JSObject *arg, int nElements)
|
||||||
{
|
{
|
||||||
XPC_QS_ASSERT_CONTEXT_OK(cx);
|
XPC_QS_ASSERT_CONTEXT_OK(cx);
|
||||||
|
|
||||||
nsICanvasRenderingContextWebGL *self;
|
nsIDOMWebGLRenderingContext *self;
|
||||||
xpc_qsSelfRef selfref;
|
xpc_qsSelfRef selfref;
|
||||||
xpc_qsArgValArray<3> vp(cx);
|
xpc_qsArgValArray<3> vp(cx);
|
||||||
if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, &vp.array[0], nsnull)) {
|
if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, &vp.array[0], nsnull)) {
|
||||||
|
@ -970,7 +970,7 @@ helper_nsICanvasRenderingContextWebGL_Uniform_x_fv_tn(JSContext *cx, JSObject *o
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!arg) {
|
if (!arg) {
|
||||||
xpc_qsThrowMethodFailedWithDetails(cx, NS_ERROR_FAILURE, "nsICanvasRenderingContextWebGL", "uniformNfv");
|
xpc_qsThrowMethodFailedWithDetails(cx, NS_ERROR_FAILURE, "nsIDOMWebGLRenderingContext", "uniformNfv");
|
||||||
js_SetTraceableNativeFailed(cx);
|
js_SetTraceableNativeFailed(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1000,7 +1000,7 @@ helper_nsICanvasRenderingContextWebGL_Uniform_x_fv_tn(JSContext *cx, JSObject *o
|
||||||
*obj_tvr.jsval_addr() = OBJECT_TO_JSVAL(nobj);
|
*obj_tvr.jsval_addr() = OBJECT_TO_JSVAL(nobj);
|
||||||
wa = js::TypedArray::fromJSObject(nobj);
|
wa = js::TypedArray::fromJSObject(nobj);
|
||||||
} else {
|
} else {
|
||||||
xpc_qsThrowMethodFailedWithDetails(cx, NS_ERROR_FAILURE, "nsICanvasRenderingContextWebGL", "uniformNfv");
|
xpc_qsThrowMethodFailedWithDetails(cx, NS_ERROR_FAILURE, "nsIDOMWebGLRenderingContext", "uniformNfv");
|
||||||
js_SetTraceableNativeFailed(cx);
|
js_SetTraceableNativeFailed(cx);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1018,7 +1018,7 @@ helper_nsICanvasRenderingContextWebGL_Uniform_x_fv_tn(JSContext *cx, JSObject *o
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
xpc_qsThrowMethodFailedWithDetails(cx, rv, "nsICanvasRenderingContextWebGL", "uniformNfv");
|
xpc_qsThrowMethodFailedWithDetails(cx, rv, "nsIDOMWebGLRenderingContext", "uniformNfv");
|
||||||
js_SetTraceableNativeFailed(cx);
|
js_SetTraceableNativeFailed(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1026,12 +1026,12 @@ helper_nsICanvasRenderingContextWebGL_Uniform_x_fv_tn(JSContext *cx, JSObject *o
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void FASTCALL
|
static inline void FASTCALL
|
||||||
helper_nsICanvasRenderingContextWebGL_UniformMatrix_x_fv_tn(JSContext *cx, JSObject *obj, JSObject *locationobj,
|
helper_nsIDOMWebGLRenderingContext_UniformMatrix_x_fv_tn(JSContext *cx, JSObject *obj, JSObject *locationobj,
|
||||||
JSBool transpose, JSObject *arg, int nElements)
|
JSBool transpose, JSObject *arg, int nElements)
|
||||||
{
|
{
|
||||||
XPC_QS_ASSERT_CONTEXT_OK(cx);
|
XPC_QS_ASSERT_CONTEXT_OK(cx);
|
||||||
|
|
||||||
nsICanvasRenderingContextWebGL *self;
|
nsIDOMWebGLRenderingContext *self;
|
||||||
xpc_qsSelfRef selfref;
|
xpc_qsSelfRef selfref;
|
||||||
xpc_qsArgValArray<4> vp(cx);
|
xpc_qsArgValArray<4> vp(cx);
|
||||||
if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, &vp.array[0], nsnull)) {
|
if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, &vp.array[0], nsnull)) {
|
||||||
|
@ -1040,7 +1040,7 @@ helper_nsICanvasRenderingContextWebGL_UniformMatrix_x_fv_tn(JSContext *cx, JSObj
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!arg) {
|
if (!arg) {
|
||||||
xpc_qsThrowMethodFailedWithDetails(cx, NS_ERROR_FAILURE, "nsICanvasRenderingContextWebGL", "uniformMatrixNfv");
|
xpc_qsThrowMethodFailedWithDetails(cx, NS_ERROR_FAILURE, "nsIDOMWebGLRenderingContext", "uniformMatrixNfv");
|
||||||
js_SetTraceableNativeFailed(cx);
|
js_SetTraceableNativeFailed(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1070,7 +1070,7 @@ helper_nsICanvasRenderingContextWebGL_UniformMatrix_x_fv_tn(JSContext *cx, JSObj
|
||||||
*obj_tvr.jsval_addr() = OBJECT_TO_JSVAL(nobj);
|
*obj_tvr.jsval_addr() = OBJECT_TO_JSVAL(nobj);
|
||||||
wa = js::TypedArray::fromJSObject(nobj);
|
wa = js::TypedArray::fromJSObject(nobj);
|
||||||
} else {
|
} else {
|
||||||
xpc_qsThrowMethodFailedWithDetails(cx, NS_ERROR_FAILURE, "nsICanvasRenderingContextWebGL", "uniformMatrixNfv");
|
xpc_qsThrowMethodFailedWithDetails(cx, NS_ERROR_FAILURE, "nsIDOMWebGLRenderingContext", "uniformMatrixNfv");
|
||||||
js_SetTraceableNativeFailed(cx);
|
js_SetTraceableNativeFailed(cx);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1085,7 +1085,7 @@ helper_nsICanvasRenderingContextWebGL_UniformMatrix_x_fv_tn(JSContext *cx, JSObj
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
xpc_qsThrowMethodFailedWithDetails(cx, rv, "nsICanvasRenderingContextWebGL", "uniformMatrixNfv");
|
xpc_qsThrowMethodFailedWithDetails(cx, rv, "nsIDOMWebGLRenderingContext", "uniformMatrixNfv");
|
||||||
js_SetTraceableNativeFailed(cx);
|
js_SetTraceableNativeFailed(cx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1093,133 +1093,133 @@ helper_nsICanvasRenderingContextWebGL_UniformMatrix_x_fv_tn(JSContext *cx, JSObj
|
||||||
// FIXME This should return void, not uint32
|
// FIXME This should return void, not uint32
|
||||||
// (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
|
// (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
|
||||||
static uint32 FASTCALL
|
static uint32 FASTCALL
|
||||||
nsICanvasRenderingContextWebGL_Uniform1iv_tn(JSContext *cx, JSObject *obj, JSObject *location, JSObject *arg)
|
nsIDOMWebGLRenderingContext_Uniform1iv_tn(JSContext *cx, JSObject *obj, JSObject *location, JSObject *arg)
|
||||||
{
|
{
|
||||||
helper_nsICanvasRenderingContextWebGL_Uniform_x_iv_tn(cx, obj, location, arg, 1);
|
helper_nsIDOMWebGLRenderingContext_Uniform_x_iv_tn(cx, obj, location, arg, 1);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_Uniform1iv,
|
JS_DEFINE_TRCINFO_1(nsIDOMWebGLRenderingContext_Uniform1iv,
|
||||||
(4, (static, UINT32_FAIL, nsICanvasRenderingContextWebGL_Uniform1iv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
|
(4, (static, UINT32_FAIL, nsIDOMWebGLRenderingContext_Uniform1iv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
|
||||||
|
|
||||||
// FIXME This should return void, not uint32
|
// FIXME This should return void, not uint32
|
||||||
// (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
|
// (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
|
||||||
static uint32 FASTCALL
|
static uint32 FASTCALL
|
||||||
nsICanvasRenderingContextWebGL_Uniform2iv_tn(JSContext *cx, JSObject *obj, JSObject *location, JSObject *arg)
|
nsIDOMWebGLRenderingContext_Uniform2iv_tn(JSContext *cx, JSObject *obj, JSObject *location, JSObject *arg)
|
||||||
{
|
{
|
||||||
helper_nsICanvasRenderingContextWebGL_Uniform_x_iv_tn(cx, obj, location, arg, 2);
|
helper_nsIDOMWebGLRenderingContext_Uniform_x_iv_tn(cx, obj, location, arg, 2);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_Uniform2iv,
|
JS_DEFINE_TRCINFO_1(nsIDOMWebGLRenderingContext_Uniform2iv,
|
||||||
(4, (static, UINT32_FAIL, nsICanvasRenderingContextWebGL_Uniform2iv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
|
(4, (static, UINT32_FAIL, nsIDOMWebGLRenderingContext_Uniform2iv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
|
||||||
|
|
||||||
// FIXME This should return void, not uint32
|
// FIXME This should return void, not uint32
|
||||||
// (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
|
// (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
|
||||||
static uint32 FASTCALL
|
static uint32 FASTCALL
|
||||||
nsICanvasRenderingContextWebGL_Uniform3iv_tn(JSContext *cx, JSObject *obj, JSObject *location, JSObject *arg)
|
nsIDOMWebGLRenderingContext_Uniform3iv_tn(JSContext *cx, JSObject *obj, JSObject *location, JSObject *arg)
|
||||||
{
|
{
|
||||||
helper_nsICanvasRenderingContextWebGL_Uniform_x_iv_tn(cx, obj, location, arg, 3);
|
helper_nsIDOMWebGLRenderingContext_Uniform_x_iv_tn(cx, obj, location, arg, 3);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_Uniform3iv,
|
JS_DEFINE_TRCINFO_1(nsIDOMWebGLRenderingContext_Uniform3iv,
|
||||||
(4, (static, UINT32_FAIL, nsICanvasRenderingContextWebGL_Uniform3iv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
|
(4, (static, UINT32_FAIL, nsIDOMWebGLRenderingContext_Uniform3iv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
|
||||||
|
|
||||||
// FIXME This should return void, not uint32
|
// FIXME This should return void, not uint32
|
||||||
// (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
|
// (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
|
||||||
static uint32 FASTCALL
|
static uint32 FASTCALL
|
||||||
nsICanvasRenderingContextWebGL_Uniform4iv_tn(JSContext *cx, JSObject *obj, JSObject *location, JSObject *arg)
|
nsIDOMWebGLRenderingContext_Uniform4iv_tn(JSContext *cx, JSObject *obj, JSObject *location, JSObject *arg)
|
||||||
{
|
{
|
||||||
helper_nsICanvasRenderingContextWebGL_Uniform_x_iv_tn(cx, obj, location, arg, 4);
|
helper_nsIDOMWebGLRenderingContext_Uniform_x_iv_tn(cx, obj, location, arg, 4);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_Uniform4iv,
|
JS_DEFINE_TRCINFO_1(nsIDOMWebGLRenderingContext_Uniform4iv,
|
||||||
(4, (static, UINT32_FAIL, nsICanvasRenderingContextWebGL_Uniform4iv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
|
(4, (static, UINT32_FAIL, nsIDOMWebGLRenderingContext_Uniform4iv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
|
||||||
|
|
||||||
// FIXME This should return void, not uint32
|
// FIXME This should return void, not uint32
|
||||||
// (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
|
// (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
|
||||||
static uint32 FASTCALL
|
static uint32 FASTCALL
|
||||||
nsICanvasRenderingContextWebGL_Uniform1fv_tn(JSContext *cx, JSObject *obj, JSObject *location, JSObject *arg)
|
nsIDOMWebGLRenderingContext_Uniform1fv_tn(JSContext *cx, JSObject *obj, JSObject *location, JSObject *arg)
|
||||||
{
|
{
|
||||||
helper_nsICanvasRenderingContextWebGL_Uniform_x_fv_tn(cx, obj, location, arg, 1);
|
helper_nsIDOMWebGLRenderingContext_Uniform_x_fv_tn(cx, obj, location, arg, 1);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_Uniform1fv,
|
JS_DEFINE_TRCINFO_1(nsIDOMWebGLRenderingContext_Uniform1fv,
|
||||||
(4, (static, UINT32_FAIL, nsICanvasRenderingContextWebGL_Uniform1fv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
|
(4, (static, UINT32_FAIL, nsIDOMWebGLRenderingContext_Uniform1fv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
|
||||||
|
|
||||||
// FIXME This should return void, not uint32
|
// FIXME This should return void, not uint32
|
||||||
// (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
|
// (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
|
||||||
static uint32 FASTCALL
|
static uint32 FASTCALL
|
||||||
nsICanvasRenderingContextWebGL_Uniform2fv_tn(JSContext *cx, JSObject *obj, JSObject *location, JSObject *arg)
|
nsIDOMWebGLRenderingContext_Uniform2fv_tn(JSContext *cx, JSObject *obj, JSObject *location, JSObject *arg)
|
||||||
{
|
{
|
||||||
helper_nsICanvasRenderingContextWebGL_Uniform_x_fv_tn(cx, obj, location, arg, 2);
|
helper_nsIDOMWebGLRenderingContext_Uniform_x_fv_tn(cx, obj, location, arg, 2);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_Uniform2fv,
|
JS_DEFINE_TRCINFO_1(nsIDOMWebGLRenderingContext_Uniform2fv,
|
||||||
(4, (static, UINT32_FAIL, nsICanvasRenderingContextWebGL_Uniform2fv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
|
(4, (static, UINT32_FAIL, nsIDOMWebGLRenderingContext_Uniform2fv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
|
||||||
|
|
||||||
// FIXME This should return void, not uint32
|
// FIXME This should return void, not uint32
|
||||||
// (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
|
// (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
|
||||||
static uint32 FASTCALL
|
static uint32 FASTCALL
|
||||||
nsICanvasRenderingContextWebGL_Uniform3fv_tn(JSContext *cx, JSObject *obj, JSObject *location, JSObject *arg)
|
nsIDOMWebGLRenderingContext_Uniform3fv_tn(JSContext *cx, JSObject *obj, JSObject *location, JSObject *arg)
|
||||||
{
|
{
|
||||||
helper_nsICanvasRenderingContextWebGL_Uniform_x_fv_tn(cx, obj, location, arg, 3);
|
helper_nsIDOMWebGLRenderingContext_Uniform_x_fv_tn(cx, obj, location, arg, 3);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_Uniform3fv,
|
JS_DEFINE_TRCINFO_1(nsIDOMWebGLRenderingContext_Uniform3fv,
|
||||||
(4, (static, UINT32_FAIL, nsICanvasRenderingContextWebGL_Uniform3fv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
|
(4, (static, UINT32_FAIL, nsIDOMWebGLRenderingContext_Uniform3fv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
|
||||||
|
|
||||||
// FIXME This should return void, not uint32
|
// FIXME This should return void, not uint32
|
||||||
// (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
|
// (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
|
||||||
static uint32 FASTCALL
|
static uint32 FASTCALL
|
||||||
nsICanvasRenderingContextWebGL_Uniform4fv_tn(JSContext *cx, JSObject *obj, JSObject *location, JSObject *arg)
|
nsIDOMWebGLRenderingContext_Uniform4fv_tn(JSContext *cx, JSObject *obj, JSObject *location, JSObject *arg)
|
||||||
{
|
{
|
||||||
helper_nsICanvasRenderingContextWebGL_Uniform_x_fv_tn(cx, obj, location, arg, 4);
|
helper_nsIDOMWebGLRenderingContext_Uniform_x_fv_tn(cx, obj, location, arg, 4);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_Uniform4fv,
|
JS_DEFINE_TRCINFO_1(nsIDOMWebGLRenderingContext_Uniform4fv,
|
||||||
(4, (static, UINT32_FAIL, nsICanvasRenderingContextWebGL_Uniform4fv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
|
(4, (static, UINT32_FAIL, nsIDOMWebGLRenderingContext_Uniform4fv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
|
||||||
|
|
||||||
// FIXME This should return void, not uint32
|
// FIXME This should return void, not uint32
|
||||||
// (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
|
// (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
|
||||||
static uint32 FASTCALL
|
static uint32 FASTCALL
|
||||||
nsICanvasRenderingContextWebGL_UniformMatrix2fv_tn(JSContext *cx, JSObject *obj, JSObject *loc, JSBool transpose, JSObject *arg)
|
nsIDOMWebGLRenderingContext_UniformMatrix2fv_tn(JSContext *cx, JSObject *obj, JSObject *loc, JSBool transpose, JSObject *arg)
|
||||||
{
|
{
|
||||||
helper_nsICanvasRenderingContextWebGL_UniformMatrix_x_fv_tn(cx, obj, loc, transpose, arg, 2);
|
helper_nsIDOMWebGLRenderingContext_UniformMatrix_x_fv_tn(cx, obj, loc, transpose, arg, 2);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_UniformMatrix2fv,
|
JS_DEFINE_TRCINFO_1(nsIDOMWebGLRenderingContext_UniformMatrix2fv,
|
||||||
(5, (static, UINT32_FAIL, nsICanvasRenderingContextWebGL_UniformMatrix2fv_tn, CONTEXT, THIS, OBJECT, BOOL, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
|
(5, (static, UINT32_FAIL, nsIDOMWebGLRenderingContext_UniformMatrix2fv_tn, CONTEXT, THIS, OBJECT, BOOL, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
|
||||||
|
|
||||||
// FIXME This should return void, not uint32
|
// FIXME This should return void, not uint32
|
||||||
// (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
|
// (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
|
||||||
static uint32 FASTCALL
|
static uint32 FASTCALL
|
||||||
nsICanvasRenderingContextWebGL_UniformMatrix3fv_tn(JSContext *cx, JSObject *obj, JSObject *loc, JSBool transpose, JSObject *arg)
|
nsIDOMWebGLRenderingContext_UniformMatrix3fv_tn(JSContext *cx, JSObject *obj, JSObject *loc, JSBool transpose, JSObject *arg)
|
||||||
{
|
{
|
||||||
helper_nsICanvasRenderingContextWebGL_UniformMatrix_x_fv_tn(cx, obj, loc, transpose, arg, 3);
|
helper_nsIDOMWebGLRenderingContext_UniformMatrix_x_fv_tn(cx, obj, loc, transpose, arg, 3);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_UniformMatrix3fv,
|
JS_DEFINE_TRCINFO_1(nsIDOMWebGLRenderingContext_UniformMatrix3fv,
|
||||||
(5, (static, UINT32_FAIL, nsICanvasRenderingContextWebGL_UniformMatrix3fv_tn, CONTEXT, THIS, OBJECT, BOOL, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
|
(5, (static, UINT32_FAIL, nsIDOMWebGLRenderingContext_UniformMatrix3fv_tn, CONTEXT, THIS, OBJECT, BOOL, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
|
||||||
|
|
||||||
// FIXME This should return void, not uint32
|
// FIXME This should return void, not uint32
|
||||||
// (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
|
// (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
|
||||||
static uint32 FASTCALL
|
static uint32 FASTCALL
|
||||||
nsICanvasRenderingContextWebGL_UniformMatrix4fv_tn(JSContext *cx, JSObject *obj, JSObject *loc, JSBool transpose, JSObject *arg)
|
nsIDOMWebGLRenderingContext_UniformMatrix4fv_tn(JSContext *cx, JSObject *obj, JSObject *loc, JSBool transpose, JSObject *arg)
|
||||||
{
|
{
|
||||||
helper_nsICanvasRenderingContextWebGL_UniformMatrix_x_fv_tn(cx, obj, loc, transpose, arg, 4);
|
helper_nsIDOMWebGLRenderingContext_UniformMatrix_x_fv_tn(cx, obj, loc, transpose, arg, 4);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_UniformMatrix4fv,
|
JS_DEFINE_TRCINFO_1(nsIDOMWebGLRenderingContext_UniformMatrix4fv,
|
||||||
(5, (static, UINT32_FAIL, nsICanvasRenderingContextWebGL_UniformMatrix4fv_tn, CONTEXT, THIS, OBJECT, BOOL, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
|
(5, (static, UINT32_FAIL, nsIDOMWebGLRenderingContext_UniformMatrix4fv_tn, CONTEXT, THIS, OBJECT, BOOL, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
|
||||||
|
|
||||||
#endif /* JS_TRACER */
|
#endif /* JS_TRACER */
|
||||||
|
|
|
@ -48,6 +48,11 @@
|
||||||
#include "nsDOMError.h"
|
#include "nsDOMError.h"
|
||||||
#include "nsIGfxInfo.h"
|
#include "nsIGfxInfo.h"
|
||||||
|
|
||||||
|
#include "nsIPropertyBag.h"
|
||||||
|
#include "nsIVariant.h"
|
||||||
|
|
||||||
|
#include "imgIEncoder.h"
|
||||||
|
|
||||||
#include "gfxContext.h"
|
#include "gfxContext.h"
|
||||||
#include "gfxPattern.h"
|
#include "gfxPattern.h"
|
||||||
#include "gfxUtils.h"
|
#include "gfxUtils.h"
|
||||||
|
@ -66,12 +71,12 @@ using namespace mozilla;
|
||||||
using namespace mozilla::gl;
|
using namespace mozilla::gl;
|
||||||
using namespace mozilla::layers;
|
using namespace mozilla::layers;
|
||||||
|
|
||||||
nsresult NS_NewCanvasRenderingContextWebGL(nsICanvasRenderingContextWebGL** aResult);
|
nsresult NS_NewCanvasRenderingContextWebGL(nsIDOMWebGLRenderingContext** aResult);
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
NS_NewCanvasRenderingContextWebGL(nsICanvasRenderingContextWebGL** aResult)
|
NS_NewCanvasRenderingContextWebGL(nsIDOMWebGLRenderingContext** aResult)
|
||||||
{
|
{
|
||||||
nsICanvasRenderingContextWebGL* ctx = new WebGLContext();
|
nsIDOMWebGLRenderingContext* ctx = new WebGLContext();
|
||||||
if (!ctx)
|
if (!ctx)
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
||||||
|
@ -88,6 +93,7 @@ WebGLContext::WebGLContext()
|
||||||
mInvalidated = PR_FALSE;
|
mInvalidated = PR_FALSE;
|
||||||
mResetLayer = PR_TRUE;
|
mResetLayer = PR_TRUE;
|
||||||
mVerbose = PR_FALSE;
|
mVerbose = PR_FALSE;
|
||||||
|
mOptionsFrozen = PR_FALSE;
|
||||||
|
|
||||||
mActiveTexture = 0;
|
mActiveTexture = 0;
|
||||||
mSynthesizedGLError = LOCAL_GL_NO_ERROR;
|
mSynthesizedGLError = LOCAL_GL_NO_ERROR;
|
||||||
|
@ -266,6 +272,67 @@ WebGLContext::SetCanvasElement(nsHTMLCanvasElement* aParentCanvas)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
GetBoolFromPropertyBag(nsIPropertyBag *bag, const char *propName, bool *boolResult)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIVariant> vv;
|
||||||
|
PRBool bv;
|
||||||
|
|
||||||
|
nsresult rv = bag->GetProperty(NS_ConvertASCIItoUTF16(propName), getter_AddRefs(vv));
|
||||||
|
if (NS_FAILED(rv) || !vv)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
rv = vv->GetAsBool(&bv);
|
||||||
|
if (NS_FAILED(rv))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
*boolResult = bv ? true : false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
WebGLContext::SetContextOptions(nsIPropertyBag *aOptions)
|
||||||
|
{
|
||||||
|
if (!aOptions)
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
WebGLContextOptions newOpts;
|
||||||
|
|
||||||
|
// defaults are: yes: depth, alpha, premultipliedAlpha; no: stencil
|
||||||
|
if (!GetBoolFromPropertyBag(aOptions, "stencil", &newOpts.stencil))
|
||||||
|
newOpts.stencil = false;
|
||||||
|
|
||||||
|
if (!GetBoolFromPropertyBag(aOptions, "depth", &newOpts.depth))
|
||||||
|
newOpts.depth = true;
|
||||||
|
|
||||||
|
if (!GetBoolFromPropertyBag(aOptions, "alpha", &newOpts.alpha))
|
||||||
|
newOpts.alpha = true;
|
||||||
|
|
||||||
|
if (!GetBoolFromPropertyBag(aOptions, "premultipliedAlpha", &newOpts.premultipliedAlpha))
|
||||||
|
newOpts.premultipliedAlpha = true;
|
||||||
|
|
||||||
|
GetBoolFromPropertyBag(aOptions, "antialiasHint", &newOpts.antialiasHint);
|
||||||
|
|
||||||
|
// enforce that if stencil is specified, we also give back depth
|
||||||
|
newOpts.depth |= newOpts.stencil;
|
||||||
|
|
||||||
|
LogMessage("aaHint: %d stencil: %d depth: %d alpha: %d premult: %d\n",
|
||||||
|
newOpts.antialiasHint ? 1 : 0,
|
||||||
|
newOpts.stencil ? 1 : 0,
|
||||||
|
newOpts.depth ? 1 : 0,
|
||||||
|
newOpts.alpha ? 1 : 0,
|
||||||
|
newOpts.premultipliedAlpha ? 1 : 0);
|
||||||
|
|
||||||
|
if (mOptionsFrozen && newOpts != mOptions) {
|
||||||
|
// Error if the options are already frozen, and the ones that were asked for
|
||||||
|
// aren't the same as what they were originally.
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
mOptions = newOpts;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
WebGLContext::SetDimensions(PRInt32 width, PRInt32 height)
|
WebGLContext::SetDimensions(PRInt32 width, PRInt32 height)
|
||||||
{
|
{
|
||||||
|
@ -300,8 +367,26 @@ WebGLContext::SetDimensions(PRInt32 width, PRInt32 height)
|
||||||
DestroyResourcesAndContext();
|
DestroyResourcesAndContext();
|
||||||
|
|
||||||
gl::ContextFormat format(gl::ContextFormat::BasicRGBA32);
|
gl::ContextFormat format(gl::ContextFormat::BasicRGBA32);
|
||||||
format.depth = 16;
|
if (mOptions.depth) {
|
||||||
format.minDepth = 1;
|
format.depth = 24;
|
||||||
|
format.minDepth = 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mOptions.stencil) {
|
||||||
|
format.stencil = 8;
|
||||||
|
format.minStencil = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mOptions.alpha) {
|
||||||
|
// Select 565; we won't/shouldn't hit this on the desktop,
|
||||||
|
// but let mobile know we're ok with it.
|
||||||
|
format.red = 5;
|
||||||
|
format.green = 6;
|
||||||
|
format.blue = 5;
|
||||||
|
|
||||||
|
format.alpha = 0;
|
||||||
|
format.minAlpha = 0;
|
||||||
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIPrefBranch> prefService = do_GetService(NS_PREFSERVICE_CONTRACTID);
|
nsCOMPtr<nsIPrefBranch> prefService = do_GetService(NS_PREFSERVICE_CONTRACTID);
|
||||||
NS_ENSURE_TRUE(prefService != nsnull, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(prefService != nsnull, NS_ERROR_FAILURE);
|
||||||
|
@ -421,6 +506,7 @@ WebGLContext::SetDimensions(PRInt32 width, PRInt32 height)
|
||||||
mWidth = width;
|
mWidth = width;
|
||||||
mHeight = height;
|
mHeight = height;
|
||||||
mResetLayer = PR_TRUE;
|
mResetLayer = PR_TRUE;
|
||||||
|
mOptionsFrozen = PR_TRUE;
|
||||||
|
|
||||||
// increment the generation number
|
// increment the generation number
|
||||||
++mGeneration;
|
++mGeneration;
|
||||||
|
@ -482,17 +568,20 @@ WebGLContext::GetInputStream(const char* aMimeType,
|
||||||
const PRUnichar* aEncoderOptions,
|
const PRUnichar* aEncoderOptions,
|
||||||
nsIInputStream **aStream)
|
nsIInputStream **aStream)
|
||||||
{
|
{
|
||||||
return NS_ERROR_FAILURE;
|
NS_ASSERTION(gl, "GetInputStream on invalid context?");
|
||||||
|
if (!gl)
|
||||||
// XXX fix this
|
|
||||||
#if 0
|
|
||||||
if (!mGLPbuffer ||
|
|
||||||
!mGLPbuffer->ThebesSurface())
|
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
nsRefPtr<gfxImageSurface> surf = new gfxImageSurface(gfxIntSize(mWidth, mHeight),
|
||||||
|
gfxASurface::ImageFormatARGB32);
|
||||||
|
if (surf->CairoStatus() != 0)
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
gl->ReadPixelsIntoImageSurface(0, 0, mWidth, mHeight, surf);
|
||||||
|
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
const char encoderPrefix[] = "@mozilla.org/image/encoder;2?type=";
|
const char encoderPrefix[] = "@mozilla.org/image/encoder;2?type=";
|
||||||
nsAutoArrayPtr<char> conid(new (std::nothrow) char[strlen(encoderPrefix) + strlen(aMimeType) + 1]);
|
nsAutoArrayPtr<char> conid(new char[strlen(encoderPrefix) + strlen(aMimeType) + 1]);
|
||||||
|
|
||||||
if (!conid)
|
if (!conid)
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
@ -504,45 +593,15 @@ WebGLContext::GetInputStream(const char* aMimeType,
|
||||||
if (!encoder)
|
if (!encoder)
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
nsAutoArrayPtr<PRUint8> imageBuffer(new (std::nothrow) PRUint8[mWidth * mHeight * 4]);
|
rv = encoder->InitFromData(surf->Data(),
|
||||||
if (!imageBuffer)
|
mWidth * mHeight * 4,
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
mWidth, mHeight,
|
||||||
|
surf->Stride(),
|
||||||
nsRefPtr<gfxImageSurface> imgsurf = new gfxImageSurface(imageBuffer.get(),
|
|
||||||
gfxIntSize(mWidth, mHeight),
|
|
||||||
mWidth * 4,
|
|
||||||
gfxASurface::ImageFormatARGB32);
|
|
||||||
|
|
||||||
if (!imgsurf || imgsurf->CairoStatus())
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
nsRefPtr<gfxContext> ctx = new gfxContext(imgsurf);
|
|
||||||
|
|
||||||
if (!ctx || ctx->HasError())
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
nsRefPtr<gfxASurface> surf = mGLPbuffer->ThebesSurface();
|
|
||||||
nsRefPtr<gfxPattern> pat = CanvasGLThebes::CreatePattern(surf);
|
|
||||||
gfxMatrix m;
|
|
||||||
m.Translate(gfxPoint(0.0, mGLPbuffer->Height()));
|
|
||||||
m.Scale(1.0, -1.0);
|
|
||||||
pat->SetMatrix(m);
|
|
||||||
|
|
||||||
// XXX I don't want to use PixelSnapped here, but layout doesn't guarantee
|
|
||||||
// pixel alignment for this stuff!
|
|
||||||
ctx->NewPath();
|
|
||||||
ctx->PixelSnappedRectangleAndSetPattern(gfxRect(0, 0, mWidth, mHeight), pat);
|
|
||||||
ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
|
||||||
ctx->Fill();
|
|
||||||
|
|
||||||
rv = encoder->InitFromData(imageBuffer.get(),
|
|
||||||
mWidth * mHeight * 4, mWidth, mHeight, mWidth * 4,
|
|
||||||
imgIEncoder::INPUT_FORMAT_HOSTARGB,
|
imgIEncoder::INPUT_FORMAT_HOSTARGB,
|
||||||
nsDependentString(aEncoderOptions));
|
nsDependentString(aEncoderOptions));
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
return CallQueryInterface(encoder, aStream);
|
return CallQueryInterface(encoder, aStream);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
@ -589,7 +648,7 @@ WebGLContext::GetCanvasLayer(CanvasLayer *aOldLayer,
|
||||||
}
|
}
|
||||||
|
|
||||||
data.mSize = nsIntSize(mWidth, mHeight);
|
data.mSize = nsIntSize(mWidth, mHeight);
|
||||||
data.mGLBufferIsPremultiplied = PR_FALSE;
|
data.mGLBufferIsPremultiplied = mOptions.premultipliedAlpha ? PR_TRUE : PR_FALSE;
|
||||||
|
|
||||||
canvasLayer->Initialize(data);
|
canvasLayer->Initialize(data);
|
||||||
PRUint32 flags = gl->CreationFormat().alpha == 0 ? Layer::CONTENT_OPAQUE : 0;
|
PRUint32 flags = gl->CreationFormat().alpha == 0 ? Layer::CONTENT_OPAQUE : 0;
|
||||||
|
@ -602,12 +661,46 @@ WebGLContext::GetCanvasLayer(CanvasLayer *aOldLayer,
|
||||||
return canvasLayer.forget().get();
|
return canvasLayer.forget().get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
WebGLContext::GetContextAttributes(jsval *aResult)
|
||||||
|
{
|
||||||
|
JSContext *cx = nsContentUtils::GetCurrentJSContext();
|
||||||
|
if (!cx)
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
JSObject *obj = JS_NewObject(cx, NULL, NULL, NULL);
|
||||||
|
if (!obj)
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
*aResult = OBJECT_TO_JSVAL(obj);
|
||||||
|
|
||||||
|
gl::ContextFormat cf = gl->ActualFormat();
|
||||||
|
|
||||||
|
if (!JS_DefineProperty(cx, obj, "alpha", cf.alpha > 0 ? JSVAL_TRUE : JSVAL_FALSE,
|
||||||
|
NULL, NULL, JSPROP_ENUMERATE) ||
|
||||||
|
!JS_DefineProperty(cx, obj, "depth", cf.depth > 0 ? JSVAL_TRUE : JSVAL_FALSE,
|
||||||
|
NULL, NULL, JSPROP_ENUMERATE) ||
|
||||||
|
!JS_DefineProperty(cx, obj, "stencil", cf.stencil > 0 ? JSVAL_TRUE : JSVAL_FALSE,
|
||||||
|
NULL, NULL, JSPROP_ENUMERATE) ||
|
||||||
|
!JS_DefineProperty(cx, obj, "antialias", JSVAL_FALSE,
|
||||||
|
NULL, NULL, JSPROP_ENUMERATE) ||
|
||||||
|
!JS_DefineProperty(cx, obj, "premultipliedAlpha",
|
||||||
|
mOptions.premultipliedAlpha ? JSVAL_TRUE : JSVAL_FALSE,
|
||||||
|
NULL, NULL, JSPROP_ENUMERATE))
|
||||||
|
{
|
||||||
|
*aResult = JSVAL_VOID;
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// XPCOM goop
|
// XPCOM goop
|
||||||
//
|
//
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTING_ADDREF_AMBIGUOUS(WebGLContext, nsICanvasRenderingContextWebGL)
|
NS_IMPL_CYCLE_COLLECTING_ADDREF_AMBIGUOUS(WebGLContext, nsIDOMWebGLRenderingContext)
|
||||||
NS_IMPL_CYCLE_COLLECTING_RELEASE_AMBIGUOUS(WebGLContext, nsICanvasRenderingContextWebGL)
|
NS_IMPL_CYCLE_COLLECTING_RELEASE_AMBIGUOUS(WebGLContext, nsIDOMWebGLRenderingContext)
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_CLASS(WebGLContext)
|
NS_IMPL_CYCLE_COLLECTION_CLASS(WebGLContext)
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(WebGLContext)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(WebGLContext)
|
||||||
|
@ -620,10 +713,10 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||||
DOMCI_DATA(CanvasRenderingContextWebGL, WebGLContext)
|
DOMCI_DATA(CanvasRenderingContextWebGL, WebGLContext)
|
||||||
|
|
||||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WebGLContext)
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WebGLContext)
|
||||||
NS_INTERFACE_MAP_ENTRY(nsICanvasRenderingContextWebGL)
|
NS_INTERFACE_MAP_ENTRY(nsIDOMWebGLRenderingContext)
|
||||||
NS_INTERFACE_MAP_ENTRY(nsICanvasRenderingContextInternal)
|
NS_INTERFACE_MAP_ENTRY(nsICanvasRenderingContextInternal)
|
||||||
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
|
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
|
||||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsICanvasRenderingContextWebGL)
|
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMWebGLRenderingContext)
|
||||||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CanvasRenderingContextWebGL)
|
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CanvasRenderingContextWebGL)
|
||||||
NS_INTERFACE_MAP_END
|
NS_INTERFACE_MAP_END
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@
|
||||||
|
|
||||||
#include "nsIDocShell.h"
|
#include "nsIDocShell.h"
|
||||||
|
|
||||||
#include "nsICanvasRenderingContextWebGL.h"
|
#include "nsIDOMWebGLRenderingContext.h"
|
||||||
#include "nsICanvasRenderingContextInternal.h"
|
#include "nsICanvasRenderingContextInternal.h"
|
||||||
#include "nsHTMLCanvasElement.h"
|
#include "nsHTMLCanvasElement.h"
|
||||||
#include "nsWeakReference.h"
|
#include "nsWeakReference.h"
|
||||||
|
@ -67,6 +67,7 @@
|
||||||
#define CONTEXT_LOST_WEBGL 0x9242
|
#define CONTEXT_LOST_WEBGL 0x9242
|
||||||
|
|
||||||
class nsIDocShell;
|
class nsIDocShell;
|
||||||
|
class nsIPropertyBag;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
|
@ -235,8 +236,10 @@ private:
|
||||||
class WebGLBuffer;
|
class WebGLBuffer;
|
||||||
|
|
||||||
struct WebGLVertexAttribData {
|
struct WebGLVertexAttribData {
|
||||||
|
// note that these initial values are what GL initializes vertex attribs to
|
||||||
WebGLVertexAttribData()
|
WebGLVertexAttribData()
|
||||||
: buf(0), stride(0), size(0), byteOffset(0), type(0), enabled(PR_FALSE), normalized(PR_FALSE)
|
: buf(0), stride(0), size(4), byteOffset(0),
|
||||||
|
type(LOCAL_GL_FLOAT), enabled(PR_FALSE), normalized(PR_FALSE)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
WebGLObjectRefPtr<WebGLBuffer> buf;
|
WebGLObjectRefPtr<WebGLBuffer> buf;
|
||||||
|
@ -277,8 +280,41 @@ struct WebGLVertexAttribData {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct WebGLContextOptions {
|
||||||
|
// these are defaults
|
||||||
|
WebGLContextOptions()
|
||||||
|
: alpha(true), depth(true), stencil(false),
|
||||||
|
premultipliedAlpha(true), antialiasHint(false)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
bool operator==(const WebGLContextOptions& other) const {
|
||||||
|
return
|
||||||
|
alpha == other.alpha &&
|
||||||
|
depth == other.depth &&
|
||||||
|
stencil == other.stencil &&
|
||||||
|
premultipliedAlpha == other.premultipliedAlpha &&
|
||||||
|
antialiasHint == other.antialiasHint;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const WebGLContextOptions& other) const {
|
||||||
|
return
|
||||||
|
alpha != other.alpha ||
|
||||||
|
depth != other.depth ||
|
||||||
|
stencil != other.stencil ||
|
||||||
|
premultipliedAlpha != other.premultipliedAlpha ||
|
||||||
|
antialiasHint != other.antialiasHint;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool alpha;
|
||||||
|
bool depth;
|
||||||
|
bool stencil;
|
||||||
|
|
||||||
|
bool premultipliedAlpha;
|
||||||
|
bool antialiasHint;
|
||||||
|
};
|
||||||
|
|
||||||
class WebGLContext :
|
class WebGLContext :
|
||||||
public nsICanvasRenderingContextWebGL,
|
public nsIDOMWebGLRenderingContext,
|
||||||
public nsICanvasRenderingContextInternal,
|
public nsICanvasRenderingContextInternal,
|
||||||
public nsSupportsWeakReference
|
public nsSupportsWeakReference
|
||||||
{
|
{
|
||||||
|
@ -288,9 +324,9 @@ public:
|
||||||
|
|
||||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||||
|
|
||||||
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(WebGLContext, nsICanvasRenderingContextWebGL)
|
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(WebGLContext, nsIDOMWebGLRenderingContext)
|
||||||
|
|
||||||
NS_DECL_NSICANVASRENDERINGCONTEXTWEBGL
|
NS_DECL_NSIDOMWEBGLRENDERINGCONTEXT
|
||||||
|
|
||||||
// nsICanvasRenderingContextInternal
|
// nsICanvasRenderingContextInternal
|
||||||
NS_IMETHOD SetCanvasElement(nsHTMLCanvasElement* aParentCanvas);
|
NS_IMETHOD SetCanvasElement(nsHTMLCanvasElement* aParentCanvas);
|
||||||
|
@ -305,6 +341,8 @@ public:
|
||||||
nsIInputStream **aStream);
|
nsIInputStream **aStream);
|
||||||
NS_IMETHOD GetThebesSurface(gfxASurface **surface);
|
NS_IMETHOD GetThebesSurface(gfxASurface **surface);
|
||||||
NS_IMETHOD SetIsOpaque(PRBool b) { return NS_OK; };
|
NS_IMETHOD SetIsOpaque(PRBool b) { return NS_OK; };
|
||||||
|
NS_IMETHOD SetContextOptions(nsIPropertyBag *aOptions);
|
||||||
|
|
||||||
NS_IMETHOD SetIsIPC(PRBool b) { return NS_ERROR_NOT_IMPLEMENTED; }
|
NS_IMETHOD SetIsIPC(PRBool b) { return NS_ERROR_NOT_IMPLEMENTED; }
|
||||||
NS_IMETHOD Redraw(const gfxRect&) { return NS_ERROR_NOT_IMPLEMENTED; }
|
NS_IMETHOD Redraw(const gfxRect&) { return NS_ERROR_NOT_IMPLEMENTED; }
|
||||||
NS_IMETHOD Swap(mozilla::ipc::Shmem& aBack,
|
NS_IMETHOD Swap(mozilla::ipc::Shmem& aBack,
|
||||||
|
@ -360,9 +398,12 @@ protected:
|
||||||
PRInt32 mWidth, mHeight;
|
PRInt32 mWidth, mHeight;
|
||||||
CheckedUint32 mGeneration;
|
CheckedUint32 mGeneration;
|
||||||
|
|
||||||
|
WebGLContextOptions mOptions;
|
||||||
|
|
||||||
PRPackedBool mInvalidated;
|
PRPackedBool mInvalidated;
|
||||||
PRPackedBool mResetLayer;
|
PRPackedBool mResetLayer;
|
||||||
PRPackedBool mVerbose;
|
PRPackedBool mVerbose;
|
||||||
|
PRPackedBool mOptionsFrozen;
|
||||||
|
|
||||||
WebGLuint mActiveTexture;
|
WebGLuint mActiveTexture;
|
||||||
WebGLenum mSynthesizedGLError;
|
WebGLenum mSynthesizedGLError;
|
||||||
|
@ -729,13 +770,14 @@ public:
|
||||||
NS_DECL_NSIWEBGLTEXTURE
|
NS_DECL_NSIWEBGLTEXTURE
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
friend class WebGLContext;
|
||||||
|
friend class WebGLFramebuffer;
|
||||||
|
|
||||||
PRBool mDeleted;
|
PRBool mDeleted;
|
||||||
WebGLuint mName;
|
WebGLuint mName;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
// we store information about the various images that are part of
|
||||||
/////// everything below that point is only used for the texture completeness/npot business
|
// this texture (cubemap faces, mipmap levels)
|
||||||
/////// (sections 3.7.10 and 3.8.2 in GL ES 2.0.24 spec)
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
struct ImageInfo {
|
struct ImageInfo {
|
||||||
ImageInfo() : mWidth(0), mHeight(0), mFormat(0), mType(0), mIsDefined(PR_FALSE) {}
|
ImageInfo() : mWidth(0), mHeight(0), mFormat(0), mType(0), mIsDefined(PR_FALSE) {}
|
||||||
|
@ -1211,21 +1253,21 @@ public:
|
||||||
return mAttachedShaders.RemoveElement(shader);
|
return mAttachedShaders.RemoveElement(shader);
|
||||||
}
|
}
|
||||||
|
|
||||||
PRBool HasBothShaderTypesAttached() {
|
PRBool HasAttachedShaderOfType(GLenum shaderType) {
|
||||||
PRBool haveVertex = PR_FALSE;
|
|
||||||
PRBool haveFrag = PR_FALSE;
|
|
||||||
for (PRUint32 i = 0; i < mAttachedShaders.Length(); ++i) {
|
for (PRUint32 i = 0; i < mAttachedShaders.Length(); ++i) {
|
||||||
if (mAttachedShaders[i]->ShaderType() == LOCAL_GL_FRAGMENT_SHADER)
|
if (mAttachedShaders[i]->ShaderType() == shaderType) {
|
||||||
haveFrag = PR_TRUE;
|
|
||||||
else if (mAttachedShaders[i]->ShaderType() == LOCAL_GL_VERTEX_SHADER)
|
|
||||||
haveVertex = PR_TRUE;
|
|
||||||
if (haveFrag && haveVertex)
|
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PRBool HasBothShaderTypesAttached() {
|
||||||
|
return
|
||||||
|
HasAttachedShaderOfType(LOCAL_GL_VERTEX_SHADER) &&
|
||||||
|
HasAttachedShaderOfType(LOCAL_GL_FRAGMENT_SHADER);
|
||||||
|
}
|
||||||
|
|
||||||
PRBool NextGeneration()
|
PRBool NextGeneration()
|
||||||
{
|
{
|
||||||
if (!(mGeneration+1).valid())
|
if (!(mGeneration+1).valid())
|
||||||
|
@ -1328,6 +1370,7 @@ public:
|
||||||
WebGLFramebuffer(WebGLContext *context, WebGLuint name) :
|
WebGLFramebuffer(WebGLContext *context, WebGLuint name) :
|
||||||
WebGLContextBoundObject(context),
|
WebGLContextBoundObject(context),
|
||||||
mName(name), mDeleted(PR_FALSE),
|
mName(name), mDeleted(PR_FALSE),
|
||||||
|
mColorAttachment0HasAlpha(PR_FALSE),
|
||||||
mHasDepthAttachment(PR_FALSE),
|
mHasDepthAttachment(PR_FALSE),
|
||||||
mHasStencilAttachment(PR_FALSE),
|
mHasStencilAttachment(PR_FALSE),
|
||||||
mHasDepthStencilAttachment(PR_FALSE)
|
mHasDepthStencilAttachment(PR_FALSE)
|
||||||
|
@ -1342,6 +1385,8 @@ public:
|
||||||
PRBool Deleted() { return mDeleted; }
|
PRBool Deleted() { return mDeleted; }
|
||||||
WebGLuint GLName() { return mName; }
|
WebGLuint GLName() { return mName; }
|
||||||
|
|
||||||
|
PRBool ColorAttachment0HasAlpha() { return mColorAttachment0HasAlpha; }
|
||||||
|
|
||||||
nsresult FramebufferRenderbuffer(WebGLenum target,
|
nsresult FramebufferRenderbuffer(WebGLenum target,
|
||||||
WebGLenum attachment,
|
WebGLenum attachment,
|
||||||
WebGLenum rbtarget,
|
WebGLenum rbtarget,
|
||||||
|
@ -1405,15 +1450,20 @@ public:
|
||||||
{
|
{
|
||||||
return mContext->ErrorInvalidOperation(badAttachmentFormatMsg);
|
return mContext->ErrorInvalidOperation(badAttachmentFormatMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ReadPixels needs alpha and size information, but only
|
||||||
|
// for COLOR_ATTACHMENT0
|
||||||
|
if (attachment == LOCAL_GL_COLOR_ATTACHMENT0) {
|
||||||
|
setDimensions(wrb);
|
||||||
|
mColorAttachment0HasAlpha = InternalFormatHasAlpha(wrb->mInternalFormat);
|
||||||
|
} else {
|
||||||
|
mColorAttachment0HasAlpha = PR_FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mColorRenderbufferAttachment = wrb;
|
mColorRenderbufferAttachment = wrb;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// dimensions are kept for readPixels primarily, function only uses COLOR_ATTACHMENT0
|
|
||||||
if (attachment == LOCAL_GL_COLOR_ATTACHMENT0)
|
|
||||||
setDimensions(wrb);
|
|
||||||
|
|
||||||
mContext->MakeContextCurrent();
|
mContext->MakeContextCurrent();
|
||||||
mContext->gl->fFramebufferRenderbuffer(target, attachment, rbtarget, renderbuffername);
|
mContext->gl->fFramebufferRenderbuffer(target, attachment, rbtarget, renderbuffername);
|
||||||
|
|
||||||
|
@ -1460,14 +1510,26 @@ public:
|
||||||
{
|
{
|
||||||
return mContext->ErrorInvalidEnumInfo("framebufferTexture2D: attachment", attachment);
|
return mContext->ErrorInvalidEnumInfo("framebufferTexture2D: attachment", attachment);
|
||||||
}
|
}
|
||||||
// nothing to do for color buffers. all textures have a color-renderable format.
|
|
||||||
|
// keep data for readPixels, function only uses COLOR_ATTACHMENT0
|
||||||
|
if (attachment == LOCAL_GL_COLOR_ATTACHMENT0) {
|
||||||
|
setDimensions(wtex);
|
||||||
|
|
||||||
|
if (wtex) {
|
||||||
|
const WebGLTexture::ImageInfo& ia = wtex->ImageInfoAt
|
||||||
|
(level, textarget == LOCAL_GL_TEXTURE_2D
|
||||||
|
? 0
|
||||||
|
: textarget - LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X);
|
||||||
|
mColorAttachment0HasAlpha = InternalFormatHasAlpha(ia.mFormat);
|
||||||
|
} else {
|
||||||
|
mColorAttachment0HasAlpha = PR_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// nothing else to do for color buffers. all textures have a color-renderable format.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// dimensions are kept for readPixels primarily, function only uses COLOR_ATTACHMENT0
|
|
||||||
if (attachment == LOCAL_GL_COLOR_ATTACHMENT0)
|
|
||||||
setDimensions(wtex);
|
|
||||||
|
|
||||||
mContext->MakeContextCurrent();
|
mContext->MakeContextCurrent();
|
||||||
mContext->gl->fFramebufferTexture2D(target, attachment, textarget, texturename, level);
|
mContext->gl->fFramebufferTexture2D(target, attachment, textarget, texturename, level);
|
||||||
|
|
||||||
|
@ -1501,6 +1563,14 @@ public:
|
||||||
int(mHasDepthStencilAttachment) > 1;
|
int(mHasDepthStencilAttachment) > 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PRBool InternalFormatHasAlpha(WebGLenum aInternalFormat) {
|
||||||
|
return
|
||||||
|
aInternalFormat == LOCAL_GL_RGBA ||
|
||||||
|
aInternalFormat == LOCAL_GL_ALPHA ||
|
||||||
|
aInternalFormat == LOCAL_GL_RGBA4 ||
|
||||||
|
aInternalFormat == LOCAL_GL_RGB5_A1;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// protected because WebGLContext should only call InitializeRenderbuffers
|
// protected because WebGLContext should only call InitializeRenderbuffers
|
||||||
|
@ -1605,7 +1675,8 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
WebGLuint mName;
|
WebGLuint mName;
|
||||||
PRBool mDeleted;
|
PRPackedBool mDeleted;
|
||||||
|
PRPackedBool mColorAttachment0HasAlpha;
|
||||||
|
|
||||||
// we only store pointers to attached renderbuffers, not to attached textures, because
|
// we only store pointers to attached renderbuffers, not to attached textures, because
|
||||||
// we will only need to initialize renderbuffers. Textures are already initialized.
|
// we will only need to initialize renderbuffers. Textures are already initialized.
|
||||||
|
|
|
@ -123,18 +123,17 @@ WebGLProgram::GetUniformLocationObject(GLint glLocation)
|
||||||
return loc.forget();
|
return loc.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PRBool
|
||||||
|
InternalFormatHasAlpha(WebGLenum aInternalFormat) {
|
||||||
|
return aInternalFormat == LOCAL_GL_RGBA4 ||
|
||||||
|
aInternalFormat == LOCAL_GL_RGB5_A1;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// WebGL API
|
// WebGL API
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
/* void present (); */
|
|
||||||
NS_IMETHODIMP
|
|
||||||
WebGLContext::Present()
|
|
||||||
{
|
|
||||||
return NS_ERROR_NOT_IMPLEMENTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* void GlActiveTexture (in GLenum texture); */
|
/* void GlActiveTexture (in GLenum texture); */
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
WebGLContext::ActiveTexture(WebGLenum texture)
|
WebGLContext::ActiveTexture(WebGLenum texture)
|
||||||
|
@ -163,6 +162,12 @@ WebGLContext::AttachShader(nsIWebGLProgram *pobj, nsIWebGLShader *shobj)
|
||||||
!GetConcreteObjectAndGLName("attachShader: shader", shobj, &shader, &shadername))
|
!GetConcreteObjectAndGLName("attachShader: shader", shobj, &shader, &shadername))
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
||||||
|
// Per GLSL ES 2.0, we can only have one of each type of shader
|
||||||
|
// attached. This renders the next test somewhat moot, but we'll
|
||||||
|
// leave it for when we support more than one shader of each type.
|
||||||
|
if (program->HasAttachedShaderOfType(shader->ShaderType()))
|
||||||
|
return ErrorInvalidOperation("AttachShader: only one of each type of shader may be attached to a program");
|
||||||
|
|
||||||
if (!program->AttachShader(shader))
|
if (!program->AttachShader(shader))
|
||||||
return ErrorInvalidOperation("AttachShader: shader is already attached");
|
return ErrorInvalidOperation("AttachShader: shader is already attached");
|
||||||
|
|
||||||
|
@ -540,6 +545,11 @@ WebGLContext::Clear(PRUint32 mask)
|
||||||
if (mBoundFramebuffer && !mBoundFramebuffer->CheckAndInitializeRenderbuffers())
|
if (mBoundFramebuffer && !mBoundFramebuffer->CheckAndInitializeRenderbuffers())
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
||||||
|
PRUint32 m = mask & (LOCAL_GL_COLOR_BUFFER_BIT | LOCAL_GL_DEPTH_BUFFER_BIT | LOCAL_GL_STENCIL_BUFFER_BIT);
|
||||||
|
if (mask != m) {
|
||||||
|
return ErrorInvalidValue("clear: invalid mask bits");
|
||||||
|
}
|
||||||
|
|
||||||
gl->fClear(mask);
|
gl->fClear(mask);
|
||||||
Invalidate();
|
Invalidate();
|
||||||
|
|
||||||
|
@ -1433,7 +1443,6 @@ WebGLContext::GetParameter(PRUint32 pname, nsIVariant **retval)
|
||||||
case LOCAL_GL_CULL_FACE_MODE:
|
case LOCAL_GL_CULL_FACE_MODE:
|
||||||
case LOCAL_GL_FRONT_FACE:
|
case LOCAL_GL_FRONT_FACE:
|
||||||
case LOCAL_GL_ACTIVE_TEXTURE:
|
case LOCAL_GL_ACTIVE_TEXTURE:
|
||||||
case LOCAL_GL_DEPTH_CLEAR_VALUE:
|
|
||||||
case LOCAL_GL_STENCIL_CLEAR_VALUE:
|
case LOCAL_GL_STENCIL_CLEAR_VALUE:
|
||||||
case LOCAL_GL_STENCIL_FUNC:
|
case LOCAL_GL_STENCIL_FUNC:
|
||||||
case LOCAL_GL_STENCIL_REF:
|
case LOCAL_GL_STENCIL_REF:
|
||||||
|
@ -1521,6 +1530,7 @@ WebGLContext::GetParameter(PRUint32 pname, nsIVariant **retval)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// float
|
// float
|
||||||
|
case LOCAL_GL_DEPTH_CLEAR_VALUE:
|
||||||
case LOCAL_GL_LINE_WIDTH:
|
case LOCAL_GL_LINE_WIDTH:
|
||||||
case LOCAL_GL_POLYGON_OFFSET_FACTOR:
|
case LOCAL_GL_POLYGON_OFFSET_FACTOR:
|
||||||
case LOCAL_GL_POLYGON_OFFSET_UNITS:
|
case LOCAL_GL_POLYGON_OFFSET_UNITS:
|
||||||
|
@ -2470,30 +2480,31 @@ WebGLContext::ReadPixels_base(WebGLint x, WebGLint y, WebGLsizei width, WebGLsiz
|
||||||
WebGLsizei boundHeight = mBoundFramebuffer ? mBoundFramebuffer->height() : mHeight;
|
WebGLsizei boundHeight = mBoundFramebuffer ? mBoundFramebuffer->height() : mHeight;
|
||||||
|
|
||||||
PRUint32 size = 0;
|
PRUint32 size = 0;
|
||||||
|
bool badFormat = false, badType = false;
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case LOCAL_GL_ALPHA:
|
case LOCAL_GL_RGBA:
|
||||||
size = 1;
|
|
||||||
break;
|
|
||||||
case LOCAL_GL_RGB:
|
|
||||||
size = 3;
|
|
||||||
break;
|
|
||||||
case LOCAL_GL_RGBA:
|
|
||||||
size = 4;
|
size = 4;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return ErrorInvalidEnumInfo("readPixels: format", format);
|
badFormat = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
// case LOCAL_GL_UNSIGNED_SHORT_4_4_4_4:
|
case LOCAL_GL_UNSIGNED_BYTE:
|
||||||
// case LOCAL_GL_UNSIGNED_SHORT_5_5_5_1:
|
break;
|
||||||
// case LOCAL_GL_UNSIGNED_SHORT_5_6_5:
|
default:
|
||||||
case LOCAL_GL_UNSIGNED_BYTE:
|
badType = true;
|
||||||
break;
|
break;
|
||||||
default:
|
|
||||||
return ErrorInvalidEnumInfo("ReadPixels: type", type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (badFormat && badType)
|
||||||
|
return ErrorInvalidOperation("readPixels: bad format and type");
|
||||||
|
if (badFormat)
|
||||||
|
return ErrorInvalidEnumInfo("readPixels: format", format);
|
||||||
|
if (badType)
|
||||||
|
return ErrorInvalidEnumInfo("ReadPixels: type", type);
|
||||||
|
|
||||||
CheckedUint32 checked_plainRowSize = CheckedUint32(width) * size;
|
CheckedUint32 checked_plainRowSize = CheckedUint32(width) * size;
|
||||||
|
|
||||||
PRUint32 packAlignment = mPixelStorePackAlignment;
|
PRUint32 packAlignment = mPixelStorePackAlignment;
|
||||||
|
@ -2579,6 +2590,51 @@ WebGLContext::ReadPixels_base(WebGLint x, WebGLint y, WebGLsizei width, WebGLsiz
|
||||||
}
|
}
|
||||||
delete [] subrect_data;
|
delete [] subrect_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if we're reading alpha, we may need to do fixup
|
||||||
|
if (format == LOCAL_GL_ALPHA ||
|
||||||
|
format == LOCAL_GL_RGBA)
|
||||||
|
{
|
||||||
|
PRBool needAlphaFixup;
|
||||||
|
if (mBoundFramebuffer) {
|
||||||
|
needAlphaFixup = !mBoundFramebuffer->ColorAttachment0HasAlpha();
|
||||||
|
} else {
|
||||||
|
needAlphaFixup = gl->ActualFormat().alpha == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (needAlphaFixup) {
|
||||||
|
if (format == LOCAL_GL_ALPHA && type == LOCAL_GL_UNSIGNED_BYTE) {
|
||||||
|
// this is easy; it's an 0xff memset per row
|
||||||
|
PRUint8 *row = (PRUint8*)data;
|
||||||
|
for (GLint j = 0; j < height; ++j) {
|
||||||
|
memset(row, 0xff, checked_plainRowSize.value());
|
||||||
|
row += checked_alignedRowSize.value();
|
||||||
|
}
|
||||||
|
} else if (format == LOCAL_GL_RGBA && type == LOCAL_GL_UNSIGNED_BYTE) {
|
||||||
|
// this is harder, we need to just set the alpha byte here
|
||||||
|
PRUint8 *row = (PRUint8*)data;
|
||||||
|
for (GLint j = 0; j < height; ++j) {
|
||||||
|
PRUint8 *rowp = row;
|
||||||
|
#ifdef IS_LITTLE_ENDIAN
|
||||||
|
// offset to get the alpha byte; we're always going to
|
||||||
|
// move by 4 bytes
|
||||||
|
rowp += 3;
|
||||||
|
#endif
|
||||||
|
PRUint8 *endrowp = rowp + 4 * width;
|
||||||
|
while (rowp != endrowp) {
|
||||||
|
*rowp = 0xff;
|
||||||
|
rowp += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
row += checked_alignedRowSize.value();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
NS_WARNING("Unhandled case, how'd we get here?");
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3767,7 +3823,7 @@ WebGLContext::TexSubImage2D_base(WebGLenum target, WebGLint level,
|
||||||
PRUint32 bytesNeeded = checked_neededByteLength.value();
|
PRUint32 bytesNeeded = checked_neededByteLength.value();
|
||||||
|
|
||||||
if (byteLength < bytesNeeded)
|
if (byteLength < bytesNeeded)
|
||||||
return ErrorInvalidValue("texSubImage2D: not enough data for operation (need %d, have %d)", bytesNeeded, byteLength);
|
return ErrorInvalidOperation("texSubImage2D: not enough data for operation (need %d, have %d)", bytesNeeded, byteLength);
|
||||||
|
|
||||||
WebGLTexture *tex = activeBoundTextureForTarget(target);
|
WebGLTexture *tex = activeBoundTextureForTarget(target);
|
||||||
|
|
||||||
|
@ -3880,129 +3936,6 @@ WebGLContext::TexSubImage2D_dom(WebGLenum target, WebGLint level,
|
||||||
srcFormat, PR_TRUE);
|
srcFormat, PR_TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
// ImageData getImageData (in float x, in float y, in float width, in float height);
|
|
||||||
NS_IMETHODIMP
|
|
||||||
WebGLContext::GetImageData(PRUint32 x, PRUint32 y, PRUint32 w, PRUint32 h)
|
|
||||||
{
|
|
||||||
// disabled due to win32 linkage issues with thebes symbols and NS_RELEASE
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
NativeJSContext js;
|
|
||||||
if (NS_FAILED(js.error))
|
|
||||||
return js.error;
|
|
||||||
|
|
||||||
if (js.argc != 4) return NS_ERROR_INVALID_ARG;
|
|
||||||
|
|
||||||
if (!mGLPbuffer ||
|
|
||||||
!mGLPbuffer->ThebesSurface())
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
if (!mCanvasElement)
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
if (HTMLCanvasElement()->IsWriteOnly() && !IsCallerTrustedForRead()) {
|
|
||||||
// XXX ERRMSG we need to report an error to developers here! (bug 329026)
|
|
||||||
return NS_ERROR_DOM_SECURITY_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
JSContext *ctx = js.ctx;
|
|
||||||
|
|
||||||
if (!CanvasUtils::CheckSaneSubrectSize (x, y, w, h, mWidth, mHeight))
|
|
||||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
|
||||||
|
|
||||||
nsAutoArrayPtr<PRUint8> surfaceData (new (std::nothrow) PRUint8[w * h * 4]);
|
|
||||||
int surfaceDataStride = w*4;
|
|
||||||
int surfaceDataOffset = 0;
|
|
||||||
|
|
||||||
if (!surfaceData)
|
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
|
||||||
|
|
||||||
nsRefPtr<gfxImageSurface> tmpsurf = new gfxImageSurface(surfaceData,
|
|
||||||
gfxIntSize(w, h),
|
|
||||||
w * 4,
|
|
||||||
gfxASurface::ImageFormatARGB32);
|
|
||||||
if (!tmpsurf || tmpsurf->CairoStatus())
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
nsRefPtr<gfxContext> tmpctx = new gfxContext(tmpsurf);
|
|
||||||
|
|
||||||
if (!tmpctx || tmpctx->HasError())
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
nsRefPtr<gfxASurface> surf = mGLPbuffer->ThebesSurface();
|
|
||||||
nsRefPtr<gfxPattern> pat = CanvasGLThebes::CreatePattern(surf);
|
|
||||||
gfxMatrix m;
|
|
||||||
m.Translate(gfxPoint(x, mGLPbuffer->Height()-y));
|
|
||||||
m.Scale(1.0, -1.0);
|
|
||||||
pat->SetMatrix(m);
|
|
||||||
|
|
||||||
// XXX I don't want to use PixelSnapped here, but layout doesn't guarantee
|
|
||||||
// pixel alignment for this stuff!
|
|
||||||
tmpctx->NewPath();
|
|
||||||
tmpctx->PixelSnappedRectangleAndSetPattern(gfxRect(0, 0, w, h), pat);
|
|
||||||
tmpctx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
|
||||||
tmpctx->Fill();
|
|
||||||
|
|
||||||
tmpctx = nsnull;
|
|
||||||
tmpsurf = nsnull;
|
|
||||||
|
|
||||||
PRUint32 len = w * h * 4;
|
|
||||||
if (len > (((PRUint32)0xfff00000)/sizeof(jsval)))
|
|
||||||
return NS_ERROR_INVALID_ARG;
|
|
||||||
|
|
||||||
nsAutoArrayPtr<jsval> jsvector(new (std::nothrow) jsval[w * h * 4]);
|
|
||||||
if (!jsvector)
|
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
|
||||||
jsval *dest = jsvector.get();
|
|
||||||
PRUint8 *row;
|
|
||||||
for (PRUint32 j = 0; j < h; j++) {
|
|
||||||
row = surfaceData + surfaceDataOffset + (surfaceDataStride * j);
|
|
||||||
for (PRUint32 i = 0; i < w; i++) {
|
|
||||||
// XXX Is there some useful swizzle MMX we can use here?
|
|
||||||
// I guess we have to INT_TO_JSVAL still
|
|
||||||
#ifdef IS_LITTLE_ENDIAN
|
|
||||||
PRUint8 b = *row++;
|
|
||||||
PRUint8 g = *row++;
|
|
||||||
PRUint8 r = *row++;
|
|
||||||
PRUint8 a = *row++;
|
|
||||||
#else
|
|
||||||
PRUint8 a = *row++;
|
|
||||||
PRUint8 r = *row++;
|
|
||||||
PRUint8 g = *row++;
|
|
||||||
PRUint8 b = *row++;
|
|
||||||
#endif
|
|
||||||
// Convert to non-premultiplied color
|
|
||||||
if (a != 0) {
|
|
||||||
r = (r * 255) / a;
|
|
||||||
g = (g * 255) / a;
|
|
||||||
b = (b * 255) / a;
|
|
||||||
}
|
|
||||||
|
|
||||||
*dest++ = INT_TO_JSVAL(r);
|
|
||||||
*dest++ = INT_TO_JSVAL(g);
|
|
||||||
*dest++ = INT_TO_JSVAL(b);
|
|
||||||
*dest++ = INT_TO_JSVAL(a);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
JSObject *dataArray = JS_NewArrayObject(ctx, w*h*4, jsvector);
|
|
||||||
if (!dataArray)
|
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
|
||||||
|
|
||||||
JSObjectHelper retobj(&js);
|
|
||||||
retobj.DefineProperty("width", w);
|
|
||||||
retobj.DefineProperty("height", h);
|
|
||||||
retobj.DefineProperty("data", dataArray);
|
|
||||||
|
|
||||||
js.SetRetVal(retobj);
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PRBool
|
PRBool
|
||||||
BaseTypeAndSizeFromUniformType(WebGLenum uType, WebGLenum *baseType, WebGLint *unitSize)
|
BaseTypeAndSizeFromUniformType(WebGLenum uType, WebGLenum *baseType, WebGLint *unitSize)
|
||||||
{
|
{
|
||||||
|
|
|
@ -36,12 +36,12 @@
|
||||||
*
|
*
|
||||||
* ***** END LICENSE BLOCK ***** */
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
#include "nsICanvasRenderingContextWebGL.h"
|
#include "nsIDOMWebGLRenderingContext.h"
|
||||||
#include "nsDOMClassInfoID.h"
|
#include "nsDOMClassInfoID.h"
|
||||||
|
|
||||||
#define DUMMY(func,rtype) nsresult func (rtype ** aResult) { return NS_ERROR_FAILURE; }
|
#define DUMMY(func,rtype) nsresult func (rtype ** aResult) { return NS_ERROR_FAILURE; }
|
||||||
|
|
||||||
DUMMY(NS_NewCanvasRenderingContextWebGL, nsICanvasRenderingContextWebGL)
|
DUMMY(NS_NewCanvasRenderingContextWebGL, nsIDOMWebGLRenderingContext)
|
||||||
|
|
||||||
DOMCI_DATA(CanvasRenderingContextWebGL, void)
|
DOMCI_DATA(CanvasRenderingContextWebGL, void)
|
||||||
DOMCI_DATA(WebGLBuffer, void)
|
DOMCI_DATA(WebGLBuffer, void)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
This is a local copy of the WebGL conformance suite.
|
This is a local copy of the WebGL conformance suite.
|
||||||
|
|
||||||
SVN revision: 11955
|
SVN revision: 12905
|
||||||
|
|
||||||
The canonical location for this testsuite is:
|
The canonical location for this testsuite is:
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@ buffer-data-array-buffer.html
|
||||||
canvas-test.html
|
canvas-test.html
|
||||||
constants.html
|
constants.html
|
||||||
context-attributes-alpha-depth-stencil-antialias.html
|
context-attributes-alpha-depth-stencil-antialias.html
|
||||||
context-attributes.html
|
|
||||||
context-type-test.html
|
context-type-test.html
|
||||||
copy-tex-image-and-sub-image-2d.html
|
copy-tex-image-and-sub-image-2d.html
|
||||||
draw-arrays-out-of-bounds.html
|
draw-arrays-out-of-bounds.html
|
||||||
|
@ -17,11 +16,13 @@ framebuffer-object-attachment.html
|
||||||
framebuffer-test.html
|
framebuffer-test.html
|
||||||
get-active-test.html
|
get-active-test.html
|
||||||
gl-bind-attrib-location-test.html
|
gl-bind-attrib-location-test.html
|
||||||
|
gl-clear.html
|
||||||
gl-drawelements.html
|
gl-drawelements.html
|
||||||
gl-enable-enum-test.html
|
gl-enable-enum-test.html
|
||||||
gl-enable-vertex-attrib.html
|
gl-enable-vertex-attrib.html
|
||||||
gl-enum-tests.html
|
gl-enum-tests.html
|
||||||
gl-get-active-attribute.html
|
gl-get-active-attribute.html
|
||||||
|
gl-get-active-uniform.html
|
||||||
gl-get-calls.html
|
gl-get-calls.html
|
||||||
gl-getstring.html
|
gl-getstring.html
|
||||||
gl-object-get-calls.html
|
gl-object-get-calls.html
|
||||||
|
@ -45,10 +46,13 @@ index-validation-with-resized-buffer.html
|
||||||
index-validation.html
|
index-validation.html
|
||||||
invalid-UTF-16.html
|
invalid-UTF-16.html
|
||||||
invalid-passed-params.html
|
invalid-passed-params.html
|
||||||
|
is-object.html
|
||||||
methods.html
|
methods.html
|
||||||
more-than-65536-points.html
|
more-than-65536-points.html
|
||||||
null-object-behaviour.html
|
null-object-behaviour.html
|
||||||
null-uniform-location.html
|
null-uniform-location.html
|
||||||
|
object-deletion-behaviour.html
|
||||||
|
origin-clean-conformance.html
|
||||||
point-size.html
|
point-size.html
|
||||||
program-test.html
|
program-test.html
|
||||||
read-pixels-pack-alignment.html
|
read-pixels-pack-alignment.html
|
||||||
|
@ -72,7 +76,9 @@ texture-formats-test.html
|
||||||
texture-npot.html
|
texture-npot.html
|
||||||
texture-transparent-pixels-initialized.html
|
texture-transparent-pixels-initialized.html
|
||||||
triangle.html
|
triangle.html
|
||||||
#uniform-location.html
|
type-conversion-test.html
|
||||||
|
uniform-location.html
|
||||||
uniform-samplers-test.html
|
uniform-samplers-test.html
|
||||||
uninitialized-test.html
|
uninitialized-test.html
|
||||||
viewport-unchanged-upon-resize.html
|
viewport-unchanged-upon-resize.html
|
||||||
|
webgl-specific.html
|
||||||
|
|
|
@ -1,82 +0,0 @@
|
||||||
array-buffer-crash.html
|
|
||||||
array-buffer-view-crash.html
|
|
||||||
array-unit-tests.html
|
|
||||||
bad-arguments-test.html
|
|
||||||
buffer-bind-test.html
|
|
||||||
buffer-data-array-buffer.html
|
|
||||||
canvas-test.html
|
|
||||||
constants.html
|
|
||||||
context-attributes-alpha-depth-stencil-antialias.html
|
|
||||||
context-attributes.html
|
|
||||||
context-type-test.html
|
|
||||||
copy-tex-image-and-sub-image-2d.html
|
|
||||||
draw-arrays-out-of-bounds.html
|
|
||||||
draw-elements-out-of-bounds.html
|
|
||||||
error-reporting.html
|
|
||||||
framebuffer-object-attachment.html
|
|
||||||
framebuffer-test.html
|
|
||||||
get-active-test.html
|
|
||||||
gl-bind-attrib-location-test.html
|
|
||||||
gl-clear.html
|
|
||||||
gl-drawelements.html
|
|
||||||
gl-enable-enum-test.html
|
|
||||||
gl-enable-vertex-attrib.html
|
|
||||||
gl-enum-tests.html
|
|
||||||
gl-get-active-attribute.html
|
|
||||||
gl-get-active-uniform.html
|
|
||||||
gl-get-calls.html
|
|
||||||
gl-getstring.html
|
|
||||||
gl-object-get-calls.html
|
|
||||||
gl-pixelstorei.html
|
|
||||||
gl-scissor-test.html
|
|
||||||
gl-shader-test.html
|
|
||||||
gl-teximage.html
|
|
||||||
gl-uniform-arrays.html
|
|
||||||
gl-uniform-bool.html
|
|
||||||
gl-uniformmatrix4fv.html
|
|
||||||
gl-unknown-uniform.html
|
|
||||||
gl-vertex-attrib.html
|
|
||||||
gl-vertexattribpointer.html
|
|
||||||
glsl-2types-of-textures-on-same-unit.html
|
|
||||||
glsl-conformance.html
|
|
||||||
incorrect-context-object-behaviour.html
|
|
||||||
index-validation-copies-indices.html
|
|
||||||
index-validation-crash-with-buffer-sub-data.html
|
|
||||||
index-validation-verifies-too-many-indices.html
|
|
||||||
index-validation-with-resized-buffer.html
|
|
||||||
index-validation.html
|
|
||||||
invalid-UTF-16.html
|
|
||||||
invalid-passed-params.html
|
|
||||||
methods.html
|
|
||||||
more-than-65536-points.html
|
|
||||||
null-object-behaviour.html
|
|
||||||
null-uniform-location.html
|
|
||||||
object-deletion-behaviour.html
|
|
||||||
origin-clean-conformance.html
|
|
||||||
point-size.html
|
|
||||||
program-test.html
|
|
||||||
read-pixels-pack-alignment.html
|
|
||||||
read-pixels-test.html
|
|
||||||
renderbuffer-initialization.html
|
|
||||||
resource-sharing-test.html
|
|
||||||
tex-image-and-sub-image-2d-with-array-buffer-view.html
|
|
||||||
tex-image-and-sub-image-2d-with-image-data.html
|
|
||||||
tex-image-and-sub-image-2d-with-image.html
|
|
||||||
tex-image-and-sub-image-2d-with-video.html
|
|
||||||
tex-image-and-uniform-binding-bugs.html
|
|
||||||
tex-image-with-format-and-type.html
|
|
||||||
tex-image-with-invalid-data.html
|
|
||||||
tex-input-validation.html
|
|
||||||
tex-sub-image-2d.html
|
|
||||||
texparameter-test.html
|
|
||||||
texture-active-bind-2.html
|
|
||||||
texture-active-bind.html
|
|
||||||
texture-complete.html
|
|
||||||
texture-formats-test.html
|
|
||||||
texture-npot.html
|
|
||||||
texture-transparent-pixels-initialized.html
|
|
||||||
triangle.html
|
|
||||||
uniform-location.html
|
|
||||||
uniform-samplers-test.html
|
|
||||||
uninitialized-test.html
|
|
||||||
viewport-unchanged-upon-resize.html
|
|
|
@ -438,6 +438,15 @@ function testConstructionWithUnalignedOffset(type, name, elementSizeInBytes) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function testConstructionWithUnalignedLength(type, name, elementSizeInBytes) {
|
||||||
|
if (elementSizeInBytes > 1) {
|
||||||
|
shouldThrowIndexSizeErr(function() {
|
||||||
|
var buffer = new ArrayBuffer(elementSizeInBytes + 1);
|
||||||
|
var array = new type(buffer, 0);
|
||||||
|
}, "Construction of " + name + " with unaligned length");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function testConstructionOfHugeArray(type, name, sz) {
|
function testConstructionOfHugeArray(type, name, sz) {
|
||||||
if (sz == 1)
|
if (sz == 1)
|
||||||
return;
|
return;
|
||||||
|
@ -671,6 +680,7 @@ function runTests() {
|
||||||
testConstructionWithOutOfRangeValues(type, name);
|
testConstructionWithOutOfRangeValues(type, name);
|
||||||
testConstructionWithNegativeOutOfRangeValues(type, name);
|
testConstructionWithNegativeOutOfRangeValues(type, name);
|
||||||
testConstructionWithUnalignedOffset(type, name, testCase.elementSizeInBytes);
|
testConstructionWithUnalignedOffset(type, name, testCase.elementSizeInBytes);
|
||||||
|
testConstructionWithUnalignedLength(type, name, testCase.elementSizeInBytes);
|
||||||
testConstructionOfHugeArray(type, name, testCase.elementSizeInBytes);
|
testConstructionOfHugeArray(type, name, testCase.elementSizeInBytes);
|
||||||
testConstructionWithBothArrayBufferAndLength(type, name, testCase.elementSizeInBytes);
|
testConstructionWithBothArrayBufferAndLength(type, name, testCase.elementSizeInBytes);
|
||||||
testSlicingWithOutOfRangeValues(type, name, testCase.elementSizeInBytes);
|
testSlicingWithOutOfRangeValues(type, name, testCase.elementSizeInBytes);
|
||||||
|
|
|
@ -79,7 +79,6 @@ for (var i = 0; i < arguments.length; ++i) {
|
||||||
argument = arguments[i].value;
|
argument = arguments[i].value;
|
||||||
func("context.compileShader(argument)");
|
func("context.compileShader(argument)");
|
||||||
func("context.linkProgram(argument)");
|
func("context.linkProgram(argument)");
|
||||||
func("context.attachShader(argument)");
|
|
||||||
func("context.attachShader(program, argument)");
|
func("context.attachShader(program, argument)");
|
||||||
func("context.attachShader(argument, shader)");
|
func("context.attachShader(argument, shader)");
|
||||||
func("context.detachShader(program, argument)");
|
func("context.detachShader(program, argument)");
|
||||||
|
|
|
@ -33,6 +33,10 @@ glErrorShouldBe(gl, gl.INVALID_OPERATION);
|
||||||
gl.bindBuffer(gl.ARRAY_BUFFER, buf);
|
gl.bindBuffer(gl.ARRAY_BUFFER, buf);
|
||||||
glErrorShouldBe(gl, gl.NO_ERROR);
|
glErrorShouldBe(gl, gl.NO_ERROR);
|
||||||
|
|
||||||
|
// This should not crash, but the selection of the overload is ambiguous per Web IDL.
|
||||||
|
gl.bufferData(gl.ARRAY_BUFFER, null, gl.STATIC_DRAW);
|
||||||
|
gl.getError();
|
||||||
|
|
||||||
gl.bufferData(gl.ARRAY_BUFFER, array, gl.STATIC_DRAW);
|
gl.bufferData(gl.ARRAY_BUFFER, array, gl.STATIC_DRAW);
|
||||||
glErrorShouldBe(gl, gl.NO_ERROR);
|
glErrorShouldBe(gl, gl.NO_ERROR);
|
||||||
|
|
||||||
|
@ -41,6 +45,9 @@ array = new ArrayBuffer(64);
|
||||||
gl.bufferSubData(gl.ARRAY_BUFFER, 10, array);
|
gl.bufferSubData(gl.ARRAY_BUFFER, 10, array);
|
||||||
glErrorShouldBe(gl, gl.NO_ERROR);
|
glErrorShouldBe(gl, gl.NO_ERROR);
|
||||||
|
|
||||||
|
gl.bufferSubData(gl.ARRAY_BUFFER, 10, null);
|
||||||
|
glErrorShouldBe(gl, gl.NO_ERROR);
|
||||||
|
|
||||||
successfullyParsed = true;
|
successfullyParsed = true;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -375,10 +375,6 @@ VERTEX_ATTRIB_ARRAY_NORMALIZED : 0x886A,
|
||||||
VERTEX_ATTRIB_ARRAY_POINTER : 0x8645,
|
VERTEX_ATTRIB_ARRAY_POINTER : 0x8645,
|
||||||
VERTEX_ATTRIB_ARRAY_BUFFER_BINDING : 0x889F,
|
VERTEX_ATTRIB_ARRAY_BUFFER_BINDING : 0x889F,
|
||||||
|
|
||||||
/* Read Format */
|
|
||||||
IMPLEMENTATION_COLOR_READ_TYPE : 0x8B9A,
|
|
||||||
IMPLEMENTATION_COLOR_READ_FORMAT : 0x8B9B,
|
|
||||||
|
|
||||||
/* Shader Source */
|
/* Shader Source */
|
||||||
COMPILE_STATUS : 0x8B81,
|
COMPILE_STATUS : 0x8B81,
|
||||||
INFO_LOG_LENGTH : 0x8B84,
|
INFO_LOG_LENGTH : 0x8B84,
|
||||||
|
@ -403,6 +399,7 @@ RGB565 : 0x8D62,
|
||||||
DEPTH_COMPONENT16 : 0x81A5,
|
DEPTH_COMPONENT16 : 0x81A5,
|
||||||
STENCIL_INDEX : 0x1901,
|
STENCIL_INDEX : 0x1901,
|
||||||
STENCIL_INDEX8 : 0x8D48,
|
STENCIL_INDEX8 : 0x8D48,
|
||||||
|
DEPTH_STENCIL : 0x84F9,
|
||||||
|
|
||||||
RENDERBUFFER_WIDTH : 0x8D42,
|
RENDERBUFFER_WIDTH : 0x8D42,
|
||||||
RENDERBUFFER_HEIGHT : 0x8D43,
|
RENDERBUFFER_HEIGHT : 0x8D43,
|
||||||
|
@ -422,6 +419,7 @@ FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE : 0x8CD3,
|
||||||
COLOR_ATTACHMENT0 : 0x8CE0,
|
COLOR_ATTACHMENT0 : 0x8CE0,
|
||||||
DEPTH_ATTACHMENT : 0x8D00,
|
DEPTH_ATTACHMENT : 0x8D00,
|
||||||
STENCIL_ATTACHMENT : 0x8D20,
|
STENCIL_ATTACHMENT : 0x8D20,
|
||||||
|
DEPTH_STENCIL_ATTACHMENT : 0x821A,
|
||||||
|
|
||||||
NONE : 0,
|
NONE : 0,
|
||||||
|
|
||||||
|
@ -435,7 +433,14 @@ FRAMEBUFFER_BINDING : 0x8CA6,
|
||||||
RENDERBUFFER_BINDING : 0x8CA7,
|
RENDERBUFFER_BINDING : 0x8CA7,
|
||||||
MAX_RENDERBUFFER_SIZE : 0x84E8,
|
MAX_RENDERBUFFER_SIZE : 0x84E8,
|
||||||
|
|
||||||
INVALID_FRAMEBUFFER_OPERATION : 0x0506
|
INVALID_FRAMEBUFFER_OPERATION : 0x0506,
|
||||||
|
|
||||||
|
/* WebGL-specific enums */
|
||||||
|
UNPACK_FLIP_Y_WEBGL : 0x9240,
|
||||||
|
UNPACK_PREMULTIPLY_ALPHA_WEBGL : 0x9241,
|
||||||
|
CONTEXT_LOST_WEBGL : 0x9242,
|
||||||
|
UNPACK_COLORSPACE_CONVERSION_WEBGL : 0x9243,
|
||||||
|
BROWSER_DEFAULT_WEBGL : 0x9244
|
||||||
};
|
};
|
||||||
|
|
||||||
function assertProperty(v, p) {
|
function assertProperty(v, p) {
|
||||||
|
|
|
@ -54,66 +54,14 @@ function init()
|
||||||
|
|
||||||
function getWebGL(canvasName, contextAttribs, clearColor, clearDepth, clearStencil)
|
function getWebGL(canvasName, contextAttribs, clearColor, clearDepth, clearStencil)
|
||||||
{
|
{
|
||||||
var canvas = document.getElementById(canvasName);
|
var context = initWebGL(canvasName, "vshader", "fshader", ["pos", "colorIn"], clearColor, clearDepth, contextAttribs);
|
||||||
var gl = canvas.getContext("experimental-webgl", contextAttribs);
|
if (context) {
|
||||||
if (!gl) {
|
context.clearStencil(clearStencil);
|
||||||
alert("No WebGL context found");
|
context.enable(context.STENCIL_TEST);
|
||||||
return null;
|
context.disable(context.BLEND);
|
||||||
|
context.clear(context.COLOR_BUFFER_BIT | context.DEPTH_BUFFER_BIT | context.STENCIL_BUFFER_BIT);
|
||||||
}
|
}
|
||||||
var actualContextAttribs = gl.getContextAttributes();
|
return context;
|
||||||
|
|
||||||
// Add a console
|
|
||||||
gl.console = ("console" in window) ? window.console : { log: function() { } };
|
|
||||||
|
|
||||||
// create our shaders
|
|
||||||
var vertexShader = loadShader(gl, "vshader");
|
|
||||||
var fragmentShader = loadShader(gl, "fshader");
|
|
||||||
|
|
||||||
if (!vertexShader || !fragmentShader)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
// Create the program object
|
|
||||||
gl.program = gl.createProgram();
|
|
||||||
|
|
||||||
if (!gl.program)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
// Attach our two shaders to the program
|
|
||||||
gl.attachShader(gl.program, vertexShader);
|
|
||||||
gl.attachShader(gl.program, fragmentShader);
|
|
||||||
|
|
||||||
// Bind attributes
|
|
||||||
var attribs = [ "pos", "colorIn" ];
|
|
||||||
for (var i in attribs)
|
|
||||||
gl.bindAttribLocation(gl.program, i, attribs[i]);
|
|
||||||
|
|
||||||
// Link the program
|
|
||||||
gl.linkProgram(gl.program);
|
|
||||||
|
|
||||||
// Check the link status
|
|
||||||
var linked = gl.getProgramParameter(gl.program, gl.LINK_STATUS);
|
|
||||||
if (!linked) {
|
|
||||||
// something went wrong with the link
|
|
||||||
var error = gl.getProgramInfoLog (gl.program);
|
|
||||||
gl.console.log("Error in program linking:"+error);
|
|
||||||
|
|
||||||
gl.deleteProgram(gl.program);
|
|
||||||
gl.deleteProgram(fragmentShader);
|
|
||||||
gl.deleteProgram(vertexShader);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
gl.useProgram(gl.program);
|
|
||||||
|
|
||||||
gl.clearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
|
|
||||||
gl.clearDepth(clearDepth);
|
|
||||||
gl.clearStencil(clearStencil);
|
|
||||||
gl.enable(gl.DEPTH_TEST);
|
|
||||||
gl.enable(gl.STENCIL_TEST);
|
|
||||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
|
|
||||||
|
|
||||||
return gl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawAndReadPixel(gl, vertices, colors, x, y)
|
function drawAndReadPixel(gl, vertices, colors, x, y)
|
||||||
|
@ -146,11 +94,6 @@ function testAlpha(alpha)
|
||||||
else
|
else
|
||||||
shouldBeNonNull("webGL = getWebGL('alphaOff', { alpha: false, depth: false, stencil: false, antialias: false }, [ 0, 0, 0, 0 ], 1, 0)");
|
shouldBeNonNull("webGL = getWebGL('alphaOff', { alpha: false, depth: false, stencil: false, antialias: false }, [ 0, 0, 0, 0 ], 1, 0)");
|
||||||
shouldBeNonNull("contextAttribs = webGL.getContextAttributes()");
|
shouldBeNonNull("contextAttribs = webGL.getContextAttributes()");
|
||||||
shouldBe("contextAttribs.alpha", (alpha ? "true" : "false"));
|
|
||||||
shouldBe("contextAttribs.depth", "false");
|
|
||||||
shouldBe("contextAttribs.stencil", "false");
|
|
||||||
shouldBe("contextAttribs.antialias", "false");
|
|
||||||
shouldBe("contextAttribs.premultipliedAlpha", "true");
|
|
||||||
|
|
||||||
var buf = new Uint8Array(1 * 1 * 4);
|
var buf = new Uint8Array(1 * 1 * 4);
|
||||||
webGL.readPixels(0, 0, 1, 1, webGL.RGBA, webGL.UNSIGNED_BYTE, buf);
|
webGL.readPixels(0, 0, 1, 1, webGL.RGBA, webGL.UNSIGNED_BYTE, buf);
|
||||||
|
@ -158,7 +101,7 @@ function testAlpha(alpha)
|
||||||
pixel[1] = buf[1];
|
pixel[1] = buf[1];
|
||||||
pixel[2] = buf[2];
|
pixel[2] = buf[2];
|
||||||
pixel[3] = buf[3];
|
pixel[3] = buf[3];
|
||||||
correctColor = (alpha ? [0, 0, 0, 0] : [0, 0, 0, 255]);
|
correctColor = (contextAttribs.alpha ? [0, 0, 0, 0] : [0, 0, 0, 255]);
|
||||||
shouldBe("pixel", "correctColor");
|
shouldBe("pixel", "correctColor");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,11 +113,6 @@ function testDepth(depth)
|
||||||
else
|
else
|
||||||
shouldBeNonNull("webGL = getWebGL('depthOff', { depth: false, stencil: false, antialias: false }, [ 0, 0, 0, 1 ], 1, 0)");
|
shouldBeNonNull("webGL = getWebGL('depthOff', { depth: false, stencil: false, antialias: false }, [ 0, 0, 0, 1 ], 1, 0)");
|
||||||
shouldBeNonNull("contextAttribs = webGL.getContextAttributes()");
|
shouldBeNonNull("contextAttribs = webGL.getContextAttributes()");
|
||||||
shouldBe("contextAttribs.depth", (depth ? "true" : "false"));
|
|
||||||
shouldBe("contextAttribs.alpha", "true");
|
|
||||||
shouldBe("contextAttribs.stencil", "false");
|
|
||||||
shouldBe("contextAttribs.antialias", "false");
|
|
||||||
shouldBe("contextAttribs.premultipliedAlpha", "true");
|
|
||||||
|
|
||||||
webGL.depthFunc(webGL.NEVER);
|
webGL.depthFunc(webGL.NEVER);
|
||||||
|
|
||||||
|
@ -198,7 +136,7 @@ function testDepth(depth)
|
||||||
pixel[1] = buf[1];
|
pixel[1] = buf[1];
|
||||||
pixel[2] = buf[2];
|
pixel[2] = buf[2];
|
||||||
pixel[3] = buf[3];
|
pixel[3] = buf[3];
|
||||||
correctColor = (depth ? [0, 0, 0, 255] : [255, 0, 0, 255]);
|
correctColor = (contextAttribs.depth ? [0, 0, 0, 255] : [255, 0, 0, 255]);
|
||||||
shouldBe("pixel", "correctColor");
|
shouldBe("pixel", "correctColor");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,11 +148,6 @@ function testStencil(stencil)
|
||||||
else
|
else
|
||||||
shouldBeNonNull("webGL = getWebGL('stencilOff', { depth: false, stencil: false, antialias: false }, [ 0, 0, 0, 1 ], 1, 0)");
|
shouldBeNonNull("webGL = getWebGL('stencilOff', { depth: false, stencil: false, antialias: false }, [ 0, 0, 0, 1 ], 1, 0)");
|
||||||
shouldBeNonNull("contextAttribs = webGL.getContextAttributes()");
|
shouldBeNonNull("contextAttribs = webGL.getContextAttributes()");
|
||||||
// If EXT_packed_depth_stencil is supported, both depth & stencil will be true; otherwise, both will be false.
|
|
||||||
shouldBe("contextAttribs.depth == contextAttribs.stencil", "true");
|
|
||||||
shouldBe("contextAttribs.alpha", "true");
|
|
||||||
shouldBe("contextAttribs.antialias", "false");
|
|
||||||
shouldBe("contextAttribs.premultipliedAlpha", "true");
|
|
||||||
|
|
||||||
webGL.depthFunc(webGL.ALWAYS);
|
webGL.depthFunc(webGL.ALWAYS);
|
||||||
|
|
||||||
|
@ -241,10 +174,7 @@ function testStencil(stencil)
|
||||||
pixel[1] = buf[1];
|
pixel[1] = buf[1];
|
||||||
pixel[2] = buf[2];
|
pixel[2] = buf[2];
|
||||||
pixel[3] = buf[3];
|
pixel[3] = buf[3];
|
||||||
correctColor = (stencil ? [0, 0, 0, 255] : [255, 0, 0, 255]);
|
correctColor = (contextAttribs.stencil ? [0, 0, 0, 255] : [255, 0, 0, 255]);
|
||||||
// If stencil is requested but not supported, we fake the effect.
|
|
||||||
if (stencil && !contextAttribs.stencil)
|
|
||||||
pixel[0] = 0;
|
|
||||||
shouldBe("pixel", "correctColor");
|
shouldBe("pixel", "correctColor");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,11 +186,6 @@ function testAntialias(antialias)
|
||||||
else
|
else
|
||||||
shouldBeNonNull("webGL = getWebGL('antialiasOff', { depth: false, stencil: false, alpha: false, antialias: false }, [ 0, 0, 0, 1 ], 1, 0)");
|
shouldBeNonNull("webGL = getWebGL('antialiasOff', { depth: false, stencil: false, alpha: false, antialias: false }, [ 0, 0, 0, 1 ], 1, 0)");
|
||||||
shouldBeNonNull("contextAttribs = webGL.getContextAttributes()");
|
shouldBeNonNull("contextAttribs = webGL.getContextAttributes()");
|
||||||
shouldBe("contextAttribs.depth", "false");
|
|
||||||
shouldBe("contextAttribs.stencil", "false");
|
|
||||||
shouldBe("contextAttribs.alpha", "false");
|
|
||||||
shouldBe("contextAttribs.antialias == true || contextAttribs.antialias == false", "true");
|
|
||||||
shouldBe("contextAttribs.premultipliedAlpha", "true");
|
|
||||||
|
|
||||||
var vertices = new Float32Array([
|
var vertices = new Float32Array([
|
||||||
1.0, 1.0, 0.0,
|
1.0, 1.0, 0.0,
|
||||||
|
@ -272,10 +197,7 @@ function testAntialias(antialias)
|
||||||
255, 0, 0, 255]);
|
255, 0, 0, 255]);
|
||||||
var buf = drawAndReadPixel(webGL, vertices, colors, 0, 0);
|
var buf = drawAndReadPixel(webGL, vertices, colors, 0, 0);
|
||||||
pixel[0] = buf[0];
|
pixel[0] = buf[0];
|
||||||
// If antialias is requested but not supported, we fake the effect.
|
shouldBe("pixel[0] != 255 && pixel[0] != 0", "contextAttribs.antialias");
|
||||||
if (antialias && !contextAttribs.antialias)
|
|
||||||
pixel[0] = 127;
|
|
||||||
shouldBe("pixel[0] == 255 || pixel[0] == 0", (antialias ? "false" : "true"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function runTest()
|
function runTest()
|
||||||
|
|
|
@ -1,66 +0,0 @@
|
||||||
<!--
|
|
||||||
Copyright (c) 2010 The Chromium Authors. All rights reserved.
|
|
||||||
Use of this source code is governed by a BSD-style license that can be
|
|
||||||
found in the LICENSE file.
|
|
||||||
-->
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<link rel="stylesheet" href="../resources/js-test-style.css"/>
|
|
||||||
<script src="../resources/js-test-pre.js"></script>
|
|
||||||
<script src="resources/webgl-test.js"></script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="description"></div>
|
|
||||||
<div id="console"></div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
description("Test passing down and fetching of WebGLContextAttributes");
|
|
||||||
|
|
||||||
debug("Test default values");
|
|
||||||
var context;
|
|
||||||
var attribs;
|
|
||||||
shouldBeNonNull("context = create3DContext(null)");
|
|
||||||
shouldBeNonNull("attribs = context.getContextAttributes()");
|
|
||||||
shouldBe("attribs.depth", "true");
|
|
||||||
shouldBe("attribs.alpha", "true");
|
|
||||||
shouldBe("attribs.stencil", "false");
|
|
||||||
// Antialias is requested by default, but might or might not be supported.
|
|
||||||
shouldBe("attribs.antialias == true || attribs.antialias == false", "true");
|
|
||||||
shouldBe("attribs.premultipliedAlpha", "true");
|
|
||||||
|
|
||||||
debug ("Test customized values");
|
|
||||||
shouldBeNonNull("context = create3DContext(null, { stencil: false, antialias: false })");
|
|
||||||
shouldBeNonNull("attribs = context.getContextAttributes()");
|
|
||||||
shouldBe("attribs.depth", "true");
|
|
||||||
shouldBe("attribs.alpha", "true");
|
|
||||||
shouldBe("attribs.stencil", "false");
|
|
||||||
shouldBe("attribs.antialias", "false");
|
|
||||||
shouldBe("attribs.premultipliedAlpha", "true");
|
|
||||||
|
|
||||||
debug("Test customized values");
|
|
||||||
// (stencil == true && depth == false) is not supported.
|
|
||||||
// Default depth to true if EXT_packed_depth_stencil is supported.
|
|
||||||
// Otherwise, both depth and stencil should be false.
|
|
||||||
shouldBeNonNull("context = create3DContext(null, { depth: false, stencil: true, antialias: false })");
|
|
||||||
shouldBeNonNull("attribs = context.getContextAttributes()");
|
|
||||||
shouldBe("attribs.depth == attribs.stencil", "true");
|
|
||||||
shouldBe("attribs.alpha", "true");
|
|
||||||
shouldBe("attribs.antialias", "false");
|
|
||||||
shouldBe("attribs.premultipliedAlpha", "true");
|
|
||||||
|
|
||||||
debug("Test customized values");
|
|
||||||
// (premultipliedAlpha == false) is not supported by most implementations yet
|
|
||||||
shouldBeNonNull("context = create3DContext(null, { premultipliedAlpha: false, antialias: false })");
|
|
||||||
shouldBeNonNull("attribs = context.getContextAttributes()");
|
|
||||||
shouldBe("attribs.depth", "true");
|
|
||||||
shouldBe("attribs.alpha", "true");
|
|
||||||
shouldBe("attribs.stencil == true || attribs.stencil == false", "true");
|
|
||||||
shouldBe("attribs.antialias", "false");
|
|
||||||
shouldBe("attribs.premultipliedAlpha == true || attribs.premultipliedAlpha == false", "true");
|
|
||||||
|
|
||||||
successfullyParsed = true;
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script src="../resources/js-test-post.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -88,7 +88,7 @@ function runTestIteration(antialias)
|
||||||
gl.enableVertexAttribArray(0);
|
gl.enableVertexAttribArray(0);
|
||||||
gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
|
gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
|
||||||
gl.enableVertexAttribArray(1);
|
gl.enableVertexAttribArray(1);
|
||||||
gl.vertexAttribPointer(1, 2, gl.FLOAT, gl.FALSE, 0, texCoordOffset);
|
gl.vertexAttribPointer(1, 2, gl.FLOAT, false, 0, texCoordOffset);
|
||||||
|
|
||||||
gl.colorMask(1, 1, 1, 0);
|
gl.colorMask(1, 1, 1, 0);
|
||||||
gl.disable(gl.BLEND);
|
gl.disable(gl.BLEND);
|
||||||
|
|
|
@ -50,10 +50,10 @@ shouldGenerateGLError(context, context.INVALID_OPERATION, "context.drawArrays(co
|
||||||
shouldGenerateGLError(context, context.INVALID_OPERATION, "context.drawArrays(context.TRIANGLES, 0, 10000)");
|
shouldGenerateGLError(context, context.INVALID_OPERATION, "context.drawArrays(context.TRIANGLES, 0, 10000)");
|
||||||
shouldGenerateGLError(context, context.INVALID_OPERATION, "context.drawArrays(context.TRIANGLES, 0, 10000000000000)");
|
shouldGenerateGLError(context, context.INVALID_OPERATION, "context.drawArrays(context.TRIANGLES, 0, 10000000000000)");
|
||||||
shouldGenerateGLError(context, context.INVALID_VALUE, "context.drawArrays(context.TRIANGLES, 0, -1)");
|
shouldGenerateGLError(context, context.INVALID_VALUE, "context.drawArrays(context.TRIANGLES, 0, -1)");
|
||||||
shouldGenerateGLError(context, context.INVALID_OPERATION, "context.drawArrays(context.TRIANGLES, 1, 0)");
|
shouldGenerateGLError(context, context.NO_ERROR, "context.drawArrays(context.TRIANGLES, 1, 0)");
|
||||||
shouldGenerateGLError(context, context.INVALID_VALUE, "context.drawArrays(context.TRIANGLES, -1, 0)");
|
shouldGenerateGLError(context, context.INVALID_VALUE, "context.drawArrays(context.TRIANGLES, -1, 0)");
|
||||||
shouldGenerateGLError(context, context.NO_ERROR, "context.drawArrays(context.TRIANGLES, 0, 0)");
|
shouldGenerateGLError(context, context.NO_ERROR, "context.drawArrays(context.TRIANGLES, 0, 0)");
|
||||||
shouldGenerateGLError(context, context.INVALID_OPERATION, "context.drawArrays(context.TRIANGLES, 100, 0)");
|
shouldGenerateGLError(context, context.NO_ERROR, "context.drawArrays(context.TRIANGLES, 100, 0)");
|
||||||
shouldGenerateGLError(context, context.INVALID_VALUE, "context.drawArrays(context.TRIANGLES, 1, -1)");
|
shouldGenerateGLError(context, context.INVALID_VALUE, "context.drawArrays(context.TRIANGLES, 1, -1)");
|
||||||
shouldGenerateGLError(context, context.INVALID_VALUE, "context.drawArrays(context.TRIANGLES, -1, 1)");
|
shouldGenerateGLError(context, context.INVALID_VALUE, "context.drawArrays(context.TRIANGLES, -1, 1)");
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ shouldGenerateGLError(context, context.INVALID_OPERATION, "context.drawArrays(co
|
||||||
shouldGenerateGLError(context, context.INVALID_VALUE, "context.drawArrays(context.TRIANGLES, 0, -1)");
|
shouldGenerateGLError(context, context.INVALID_VALUE, "context.drawArrays(context.TRIANGLES, 0, -1)");
|
||||||
shouldGenerateGLError(context, context.INVALID_VALUE, "context.drawArrays(context.TRIANGLES, -1, 0)");
|
shouldGenerateGLError(context, context.INVALID_VALUE, "context.drawArrays(context.TRIANGLES, -1, 0)");
|
||||||
shouldGenerateGLError(context, context.NO_ERROR, "context.drawArrays(context.TRIANGLES, 0, 0)");
|
shouldGenerateGLError(context, context.NO_ERROR, "context.drawArrays(context.TRIANGLES, 0, 0)");
|
||||||
shouldGenerateGLError(context, context.INVALID_OPERATION, "context.drawArrays(context.TRIANGLES, 100, 0)");
|
shouldGenerateGLError(context, context.NO_ERROR, "context.drawArrays(context.TRIANGLES, 100, 0)");
|
||||||
shouldGenerateGLError(context, context.INVALID_VALUE, "context.drawArrays(context.TRIANGLES, 1, -1)");
|
shouldGenerateGLError(context, context.INVALID_VALUE, "context.drawArrays(context.TRIANGLES, 1, -1)");
|
||||||
shouldGenerateGLError(context, context.INVALID_VALUE, "context.drawArrays(context.TRIANGLES, -1, 1)");
|
shouldGenerateGLError(context, context.INVALID_VALUE, "context.drawArrays(context.TRIANGLES, -1, 1)");
|
||||||
|
|
||||||
|
|
|
@ -74,7 +74,7 @@ shouldGenerateGLError(context, context.INVALID_VALUE, "context.drawElements(cont
|
||||||
shouldGenerateGLError(context, context.INVALID_VALUE, "context.drawElements(context.TRIANGLES, 0, context.UNSIGNED_BYTE, -1)");
|
shouldGenerateGLError(context, context.INVALID_VALUE, "context.drawElements(context.TRIANGLES, 0, context.UNSIGNED_BYTE, -1)");
|
||||||
shouldGenerateGLError(context, context.INVALID_VALUE, "context.drawElements(context.TRIANGLES, -1, context.UNSIGNED_BYTE, 1)");
|
shouldGenerateGLError(context, context.INVALID_VALUE, "context.drawElements(context.TRIANGLES, -1, context.UNSIGNED_BYTE, 1)");
|
||||||
shouldGenerateGLError(context, context.INVALID_VALUE, "context.drawElements(context.TRIANGLES, 1, context.UNSIGNED_BYTE, -1)");
|
shouldGenerateGLError(context, context.INVALID_VALUE, "context.drawElements(context.TRIANGLES, 1, context.UNSIGNED_BYTE, -1)");
|
||||||
shouldGenerateGLError(context, context.INVALID_OPERATION, "context.drawElements(context.TRIANGLES, 0, context.UNSIGNED_BYTE, 4)");
|
shouldGenerateGLError(context, context.NO_ERROR, "context.drawElements(context.TRIANGLES, 0, context.UNSIGNED_BYTE, 4)");
|
||||||
shouldGenerateGLError(context, context.INVALID_VALUE, "context.drawElements(context.TRIANGLES, 0xffffffff, context.UNSIGNED_BYTE, 0)");
|
shouldGenerateGLError(context, context.INVALID_VALUE, "context.drawElements(context.TRIANGLES, 0xffffffff, context.UNSIGNED_BYTE, 0)");
|
||||||
shouldGenerateGLError(context, context.INVALID_OPERATION, "context.drawElements(context.TRIANGLES, 0x7fffffff, context.UNSIGNED_BYTE, 0)");
|
shouldGenerateGLError(context, context.INVALID_OPERATION, "context.drawElements(context.TRIANGLES, 0x7fffffff, context.UNSIGNED_BYTE, 0)");
|
||||||
shouldGenerateGLError(context, context.INVALID_OPERATION, "context.drawElements(context.TRIANGLES, 0x7fffffff, context.UNSIGNED_BYTE, 0x7fffffff)");
|
shouldGenerateGLError(context, context.INVALID_OPERATION, "context.drawElements(context.TRIANGLES, 0x7fffffff, context.UNSIGNED_BYTE, 0x7fffffff)");
|
||||||
|
|
|
@ -28,25 +28,29 @@ function testAttachment(attachment, buffer, isConflicted)
|
||||||
{
|
{
|
||||||
shouldBeNonNull("fbo = gl.createFramebuffer()");
|
shouldBeNonNull("fbo = gl.createFramebuffer()");
|
||||||
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
|
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
|
||||||
|
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer);
|
||||||
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment, gl.RENDERBUFFER, buffer);
|
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment, gl.RENDERBUFFER, buffer);
|
||||||
glErrorShouldBe(gl, isConflicted ? gl.INVALID_OPERATION : gl.NO_ERROR);
|
glErrorShouldBe(gl, gl.NO_ERROR);
|
||||||
|
if (isConflicted) {
|
||||||
|
shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_UNSUPPORTED");
|
||||||
|
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||||
|
glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION);
|
||||||
|
gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array(width * height * 4));
|
||||||
|
glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function testAttachments(attachment0, buffer0, attachment1, buffer1, isConflicted)
|
function testAttachments(attachment0, buffer0, attachment1, buffer1, isConflicted)
|
||||||
{
|
{
|
||||||
shouldBeNonNull("fbo = gl.createFramebuffer()");
|
shouldBeNonNull("fbo = gl.createFramebuffer()");
|
||||||
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
|
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
|
||||||
|
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer);
|
||||||
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment0, gl.RENDERBUFFER, buffer0);
|
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment0, gl.RENDERBUFFER, buffer0);
|
||||||
glErrorShouldBe(gl, gl.NO_ERROR);
|
glErrorShouldBe(gl, gl.NO_ERROR);
|
||||||
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment1, gl.RENDERBUFFER, buffer1);
|
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment1, gl.RENDERBUFFER, buffer1);
|
||||||
glErrorShouldBe(gl, isConflicted ? gl.INVALID_OPERATION : gl.NO_ERROR);
|
glErrorShouldBe(gl, gl.NO_ERROR);
|
||||||
if (isConflicted) {
|
if (isConflicted)
|
||||||
// Detach buffer0 first using a null object, then attaching buffer1 should succeed.
|
shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_UNSUPPORTED");
|
||||||
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment0, gl.RENDERBUFFER, null);
|
|
||||||
glErrorShouldBe(gl, gl.NO_ERROR);
|
|
||||||
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment1, gl.RENDERBUFFER, buffer1);
|
|
||||||
glErrorShouldBe(gl, gl.NO_ERROR);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function testColorRenderbuffer(internalformat)
|
function testColorRenderbuffer(internalformat)
|
||||||
|
@ -58,10 +62,33 @@ function testColorRenderbuffer(internalformat)
|
||||||
testAttachment(gl.COLOR_ATTACHMENT0, colorBuffer, false);
|
testAttachment(gl.COLOR_ATTACHMENT0, colorBuffer, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function testDepthStencilRenderbuffer()
|
||||||
|
{
|
||||||
|
shouldBeNonNull("depthStencilBuffer = gl.createRenderbuffer()");
|
||||||
|
gl.bindRenderbuffer(gl.RENDERBUFFER, depthStencilBuffer);
|
||||||
|
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, width, height);
|
||||||
|
glErrorShouldBe(gl, gl.NO_ERROR);
|
||||||
|
shouldBe("gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_WIDTH)", "width");
|
||||||
|
shouldBe("gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_HEIGHT)", "height");
|
||||||
|
shouldBe("gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_INTERNAL_FORMAT)", "gl.DEPTH_STENCIL");
|
||||||
|
shouldBe("gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_RED_SIZE)", "0");
|
||||||
|
shouldBe("gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_GREEN_SIZE)", "0");
|
||||||
|
shouldBe("gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_BLUE_SIZE)", "0");
|
||||||
|
shouldBe("gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_ALPHA_SIZE)", "0");
|
||||||
|
shouldBeTrue("gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_DEPTH_SIZE) > 0");
|
||||||
|
shouldBeTrue("gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_STENCIL_SIZE) > 0");
|
||||||
|
glErrorShouldBe(gl, gl.NO_ERROR);
|
||||||
|
testAttachment(gl.DEPTH_STENCIL_ATTACHMENT, depthStencilBuffer, false);
|
||||||
|
}
|
||||||
|
|
||||||
description("Test framebuffer object attachment behaviors");
|
description("Test framebuffer object attachment behaviors");
|
||||||
|
|
||||||
debug("Create renderbuffers");
|
debug("Create renderbuffers");
|
||||||
shouldBeNonNull("gl = create3DContext()");
|
shouldBeNonNull("gl = create3DContext()");
|
||||||
|
shouldBeNonNull("colorBuffer = gl.createRenderbuffer()");
|
||||||
|
gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer);
|
||||||
|
gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, width, height);
|
||||||
|
glErrorShouldBe(gl, gl.NO_ERROR);
|
||||||
shouldBeNonNull("depthBuffer = gl.createRenderbuffer()");
|
shouldBeNonNull("depthBuffer = gl.createRenderbuffer()");
|
||||||
gl.bindRenderbuffer(gl.RENDERBUFFER, depthBuffer);
|
gl.bindRenderbuffer(gl.RENDERBUFFER, depthBuffer);
|
||||||
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, width, height);
|
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, width, height);
|
||||||
|
@ -116,6 +143,9 @@ testColorRenderbuffer(gl.RGB5_A1);
|
||||||
debug("Attach color renderbuffer with internalformat == RGB565");
|
debug("Attach color renderbuffer with internalformat == RGB565");
|
||||||
testColorRenderbuffer(gl.RGB565);
|
testColorRenderbuffer(gl.RGB565);
|
||||||
|
|
||||||
|
debug("Create and attach depthStencil renderbuffer");
|
||||||
|
testDepthStencilRenderbuffer();
|
||||||
|
|
||||||
successfullyParsed = true;
|
successfullyParsed = true;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,7 @@ var shaders = gl.getAttachedShaders(standardProgram);
|
||||||
shouldBe('shaders.length', '2');
|
shouldBe('shaders.length', '2');
|
||||||
shouldBeTrue('shaders[0] == standardVert && shaders[1] == standardFrag || shaders[1] == standardVert && shaders[0] == standardFrag');
|
shouldBeTrue('shaders[0] == standardVert && shaders[1] == standardFrag || shaders[1] == standardVert && shaders[0] == standardFrag');
|
||||||
glErrorShouldBe(gl, gl.NO_ERROR);
|
glErrorShouldBe(gl, gl.NO_ERROR);
|
||||||
shouldBeUndefined('gl.getAttachedShaders(null)');
|
shouldBeNull('gl.getAttachedShaders(null)');
|
||||||
glErrorShouldBe(gl, gl.INVALID_VALUE);
|
glErrorShouldBe(gl, gl.INVALID_VALUE);
|
||||||
shouldThrow('gl.getAttachedShaders(standardVert)');
|
shouldThrow('gl.getAttachedShaders(standardVert)');
|
||||||
glErrorShouldBe(gl, gl.NO_ERROR);
|
glErrorShouldBe(gl, gl.NO_ERROR);
|
||||||
|
@ -174,9 +174,9 @@ gl.uniform3i(bval3Loc, 1, 0, 1);
|
||||||
gl.uniform4i(bval4Loc, 1, 0, 1, 0);
|
gl.uniform4i(bval4Loc, 1, 0, 1, 0);
|
||||||
glErrorShouldBe(gl, gl.NO_ERROR);
|
glErrorShouldBe(gl, gl.NO_ERROR);
|
||||||
shouldBe('gl.getUniform(boolProgram, bvalLoc)', 'true');
|
shouldBe('gl.getUniform(boolProgram, bvalLoc)', 'true');
|
||||||
shouldBe('gl.getUniform(boolProgram, bval2Loc)', '[1, 0]');
|
shouldBe('gl.getUniform(boolProgram, bval2Loc)', '[true, false]');
|
||||||
shouldBe('gl.getUniform(boolProgram, bval3Loc)', '[1, 0, 1]');
|
shouldBe('gl.getUniform(boolProgram, bval3Loc)', '[true, false, true]');
|
||||||
shouldBe('gl.getUniform(boolProgram, bval4Loc)', '[1, 0, 1, 0]');
|
shouldBe('gl.getUniform(boolProgram, bval4Loc)', '[true, false, true, false]');
|
||||||
// Integer uniform variables
|
// Integer uniform variables
|
||||||
var intProgram = loadProgram(gl, "resources/intUniformShader.vert", "resources/noopUniformShader.frag");
|
var intProgram = loadProgram(gl, "resources/intUniformShader.vert", "resources/noopUniformShader.frag");
|
||||||
shouldBe('gl.getProgramParameter(intProgram, gl.LINK_STATUS)', 'true');
|
shouldBe('gl.getProgramParameter(intProgram, gl.LINK_STATUS)', 'true');
|
||||||
|
|
|
@ -38,7 +38,8 @@ var imgURLs = [
|
||||||
'resources/gray-ramp.png',
|
'resources/gray-ramp.png',
|
||||||
'resources/zero-alpha.png',
|
'resources/zero-alpha.png',
|
||||||
'resources/3x3.png',
|
'resources/3x3.png',
|
||||||
'resources/blue-1x1.jpg'];
|
'resources/blue-1x1.jpg',
|
||||||
|
'resources/green-2x2-16bit.png'];
|
||||||
|
|
||||||
wtu.loadImagesAsync(imgURLs, runTests);
|
wtu.loadImagesAsync(imgURLs, runTests);
|
||||||
|
|
||||||
|
@ -167,6 +168,7 @@ function runTests(imgs) {
|
||||||
|
|
||||||
debug("");
|
debug("");
|
||||||
debug("Check that gamma settings don't effect 8bit pngs");
|
debug("Check that gamma settings don't effect 8bit pngs");
|
||||||
|
gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, gl.NONE);
|
||||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE,
|
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE,
|
||||||
imgs['resources/gray-ramp-default-gamma.png']);
|
imgs['resources/gray-ramp-default-gamma.png']);
|
||||||
glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
|
glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
|
||||||
|
@ -289,6 +291,19 @@ function runTests(imgs) {
|
||||||
|
|
||||||
glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors");
|
glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors");
|
||||||
|
|
||||||
|
debug("");
|
||||||
|
debug("check uploading of 16-bit images");
|
||||||
|
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
|
||||||
|
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
|
||||||
|
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE,
|
||||||
|
imgs['resources/green-2x2-16bit.png']);
|
||||||
|
glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup");
|
||||||
|
wtu.drawQuad(gl);
|
||||||
|
gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf);
|
||||||
|
|
||||||
|
checkPixelRange(buf, middle, center, [ 15, 121, 0, 255], 10);
|
||||||
|
|
||||||
|
glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors");
|
||||||
debug("");
|
debug("");
|
||||||
successfullyParsed = true;
|
successfullyParsed = true;
|
||||||
shouldBeTrue("successfullyParsed");
|
shouldBeTrue("successfullyParsed");
|
||||||
|
|
|
@ -19,7 +19,7 @@ found in the LICENSE file.
|
||||||
<div id="console"></div>
|
<div id="console"></div>
|
||||||
<canvas id="canvas" width="2" height="2"> </canvas>
|
<canvas id="canvas" width="2" height="2"> </canvas>
|
||||||
<script>
|
<script>
|
||||||
description("This test ensures WebGL implementations vertexAttribPointer can not be set if no buffer is bound.");
|
description("This test checks vertexAttribPointer behaviors in WebGL.");
|
||||||
|
|
||||||
debug("");
|
debug("");
|
||||||
debug("Canvas.getContext");
|
debug("Canvas.getContext");
|
||||||
|
@ -36,6 +36,16 @@ if (!gl) {
|
||||||
gl.vertexAttribPointer(0, 3, gl.FLOAT, 0, 0, 12);
|
gl.vertexAttribPointer(0, 3, gl.FLOAT, 0, 0, 12);
|
||||||
glErrorShouldBe(gl, gl.INVALID_OPERATION,
|
glErrorShouldBe(gl, gl.INVALID_OPERATION,
|
||||||
"vertexAttribPointer should fail if no buffer is bound");
|
"vertexAttribPointer should fail if no buffer is bound");
|
||||||
|
|
||||||
|
var vertexObject = gl.createBuffer();
|
||||||
|
gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
|
||||||
|
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(512), gl.STATIC_DRAW);
|
||||||
|
gl.vertexAttribPointer(0, 1, gl.FLOAT, 0, 256, 0);
|
||||||
|
glErrorShouldBe(gl, gl.INVALID_VALUE,
|
||||||
|
"WebGL API supports vertex attribute data strides up to 255 bytes");
|
||||||
|
gl.vertexAttribPointer(0, 1, gl.FLOAT, 0, 255, 0);
|
||||||
|
glErrorShouldBe(gl, gl.NO_ERROR,
|
||||||
|
"vertexAttribPointer with stride <= 255 should succeed");
|
||||||
}
|
}
|
||||||
|
|
||||||
debug("");
|
debug("");
|
||||||
|
|
|
@ -60,6 +60,7 @@ function init()
|
||||||
|
|
||||||
gl = initWebGL("example", "vshader", "fshader", [ "vPosition", "texCoord0"],
|
gl = initWebGL("example", "vshader", "fshader", [ "vPosition", "texCoord0"],
|
||||||
[ 0, 0, 0, 1 ], 1);
|
[ 0, 0, 0, 1 ], 1);
|
||||||
|
gl = WebGLDebugUtils.makeDebugContext(gl);
|
||||||
|
|
||||||
gl.disable(gl.DEPTH_TEST);
|
gl.disable(gl.DEPTH_TEST);
|
||||||
gl.disable(gl.BLEND);
|
gl.disable(gl.BLEND);
|
||||||
|
@ -124,7 +125,7 @@ function init()
|
||||||
var y = Math.floor(ii / 2);
|
var y = Math.floor(ii / 2);
|
||||||
gl.drawArrays(gl.TRIANGLES, 0, 6);
|
gl.drawArrays(gl.TRIANGLES, 0, 6);
|
||||||
glErrorShouldBe(gl, gl.INVALID_OPERATION,
|
glErrorShouldBe(gl, gl.INVALID_OPERATION,
|
||||||
"drawing with 2 different targets on the same texture unit should generate error");
|
"drawing with 2 different targets on the same texture unit should generate INVALID_VALUE");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -223,6 +223,37 @@ foo
|
||||||
<script id="vshaderWith__FILE__" type="text/something-not-javascript">
|
<script id="vshaderWith__FILE__" type="text/something-not-javascript">
|
||||||
__FILE__
|
__FILE__
|
||||||
</script>
|
</script>
|
||||||
|
<script id="fshaderWithdFdx" type="text/something-not-javascript">
|
||||||
|
#extension GL_OES_standard_derivatives:enable
|
||||||
|
precision mediump float;
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_FragColor = vec4(dFdx(0.5),0.0,0.0,1.0);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script id="fshaderWithdFdxNoExt" type="text/something-not-javascript">
|
||||||
|
precision mediump float;
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_FragColor = vec4(dFdx(0.5),0.0,0.0,1.0);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script id="fshaderWith256CharacterIdentifier" type="text/something-not-javascript">
|
||||||
|
precision mediump float;
|
||||||
|
uniform float a123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345 = 2.0;
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_FragColor = vec4(a123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345,0.0,0.0,1.0);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script id="fshaderWith257CharacterIdentifier" type="text/something-not-javascript">
|
||||||
|
precision mediump float;
|
||||||
|
uniform float a1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456 = 2.0;
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_FragColor = vec4(a1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456,0.0,0.0,1.0);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
<canvas id="canvas" width="2" height="2"> </canvas>
|
<canvas id="canvas" width="2" height="2"> </canvas>
|
||||||
<script>
|
<script>
|
||||||
description("This test ensures WebGL implementations allow proper GLES2 shaders compile and improper ones fail.");
|
description("This test ensures WebGL implementations allow proper GLES2 shaders compile and improper ones fail.");
|
||||||
|
@ -310,6 +341,20 @@ if (!gl) {
|
||||||
linkSuccess: false,
|
linkSuccess: false,
|
||||||
passMsg: 'fragment shader that uses gl_FragDepth should fail',
|
passMsg: 'fragment shader that uses gl_FragDepth should fail',
|
||||||
},
|
},
|
||||||
|
{ vShaderId: 'vshader',
|
||||||
|
vShaderSuccess: true,
|
||||||
|
fShaderId: 'fshaderWithdFdx',
|
||||||
|
fShaderSuccess: false,
|
||||||
|
linkSuccess: false,
|
||||||
|
passMsg: 'fragment shader that uses dFdx should fail',
|
||||||
|
},
|
||||||
|
{ vShaderId: 'vshader',
|
||||||
|
vShaderSuccess: true,
|
||||||
|
fShaderId: 'fshaderWithdFdxNoExt',
|
||||||
|
fShaderSuccess: false,
|
||||||
|
linkSuccess: false,
|
||||||
|
passMsg: 'fragment shader that uses dFdx without #extension should fail',
|
||||||
|
},
|
||||||
{ vShaderId: 'vshaderWithClipVertex',
|
{ vShaderId: 'vshaderWithClipVertex',
|
||||||
vShaderSuccess: false,
|
vShaderSuccess: false,
|
||||||
fShaderId: 'fshader',
|
fShaderId: 'fshader',
|
||||||
|
@ -415,7 +460,21 @@ if (!gl) {
|
||||||
fShaderSuccess: true,
|
fShaderSuccess: true,
|
||||||
linkSuccess: false,
|
linkSuccess: false,
|
||||||
passMsg: 'vertex shader uses #line directive should report correct line',
|
passMsg: 'vertex shader uses #line directive should report correct line',
|
||||||
}
|
},
|
||||||
|
{ vShaderId: 'vshader',
|
||||||
|
vShaderSuccess: true,
|
||||||
|
fShaderId: 'fshaderWith256CharacterIdentifier',
|
||||||
|
fShaderSuccess: true,
|
||||||
|
linkSuccess: true,
|
||||||
|
passMsg: 'shared that uses 256 character identifier should succeed',
|
||||||
|
},
|
||||||
|
{ vShaderId: 'vshader',
|
||||||
|
vShaderSuccess: true,
|
||||||
|
fShaderId: 'fshaderWith257CharacterIdentifier',
|
||||||
|
fShaderSuccess: false,
|
||||||
|
linkSuccess: false,
|
||||||
|
passMsg: 'shared that uses 257 character identifier should fail',
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
// Read in all the shader source.
|
// Read in all the shader source.
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<link rel="stylesheet" href="../resources/js-test-style.css"/>
|
||||||
|
<script src="../resources/js-test-pre.js"></script>
|
||||||
|
<script src="resources/webgl-test.js"></script>
|
||||||
|
<script src="resources/webgl-test-utils.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="description"></div>
|
||||||
|
<div id="console"></div>
|
||||||
|
<canvas id="canvas">
|
||||||
|
<script>
|
||||||
|
var wtu;
|
||||||
|
var canvas;
|
||||||
|
var gl;
|
||||||
|
var shouldGenerateGLError;
|
||||||
|
|
||||||
|
var buffer;
|
||||||
|
var framebuffer;
|
||||||
|
var program;
|
||||||
|
var renderbuffer;
|
||||||
|
var shader;
|
||||||
|
var texture;
|
||||||
|
|
||||||
|
description("Tests 'is' calls against non-bound and deleted objects");
|
||||||
|
|
||||||
|
wtu = WebGLTestUtils;
|
||||||
|
canvas = document.getElementById("canvas");
|
||||||
|
gl = wtu.create3DContext(canvas);
|
||||||
|
shouldGenerateGLError = wtu.shouldGenerateGLError;
|
||||||
|
|
||||||
|
shouldGenerateGLError(gl, gl.NO_ERROR, "buffer = gl.createBuffer()");
|
||||||
|
shouldBeFalse("gl.isBuffer(buffer)");
|
||||||
|
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ARRAY_BUFFER, buffer)");
|
||||||
|
shouldBeTrue("gl.isBuffer(buffer)");
|
||||||
|
debug("");
|
||||||
|
|
||||||
|
shouldGenerateGLError(gl, gl.NO_ERROR, "framebuffer = gl.createFramebuffer()");
|
||||||
|
shouldBeFalse("gl.isFramebuffer(framebuffer)");
|
||||||
|
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer)");
|
||||||
|
shouldBeTrue("gl.isFramebuffer(framebuffer)");
|
||||||
|
debug("");
|
||||||
|
|
||||||
|
shouldGenerateGLError(gl, gl.NO_ERROR, "renderbuffer = gl.createRenderbuffer()");
|
||||||
|
shouldBeFalse("gl.isRenderbuffer(renderbuffer)");
|
||||||
|
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer)");
|
||||||
|
shouldBeTrue("gl.isRenderbuffer(renderbuffer)");
|
||||||
|
debug("");
|
||||||
|
|
||||||
|
shouldGenerateGLError(gl, gl.NO_ERROR, "texture = gl.createTexture()");
|
||||||
|
shouldBeFalse("gl.isTexture(texture)");
|
||||||
|
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindTexture(gl.TEXTURE_2D, texture)");
|
||||||
|
shouldBeTrue("gl.isTexture(texture)");
|
||||||
|
debug("");
|
||||||
|
|
||||||
|
shouldGenerateGLError(gl, gl.NO_ERROR, "program = gl.createProgram()");
|
||||||
|
shouldBeTrue("gl.isProgram(program)");
|
||||||
|
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteProgram(program)");
|
||||||
|
shouldBeFalse("gl.isProgram(program)");
|
||||||
|
debug("");
|
||||||
|
|
||||||
|
shouldGenerateGLError(gl, gl.NO_ERROR, "shader = gl.createShader(gl.VERTEX_SHADER)");
|
||||||
|
shouldBeTrue("gl.isShader(shader)");
|
||||||
|
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteShader(shader)");
|
||||||
|
shouldBeFalse("gl.isShader(shader)");
|
||||||
|
debug("");
|
||||||
|
|
||||||
|
successfullyParsed = true;
|
||||||
|
</script>
|
||||||
|
<script src="../resources/js-test-post.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -44,8 +44,6 @@ var gl = null;
|
||||||
var array = null;
|
var array = null;
|
||||||
var pixel = [ 0, 0, 0, 0 ];
|
var pixel = [ 0, 0, 0, 0 ];
|
||||||
var expectedColor = [ 0, 0, 0, 0 ];
|
var expectedColor = [ 0, 0, 0, 0 ];
|
||||||
var pixelFormat = 0;
|
|
||||||
var pixelType = 0;
|
|
||||||
|
|
||||||
function calculatePixelBytes(format, type)
|
function calculatePixelBytes(format, type)
|
||||||
{
|
{
|
||||||
|
@ -168,38 +166,26 @@ function runTestIteration(format, type, packAlignment, width, height)
|
||||||
var bytesPerPixel = calculatePixelBytes(format, type);
|
var bytesPerPixel = calculatePixelBytes(format, type);
|
||||||
var padding = calculatePaddingBytes(bytesPerPixel, packAlignment, width);
|
var padding = calculatePaddingBytes(bytesPerPixel, packAlignment, width);
|
||||||
var size = bytesPerPixel * width * height + padding * (height - 1);
|
var size = bytesPerPixel * width * height + padding * (height - 1);
|
||||||
var isShort = false;
|
if (type != gl.UNSIGNED_BYTE) {
|
||||||
switch (type) {
|
throw "test error: only UNSIGNED_BYTE is valid to ReadPixels";
|
||||||
case gl.UNSIGNED_SHORT_5_6_5:
|
|
||||||
case gl.UNSIGNED_SHORT_4_4_4_4:
|
|
||||||
case gl.UNSIGNED_SHORT_5_5_5_1:
|
|
||||||
isShort = true;
|
|
||||||
}
|
}
|
||||||
if (isShort)
|
|
||||||
size /= 2;
|
|
||||||
if (size < 0)
|
if (size < 0)
|
||||||
size = 0;
|
size = 0;
|
||||||
if (type == gl.UNSIGNED_BYTE)
|
array = new Uint8Array(size);
|
||||||
array = new Uint8Array(size);
|
|
||||||
else
|
|
||||||
array = new Uint16Array(size);
|
|
||||||
gl.readPixels(0, 0, width, height, format, type, array);
|
gl.readPixels(0, 0, width, height, format, type, array);
|
||||||
if (width < 0 || height < 0) {
|
if (width < 0 || height < 0) {
|
||||||
glErrorShouldBe(gl, gl.INVALID_VALUE);
|
glErrorShouldBe(gl, gl.INVALID_VALUE);
|
||||||
return;
|
return;
|
||||||
} else {
|
|
||||||
glErrorShouldBe(gl, gl.NO_ERROR);
|
|
||||||
if (!array.length)
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glErrorShouldBe(gl, gl.NO_ERROR);
|
||||||
|
if (!array.length)
|
||||||
|
return;
|
||||||
|
|
||||||
// Check the last pixel of the last row.
|
// Check the last pixel of the last row.
|
||||||
var bytesPerRow = width * bytesPerPixel + padding;
|
var bytesPerRow = width * bytesPerPixel + padding;
|
||||||
var pos = bytesPerRow * (height - 1) + (width - 1) * bytesPerPixel;
|
var pos = bytesPerRow * (height - 1) + (width - 1) * bytesPerPixel;
|
||||||
var numComponents = bytesPerPixel;
|
var numComponents = bytesPerPixel;
|
||||||
if (isShort) {
|
|
||||||
pos /= 2;
|
|
||||||
numComponents /= 2;
|
|
||||||
}
|
|
||||||
for (var i = 0; i < numComponents; ++i)
|
for (var i = 0; i < numComponents; ++i)
|
||||||
pixel[i] = array[pos + i];
|
pixel[i] = array[pos + i];
|
||||||
for (var i = numComponents; i < 4; ++i)
|
for (var i = numComponents; i < 4; ++i)
|
||||||
|
@ -209,75 +195,44 @@ function runTestIteration(format, type, packAlignment, width, height)
|
||||||
shouldBe("pixel", "expectedColor");
|
shouldBe("pixel", "expectedColor");
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkSupportedPixelFormatAndType()
|
|
||||||
{
|
|
||||||
debug("Check supported pixel format/type besides RGBA/UNSIGNED_BYTE");
|
|
||||||
glErrorShouldBe(gl, gl.NO_ERROR);
|
|
||||||
pixelFormat = gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_FORMAT);
|
|
||||||
pixelType = gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_TYPE);
|
|
||||||
glErrorShouldBe(gl, gl.NO_ERROR);
|
|
||||||
shouldBeFalse("pixelFormat == gl.RGBA && pixelType == gl.UNSIGNED_BYTE");
|
|
||||||
}
|
|
||||||
|
|
||||||
description('Verify readPixels() works fine with various PACK_ALIGNMENT values.');
|
description('Verify readPixels() works fine with various PACK_ALIGNMENT values.');
|
||||||
|
|
||||||
shouldBeNonNull("gl = initWebGL('example', 'vshader', 'fshader', [ 'pos', 'colorIn' ], [ 0, 0, 0, 1 ], 1)");
|
shouldBeNonNull("gl = initWebGL('example', 'vshader', 'fshader', [ 'pos', 'colorIn' ], [ 0, 0, 0, 1 ], 1)");
|
||||||
gl.disable(gl.BLEND);
|
gl.disable(gl.BLEND);
|
||||||
|
|
||||||
checkSupportedPixelFormatAndType();
|
var formats = [ gl.RGBA ];
|
||||||
|
var formatNames = [ "RGBA" ];
|
||||||
|
|
||||||
debug("Testing format = RGBA and type = UNSIGNED_BYTE");
|
for (var i = 0; i < formats.length; ++i) {
|
||||||
runTestIteration(gl.RGBA, gl.UNSIGNED_BYTE, 1, 1, 2);
|
var format = formats[i];
|
||||||
runTestIteration(gl.RGBA, gl.UNSIGNED_BYTE, 2, 1, 2);
|
|
||||||
runTestIteration(gl.RGBA, gl.UNSIGNED_BYTE, 4, 1, 2);
|
|
||||||
runTestIteration(gl.RGBA, gl.UNSIGNED_BYTE, 8, 1, 2);
|
|
||||||
runTestIteration(gl.RGBA, gl.UNSIGNED_BYTE, 4, 2, 2);
|
|
||||||
runTestIteration(gl.RGBA, gl.UNSIGNED_BYTE, 8, 2, 2);
|
|
||||||
runTestIteration(gl.RGBA, gl.UNSIGNED_BYTE, 4, 3, 2);
|
|
||||||
runTestIteration(gl.RGBA, gl.UNSIGNED_BYTE, 8, 3, 2);
|
|
||||||
runTestIteration(gl.RGBA, gl.UNSIGNED_BYTE, 4, 4, 2);
|
|
||||||
runTestIteration(gl.RGBA, gl.UNSIGNED_BYTE, 8, 4, 2);
|
|
||||||
runTestIteration(gl.RGBA, gl.UNSIGNED_BYTE, 8, 5, 1);
|
|
||||||
runTestIteration(gl.RGBA, gl.UNSIGNED_BYTE, 4, 5, 2);
|
|
||||||
runTestIteration(gl.RGBA, gl.UNSIGNED_BYTE, 8, 5, 2);
|
|
||||||
runTestIteration(gl.RGBA, gl.UNSIGNED_BYTE, 8, 6, 2);
|
|
||||||
runTestIteration(gl.RGBA, gl.UNSIGNED_BYTE, 8, 7, 2);
|
|
||||||
runTestIteration(gl.RGBA, gl.UNSIGNED_BYTE, 8, 8, 2);
|
|
||||||
runTestIteration(gl.RGBA, gl.UNSIGNED_BYTE, 1, 0, 0);
|
|
||||||
runTestIteration(gl.RGBA, gl.UNSIGNED_BYTE, 2, 0, 0);
|
|
||||||
runTestIteration(gl.RGBA, gl.UNSIGNED_BYTE, 4, 0, 0);
|
|
||||||
runTestIteration(gl.RGBA, gl.UNSIGNED_BYTE, 8, 0, 0);
|
|
||||||
runTestIteration(gl.RGBA, gl.UNSIGNED_BYTE, 1, -1, 1);
|
|
||||||
runTestIteration(gl.RGBA, gl.UNSIGNED_BYTE, 2, 1, -1);
|
|
||||||
runTestIteration(gl.RGBA, gl.UNSIGNED_BYTE, 4, 0, -1);
|
|
||||||
runTestIteration(gl.RGBA, gl.UNSIGNED_BYTE, 8, -1, -1);
|
|
||||||
|
|
||||||
debug("Testing the other supported format/type combination");
|
|
||||||
runTestIteration(pixelFormat, pixelType, 1, 1, 2);
|
|
||||||
runTestIteration(pixelFormat, pixelType, 2, 1, 2);
|
|
||||||
runTestIteration(pixelFormat, pixelType, 4, 1, 2);
|
|
||||||
runTestIteration(pixelFormat, pixelType, 8, 1, 2);
|
|
||||||
runTestIteration(pixelFormat, pixelType, 4, 2, 2);
|
|
||||||
runTestIteration(pixelFormat, pixelType, 8, 2, 2);
|
|
||||||
runTestIteration(pixelFormat, pixelType, 4, 3, 2);
|
|
||||||
runTestIteration(pixelFormat, pixelType, 8, 3, 2);
|
|
||||||
runTestIteration(pixelFormat, pixelType, 4, 4, 2);
|
|
||||||
runTestIteration(pixelFormat, pixelType, 8, 4, 2);
|
|
||||||
runTestIteration(pixelFormat, pixelType, 8, 5, 1);
|
|
||||||
runTestIteration(pixelFormat, pixelType, 4, 5, 2);
|
|
||||||
runTestIteration(pixelFormat, pixelType, 8, 5, 2);
|
|
||||||
runTestIteration(pixelFormat, pixelType, 8, 6, 2);
|
|
||||||
runTestIteration(pixelFormat, pixelType, 8, 7, 2);
|
|
||||||
runTestIteration(pixelFormat, pixelType, 8, 8, 2);
|
|
||||||
runTestIteration(pixelFormat, pixelType, 1, 0, 0);
|
|
||||||
runTestIteration(pixelFormat, pixelType, 2, 0, 0);
|
|
||||||
runTestIteration(pixelFormat, pixelType, 4, 0, 0);
|
|
||||||
runTestIteration(pixelFormat, pixelType, 8, 0, 0);
|
|
||||||
runTestIteration(pixelFormat, pixelType, 1, -1, 1);
|
|
||||||
runTestIteration(pixelFormat, pixelType, 2, 1, -1);
|
|
||||||
runTestIteration(pixelFormat, pixelType, 4, 0, -1);
|
|
||||||
runTestIteration(pixelFormat, pixelType, 8, -1, -1);
|
|
||||||
|
|
||||||
|
debug("Testing format = " + formatNames[i] + " and type = UNSIGNED_BYTE");
|
||||||
|
runTestIteration(format, gl.UNSIGNED_BYTE, 1, 1, 2);
|
||||||
|
runTestIteration(format, gl.UNSIGNED_BYTE, 2, 1, 2);
|
||||||
|
runTestIteration(format, gl.UNSIGNED_BYTE, 4, 1, 2);
|
||||||
|
runTestIteration(format, gl.UNSIGNED_BYTE, 8, 1, 2);
|
||||||
|
runTestIteration(format, gl.UNSIGNED_BYTE, 4, 2, 2);
|
||||||
|
runTestIteration(format, gl.UNSIGNED_BYTE, 8, 2, 2);
|
||||||
|
runTestIteration(format, gl.UNSIGNED_BYTE, 4, 3, 2);
|
||||||
|
runTestIteration(format, gl.UNSIGNED_BYTE, 8, 3, 2);
|
||||||
|
runTestIteration(format, gl.UNSIGNED_BYTE, 4, 4, 2);
|
||||||
|
runTestIteration(format, gl.UNSIGNED_BYTE, 8, 4, 2);
|
||||||
|
runTestIteration(format, gl.UNSIGNED_BYTE, 8, 5, 1);
|
||||||
|
runTestIteration(format, gl.UNSIGNED_BYTE, 4, 5, 2);
|
||||||
|
runTestIteration(format, gl.UNSIGNED_BYTE, 8, 5, 2);
|
||||||
|
runTestIteration(format, gl.UNSIGNED_BYTE, 8, 6, 2);
|
||||||
|
runTestIteration(format, gl.UNSIGNED_BYTE, 8, 7, 2);
|
||||||
|
runTestIteration(format, gl.UNSIGNED_BYTE, 8, 8, 2);
|
||||||
|
runTestIteration(format, gl.UNSIGNED_BYTE, 1, 0, 0);
|
||||||
|
runTestIteration(format, gl.UNSIGNED_BYTE, 2, 0, 0);
|
||||||
|
runTestIteration(format, gl.UNSIGNED_BYTE, 4, 0, 0);
|
||||||
|
runTestIteration(format, gl.UNSIGNED_BYTE, 8, 0, 0);
|
||||||
|
runTestIteration(format, gl.UNSIGNED_BYTE, 1, -1, 1);
|
||||||
|
runTestIteration(format, gl.UNSIGNED_BYTE, 2, 1, -1);
|
||||||
|
runTestIteration(format, gl.UNSIGNED_BYTE, 4, 0, -1);
|
||||||
|
runTestIteration(format, gl.UNSIGNED_BYTE, 8, -1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
successfullyParsed = true;
|
successfullyParsed = true;
|
||||||
</script>
|
</script>
|
||||||
<script src="../resources/js-test-post.js"></script>
|
<script src="../resources/js-test-post.js"></script>
|
||||||
|
|
|
@ -11,6 +11,7 @@ found in the LICENSE file.
|
||||||
<link rel="stylesheet" href="../resources/js-test-style.css"/>
|
<link rel="stylesheet" href="../resources/js-test-style.css"/>
|
||||||
<script src="../resources/js-test-pre.js"></script>
|
<script src="../resources/js-test-pre.js"></script>
|
||||||
<script src="resources/webgl-test.js"> </script>
|
<script src="resources/webgl-test.js"> </script>
|
||||||
|
<script src="resources/webgl-test-utils.js"> </script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<canvas id="example" width="200" height="200"></canvas>
|
<canvas id="example" width="200" height="200"></canvas>
|
||||||
|
@ -19,6 +20,7 @@ found in the LICENSE file.
|
||||||
<script>
|
<script>
|
||||||
description("Checks that ReadPixels works as expected.");
|
description("Checks that ReadPixels works as expected.");
|
||||||
|
|
||||||
|
var wtu = WebGLTestUtils;
|
||||||
var canvas = document.getElementById("example");
|
var canvas = document.getElementById("example");
|
||||||
var gl = create3DContext(canvas);
|
var gl = create3DContext(canvas);
|
||||||
|
|
||||||
|
@ -90,6 +92,56 @@ function checkBuffer(checkColor, x, y, oneColor, oneX, oneY) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var badFormats = [
|
||||||
|
{
|
||||||
|
format: gl.RGB,
|
||||||
|
type: gl.UNSIGNED_BYTE,
|
||||||
|
dest: new Uint8Array(3)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
format: gl.RGB,
|
||||||
|
type: gl.UNSIGNED_SHORT_5_6_5,
|
||||||
|
dest: new Uint8Array(3)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
format: gl.RGBA,
|
||||||
|
type: gl.UNSIGNED_SHORT_5_5_5_1,
|
||||||
|
dest: new Uint16Array(1)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
format: gl.RGBA,
|
||||||
|
type: gl.UNSIGNED_SHORT_4_4_4_4,
|
||||||
|
dest: new Uint16Array(1)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
format: gl.ALPHA,
|
||||||
|
type: gl.UNSIGNED_BYTE,
|
||||||
|
dest: new Uint8Array(1)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
format: gl.LUMINANCE,
|
||||||
|
type: gl.UNSIGNED_BYTE,
|
||||||
|
dest: new Uint8Array(1) },
|
||||||
|
{
|
||||||
|
format: gl.LUMINANCE_ALPHA,
|
||||||
|
type: gl.UNSIGNED_BYTE,
|
||||||
|
dest: new Uint8Array(2)
|
||||||
|
}
|
||||||
|
];
|
||||||
|
for (var tt = 0; tt < badFormats.length; ++ tt) {
|
||||||
|
var info = badFormats[tt]
|
||||||
|
var format = info.format;
|
||||||
|
var type = info.type;
|
||||||
|
var dest = info.dest;
|
||||||
|
gl.readPixels(0, 0, 1, 1, format, type, dest);
|
||||||
|
// note that the GL error is INVALID_OPERATION if both format and type are invalid, but
|
||||||
|
// INVALID_ENUM if only one is.
|
||||||
|
glErrorShouldBe(
|
||||||
|
gl, (format == gl.RGBA || type == gl.UNSIGNED_BYTE) ? gl.INVALID_ENUM : gl.INVALID_OPERATION,
|
||||||
|
"Should not be able to read as " + wtu.glEnumToString(gl, format) +
|
||||||
|
" / " + wtu.glEnumToString(gl, type));
|
||||||
|
}
|
||||||
|
|
||||||
debug("");
|
debug("");
|
||||||
successfullyParsed = true;
|
successfullyParsed = true;
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -12,7 +12,7 @@ found in the LICENSE file.
|
||||||
function runTest()
|
function runTest()
|
||||||
{
|
{
|
||||||
var canvas = document.getElementById("testbed");
|
var canvas = document.getElementById("testbed");
|
||||||
var gl = canvas.getContext("experimental-webgl");
|
var gl = create3DContext(canvas);
|
||||||
if (!gl) {
|
if (!gl) {
|
||||||
testFailed('canvas.getContext() failed');
|
testFailed('canvas.getContext() failed');
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -9,46 +9,18 @@ found in the LICENSE file.
|
||||||
<script src="../resources/js-test-pre.js"></script>
|
<script src="../resources/js-test-pre.js"></script>
|
||||||
<script src="resources/webgl-test.js"></script>
|
<script src="resources/webgl-test.js"></script>
|
||||||
<script src="resources/webgl-test-utils.js"></script>
|
<script src="resources/webgl-test-utils.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<canvas id="example" width="1px" height="2px"></canvas>
|
||||||
|
<div id="description"></div>
|
||||||
|
<div id="console"></div>
|
||||||
<script>
|
<script>
|
||||||
|
description('Verifies texImage2D and texSubImage2D code paths taking ArrayBufferView');
|
||||||
|
|
||||||
var wtu = WebGLTestUtils;
|
var wtu = WebGLTestUtils;
|
||||||
var gl = null;
|
var gl = null;
|
||||||
var textureLoc = null;
|
var textureLoc = null;
|
||||||
var successfullyParsed = false;
|
var successfullyParsed = false;
|
||||||
var imageData = null;
|
|
||||||
|
|
||||||
function init()
|
|
||||||
{
|
|
||||||
if (window.initNonKhronosFramework) {
|
|
||||||
window.initNonKhronosFramework(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
description('Verifies texImage2D and texSubImage2D code paths taking ArrayBufferView');
|
|
||||||
|
|
||||||
var canvas2d = document.getElementById("texcanvas");
|
|
||||||
var context2d = canvas2d.getContext("2d");
|
|
||||||
imageData = context2d.createImageData(1, 2);
|
|
||||||
var data = imageData.data;
|
|
||||||
data[0] = 255;
|
|
||||||
data[1] = 0;
|
|
||||||
data[2] = 0;
|
|
||||||
data[3] = 255;
|
|
||||||
data[4] = 0;
|
|
||||||
data[5] = 255;
|
|
||||||
data[6] = 0;
|
|
||||||
data[7] = 0;
|
|
||||||
|
|
||||||
var canvas = document.getElementById("example");
|
|
||||||
gl = wtu.create3DContext(canvas);
|
|
||||||
var program = wtu.setupTexturedQuad(gl);
|
|
||||||
gl.disable(gl.BLEND);
|
|
||||||
|
|
||||||
gl.clearColor(0,0,0,1);
|
|
||||||
gl.clearDepth(1);
|
|
||||||
|
|
||||||
textureLoc = gl.getUniformLocation(program, "tex");
|
|
||||||
|
|
||||||
runTest();
|
|
||||||
}
|
|
||||||
|
|
||||||
// These two declarations need to be global for "shouldBe" to see them
|
// These two declarations need to be global for "shouldBe" to see them
|
||||||
var buf = null;
|
var buf = null;
|
||||||
|
@ -199,24 +171,21 @@ function runTest()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
successfullyParsed = true;
|
|
||||||
var epilogue = document.createElement("script");
|
|
||||||
epilogue.onload = finish;
|
|
||||||
epilogue.src = "../resources/js-test-post.js";
|
|
||||||
document.body.appendChild(epilogue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function finish() {
|
var canvas = document.getElementById("example");
|
||||||
if (window.nonKhronosFrameworkNotifyDone) {
|
gl = wtu.create3DContext(canvas);
|
||||||
window.nonKhronosFrameworkNotifyDone();
|
var program = wtu.setupTexturedQuad(gl);
|
||||||
}
|
gl.disable(gl.BLEND);
|
||||||
}
|
|
||||||
|
gl.clearColor(0,0,0,1);
|
||||||
|
gl.clearDepth(1);
|
||||||
|
|
||||||
|
textureLoc = gl.getUniformLocation(program, "tex");
|
||||||
|
|
||||||
|
runTest();
|
||||||
|
successfullyParsed = true;
|
||||||
</script>
|
</script>
|
||||||
</head>
|
<script src="../resources/js-test-post.js"></script>
|
||||||
<body onload="init()">
|
|
||||||
<canvas id="texcanvas" width="1px" height="2px"></canvas>
|
|
||||||
<canvas id="example" width="1px" height="2px"></canvas>
|
|
||||||
<div id="description"></div>
|
|
||||||
<div id="console"></div>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -6,13 +6,12 @@
|
||||||
<link rel="stylesheet" href="../resources/js-test-style.css"/>
|
<link rel="stylesheet" href="../resources/js-test-style.css"/>
|
||||||
<script src="../resources/js-test-pre.js"></script>
|
<script src="../resources/js-test-pre.js"></script>
|
||||||
<script src="resources/webgl-test.js"></script>
|
<script src="resources/webgl-test.js"></script>
|
||||||
<script src="resources/testrunner.js"></script>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="description"></div>
|
<div id="description"></div>
|
||||||
<div id="console"></div>
|
<div id="console"></div>
|
||||||
<canvas id="canvas" width="2" height="2"> </canvas>
|
<canvas id="canvas" width="2" height="2"> </canvas>
|
||||||
<script><!--
|
<script type="text/javascript">
|
||||||
description("texImage2D and texSubImage2D tests with invalid data");
|
description("texImage2D and texSubImage2D tests with invalid data");
|
||||||
|
|
||||||
var canvas = document.getElementById("canvas");
|
var canvas = document.getElementById("canvas");
|
||||||
|
@ -22,63 +21,79 @@ if (!gl)
|
||||||
else
|
else
|
||||||
testPassed("Context created.");
|
testPassed("Context created.");
|
||||||
|
|
||||||
|
var tex;
|
||||||
|
|
||||||
/* object containing all tests in this testsuite */
|
function setup() {
|
||||||
var bug32619_tests = {
|
tex = gl.createTexture();
|
||||||
setup: function () {
|
|
||||||
bug32619_tests.tex = gl.createTexture();
|
|
||||||
gl.bindTexture(gl.TEXTURE_2D, bug32619_tests.tex);
|
gl.bindTexture(gl.TEXTURE_2D, bug32619_tests.tex);
|
||||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 64, 64, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
|
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 64, 64, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
|
||||||
},
|
|
||||||
teardown: function () {
|
|
||||||
gl.deleteTexture(bug32619_tests.tex);
|
|
||||||
},
|
|
||||||
|
|
||||||
"Passing a buffer not large enough to texImage2D should generate an INVALID_OPERATION" : function () {
|
|
||||||
this.setup = function () {
|
|
||||||
var tooSmall = new Uint8Array(64);
|
|
||||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 64, 64, 0, gl.RGBA, gl.UNSIGNED_BYTE, tooSmall);
|
|
||||||
};
|
|
||||||
this.expects = gl.INVALID_OPERATION;
|
|
||||||
},
|
|
||||||
"Passing texImage2D parameter data of Number type should throw a TypeError" : function () {
|
|
||||||
this.setup = function () {
|
|
||||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 64, 64, 0, gl.RGBA, gl.UNSIGNED_BYTE, 42);
|
|
||||||
};
|
|
||||||
this.expects = "TypeError";
|
|
||||||
},
|
|
||||||
"Passing texImage2D parameter data of String type should throw a TypeError" : function () {
|
|
||||||
this.setup = function () {
|
|
||||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 64, 64, 0, gl.RGBA, gl.UNSIGNED_BYTE, "not a buffer");
|
|
||||||
};
|
|
||||||
this.expects = "TypeError";
|
|
||||||
},
|
|
||||||
"Passing a buffer not large enough to texSubImage2D should generate an INVALID_OPERATION" : function () {
|
|
||||||
this.setup = function () {
|
|
||||||
var tooSmall = new Uint8Array(64);
|
|
||||||
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 64, 64, gl.RGBA, gl.UNSIGNED_BYTE, tooSmall);
|
|
||||||
};
|
|
||||||
this.expects = gl.INVALID_OPERATION;
|
|
||||||
},
|
|
||||||
"Passing texSubImage2D parameter data of Number type should throw a TypeError" : function () {
|
|
||||||
this.setup = function () {
|
|
||||||
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 64, 64, gl.RGBA, gl.UNSIGNED_BYTE, 42);
|
|
||||||
};
|
|
||||||
this.expects = "TypeError";
|
|
||||||
},
|
|
||||||
"Passing texSubImage2D parameter data of String type should throw a TypeError" : function () {
|
|
||||||
this.setup = function () {
|
|
||||||
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 64, 64, gl.RGBA, gl.UNSIGNED_BYTE, "not a buffer");
|
|
||||||
};
|
|
||||||
this.expects = "TypeError";
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
runTestsuite(bug32619_tests);
|
function teardown() {
|
||||||
|
gl.deleteTexture(tex);
|
||||||
|
}
|
||||||
|
|
||||||
|
function test(desc, func, expected) {
|
||||||
|
debug(desc);
|
||||||
|
|
||||||
|
var exc = null;
|
||||||
|
try {
|
||||||
|
func();
|
||||||
|
} catch (x) {
|
||||||
|
exc = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expected == gl.INVALID_OPERATION) {
|
||||||
|
glErrorShouldBe(gl, expected);
|
||||||
|
} else if (expected == "exception") {
|
||||||
|
if (exc) {
|
||||||
|
testPassed("threw exception");
|
||||||
|
} else {
|
||||||
|
testFailed("did not throw exception");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test("Passing a buffer not large enough to texImage2D should generate an INVALID_OPERATION",
|
||||||
|
function () {
|
||||||
|
var tooSmall = new Uint8Array(64);
|
||||||
|
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 64, 64, 0, gl.RGBA, gl.UNSIGNED_BYTE, tooSmall);
|
||||||
|
},
|
||||||
|
gl.INVALID_OPERATION);
|
||||||
|
|
||||||
|
test("Passing texImage2D parameter data of Number type should throw an exception",
|
||||||
|
function () {
|
||||||
|
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 64, 64, 0, gl.RGBA, gl.UNSIGNED_BYTE, 42);
|
||||||
|
},
|
||||||
|
"exception");
|
||||||
|
|
||||||
|
test("Passing texImage2D parameter data of String type should throw a TypeError",
|
||||||
|
function () {
|
||||||
|
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 64, 64, 0, gl.RGBA, gl.UNSIGNED_BYTE, "not a buffer");
|
||||||
|
},
|
||||||
|
"exception");
|
||||||
|
test("Passing a buffer not large enough to texSubImage2D should generate an INVALID_OPERATION",
|
||||||
|
function () {
|
||||||
|
var tooSmall = new Uint8Array(64);
|
||||||
|
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 64, 64, gl.RGBA, gl.UNSIGNED_BYTE, tooSmall);
|
||||||
|
},
|
||||||
|
gl.INVALID_OPERATION);
|
||||||
|
|
||||||
|
test("Passing texSubImage2D parameter data of Number type should throw a TypeError",
|
||||||
|
function () {
|
||||||
|
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 64, 64, gl.RGBA, gl.UNSIGNED_BYTE, 42);
|
||||||
|
},
|
||||||
|
"exception");
|
||||||
|
|
||||||
|
test("Passing texSubImage2D parameter data of String type should throw a TypeError",
|
||||||
|
function () {
|
||||||
|
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 64, 64, gl.RGBA, gl.UNSIGNED_BYTE, "not a buffer");
|
||||||
|
},
|
||||||
|
"exception");
|
||||||
|
|
||||||
debug("");
|
debug("");
|
||||||
successfullyParsed = true;
|
successfullyParsed = true;
|
||||||
--></script>
|
</script>
|
||||||
<script src="../resources/js-test-post.js"></script>
|
<script src="../resources/js-test-post.js"></script>
|
||||||
<script>
|
<script>
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -51,7 +51,7 @@ function init()
|
||||||
var canvas = document.getElementById("example");
|
var canvas = document.getElementById("example");
|
||||||
gl = wtu.create3DContext(canvas);
|
gl = wtu.create3DContext(canvas);
|
||||||
var program = wtu.setupTexturedQuad(gl);
|
var program = wtu.setupTexturedQuad(gl);
|
||||||
gl.clearColor(0,0,0,1);
|
gl.clearColor(0.5,0.5,0.5,1);
|
||||||
gl.clearDepth(1);
|
gl.clearDepth(1);
|
||||||
|
|
||||||
textureLoc = gl.getUniformLocation(program, "tex");
|
textureLoc = gl.getUniformLocation(program, "tex");
|
||||||
|
@ -70,7 +70,7 @@ function init()
|
||||||
gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
|
gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
|
||||||
gl.bufferData(gl.ARRAY_BUFFER, texCoords, gl.STATIC_DRAW);
|
gl.bufferData(gl.ARRAY_BUFFER, texCoords, gl.STATIC_DRAW);
|
||||||
gl.enableVertexAttribArray(1);
|
gl.enableVertexAttribArray(1);
|
||||||
gl.vertexAttribPointer(1, 2, gl.FLOAT, gl.FALSE, 0, 0);
|
gl.vertexAttribPointer(1, 2, gl.FLOAT, false, 0, 0);
|
||||||
|
|
||||||
texture = wtu.loadTexture(gl, "resources/bug-32888-texture.png", runTest);
|
texture = wtu.loadTexture(gl, "resources/bug-32888-texture.png", runTest);
|
||||||
}
|
}
|
||||||
|
@ -82,16 +82,18 @@ var idx = 0;
|
||||||
function runTest()
|
function runTest()
|
||||||
{
|
{
|
||||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||||
|
gl.enable(gl.BLEND);
|
||||||
|
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
|
||||||
// Bind the texture to texture unit 0
|
// Bind the texture to texture unit 0
|
||||||
gl.bindTexture(gl.TEXTURE_2D, texture);
|
gl.bindTexture(gl.TEXTURE_2D, texture);
|
||||||
// Point the uniform sampler to texture unit 0
|
// Point the uniform sampler to texture unit 0
|
||||||
gl.uniform1i(textureLoc, 0);
|
gl.uniform1i(textureLoc, 0);
|
||||||
// Draw the triangles
|
// Draw the triangles
|
||||||
wtu.drawQuad(gl, [100, 100, 100, 255]);
|
wtu.drawQuad(gl, [0, 0, 0, 255]);
|
||||||
|
|
||||||
// Spot check a couple of 2x2 regions in the upper and lower left
|
// Spot check a couple of 2x2 regions in the upper and lower left
|
||||||
// corners; they should be the rgb values in the texture.
|
// corners; they should be the rgb values in the texture.
|
||||||
color = [255, 255, 255]
|
color = [0, 0, 0];
|
||||||
debug("Checking lower left corner");
|
debug("Checking lower left corner");
|
||||||
wtu.checkCanvasRect(gl, 1, gl.canvas.height - 3, 2, 2, color,
|
wtu.checkCanvasRect(gl, 1, gl.canvas.height - 3, 2, 2, color,
|
||||||
"shouldBe " + color);
|
"shouldBe " + color);
|
||||||
|
|
|
@ -0,0 +1,168 @@
|
||||||
|
<!--
|
||||||
|
Copyright (C) 2009 Apple Computer, Inc. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
1. Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
|
||||||
|
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||||
|
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
-->
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<link rel="stylesheet" href="../resources/js-test-style.css"/>
|
||||||
|
<script src="../resources/js-test-pre.js"></script>
|
||||||
|
<script src="resources/webgl-test.js"></script>
|
||||||
|
<script src="resources/webgl-test-utils.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="description"></div>
|
||||||
|
<div id="console"></div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var wtu = WebGLTestUtils;
|
||||||
|
description("Tests calling WebGL APIs with various types");
|
||||||
|
|
||||||
|
var context = wtu.create3DContext();
|
||||||
|
var program = wtu.loadStandardProgram(context);
|
||||||
|
var shader = wtu.loadStandardVertexShader(context);
|
||||||
|
var shouldGenerateGLError = wtu.shouldGenerateGLError;
|
||||||
|
|
||||||
|
assertMsg(program != null, "Program Compiled");
|
||||||
|
assertMsg(shader != null, "Shader Compiled");
|
||||||
|
|
||||||
|
var loc = context.getUniformLocation(program, "u_modelViewProjMatrix");
|
||||||
|
assertMsg(loc != null, "getUniformLocation succeeded");
|
||||||
|
|
||||||
|
var buffer = context.createBuffer();
|
||||||
|
context.bindBuffer(context.ARRAY_BUFFER, buffer);
|
||||||
|
var texture = context.createTexture();
|
||||||
|
context.bindTexture(context.TEXTURE_2D, texture);
|
||||||
|
context.useProgram(program);
|
||||||
|
|
||||||
|
var args = [
|
||||||
|
{ type: "number", value: 0 },
|
||||||
|
{ type: "number", value: 2 },
|
||||||
|
{ type: "string that is NaN", value: "foo", },
|
||||||
|
{ type: "string that is number", value: "2", },
|
||||||
|
{ type: "null", value: null },
|
||||||
|
{ type: "Empty Array", value: [] },
|
||||||
|
{ type: "Object", value: {} },
|
||||||
|
{ type: "Array of Number", value: [2] },
|
||||||
|
{ type: "Array of String", value: ["foo"] },
|
||||||
|
{ type: "Array of String that is number", value: ["0"] },
|
||||||
|
{ type: "Array of String that is number", value: ["2"] },
|
||||||
|
{ type: "TypedArray", value: new Float32Array(1) }
|
||||||
|
];
|
||||||
|
|
||||||
|
var argument;
|
||||||
|
|
||||||
|
for (var i = 0; i < args.length; ++i) {
|
||||||
|
argument = args[i].value;
|
||||||
|
var func1 = shouldBeUndefined;
|
||||||
|
var func2 = shouldBeNonNull;
|
||||||
|
if (argument == 2) {
|
||||||
|
func2 = shouldBeNull;
|
||||||
|
}
|
||||||
|
func3 = shouldBeNull;
|
||||||
|
debug("");
|
||||||
|
debug("testing type of " + args[i].type + " : value = " + argument);
|
||||||
|
func1("context.bindAttribLocation(program, argument, 'foo')");
|
||||||
|
func1("context.blendColor(argument, argument, argument, argument)");
|
||||||
|
func1("context.bufferData(context.ARRAY_BUFFER, argument, context.STATIC_DRAW)");
|
||||||
|
func1("context.bufferData(context.ARRAY_BUFFER, new Float32Array(10), context.STATIC_DRAW)");
|
||||||
|
func1("context.bufferSubData(context.ARRAY_BUFFER, argument, new Float32Array(2))");
|
||||||
|
func1("context.clear(argument)")
|
||||||
|
func1("context.clearColor(argument, 0, 0, 0)");
|
||||||
|
func1("context.clearColor(0, argument, 0, 0)");
|
||||||
|
func1("context.clearColor(0, 0, argument, 0)");
|
||||||
|
func1("context.clearColor(0, 0, 0, argument)");
|
||||||
|
func1("context.clearDepth(argument)");
|
||||||
|
func1("context.clearStencil(argument)");
|
||||||
|
func1("context.copyTexImage2D(context.TEXTURE_2D, argument, context.RGBA, 0, 0, 1, 1, 0)");
|
||||||
|
func1("context.copyTexImage2D(context.TEXTURE_2D, 0, context.RGBA, argument, 0, 1, 1, 0)");
|
||||||
|
func1("context.copyTexImage2D(context.TEXTURE_2D, 0, context.RGBA, 0, argument, 1, 1, 0)");
|
||||||
|
func1("context.copyTexImage2D(context.TEXTURE_2D, 0, context.RGBA, 0, 0, argument, 1, 0)");
|
||||||
|
func1("context.copyTexImage2D(context.TEXTURE_2D, 0, context.RGBA, 0, 0, 0, argument, 0)");
|
||||||
|
func1("context.copyTexSubImage2D(context.TEXTURE_2D, argument, 0, 0, 0, 0, 0, 0)");
|
||||||
|
func1("context.copyTexSubImage2D(context.TEXTURE_2D, 0, argument, 0, 0, 0, 0, 0)");
|
||||||
|
func1("context.copyTexSubImage2D(context.TEXTURE_2D, 0, 0, argument, 0, 0, 0, 0)");
|
||||||
|
func1("context.copyTexSubImage2D(context.TEXTURE_2D, 0, 0, 0, argument, 0, 0, 0)");
|
||||||
|
func1("context.copyTexSubImage2D(context.TEXTURE_2D, 0, 0, 0, 0, argument, 0, 0)");
|
||||||
|
func1("context.copyTexSubImage2D(context.TEXTURE_2D, 0, 0, 0, 0, 0, argument, 0)");
|
||||||
|
func1("context.copyTexSubImage2D(context.TEXTURE_2D, 0, 0, 0, 0, 0, 0, argument)");
|
||||||
|
func1("context.depthMask(argument)");
|
||||||
|
func1("context.depthRange(argument, 1)");
|
||||||
|
func1("context.depthRange(0, argument)");
|
||||||
|
func1("context.drawArrays(context.POINTS, argument, 1)");
|
||||||
|
func1("context.drawArrays(context.POINTS, 0, argument)");
|
||||||
|
//func1("context.drawElements(...)");
|
||||||
|
func1("context.enableVertexAttribArray(argument)");
|
||||||
|
func1("context.disableVertexAttribArray(argument)");
|
||||||
|
func2("context.getActiveAttrib(program, argument)");
|
||||||
|
func2("context.getActiveUniform(program, argument)");
|
||||||
|
func3("context.getParameter(argument)");
|
||||||
|
func1("context.lineWidth(argument)");
|
||||||
|
func1("context.polygonOffset(argument, 0)");
|
||||||
|
func1("context.polygonOffset(0, argument)");
|
||||||
|
//func1("context.readPixels(...)");
|
||||||
|
//func1("context.renderbufferStorage(...)");
|
||||||
|
func1("context.sampleCoverage(argument, 0)");
|
||||||
|
func1("context.sampleCoverage(0, argument)");
|
||||||
|
func1("context.scissor(argument, 0, 10, 10)");
|
||||||
|
func1("context.scissor(0, argument, 10, 10)");
|
||||||
|
func1("context.scissor(0, 0, argument, 10)");
|
||||||
|
func1("context.scissor(0, 0, 10, argument)");
|
||||||
|
func1("context.shaderSource(shader, argument)");
|
||||||
|
func1("context.stencilFunc(context.NEVER, argument, 255)");
|
||||||
|
func1("context.stencilFunc(context.NEVER, 0, argument)");
|
||||||
|
//func1("context.stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)");
|
||||||
|
func1("context.stencilMask(argument)");
|
||||||
|
//func1("context.stencilMaskSeparate(context.FRONT, argument);
|
||||||
|
//func1("context.texImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, ArrayBufferView pixels)");
|
||||||
|
//func1("context.texParameterf(GLenum target, GLenum pname, GLfloat param)");
|
||||||
|
//func1("context.texParameteri(GLenum target, GLenum pname, GLint param)");
|
||||||
|
//func1("context.texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,GLsizei width, GLsizei height,GLenum format, GLenum type, ArrayBufferView pixels)");
|
||||||
|
func1("context.uniform1i(loc, argument)");
|
||||||
|
func1("context.uniform2i(loc, argument, 0)");
|
||||||
|
func1("context.uniform2i(loc, 0, argument)");
|
||||||
|
func1("context.uniform3i(loc, argument, 0, 0)");
|
||||||
|
func1("context.uniform3i(loc, 0, argument, 0)");
|
||||||
|
func1("context.uniform3i(loc, 0, 0, argument)");
|
||||||
|
func1("context.uniform4i(loc, argument, 0, 0, 0)");
|
||||||
|
func1("context.uniform4i(loc, 0, argument, 0, 0)");
|
||||||
|
func1("context.uniform4i(loc, 0, 0, argument, 0)");
|
||||||
|
func1("context.uniform4i(loc, 0, 0, 0, argument)");
|
||||||
|
func1("context.uniform1f(loc, argument)");
|
||||||
|
func1("context.uniform2f(loc, argument, 0)");
|
||||||
|
func1("context.uniform2f(loc, 0, argument)");
|
||||||
|
func1("context.uniform3f(loc, argument, 0, 0)");
|
||||||
|
func1("context.uniform3f(loc, 0, argument, 0)");
|
||||||
|
func1("context.uniform3f(loc, 0, 0, argument)");
|
||||||
|
func1("context.uniform4f(loc, argument, 0, 0, 0)");
|
||||||
|
func1("context.uniform4f(loc, 0, argument, 0, 0)");
|
||||||
|
func1("context.uniform4f(loc, 0, 0, argument, 0)");
|
||||||
|
func1("context.uniform4f(loc, 0, 0, 0, argument)");
|
||||||
|
}
|
||||||
|
|
||||||
|
successfullyParsed = true;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script src="../resources/js-test-post.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
|
@ -6,13 +6,12 @@
|
||||||
<link rel="stylesheet" href="../resources/js-test-style.css"/>
|
<link rel="stylesheet" href="../resources/js-test-style.css"/>
|
||||||
<script src="../resources/js-test-pre.js"></script>
|
<script src="../resources/js-test-pre.js"></script>
|
||||||
<script src="resources/webgl-test.js"></script>
|
<script src="resources/webgl-test.js"></script>
|
||||||
<script src="resources/testrunner.js"></script>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="description"></div>
|
<div id="description"></div>
|
||||||
<div id="console"></div>
|
<div id="console"></div>
|
||||||
<canvas id="canvas" width="2" height="2"> </canvas>
|
<canvas id="canvas" width="2" height="2"> </canvas>
|
||||||
<script><!--
|
<script>
|
||||||
description("Tests to check user code cannot access uninitialized data from GL resources.");
|
description("Tests to check user code cannot access uninitialized data from GL resources.");
|
||||||
|
|
||||||
var canvas = document.getElementById("canvas");
|
var canvas = document.getElementById("canvas");
|
||||||
|
@ -23,66 +22,71 @@ else
|
||||||
testPassed("Context created.");
|
testPassed("Context created.");
|
||||||
|
|
||||||
|
|
||||||
/* object containing all tests in this testsuite */
|
debug("Reading an uninitialized texture should succeed with all bytes set to 0.");
|
||||||
var uninitializedTests = {
|
|
||||||
"Reading an uninitialized texture should succeed with all bytes set to 0." : function () {
|
|
||||||
this._width = 512;
|
|
||||||
this._height = 512;
|
|
||||||
this._bpp = 4;
|
|
||||||
this._expectedDataLength = this._width*this._height*this._bpp;
|
|
||||||
|
|
||||||
this.setup = function () {
|
var width = 512;
|
||||||
var tex = gl.createTexture();
|
var height = 512;
|
||||||
gl.bindTexture(gl.TEXTURE_2D, tex);
|
var bpp = 4;
|
||||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this._width, this._height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
|
var expectedDataLength = width*height*bpp;
|
||||||
|
|
||||||
// this can be quite undeterministic so to improve odds of seeing uninitialized data write bits
|
var tex = gl.createTexture();
|
||||||
// into tex then delete texture then re-create one with same characteristics (driver will likely reuse mem)
|
gl.bindTexture(gl.TEXTURE_2D, tex);
|
||||||
// with this trick on r59046 WebKit/OSX I get FAIL 100% of the time instead of ~15% of the time.
|
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
|
||||||
var badData = new Uint8Array(this._expectedDataLength);
|
|
||||||
for (var i = 0; i < badData.length; ++i) badData[i] = i % 255;
|
|
||||||
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, this._width, this._height, gl.RGBA, gl.UNSIGNED_BYTE, badData);
|
|
||||||
gl.finish(); // make sure it has been uploaded
|
|
||||||
gl.deleteTexture(tex);
|
|
||||||
gl.finish(); // make sure it has been deleted
|
|
||||||
|
|
||||||
var tex = gl.createTexture();
|
// this can be quite undeterministic so to improve odds of seeing uninitialized data write bits
|
||||||
gl.bindTexture(gl.TEXTURE_2D, tex);
|
// into tex then delete texture then re-create one with same characteristics (driver will likely reuse mem)
|
||||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this._width, this._height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
|
// with this trick on r59046 WebKit/OSX I get FAIL 100% of the time instead of ~15% of the time.
|
||||||
|
|
||||||
var fb = gl.createFramebuffer();
|
var badData = new Uint8Array(expectedDataLength);
|
||||||
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
|
for (var i = 0; i < badData.length; ++i)
|
||||||
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
|
badData[i] = i % 255;
|
||||||
|
|
||||||
this.data = new Uint8Array(this._width * this._height * 4);
|
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, badData);
|
||||||
gl.readPixels(0, 0, this._width, this._height, gl.RGBA, gl.UNSIGNED_BYTE, this.data);
|
gl.finish(); // make sure it has been uploaded
|
||||||
};
|
|
||||||
|
|
||||||
this.expects = function () {
|
gl.deleteTexture(tex);
|
||||||
if (this.data.length !== this._expectedDataLength) {
|
gl.finish(); // make sure it has been deleted
|
||||||
debug("expected data length " + this._expectedDataLength + " but got " + this.data.length + " instead.");
|
|
||||||
return false;
|
var tex = gl.createTexture();
|
||||||
}
|
gl.bindTexture(gl.TEXTURE_2D, tex);
|
||||||
for (var i = 0; i < this.data.length; ++i)
|
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
|
||||||
if (0 !== this.data[i]) {
|
|
||||||
debug("byte at offset " + i + " has value " + this.data[i]);
|
var fb = gl.createFramebuffer();
|
||||||
return false;
|
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
|
||||||
}
|
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
|
||||||
return true;
|
|
||||||
};
|
data = new Uint8Array(width * height * 4);
|
||||||
|
gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, data);
|
||||||
|
|
||||||
|
if (data.length != expectedDataLength) {
|
||||||
|
testFailed("expected data length " + expectedDataLength + " but got " + data.length + " instead.");
|
||||||
|
} else {
|
||||||
|
var k = 0;
|
||||||
|
for (var i = 0; i < data.length; ++i) {
|
||||||
|
if (data[i] != 0) {
|
||||||
|
k++;
|
||||||
}
|
}
|
||||||
//TODO: uninitialized vertex array buffer
|
}
|
||||||
//TODO: uninitialized vertex elements buffer
|
|
||||||
//TODO: uninitialized framebuffer? (implementations would need to do a GL clear at first binding?)
|
if (k) {
|
||||||
//TODO: uninitialized renderbuffer? (implementations would need to do a GL clear at first binding?)
|
testFailed("Found " + k + " non-zero bytes");
|
||||||
//TODO: uninitialized uniform arrays?
|
} else {
|
||||||
|
testPassed("All data initialized");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
runTestsuite(uninitializedTests);
|
glErrorShouldBe(gl, gl.NO_ERROR);
|
||||||
|
|
||||||
|
//TODO: uninitialized vertex array buffer
|
||||||
|
//TODO: uninitialized vertex elements buffer
|
||||||
|
//TODO: uninitialized framebuffer? (implementations would need to do a GL clear at first binding?)
|
||||||
|
//TODO: uninitialized renderbuffer? (implementations would need to do a GL clear at first binding?)
|
||||||
|
//TODO: uninitialized uniform arrays?
|
||||||
|
|
||||||
|
|
||||||
debug("");
|
debug("");
|
||||||
successfullyParsed = true;
|
successfullyParsed = true;
|
||||||
--></script>
|
</script>
|
||||||
<script src="../resources/js-test-post.js"></script>
|
<script src="../resources/js-test-post.js"></script>
|
||||||
<script>
|
<script>
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -0,0 +1,120 @@
|
||||||
|
<!--
|
||||||
|
Copyright (c) 2010 The Chromium Authors. All rights reserved.
|
||||||
|
Use of this source code is governed by a BSD-style license that can be
|
||||||
|
found in the LICENSE file.
|
||||||
|
-->
|
||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
||||||
|
"http://www.w3.org/TR/html4/loose.dtd">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>WebGL GLES2 difference test.</title>
|
||||||
|
<link rel="stylesheet" href="../resources/js-test-style.css"/>
|
||||||
|
<script src="../resources/js-test-pre.js"></script>
|
||||||
|
<script src="resources/webgl-test.js"></script>
|
||||||
|
<script src="resources/webgl-test-utils.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="description"></div>
|
||||||
|
<div id="console"></div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var wtu = WebGLTestUtils;
|
||||||
|
description("Tests the a few differences between WebGL and GLES2");
|
||||||
|
|
||||||
|
var gl = wtu.create3DContext();
|
||||||
|
|
||||||
|
gl.blendFunc(gl.CONSTANT_COLOR, gl.CONSTANT_ALPHA);
|
||||||
|
glErrorShouldBe(gl, gl.INVALID_OPERATION,
|
||||||
|
"constant color and constant alpha cannot be used together as source and destination factors in the blend function");
|
||||||
|
gl.blendFunc(gl.ONE_MINUS_CONSTANT_COLOR, gl.CONSTANT_ALPHA);
|
||||||
|
glErrorShouldBe(gl, gl.INVALID_OPERATION,
|
||||||
|
"constant color and constant alpha cannot be used together as source and destination factors in the blend function");
|
||||||
|
gl.blendFunc(gl.CONSTANT_COLOR, gl.ONE_MINUS_CONSTANT_ALPHA);
|
||||||
|
glErrorShouldBe(gl, gl.INVALID_OPERATION,
|
||||||
|
"constant color and constant alpha cannot be used together as source and destination factors in the blend function");
|
||||||
|
gl.blendFunc(gl.ONE_MINUS_CONSTANT_COLOR, gl.ONE_MINUS_CONSTANT_ALPHA);
|
||||||
|
glErrorShouldBe(gl, gl.INVALID_OPERATION,
|
||||||
|
"constant color and constant alpha cannot be used together as source and destination factors in the blend function");
|
||||||
|
gl.blendFunc(gl.CONSTANT_ALPHA, gl.CONSTANT_COLOR);
|
||||||
|
glErrorShouldBe(gl, gl.INVALID_OPERATION,
|
||||||
|
"constant color and constant alpha cannot be used together as source and destination factors in the blend function");
|
||||||
|
gl.blendFunc(gl.CONSTANT_ALPHA, gl.ONE_MINUS_CONSTANT_COLOR);
|
||||||
|
glErrorShouldBe(gl, gl.INVALID_OPERATION,
|
||||||
|
"constant color and constant alpha cannot be used together as source and destination factors in the blend function");
|
||||||
|
gl.blendFunc(gl.ONE_MINUS_CONSTANT_ALPHA, gl.CONSTANT_COLOR);
|
||||||
|
glErrorShouldBe(gl, gl.INVALID_OPERATION,
|
||||||
|
"constant color and constant alpha cannot be used together as source and destination factors in the blend function");
|
||||||
|
gl.blendFunc(gl.ONE_MINUS_CONSTANT_ALPHA, gl.ONE_MINUS_CONSTANT_COLOR);
|
||||||
|
glErrorShouldBe(gl, gl.INVALID_OPERATION,
|
||||||
|
"constant color and constant alpha cannot be used together as source and destination factors in the blend function");
|
||||||
|
|
||||||
|
gl.blendFuncSeparate(gl.CONSTANT_COLOR, gl.CONSTANT_ALPHA, gl.ONE, gl.ZERO);
|
||||||
|
glErrorShouldBe(gl, gl.INVALID_OPERATION,
|
||||||
|
"constant color and constant alpha cannot be used together as source and destination factors in the blend function");
|
||||||
|
gl.blendFuncSeparate(gl.ONE_MINUS_CONSTANT_COLOR, gl.CONSTANT_ALPHA, gl.ONE, gl.ZERO);
|
||||||
|
glErrorShouldBe(gl, gl.INVALID_OPERATION,
|
||||||
|
"constant color and constant alpha cannot be used together as source and destination factors in the blend function");
|
||||||
|
gl.blendFuncSeparate(gl.CONSTANT_COLOR, gl.ONE_MINUS_CONSTANT_ALPHA, gl.ONE, gl.ZERO);
|
||||||
|
glErrorShouldBe(gl, gl.INVALID_OPERATION,
|
||||||
|
"constant color and constant alpha cannot be used together as source and destination factors in the blend function");
|
||||||
|
gl.blendFuncSeparate(gl.ONE_MINUS_CONSTANT_COLOR, gl.ONE_MINUS_CONSTANT_ALPHA, gl.ONE, gl.ZERO);
|
||||||
|
glErrorShouldBe(gl, gl.INVALID_OPERATION,
|
||||||
|
"constant color and constant alpha cannot be used together as source and destination factors in the blend function");
|
||||||
|
gl.blendFuncSeparate(gl.CONSTANT_ALPHA, gl.CONSTANT_COLOR, gl.ONE, gl.ZERO);
|
||||||
|
glErrorShouldBe(gl, gl.INVALID_OPERATION,
|
||||||
|
"constant color and constant alpha cannot be used together as source and destination factors in the blend function");
|
||||||
|
gl.blendFuncSeparate(gl.CONSTANT_ALPHA, gl.ONE_MINUS_CONSTANT_COLOR, gl.ONE, gl.ZERO);
|
||||||
|
glErrorShouldBe(gl, gl.INVALID_OPERATION,
|
||||||
|
"constant color and constant alpha cannot be used together as source and destination factors in the blend function");
|
||||||
|
gl.blendFuncSeparate(gl.ONE_MINUS_CONSTANT_ALPHA, gl.CONSTANT_COLOR, gl.ONE, gl.ZERO);
|
||||||
|
glErrorShouldBe(gl, gl.INVALID_OPERATION,
|
||||||
|
"constant color and constant alpha cannot be used together as source and destination factors in the blend function");
|
||||||
|
gl.blendFuncSeparate(gl.ONE_MINUS_CONSTANT_ALPHA, gl.ONE_MINUS_CONSTANT_COLOR, gl.ONE, gl.ZERO);
|
||||||
|
glErrorShouldBe(gl, gl.INVALID_OPERATION,
|
||||||
|
"constant color and constant alpha cannot be used together as source and destination factors in the blend function");
|
||||||
|
|
||||||
|
gl.depthRange(20, 10);
|
||||||
|
glErrorShouldBe(gl, gl.INVALID_OPERATION,
|
||||||
|
"depthRange should generate INVALID_OPERATION if zNear is greater than zFar");
|
||||||
|
|
||||||
|
gl.stencilMask(255);
|
||||||
|
glErrorShouldBe(gl, gl.NO_ERROR,
|
||||||
|
"stencilMask should generate no error");
|
||||||
|
gl.stencilMaskSeparate(gl.FRONT, 1);
|
||||||
|
glErrorShouldBe(gl, gl.INVALID_OPERATION,
|
||||||
|
"a different mask value for front and back facing is illegal");
|
||||||
|
gl.stencilMaskSeparate(gl.BACK, 1);
|
||||||
|
glErrorShouldBe(gl, gl.INVALID_OPERATION,
|
||||||
|
"a different mask value for front and back facing is illegal");
|
||||||
|
|
||||||
|
gl.stencilFunc(gl.ALWAYS, 0, 255);
|
||||||
|
glErrorShouldBe(gl, gl.NO_ERROR,
|
||||||
|
"stencilFunc should generate no error");
|
||||||
|
gl.stencilFuncSeparate(gl.FRONT, gl.ALWAYS, 1, 255);
|
||||||
|
glErrorShouldBe(gl, gl.INVALID_OPERATION,
|
||||||
|
"a different reference value for front and back facing is illegal");
|
||||||
|
gl.stencilFuncSeparate(gl.BACK, gl.ALWAYS, 1, 255);
|
||||||
|
glErrorShouldBe(gl, gl.INVALID_OPERATION,
|
||||||
|
"a different reference value for front and back facing is illegal");
|
||||||
|
gl.stencilFuncSeparate(gl.FRONT, gl.ALWAYS, 0, 1);
|
||||||
|
glErrorShouldBe(gl, gl.INVALID_OPERATION,
|
||||||
|
"a different mask value for front and back facing is illegal");
|
||||||
|
gl.stencilFuncSeparate(gl.BACK, gl.ALWAYS, 0, 1);
|
||||||
|
glErrorShouldBe(gl, gl.INVALID_OPERATION,
|
||||||
|
"a different mask value for front and back facing is illegal");
|
||||||
|
|
||||||
|
shouldBeUndefined(gl.IMPLEMENTATION_COLOR_READ_FORMAT);
|
||||||
|
shouldBeUndefined(gl.IMPLEMENTATION_COLOR_READ_TYPE);
|
||||||
|
|
||||||
|
shouldBe("gl.getParameter(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL)", "gl.BROWSER_DEFAULT_WEBGL");
|
||||||
|
gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, gl.NONE);
|
||||||
|
shouldBe("gl.getParameter(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL)", "gl.NONE");
|
||||||
|
glErrorShouldBe(gl, gl.NO_ERROR,
|
||||||
|
"set/get UNPACK_COLORSPACE_CONVERSION_WEBGL should generate no error");
|
||||||
|
|
||||||
|
successfullyParsed = true;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script src="../resources/js-test-post.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -93,6 +93,7 @@ static const char* const sEventNames[] = {
|
||||||
#endif // MOZ_MEDIA
|
#endif // MOZ_MEDIA
|
||||||
"MozAfterPaint",
|
"MozAfterPaint",
|
||||||
"MozBeforePaint",
|
"MozBeforePaint",
|
||||||
|
"MozBeforeResize",
|
||||||
"MozSwipeGesture",
|
"MozSwipeGesture",
|
||||||
"MozMagnifyGestureStart",
|
"MozMagnifyGestureStart",
|
||||||
"MozMagnifyGestureUpdate",
|
"MozMagnifyGestureUpdate",
|
||||||
|
@ -1316,6 +1317,8 @@ const char* nsDOMEvent::GetEventName(PRUint32 aEventType)
|
||||||
return sEventNames[eDOMEvents_afterpaint];
|
return sEventNames[eDOMEvents_afterpaint];
|
||||||
case NS_BEFOREPAINT:
|
case NS_BEFOREPAINT:
|
||||||
return sEventNames[eDOMEvents_beforepaint];
|
return sEventNames[eDOMEvents_beforepaint];
|
||||||
|
case NS_BEFORERESIZE_EVENT:
|
||||||
|
return sEventNames[eDOMEvents_beforeresize];
|
||||||
case NS_SIMPLE_GESTURE_SWIPE:
|
case NS_SIMPLE_GESTURE_SWIPE:
|
||||||
return sEventNames[eDOMEvents_MozSwipeGesture];
|
return sEventNames[eDOMEvents_MozSwipeGesture];
|
||||||
case NS_SIMPLE_GESTURE_MAGNIFY_START:
|
case NS_SIMPLE_GESTURE_MAGNIFY_START:
|
||||||
|
|
|
@ -175,6 +175,7 @@ public:
|
||||||
#endif
|
#endif
|
||||||
eDOMEvents_afterpaint,
|
eDOMEvents_afterpaint,
|
||||||
eDOMEvents_beforepaint,
|
eDOMEvents_beforepaint,
|
||||||
|
eDOMEvents_beforeresize,
|
||||||
eDOMEvents_MozSwipeGesture,
|
eDOMEvents_MozSwipeGesture,
|
||||||
eDOMEvents_MozMagnifyGestureStart,
|
eDOMEvents_MozMagnifyGestureStart,
|
||||||
eDOMEvents_MozMagnifyGestureUpdate,
|
eDOMEvents_MozMagnifyGestureUpdate,
|
||||||
|
|
|
@ -110,6 +110,8 @@ _CHROME_FILES = \
|
||||||
test_bug415498.xul \
|
test_bug415498.xul \
|
||||||
bug415498-doc1.html \
|
bug415498-doc1.html \
|
||||||
bug415498-doc2.html \
|
bug415498-doc2.html \
|
||||||
|
bug602962.xul \
|
||||||
|
test_bug602962.xul \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
libs:: $(_TEST_FILES)
|
libs:: $(_TEST_FILES)
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||||
|
|
||||||
|
<window onload="window.opener.doTest()" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||||
|
<scrollbox id="page-scrollbox" style="border: 1px solid red; background-color: black;overflow: auto" flex="1">
|
||||||
|
<box id="page-box" style="border: 1px solid green;"/>
|
||||||
|
</scrollbox>
|
||||||
|
</window>
|
|
@ -0,0 +1,94 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||||
|
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||||
|
<!--
|
||||||
|
https://bugzilla.mozilla.org/show_bug.cgi?id=602962
|
||||||
|
-->
|
||||||
|
<window title="Mozilla Bug 602962" onload="openWindow()"
|
||||||
|
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||||
|
|
||||||
|
<title>Test for Bug 602962</title>
|
||||||
|
<script type="application/javascript" src="chrome://mochikit/content/MochiKit/packed.js"/>
|
||||||
|
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||||
|
|
||||||
|
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=602962">Mozilla Bug 602962</a>
|
||||||
|
<p id="display"></p>
|
||||||
|
<div id="content" style="display: none">
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
<script class="testbody" type="application/javascript;version=1.8"><![CDATA[
|
||||||
|
/** Test for Bug 602962 **/
|
||||||
|
var scrollbox, sbo, content;
|
||||||
|
var scrollX = 0, scrollY = 0;
|
||||||
|
|
||||||
|
var mozBeforeResizeHasFired = false;
|
||||||
|
var oldWidth = 0, oldHeight = 0;
|
||||||
|
var win = null;
|
||||||
|
|
||||||
|
function openWindow() {
|
||||||
|
win = window.open("chrome://mochitests/content/chrome/content/events/test/bug602962.xul", "_blank", "width=600,height=600");
|
||||||
|
}
|
||||||
|
|
||||||
|
function doTest() {
|
||||||
|
scrollbox = win.document.getElementById("page-scrollbox");
|
||||||
|
sbo = scrollbox.boxObject.QueryInterface(Components.interfaces.nsIScrollBoxObject);
|
||||||
|
content = win.document.getElementById("page-box");
|
||||||
|
content.style.width = 400 + "px";
|
||||||
|
|
||||||
|
win.addEventListener("resize", function() {
|
||||||
|
win.removeEventListener("resize", arguments.callee, false);
|
||||||
|
|
||||||
|
sbo.scrollBy(200, 0);
|
||||||
|
setTimeout(function() { resize(); }, 0);
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
oldWidth = win.outerWidth;
|
||||||
|
oldHeight = win.outerHeight;
|
||||||
|
win.resizeTo(200, 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
function resize() {
|
||||||
|
win.addEventListener("MozBeforeResize", function() {
|
||||||
|
win.removeEventListener("MozBeforeResize", arguments.callee, false);
|
||||||
|
mozBeforeResizeHasFired = true;
|
||||||
|
|
||||||
|
let x = {}, y = {};
|
||||||
|
sbo.getPosition(x, y);
|
||||||
|
scrollX = x.value, scrollY = y.value;
|
||||||
|
is(scrollX, 200, "Scroll X should not have changed yet");
|
||||||
|
is(scrollY, 0, "Scroll Y should not have changed yet");
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
win.addEventListener("resize", function() {
|
||||||
|
content.style.width = (oldWidth + 400) + "px";
|
||||||
|
win.removeEventListener("resize", arguments.callee, true);
|
||||||
|
|
||||||
|
setTimeout(function() {
|
||||||
|
finish();
|
||||||
|
}, 0);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
win.resizeTo(oldWidth, oldHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
function finish() {
|
||||||
|
is(mozBeforeResizeHasFired, true, "The MozBeforeResize event should already have fired");
|
||||||
|
sbo.scrollBy(scrollX, scrollY);
|
||||||
|
|
||||||
|
let x = {}, y = {};
|
||||||
|
sbo.getPosition(x, y);
|
||||||
|
is(x.value, 200, "Scroll X should have been restored to the value before the resize");
|
||||||
|
is(y.value, 0, "Scroll Y should have been restored to the value before the resize");
|
||||||
|
|
||||||
|
is(win.outerWidth, oldWidth, "Width should be resized");
|
||||||
|
is(win.outerHeight, oldHeight, "Height should be resized");
|
||||||
|
win.close();
|
||||||
|
SimpleTest.finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
]]></script>
|
||||||
|
|
||||||
|
</window>
|
|
@ -169,7 +169,7 @@ public:
|
||||||
protected:
|
protected:
|
||||||
nsIntSize GetWidthHeight();
|
nsIntSize GetWidthHeight();
|
||||||
|
|
||||||
nsresult UpdateContext();
|
nsresult UpdateContext(nsIPropertyBag *aNewContextOptions = nsnull);
|
||||||
nsresult ExtractData(const nsAString& aType,
|
nsresult ExtractData(const nsAString& aType,
|
||||||
const nsAString& aOptions,
|
const nsAString& aOptions,
|
||||||
char*& aData,
|
char*& aData,
|
||||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче