merge mozilla-central to tracemonkey

This commit is contained in:
Robert Sayre 2010-11-19 15:54:33 -08:00
Родитель 86c0a8c1ac b4e4b26fa9
Коммит cc61a33126
717 изменённых файлов: 12832 добавлений и 5343 удалений

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

@ -37,10 +37,12 @@
#include "AccIterator.h"
#include "nsAccessibilityService.h"
#include "nsAccessible.h"
////////////////////////////////////////////////////////////////////////////////
// nsAccIterator
// AccIterator
////////////////////////////////////////////////////////////////////////////////
AccIterator::AccIterator(nsAccessible *aAccessible,
filters::FilterFuncPtr aFilterFunc,
@ -93,3 +95,45 @@ AccIterator::IteratorState::IteratorState(nsAccessible *aParent,
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 "nscore.h"
#include "nsDocAccessible.h"
/**
* Allows to iterate through accessible children or subtree complying with
@ -93,4 +94,41 @@ private:
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

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

@ -844,15 +844,11 @@ static PRBool HasRelatedContent(nsIContent *aContent)
return PR_FALSE;
}
nsIAtom *relationAttrs[] = {nsAccessibilityAtoms::aria_labelledby,
nsAccessibilityAtoms::aria_describedby,
nsAccessibilityAtoms::aria_owns,
nsAccessibilityAtoms::aria_controls,
nsAccessibilityAtoms::aria_flowto};
if (nsCoreUtils::FindNeighbourPointingToNode(aContent, relationAttrs,
NS_ARRAY_LENGTH(relationAttrs))) {
// If the given ID is referred by relation attribute then create an accessible
// for it. Take care of HTML elements only for now.
if (aContent->IsHTML() &&
nsAccUtils::GetDocAccessibleFor(aContent)->IsDependentID(id))
return PR_TRUE;
}
nsIContent *ancestorContent = aContent;
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
// defined on.
nsresult rv;
nsresult rv = NS_OK_NO_RELATION_TARGET;
switch (aRelationType)
{
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) {
nsIAtom *IDAttr = mContent->IsHTML() ?
nsAccessibilityAtoms::_for : nsAccessibilityAtoms::control;
rv = nsRelUtils::
AddTargetFromIDRefAttr(aRelationType, aRelation, mContent, IDAttr);
NS_ENSURE_SUCCESS(rv, rv);
if (rv != NS_OK_NO_RELATION_TARGET)
return NS_OK; // XXX bug 381599, avoid performance problems
}
return nsRelUtils::
AddTargetFromNeighbour(aRelationType, aRelation, mContent,
nsAccessibilityAtoms::aria_labelledby);
return rv;
}
case nsIAccessibleRelation::RELATION_LABELLED_BY:
@ -2091,13 +2094,14 @@ nsAccessible::GetRelationByType(PRUint32 aRelationType,
case nsIAccessibleRelation::RELATION_DESCRIPTION_FOR:
{
rv = nsRelUtils::
AddTargetFromNeighbour(aRelationType, aRelation, mContent,
nsAccessibilityAtoms::aria_describedby);
NS_ENSURE_SUCCESS(rv, rv);
RelatedAccIterator iter(GetDocAccessible(), mContent,
nsAccessibilityAtoms::aria_describedby);
if (rv != NS_OK_NO_RELATION_TARGET)
return NS_OK; // XXX bug 381599, avoid performance problems
nsAccessible* related = nsnull;
while ((related = iter.Next())) {
rv = nsRelUtils::AddTarget(aRelationType, aRelation, related);
NS_ENSURE_SUCCESS(rv, rv);
}
if (mContent->Tag() == nsAccessibilityAtoms::description &&
mContent->IsXUL()) {
@ -2109,18 +2113,23 @@ nsAccessible::GetRelationByType(PRUint32 aRelationType,
nsAccessibilityAtoms::control);
}
return NS_OK;
return rv;
}
case nsIAccessibleRelation::RELATION_NODE_CHILD_OF:
{
rv = nsRelUtils::
AddTargetFromNeighbour(aRelationType, aRelation, mContent,
nsAccessibilityAtoms::aria_owns);
NS_ENSURE_SUCCESS(rv, rv);
RelatedAccIterator iter(GetDocAccessible(), mContent,
nsAccessibilityAtoms::aria_owns);
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)
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
// get the parent the hard way.
@ -2153,14 +2162,20 @@ nsAccessible::GetRelationByType(PRUint32 aRelationType,
}
}
return NS_OK;
return rv;
}
case nsIAccessibleRelation::RELATION_CONTROLLED_BY:
{
return nsRelUtils::
AddTargetFromNeighbour(aRelationType, aRelation, mContent,
nsAccessibilityAtoms::aria_controls);
RelatedAccIterator iter(GetDocAccessible(), mContent,
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:
@ -2188,9 +2203,15 @@ nsAccessible::GetRelationByType(PRUint32 aRelationType,
case nsIAccessibleRelation::RELATION_FLOWS_FROM:
{
return nsRelUtils::
AddTargetFromNeighbour(aRelationType, aRelation, mContent,
nsAccessibilityAtoms::aria_flowto);
RelatedAccIterator iter(GetDocAccessible(), mContent,
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:
@ -3169,8 +3190,17 @@ nsAccessible::EnsureChildren()
// State is embedded children until text leaf accessible is appended.
mChildrenFlags = eEmbeddedChildren; // Prevent reentry
// Notify the document about caching status.
nsDocAccessible* document = GetDocAccessible();
if (document)
document->NotifyOfCachingStart(this);
CacheChildren();
if (document)
document->NotifyOfCachingEnd(this);
return PR_FALSE;
}

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

@ -51,7 +51,6 @@
#include "nsStringGlue.h"
#include "nsTArray.h"
#include "nsRefPtrHashtable.h"
#include "nsDataHashtable.h"
class AccGroupInfo;
class EmbeddedObjCollector;
@ -67,8 +66,6 @@ class nsIView;
typedef nsRefPtrHashtable<nsVoidPtrHashKey, nsAccessible>
nsAccessibleHashtable;
typedef nsDataHashtable<nsPtrHashKey<const nsINode>, nsAccessible*>
NodeToAccessibleMap;
// see nsAccessible::GetAttrValue
#define NS_OK_NO_ARIA_VALUE \

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

@ -47,7 +47,6 @@
#include "nsIDOM3Node.h"
#include "nsIDOMDocument.h"
#include "nsIDOMDocumentView.h"
#include "nsIDOMDocumentXBL.h"
#include "nsIDOMHTMLDocument.h"
#include "nsIDOMHTMLElement.h"
#include "nsIDOMNodeList.h"
@ -805,67 +804,6 @@ nsCoreUtils::GetLanguageFor(nsIContent *aContent, nsIContent *aRootContent,
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
nsCoreUtils::GetElementsHavingIDRefsAttr(nsIContent *aRootContent,
nsIContent *aContent,
@ -1165,3 +1103,78 @@ nsAccessibleDOMStringList::Contains(const nsAString& aString, PRBool *aResult)
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 "nsIDOMDocumentXBL.h"
#include "nsIDOMNode.h"
#include "nsIContent.h"
#include "nsIBoxObject.h"
@ -304,17 +305,6 @@ public:
static void GetLanguageFor(nsIContent *aContent, nsIContent *aRootContent,
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.
*
@ -515,5 +505,39 @@ private:
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

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

@ -85,6 +85,16 @@ namespace dom = mozilla::dom;
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
@ -93,8 +103,10 @@ nsDocAccessible::
nsDocAccessible(nsIDocument *aDocument, nsIContent *aRootContent,
nsIWeakReference *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?
mAccessibleCache.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_NSCOMPTR(mEventQueue)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSTARRAY(mChildDocuments)
tmp->mDependentIDsHash.Clear();
tmp->mNodeToAccessibleMap.Clear();
ClearCache(tmp->mAccessibleCache);
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
// return nsDocAccessible to inherit from nsAccessibleWrap.
nsCOMPtr<nsIDOMXULDocument> xulDoc(do_QueryInterface(mDocument));
if (xulDoc)
if (mDocument && mDocument->IsXUL())
status = nsAccessible::QueryInterface(aIID, (void**)&foundInterface);
else
status = nsHyperTextAccessible::QueryInterface(aIID,
@ -664,6 +676,7 @@ nsDocAccessible::Shutdown()
mWeakShell = nsnull; // Avoid reentrancy
mDependentIDsHash.Clear();
mNodeToAccessibleMap.Clear();
ClearCache(mAccessibleCache);
@ -929,10 +942,19 @@ nsDocAccessible::AttributeWillChange(nsIDocument *aDocument,
PRInt32 aNameSpaceID,
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,
// such as the existence of aria-pressed for button (so we know if we need to
// 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
@ -943,6 +965,16 @@ nsDocAccessible::AttributeChanged(nsIDocument *aDocument,
{
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 (aElement == gLastFocusedNode) {
nsAccessible *focusedAccessible = GetAccService()->GetAccessible(aElement);
@ -1362,6 +1394,7 @@ nsDocAccessible::BindToDocument(nsAccessible* aAccessible,
}
aAccessible->SetRoleMapEntry(aRoleMapEntry);
AddDependentIDsFor(aAccessible);
return true;
}
@ -1373,6 +1406,8 @@ nsDocAccessible::UnbindFromDocument(nsAccessible* aAccessible)
mNodeToAccessibleMap.Get(aAccessible->GetNode()) == aAccessible)
mNodeToAccessibleMap.Remove(aAccessible->GetNode());
RemoveDependentIDsFor(aAccessible);
#ifdef DEBUG
NS_ASSERTION(mAccessibleCache.GetWeak(aAccessible->UniqueID()),
"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
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
nsDocAccessible::FireValueChangeForTextFields(nsAccessible *aAccessible)
{

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

@ -44,6 +44,8 @@
#include "nsHyperTextAccessibleWrap.h"
#include "nsEventShell.h"
#include "nsClassHashtable.h"
#include "nsDataHashtable.h"
#include "nsIDocument.h"
#include "nsIDocumentObserver.h"
#include "nsIEditor.h"
@ -210,6 +212,16 @@ public:
*/
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.
*
@ -241,6 +253,17 @@ public:
*/
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:
virtual void GetBoundsRect(nsRect& aRect, nsIFrame** aRelativeFrame);
@ -267,6 +290,28 @@ protected:
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);
/**
@ -299,14 +344,6 @@ protected:
CharacterDataChangeInfo* aInfo,
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
* field (has a ROLE_ENTRY).
@ -347,7 +384,8 @@ protected:
* Cache of accessibles within this document accessible.
*/
nsAccessibleHashtable mAccessibleCache;
NodeToAccessibleMap mNodeToAccessibleMap;
nsDataHashtable<nsPtrHashKey<const nsINode>, nsAccessible*>
mNodeToAccessibleMap;
nsCOMPtr<nsIDocument> mDocument;
nsCOMPtr<nsITimer> mScrollWatchTimer;
@ -366,9 +404,46 @@ protected:
static nsIAtom *gLastFocusedFrameType;
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_DOCACCESSIBLE_IMPL_CID)
#endif
#endif

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

@ -134,27 +134,16 @@ nsRelUtils::AddTargetFromIDRefsAttr(PRUint32 aRelationType,
nsIAccessibleRelation **aRelation,
nsIContent *aContent, nsIAtom *aAttr)
{
nsCOMPtr<nsIArray> refElms;
nsCoreUtils::GetElementsByIDRefsAttr(aContent, aAttr, getter_AddRefs(refElms));
nsresult rv = NS_OK_NO_RELATION_TARGET;
if (!refElms)
return NS_OK_NO_RELATION_TARGET;
PRUint32 count = 0;
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);
nsIContent* refElm = nsnull;
IDRefsIterator iter(aContent, aAttr);
while ((refElm = iter.NextElem())) {
rv = AddTargetFromContent(aRelationType, aRelation, refElm);
NS_ENSURE_SUCCESS(rv, rv);
}
return NS_OK;
return rv;
}
nsresult

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

@ -92,26 +92,14 @@ nsTextEquivUtils::GetTextEquivFromIDRefs(nsAccessible *aAccessible,
if (!content)
return NS_OK;
nsCOMPtr<nsIArray> refElms;
nsCoreUtils::GetElementsByIDRefsAttr(content, aIDRefsAttr,
getter_AddRefs(refElms));
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);
nsIContent* refContent = nsnull;
IDRefsIterator iter(content, aIDRefsAttr);
while ((refContent = iter.NextElem())) {
if (!aTextEquiv.IsEmpty())
aTextEquiv += ' ';
rv = AppendTextEquivFromContent(aAccessible, refContent, &aTextEquiv);
nsresult rv = AppendTextEquivFromContent(aAccessible, refContent,
&aTextEquiv);
NS_ENSURE_SUCCESS(rv, rv);
}

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

@ -308,34 +308,27 @@ nsHTMLTableCellAccessible::GetHeaderCells(PRInt32 aRowOrColumnHeaderCell,
nsIArray **aHeaderCells)
{
// Get header cells from @header attribute.
nsCOMPtr<nsIArray> headerCellElms;
nsCoreUtils::GetElementsByIDRefsAttr(mContent, nsAccessibilityAtoms::headers,
getter_AddRefs(headerCellElms));
if (headerCellElms) {
IDRefsIterator iter(mContent, nsAccessibilityAtoms::headers);
nsIContent* headerCellElm = iter.NextElem();
if (headerCellElm) {
nsresult rv = NS_OK;
nsCOMPtr<nsIMutableArray> headerCells =
do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
PRUint32 count = 0;
rv = headerCellElms->GetLength(&count);
if (NS_SUCCEEDED(rv) && count > 0) {
nsCOMPtr<nsIContent> headerCellContent;
for (PRUint32 idx = 0; idx < count; idx++) {
headerCellContent = do_QueryElementAt(headerCellElms, idx, &rv);
nsAccessible *headerCell =
GetAccService()->GetAccessibleInWeakShell(headerCellContent, mWeakShell);
do {
nsAccessible* headerCell =
GetAccService()->GetAccessibleInWeakShell(headerCellElm, mWeakShell);
if (headerCell &&
(aRowOrColumnHeaderCell == nsAccUtils::eRowHeaderCells &&
headerCell->Role() == nsIAccessibleRole::ROLE_ROWHEADER ||
aRowOrColumnHeaderCell == nsAccUtils::eColumnHeaderCells &&
headerCell->Role() == nsIAccessibleRole::ROLE_COLUMNHEADER))
headerCells->AppendElement(static_cast<nsIAccessible*>(headerCell),
PR_FALSE);
if (headerCell &&
(aRowOrColumnHeaderCell == nsAccUtils::eRowHeaderCells &&
headerCell->Role() == nsIAccessibleRole::ROLE_ROWHEADER ||
aRowOrColumnHeaderCell == nsAccUtils::eColumnHeaderCells &&
headerCell->Role() == nsIAccessibleRole::ROLE_COLUMNHEADER)) {
headerCells->AppendElement(static_cast<nsIAccessible*>(headerCell),
PR_FALSE);
}
}
} while ((headerCellElm = iter.NextElem()));
NS_ADDREF(*aHeaderCells = headerCells);
return NS_OK;

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

@ -50,6 +50,7 @@ _TEST_FILES =\
test_general.xul \
test_tabbrowser.xul \
test_tree.xul \
test_update.html \
$(NULL)
libs:: $(_TEST_FILES)

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

@ -65,6 +65,9 @@
testRelation(iframeDocAcc, RELATION_NODE_CHILD_OF, iframeAcc);
// 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("tab", RELATION_CONTROLLER_FOR, "tabpanel");

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

@ -66,6 +66,9 @@
testRelation(iframeDocAcc, RELATION_NODE_CHILD_OF, iframeAcc);
// 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("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 */
.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-over-link-layer:not([overlinkstate]) {
.urlbar-over-link-layer[overlinkstate="fade-out"] {
-moz-transition-property: color;
-moz-transition-duration: 150ms;
-moz-transition-timing-function: linear;
color: transparent;
}
.urlbar-over-link-box[overlinkstate="fade-in"],
.urlbar-textbox-container-children:not([overlinkstate]) {
.urlbar-over-link-layer[overlinkstate="fade-in"],
.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-duration: 150ms;
opacity: 1;
}
.urlbar-textbox-container-children[overlinkstate="fade-in"],
.urlbar-over-link-box:not([overlinkstate]) {
.urlbar-over-link-box[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: 0;
}
.urlbar-textbox-container-children[overlinkstate="fade-in"] {
-moz-transition-property: opacity;
-moz-transition-duration: 150ms;
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"] {
color: transparent;
}
@ -207,6 +218,14 @@ html|*.urlbar-input {
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
the URL - this needs to follow the locale's direction, unlike URLs. */
richlistitem[type~="action"]:-moz-locale-dir(rtl) > .ac-url-box {

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

@ -3994,14 +3994,16 @@ var XULBrowserWindow = {
this.defaultStatus = status;
},
setOverLink: function (link) {
// Encode bidirectional formatting characters.
// (RFC 3987 sections 3.2 and 4.1 paragraph 6)
link = link.replace(/[\u200e\u200f\u202a\u202b\u202c\u202d\u202e]/g,
setOverLink: function (url, anchorElt) {
if (gURLBar) {
// Encode bidirectional formatting characters.
// (RFC 3987 sections 3.2 and 4.1 paragraph 6)
url = url.replace(/[\u200e\u200f\u202a\u202b\u202c\u202d\u202e]/g,
encodeURIComponent);
gURLBar.setOverLink(link);
gURLBar.setOverLink(url);
}
},
// Called before links are navigated to to allow us to retarget them if needed.
onBeforeLinkTraversal: function(originalTarget, linkURI, linkNode, isAppTab) {
// Don't modify non-default targets or targets that aren't in top-level app
@ -4198,7 +4200,9 @@ var XULBrowserWindow = {
else
this.isImage.setAttribute('disabled', 'true');
this.hideOverLinkImmediately = true;
this.setOverLink("", null);
this.hideOverLinkImmediately = false;
// We should probably not do this if the value has changed since the user
// searched

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

@ -444,10 +444,12 @@
</button>
</hbox>
<spacer id="titlebar-spacer" flex="1"/>
<hbox id="titlebar-buttonbox" align="start">
<toolbarbutton class="titlebar-button" id="titlebar-min" oncommand="window.minimize();"/>
<toolbarbutton class="titlebar-button" id="titlebar-max" oncommand="onTitlebarMaxClick();"/>
<toolbarbutton class="titlebar-button" id="titlebar-close" command="cmd_closeWindow"/>
<hbox id="titlebar-buttonbox-container" align="start">
<hbox id="titlebar-buttonbox">
<toolbarbutton class="titlebar-button" id="titlebar-min" oncommand="window.minimize();"/>
<toolbarbutton class="titlebar-button" id="titlebar-max" oncommand="onTitlebarMaxClick();"/>
<toolbarbutton class="titlebar-button" id="titlebar-close" command="cmd_closeWindow"/>
</hbox>
</hbox>
</hbox>
</vbox>

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

@ -43,9 +43,17 @@
// The Drag that's currently in process.
var drag = {
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)

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

@ -564,17 +564,25 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
this._sendToSubscribers("close");
this.removeTrenches();
iQ(this.container).animate({
opacity: 0,
"-moz-transform": "scale(.3)",
}, {
duration: 170,
complete: function() {
iQ(this).remove();
Items.unsquish();
}
});
if (this.hidden) {
iQ(this.container).remove();
if (this.$undoContainer) {
this.$undoContainer.remove();
this.$undoContainer = null;
}
Items.unsquish();
} else {
iQ(this.container).animate({
opacity: 0,
"-moz-transform": "scale(.3)",
}, {
duration: 170,
complete: function() {
iQ(this).remove();
Items.unsquish();
}
});
}
this.deleteData();
},
@ -607,10 +615,107 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
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
// Makes the affordance for undo a close group action
_createUndoButton: function() {
_createUndoButton: function GroupItem__createUndoButton() {
let self = this;
this.$undoContainer = iQ("<div/>")
.addClass("undo")
@ -629,6 +734,7 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
});
this.hidden = true;
// hide group item and show undo container.
setTimeout(function() {
self.$undoContainer.animate({
"-moz-transform": "scale(1)",
@ -642,36 +748,17 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
});
}, 50);
// add click handlers
this.$undoContainer.click(function(e) {
// Only do this for clicks on this actual element.
if (e.target.nodeName != self.$undoContainer[0].nodeName)
return;
self.$undoContainer.fadeOut(function() {
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 });
});
self.$undoContainer.fadeOut(function() { self._unhide(); });
});
undoClose.click(function() {
self._cancelFadeAwayUndoButtonTimer();
self.$undoContainer.fadeOut(function() { self._removeHiddenGroupItem(); });
self.$undoContainer.fadeOut(function() { self.closeHidden(); });
});
this.setupFadeAwayUndoButtonTimer();
@ -704,60 +791,6 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
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
// Adds an item to the groupItem.
@ -1047,6 +1080,10 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
// Parameters:
// options - passed to <Items.arrange> or <_stackArrange>
arrange: function GroupItem_arrange(options) {
if (GroupItems._arrangePaused) {
GroupItems.pushArrange(this, options);
return;
}
if (this.expanded) {
this.topChild = null;
var box = new Rect(this.expanded.bounds);
@ -1490,6 +1527,9 @@ let GroupItems = {
_activeGroupItem: null,
_activeOrphanTab: null,
_cleanupFunctions: [],
_arrangePaused: false,
_arrangesPending: [],
_removingHiddenGroups: false,
// ----------
// Function: init
@ -1521,6 +1561,51 @@ let GroupItems = {
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
// watch for icon changes on app tabs
@ -2107,19 +2192,16 @@ let GroupItems = {
// Function: removeHiddenGroups
// Removes all hidden groups' data and its browser tabs.
removeHiddenGroups: function GroupItems_removeHiddenGroups() {
iQ(".undo").remove();
// ToDo: encapsulate this in the group item. bug 594863
this.groupItems.forEach(function(groupItem) {
if (groupItem.hidden) {
let toClose = groupItem._children.concat();
toClose.forEach(function(child) {
child.removeSubscriber(groupItem, "close");
child.close();
});
if (this._removingHiddenGroups)
return;
this._removingHiddenGroups = true;
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 = [
'keyup',
'keydown',
'keypress',
'mouseup',
'mousedown',
'mouseover',

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

@ -216,7 +216,6 @@ Item.prototype = {
// ___ resize
var self = this;
var resizeInfo = null;
this.resizeOptions = {
aspectRatio: self.keepProportional,
minWidth: 90,
@ -224,16 +223,16 @@ Item.prototype = {
start: function(e,ui) {
if (this.isAGroupItem)
GroupItems.setActiveGroupItem(this);
resizeInfo = new Drag(this, e, true); // true = isResizing
resize.info = new Drag(this, e, true); // true = isResizing
},
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() {
self.setUserSize();
self.pushAway();
resizeInfo.stop();
resizeInfo = null;
resize.info.stop();
resize.info = null;
}
};
},
@ -599,6 +598,9 @@ Item.prototype = {
// ___ mousemove
var handleMouseMove = function(e) {
// global drag tracking
drag.lastMoveTime = Date.now();
// positioning
var mouse = new Point(e.pageX, e.pageY);
if (!startSent) {
@ -766,6 +768,9 @@ Item.prototype = {
// ___ mousemove
var handleMouseMove = function(e) {
// global resize tracking
resize.lastMoveTime = Date.now();
var mouse = new Point(e.pageX, e.pageY);
var box = self.getBounds();
if (UI.rtl) {

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

@ -132,7 +132,7 @@ var TabUtils = {
// Function: favURLOf
// Given a <TabItem> or a <xul:tab> returns the URL of tab's favicon.
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.
beforeSearchKeyHandler: function (event) {
// Only match reasonable text-like characters for quick search.
var key = String.fromCharCode(event.which);
// 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;
// If we are already in an input field, allow typing as normal.
@ -353,16 +353,17 @@ SearchEventHandlerClass.prototype = {
// Handles all keypresses while search mode.
inSearchKeyHandler: function (event) {
var term = iQ("#searchbox").val();
if (event.which == event.DOM_VK_ESCAPE)
hideSearch(event);
if (event.which == event.DOM_VK_BACK_SPACE && term.length <= 1)
if ((event.keyCode == event.DOM_VK_ESCAPE) ||
(event.keyCode == event.DOM_VK_BACK_SPACE && term.length <= 1)) {
hideSearch(event);
return;
}
var matcher = new TabMatcher(term);
var matches = matcher.matched();
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);
if (matches.length > 0)
matches[0].zoomIn();
@ -378,9 +379,9 @@ SearchEventHandlerClass.prototype = {
switchToBeforeMode: function switchToBeforeMode() {
var self = this;
if (this.currentHandler)
iQ(document).unbind("keydown", this.currentHandler);
iQ(window).unbind("keypress", this.currentHandler);
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() {
var self = this;
if (this.currentHandler)
iQ(document).unbind("keydown", this.currentHandler);
iQ(window).unbind("keypress", this.currentHandler);
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();
}
let newEvent = document.createEvent("Events");
newEvent.initEvent("tabviewsearchdisabled", false, false);
dispatchEvent(newEvent);
// Return focus to the tab window
UI.blurAll();
gTabViewFrame.contentWindow.focus();
let newEvent = document.createEvent("Events");
newEvent.initEvent("tabviewsearchdisabled", false, false);
dispatchEvent(newEvent);
}
function performSearch() {
@ -513,13 +514,13 @@ function ensureSearchShown(event){
var $search = iQ("#search");
var $searchbox = iQ("#searchbox");
iQ("#searchbutton").css({ opacity: 1 });
if ($search.css("display") == "none") {
if (!isSearchEnabled()) {
$search.show();
var mainWindow = gWindow.document.getElementById("main-window");
mainWindow.setAttribute("activetitlebarcolor", "#717171");
// Marshal the focusing, otherwise you end up with
// a race condition where only sometimes would the
// first keystroke be registered by the search box.
@ -529,18 +530,20 @@ function ensureSearchShown(event){
$searchbox[0].focus();
$searchbox[0].val = '0';
$searchbox.css({"z-index":"1015"});
if (event != null){
var keyCode = event.which + (event.shiftKey ? 0 : 32);
$searchbox.val(String.fromCharCode(keyCode));
}
}, 0);
if (event != null)
$searchbox.val(String.fromCharCode(event.charCode));
let newEvent = document.createEvent("Events");
newEvent.initEvent("tabviewsearchenabled", false, false);
dispatchEvent(newEvent);
let newEvent = document.createEvent("Events");
newEvent.initEvent("tabviewsearchenabled", false, false);
dispatchEvent(newEvent);
}, 0);
}
}
function isSearchEnabled() {
return iQ("#search").css("display") != "none";
}
var SearchEventHandler = new SearchEventHandlerClass();
// Features to add:

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

@ -70,8 +70,10 @@ function TabItem(tab, options) {
this.canvasSizeForced = 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.thumbEl = (iQ('.thumb', $div))[0];
this.canvasEl = (iQ('.thumb canvas', $div))[0];
this.cachedThumbEl = (iQ('img.cached-thumb', $div))[0];
@ -96,6 +98,8 @@ function TabItem(tab, options) {
this.bounds = $div.bounds();
this._lastTabUpdateTime = Date.now();
// ___ superclass setup
this._init($div[0]);
@ -194,6 +198,7 @@ function TabItem(tab, options) {
iQ("<div>")
.addClass('close')
.appendTo($div);
this.closeEl = (iQ(".close", $div))[0];
iQ("<div>")
.addClass('expander')
@ -322,10 +327,10 @@ TabItem.prototype = Utils.extend(new Item(), new Subscribable(), {
this.bounds.copy(rect);
else {
var $container = iQ(this.container);
var $title = iQ('.tab-title', $container);
var $thumb = iQ('.thumb', $container);
var $close = iQ('.close', $container);
var $fav = iQ('.favicon', $container);
var $title = iQ(this.nameEl);
var $thumb = iQ(this.thumbEl);
var $close = iQ(this.closeEl);
var $fav = iQ(this.favEl);
var css = {};
const fontSizeRange = new Range(8,15);
@ -461,12 +466,20 @@ TabItem.prototype = Utils.extend(new Item(), new Subscribable(), {
// Function: close
// Closes this item (actually closes the tab associated with it, which automatically
// closes the item.
// Returns true if this tab is removed.
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);
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
// associated with the tab will automatically go away
return !tabNotClosed;
},
// ----------
@ -544,9 +557,14 @@ TabItem.prototype = Utils.extend(new Item(), new Subscribable(), {
function onZoomDone() {
UI.goToTab(tab);
if (isNewBlankTab)
gWindow.gURLBar.focus();
// tab might not be selected because hideTabView() is invoked after
// 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)
childHitResult.callback();
}
@ -581,8 +599,9 @@ TabItem.prototype = Utils.extend(new Item(), new Subscribable(), {
onZoomDone();
}
});
} else
} else {
setTimeout(onZoomDone, 0);
}
}
},
@ -684,10 +703,11 @@ let TabItems = {
items: [],
paintingPaused: 0,
_tabsWaitingForUpdate: [],
_heartbeatOn: false,
_heartbeatTiming: 100, // milliseconds between beats
_heartbeatOn: false, // see explanation at startHeartbeat() below
_heartbeatTiming: 100, // milliseconds between _checkHeartbeat() calls
_lastUpdateTime: Date.now(),
_eventListeners: [],
tempCanvas: null,
// ----------
// Function: init
@ -696,6 +716,15 @@ let TabItems = {
Utils.assert(window.AllTabs, "AllTabs must be initialized first");
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
this._eventListeners["open"] = function(tab) {
if (tab.ownerDocument.defaultView != gWindow || tab.pinned)
@ -774,6 +803,7 @@ let TabItems = {
if (shouldDefer && !isCurrentTab) {
if (this._tabsWaitingForUpdate.indexOf(tab) == -1)
this._tabsWaitingForUpdate.push(tab);
this.startHeartbeat();
} else
this._update(tab);
} catch(e) {
@ -802,8 +832,8 @@ let TabItems = {
if (iconUrl == null)
iconUrl = Utils.defaultFaviconURL;
if (iconUrl != tabItem.favEl.src)
tabItem.favEl.src = iconUrl;
if (iconUrl != tabItem.favImgEl.src)
tabItem.favImgEl.src = iconUrl;
// ___ URL
let tabUrl = tab.linkedBrowser.currentURI.spec;
@ -834,6 +864,9 @@ let TabItems = {
}
}
this._lastUpdateTime = Date.now();
tabItem._lastTabUpdateTime = this._lastUpdateTime;
tabItem.tabCanvas.paint();
// ___ cache
@ -843,8 +876,6 @@ let TabItems = {
} catch(e) {
Utils.log(e);
}
this._lastUpdateTime = Date.now();
},
// ----------
@ -901,55 +932,64 @@ let TabItems = {
},
// ----------
// Function: heartbeat
// Allows us to spreadout update calls over a period of time.
heartbeat: function TabItems_heartbeat() {
if (!this._heartbeatOn)
// Function: startHeartbeat
// Start a new heartbeat if there isn't one already started.
// The heartbeat is a chain of setTimeout calls that allows us to spread
// 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;
if (this._tabsWaitingForUpdate.length) {
if (this._tabsWaitingForUpdate.length && UI.isIdle()) {
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) {
setTimeout(function() {
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();
this.startHeartbeat();
}
},
// ----------
// 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
// Returns a boolean indicating whether painting
@ -1106,8 +1146,6 @@ TabCanvas.prototype = {
// ----------
// Function: paint
paint: function TabCanvas_paint(evt) {
var ctx = this.canvas.getContext("2d");
var w = this.canvas.width;
var h = this.canvas.height;
if (!w || !h)
@ -1119,19 +1157,59 @@ TabCanvas.prototype = {
return;
}
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);
let tempCanvas = TabItems.tempCanvas;
if (w < tempCanvas.width) {
// Small draw case where nearest-neighbor algorithm breaks down in Windows
// First draw to a larger canvas (150px wide), and then draw that image
// to the destination canvas.
var tempCtx = tempCanvas.getContext("2d");
let canvW = tempCanvas.width;
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
_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
// Keeps track of info related to private browsing, including:
// transitionStage - what step we're on in entering/exiting PB
@ -171,6 +177,7 @@ let UI = {
// ___ Storage
GroupItems.pauseArrange();
GroupItems.init();
let firstTime = true;
@ -221,9 +228,11 @@ let UI = {
// initialized.
let event = document.createEvent("Events");
event.initEvent("tabviewframeinitialized", true, false);
dispatchEvent(event);
dispatchEvent(event);
} catch(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
// Returns the currently active tab as a <TabItem>
@ -450,6 +471,8 @@ let UI = {
if (!this._isTabViewVisible())
return;
// another tab might be select if user decides to stay on a page when
// a onclose confirmation prompts.
GroupItems.removeHiddenGroups();
TabItems.pausePainting();
@ -678,6 +701,7 @@ let UI = {
},
// ----------
// Function: goToTab
// Selects the given xul:tab in the browser.
goToTab: function UI_goToTab(xulTab) {
// If it's not focused, the onFocus listener would handle it.
@ -710,6 +734,11 @@ let UI = {
if (this._isTabViewVisible())
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 newItem = null;
@ -814,11 +843,16 @@ let UI = {
var self = this;
iQ(window).keyup(function(event) {
if (!event.metaKey) Keys.meta = false;
if (!event.metaKey)
Keys.meta = false;
});
iQ(window).keydown(function(event) {
if (event.metaKey) Keys.meta = true;
if (event.metaKey)
Keys.meta = true;
if (isSearchEnabled())
return;
function getClosestTabBy(norm) {
if (!self.getActiveTab())
@ -875,7 +909,7 @@ let UI = {
event.keyCode == KeyEvent.DOM_VK_ENTER) {
let activeTab = self.getActiveTab();
if (activeTab)
activeTab.zoomIn();
activeTab.zoomIn();
event.stopPropagation();
event.preventDefault();
@ -989,11 +1023,12 @@ let UI = {
}
function collapse() {
let center = phantom.bounds().center();
phantom.animate({
width: 0,
height: 0,
top: phantom.position().x + phantom.height()/2,
left: phantom.position().y + phantom.width()/2
top: center.y,
left: center.x
}, {
duration: 300,
complete: function() {

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

@ -3,37 +3,41 @@
* 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() {
waitForExplicitFinish();
let tab = gBrowser.selectedTab = gBrowser.addTab();
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 = {
let windowObserver = {
observe: function(aSubject, aTopic, aData) {
if (aTopic == "domwindowopened") {
ok(false, "Alert window opened");
@ -42,19 +46,67 @@ function test() {
win.removeEventListener("load", arguments.callee, false);
win.close();
}, false);
gBrowser.removeProgressListener(listener);
executeSoon(function () {
gBrowser.removeTab(tab);
finish();
});
executeSoon(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
gURLBar.value = searchText;
gURLBar.value = gCurrTest.testText;
gURLBar.focus();
EventUtils.synthesizeKey("VK_RETURN", {});
}

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

@ -48,6 +48,7 @@ _BROWSER_FILES = \
browser_tabview_apptabs.js \
browser_tabview_bug580412.js \
browser_tabview_bug587043.js \
browser_tabview_bug587231.js \
browser_tabview_bug587990.js \
browser_tabview_bug589324.js \
browser_tabview_bug590606.js \
@ -59,7 +60,9 @@ _BROWSER_FILES = \
browser_tabview_bug595804.js \
browser_tabview_bug595930.js \
browser_tabview_bug595943.js \
browser_tabview_bug597399.js \
browser_tabview_bug598600.js \
browser_tabview_bug599626.js \
browser_tabview_dragdrop.js \
browser_tabview_exit_button.js \
browser_tabview_group.js \
@ -76,6 +79,7 @@ _BROWSER_FILES = \
head.js \
search1.html \
search2.html \
test_bug599626.html \
$(NULL)
# 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");
let onSearchEnabled = function() {
let search = contentWindow.document.getElementById("search");
ok(search.style.display != "none", "Search is enabled");
contentWindow.removeEventListener(
"tabviewsearchenabled", onSearchEnabled, false);
let search = contentWindow.document.getElementById("search");
ok(search.style.display != "none", "Search is enabled");
escapeTest(contentWindow);
}
contentWindow.addEventListener("tabviewsearchenabled", onSearchEnabled,
@ -70,21 +70,16 @@ function onTabViewWindowLoaded() {
function escapeTest(contentWindow) {
let onSearchDisabled = function() {
let search = contentWindow.document.getElementById("search");
ok(search.style.display == "none", "Search is disabled");
contentWindow.removeEventListener(
"tabviewsearchdisabled", onSearchDisabled, false);
let search = contentWindow.document.getElementById("search");
ok(search.style.display == "none", "Search is disabled");
toggleTabViewTest(contentWindow);
}
contentWindow.addEventListener("tabviewsearchdisabled", onSearchDisabled,
false);
// the search box focus()es in a function on the timeout queue, so we just
// want to queue behind it.
setTimeout( function() {
EventUtils.synthesizeKey("VK_ESCAPE", {});
}, 0);
EventUtils.synthesizeKey("VK_ESCAPE", { type: "keypress" }, contentWindow);
}
function toggleTabViewTest(contentWindow) {
@ -92,14 +87,9 @@ function toggleTabViewTest(contentWindow) {
contentWindow.removeEventListener("tabviewhidden", onTabViewHidden, false);
ok(!TabView.isVisible(), "Tab View is hidden");
finish();
}
contentWindow.addEventListener("tabviewhidden", onTabViewHidden, false);
// When search is hidden, it focus()es on the background, so avert the
// race condition by delaying ourselves on the timeout queue
setTimeout( function() {
// Use keyboard shortcut to toggle back to browser view
EventUtils.synthesizeKey("e", { accelKey: true });
}, 0);
// Use keyboard shortcut to toggle back to browser view
EventUtils.synthesizeKey("e", { accelKey: true });
}

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

@ -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">
<parameter name="aValue"/>
<body><![CDATA[
this._hideOverLink();
this._value = aValue;
var returnValue = aValue;
var action = this._parseActionUrl(aValue);
@ -642,19 +643,21 @@
<method name="setOverLink">
<parameter name="aURL"/>
<body><![CDATA[
// If the over-link is already scheduled to appear or hide, cancel it.
if (this._overLinkDelayTimer) {
clearTimeout(this._overLinkDelayTimer);
this._overLinkDelayTimer = null;
this._cancelOverLinkDelayTimer();
// Hide the over-link immediately if necessary.
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 || this.focused) {
// If aURL is falsey, fade it out after a delay. This happens on
// mouseout for example.
if (!aURL) {
this._overLinkDelayTimer = setTimeout(function overLinkOut(self) {
self._overLinkDelayTimer = null;
let style = window.getComputedStyle(self._overLinkBox, null);
self._overLinkTransitioning = style.opacity != 0;
self.removeAttribute("overlinkstate");
self._setOverLinkState("fade-out");
}, this._overLinkOutDelay, this);
return;
}
@ -662,8 +665,7 @@
// If it's in transition, update and show it immediately.
if (this._overLinkTransitioning) {
this._updateOverLink(aURL);
this._overLinkTransitioning = false;
this.setAttribute("overlinkstate", "showing");
this._setOverLinkState("showing");
return;
}
@ -673,13 +675,54 @@
this._overLinkDelayTimer = setTimeout(function overLinkIn(self) {
self._overLinkDelayTimer = null;
self._updateOverLink(aURL);
let style = window.getComputedStyle(self._overLinkBox, null);
self._overLinkTransitioning = style.opacity != 1;
self.setAttribute("overlinkstate", "fade-in");
self._setOverLinkState("fade-in");
}, this._overLinkInDelay, this);
]]></body>
</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">
<parameter name="aURL"/>
<body><![CDATA[
@ -761,8 +804,8 @@
]]></handler>
<handler event="focus" phase="capturing"><![CDATA[
this._hideOverLink();
this._hideURLTooltip();
this.setOverLink(null);
]]></handler>
<handler event="dragover" phase="capturing" action="this.onDragOver(event, this);"/>

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

@ -45,8 +45,8 @@ function test() {
const HISTORY_SIDEBAR_TREE_ID = "historyTree";
// Initialization.
let ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
getService(Ci.nsIWindowWatcher);
let os = Cc["@mozilla.org/observer-service;1"].
getService(Ci.nsIObserverService);
let bs = PlacesUtils.bookmarks;
let hs = PlacesUtils.history;
let sidebarBox = document.getElementById("sidebar-box");
@ -125,22 +125,20 @@ function test() {
preFunc();
function observer(aSubject, aTopic, aData) {
if (aTopic != "domwindowopened")
return;
ww.unregisterNotification(observer);
let alertDialog = aSubject.QueryInterface(Ci.nsIDOMWindow);
alertDialog.addEventListener("load", function () {
alertDialog.removeEventListener("load", arguments.callee, false);
info("alert dialog observed as expected");
executeSoon(function () {
alertDialog.close();
info("alert dialog observed as expected");
os.removeObserver(observer, "common-dialog-loaded");
os.removeObserver(observer, "tabmodal-dialog-loaded");
aSubject.Dialog.ui.button0.click();
executeSoon(function () {
toggleSidebar(currentTest.sidebarName);
currentTest.cleanup();
postFunc();
});
}, false);
}
ww.registerNotification(observer);
os.addObserver(observer, "common-dialog-loaded", false);
os.addObserver(observer, "tabmodal-dialog-loaded", false);
// Select the inserted places item.
currentTest.selectNode(tree);
@ -160,7 +158,7 @@ function test() {
y = y.value + height.value / 2;
// Simulate the click.
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.
// 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

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

@ -69,10 +69,20 @@ function runNextTest() {
// set an empty state & run the next test, or finish
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' }] }] }));
let test = tests.shift();
info("running " + test.name);
executeSoon(test);
let currentTest = tests.shift();
info("running " + currentTest.name);
executeSoon(currentTest);
}
else {
ss.setBrowserState(stateBackup);

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

@ -105,7 +105,7 @@
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;
}

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

@ -325,7 +325,7 @@
-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;
}
@ -339,7 +339,7 @@
-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;
}
@ -1412,10 +1412,6 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
padding-bottom: 1px;
}
.tabbrowser-tabs:-moz-system-metric(touch-enabled) {
min-height: 7.3mozmm;
}
/* Tabs */
.tabbrowser-tab,
.tabs-newtab-button {
@ -1558,6 +1554,10 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
.tabs-newtab-button {
min-width: 10mozmm;
}
.tab-content {
min-height: -moz-calc(6.8mozmm - 7px); /* subtract borders from the desired height */
}
}
.tabbrowser-arrowscrollbox > .scrollbutton-up,

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

@ -37,6 +37,7 @@
# ***** END LICENSE BLOCK *****
import socket
import SocketServer
import time, datetime
import os
import re
@ -58,14 +59,14 @@ class FileError(Exception):
class DeviceManager:
host = ''
port = 0
debug = 2
debug = 2
_redo = False
deviceRoot = None
tempRoot = os.getcwd()
base_prompt = '\$\>'
prompt_sep = '\x00'
prompt_regex = '.*' + base_prompt + prompt_sep
agentErrorRE = re.compile('^##AGENT-ERROR##.*')
agentErrorRE = re.compile('^##AGENT-WARNING##.*')
def __init__(self, host, port = 20701):
self.host = host
@ -272,7 +273,10 @@ class DeviceManager:
return None
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
def mkDirs(self, filename):
@ -306,7 +310,9 @@ class DeviceManager:
match = ".*" + dirname + "$"
dirre = re.compile(match)
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
retVal = self.stripPrompt(data)
data = retVal.split('\n')
@ -549,11 +555,12 @@ class DeviceManager:
# /reftest
# /mochitest
def getDeviceRoot(self):
if (not self.deviceRoot):
data = self.sendCMD(['testroot'])
if (data == None):
return '/tests'
self.deviceRoot = self.stripPrompt(data).strip('\n') + '/tests'
# This caching of deviceRoot is causing issues if things fail
# if (not self.deviceRoot):
data = self.sendCMD(['testroot'])
if (data == None):
return '/tests'
self.deviceRoot = self.stripPrompt(data).strip('\n') + '/tests'
if (not self.dirExists(self.deviceRoot)):
self.mkDir(self.deviceRoot)
@ -690,8 +697,8 @@ class DeviceManager:
Application bundle - path to the application bundle on the device
Destination - destination directory of where application should be
installed to (optional)
Returns True or False depending on what we get back
TODO: we need a real way to know if this works or not
Returns None for success, or output if known failure
TODO: we need a better way to know if this works or not
"""
def installApp(self, appBundlePath, destPath=None):
cmd = 'inst ' + appBundlePath
@ -699,9 +706,13 @@ class DeviceManager:
cmd += ' ' + destPath
data = self.sendCMD([cmd])
if (data is None):
return False
else:
return True
return None
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.
@ -714,9 +725,53 @@ class DeviceManager:
cmd = 'uninst ' + appName
if installPath:
cmd += ' ' + installPath
self.sendCMD([cmd])
data = self.sendCMD([cmd])
if (self.debug > 3): print "uninstallAppAndReboot: " + str(data)
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
"""
@ -726,3 +781,112 @@ class DeviceManager:
return None
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
from automation import Automation
from devicemanager import DeviceManager
from devicemanager import DeviceManager, NetworkTools
class RemoteAutomation(Automation):
_devicemanager = None
@ -99,31 +99,9 @@ class RemoteAutomation(Automation):
# return app, ['--environ:NO_EM_RESTART=1'] + 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):
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
nettools = NetworkTools()
return nettools.getLanIp()
def Process(self, cmd, stdout = None, stderr = None, env = None, cwd = '.'):
if stdout == None or stdout == -1:
@ -176,4 +154,3 @@ class RemoteAutomation(Automation):
def kill(self):
self.dm.killProcess(self.procName)

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

@ -1,5 +1,6 @@
{
global:
NSModule;
NSGetModule;
local: *;
};

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

@ -1,5 +1,6 @@
EXPORTED {
global:
NSModule;
NSGetModule;
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;
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 //
///////////////////////////
@ -2414,11 +2408,8 @@ nsScriptSecurityManager::doGetObjectPrincipal(JSObject *aObj
do {
// Note: jsClass is set before this loop, and also at the
// *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,
#ifdef DEBUG
aAllowShortCircuit
@ -3423,7 +3414,6 @@ nsresult nsScriptSecurityManager::Init()
JS_SetRuntimeSecurityCallbacks(sRuntime, &securityCallbacks);
NS_ASSERTION(!oldcallbacks, "Someone else set security callbacks!");
sXPConnect->GetXPCWrappedNativeJSClassInfo(&sXPCWrappedNativeEqualityOps);
return NS_OK;
}

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

@ -43,6 +43,6 @@ VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
DIRS = mochitest browser
DIRS = mochitest
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_ARM_ASM = @VPX_ARM_ASM@
NS_PRINTING = @NS_PRINTING@
MOZ_PDF_PRINTING = @MOZ_PDF_PRINTING@
MOZ_CRASHREPORTER = @MOZ_CRASHREPORTER@
MOZ_HELP_VIEWER = @MOZ_HELP_VIEWER@
MOC= @MOC@
@ -195,6 +196,7 @@ RM = rm -f
MOZ_UI_LOCALE = @MOZ_UI_LOCALE@
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_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
ifneq (,$(filter-out WINNT WINCE,$(OS_ARCH)))
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

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

@ -301,8 +301,8 @@ if test "$target" = "arm-android-eabi" ; then
STRIP="$android_toolchain"/bin/arm-eabi-strip
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"
CXXFLAGS="-mandroid -I$android_platform/usr/include -msoft-float -fno-short-enums -fno-exceptions -march=armv5te -mthumb-interwork $CXXFLAGS"
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 $CXXFLAGS"
dnl Add -llog by default, since we use it all over the place.
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'
MOZ_COMPONENT_NSPR_LIBS='$(NSPR_LIBS)'
if test $_MSC_VER -ge 1400; then
LDFLAGS="$LDFLAGS -NXCOMPAT"
LDFLAGS="$LDFLAGS -LARGEADDRESSAWARE -NXCOMPAT"
dnl For profile-guided optimization
PROFILE_GEN_CFLAGS="-GL"
PROFILE_GEN_LDFLAGS="-LTCG:PGINSTRUMENT"
@ -2893,11 +2893,13 @@ esac
AC_SUBST(NO_LD_ARCHIVE_FLAGS)
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 ========================================================
case "$target" in
*-linux*|*-kfreebsd*-gnu|*-gnu*)
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*)
if test -z "$GNU_CC"; then
@ -4992,6 +4994,7 @@ MOZ_XTF=1
MOZ_XUL=1
MOZ_ZIPWRITER=1
NS_PRINTING=1
MOZ_PDF_PRINTING=
MOZ_DISABLE_DOMCRYPTO=
NSS_DISABLE_DBM=
NECKO_WIFI=1
@ -5031,7 +5034,6 @@ case "${target}" in
NSS_DISABLE_DBM=1
USE_ARM_KUSER=1
MOZ_INSTALLER=
NS_PRINTING=
NECKO_WIFI=
MOZ_THUMB2=1
MOZ_THEME_FASTSTRIPE=1
@ -5187,6 +5189,7 @@ cairo-windows)
NS_PRINTING=
;;
esac
MOZ_PDF_PRINTING=1
;;
cairo-gtk2|cairo-gtk2-x11)
@ -5203,6 +5206,7 @@ cairo-gtk2|cairo-gtk2-x11)
TK_CFLAGS='$(MOZ_GTK2_CFLAGS)'
TK_LIBS='$(MOZ_GTK2_LIBS)'
AC_DEFINE(MOZ_WIDGET_GTK2)
MOZ_PDF_PRINTING=1
;;
cairo-gtk2-dfb)
@ -5220,6 +5224,7 @@ cairo-gtk2-dfb)
AC_MSG_WARN([Disabling X when DirectFB is specified.])
no_x=yes
fi
MOZ_PDF_PRINTING=1
;;
cairo-qt)
@ -5237,6 +5242,7 @@ cairo-qt)
TK_CFLAGS='$(MOZ_QT_CFLAGS)'
TK_LIBS='$(MOZ_QT_LIBS)'
AC_DEFINE(MOZ_WIDGET_QT)
MOZ_PDF_PRINTING=1
;;
cairo-beos)
@ -5251,6 +5257,7 @@ cairo-os2)
USE_FC_FREETYPE=1
TK_CFLAGS='$(MOZ_CAIRO_CFLAGS)'
TK_LIBS='$(MOZ_CAIRO_LIBS)'
MOZ_PDF_PRINTING=1
;;
cairo-cocoa)
@ -5271,11 +5278,20 @@ cairo-cocoa)
cairo-android)
AC_DEFINE(MOZ_WIDGET_ANDROID)
MOZ_WIDGET_TOOLKIT=android
TK_CFLAGS='$(MOZ_CAIRO_CFLAGS)'
TK_LIBS='$(MOZ_CAIRO_LIBS)'
MOZ_WEBGL=1
MOZ_PDF_PRINTING=1
;;
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
AC_DEFINE(MOZ_ENABLE_XREMOTE)
fi
@ -7098,6 +7114,16 @@ if test -n "$MOZ_THUMB2"; then
AC_MSG_ERROR([--enable-thumb2 is not supported for non-ARM CPU architectures])
;;
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
AC_SUBST(MOZ_THUMB2)
@ -8499,7 +8525,6 @@ if test "$MOZ_TREE_CAIRO"; then
XLIB_SURFACE_FEATURE="#define CAIRO_HAS_XLIB_SURFACE 1"
XLIB_XRENDER_SURFACE_FEATURE="#define CAIRO_HAS_XLIB_XRENDER_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"
MOZ_ENABLE_CAIRO_FT=1
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)
fi
PDF_SURFACE_FEATURE="#define CAIRO_HAS_PDF_SURFACE 1"
fi
if test "$MOZ_WIDGET_TOOLKIT" = "os2"; then
OS2_SURFACE_FEATURE="#define CAIRO_HAS_OS2_SURFACE 1"
FT_FONT_FEATURE="#define CAIRO_HAS_FT_FONT 1"
PDF_SURFACE_FEATURE="#define CAIRO_HAS_PDF_SURFACE 1"
MOZ_ENABLE_CAIRO_FT=1
CAIRO_FT_CFLAGS="-I${MZFTCFGFT2}/include"
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(INCREMENTAL_LINKER)
AC_SUBST(MOZ_COMPONENTS_VERSION_SCRIPT_LDFLAGS)
AC_SUBST(MOZ_JEMALLOC_STANDALONE_GLUE_LDOPTS)
AC_SUBST(MOZ_COMPONENT_NSPR_LIBS)
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 595606-1.html
load 595606-2.html
load 606729-1.html

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

@ -42,6 +42,8 @@
#include "nsAString.h"
#include "nsMargin.h"
class nsIInterfaceRequestor;
// {3682DD99-8560-44f4-9B8F-CCCE9D7B96FB}
#define NS_ICONTENTUTILS_IID \
{ 0x3682dd99, 0x8560, 0x44f4, \
@ -71,4 +73,20 @@ public:
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__ */

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

@ -70,6 +70,7 @@ public:
mFrozen(PR_FALSE),
mDefer(PR_FALSE),
mAsync(PR_FALSE),
mExternal(PR_FALSE),
mParserCreated(aFromParser == mozilla::dom::FROM_PARSER_FRAGMENT ?
mozilla::dom::NOT_FROM_PARSER : aFromParser),
// Fragment parser-created scripts (if executable)
@ -126,6 +127,15 @@ public:
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.
*/
@ -249,6 +259,12 @@ protected:
*/
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.
*/

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

@ -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::onpagehide, NS_PAGE_HIDE, EventNameType_HTML, NS_EVENT },
{ nsGkAtoms::onMozBeforeResize, NS_BEFORERESIZE_EVENT, EventNameType_None, NS_EVENT },
{ nsGkAtoms::onresize, NS_RESIZE_EVENT,
(EventNameType_HTMLXUL | EventNameType_SVGSVG), NS_EVENT },
{ nsGkAtoms::onscroll, NS_SCROLL_EVENT,
@ -5536,6 +5537,11 @@ nsContentUtils::WrapNative(JSContext *cx, JSObject *scope, nsISupports *native,
return NS_OK;
}
JSObject *wrapper = xpc_GetCachedSlimWrapper(cache, scope, vp);
if (wrapper) {
return NS_OK;
}
NS_ENSURE_TRUE(sXPConnect && sThreadJSContextStack, NS_ERROR_UNEXPECTED);
// Keep sXPConnect and sThreadJSContextStack alive. If we're on the main
@ -6489,3 +6495,11 @@ nsIContentUtils::FindInternalContentViewer(const char* aType,
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(onRequest, "onRequest")
GK_ATOM(onreset, "onreset")
GK_ATOM(onMozBeforeResize, "onMozBeforeResize")
GK_ATOM(onresize, "onresize")
GK_ATOM(onscroll, "onscroll")
GK_ATOM(onselect, "onselect")

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

@ -546,10 +546,13 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
// Step 9. in the HTML5 spec
nsCOMPtr<nsIURI> scriptURI = aElement->GetScriptURI();
nsRefPtr<nsScriptLoadRequest> request;
if (scriptURI) {
if (aElement->GetScriptExternal()) {
// external script
nsCOMPtr<nsIURI> scriptURI = aElement->GetScriptURI();
if (!scriptURI) {
return NS_ERROR_NOT_AVAILABLE;
}
nsTArray<PreloadInfo>::index_type i =
mPreloads.IndexOf(scriptURI.get(), 0, PreloadURIComparator());
if (i != nsTArray<PreloadInfo>::NoIndex) {

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

@ -442,6 +442,7 @@ _TEST_FILES2 = \
file_bug604660-5.xml \
file_bug604660-6.xsl \
test_bug605982.html \
test_bug606729.html \
test_treewalker_nextsibling.xml \
$(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 gfxContext;
class gfxASurface;
class nsIPropertyBag;
namespace mozilla {
namespace layers {
@ -115,6 +116,14 @@ public:
// Redraw the dirty rectangle of this canvas.
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
// 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

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

@ -82,14 +82,14 @@ helper_isFloat32Array(JSObject *obj) {
* BufferData_array (int, js::TypedArray *, int)
*/
static JSBool
nsICanvasRenderingContextWebGL_BufferData(JSContext *cx, uintN argc, jsval *vp)
nsIDOMWebGLRenderingContext_BufferData(JSContext *cx, uintN argc, jsval *vp)
{
XPC_QS_ASSERT_CONTEXT_OK(cx);
JSObject *obj = JS_THIS_OBJECT(cx, vp);
if (!obj)
return JS_FALSE;
nsICanvasRenderingContextWebGL *self;
nsIDOMWebGLRenderingContext *self;
xpc_qsSelfRef selfref;
js::AutoValueRooter tvr(cx);
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 *)
*/
static JSBool
nsICanvasRenderingContextWebGL_BufferSubData(JSContext *cx, uintN argc, jsval *vp)
nsIDOMWebGLRenderingContext_BufferSubData(JSContext *cx, uintN argc, jsval *vp)
{
XPC_QS_ASSERT_CONTEXT_OK(cx);
JSObject *obj = JS_THIS_OBJECT(cx, vp);
if (!obj)
return JS_FALSE;
nsICanvasRenderingContextWebGL *self;
nsIDOMWebGLRenderingContext *self;
xpc_qsSelfRef selfref;
js::AutoValueRooter tvr(cx);
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)
*/
static JSBool
nsICanvasRenderingContextWebGL_ReadPixels(JSContext *cx, uintN argc, jsval *vp)
nsIDOMWebGLRenderingContext_ReadPixels(JSContext *cx, uintN argc, jsval *vp)
{
XPC_QS_ASSERT_CONTEXT_OK(cx);
JSObject *obj = JS_THIS_OBJECT(cx, vp);
@ -224,7 +224,7 @@ nsICanvasRenderingContextWebGL_ReadPixels(JSContext *cx, uintN argc, jsval *vp)
nsresult rv;
nsICanvasRenderingContextWebGL *self;
nsIDOMWebGLRenderingContext *self;
xpc_qsSelfRef selfref;
js::AutoValueRooter tvr(cx);
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)
*/
static JSBool
nsICanvasRenderingContextWebGL_TexImage2D(JSContext *cx, uintN argc, jsval *vp)
nsIDOMWebGLRenderingContext_TexImage2D(JSContext *cx, uintN argc, jsval *vp)
{
XPC_QS_ASSERT_CONTEXT_OK(cx);
JSObject *obj = JS_THIS_OBJECT(cx, vp);
@ -287,7 +287,7 @@ nsICanvasRenderingContextWebGL_TexImage2D(JSContext *cx, uintN argc, jsval *vp)
nsresult rv;
nsICanvasRenderingContextWebGL *self;
nsIDOMWebGLRenderingContext *self;
xpc_qsSelfRef selfref;
js::AutoValueRooter tvr(cx);
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)
*/
static JSBool
nsICanvasRenderingContextWebGL_TexSubImage2D(JSContext *cx, uintN argc, jsval *vp)
nsIDOMWebGLRenderingContext_TexSubImage2D(JSContext *cx, uintN argc, jsval *vp)
{
XPC_QS_ASSERT_CONTEXT_OK(cx);
JSObject *obj = JS_THIS_OBJECT(cx, vp);
@ -405,7 +405,7 @@ nsICanvasRenderingContextWebGL_TexSubImage2D(JSContext *cx, uintN argc, jsval *v
nsresult rv;
nsICanvasRenderingContextWebGL *self;
nsIDOMWebGLRenderingContext *self;
xpc_qsSelfRef selfref;
js::AutoValueRooter tvr(cx);
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 */
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);
JSObject *obj = JS_THIS_OBJECT(cx, vp);
@ -513,7 +513,7 @@ helper_nsICanvasRenderingContextWebGL_Uniform_x_iv(JSContext *cx, uintN argc, js
nsresult rv;
nsICanvasRenderingContextWebGL *self;
nsIDOMWebGLRenderingContext *self;
xpc_qsSelfRef selfref;
js::AutoValueRooter tvr(cx);
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 */
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);
JSObject *obj = JS_THIS_OBJECT(cx, vp);
@ -587,7 +587,7 @@ helper_nsICanvasRenderingContextWebGL_Uniform_x_fv(JSContext *cx, uintN argc, js
nsresult rv;
nsICanvasRenderingContextWebGL *self;
nsIDOMWebGLRenderingContext *self;
xpc_qsSelfRef selfref;
js::AutoValueRooter tvr(cx);
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 */
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);
JSObject *obj = JS_THIS_OBJECT(cx, vp);
@ -661,7 +661,7 @@ helper_nsICanvasRenderingContextWebGL_UniformMatrix_x_fv(JSContext *cx, uintN ar
nsresult rv;
nsICanvasRenderingContextWebGL *self;
nsIDOMWebGLRenderingContext *self;
xpc_qsSelfRef selfref;
js::AutoValueRooter tvr(cx);
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
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);
JSObject *obj = JS_THIS_OBJECT(cx, vp);
@ -736,7 +736,7 @@ helper_nsICanvasRenderingContextWebGL_VertexAttrib_x_fv(JSContext *cx, uintN arg
nsresult rv;
nsICanvasRenderingContextWebGL *self;
nsIDOMWebGLRenderingContext *self;
xpc_qsSelfRef selfref;
js::AutoValueRooter tvr(cx);
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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)
{
XPC_QS_ASSERT_CONTEXT_OK(cx);
nsICanvasRenderingContextWebGL *self;
nsIDOMWebGLRenderingContext *self;
xpc_qsSelfRef selfref;
xpc_qsArgValArray<3> vp(cx);
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) {
xpc_qsThrowMethodFailedWithDetails(cx, NS_ERROR_FAILURE, "nsICanvasRenderingContextWebGL", "uniformNiv");
xpc_qsThrowMethodFailedWithDetails(cx, NS_ERROR_FAILURE, "nsIDOMWebGLRenderingContext", "uniformNiv");
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);
wa = js::TypedArray::fromJSObject(nobj);
} else {
xpc_qsThrowMethodFailedWithDetails(cx, NS_ERROR_FAILURE, "nsICanvasRenderingContextWebGL", "uniformNiv");
xpc_qsThrowMethodFailedWithDetails(cx, NS_ERROR_FAILURE, "nsIDOMWebGLRenderingContext", "uniformNiv");
js_SetTraceableNativeFailed(cx);
return;
}
@ -950,18 +950,18 @@ helper_nsICanvasRenderingContextWebGL_Uniform_x_iv_tn(JSContext *cx, JSObject *o
}
if (NS_FAILED(rv)) {
xpc_qsThrowMethodFailedWithDetails(cx, rv, "nsICanvasRenderingContextWebGL", "uniformNiv");
xpc_qsThrowMethodFailedWithDetails(cx, rv, "nsIDOMWebGLRenderingContext", "uniformNiv");
js_SetTraceableNativeFailed(cx);
}
}
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)
{
XPC_QS_ASSERT_CONTEXT_OK(cx);
nsICanvasRenderingContextWebGL *self;
nsIDOMWebGLRenderingContext *self;
xpc_qsSelfRef selfref;
xpc_qsArgValArray<3> vp(cx);
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) {
xpc_qsThrowMethodFailedWithDetails(cx, NS_ERROR_FAILURE, "nsICanvasRenderingContextWebGL", "uniformNfv");
xpc_qsThrowMethodFailedWithDetails(cx, NS_ERROR_FAILURE, "nsIDOMWebGLRenderingContext", "uniformNfv");
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);
wa = js::TypedArray::fromJSObject(nobj);
} else {
xpc_qsThrowMethodFailedWithDetails(cx, NS_ERROR_FAILURE, "nsICanvasRenderingContextWebGL", "uniformNfv");
xpc_qsThrowMethodFailedWithDetails(cx, NS_ERROR_FAILURE, "nsIDOMWebGLRenderingContext", "uniformNfv");
js_SetTraceableNativeFailed(cx);
return;
}
@ -1018,7 +1018,7 @@ helper_nsICanvasRenderingContextWebGL_Uniform_x_fv_tn(JSContext *cx, JSObject *o
}
if (NS_FAILED(rv)) {
xpc_qsThrowMethodFailedWithDetails(cx, rv, "nsICanvasRenderingContextWebGL", "uniformNfv");
xpc_qsThrowMethodFailedWithDetails(cx, rv, "nsIDOMWebGLRenderingContext", "uniformNfv");
js_SetTraceableNativeFailed(cx);
}
@ -1026,12 +1026,12 @@ helper_nsICanvasRenderingContextWebGL_Uniform_x_fv_tn(JSContext *cx, JSObject *o
}
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)
{
XPC_QS_ASSERT_CONTEXT_OK(cx);
nsICanvasRenderingContextWebGL *self;
nsIDOMWebGLRenderingContext *self;
xpc_qsSelfRef selfref;
xpc_qsArgValArray<4> vp(cx);
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) {
xpc_qsThrowMethodFailedWithDetails(cx, NS_ERROR_FAILURE, "nsICanvasRenderingContextWebGL", "uniformMatrixNfv");
xpc_qsThrowMethodFailedWithDetails(cx, NS_ERROR_FAILURE, "nsIDOMWebGLRenderingContext", "uniformMatrixNfv");
js_SetTraceableNativeFailed(cx);
}
@ -1070,7 +1070,7 @@ helper_nsICanvasRenderingContextWebGL_UniformMatrix_x_fv_tn(JSContext *cx, JSObj
*obj_tvr.jsval_addr() = OBJECT_TO_JSVAL(nobj);
wa = js::TypedArray::fromJSObject(nobj);
} else {
xpc_qsThrowMethodFailedWithDetails(cx, NS_ERROR_FAILURE, "nsICanvasRenderingContextWebGL", "uniformMatrixNfv");
xpc_qsThrowMethodFailedWithDetails(cx, NS_ERROR_FAILURE, "nsIDOMWebGLRenderingContext", "uniformMatrixNfv");
js_SetTraceableNativeFailed(cx);
return;
}
@ -1085,7 +1085,7 @@ helper_nsICanvasRenderingContextWebGL_UniformMatrix_x_fv_tn(JSContext *cx, JSObj
}
if (NS_FAILED(rv)) {
xpc_qsThrowMethodFailedWithDetails(cx, rv, "nsICanvasRenderingContextWebGL", "uniformMatrixNfv");
xpc_qsThrowMethodFailedWithDetails(cx, rv, "nsIDOMWebGLRenderingContext", "uniformMatrixNfv");
js_SetTraceableNativeFailed(cx);
}
}
@ -1093,133 +1093,133 @@ helper_nsICanvasRenderingContextWebGL_UniformMatrix_x_fv_tn(JSContext *cx, JSObj
// FIXME This should return void, not uint32
// (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
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;
}
JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_Uniform1iv,
(4, (static, UINT32_FAIL, nsICanvasRenderingContextWebGL_Uniform1iv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
JS_DEFINE_TRCINFO_1(nsIDOMWebGLRenderingContext_Uniform1iv,
(4, (static, UINT32_FAIL, nsIDOMWebGLRenderingContext_Uniform1iv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
// FIXME This should return void, not uint32
// (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
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;
}
JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_Uniform2iv,
(4, (static, UINT32_FAIL, nsICanvasRenderingContextWebGL_Uniform2iv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
JS_DEFINE_TRCINFO_1(nsIDOMWebGLRenderingContext_Uniform2iv,
(4, (static, UINT32_FAIL, nsIDOMWebGLRenderingContext_Uniform2iv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
// FIXME This should return void, not uint32
// (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
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;
}
JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_Uniform3iv,
(4, (static, UINT32_FAIL, nsICanvasRenderingContextWebGL_Uniform3iv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
JS_DEFINE_TRCINFO_1(nsIDOMWebGLRenderingContext_Uniform3iv,
(4, (static, UINT32_FAIL, nsIDOMWebGLRenderingContext_Uniform3iv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
// FIXME This should return void, not uint32
// (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
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;
}
JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_Uniform4iv,
(4, (static, UINT32_FAIL, nsICanvasRenderingContextWebGL_Uniform4iv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
JS_DEFINE_TRCINFO_1(nsIDOMWebGLRenderingContext_Uniform4iv,
(4, (static, UINT32_FAIL, nsIDOMWebGLRenderingContext_Uniform4iv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
// FIXME This should return void, not uint32
// (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
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;
}
JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_Uniform1fv,
(4, (static, UINT32_FAIL, nsICanvasRenderingContextWebGL_Uniform1fv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
JS_DEFINE_TRCINFO_1(nsIDOMWebGLRenderingContext_Uniform1fv,
(4, (static, UINT32_FAIL, nsIDOMWebGLRenderingContext_Uniform1fv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
// FIXME This should return void, not uint32
// (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
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;
}
JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_Uniform2fv,
(4, (static, UINT32_FAIL, nsICanvasRenderingContextWebGL_Uniform2fv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
JS_DEFINE_TRCINFO_1(nsIDOMWebGLRenderingContext_Uniform2fv,
(4, (static, UINT32_FAIL, nsIDOMWebGLRenderingContext_Uniform2fv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
// FIXME This should return void, not uint32
// (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
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;
}
JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_Uniform3fv,
(4, (static, UINT32_FAIL, nsICanvasRenderingContextWebGL_Uniform3fv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
JS_DEFINE_TRCINFO_1(nsIDOMWebGLRenderingContext_Uniform3fv,
(4, (static, UINT32_FAIL, nsIDOMWebGLRenderingContext_Uniform3fv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
// FIXME This should return void, not uint32
// (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
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;
}
JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_Uniform4fv,
(4, (static, UINT32_FAIL, nsICanvasRenderingContextWebGL_Uniform4fv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
JS_DEFINE_TRCINFO_1(nsIDOMWebGLRenderingContext_Uniform4fv,
(4, (static, UINT32_FAIL, nsIDOMWebGLRenderingContext_Uniform4fv_tn, CONTEXT, THIS, OBJECT, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
// FIXME This should return void, not uint32
// (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
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;
}
JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_UniformMatrix2fv,
(5, (static, UINT32_FAIL, nsICanvasRenderingContextWebGL_UniformMatrix2fv_tn, CONTEXT, THIS, OBJECT, BOOL, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
JS_DEFINE_TRCINFO_1(nsIDOMWebGLRenderingContext_UniformMatrix2fv,
(5, (static, UINT32_FAIL, nsIDOMWebGLRenderingContext_UniformMatrix2fv_tn, CONTEXT, THIS, OBJECT, BOOL, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
// FIXME This should return void, not uint32
// (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
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;
}
JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_UniformMatrix3fv,
(5, (static, UINT32_FAIL, nsICanvasRenderingContextWebGL_UniformMatrix3fv_tn, CONTEXT, THIS, OBJECT, BOOL, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
JS_DEFINE_TRCINFO_1(nsIDOMWebGLRenderingContext_UniformMatrix3fv,
(5, (static, UINT32_FAIL, nsIDOMWebGLRenderingContext_UniformMatrix3fv_tn, CONTEXT, THIS, OBJECT, BOOL, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
// FIXME This should return void, not uint32
// (waiting for https://bugzilla.mozilla.org/show_bug.cgi?id=572798)
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;
}
JS_DEFINE_TRCINFO_1(nsICanvasRenderingContextWebGL_UniformMatrix4fv,
(5, (static, UINT32_FAIL, nsICanvasRenderingContextWebGL_UniformMatrix4fv_tn, CONTEXT, THIS, OBJECT, BOOL, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
JS_DEFINE_TRCINFO_1(nsIDOMWebGLRenderingContext_UniformMatrix4fv,
(5, (static, UINT32_FAIL, nsIDOMWebGLRenderingContext_UniformMatrix4fv_tn, CONTEXT, THIS, OBJECT, BOOL, OBJECT, 0, nanojit::ACCSET_STORE_ANY)))
#endif /* JS_TRACER */

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

@ -48,6 +48,11 @@
#include "nsDOMError.h"
#include "nsIGfxInfo.h"
#include "nsIPropertyBag.h"
#include "nsIVariant.h"
#include "imgIEncoder.h"
#include "gfxContext.h"
#include "gfxPattern.h"
#include "gfxUtils.h"
@ -66,12 +71,12 @@ using namespace mozilla;
using namespace mozilla::gl;
using namespace mozilla::layers;
nsresult NS_NewCanvasRenderingContextWebGL(nsICanvasRenderingContextWebGL** aResult);
nsresult NS_NewCanvasRenderingContextWebGL(nsIDOMWebGLRenderingContext** aResult);
nsresult
NS_NewCanvasRenderingContextWebGL(nsICanvasRenderingContextWebGL** aResult)
NS_NewCanvasRenderingContextWebGL(nsIDOMWebGLRenderingContext** aResult)
{
nsICanvasRenderingContextWebGL* ctx = new WebGLContext();
nsIDOMWebGLRenderingContext* ctx = new WebGLContext();
if (!ctx)
return NS_ERROR_OUT_OF_MEMORY;
@ -88,6 +93,7 @@ WebGLContext::WebGLContext()
mInvalidated = PR_FALSE;
mResetLayer = PR_TRUE;
mVerbose = PR_FALSE;
mOptionsFrozen = PR_FALSE;
mActiveTexture = 0;
mSynthesizedGLError = LOCAL_GL_NO_ERROR;
@ -266,6 +272,67 @@ WebGLContext::SetCanvasElement(nsHTMLCanvasElement* aParentCanvas)
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
WebGLContext::SetDimensions(PRInt32 width, PRInt32 height)
{
@ -300,8 +367,26 @@ WebGLContext::SetDimensions(PRInt32 width, PRInt32 height)
DestroyResourcesAndContext();
gl::ContextFormat format(gl::ContextFormat::BasicRGBA32);
format.depth = 16;
format.minDepth = 1;
if (mOptions.depth) {
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);
NS_ENSURE_TRUE(prefService != nsnull, NS_ERROR_FAILURE);
@ -421,6 +506,7 @@ WebGLContext::SetDimensions(PRInt32 width, PRInt32 height)
mWidth = width;
mHeight = height;
mResetLayer = PR_TRUE;
mOptionsFrozen = PR_TRUE;
// increment the generation number
++mGeneration;
@ -482,17 +568,20 @@ WebGLContext::GetInputStream(const char* aMimeType,
const PRUnichar* aEncoderOptions,
nsIInputStream **aStream)
{
return NS_ERROR_FAILURE;
// XXX fix this
#if 0
if (!mGLPbuffer ||
!mGLPbuffer->ThebesSurface())
NS_ASSERTION(gl, "GetInputStream on invalid context?");
if (!gl)
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;
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)
return NS_ERROR_OUT_OF_MEMORY;
@ -504,45 +593,15 @@ WebGLContext::GetInputStream(const char* aMimeType,
if (!encoder)
return NS_ERROR_FAILURE;
nsAutoArrayPtr<PRUint8> imageBuffer(new (std::nothrow) PRUint8[mWidth * mHeight * 4]);
if (!imageBuffer)
return NS_ERROR_OUT_OF_MEMORY;
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,
rv = encoder->InitFromData(surf->Data(),
mWidth * mHeight * 4,
mWidth, mHeight,
surf->Stride(),
imgIEncoder::INPUT_FORMAT_HOSTARGB,
nsDependentString(aEncoderOptions));
NS_ENSURE_SUCCESS(rv, rv);
return CallQueryInterface(encoder, aStream);
#endif
}
NS_IMETHODIMP
@ -589,7 +648,7 @@ WebGLContext::GetCanvasLayer(CanvasLayer *aOldLayer,
}
data.mSize = nsIntSize(mWidth, mHeight);
data.mGLBufferIsPremultiplied = PR_FALSE;
data.mGLBufferIsPremultiplied = mOptions.premultipliedAlpha ? PR_TRUE : PR_FALSE;
canvasLayer->Initialize(data);
PRUint32 flags = gl->CreationFormat().alpha == 0 ? Layer::CONTENT_OPAQUE : 0;
@ -602,12 +661,46 @@ WebGLContext::GetCanvasLayer(CanvasLayer *aOldLayer,
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
//
NS_IMPL_CYCLE_COLLECTING_ADDREF_AMBIGUOUS(WebGLContext, nsICanvasRenderingContextWebGL)
NS_IMPL_CYCLE_COLLECTING_RELEASE_AMBIGUOUS(WebGLContext, nsICanvasRenderingContextWebGL)
NS_IMPL_CYCLE_COLLECTING_ADDREF_AMBIGUOUS(WebGLContext, nsIDOMWebGLRenderingContext)
NS_IMPL_CYCLE_COLLECTING_RELEASE_AMBIGUOUS(WebGLContext, nsIDOMWebGLRenderingContext)
NS_IMPL_CYCLE_COLLECTION_CLASS(WebGLContext)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(WebGLContext)
@ -620,10 +713,10 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
DOMCI_DATA(CanvasRenderingContextWebGL, 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(nsISupportsWeakReference)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsICanvasRenderingContextWebGL)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMWebGLRenderingContext)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CanvasRenderingContextWebGL)
NS_INTERFACE_MAP_END

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

@ -50,7 +50,7 @@
#include "nsIDocShell.h"
#include "nsICanvasRenderingContextWebGL.h"
#include "nsIDOMWebGLRenderingContext.h"
#include "nsICanvasRenderingContextInternal.h"
#include "nsHTMLCanvasElement.h"
#include "nsWeakReference.h"
@ -67,6 +67,7 @@
#define CONTEXT_LOST_WEBGL 0x9242
class nsIDocShell;
class nsIPropertyBag;
namespace mozilla {
@ -235,8 +236,10 @@ private:
class WebGLBuffer;
struct WebGLVertexAttribData {
// note that these initial values are what GL initializes vertex attribs to
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;
@ -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 :
public nsICanvasRenderingContextWebGL,
public nsIDOMWebGLRenderingContext,
public nsICanvasRenderingContextInternal,
public nsSupportsWeakReference
{
@ -288,9 +324,9 @@ public:
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
NS_IMETHOD SetCanvasElement(nsHTMLCanvasElement* aParentCanvas);
@ -305,6 +341,8 @@ public:
nsIInputStream **aStream);
NS_IMETHOD GetThebesSurface(gfxASurface **surface);
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 Redraw(const gfxRect&) { return NS_ERROR_NOT_IMPLEMENTED; }
NS_IMETHOD Swap(mozilla::ipc::Shmem& aBack,
@ -360,9 +398,12 @@ protected:
PRInt32 mWidth, mHeight;
CheckedUint32 mGeneration;
WebGLContextOptions mOptions;
PRPackedBool mInvalidated;
PRPackedBool mResetLayer;
PRPackedBool mVerbose;
PRPackedBool mOptionsFrozen;
WebGLuint mActiveTexture;
WebGLenum mSynthesizedGLError;
@ -729,13 +770,14 @@ public:
NS_DECL_NSIWEBGLTEXTURE
protected:
friend class WebGLContext;
friend class WebGLFramebuffer;
PRBool mDeleted;
WebGLuint mName;
////////////////////////////////////////////////////////////////////////////////////////////////////
/////// everything below that point is only used for the texture completeness/npot business
/////// (sections 3.7.10 and 3.8.2 in GL ES 2.0.24 spec)
////////////////////////////////////////////////////////////////////////////////////////////////////
// we store information about the various images that are part of
// this texture (cubemap faces, mipmap levels)
struct ImageInfo {
ImageInfo() : mWidth(0), mHeight(0), mFormat(0), mType(0), mIsDefined(PR_FALSE) {}
@ -1211,21 +1253,21 @@ public:
return mAttachedShaders.RemoveElement(shader);
}
PRBool HasBothShaderTypesAttached() {
PRBool haveVertex = PR_FALSE;
PRBool haveFrag = PR_FALSE;
PRBool HasAttachedShaderOfType(GLenum shaderType) {
for (PRUint32 i = 0; i < mAttachedShaders.Length(); ++i) {
if (mAttachedShaders[i]->ShaderType() == LOCAL_GL_FRAGMENT_SHADER)
haveFrag = PR_TRUE;
else if (mAttachedShaders[i]->ShaderType() == LOCAL_GL_VERTEX_SHADER)
haveVertex = PR_TRUE;
if (haveFrag && haveVertex)
if (mAttachedShaders[i]->ShaderType() == shaderType) {
return PR_TRUE;
}
}
return PR_FALSE;
}
PRBool HasBothShaderTypesAttached() {
return
HasAttachedShaderOfType(LOCAL_GL_VERTEX_SHADER) &&
HasAttachedShaderOfType(LOCAL_GL_FRAGMENT_SHADER);
}
PRBool NextGeneration()
{
if (!(mGeneration+1).valid())
@ -1328,6 +1370,7 @@ public:
WebGLFramebuffer(WebGLContext *context, WebGLuint name) :
WebGLContextBoundObject(context),
mName(name), mDeleted(PR_FALSE),
mColorAttachment0HasAlpha(PR_FALSE),
mHasDepthAttachment(PR_FALSE),
mHasStencilAttachment(PR_FALSE),
mHasDepthStencilAttachment(PR_FALSE)
@ -1342,6 +1385,8 @@ public:
PRBool Deleted() { return mDeleted; }
WebGLuint GLName() { return mName; }
PRBool ColorAttachment0HasAlpha() { return mColorAttachment0HasAlpha; }
nsresult FramebufferRenderbuffer(WebGLenum target,
WebGLenum attachment,
WebGLenum rbtarget,
@ -1405,15 +1450,20 @@ public:
{
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;
break;
}
// dimensions are kept for readPixels primarily, function only uses COLOR_ATTACHMENT0
if (attachment == LOCAL_GL_COLOR_ATTACHMENT0)
setDimensions(wrb);
mContext->MakeContextCurrent();
mContext->gl->fFramebufferRenderbuffer(target, attachment, rbtarget, renderbuffername);
@ -1460,14 +1510,26 @@ public:
{
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;
}
// dimensions are kept for readPixels primarily, function only uses COLOR_ATTACHMENT0
if (attachment == LOCAL_GL_COLOR_ATTACHMENT0)
setDimensions(wtex);
mContext->MakeContextCurrent();
mContext->gl->fFramebufferTexture2D(target, attachment, textarget, texturename, level);
@ -1501,6 +1563,14 @@ public:
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 because WebGLContext should only call InitializeRenderbuffers
@ -1605,7 +1675,8 @@ protected:
}
WebGLuint mName;
PRBool mDeleted;
PRPackedBool mDeleted;
PRPackedBool mColorAttachment0HasAlpha;
// we only store pointers to attached renderbuffers, not to attached textures, because
// we will only need to initialize renderbuffers. Textures are already initialized.

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

@ -123,18 +123,17 @@ WebGLProgram::GetUniformLocationObject(GLint glLocation)
return loc.forget();
}
static PRBool
InternalFormatHasAlpha(WebGLenum aInternalFormat) {
return aInternalFormat == LOCAL_GL_RGBA4 ||
aInternalFormat == LOCAL_GL_RGB5_A1;
}
//
// WebGL API
//
/* void present (); */
NS_IMETHODIMP
WebGLContext::Present()
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* void GlActiveTexture (in GLenum texture); */
NS_IMETHODIMP
WebGLContext::ActiveTexture(WebGLenum texture)
@ -163,6 +162,12 @@ WebGLContext::AttachShader(nsIWebGLProgram *pobj, nsIWebGLShader *shobj)
!GetConcreteObjectAndGLName("attachShader: shader", shobj, &shader, &shadername))
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))
return ErrorInvalidOperation("AttachShader: shader is already attached");
@ -540,6 +545,11 @@ WebGLContext::Clear(PRUint32 mask)
if (mBoundFramebuffer && !mBoundFramebuffer->CheckAndInitializeRenderbuffers())
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);
Invalidate();
@ -1433,7 +1443,6 @@ WebGLContext::GetParameter(PRUint32 pname, nsIVariant **retval)
case LOCAL_GL_CULL_FACE_MODE:
case LOCAL_GL_FRONT_FACE:
case LOCAL_GL_ACTIVE_TEXTURE:
case LOCAL_GL_DEPTH_CLEAR_VALUE:
case LOCAL_GL_STENCIL_CLEAR_VALUE:
case LOCAL_GL_STENCIL_FUNC:
case LOCAL_GL_STENCIL_REF:
@ -1521,6 +1530,7 @@ WebGLContext::GetParameter(PRUint32 pname, nsIVariant **retval)
break;
// float
case LOCAL_GL_DEPTH_CLEAR_VALUE:
case LOCAL_GL_LINE_WIDTH:
case LOCAL_GL_POLYGON_OFFSET_FACTOR:
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;
PRUint32 size = 0;
bool badFormat = false, badType = false;
switch (format) {
case LOCAL_GL_ALPHA:
size = 1;
break;
case LOCAL_GL_RGB:
size = 3;
break;
case LOCAL_GL_RGBA:
case LOCAL_GL_RGBA:
size = 4;
break;
default:
return ErrorInvalidEnumInfo("readPixels: format", format);
default:
badFormat = true;
break;
}
switch (type) {
// case LOCAL_GL_UNSIGNED_SHORT_4_4_4_4:
// case LOCAL_GL_UNSIGNED_SHORT_5_5_5_1:
// case LOCAL_GL_UNSIGNED_SHORT_5_6_5:
case LOCAL_GL_UNSIGNED_BYTE:
case LOCAL_GL_UNSIGNED_BYTE:
break;
default:
badType = true;
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;
PRUint32 packAlignment = mPixelStorePackAlignment;
@ -2579,6 +2590,51 @@ WebGLContext::ReadPixels_base(WebGLint x, WebGLint y, WebGLsizei width, WebGLsiz
}
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;
}
@ -3767,7 +3823,7 @@ WebGLContext::TexSubImage2D_base(WebGLenum target, WebGLint level,
PRUint32 bytesNeeded = checked_neededByteLength.value();
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);
@ -3880,129 +3936,6 @@ WebGLContext::TexSubImage2D_dom(WebGLenum target, WebGLint level,
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
BaseTypeAndSizeFromUniformType(WebGLenum uType, WebGLenum *baseType, WebGLint *unitSize)
{

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

@ -36,12 +36,12 @@
*
* ***** END LICENSE BLOCK ***** */
#include "nsICanvasRenderingContextWebGL.h"
#include "nsIDOMWebGLRenderingContext.h"
#include "nsDOMClassInfoID.h"
#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(WebGLBuffer, void)

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

@ -1,6 +1,6 @@
This is a local copy of the WebGL conformance suite.
SVN revision: 11955
SVN revision: 12905
The canonical location for this testsuite is:

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

@ -7,7 +7,6 @@ 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
@ -17,11 +16,13 @@ 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
@ -45,10 +46,13 @@ index-validation-with-resized-buffer.html
index-validation.html
invalid-UTF-16.html
invalid-passed-params.html
is-object.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
@ -72,7 +76,9 @@ texture-formats-test.html
texture-npot.html
texture-transparent-pixels-initialized.html
triangle.html
#uniform-location.html
type-conversion-test.html
uniform-location.html
uniform-samplers-test.html
uninitialized-test.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) {
if (sz == 1)
return;
@ -671,6 +680,7 @@ function runTests() {
testConstructionWithOutOfRangeValues(type, name);
testConstructionWithNegativeOutOfRangeValues(type, name);
testConstructionWithUnalignedOffset(type, name, testCase.elementSizeInBytes);
testConstructionWithUnalignedLength(type, name, testCase.elementSizeInBytes);
testConstructionOfHugeArray(type, name, testCase.elementSizeInBytes);
testConstructionWithBothArrayBufferAndLength(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;
func("context.compileShader(argument)");
func("context.linkProgram(argument)");
func("context.attachShader(argument)");
func("context.attachShader(program, argument)");
func("context.attachShader(argument, shader)");
func("context.detachShader(program, argument)");

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

@ -33,6 +33,10 @@ glErrorShouldBe(gl, gl.INVALID_OPERATION);
gl.bindBuffer(gl.ARRAY_BUFFER, buf);
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);
glErrorShouldBe(gl, gl.NO_ERROR);
@ -41,6 +45,9 @@ array = new ArrayBuffer(64);
gl.bufferSubData(gl.ARRAY_BUFFER, 10, array);
glErrorShouldBe(gl, gl.NO_ERROR);
gl.bufferSubData(gl.ARRAY_BUFFER, 10, null);
glErrorShouldBe(gl, gl.NO_ERROR);
successfullyParsed = true;
</script>

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

@ -375,10 +375,6 @@ VERTEX_ATTRIB_ARRAY_NORMALIZED : 0x886A,
VERTEX_ATTRIB_ARRAY_POINTER : 0x8645,
VERTEX_ATTRIB_ARRAY_BUFFER_BINDING : 0x889F,
/* Read Format */
IMPLEMENTATION_COLOR_READ_TYPE : 0x8B9A,
IMPLEMENTATION_COLOR_READ_FORMAT : 0x8B9B,
/* Shader Source */
COMPILE_STATUS : 0x8B81,
INFO_LOG_LENGTH : 0x8B84,
@ -403,6 +399,7 @@ RGB565 : 0x8D62,
DEPTH_COMPONENT16 : 0x81A5,
STENCIL_INDEX : 0x1901,
STENCIL_INDEX8 : 0x8D48,
DEPTH_STENCIL : 0x84F9,
RENDERBUFFER_WIDTH : 0x8D42,
RENDERBUFFER_HEIGHT : 0x8D43,
@ -422,6 +419,7 @@ FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE : 0x8CD3,
COLOR_ATTACHMENT0 : 0x8CE0,
DEPTH_ATTACHMENT : 0x8D00,
STENCIL_ATTACHMENT : 0x8D20,
DEPTH_STENCIL_ATTACHMENT : 0x821A,
NONE : 0,
@ -435,7 +433,14 @@ FRAMEBUFFER_BINDING : 0x8CA6,
RENDERBUFFER_BINDING : 0x8CA7,
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) {

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

@ -54,66 +54,14 @@ function init()
function getWebGL(canvasName, contextAttribs, clearColor, clearDepth, clearStencil)
{
var canvas = document.getElementById(canvasName);
var gl = canvas.getContext("experimental-webgl", contextAttribs);
if (!gl) {
alert("No WebGL context found");
return null;
var context = initWebGL(canvasName, "vshader", "fshader", ["pos", "colorIn"], clearColor, clearDepth, contextAttribs);
if (context) {
context.clearStencil(clearStencil);
context.enable(context.STENCIL_TEST);
context.disable(context.BLEND);
context.clear(context.COLOR_BUFFER_BIT | context.DEPTH_BUFFER_BIT | context.STENCIL_BUFFER_BIT);
}
var actualContextAttribs = gl.getContextAttributes();
// 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;
return context;
}
function drawAndReadPixel(gl, vertices, colors, x, y)
@ -146,11 +94,6 @@ function testAlpha(alpha)
else
shouldBeNonNull("webGL = getWebGL('alphaOff', { alpha: false, depth: false, stencil: false, antialias: false }, [ 0, 0, 0, 0 ], 1, 0)");
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);
webGL.readPixels(0, 0, 1, 1, webGL.RGBA, webGL.UNSIGNED_BYTE, buf);
@ -158,7 +101,7 @@ function testAlpha(alpha)
pixel[1] = buf[1];
pixel[2] = buf[2];
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");
}
@ -170,11 +113,6 @@ function testDepth(depth)
else
shouldBeNonNull("webGL = getWebGL('depthOff', { depth: false, stencil: false, antialias: false }, [ 0, 0, 0, 1 ], 1, 0)");
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);
@ -198,7 +136,7 @@ function testDepth(depth)
pixel[1] = buf[1];
pixel[2] = buf[2];
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");
}
@ -210,11 +148,6 @@ function testStencil(stencil)
else
shouldBeNonNull("webGL = getWebGL('stencilOff', { depth: false, stencil: false, antialias: false }, [ 0, 0, 0, 1 ], 1, 0)");
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);
@ -241,10 +174,7 @@ function testStencil(stencil)
pixel[1] = buf[1];
pixel[2] = buf[2];
pixel[3] = buf[3];
correctColor = (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;
correctColor = (contextAttribs.stencil ? [0, 0, 0, 255] : [255, 0, 0, 255]);
shouldBe("pixel", "correctColor");
}
@ -256,11 +186,6 @@ function testAntialias(antialias)
else
shouldBeNonNull("webGL = getWebGL('antialiasOff', { depth: false, stencil: false, alpha: false, antialias: false }, [ 0, 0, 0, 1 ], 1, 0)");
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([
1.0, 1.0, 0.0,
@ -272,10 +197,7 @@ function testAntialias(antialias)
255, 0, 0, 255]);
var buf = drawAndReadPixel(webGL, vertices, colors, 0, 0);
pixel[0] = buf[0];
// If antialias is requested but not supported, we fake the effect.
if (antialias && !contextAttribs.antialias)
pixel[0] = 127;
shouldBe("pixel[0] == 255 || pixel[0] == 0", (antialias ? "false" : "true"));
shouldBe("pixel[0] != 255 && pixel[0] != 0", "contextAttribs.antialias");
}
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.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
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.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, 10000000000000)");
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.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)");
@ -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, -1, 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)");

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

@ -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, -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_OPERATION, "context.drawElements(context.TRIANGLES, 0x7fffffff, context.UNSIGNED_BYTE, 0)");
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()");
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer);
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)
{
shouldBeNonNull("fbo = gl.createFramebuffer()");
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment0, gl.RENDERBUFFER, buffer0);
glErrorShouldBe(gl, gl.NO_ERROR);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment1, gl.RENDERBUFFER, buffer1);
glErrorShouldBe(gl, isConflicted ? gl.INVALID_OPERATION : gl.NO_ERROR);
if (isConflicted) {
// Detach buffer0 first using a null object, then attaching buffer1 should succeed.
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);
}
glErrorShouldBe(gl, gl.NO_ERROR);
if (isConflicted)
shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_UNSUPPORTED");
}
function testColorRenderbuffer(internalformat)
@ -58,10 +62,33 @@ function testColorRenderbuffer(internalformat)
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");
debug("Create renderbuffers");
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()");
gl.bindRenderbuffer(gl.RENDERBUFFER, depthBuffer);
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, width, height);
@ -116,6 +143,9 @@ testColorRenderbuffer(gl.RGB5_A1);
debug("Attach color renderbuffer with internalformat == RGB565");
testColorRenderbuffer(gl.RGB565);
debug("Create and attach depthStencil renderbuffer");
testDepthStencilRenderbuffer();
successfullyParsed = true;
</script>

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

@ -64,7 +64,7 @@ var shaders = gl.getAttachedShaders(standardProgram);
shouldBe('shaders.length', '2');
shouldBeTrue('shaders[0] == standardVert && shaders[1] == standardFrag || shaders[1] == standardVert && shaders[0] == standardFrag');
glErrorShouldBe(gl, gl.NO_ERROR);
shouldBeUndefined('gl.getAttachedShaders(null)');
shouldBeNull('gl.getAttachedShaders(null)');
glErrorShouldBe(gl, gl.INVALID_VALUE);
shouldThrow('gl.getAttachedShaders(standardVert)');
glErrorShouldBe(gl, gl.NO_ERROR);
@ -174,9 +174,9 @@ gl.uniform3i(bval3Loc, 1, 0, 1);
gl.uniform4i(bval4Loc, 1, 0, 1, 0);
glErrorShouldBe(gl, gl.NO_ERROR);
shouldBe('gl.getUniform(boolProgram, bvalLoc)', 'true');
shouldBe('gl.getUniform(boolProgram, bval2Loc)', '[1, 0]');
shouldBe('gl.getUniform(boolProgram, bval3Loc)', '[1, 0, 1]');
shouldBe('gl.getUniform(boolProgram, bval4Loc)', '[1, 0, 1, 0]');
shouldBe('gl.getUniform(boolProgram, bval2Loc)', '[true, false]');
shouldBe('gl.getUniform(boolProgram, bval3Loc)', '[true, false, true]');
shouldBe('gl.getUniform(boolProgram, bval4Loc)', '[true, false, true, false]');
// Integer uniform variables
var intProgram = loadProgram(gl, "resources/intUniformShader.vert", "resources/noopUniformShader.frag");
shouldBe('gl.getProgramParameter(intProgram, gl.LINK_STATUS)', 'true');

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

@ -38,7 +38,8 @@ var imgURLs = [
'resources/gray-ramp.png',
'resources/zero-alpha.png',
'resources/3x3.png',
'resources/blue-1x1.jpg'];
'resources/blue-1x1.jpg',
'resources/green-2x2-16bit.png'];
wtu.loadImagesAsync(imgURLs, runTests);
@ -167,6 +168,7 @@ function runTests(imgs) {
debug("");
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,
imgs['resources/gray-ramp-default-gamma.png']);
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");
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("");
successfullyParsed = true;
shouldBeTrue("successfullyParsed");

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

@ -19,7 +19,7 @@ found in the LICENSE file.
<div id="console"></div>
<canvas id="canvas" width="2" height="2"> </canvas>
<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("Canvas.getContext");
@ -36,6 +36,16 @@ if (!gl) {
gl.vertexAttribPointer(0, 3, gl.FLOAT, 0, 0, 12);
glErrorShouldBe(gl, gl.INVALID_OPERATION,
"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("");

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

@ -60,6 +60,7 @@ function init()
gl = initWebGL("example", "vshader", "fshader", [ "vPosition", "texCoord0"],
[ 0, 0, 0, 1 ], 1);
gl = WebGLDebugUtils.makeDebugContext(gl);
gl.disable(gl.DEPTH_TEST);
gl.disable(gl.BLEND);
@ -124,7 +125,7 @@ function init()
var y = Math.floor(ii / 2);
gl.drawArrays(gl.TRIANGLES, 0, 6);
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">
__FILE__
</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>
<script>
description("This test ensures WebGL implementations allow proper GLES2 shaders compile and improper ones fail.");
@ -310,6 +341,20 @@ if (!gl) {
linkSuccess: false,
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',
vShaderSuccess: false,
fShaderId: 'fshader',
@ -415,7 +460,21 @@ if (!gl) {
fShaderSuccess: true,
linkSuccess: false,
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.

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

@ -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 pixel = [ 0, 0, 0, 0 ];
var expectedColor = [ 0, 0, 0, 0 ];
var pixelFormat = 0;
var pixelType = 0;
function calculatePixelBytes(format, type)
{
@ -168,38 +166,26 @@ function runTestIteration(format, type, packAlignment, width, height)
var bytesPerPixel = calculatePixelBytes(format, type);
var padding = calculatePaddingBytes(bytesPerPixel, packAlignment, width);
var size = bytesPerPixel * width * height + padding * (height - 1);
var isShort = false;
switch (type) {
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 (type != gl.UNSIGNED_BYTE) {
throw "test error: only UNSIGNED_BYTE is valid to ReadPixels";
}
if (isShort)
size /= 2;
if (size < 0)
size = 0;
if (type == gl.UNSIGNED_BYTE)
array = new Uint8Array(size);
else
array = new Uint16Array(size);
array = new Uint8Array(size);
gl.readPixels(0, 0, width, height, format, type, array);
if (width < 0 || height < 0) {
glErrorShouldBe(gl, gl.INVALID_VALUE);
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.
var bytesPerRow = width * bytesPerPixel + padding;
var pos = bytesPerRow * (height - 1) + (width - 1) * bytesPerPixel;
var numComponents = bytesPerPixel;
if (isShort) {
pos /= 2;
numComponents /= 2;
}
for (var i = 0; i < numComponents; ++i)
pixel[i] = array[pos + i];
for (var i = numComponents; i < 4; ++i)
@ -209,75 +195,44 @@ function runTestIteration(format, type, packAlignment, width, height)
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.');
shouldBeNonNull("gl = initWebGL('example', 'vshader', 'fshader', [ 'pos', 'colorIn' ], [ 0, 0, 0, 1 ], 1)");
gl.disable(gl.BLEND);
checkSupportedPixelFormatAndType();
var formats = [ gl.RGBA ];
var formatNames = [ "RGBA" ];
debug("Testing format = RGBA and type = UNSIGNED_BYTE");
runTestIteration(gl.RGBA, gl.UNSIGNED_BYTE, 1, 1, 2);
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);
for (var i = 0; i < formats.length; ++i) {
var format = formats[i];
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;
</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"/>
<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>
<canvas id="example" width="200" height="200"></canvas>
@ -19,6 +20,7 @@ found in the LICENSE file.
<script>
description("Checks that ReadPixels works as expected.");
var wtu = WebGLTestUtils;
var canvas = document.getElementById("example");
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("");
successfullyParsed = true;
</script>

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

@ -12,7 +12,7 @@ found in the LICENSE file.
function runTest()
{
var canvas = document.getElementById("testbed");
var gl = canvas.getContext("experimental-webgl");
var gl = create3DContext(canvas);
if (!gl) {
testFailed('canvas.getContext() failed');
return false;

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

@ -9,46 +9,18 @@ found in the LICENSE file.
<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>
<canvas id="example" width="1px" height="2px"></canvas>
<div id="description"></div>
<div id="console"></div>
<script>
description('Verifies texImage2D and texSubImage2D code paths taking ArrayBufferView');
var wtu = WebGLTestUtils;
var gl = null;
var textureLoc = null;
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
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() {
if (window.nonKhronosFrameworkNotifyDone) {
window.nonKhronosFrameworkNotifyDone();
}
}
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();
successfullyParsed = true;
</script>
</head>
<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>
<script src="../resources/js-test-post.js"></script>
</body>
</html>

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

@ -6,13 +6,12 @@
<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/testrunner.js"></script>
</head>
<body>
<div id="description"></div>
<div id="console"></div>
<canvas id="canvas" width="2" height="2"> </canvas>
<script><!--
<script type="text/javascript">
description("texImage2D and texSubImage2D tests with invalid data");
var canvas = document.getElementById("canvas");
@ -22,63 +21,79 @@ if (!gl)
else
testPassed("Context created.");
var tex;
/* object containing all tests in this testsuite */
var bug32619_tests = {
setup: function () {
bug32619_tests.tex = gl.createTexture();
function setup() {
tex = gl.createTexture();
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);
},
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("");
successfullyParsed = true;
--></script>
</script>
<script src="../resources/js-test-post.js"></script>
<script>
</script>

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

@ -51,7 +51,7 @@ function init()
var canvas = document.getElementById("example");
gl = wtu.create3DContext(canvas);
var program = wtu.setupTexturedQuad(gl);
gl.clearColor(0,0,0,1);
gl.clearColor(0.5,0.5,0.5,1);
gl.clearDepth(1);
textureLoc = gl.getUniformLocation(program, "tex");
@ -70,7 +70,7 @@ function init()
gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
gl.bufferData(gl.ARRAY_BUFFER, texCoords, gl.STATIC_DRAW);
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);
}
@ -82,16 +82,18 @@ var idx = 0;
function runTest()
{
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
gl.bindTexture(gl.TEXTURE_2D, texture);
// Point the uniform sampler to texture unit 0
gl.uniform1i(textureLoc, 0);
// 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
// corners; they should be the rgb values in the texture.
color = [255, 255, 255]
color = [0, 0, 0];
debug("Checking lower left corner");
wtu.checkCanvasRect(gl, 1, gl.canvas.height - 3, 2, 2, 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"/>
<script src="../resources/js-test-pre.js"></script>
<script src="resources/webgl-test.js"></script>
<script src="resources/testrunner.js"></script>
</head>
<body>
<div id="description"></div>
<div id="console"></div>
<canvas id="canvas" width="2" height="2"> </canvas>
<script><!--
<script>
description("Tests to check user code cannot access uninitialized data from GL resources.");
var canvas = document.getElementById("canvas");
@ -23,66 +22,71 @@ else
testPassed("Context created.");
/* object containing all tests in this testsuite */
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;
debug("Reading an uninitialized texture should succeed with all bytes set to 0.");
this.setup = function () {
var tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this._width, this._height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
var width = 512;
var height = 512;
var bpp = 4;
var expectedDataLength = width*height*bpp;
// this can be quite undeterministic so to improve odds of seeing uninitialized data write bits
// into tex then delete texture then re-create one with same characteristics (driver will likely reuse mem)
// with this trick on r59046 WebKit/OSX I get FAIL 100% of the time instead of ~15% of the time.
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();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
var tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this._width, this._height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
// this can be quite undeterministic so to improve odds of seeing uninitialized data write bits
// into tex then delete texture then re-create one with same characteristics (driver will likely reuse mem)
// with this trick on r59046 WebKit/OSX I get FAIL 100% of the time instead of ~15% of the time.
var fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
var badData = new Uint8Array(expectedDataLength);
for (var i = 0; i < badData.length; ++i)
badData[i] = i % 255;
this.data = new Uint8Array(this._width * this._height * 4);
gl.readPixels(0, 0, this._width, this._height, gl.RGBA, gl.UNSIGNED_BYTE, this.data);
};
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, badData);
gl.finish(); // make sure it has been uploaded
this.expects = function () {
if (this.data.length !== this._expectedDataLength) {
debug("expected data length " + this._expectedDataLength + " but got " + this.data.length + " instead.");
return false;
}
for (var i = 0; i < this.data.length; ++i)
if (0 !== this.data[i]) {
debug("byte at offset " + i + " has value " + this.data[i]);
return false;
}
return true;
};
gl.deleteTexture(tex);
gl.finish(); // make sure it has been deleted
var tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
var fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
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?)
//TODO: uninitialized renderbuffer? (implementations would need to do a GL clear at first binding?)
//TODO: uninitialized uniform arrays?
}
if (k) {
testFailed("Found " + k + " non-zero bytes");
} 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("");
successfullyParsed = true;
--></script>
</script>
<script src="../resources/js-test-post.js"></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
"MozAfterPaint",
"MozBeforePaint",
"MozBeforeResize",
"MozSwipeGesture",
"MozMagnifyGestureStart",
"MozMagnifyGestureUpdate",
@ -1316,6 +1317,8 @@ const char* nsDOMEvent::GetEventName(PRUint32 aEventType)
return sEventNames[eDOMEvents_afterpaint];
case NS_BEFOREPAINT:
return sEventNames[eDOMEvents_beforepaint];
case NS_BEFORERESIZE_EVENT:
return sEventNames[eDOMEvents_beforeresize];
case NS_SIMPLE_GESTURE_SWIPE:
return sEventNames[eDOMEvents_MozSwipeGesture];
case NS_SIMPLE_GESTURE_MAGNIFY_START:

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

@ -175,6 +175,7 @@ public:
#endif
eDOMEvents_afterpaint,
eDOMEvents_beforepaint,
eDOMEvents_beforeresize,
eDOMEvents_MozSwipeGesture,
eDOMEvents_MozMagnifyGestureStart,
eDOMEvents_MozMagnifyGestureUpdate,

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

@ -110,6 +110,8 @@ _CHROME_FILES = \
test_bug415498.xul \
bug415498-doc1.html \
bug415498-doc2.html \
bug602962.xul \
test_bug602962.xul \
$(NULL)
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:
nsIntSize GetWidthHeight();
nsresult UpdateContext();
nsresult UpdateContext(nsIPropertyBag *aNewContextOptions = nsnull);
nsresult ExtractData(const nsAString& aType,
const nsAString& aOptions,
char*& aData,

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