Merge mozilla-central to tracemonkey.

This commit is contained in:
Robert Sayre 2010-11-24 14:00:42 -08:00
Родитель 146d06f08b bcb3935aa9
Коммит 88e6ba5ed6
868 изменённых файлов: 23176 добавлений и 12681 удалений

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

@ -137,3 +137,115 @@ RelatedAccIterator::Next()
return nsnull;
}
////////////////////////////////////////////////////////////////////////////////
// HTMLLabelIterator
////////////////////////////////////////////////////////////////////////////////
HTMLLabelIterator::
HTMLLabelIterator(nsDocAccessible* aDocument, nsIContent* aElement,
LabelFilter aFilter) :
mRelIter(aDocument, aElement, nsAccessibilityAtoms::_for),
mElement(aElement), mLabelFilter(aFilter)
{
}
nsAccessible*
HTMLLabelIterator::Next()
{
// Get either <label for="[id]"> element which explicitly points to given
// element, or <label> ancestor which implicitly point to it.
nsAccessible* label = nsnull;
while ((label = mRelIter.Next())) {
if (label->GetContent()->Tag() == nsAccessibilityAtoms::label)
return label;
}
if (mLabelFilter == eSkipAncestorLabel)
return nsnull;
// Go up tree get name of ancestor label if there is one (an ancestor <label>
// implicitly points to us). Don't go up farther than form or body element.
nsIContent* walkUpContent = mElement;
while ((walkUpContent = walkUpContent->GetParent()) &&
walkUpContent->Tag() != nsAccessibilityAtoms::form &&
walkUpContent->Tag() != nsAccessibilityAtoms::body) {
if (walkUpContent->Tag() == nsAccessibilityAtoms::label) {
// Prevent infinite loop.
mLabelFilter = eSkipAncestorLabel;
return GetAccService()->GetAccessible(walkUpContent);
}
}
return nsnull;
}
////////////////////////////////////////////////////////////////////////////////
// HTMLOutputIterator
////////////////////////////////////////////////////////////////////////////////
HTMLOutputIterator::
HTMLOutputIterator(nsDocAccessible* aDocument, nsIContent* aElement) :
mRelIter(aDocument, aElement, nsAccessibilityAtoms::_for)
{
}
nsAccessible*
HTMLOutputIterator::Next()
{
nsAccessible* output = nsnull;
while ((output = mRelIter.Next())) {
if (output->GetContent()->Tag() == nsAccessibilityAtoms::output)
return output;
}
return nsnull;
}
////////////////////////////////////////////////////////////////////////////////
// XULLabelIterator
////////////////////////////////////////////////////////////////////////////////
XULLabelIterator::
XULLabelIterator(nsDocAccessible* aDocument, nsIContent* aElement) :
mRelIter(aDocument, aElement, nsAccessibilityAtoms::control)
{
}
nsAccessible*
XULLabelIterator::Next()
{
nsAccessible* label = nsnull;
while ((label = mRelIter.Next())) {
if (label->GetContent()->Tag() == nsAccessibilityAtoms::label)
return label;
}
return nsnull;
}
////////////////////////////////////////////////////////////////////////////////
// XULDescriptionIterator
////////////////////////////////////////////////////////////////////////////////
XULDescriptionIterator::
XULDescriptionIterator(nsDocAccessible* aDocument, nsIContent* aElement) :
mRelIter(aDocument, aElement, nsAccessibilityAtoms::control)
{
}
nsAccessible*
XULDescriptionIterator::Next()
{
nsAccessible* descr = nsnull;
while ((descr = mRelIter.Next())) {
if (descr->GetContent()->Tag() == nsAccessibilityAtoms::description)
return descr;
}
return nsnull;
}

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

@ -131,4 +131,100 @@ private:
PRUint32 mIndex;
};
/**
* Used to iterate through HTML labels associated with the given element.
*/
class HTMLLabelIterator
{
public:
enum LabelFilter {
eAllLabels,
eSkipAncestorLabel
};
HTMLLabelIterator(nsDocAccessible* aDocument, nsIContent* aElement,
LabelFilter aFilter = eAllLabels);
/**
* Return next label accessible associated with the given element.
*/
nsAccessible* Next();
private:
HTMLLabelIterator();
HTMLLabelIterator(const HTMLLabelIterator&);
HTMLLabelIterator& operator = (const HTMLLabelIterator&);
RelatedAccIterator mRelIter;
nsIContent* mElement;
LabelFilter mLabelFilter;
};
/**
* Used to iterate through HTML outputs associated with the given element.
*/
class HTMLOutputIterator
{
public:
HTMLOutputIterator(nsDocAccessible* aDocument, nsIContent* aElement);
/**
* Return next output accessible associated with the given element.
*/
nsAccessible* Next();
private:
HTMLOutputIterator();
HTMLOutputIterator(const HTMLOutputIterator&);
HTMLOutputIterator& operator = (const HTMLOutputIterator&);
RelatedAccIterator mRelIter;
};
/**
* Used to iterate through XUL labels associated with the given element.
*/
class XULLabelIterator
{
public:
XULLabelIterator(nsDocAccessible* aDocument, nsIContent* aElement);
/**
* Return next label accessible associated with the given element.
*/
nsAccessible* Next();
private:
XULLabelIterator();
XULLabelIterator(const XULLabelIterator&);
XULLabelIterator& operator = (const XULLabelIterator&);
RelatedAccIterator mRelIter;
};
/**
* Used to iterate through XUL descriptions associated with the given element.
*/
class XULDescriptionIterator
{
public:
XULDescriptionIterator(nsDocAccessible* aDocument, nsIContent* aElement);
/**
* Return next description accessible associated with the given element.
*/
nsAccessible* Next();
private:
XULDescriptionIterator();
XULDescriptionIterator(const XULDescriptionIterator&);
XULDescriptionIterator& operator = (const XULDescriptionIterator&);
RelatedAccIterator mRelIter;
};
#endif

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

@ -214,6 +214,10 @@ nsAccDocManager::OnStateChange(nsIWebProgress *aWebProgress,
nsEventShell::FireEvent(reloadEvent);
}
// Mark the document accessible as loading, if it stays alive then we'll mark
// it as loaded when we receive proper notification.
docAcc->MarkAsLoading();
// Fire state busy change event. Use delayed event since we don't care
// actually if event isn't delivered when the document goes away like a shot.
nsRefPtr<AccEvent> stateEvent =
@ -310,8 +314,7 @@ nsAccDocManager::HandleEvent(nsIDOMEvent *aEvent)
nsCoreUtils::IsErrorPage(document)) {
NS_LOG_ACCDOCLOAD2("handled 'DOMContentLoaded' event", document)
HandleDOMDocumentLoad(document,
nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE,
PR_TRUE);
nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE);
}
return NS_OK;
@ -322,8 +325,7 @@ nsAccDocManager::HandleEvent(nsIDOMEvent *aEvent)
void
nsAccDocManager::HandleDOMDocumentLoad(nsIDocument *aDocument,
PRUint32 aLoadEventType,
PRBool aMarkAsLoaded)
PRUint32 aLoadEventType)
{
// Document accessible can be created before we were notified the DOM document
// was loaded completely. However if it's not created yet then create it.
@ -335,8 +337,8 @@ nsAccDocManager::HandleDOMDocumentLoad(nsIDocument *aDocument,
return;
}
if (aMarkAsLoaded)
docAcc->MarkAsLoaded();
// Mark the document as loaded to drop off the busy state flag on it.
docAcc->MarkAsLoaded();
// Do not fire document complete/stop events for root chrome document
// accessibles and for frame/iframe documents because

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

@ -116,13 +116,9 @@ private:
* @param aDocument [in] loaded DOM document
* @param aLoadEventType [in] specifies the event type to fire load event,
* if 0 then no event is fired
* @param aMarkAsLoaded [in] indicates whether we should mark forcedly
* an accessible document as loaded (used for error
* pages only which do not get 'pageshow' event)
*/
void HandleDOMDocumentLoad(nsIDocument *aDocument,
PRUint32 aLoadEventType,
PRBool aMarkAsLoaded = PR_FALSE);
PRUint32 aLoadEventType);
/**
* Return true if accessibility events accompanying document accessible

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

@ -294,15 +294,11 @@ NS_IMETHODIMP nsAccessible::GetDescription(nsAString& aDescription)
PRBool isXUL = mContent->IsXUL();
if (isXUL) {
// Try XUL <description control="[id]">description text</description>
nsIContent *descriptionContent =
nsCoreUtils::FindNeighbourPointingToNode(mContent,
nsAccessibilityAtoms::control,
nsAccessibilityAtoms::description);
if (descriptionContent) {
// We have a description content node
XULDescriptionIterator iter(GetDocAccessible(), mContent);
nsAccessible* descr = nsnull;
while ((descr = iter.Next())) {
nsTextEquivUtils::
AppendTextEquivFromContent(this, descriptionContent, &description);
AppendTextEquivFromContent(this, descr->GetContent(), &description);
}
}
if (description.IsEmpty()) {
@ -393,11 +389,23 @@ nsAccessible::GetKeyboardShortcut(nsAString& aAccessKey)
PRUint32 key = nsCoreUtils::GetAccessKeyFor(mContent);
if (!key && mContent->IsElement()) {
// Copy access key from label node unless it is labeled
// via an ancestor <label>, in which case that would be redundant
nsCOMPtr<nsIContent> labelContent(nsCoreUtils::GetLabelContent(mContent));
if (labelContent && !nsCoreUtils::IsAncestorOf(labelContent, mContent))
key = nsCoreUtils::GetAccessKeyFor(labelContent);
nsAccessible* label = nsnull;
// Copy access key from label node.
if (mContent->IsHTML()) {
// Unless it is labeled via an ancestor <label>, in which case that would
// be redundant.
HTMLLabelIterator iter(GetDocAccessible(), mContent,
HTMLLabelIterator::eSkipAncestorLabel);
label = iter.Next();
} else if (mContent->IsXUL()) {
XULLabelIterator iter(GetDocAccessible(), mContent);
label = iter.Next();
}
if (label)
key = nsCoreUtils::GetAccessKeyFor(label->GetContent());
}
if (!key)
@ -1137,21 +1145,23 @@ nsAccessible::TakeFocus()
nsresult
nsAccessible::GetHTMLName(nsAString& aLabel)
{
nsIContent *labelContent = nsCoreUtils::GetHTMLLabelContent(mContent);
if (labelContent) {
nsAutoString label;
nsresult rv =
nsTextEquivUtils::AppendTextEquivFromContent(this, labelContent, &label);
nsAutoString label;
nsAccessible* labelAcc = nsnull;
HTMLLabelIterator iter(GetDocAccessible(), mContent);
while ((labelAcc = iter.Next())) {
nsresult rv = nsTextEquivUtils::
AppendTextEquivFromContent(this, labelAcc->GetContent(), &label);
NS_ENSURE_SUCCESS(rv, rv);
label.CompressWhitespace();
if (!label.IsEmpty()) {
aLabel = label;
return NS_OK;
}
}
return nsTextEquivUtils::GetNameFromSubtree(this, aLabel);
if (label.IsEmpty())
return nsTextEquivUtils::GetNameFromSubtree(this, aLabel);
aLabel = label;
return NS_OK;
}
/**
@ -1198,17 +1208,19 @@ nsAccessible::GetXULName(nsAString& aLabel)
// CASES #2 and #3 ------ label as a child or <label control="id" ... > </label>
if (NS_FAILED(rv) || label.IsEmpty()) {
label.Truncate();
nsIContent *labelContent =
nsCoreUtils::FindNeighbourPointingToNode(mContent,
nsAccessibilityAtoms::control,
nsAccessibilityAtoms::label);
nsCOMPtr<nsIDOMXULLabelElement> xulLabel(do_QueryInterface(labelContent));
// Check if label's value attribute is used
if (xulLabel && NS_SUCCEEDED(xulLabel->GetValue(label)) && label.IsEmpty()) {
// If no value attribute, a non-empty label must contain
// children that define its text -- possibly using HTML
nsTextEquivUtils::AppendTextEquivFromContent(this, labelContent, &label);
nsAccessible* labelAcc = nsnull;
XULLabelIterator iter(GetDocAccessible(), mContent);
while ((labelAcc = iter.Next())) {
nsCOMPtr<nsIDOMXULLabelElement> xulLabel =
do_QueryInterface(labelAcc->GetContent());
// Check if label's value attribute is used
if (xulLabel && NS_SUCCEEDED(xulLabel->GetValue(label)) && label.IsEmpty()) {
// If no value attribute, a non-empty label must contain
// children that define its text -- possibly using HTML
nsTextEquivUtils::
AppendTextEquivFromContent(this, labelAcc->GetContent(), &label);
}
}
}
@ -2068,12 +2080,24 @@ nsAccessible::GetRelationByType(PRUint32 aRelationType,
nsAccessibilityAtoms::aria_labelledby);
NS_ENSURE_SUCCESS(rv, rv);
if (rv != NS_OK_NO_RELATION_TARGET)
return NS_OK; // XXX bug 381599, avoid performance problems
nsAccessible* label = nsnull;
if (mContent->IsHTML()) {
HTMLLabelIterator iter(GetDocAccessible(), mContent);
while ((label = iter.Next())) {
rv = nsRelUtils::AddTarget(aRelationType, aRelation, label);
NS_ENSURE_SUCCESS(rv, rv);
}
return rv;
}
return nsRelUtils::
AddTargetFromContent(aRelationType, aRelation,
nsCoreUtils::GetLabelContent(mContent));
if (mContent->IsXUL()) {
XULLabelIterator iter(GetDocAccessible(), mContent);
while ((label = iter.Next())) {
rv = nsRelUtils::AddTarget(aRelationType, aRelation, label);
NS_ENSURE_SUCCESS(rv, rv);
}
}
return rv;
}
case nsIAccessibleRelation::RELATION_DESCRIBED_BY:
@ -2083,13 +2107,16 @@ nsAccessible::GetRelationByType(PRUint32 aRelationType,
nsAccessibilityAtoms::aria_describedby);
NS_ENSURE_SUCCESS(rv, rv);
if (rv != NS_OK_NO_RELATION_TARGET)
return NS_OK; // XXX bug 381599, avoid performance problems
if (mContent->IsXUL()) {
XULDescriptionIterator iter(GetDocAccessible(), mContent);
nsAccessible* descr = nsnull;
while ((descr = iter.Next())) {
rv = nsRelUtils::AddTarget(aRelationType, aRelation, descr);
NS_ENSURE_SUCCESS(rv, rv);
}
}
return nsRelUtils::
AddTargetFromNeighbour(aRelationType, aRelation, mContent,
nsAccessibilityAtoms::control,
nsAccessibilityAtoms::description);
return rv;
}
case nsIAccessibleRelation::RELATION_DESCRIPTION_FOR:
@ -2185,13 +2212,14 @@ nsAccessible::GetRelationByType(PRUint32 aRelationType,
nsAccessibilityAtoms::aria_controls);
NS_ENSURE_SUCCESS(rv,rv);
if (rv != NS_OK_NO_RELATION_TARGET)
return NS_OK; // XXX bug 381599, avoid performance problems
HTMLOutputIterator iter(GetDocAccessible(), mContent);
nsAccessible* related = nsnull;
while ((related = iter.Next())) {
rv = nsRelUtils::AddTarget(aRelationType, aRelation, related);
NS_ENSURE_SUCCESS(rv, rv);
}
return nsRelUtils::
AddTargetFromNeighbour(aRelationType, aRelation, mContent,
nsAccessibilityAtoms::_for,
nsAccessibilityAtoms::output);
return rv;
}
case nsIAccessibleRelation::RELATION_FLOWS_TO:

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

@ -460,19 +460,6 @@ nsCoreUtils::GetDocShellTreeItemFor(nsINode *aNode)
return docShellTreeItem;
}
PRBool
nsCoreUtils::IsDocumentBusy(nsIDocument *aDocument)
{
nsCOMPtr<nsISupports> container = aDocument->GetContainer();
nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(container);
if (!docShell)
return PR_TRUE;
PRUint32 busyFlags = 0;
docShell->GetBusyFlags(&busyFlags);
return (busyFlags != nsIDocShell::BUSY_FLAGS_NONE);
}
PRBool
nsCoreUtils::IsRootDocument(nsIDocument *aDocument)
{
@ -586,211 +573,6 @@ nsCoreUtils::IsXLink(nsIContent *aContent)
aContent->HasAttr(kNameSpaceID_XLink, nsAccessibilityAtoms::href);
}
nsIContent*
nsCoreUtils::FindNeighbourPointingToNode(nsIContent *aForNode,
nsIAtom *aRelationAttr,
nsIAtom *aTagName,
PRUint32 aAncestorLevelsToSearch)
{
return FindNeighbourPointingToNode(aForNode, &aRelationAttr, 1, aTagName, aAncestorLevelsToSearch);
}
nsIContent*
nsCoreUtils::FindNeighbourPointingToNode(nsIContent *aForNode,
nsIAtom **aRelationAttrs,
PRUint32 aAttrNum,
nsIAtom *aTagName,
PRUint32 aAncestorLevelsToSearch)
{
nsAutoString controlID;
if (!nsCoreUtils::GetID(aForNode, controlID)) {
if (!aForNode->IsInAnonymousSubtree())
return nsnull;
aForNode->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::anonid, controlID);
if (controlID.IsEmpty())
return nsnull;
}
// Look for label in subtrees of nearby ancestors
nsCOMPtr<nsIContent> binding(aForNode->GetBindingParent());
PRUint32 count = 0;
nsIContent *labelContent = nsnull;
nsIContent *prevSearched = nsnull;
while (!labelContent && ++count <= aAncestorLevelsToSearch &&
(aForNode = aForNode->GetParent()) != nsnull) {
if (aForNode == binding) {
// When we reach the binding parent, make sure to check
// all of its anonymous child subtrees
nsCOMPtr<nsIDocument> doc = aForNode->GetCurrentDoc();
nsCOMPtr<nsIDOMDocumentXBL> xblDoc(do_QueryInterface(doc));
if (!xblDoc)
return nsnull;
nsCOMPtr<nsIDOMNodeList> nodes;
nsCOMPtr<nsIDOMElement> forElm(do_QueryInterface(aForNode));
xblDoc->GetAnonymousNodes(forElm, getter_AddRefs(nodes));
if (!nodes)
return nsnull;
PRUint32 length;
nsresult rv = nodes->GetLength(&length);
if (NS_FAILED(rv))
return nsnull;
for (PRUint32 index = 0; index < length && !labelContent; index++) {
nsCOMPtr<nsIDOMNode> node;
rv = nodes->Item(index, getter_AddRefs(node));
if (NS_FAILED(rv))
return nsnull;
nsCOMPtr<nsIContent> content = do_QueryInterface(node);
if (!content)
return nsnull;
if (content != prevSearched) {
labelContent = FindDescendantPointingToID(&controlID, content,
aRelationAttrs, aAttrNum,
nsnull, aTagName);
}
}
break;
}
labelContent = FindDescendantPointingToID(&controlID, aForNode,
aRelationAttrs, aAttrNum,
prevSearched, aTagName);
prevSearched = aForNode;
}
return labelContent;
}
// Pass in aAriaProperty = null and aRelationAttr == nsnull if any <label> will do
nsIContent*
nsCoreUtils::FindDescendantPointingToID(const nsString *aId,
nsIContent *aLookContent,
nsIAtom **aRelationAttrs,
PRUint32 aAttrNum,
nsIContent *aExcludeContent,
nsIAtom *aTagType)
{
// Surround id with spaces for search
nsCAutoString idWithSpaces(' ');
LossyAppendUTF16toASCII(*aId, idWithSpaces);
idWithSpaces += ' ';
return FindDescendantPointingToIDImpl(idWithSpaces, aLookContent,
aRelationAttrs, aAttrNum,
aExcludeContent, aTagType);
}
nsIContent*
nsCoreUtils::FindDescendantPointingToID(const nsString *aId,
nsIContent *aLookContent,
nsIAtom *aRelationAttr,
nsIContent *aExcludeContent,
nsIAtom *aTagType)
{
return FindDescendantPointingToID(aId, aLookContent, &aRelationAttr, 1, aExcludeContent, aTagType);
}
nsIContent*
nsCoreUtils::FindDescendantPointingToIDImpl(nsCString& aIdWithSpaces,
nsIContent *aLookContent,
nsIAtom **aRelationAttrs,
PRUint32 aAttrNum,
nsIContent *aExcludeContent,
nsIAtom *aTagType)
{
NS_ENSURE_TRUE(aLookContent, nsnull);
NS_ENSURE_TRUE(aRelationAttrs && *aRelationAttrs, nsnull);
if (!aTagType || aLookContent->Tag() == aTagType) {
// Tag matches
// Check for ID in the attributes aRelationAttrs, which can be a list
for (PRUint32 i = 0; i < aAttrNum; i++) {
nsAutoString idList;
if (aLookContent->GetAttr(kNameSpaceID_None, aRelationAttrs[i], idList)) {
idList.Insert(' ', 0); // Surround idlist with spaces for search
idList.Append(' ');
// idList is now a set of id's with spaces around each,
// and id also has spaces around it.
// If id is a substring of idList then we have a match
if (idList.Find(aIdWithSpaces) != -1) {
return aLookContent;
}
}
}
if (aTagType) {
// Don't bother to search descendants of an element with matching tag.
// That would be like looking for a nested <label> or <description>
return nsnull;
}
}
// Recursively search descendants for match
PRUint32 count = 0;
nsIContent *child;
nsIContent *labelContent = nsnull;
while ((child = aLookContent->GetChildAt(count++)) != nsnull) {
if (child != aExcludeContent) {
labelContent = FindDescendantPointingToIDImpl(aIdWithSpaces, child,
aRelationAttrs, aAttrNum,
aExcludeContent, aTagType);
if (labelContent) {
return labelContent;
}
}
}
return nsnull;
}
nsIContent*
nsCoreUtils::GetLabelContent(nsIContent *aForNode)
{
if (aForNode->IsXUL())
return FindNeighbourPointingToNode(aForNode, nsAccessibilityAtoms::control,
nsAccessibilityAtoms::label);
return GetHTMLLabelContent(aForNode);
}
nsIContent*
nsCoreUtils::GetHTMLLabelContent(nsIContent *aForNode)
{
// Get either <label for="[id]"> element which explictly points to aForNode,
// or <label> ancestor which implicitly point to it.
nsIContent *walkUpContent = aForNode;
// Go up tree get name of ancestor label if there is one. Don't go up farther
// than form element.
while ((walkUpContent = walkUpContent->GetParent()) != nsnull) {
nsIAtom *tag = walkUpContent->Tag();
if (tag == nsAccessibilityAtoms::label)
return walkUpContent; // An ancestor <label> implicitly points to us
if (tag == nsAccessibilityAtoms::form ||
tag == nsAccessibilityAtoms::body) {
// Reached top ancestor in form
// There can be a label targeted at this control using the
// for="control_id" attribute. To save computing time, only
// look for those inside of a form element
nsAutoString forId;
if (!GetID(aForNode, forId))
break;
// Actually we'll be walking down the content this time, with a depth first search
return FindDescendantPointingToID(&forId, walkUpContent,
nsAccessibilityAtoms::_for);
}
}
return nsnull;
}
void
nsCoreUtils::GetLanguageFor(nsIContent *aContent, nsIContent *aRootContent,
nsAString& aLanguage)
@ -804,56 +586,6 @@ nsCoreUtils::GetLanguageFor(nsIContent *aContent, nsIContent *aRootContent,
walkUp = walkUp->GetParent();
}
void
nsCoreUtils::GetElementsHavingIDRefsAttr(nsIContent *aRootContent,
nsIContent *aContent,
nsIAtom *aIDRefsAttr,
nsIArray **aElements)
{
*aElements = nsnull;
nsAutoString id;
if (!GetID(aContent, id))
return;
nsCAutoString idWithSpaces(' ');
LossyAppendUTF16toASCII(id, idWithSpaces);
idWithSpaces += ' ';
nsCOMPtr<nsIMutableArray> elms = do_CreateInstance(NS_ARRAY_CONTRACTID);
if (!elms)
return;
GetElementsHavingIDRefsAttrImpl(aRootContent, idWithSpaces, aIDRefsAttr,
elms);
NS_ADDREF(*aElements = elms);
}
void
nsCoreUtils::GetElementsHavingIDRefsAttrImpl(nsIContent *aRootContent,
nsCString& aIdWithSpaces,
nsIAtom *aIDRefsAttr,
nsIMutableArray *aElements)
{
PRUint32 childCount = aRootContent->GetChildCount();
for (PRUint32 index = 0; index < childCount; index++) {
nsIContent* child = aRootContent->GetChildAt(index);
nsAutoString idList;
if (child->GetAttr(kNameSpaceID_None, aIDRefsAttr, idList)) {
idList.Insert(' ', 0); // Surround idlist with spaces for search
idList.Append(' ');
// idList is now a set of id's with spaces around each, and id also has
// spaces around it. If id is a substring of idList then we have a match.
if (idList.Find(aIdWithSpaces) != -1) {
aElements->AppendElement(child, PR_FALSE);
continue; // Do not search inside children.
}
}
GetElementsHavingIDRefsAttrImpl(child, aIdWithSpaces,
aIDRefsAttr, aElements);
}
}
already_AddRefed<nsIDOMCSSStyleDeclaration>
nsCoreUtils::GetComputedStyleDeclaration(const nsAString& aPseudoElt,
nsIContent *aContent)

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

@ -223,11 +223,6 @@ public:
static already_AddRefed<nsIDocShellTreeItem>
GetDocShellTreeItemFor(nsINode *aNode);
/**
* Return true if document is loading.
*/
static PRBool IsDocumentBusy(nsIDocument *aDocument);
/**
* Return true if the given document is root document.
*/
@ -305,27 +300,6 @@ public:
static void GetLanguageFor(nsIContent *aContent, nsIContent *aRootContent,
nsAString& aLanguage);
/**
* Return the array of elements having IDRefs that points to the given node.
*
* @param aRootContent [in] root element to search inside
* @param aContent [in] an element having ID attribute
* @param aIDRefsAttr [in] IDRefs attribute
* @param aElements [out] result array of elements
*/
static void GetElementsHavingIDRefsAttr(nsIContent *aRootContent,
nsIContent *aContent,
nsIAtom *aIDRefsAttr,
nsIArray **aElements);
/**
* Helper method for GetElementsHavingIDRefsAttr.
*/
static void GetElementsHavingIDRefsAttrImpl(nsIContent *aRootContent,
nsCString& aIdWithSpaces,
nsIAtom *aIDRefsAttr,
nsIMutableArray *aElements);
/**
* Return computed styles declaration for the given node.
*/
@ -333,85 +307,6 @@ public:
GetComputedStyleDeclaration(const nsAString& aPseudoElt,
nsIContent *aContent);
/**
* Search element in neighborhood of the given element by tag name and
* attribute value that equals to ID attribute of the given element.
* ID attribute can be either 'id' attribute or 'anonid' if the element is
* anonymous.
* The first matched content will be returned.
*
* @param aForNode - the given element the search is performed for
* @param aRelationAttrs - an array of attributes, element is attribute name of searched element, ignored if aAriaProperty passed in
* @param aAttrNum - how many attributes in aRelationAttrs
* @param aTagName - tag name of searched element, or nsnull for any -- ignored if aAriaProperty passed in
* @param aAncestorLevelsToSearch - points how is the neighborhood of the
* given element big.
*/
static nsIContent *FindNeighbourPointingToNode(nsIContent *aForNode,
nsIAtom **aRelationAttrs,
PRUint32 aAttrNum,
nsIAtom *aTagName = nsnull,
PRUint32 aAncestorLevelsToSearch = 5);
/**
* Overloaded version of FindNeighbourPointingToNode to accept only one
* relation attribute.
*/
static nsIContent *FindNeighbourPointingToNode(nsIContent *aForNode,
nsIAtom *aRelationAttr,
nsIAtom *aTagName = nsnull,
PRUint32 aAncestorLevelsToSearch = 5);
/**
* Search for element that satisfies the requirements in subtree of the given
* element. The requirements are tag name, attribute name and value of
* attribute.
* The first matched content will be returned.
*
* @param aId - value of searched attribute
* @param aLookContent - element that search is performed inside
* @param aRelationAttrs - an array of searched attributes
* @param aAttrNum - how many attributes in aRelationAttrs
* @param if both aAriaProperty and aRelationAttrs are null, then any element with aTagType will do
* @param aExcludeContent - element that is skiped for search
* @param aTagType - tag name of searched element, by default it is 'label' --
* ignored if aAriaProperty passed in
*/
static nsIContent *FindDescendantPointingToID(const nsString *aId,
nsIContent *aLookContent,
nsIAtom **aRelationAttrs,
PRUint32 aAttrNum = 1,
nsIContent *aExcludeContent = nsnull,
nsIAtom *aTagType = nsAccessibilityAtoms::label);
/**
* Overloaded version of FindDescendantPointingToID to accept only one
* relation attribute.
*/
static nsIContent *FindDescendantPointingToID(const nsString *aId,
nsIContent *aLookContent,
nsIAtom *aRelationAttr,
nsIContent *aExcludeContent = nsnull,
nsIAtom *aTagType = nsAccessibilityAtoms::label);
// Helper for FindDescendantPointingToID(), same args
static nsIContent *FindDescendantPointingToIDImpl(nsCString& aIdWithSpaces,
nsIContent *aLookContent,
nsIAtom **aRelationAttrs,
PRUint32 aAttrNum = 1,
nsIContent *aExcludeContent = nsnull,
nsIAtom *aTagType = nsAccessibilityAtoms::label);
/**
* Return the label element for the given DOM element.
*/
static nsIContent *GetLabelContent(nsIContent *aForNode);
/**
* Return the HTML label element for the given HTML element.
*/
static nsIContent *GetHTMLLabelContent(nsIContent *aForNode);
/**
* Return box object for XUL treechildren element by tree box object.
*/

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

@ -91,7 +91,9 @@ static nsIAtom** kRelationAttrs[] =
&nsAccessibilityAtoms::aria_describedby,
&nsAccessibilityAtoms::aria_owns,
&nsAccessibilityAtoms::aria_controls,
&nsAccessibilityAtoms::aria_flowto
&nsAccessibilityAtoms::aria_flowto,
&nsAccessibilityAtoms::_for,
&nsAccessibilityAtoms::control
};
static const PRUint32 kRelationAttrsLen = NS_ARRAY_LENGTH(kRelationAttrs);
@ -317,7 +319,7 @@ nsDocAccessible::GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState)
*aState |= nsIAccessibleStates::STATE_FOCUSED;
}
if (nsCoreUtils::IsDocumentBusy(mDocument)) {
if (!mIsLoaded) {
*aState |= nsIAccessibleStates::STATE_BUSY;
if (aExtraState) {
*aExtraState |= nsIAccessibleStates::EXT_STATE_STALE;
@ -942,7 +944,7 @@ nsDocAccessible::AttributeWillChange(nsIDocument *aDocument,
PRInt32 aNameSpaceID,
nsIAtom* aAttribute, PRInt32 aModType)
{
// XXX TODO: bugs 381599 (partially fixed by 573469), 467143, 472142, 472143.
// XXX TODO: bugs 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.
@ -1401,20 +1403,22 @@ nsDocAccessible::BindToDocument(nsAccessible* aAccessible,
void
nsDocAccessible::UnbindFromDocument(nsAccessible* aAccessible)
{
NS_ASSERTION(mAccessibleCache.GetWeak(aAccessible->UniqueID()),
"Unbinding the unbound accessible!");
// Remove an accessible from node-to-accessible map if it exists there.
if (aAccessible->IsPrimaryForNode() &&
mNodeToAccessibleMap.Get(aAccessible->GetNode()) == aAccessible)
mNodeToAccessibleMap.Remove(aAccessible->GetNode());
RemoveDependentIDsFor(aAccessible);
#ifdef DEBUG
NS_ASSERTION(mAccessibleCache.GetWeak(aAccessible->UniqueID()),
"Unbinding the unbound accessible!");
#endif
if (!aAccessible->IsDefunct())
RemoveDependentIDsFor(aAccessible);
void* uniqueID = aAccessible->UniqueID();
NS_ASSERTION(!aAccessible->IsDefunct(), "Shutdown the shutdown accessible!");
aAccessible->Shutdown();
mAccessibleCache.Remove(uniqueID);
}
@ -1449,16 +1453,14 @@ nsDocAccessible::UpdateTree(nsIContent* aContainerNode,
// The document children were changed; the root content might be affected.
if (container == this) {
// If new root content has been inserted then update it.
nsIContent* rootContent = nsCoreUtils::GetRoleContent(mDocument);
// No root content (for example HTML document element was inserted but no
// body). Nothing to update.
if (!rootContent)
return;
// New root content has been inserted, update it and update the tree.
if (rootContent != mContent)
if (rootContent && rootContent != mContent)
mContent = rootContent;
// Continue to update the tree even if we don't have root content.
// For example, elements may be inserted under the document element while
// there is no HTML body element.
}
// XXX: Invalidate parent-child relations for container accessible and its
@ -1622,6 +1624,21 @@ nsDocAccessible::NotifyOfCachingEnd(nsAccessible* aAccessible)
}
}
////////////////////////////////////////////////////////////////////////////////
// nsAccessible protected
void
nsDocAccessible::CacheChildren()
{
// Search for accessible children starting from the document element since
// some web pages tend to insert elements under it rather than document body.
nsAccTreeWalker walker(mWeakShell, mDocument->GetRootElement(),
GetAllowsAnonChildAccessibles());
nsRefPtr<nsAccessible> child;
while ((child = walker.GetNextChild()) && AppendChild(child));
}
////////////////////////////////////////////////////////////////////////////////
// Protected members
@ -1634,6 +1651,19 @@ nsDocAccessible::AddDependentIDsFor(nsAccessible* aRelProvider,
if (aRelAttr && aRelAttr != relAttr)
continue;
if (relAttr == nsAccessibilityAtoms::_for) {
if (!aRelProvider->GetContent()->IsHTML() ||
aRelProvider->GetContent()->Tag() != nsAccessibilityAtoms::label &&
aRelProvider->GetContent()->Tag() != nsAccessibilityAtoms::output)
continue;
} else if (relAttr == nsAccessibilityAtoms::control) {
if (!aRelProvider->GetContent()->IsXUL() ||
aRelProvider->GetContent()->Tag() != nsAccessibilityAtoms::label &&
aRelProvider->GetContent()->Tag() != nsAccessibilityAtoms::description)
continue;
}
IDRefsIterator iter(aRelProvider->GetContent(), relAttr);
while (true) {
const nsDependentSubstring id = iter.NextID();

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

@ -138,11 +138,14 @@ public:
}
/**
* Marks as loaded, used for error pages as workaround since they do not
* Marks this document as loaded or loading, used to expose busy state.
* The loaded flag has special meaning for error pages and used as workaround
* to make IsContentLoaded() return correct result since these pages do not
* receive pageshow event and as consequence nsIDocument::IsShowing() returns
* false.
*/
void MarkAsLoaded() { mIsLoaded = PR_TRUE; }
void MarkAsLoading() { mIsLoaded = PR_FALSE; }
/**
* Return a native window handler or pointer depending on platform.
@ -266,6 +269,10 @@ public:
protected:
// nsAccessible
virtual void CacheChildren();
// nsDocAccessible
virtual void GetBoundsRect(nsRect& aRect, nsIFrame** aRelativeFrame);
virtual nsresult AddEventListeners();
virtual nsresult RemoveEventListeners();
@ -415,7 +422,7 @@ protected:
mRelAttr(aRelAttr), mContent(aContent) { }
nsIAtom* mRelAttr;
nsIContent* mContent;
nsCOMPtr<nsIContent> mContent;
private:
AttrRelProvider();

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

@ -145,46 +145,3 @@ nsRelUtils::AddTargetFromIDRefsAttr(PRUint32 aRelationType,
return rv;
}
nsresult
nsRelUtils::AddTargetFromNeighbour(PRUint32 aRelationType,
nsIAccessibleRelation **aRelation,
nsIContent *aContent,
nsIAtom *aNeighboutAttr,
nsIAtom *aNeighboutTagName)
{
return AddTargetFromContent(
aRelationType, aRelation,
nsCoreUtils::FindNeighbourPointingToNode(aContent, aNeighboutAttr,
aNeighboutTagName));
}
nsresult
nsRelUtils::AddTargetFromChildrenHavingIDRefsAttr(PRUint32 aRelationType,
nsIAccessibleRelation **aRelation,
nsIContent *aRootContent,
nsIContent *aContent,
nsIAtom *aIDRefsAttr)
{
nsCOMPtr<nsIArray> elms;
nsCoreUtils::GetElementsHavingIDRefsAttr(aRootContent, aContent, aIDRefsAttr,
getter_AddRefs(elms));
if (!elms)
return NS_OK_NO_RELATION_TARGET;
PRUint32 count = 0;
nsresult rv = elms->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(elms, idx, &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = AddTargetFromContent(aRelationType, aRelation, content);
NS_ENSURE_SUCCESS(rv, rv);
}
return NS_OK;
}

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

@ -119,42 +119,6 @@ public:
nsIAccessibleRelation **aRelation,
nsIContent *aContent, nsIAtom *aAttr);
/**
* Create the relation if the given relation is null and add the target to it
* found in neighbour tree.
*
* @param aRelationType [in] relation type
* @param aRelation [in, out] relation object
* @param aContent [in] node defining neighbour tree
* @param aNeighboutAttr [in] IDRef attribute of the node in neighbour
* tree pointing to node defining neighbour tree
* @param aNeighboutTagName [in, optional] tag name of the node in neighbour
* tree having IDRef attribute pointed by previous
* argument
*/
static nsresult AddTargetFromNeighbour(PRUint32 aRelationType,
nsIAccessibleRelation **aRelation,
nsIContent *aContent,
nsIAtom *aNeighboutAttr,
nsIAtom *aNeighboutTagName = nsnull);
/**
* Create the relation if the given relation is null and add the targets to it
* that have IDRefs attribute pointing to the given node.
*
* @param aRelationType [in] relation type
* @param aRelation [in, out] relation object
* @param aRootContent [in] root node we search inside of
* @param aContent [in] node having ID
* @param aIDRefsAttr [in] IDRefs attribute
*/
static nsresult
AddTargetFromChildrenHavingIDRefsAttr(PRUint32 aRelationType,
nsIAccessibleRelation **aRelation,
nsIContent *aRootContent,
nsIContent *aContent,
nsIAtom *aIDRefsAttr);
/**
* Query nsAccessibleRelation from the given nsIAccessibleRelation.
*/

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

@ -416,7 +416,7 @@ nsTextEquivUtils::IsWhitespace(PRUnichar aChar)
PRUint32 nsTextEquivUtils::gRoleToNameRulesMap[] =
{
eNoRule, // ROLE_NOTHING
eFromSubtreeIfRec, // ROLE_NOTHING
eNoRule, // ROLE_TITLEBAR
eNoRule, // ROLE_MENUBAR
eNoRule, // ROLE_SCROLLBAR

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

@ -47,6 +47,7 @@ DIRS = \
attributes \
events \
hyperlink \
name \
relations \
selectable \
states \
@ -72,12 +73,8 @@ _TEST_FILES =\
events.js \
grid.js \
layout.js \
name.css \
name.js \
name.xbl \
name_nsRootAcc_wnd.xul \
namerules.xml \
nsIAccessible_selects.js \
nsIAccessible_selects.js \
relations.js \
role.js \
selectable.js \
@ -101,12 +98,7 @@ _TEST_FILES =\
$(warning test_elm_media.html temporarily disabled) \
test_elm_nsApplicationAcc.html \
test_elm_plugin.html \
test_name.html \
test_name.xul \
test_name_button.html \
test_name_link.html \
test_name_markup.html \
test_name_nsRootAcc.xul \
test_keys.html \
$(warning test_nsIAccessible_comboboxes.xul temporarily disabled) \
test_nsIAccessible_selects.html \
test_nsIAccessible_focus.html \

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

@ -51,6 +51,7 @@ _TEST_FILES =\
focus.html \
scroll.html \
test_aria_alert.html \
test_aria_menu.html \
test_aria_statechange.html \
test_attrs.html \
test_caretmove.html \

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

@ -28,6 +28,13 @@
gOpenerWnd.SimpleTest.is(aExpected, aActual, aMsg);
}
function testStates(aAccOrElmOrID, aState, aExtraState, aAbsentState,
aAbsentExtraState)
{
gOpenerWnd.testStates(aAccOrElmOrID, aState, aExtraState, aAbsentState,
aAbsentExtraState);
}
var invokerChecker = gOpenerWnd.invokerChecker;
const STATE_BUSY = gOpenerWnd.STATE_BUSY;
@ -91,6 +98,9 @@
is(event.state, STATE_BUSY, "Wrong state of statechange event.");
is(event.isEnabled(), aIsEnabled,
"Wrong value of state of statechange event");
testStates(event.accessible, (aIsEnabled ? STATE_BUSY : 0), 0,
(aIsEnabled ? 0 : STATE_BUSY), 0);
}
}

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

@ -0,0 +1,88 @@
<html>
<head>
<title>ARIA menu events testing</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="../states.js"></script>
<script type="application/javascript"
src="../events.js"></script>
<script type="application/javascript">
function showMenu(aID, aViaDisplayStyle)
{
this.DOMNode = getNode(aID);
this.invoke = function showMenu_invoke()
{
if (aViaDisplayStyle)
this.DOMNode.style.display = "block";
else
this.DOMNode.style.visibility = "visible";
};
this.getID = function showMenu_getID()
{
return "Show ARIA menu " + aID + " by " +
(aViaDisplayStyle ? "display" : "visibility") + " style tricks";
};
}
////////////////////////////////////////////////////////////////////////////
// Do tests
var gQueue = null;
//gA11yEventDumpID = "eventdump";
function doTests()
{
gQueue = new eventQueue(EVENT_MENUPOPUP_START);
gQueue.push(new showMenu("menu1", true));
gQueue.push(new showMenu("menu2", false));
gQueue.invoke(); // Will call SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
addA11yLoadEvent(doTests);
</script>
</head>
<body>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=606207"
title="Dojo dropdown buttons are broken">
Mozilla Bug 606207
</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
<div id="menu1" role="menu" style="display: none;">
<div role="menuitem">menuitem1.1</div>
<div role="menuitem">menuitem1.2</div>
</div>
<div id="menu2" role="menu" style="visibility: hidden;">
<div role="menuitem">menuitem2.1</div>
<div role="menuitem">menuitem2.2</div>
</div>
<div id="eventdump"></div>
</body>
</html>

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

@ -17,6 +17,8 @@
src="../common.js"></script>
<script type="application/javascript"
src="../role.js"></script>
<script type="application/javascript"
src="../states.js"></script>
<script type="application/javascript"
src="../events.js"></script>

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

@ -60,7 +60,7 @@
this.invoke = function invalidInput_invoke() {
// Note: this should fire an EVENT_STATE_CHANGE
this.DOMNode.value = "I am too long";
this.DOMNode.value = "I am not an email";
};
this.check = function invalidInput_check() {
@ -88,7 +88,7 @@
gQueue.push(new makeEditableDoc(doc));
// invalid state change
gQueue.push(new invalidInput("maxlength"));
gQueue.push(new invalidInput("email"));
gQueue.invoke(); // Will call SimpleTest.finish();
}
@ -120,7 +120,7 @@
<iframe id="iframe"></iframe>
</div>
<input id="maxlength" maxlength="1">
<input id="email" type='email'>
<div id="eventdump"></div>
</body>

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

@ -1,11 +0,0 @@
box.first {
-moz-binding: url('name.xbl#first');
}
.second {
-moz-binding: url('name.xbl#second');
}
.third {
-moz-binding: url('name.xbl#third');
}

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

@ -1,3 +1,6 @@
/**
* Test accessible name for the given accessible identifier.
*/
function testName(aAccOrElmOrID, aName, aMsg)
{
var msg = aMsg ? aMsg : "";
@ -14,271 +17,3 @@ function testName(aAccOrElmOrID, aName, aMsg)
}
return acc;
}
////////////////////////////////////////////////////////////////////////////////
// Name tests described by "namerules.xml" file.
var gNameRulesFileURL = "namerules.xml";
var gRuleDoc = null;
/**
* Start name tests. Run through markup elements and test names for test
* element (see namerules.xml for details).
*/
function testNames()
{
var request = new XMLHttpRequest();
request.open("get", gNameRulesFileURL, false);
request.send();
gRuleDoc = request.responseXML;
var markupElms = evaluateXPath(gRuleDoc, "//rules/rulesample/markup");
gTestIterator.iterateMarkups(markupElms);
}
////////////////////////////////////////////////////////////////////////////////
// Private section.
/**
* Helper class to interate through name tests.
*/
var gTestIterator =
{
iterateMarkups: function gTestIterator_iterateMarkups(aMarkupElms)
{
this.markupElms = aMarkupElms;
this.iterateNext();
},
iterateRules: function gTestIterator_iterateRules(aElm, aContainer, aRuleElms)
{
this.ruleElms = aRuleElms;
this.elm = aElm;
this.container = aContainer;
this.iterateNext();
},
iterateNext: function gTestIterator_iterateNext()
{
if (this.markupIdx == -1) {
this.markupIdx++;
testNamesForMarkup(this.markupElms[this.markupIdx]);
return;
}
this.ruleIdx++;
if (this.ruleIdx == this.ruleElms.length) {
this.markupIdx++;
if (this.markupIdx == this.markupElms.length) {
SimpleTest.finish();
return;
}
document.body.removeChild(this.container);
this.ruleIdx = -1;
testNamesForMarkup(this.markupElms[this.markupIdx]);
return;
}
testNameForRule(this.elm, this.ruleElms[this.ruleIdx]);
},
markupElms: null,
markupIdx: -1,
ruleElms: null,
ruleIdx: -1,
elm: null,
container: null
};
/**
* Process every 'markup' element and test names for it. Used by testNames
* function.
*/
function testNamesForMarkup(aMarkupElm)
{
var div = document.createElement("div");
div.setAttribute("id", "test");
var child = aMarkupElm.firstChild;
while (child) {
var newChild = document.importNode(child, true);
div.appendChild(newChild);
child = child.nextSibling;
}
waitForEvent(EVENT_REORDER, document, testNamesForMarkupRules,
null, aMarkupElm, div);
document.body.appendChild(div);
}
function testNamesForMarkupRules(aMarkupElm, aContainer)
{
ensureAccessibleTree(aContainer);
var serializer = new XMLSerializer();
var expr = "//html/body/div[@id='test']/" + aMarkupElm.getAttribute("ref");
var elms = evaluateXPath(document, expr, htmlDocResolver);
var ruleId = aMarkupElm.getAttribute("ruleset");
var ruleElms = getRuleElmsByRulesetId(ruleId);
gTestIterator.iterateRules(elms[0], aContainer, ruleElms);
}
/**
* Test name for current rule and current 'markup' element. Used by
* testNamesForMarkup function.
*/
function testNameForRule(aElm, aRuleElm)
{
if (aRuleElm.hasAttribute("attr"))
testNameForAttrRule(aElm, aRuleElm);
else if (aRuleElm.hasAttribute("elm") && aRuleElm.hasAttribute("elmattr"))
testNameForElmRule(aElm, aRuleElm);
else if (aRuleElm.getAttribute("fromsubtree") == "true")
testNameForSubtreeRule(aElm, aRuleElm);
}
function testNameForAttrRule(aElm, aRule)
{
var name = "";
var attr = aRule.getAttribute("attr");
var attrValue = aElm.getAttribute(attr);
var type = aRule.getAttribute("type");
if (type == "string") {
name = attrValue;
} else if (type == "ref") {
var ids = attrValue.split(/\s+/);
for (var idx = 0; idx < ids.length; idx++) {
var labelElm = getNode(ids[idx]);
if (name != "")
name += " ";
name += labelElm.getAttribute("a11yname");
}
}
var msg = "Attribute '" + attr + "' test. ";
testName(aElm, name, msg);
aElm.removeAttribute(attr);
gTestIterator.iterateNext();
}
function testNameForElmRule(aElm, aRule)
{
var elm = aRule.getAttribute("elm");
var elmattr = aRule.getAttribute("elmattr");
var filter = {
acceptNode: function filter_acceptNode(aNode)
{
if (aNode.localName == this.mLocalName &&
aNode.getAttribute(this.mAttrName) == this.mAttrValue)
return NodeFilter.FILTER_ACCEPT;
return NodeFilter.FILTER_SKIP;
},
mLocalName: elm,
mAttrName: elmattr,
mAttrValue: aElm.getAttribute("id")
};
var treeWalker = document.createTreeWalker(document.body,
NodeFilter.SHOW_ELEMENT,
filter, false);
var labelElm = treeWalker.nextNode();
var msg = "Element '" + elm + "' test.";
testName(aElm, labelElm.getAttribute("a11yname"), msg);
var parentNode = labelElm.parentNode;
waitForEvent(EVENT_REORDER, parentNode,
gTestIterator.iterateNext, gTestIterator);
parentNode.removeChild(labelElm);
}
function testNameForSubtreeRule(aElm, aRule)
{
var msg = "From subtree test.";
testName(aElm, aElm.getAttribute("a11yname"), msg);
waitForEvent(EVENT_REORDER, aElm, gTestIterator.iterateNext, gTestIterator);
while (aElm.firstChild)
aElm.removeChild(aElm.firstChild);
}
/**
* Return array of 'rule' elements. Used in conjunction with
* getRuleElmsFromRulesetElm() function.
*/
function getRuleElmsByRulesetId(aRulesetId)
{
var expr = "//rules/ruledfn/ruleset[@id='" + aRulesetId + "']";
var rulesetElm = evaluateXPath(gRuleDoc, expr);
return getRuleElmsFromRulesetElm(rulesetElm[0]);
}
function getRuleElmsFromRulesetElm(aRulesetElm)
{
var rulesetId = aRulesetElm.getAttribute("ref");
if (rulesetId)
return getRuleElmsByRulesetId(rulesetId);
var ruleElms = [];
var child = aRulesetElm.firstChild;
while (child) {
if (child.localName == "ruleset")
ruleElms = ruleElms.concat(getRuleElmsFromRulesetElm(child));
if (child.localName == "rule")
ruleElms.push(child);
child = child.nextSibling;
}
return ruleElms;
}
/**
* Helper method to evaluate xpath expression.
*/
function evaluateXPath(aNode, aExpr, aResolver)
{
var xpe = new XPathEvaluator();
var resolver = aResolver;
if (!resolver) {
var node = aNode.ownerDocument == null ?
aNode.documentElement : aNode.ownerDocument.documentElement;
resolver = xpe.createNSResolver(node);
}
var result = xpe.evaluate(aExpr, aNode, resolver, 0, null);
var found = [];
var res;
while (res = result.iterateNext())
found.push(res);
return found;
}
function htmlDocResolver(aPrefix) {
var ns = {
'html' : 'http://www.w3.org/1999/xhtml'
};
return ns[aPrefix] || null;
}

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

@ -0,0 +1,63 @@
#
# ***** 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
# Mozilla Foundation.
# Portions created by the Initial Developer are Copyright (C) 2010
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Alexander Surkov <surkov.alexander@gmail.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 *****
DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
relativesrcdir = accessible/name
include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/rules.mk
_TEST_FILES =\
general.css \
general.xbl \
markup.js \
nsRootAcc_wnd.xul \
test_button.html \
test_general.html \
test_general.xul \
test_link.html \
test_markup.html \
test_nsRootAcc.xul \
markuprules.xml \
$(NULL)
libs:: $(_TEST_FILES)
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/a11y/$(relativesrcdir)

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

@ -0,0 +1,11 @@
box.first {
-moz-binding: url('general.xbl#first');
}
.second {
-moz-binding: url('general.xbl#second');
}
.third {
-moz-binding: url('general.xbl#third');
}

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

@ -0,0 +1,267 @@
////////////////////////////////////////////////////////////////////////////////
// Name tests described by "markuprules.xml" file.
var gNameRulesFileURL = "markuprules.xml";
var gRuleDoc = null;
/**
* Start name tests. Run through markup elements and test names for test
* element (see namerules.xml for details).
*/
function testNames()
{
var request = new XMLHttpRequest();
request.open("get", gNameRulesFileURL, false);
request.send();
gRuleDoc = request.responseXML;
var markupElms = evaluateXPath(gRuleDoc, "//rules/rulesample/markup");
gTestIterator.iterateMarkups(markupElms);
}
////////////////////////////////////////////////////////////////////////////////
// Private section.
/**
* Helper class to interate through name tests.
*/
var gTestIterator =
{
iterateMarkups: function gTestIterator_iterateMarkups(aMarkupElms)
{
this.markupElms = aMarkupElms;
this.iterateNext();
},
iterateRules: function gTestIterator_iterateRules(aElm, aContainer, aRuleElms)
{
this.ruleElms = aRuleElms;
this.elm = aElm;
this.container = aContainer;
this.iterateNext();
},
iterateNext: function gTestIterator_iterateNext()
{
if (this.markupIdx == -1) {
this.markupIdx++;
testNamesForMarkup(this.markupElms[this.markupIdx]);
return;
}
this.ruleIdx++;
if (this.ruleIdx == this.ruleElms.length) {
this.markupIdx++;
if (this.markupIdx == this.markupElms.length) {
SimpleTest.finish();
return;
}
document.body.removeChild(this.container);
this.ruleIdx = -1;
testNamesForMarkup(this.markupElms[this.markupIdx]);
return;
}
testNameForRule(this.elm, this.ruleElms[this.ruleIdx]);
},
markupElms: null,
markupIdx: -1,
ruleElms: null,
ruleIdx: -1,
elm: null,
container: null
};
/**
* Process every 'markup' element and test names for it. Used by testNames
* function.
*/
function testNamesForMarkup(aMarkupElm)
{
var div = document.createElement("div");
div.setAttribute("id", "test");
var child = aMarkupElm.firstChild;
while (child) {
var newChild = document.importNode(child, true);
div.appendChild(newChild);
child = child.nextSibling;
}
waitForEvent(EVENT_REORDER, document, testNamesForMarkupRules,
null, aMarkupElm, div);
document.body.appendChild(div);
}
function testNamesForMarkupRules(aMarkupElm, aContainer)
{
ensureAccessibleTree(aContainer);
var serializer = new XMLSerializer();
var expr = "//html/body/div[@id='test']/" + aMarkupElm.getAttribute("ref");
var elms = evaluateXPath(document, expr, htmlDocResolver);
var ruleId = aMarkupElm.getAttribute("ruleset");
var ruleElms = getRuleElmsByRulesetId(ruleId);
gTestIterator.iterateRules(elms[0], aContainer, ruleElms);
}
/**
* Test name for current rule and current 'markup' element. Used by
* testNamesForMarkup function.
*/
function testNameForRule(aElm, aRuleElm)
{
if (aRuleElm.hasAttribute("attr"))
testNameForAttrRule(aElm, aRuleElm);
else if (aRuleElm.hasAttribute("elm") && aRuleElm.hasAttribute("elmattr"))
testNameForElmRule(aElm, aRuleElm);
else if (aRuleElm.getAttribute("fromsubtree") == "true")
testNameForSubtreeRule(aElm, aRuleElm);
}
function testNameForAttrRule(aElm, aRule)
{
var name = "";
var attr = aRule.getAttribute("attr");
var attrValue = aElm.getAttribute(attr);
var type = aRule.getAttribute("type");
if (type == "string") {
name = attrValue;
} else if (type == "ref") {
var ids = attrValue.split(/\s+/);
for (var idx = 0; idx < ids.length; idx++) {
var labelElm = getNode(ids[idx]);
if (name != "")
name += " ";
name += labelElm.getAttribute("a11yname");
}
}
var msg = "Attribute '" + attr + "' test. ";
testName(aElm, name, msg);
aElm.removeAttribute(attr);
gTestIterator.iterateNext();
}
function testNameForElmRule(aElm, aRule)
{
var elm = aRule.getAttribute("elm");
var elmattr = aRule.getAttribute("elmattr");
var filter = {
acceptNode: function filter_acceptNode(aNode)
{
if (aNode.localName == this.mLocalName &&
aNode.getAttribute(this.mAttrName) == this.mAttrValue)
return NodeFilter.FILTER_ACCEPT;
return NodeFilter.FILTER_SKIP;
},
mLocalName: elm,
mAttrName: elmattr,
mAttrValue: aElm.getAttribute("id")
};
var treeWalker = document.createTreeWalker(document.body,
NodeFilter.SHOW_ELEMENT,
filter, false);
var labelElm = treeWalker.nextNode();
var msg = "Element '" + elm + "' test.";
testName(aElm, labelElm.getAttribute("a11yname"), msg);
var parentNode = labelElm.parentNode;
waitForEvent(EVENT_REORDER, parentNode,
gTestIterator.iterateNext, gTestIterator);
parentNode.removeChild(labelElm);
}
function testNameForSubtreeRule(aElm, aRule)
{
var msg = "From subtree test.";
testName(aElm, aElm.getAttribute("a11yname"), msg);
waitForEvent(EVENT_REORDER, aElm, gTestIterator.iterateNext, gTestIterator);
while (aElm.firstChild)
aElm.removeChild(aElm.firstChild);
}
/**
* Return array of 'rule' elements. Used in conjunction with
* getRuleElmsFromRulesetElm() function.
*/
function getRuleElmsByRulesetId(aRulesetId)
{
var expr = "//rules/ruledfn/ruleset[@id='" + aRulesetId + "']";
var rulesetElm = evaluateXPath(gRuleDoc, expr);
return getRuleElmsFromRulesetElm(rulesetElm[0]);
}
function getRuleElmsFromRulesetElm(aRulesetElm)
{
var rulesetId = aRulesetElm.getAttribute("ref");
if (rulesetId)
return getRuleElmsByRulesetId(rulesetId);
var ruleElms = [];
var child = aRulesetElm.firstChild;
while (child) {
if (child.localName == "ruleset")
ruleElms = ruleElms.concat(getRuleElmsFromRulesetElm(child));
if (child.localName == "rule")
ruleElms.push(child);
child = child.nextSibling;
}
return ruleElms;
}
/**
* Helper method to evaluate xpath expression.
*/
function evaluateXPath(aNode, aExpr, aResolver)
{
var xpe = new XPathEvaluator();
var resolver = aResolver;
if (!resolver) {
var node = aNode.ownerDocument == null ?
aNode.documentElement : aNode.ownerDocument.documentElement;
resolver = xpe.createNSResolver(node);
}
var result = xpe.evaluate(aExpr, aNode, resolver, 0, null);
var found = [];
var res;
while (res = result.iterateNext())
found.push(res);
return found;
}
function htmlDocResolver(aPrefix) {
var ns = {
'html' : 'http://www.w3.org/1999/xhtml'
};
return ns[aPrefix] || null;
}

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

@ -10,9 +10,9 @@
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript"
src="common.js"></script>
src="../common.js"></script>
<script type="application/javascript"
src="name.js"></script>
src="../name.js"></script>
<script type="application/javascript">
function doTest()

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

@ -11,9 +11,9 @@
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript"
src="common.js"></script>
src="../common.js"></script>
<script type="application/javascript"
src="name.js"></script>
src="../name.js"></script>
<script type="application/javascript">
function doTest()
@ -109,13 +109,16 @@
testName("btn_label_inform", "in form");
// The label element is placed outside of form where the button is.
// Do not take into account the label.
testName("btn_label_outform", "12");
// Take into account the label.
testName("btn_label_outform", "out form");
// The label element and the button are in the same document. Gets the
// name from the label subtree.
testName("btn_label_indocument", "in document");
// Multiple label elements for single button
testName("btn_label_multi", "label1label2");
//////////////////////////////////////////////////////////////////////////
// name from children
@ -128,6 +131,9 @@
// visible children (bug 443081).
testName("lb_opt1_children_hidden", "i am visible");
// Get the name from subtree of menuitem crossing role nothing to get
// the name from its children.
testName("tablemenuitem", "menuitem 1");
//////////////////////////////////////////////////////////////////////////
// title attribute
@ -360,6 +366,11 @@
<label for="btn_label_indocument">in document</label>
<button id="btn_label_indocument">13</button>
<!-- multiple label elements for single button -->
<label for="btn_label_multi">label1</label>
<label for="btn_label_multi">label2</label>
<button id="btn_label_multi">button</button>
<!-- name from children -->
<span id="btn_children" role="button">14</span>
@ -371,6 +382,15 @@
</div>
</div>
<table role="menu">
<tr role="menuitem" id="tablemenuitem">
<td>menuitem 1</td>
</tr>
<tr role="menuitem">
<td>menuitem 2</td>
</tr>
</table>
<!-- name from title attribute -->
<span id="btn_title" role="group" title="title">15</span>

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

@ -2,7 +2,7 @@
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
type="text/css"?>
<?xml-stylesheet href="name.css"
<?xml-stylesheet href="general.css"
type="text/css"?>
@ -15,11 +15,11 @@
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
<script type="application/javascript"
src="common.js"></script>
src="../common.js"></script>
<script type="application/javascript"
src="role.js"></script>
src="../role.js"></script>
<script type="application/javascript"
src="name.js"></script>
src="../name.js"></script>
<script type="application/javascript">
<![CDATA[
@ -106,6 +106,9 @@
// The label and button are siblings.
testName("btn_label_3", "label3");
// Multiple labels for single button: XUL button takes the last one.
testName("btn_label_4", "label5");
//////////////////////////////////////////////////////////////////////////
// Name from the label element in anonymous content (see bug 362365).
@ -296,6 +299,10 @@
</box>
<label control="btn_label_3">label3</label>
<button id="btn_label_3"/>
<label control="btn_label_4">label4</label>
<label control="btn_label_4">label5</label>
<button id="btn_label_4"/>
</hbox>
<!-- label element, anonymous content -->

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

@ -12,9 +12,9 @@
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript"
src="common.js"></script>
src="../common.js"></script>
<script type="application/javascript"
src="name.js"></script>
src="../name.js"></script>
<script type="application/javascript">
function doTest()

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

@ -10,11 +10,14 @@
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript"
src="common.js"></script>
src="../common.js"></script>
<script type="application/javascript"
src="events.js"></script>
src="../events.js"></script>
<script type="application/javascript"
src="name.js"></script>
src="../name.js"></script>
<script type="application/javascript"
src="markup.js"></script>
<script type="application/javascript">
// gA11yEventDumpID = "eventdump";

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

@ -14,11 +14,11 @@
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
<script type="application/javascript"
src="common.js"></script>
src="../common.js"></script>
<script type="application/javascript"
src="role.js"></script>
src="../role.js"></script>
<script type="application/javascript"
src="events.js"></script>
src="../events.js"></script>
<script type="application/javascript">
<![CDATA[
@ -36,7 +36,7 @@
return;
}
var w = window.openDialog("name_nsRootAcc_wnd.xul",
var w = window.openDialog("nsRootAcc_wnd.xul",
"nsRootAcc_name_test",
"chrome,width=600,height=600");
}

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

@ -23,6 +23,12 @@
testRelation("label1", RELATION_LABEL_FOR, "checkbox1");
testRelation("checkbox1", RELATION_LABELLED_BY, "label1");
// html:label@for, multiple
testRelation("label1_1", RELATION_LABEL_FOR, "checkbox1_1");
testRelation("label1_2", RELATION_LABEL_FOR, "checkbox1_1");
testRelation("checkbox1_1", RELATION_LABELLED_BY,
[ "label1_1", "label1_2" ]);
// aria-labelledby
testRelation("label2", RELATION_LABEL_FOR, "checkbox2");
testRelation("checkbox2", RELATION_LABELLED_BY, "label2");
@ -90,8 +96,9 @@
// output 'for' relations
testRelation("output", RELATION_CONTROLLED_BY, ["input", "input2"]);
testRelation("input", RELATION_CONTROLLER_FOR, "output");
testRelation("input2", RELATION_CONTROLLER_FOR, "output");
testRelation("output2", RELATION_CONTROLLED_BY, ["input", "input2"]);
testRelation("input", RELATION_CONTROLLER_FOR, ["output", "output2"]);
testRelation("input2", RELATION_CONTROLLER_FOR, ["output", "output2"]);
// 'described by'/'description for' relation for html:table and
// html:caption
@ -146,6 +153,10 @@
<label id="label1" for="checkbox1">label</label>
<input id="checkbox1" />
<label id="label1_1" for="checkbox1_1">label</label>
<label id="label1_2" for="checkbox1_1">label</label>
<input id="checkbox1_1" />
<span id="label2">label</span>
<span role="checkbox" id="checkbox2" aria-labelledby="label2"></span>
@ -207,6 +218,7 @@
<input id="input2" />
<input type="submit" id="submit" />
<output id="output" style="display:block" for="input input2"></output>
<output id="output2" for="input input2"></output>
</form>
<table id="table">

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

@ -26,6 +26,12 @@
testRelation("label1", RELATION_LABEL_FOR, "checkbox1");
testRelation("checkbox1", RELATION_LABELLED_BY, "label1");
// xul:label@control, multiple
testRelation("label1_1", RELATION_LABEL_FOR, "checkbox1_1");
testRelation("label1_2", RELATION_LABEL_FOR, "checkbox1_1");
testRelation("checkbox1_1", RELATION_LABELLED_BY,
[ "label1_1", "label1_2" ]);
// aria-labelledby
testRelation("label2", RELATION_LABEL_FOR, "checkbox2");
testRelation("checkbox2", RELATION_LABELLED_BY, "label2");
@ -48,6 +54,12 @@
testRelation("descr4", RELATION_DESCRIPTION_FOR, "checkbox6");
testRelation("checkbox6", RELATION_DESCRIBED_BY, "descr4");
// xul:description@control, multiple
testRelation("descr5", RELATION_DESCRIPTION_FOR, "checkbox7");
testRelation("descr6", RELATION_DESCRIPTION_FOR, "checkbox7");
testRelation("checkbox7", RELATION_DESCRIBED_BY,
[ "descr5", "descr6" ]);
// aria_owns, multiple relations
testRelation("treeitem1", RELATION_NODE_CHILD_OF, "tree");
testRelation("treeitem2", RELATION_NODE_CHILD_OF, "tree");
@ -145,6 +157,10 @@
<label id="label1" control="checkbox1">label</label>
<checkbox id="checkbox1"/>
<label id="label1_1" control="checkbox1_1">label</label>
<label id="label1_2" control="checkbox1_1">label</label>
<checkbox id="checkbox1_1"/>
<description id="label2">label</description>
<description role="checkbox" id="checkbox2" aria-labelledby="label2"/>
@ -164,6 +180,10 @@
<description id="descr4" control="checkbox6">description</description>
<checkbox id="checkbox6"/>
<description id="descr5" control="checkbox7">description</description>
<description id="descr6" control="checkbox7">description</description>
<checkbox id="checkbox7"/>
<description role="treeitem" id="treeitem1">Yellow</description>
<description role="treeitem" id="treeitem2">Orange</description>
<vbox id="tree" role="tree" aria-owns="treeitem1 treeitem2">

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

@ -38,17 +38,30 @@
testStates("f_input", STATE_UNAVAILABLE);
testStates("f_input_disabled", STATE_UNAVAILABLE);
/**
* maxlength doesn't make the element invalid until bug 613016 and bug 613019
* are fixed. Commenting out related lines and adding a todo to make sure
* it will be uncommented as soon as possible.
*/
var todoInput = document.createElement("input");
todoInput.maxLength = '2';
todoInput.value = 'foo';
todo(!todoInput.validity.valid,
"input should be invalid because of maxlength");
// invalid/valid state
var invalid = ["maxlength","pattern","email","url"];
document.getElementById("maxlength").value = "i am too long";
//var invalid = ["maxlength","pattern","email","url"];
//document.getElementById("maxlength").value = "i am too long";
var invalid = ["pattern","email","url"];
for (i in invalid) {
testStates(invalid[i], STATE_INVALID);
testStates(invalid[i] + "2", 0, 0, STATE_INVALID);
}
// invalid/valid state
var invalid = ["maxlength","pattern","email","url"];
document.getElementById("maxlength").value = "i am too long";
//var invalid = ["maxlength","pattern","email","url"];
//document.getElementById("maxlength").value = "i am too long";
var invalid = ["pattern","email","url"];
for (i in invalid) {
testStates(invalid[i], STATE_INVALID);
testStates(invalid[i] + "2", 0, 0, STATE_INVALID);

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

@ -0,0 +1,59 @@
<html>
<head>
<title>Keyboard shortcuts tests</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">
function testKeyboardShortcut(aAccOrElmOrID, aKey)
{
var acc = getAccessible(aAccOrElmOrID);
if (!acc)
return;
is(acc.keyboardShortcut, aKey,
"Wrong keyboard shortcut on " + prettyName(aAccOrElmOrID));
}
function doTest()
{
testKeyboardShortcut("input1", "");
testKeyboardShortcut("input2", "Alt+Shift+b");
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
addA11yLoadEvent(doTest);
</script>
</head>
<body>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=381599"
title="Inverse relations cache">
Mozilla Bug 381599
</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
<label accesskey="a">
<input id="input1"/>
</label>
<label accesskey="b" for="input2">
<input id="input2"/>
</body>
</html>

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

@ -46,7 +46,10 @@ include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/rules.mk
_TEST_FILES = \
doc.html \
test_doc.html \
test_singleline.html \
test_whitespaces.html \
$(NULL)
libs:: $(_TEST_FILES)

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

@ -0,0 +1,9 @@
<!DOCTYPE html>
<html>
<head>
<script type="application/javascript">
document.documentElement.appendChild(document.createTextNode("outbody"));
</script>
</head>
<body>inbody</body>
</html>

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

@ -0,0 +1,42 @@
<!DOCTYPE html>
<html>
<head>
<title>nsIAccessibleText getText related function tests for document accessible</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="../text.js"></script>
<script type="application/javascript">
function doTest()
{
testText([getNode("iframe").contentDocument], 0, 14, "outbody inbody");
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
addA11yLoadEvent(doTest);
</script>
</head>
<body>
<a target="_blank"
title="Elements appended outside the body aren't accessible"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=608887">Mozilla Bug 608887</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
<iframe id="iframe" src="doc.html"></iframe>
</body>
</html>

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

@ -0,0 +1,630 @@
<!DOCTYPE html>
<html>
<head>
<title>getText... methods tests on string with whitespaces for plain text containers</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="../text.js"></script>
<script type="application/javascript">
function doTest()
{
// Tests for elements rendering the original sring
var IDs = ["input", "div", "editable", "textarea"];
// __B__r__a__v__e__ __S__i__r__ __ __R__o__b__i__n__ __ __ __r__a__n
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
////////////////////////////////////////////////////////////////////////
// getText
testText(IDs, 0, 1, "B");
testText(IDs, 5, 6, " ");
testText(IDs, 9, 11, " ");
testText(IDs, 16, 19, " ");
testText(IDs, 0, 22, "Brave Sir Robin ran");
////////////////////////////////////////////////////////////////////////
// getTextAfterOffset
// BOUNDARY_CHAR
testTextAfterOffset(0, BOUNDARY_CHAR, "r", 1, 2,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(1, BOUNDARY_CHAR, "a", 2, 3,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(4, BOUNDARY_CHAR, " ", 5, 6,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(5, BOUNDARY_CHAR, "S", 6, 7,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(8, BOUNDARY_CHAR, " ", 9, 10,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(9, BOUNDARY_CHAR, " ", 10, 11,
"input", kOk, kTodo, kTodo,
"div", kOk, kTodo, kTodo,
"editable", kOk, kTodo, kTodo,
"textarea", kOk, kTodo, kTodo);
testTextAfterOffset(10, BOUNDARY_CHAR, "R", 11, 12,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(15, BOUNDARY_CHAR, " ", 16, 17,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(16, BOUNDARY_CHAR, " ", 17, 18,
"input", kOk, kTodo, kTodo,
"div", kOk, kTodo, kTodo,
"editable", kOk, kTodo, kTodo,
"textarea", kOk, kTodo, kTodo);
testTextAfterOffset(17, BOUNDARY_CHAR, " ", 18, 19,
"input", kOk, kTodo, kTodo,
"div", kOk, kTodo, kTodo,
"editable", kOk, kTodo, kTodo,
"textarea", kOk, kTodo, kTodo);
testTextAfterOffset(18, BOUNDARY_CHAR, "r", 19, 20,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
// BOUNDARY_WORD_START
testTextAfterOffset(0, BOUNDARY_WORD_START, "Sir ", 6, 11,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(5, BOUNDARY_WORD_START, "Sir ", 6, 11,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(6, BOUNDARY_WORD_START, "Robin ", 11, 19,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(9, BOUNDARY_WORD_START, "Robin ", 11, 19,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(10, BOUNDARY_WORD_START, "Robin ", 11, 19,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(11, BOUNDARY_WORD_START, "ran", 19, 22,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(16, BOUNDARY_WORD_START, "ran", 19, 22,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(18, BOUNDARY_WORD_START, "ran", 19, 22,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(19, BOUNDARY_WORD_START, "", 22, 22,
"input", kTodo, kTodo, kOk,
"div", kTodo, kTodo, kOk,
"editable", kTodo, kTodo, kOk,
"textarea", kTodo, kTodo, kTodo);
// BOUNDARY_WORD_END
testTextAfterOffset(0, BOUNDARY_WORD_END, " Sir", 5, 9,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(4, BOUNDARY_WORD_END, " Sir", 5, 9,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(5, BOUNDARY_WORD_END, " Sir", 5, 9,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
testTextAfterOffset(6, BOUNDARY_WORD_END, " Robin", 9, 16,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(8, BOUNDARY_WORD_END, " Robin", 9, 16,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(9, BOUNDARY_WORD_END, " Robin", 9, 16,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
testTextAfterOffset(10, BOUNDARY_WORD_END, " ran", 16, 22,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(11, BOUNDARY_WORD_END, " ran", 16, 22,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(15, BOUNDARY_WORD_END, " ran", 16, 22,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(16, BOUNDARY_WORD_END, " ran", 16, 22,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
testTextAfterOffset(17, BOUNDARY_WORD_END, "", 22, 22,
"input", kTodo, kTodo, kOk,
"div", kTodo, kTodo, kOk,
"editable", kTodo, kTodo, kOk,
"textarea", kTodo, kTodo, kOk);
testTextAfterOffset(18, BOUNDARY_WORD_END, "", 22, 22,
"input", kTodo, kTodo, kOk,
"div", kTodo, kTodo, kOk,
"editable", kTodo, kTodo, kOk,
"textarea", kTodo, kTodo, kOk);
testTextAfterOffset(19, BOUNDARY_WORD_END, "", 22, 22,
"input", kTodo, kTodo, kOk,
"div", kTodo, kTodo, kOk,
"editable", kTodo, kTodo, kOk,
"textarea", kTodo, kTodo, kOk);
testTextAfterOffset(21, BOUNDARY_WORD_END, "", 22, 22,
"input", kTodo, kTodo, kOk,
"div", kTodo, kTodo, kOk,
"editable", kTodo, kTodo, kOk,
"textarea", kTodo, kTodo, kOk);
testTextAfterOffset(22, BOUNDARY_WORD_END, "", 22, 22,
"input", kOk, kTodo, kTodo,
"div", kOk, kTodo, kTodo,
"editable", kOk, kTodo, kTodo,
"textarea", kTodo, kOk, kTodo);
////////////////////////////////////////////////////////////////////////
// getTextBeforeOffset
// BOUNDARY_CHAR
testTextBeforeOffset(0, BOUNDARY_CHAR, "", 0, 0,
"input", kTodo, kOk, kTodo,
"div", kTodo, kOk, kTodo,
"editable", kTodo, kOk, kTodo,
"textarea", kTodo, kOk, kTodo);
testTextBeforeOffset(1, BOUNDARY_CHAR, "B", 0, 1,
"input", kTodo, kOk, kTodo,
"div", kTodo, kOk, kTodo,
"editable", kTodo, kOk, kTodo,
"textarea", kTodo, kOk, kTodo);
testTextBeforeOffset(6, BOUNDARY_CHAR, " ", 5, 6,
"input", kTodo, kOk, kTodo,
"div", kTodo, kOk, kTodo,
"editable", kTodo, kOk, kTodo,
"textarea", kTodo, kOk, kTodo);
testTextBeforeOffset(10, BOUNDARY_CHAR, " ", 9, 10,
"input", kTodo, kOk, kTodo,
"div", kTodo, kOk, kTodo,
"editable", kTodo, kOk, kTodo,
"textarea", kTodo, kOk, kTodo);
testTextBeforeOffset(11, BOUNDARY_CHAR, " ", 10, 11,
"input", kTodo, kOk, kTodo,
"div", kTodo, kOk, kTodo,
"editable", kTodo, kOk, kTodo,
"textarea", kTodo, kOk, kTodo);
testTextBeforeOffset(17, BOUNDARY_CHAR, " ", 16, 17,
"input", kTodo, kOk, kTodo,
"div", kTodo, kOk, kTodo,
"editable", kTodo, kOk, kTodo,
"textarea", kTodo, kOk, kTodo);
testTextBeforeOffset(19, BOUNDARY_CHAR, " ", 18, 19,
"input", kTodo, kOk, kTodo,
"div", kTodo, kOk, kTodo,
"editable", kTodo, kOk, kTodo,
"textarea", kTodo, kOk, kTodo);
// BOUNDARY_WORD_START
testTextBeforeOffset(0, BOUNDARY_WORD_START, "", 0, 0,
"input", kTodo, kOk, kTodo,
"div", kTodo, kOk, kTodo,
"editable", kTodo, kOk, kTodo,
"textarea", kTodo, kOk, kTodo);
testTextBeforeOffset(1, BOUNDARY_WORD_START, "", 0, 0,
"input", kTodo, kOk, kTodo,
"div", kTodo, kOk, kTodo,
"editable", kTodo, kOk, kTodo,
"textarea", kTodo, kOk, kTodo);
testTextBeforeOffset(5, BOUNDARY_WORD_START, "", 0, 0,
"input", kTodo, kOk, kTodo,
"div", kTodo, kOk, kTodo,
"editable", kTodo, kOk, kTodo,
"textarea", kTodo, kOk, kTodo);
testTextBeforeOffset(6, BOUNDARY_WORD_START, "Brave ", 0, 6,
"input", kTodo, kOk, kTodo,
"div", kTodo, kOk, kTodo,
"editable", kTodo, kOk, kTodo,
"textarea", kTodo, kOk, kTodo);
testTextBeforeOffset(9, BOUNDARY_WORD_START, "Brave ", 0, 6,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextBeforeOffset(10, BOUNDARY_WORD_START, "Brave ", 0, 6,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextBeforeOffset(11, BOUNDARY_WORD_START, "Sir ", 6, 11,
"input", kTodo, kOk, kTodo,
"div", kTodo, kOk, kTodo,
"editable", kTodo, kOk, kTodo,
"textarea", kTodo, kOk, kTodo);
testTextBeforeOffset(15, BOUNDARY_WORD_START, "Sir ", 6, 11,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextBeforeOffset(16, BOUNDARY_WORD_START, "Sir ", 6, 11,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextBeforeOffset(17, BOUNDARY_WORD_START, "Sir ", 6, 11,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextBeforeOffset(18, BOUNDARY_WORD_START, "Sir ", 6, 11,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextBeforeOffset(19, BOUNDARY_WORD_START, "Robin ", 11, 19,
"input", kTodo, kOk, kTodo,
"div", kTodo, kOk, kTodo,
"editable", kTodo, kOk, kTodo,
"textarea", kTodo, kOk, kTodo);
testTextBeforeOffset(20, BOUNDARY_WORD_START, "Robin ", 11, 19,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextBeforeOffset(21, BOUNDARY_WORD_START, "Robin ", 11, 19,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
// BOUNDARY_WORD_END
testTextBeforeOffset(0, BOUNDARY_WORD_END, "", 0, 0,
"input", kTodo, kOk, kTodo,
"div", kTodo, kOk, kTodo,
"editable", kTodo, kOk, kTodo,
"textarea", kTodo, kOk, kTodo);
testTextBeforeOffset(1, BOUNDARY_WORD_END, "", 0, 0,
"input", kTodo, kOk, kTodo,
"div", kTodo, kOk, kTodo,
"editable", kTodo, kOk, kTodo,
"textarea", kTodo, kOk, kTodo);
testTextBeforeOffset(4, BOUNDARY_WORD_END, "", 0, 0,
"input", kTodo, kOk, kTodo,
"div", kTodo, kOk, kTodo,
"editable", kTodo, kOk, kTodo,
"textarea", kTodo, kOk, kTodo);
testTextBeforeOffset(5, BOUNDARY_WORD_END, "", 0, 0,
"input", kTodo, kOk, kTodo,
"div", kTodo, kOk, kTodo,
"editable", kTodo, kOk, kTodo,
"textarea", kTodo, kOk, kTodo);
testTextBeforeOffset(6, BOUNDARY_WORD_END, "Brave", 0, 5,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextBeforeOffset(7, BOUNDARY_WORD_END, "Brave", 0, 5,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextBeforeOffset(8, BOUNDARY_WORD_END, "Brave", 0, 5,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextBeforeOffset(9, BOUNDARY_WORD_END, "Brave", 0, 5,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextBeforeOffset(10, BOUNDARY_WORD_END, " Sir", 5, 9,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextBeforeOffset(11, BOUNDARY_WORD_END, " Sir", 5, 9,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextBeforeOffset(15, BOUNDARY_WORD_END, " Sir", 5, 9,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextBeforeOffset(16, BOUNDARY_WORD_END, " Sir", 5, 9,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextBeforeOffset(17, BOUNDARY_WORD_END, " Robin", 9, 16,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextBeforeOffset(18, BOUNDARY_WORD_END, " Robin", 9, 16,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextBeforeOffset(19, BOUNDARY_WORD_END, " Robin", 9, 16,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextBeforeOffset(21, BOUNDARY_WORD_END, " Robin", 9, 16,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextBeforeOffset(22, BOUNDARY_WORD_END, " Robin", 9, 16,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
////////////////////////////////////////////////////////////////////////
// getTextAtOffset
// BOUNDARY_CHAR
testTextAtOffset(0, BOUNDARY_CHAR, "B", 0, 1,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
testTextAtOffset(1, BOUNDARY_CHAR, "r", 1, 2,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
testTextAtOffset(5, BOUNDARY_CHAR, " ", 5, 6,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
testTextAtOffset(9, BOUNDARY_CHAR, " ", 9, 10,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
testTextAtOffset(10, BOUNDARY_CHAR, " ", 10, 11,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
testTextAtOffset(17, BOUNDARY_CHAR, " ", 17, 18,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
// BOUNDARY_WORD_START
testTextAtOffset(0, BOUNDARY_WORD_START, "Brave ", 0, 6,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
testTextAtOffset(5, BOUNDARY_WORD_START, "Brave ", 0, 6,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
testTextAtOffset(6, BOUNDARY_WORD_START, "Sir ", 6, 11,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
testTextAtOffset(8, BOUNDARY_WORD_START, "Sir ", 6, 11,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
testTextAtOffset(9, BOUNDARY_WORD_START, "Sir ", 6, 11,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
testTextAtOffset(10, BOUNDARY_WORD_START, "Sir ", 6, 11,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
testTextAtOffset(11, BOUNDARY_WORD_START, "Robin ", 11, 19,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
testTextAtOffset(15, BOUNDARY_WORD_START, "Robin ", 11, 19,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
testTextAtOffset(16, BOUNDARY_WORD_START, "Robin ", 11, 19,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
testTextAtOffset(17, BOUNDARY_WORD_START, "Robin ", 11, 19,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
testTextAtOffset(18, BOUNDARY_WORD_START, "Robin ", 11, 19,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
testTextAtOffset(19, BOUNDARY_WORD_START, "ran", 19, 22,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kTodo, kOk, kTodo);
testTextAtOffset(21, BOUNDARY_WORD_START, "ran", 19, 22,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kTodo, kOk, kTodo);
testTextAtOffset(22, BOUNDARY_WORD_START, "ran", 19, 22,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kOk, kTodo);
// BOUNDARY_WORD_END
testTextAtOffset(0, BOUNDARY_WORD_END, "Brave", 0, 5,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
testTextAtOffset(4, BOUNDARY_WORD_END, "Brave", 0, 5,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
testTextAtOffset(5, BOUNDARY_WORD_END, "Brave", 0, 5,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAtOffset(6, BOUNDARY_WORD_END, " Sir", 5, 9,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
testTextAtOffset(8, BOUNDARY_WORD_END, " Sir", 5, 9,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
testTextAtOffset(9, BOUNDARY_WORD_END, " Sir", 5, 9,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAtOffset(10, BOUNDARY_WORD_END, " Robin", 9, 16,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
testTextAtOffset(11, BOUNDARY_WORD_END, " Robin", 9, 16,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
testTextAtOffset(15, BOUNDARY_WORD_END, " Robin", 9, 16,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
testTextAtOffset(16, BOUNDARY_WORD_END, " Robin", 9, 16,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAtOffset(17, BOUNDARY_WORD_END, " ran", 16, 22,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
testTextAtOffset(18, BOUNDARY_WORD_END, " ran", 16, 22,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
testTextAtOffset(19, BOUNDARY_WORD_END, " ran", 16, 22,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
testTextAtOffset(20, BOUNDARY_WORD_END, " ran", 16, 22,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
testTextAtOffset(21, BOUNDARY_WORD_END, " ran", 16, 22,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
testTextAtOffset(22, BOUNDARY_WORD_END, " ran", 16, 22,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
addA11yLoadEvent(doTest);
</script>
</head>
<body>
<a target="_blank"
title="getText... methods tests on string with whitespaces for plain text containers"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=610568">Mozilla Bug 610568</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
<input id="input" value="Brave Sir Robin ran"/>
<div id="div">Brave Sir Robin ran</div>
<div id="editable" contenteditable="true">Brave Sir Robin ran</div>
<textarea id="textarea" cols="300">Brave Sir Robin ran</textarea>
</pre>
</body>
</html>

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

@ -46,7 +46,8 @@ include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/rules.mk
_TEST_FILES =\
$(warning test_applicationacc.xul temporarily disabled, see bug 561508) \
dockids.html \
$(warning test_applicationacc.xul temporarily disabled, see bug 561508) \
test_aria_globals.html \
test_aria_imgmap.html \
test_button.xul \
@ -54,6 +55,7 @@ _TEST_FILES =\
test_combobox.xul \
test_cssoverflow.html \
test_dochierarchy.html \
test_dockids.html \
test_filectrl.html \
test_formctrl.html \
test_formctrl.xul \

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

@ -0,0 +1,30 @@
<!doctype html>
<html>
<head>
<link rel="next" href="http://www.mozilla.org">
<style>
head, link, a { display: block; }
link:after { content: "Link to " attr(href); }
</style>
<script>
window.onload = function() {
document.documentElement.appendChild(document.createElement("input"));
var l = document.createElement("link");
l.href = "http://www.mozilla.org";
l.textContent = "Another ";
document.documentElement.appendChild(l);
l = document.createElement("a");
l.href = "http://www.mozilla.org";
l.textContent = "Yet another link to mozilla";
document.documentElement.appendChild(l);
}
</script>
</head>
<body>
Hey, I'm a <body> with three links that are not inside me and an input
that's not inside me.
</body>
</body>
</html>

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

@ -0,0 +1,67 @@
<!DOCTYPE html>
<html>
<head>
<title>Test document hierarchy</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="../role.js"></script>
<script type="application/javascript"
src="../states.js"></script>
<script type="application/javascript">
function doTest()
{
var tree =
{ DOCUMENT: [
{ PARAGRAPH: [ // head
{ PARAGRAPH: [ // link
{ STATICTEXT: [] }, // generated content
{ STATICTEXT: [] } // generated content
] }
] },
{ TEXT_LEAF: [ ] }, // body text
{ ENTRY: [ // input under document element
{ TEXT_LEAF: [ ] }
] },
{ PARAGRAPH: [ // link under document element
{ TEXT_LEAF: [ ] }, // link content
{ STATICTEXT: [ ] }, // generated content
{ STATICTEXT: [ ] } // generated content
] },
{ LINK: [ // anchor under document element
{ TEXT_LEAF: [ ] } // anchor content
] },
] };
testAccessibleTree(getNode("iframe").contentDocument, tree);
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
addA11yLoadEvent(doTest);
</script>
</head>
<body>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=608887"
title="Elements appended outside the body aren't accessible">
Mozilla Bug 608887
</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
<iframe src="dockids.html" id="iframe"></iframe>
</body>
</html>

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

@ -304,6 +304,41 @@
}
}
function insertElmUnderDocElmWhileBodyMissed(aID)
{
this.docNode = getDocNode(aID);
this.inputNode = getDocNode(aID).createElement("input");
this.eventSeq = [
new invokerChecker(EVENT_SHOW, this.inputNode),
new invokerChecker(EVENT_REORDER, this.docNode)
];
this.invoke = function invoke()
{
this.docNode.documentElement.appendChild(this.inputNode);
}
this.finalCheck = function finalCheck()
{
var tree =
{ DOCUMENT: [
{ ENTRY: [
{ TEXT_LEAF: [ ] }
] }
] };
testAccessibleTree(this.docNode, tree);
// Remove aftermath of this test before next test starts.
this.docNode.documentElement.removeChild(this.inputNode);
}
this.getID = function getID()
{
return "Insert element under document element while body is missed.";
}
}
function insertBodyToIFrameDoc(aID)
{
this.__proto__ = new rootContentInserted(aID, "Yo ho ho i butylka roma!");
@ -343,6 +378,7 @@
gQueue.push(new removeHTMLFromIFrameDoc("iframe"));
gQueue.push(new insertHTMLToIFrameDoc("iframe"));
gQueue.push(new removeBodyFromIFrameDoc("iframe"));
gQueue.push(new insertElmUnderDocElmWhileBodyMissed("iframe"));
gQueue.push(new insertBodyToIFrameDoc("iframe"));
gQueue.invoke(); // SimpleTest.finish() will be called in the end
@ -357,6 +393,9 @@
<a target="_blank"
title="Update accessible tree when root element is changed"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=606082">Mozilla Bug 606082</a>
<a target="_blank"
title="Elements inserted outside the body aren't accessible"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=608887">Mozilla Bug 608887</a>
<p id="display"></p>
<div id="content" style="display: none"></div>

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

@ -1037,9 +1037,16 @@ pref("services.sync.prefs.sync.xpinstall.whitelist.required", true);
pref("devtools.errorconsole.enabled", false);
pref("devtools.inspector.enabled", false);
// The last Web Console height. This is initially 0 which means that the Web
// Console will use the default height next time it shows.
// Change to -1 if you do not want the Web Console to remember its last height.
pref("devtools.hud.height", 0);
// Whether the character encoding menu is under the main Firefox button. This
// preference is a string so that localizers can alter it.
pref("browser.menu.showCharacterEncoding", "chrome://browser/locale/browser.properties");
// Allow using tab-modal prompts when possible.
pref("prompts.tab_modal.enabled", true);
// Whether the Panorama should animate going in/out of tabs
pref("browser.panorama.animate_zoom", true);

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

@ -83,6 +83,9 @@ endif
ifneq (,$(filter windows, $(MOZ_WIDGET_TOOLKIT)))
DEFINES += -DCAN_DRAW_IN_TITLEBAR=1
endif
ifneq (,$(filter windows gtk2, $(MOZ_WIDGET_TOOLKIT)))
DEFINES += -DMENUBAR_CAN_AUTOHIDE=1
endif

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

@ -16,7 +16,7 @@ tabbrowser {
#tabbrowser-tabs:not([overflow="true"]) + #new-tab-button,
#tabbrowser-tabs[overflow="true"] > .tabbrowser-arrowscrollbox > .tabs-newtab-button,
#TabsToolbar[currentset]:not([currentset*="tabbrowser-tabs,new-tab-button"]) > #tabbrowser-tabs > .tabbrowser-arrowscrollbox > .tabs-newtab-button,
#navigator-toolbox[customizing="true"] > #TabsToolbar > #tabbrowser-tabs > .tabbrowser-arrowscrollbox > .tabs-newtab-button {
#TabsToolbar[customizing="true"] > #tabbrowser-tabs > .tabbrowser-arrowscrollbox > .tabs-newtab-button {
visibility: collapse;
}
@ -145,9 +145,17 @@ toolbar[mode="icons"] > #reload-button[displaystop] {
-moz-binding: url("chrome://browser/content/urlbarBindings.xml#menuitem-iconic-tooltip");
}
%ifdef MENUBAR_CAN_AUTOHIDE
%ifndef CAN_DRAW_IN_TITLEBAR
#appmenu-toolbar-button > .toolbarbutton-text {
display: -moz-box;
}
%endif
#appmenu_offlineModeRecovery:not([checked=true]) {
display: none;
}
%endif
/* ::::: location bar ::::: */
#urlbar {

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

@ -3434,12 +3434,6 @@ function BrowserCustomizeToolbar()
PlacesToolbarHelper.customizeStart();
BookmarksMenuButton.customizeStart();
let addonBar = document.getElementById("addon-bar");
if (addonBar.collapsed) {
addonBar.wasCollapsed = addonBar.collapsed;
addonBar.collapsed = false;
}
var customizeURL = "chrome://global/content/customizeToolbar.xul";
gCustomizeSheet = getBoolPref("toolbar.customization.usesheet", false);
@ -3498,12 +3492,6 @@ function BrowserToolboxCustomizeDone(aToolboxChanged) {
PlacesToolbarHelper.customizeDone();
BookmarksMenuButton.customizeDone();
let addonBar = document.getElementById("addon-bar");
if (addonBar.wasCollapsed === true) {
addonBar.collapsed = true;
delete addonBar.wasCollapsed;
}
// The url bar splitter state is dependent on whether stop/reload
// and the location bar are combined, so we need this ordering
CombinedStopReload.init();
@ -4750,6 +4738,9 @@ function updateAppButtonDisplay() {
document.documentElement.setAttribute("chromemargin", "0,-1,-1,-1");
else
document.documentElement.removeAttribute("chromemargin");
#else
document.getElementById("appmenu-toolbar-button").hidden =
!displayAppButton;
#endif
}
#endif
@ -7438,6 +7429,13 @@ function getNotificationBox(aWindow) {
return null;
};
function getTabModalPromptBox(aWindow) {
var foundBrowser = gBrowser.getBrowserForDocument(aWindow.document);
if (foundBrowser)
return gBrowser.getTabModalPromptBox(foundBrowser);
return null;
};
/* DEPRECATED */
function getBrowser() gBrowser;
function getNavToolbox() gNavToolbox;

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

@ -764,6 +764,13 @@
</toolbaritem>
</toolbar>
#ifdef MENUBAR_CAN_AUTOHIDE
#ifndef CAN_DRAW_IN_TITLEBAR
#define APPMENU_ON_TABBAR
#endif
#endif
<toolbar id="TabsToolbar"
fullscreentoolbar="true"
customizable="true"
@ -771,9 +778,23 @@
iconsize="small" defaulticonsize="small" lockiconsize="true"
aria-label="&tabsToolbar.label;"
context="toolbar-context-menu"
#ifdef APPMENU_ON_TABBAR
defaultset="appmenu-toolbar-button,tabbrowser-tabs,new-tab-button,alltabs-button,tabview-button,tabs-closebutton"
#else
defaultset="tabbrowser-tabs,new-tab-button,alltabs-button,tabview-button,tabs-closebutton"
#endif
collapsed="true">
#ifdef APPMENU_ON_TABBAR
<toolbarbutton id="appmenu-toolbar-button"
class="chromeclass-toolbar-additional"
type="menu"
label="&brandShortName;"
tooltiptext="&appMenuButton.tooltip;">
#include browser-appmenu.inc
</toolbarbutton>
#endif
<tabs id="tabbrowser-tabs"
class="tabbrowser-tabs"
tabbrowser="content"

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

@ -290,6 +290,58 @@
</body>
</method>
<method name="getTabModalPromptBox">
<parameter name="aBrowser"/>
<body>
<![CDATA[
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
let browser = (aBrowser || this.mCurrentBrowser);
let stack = browser.parentNode;
let self = this;
let promptBox = {
appendPrompt : function(args, onCloseCallback) {
let count = browser.getAttribute("tabmodalPromptShowing");
if (count)
count = parseInt(count) + 1;
else
count = 1;
browser.setAttribute("tabmodalPromptShowing", count);
let newPrompt = document.createElementNS(XUL_NS, "tabmodalprompt");
stack.appendChild(newPrompt);
newPrompt.clientTop; // style flush to assure binding is attached
let tab = self._getTabForContentWindow(browser.contentWindow);
newPrompt.init(args, tab, onCloseCallback);
return newPrompt;
},
removePrompt : function(aPrompt) {
let count = parseInt(browser.getAttribute("tabmodalPromptShowing"));
count--;
if (count)
browser.setAttribute("tabmodalPromptShowing", count);
else
browser.removeAttribute("tabmodalPromptShowing");
stack.removeChild(aPrompt);
},
listPrompts : function(aPrompt) {
let prompts = [];
let els = stack.getElementsByTagNameNS(XUL_NS, "tabmodalprompt");
// NodeList --> real JS array
for (let i = 0; i < els.length; i++)
prompts.push(els[i]);
return prompts;
},
};
return promptBox;
]]>
</body>
</method>
<method name="_callProgressListeners">
<parameter name="aBrowser"/>
<parameter name="aMethod"/>
@ -2730,12 +2782,20 @@
var scrollButtonWidth = (this.getAttribute("overflow") != "true" || pinnedOnly) ? 0 :
this.mTabstrip._scrollButtonDown.scrollWidth;
var paddingStart = this.mTabstrip.scrollboxPaddingStart;
for (var i = this.tabbrowser._numPinnedTabs - 1; i >= 0; i--) {
let tab = this.childNodes[i];
width += pinnedOnly ? 0 : tab.scrollWidth;
tab.style.MozMarginStart = - (width + scrollButtonWidth) + "px";
if (this.getAttribute("overflow") != "true")
tab.style.MozMarginStart = - (width + scrollButtonWidth) + "px";
else
tab.style.MozMarginStart = - (width + scrollButtonWidth + paddingStart) + "px";
}
this.style.MozMarginStart = width + "px";
if (width == 0 || this.getAttribute("overflow") != "true")
this.style.MozMarginStart = width + "px";
else
this.style.MozMarginStart = width + paddingStart + "px";
this.mTabstrip.ensureElementIsVisible(this.selectedItem, false);
]]></body>
</method>

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

@ -428,7 +428,11 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
box.top += titleHeight;
box.height -= titleHeight;
box.width -= this.$appTabTray.width();
var appTabTrayWidth = this.$appTabTray.width();
box.width -= appTabTrayWidth;
if (UI.rtl) {
box.left += appTabTrayWidth;
}
// Make the computed bounds' "padding" and new tab button margin actually be
// themeable --OR-- compute this from actual bounds. Bug 586546

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

@ -1,51 +1,32 @@
function test() {
waitForExplicitFinish();
// test the main (normal) browser window
testCustomize(window, testChromeless);
}
function testChromeless() {
// test a chromeless window
var newWin = openDialog("chrome://browser/content/", "_blank",
"chrome,dialog=no,toolbar=no", "about:blank");
ok(newWin, "got new window");
function runWindowTest() {
function finalize() {
newWin.removeEventListener("load", runWindowTest, false);
newWin.close();
finish();
}
testCustomize(newWin, finalize);
}
newWin.addEventListener("load", runWindowTest, false);
testCustomize(window, finish);
}
function testCustomize(aWindow, aCallback) {
var addonBar = aWindow.document.getElementById("addon-bar");
ok(addonBar, "got addon bar");
is(addonBar.collapsed, true, "addon bar initially disabled");
ok(!isElementVisible(addonBar), "addon bar initially hidden");
// Launch toolbar customization
// ctEl is either iframe that contains the customize sheet, or the dialog
var ctEl = aWindow.BrowserCustomizeToolbar();
is(addonBar.collapsed, false,
"file menu is not collapsed during toolbar customization");
aWindow.gNavToolbox.addEventListener("beforecustomization", function () {
aWindow.gNavToolbox.removeEventListener("beforecustomization", arguments.callee, false);
executeSoon(ctInit);
}, false);
function ctInit() {
ok(isElementVisible(addonBar),
"add-on bar is visible during toolbar customization");
// Close toolbar customization
closeToolbarCustomization(aWindow, ctEl);
is(addonBar.getAttribute("collapsed"), "true",
"addon bar is collapsed after toolbar customization");
ok(!isElementVisible(addonBar),
"addon bar is hidden after toolbar customization");
if (aCallback)
aCallback();

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

@ -46,14 +46,16 @@ function runOverflowTests(aEvent) {
var element;
gBrowser.selectedTab = firstScrollable();
isLeft(firstScrollable(), "Selecting the first tab scrolls it into view");
ok(left(scrollbox) <= left(firstScrollable()), "Selecting the first tab scrolls it into view " +
"(" + left(scrollbox) + " <= " + left(firstScrollable()) + ")");
element = nextRightElement();
EventUtils.synthesizeMouse(downButton, 1, 1, {});
isRight(element, "Scrolled one tab to the right with a single click");
gBrowser.selectedTab = tabs[tabs.length - 1];
isRight(gBrowser.selectedTab, "Selecting the last tab scrolls it into view");
ok(right(gBrowser.selectedTab) <= right(scrollbox), "Selecting the last tab scrolls it into view " +
"(" + right(gBrowser.selectedTab) + " <= " + right(scrollbox) + ")");
element = nextLeftElement();
EventUtils.synthesizeMouse(upButton, 1, 1, {});
@ -64,11 +66,13 @@ function runOverflowTests(aEvent) {
isLeft(element, "Scrolled one page of tabs with a double click");
EventUtils.synthesizeMouse(upButton, 1, 1, {clickCount: 3});
isLeft(firstScrollable(), "Scrolled to the start with a triple click");
var firstScrollableLeft = left(firstScrollable());
ok(left(scrollbox) <= firstScrollableLeft, "Scrolled to the start with a triple click " +
"(" + left(scrollbox) + " <= " + firstScrollableLeft + ")");
for (var i = 2; i; i--)
EventUtils.synthesizeMouseScroll(scrollbox, 1, 1, {axis: "horizontal", delta: -1});
isLeft(firstScrollable(), "Remained at the start with the mouse wheel");
is(left(firstScrollable()), firstScrollableLeft, "Remained at the start with the mouse wheel");
element = nextRightElement();
EventUtils.synthesizeMouseScroll(scrollbox, 1, 1, {axis: "horizontal", delta: 1});

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

@ -130,24 +130,11 @@
if (!pasteAndGo)
return;
var controller = document.commandDispatcher.getControllerForCommand("cmd_paste");
var couldBeURL = controller.isCommandEnabled("cmd_paste");
if (couldBeURL) {
let cbSvc = Cc["@mozilla.org/widget/clipboard;1"].
getService(Ci.nsIClipboard);
let xferable = Cc["@mozilla.org/widget/transferable;1"].
createInstance(Ci.nsITransferable);
xferable.addDataFlavor("text/unicode");
cbSvc.getData(xferable, cbSvc.kGlobalClipboard);
let data = {};
xferable.getTransferData("text/unicode", data, {});
data = data.value.QueryInterface(Ci.nsISupportsString).data;
try {
makeURI(data);
} catch (ex) { // clipboard data is not a URL
couldBeURL = false;
}
}
pasteAndGo.hidden = !couldBeURL;
var enabled = controller.isCommandEnabled("cmd_paste");
if (enabled)
pasteAndGo.removeAttribute("disabled");
else
pasteAndGo.setAttribute("disabled", "true");
}, false);
var insertLocation = cxmenu.firstChild;
@ -628,55 +615,77 @@
"textbox-container");
]]></field>
<field name="_overLinkInDelay" readonly="true"><![CDATA[
<field name="_overLinkIntervalDelay" readonly="true"><![CDATA[
100
]]></field>
<field name="_overLinkOutDelay" readonly="true"><![CDATA[
100
]]></field>
<field name="_overLinkDelayTimer"><![CDATA[
<field name="_overLinkInterval"><![CDATA[
null
]]></field>
<method name="setOverLink">
<parameter name="aURL"/>
<body><![CDATA[
this._cancelOverLinkDelayTimer();
// NOTE: This method is called many times in a row very quickly when
// the user mouses over a bookmarks menu, tabs menu, or long list of
// links in a page, or leaves the cursor over a page with many links
// while scrolling. Therefore it's important that it be fast. Don't
// regress performance when you modify it!
// Hide the over-link immediately if necessary.
if (!aURL && (XULBrowserWindow.hideOverLinkImmediately ||
this._hideOverLinkImmediately)) {
if ((!aURL && (XULBrowserWindow.hideOverLinkImmediately ||
this._hideOverLinkImmediately)) ||
this.focused) {
this._clearOverLinkInterval();
this._setOverLinkState(null);
return;
}
// 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;
self._setOverLinkState("fade-out");
}, this._overLinkOutDelay, this);
return;
}
// If it's in transition, update and show it immediately.
if (this._overLinkTransitioning) {
// Update and show it immediately if it's in transition.
if (aURL && this._overLinkTransitioning) {
this._clearOverLinkInterval();
this._updateOverLink(aURL);
this._setOverLinkState("showing");
return;
}
// Delay the update if it's hidden or shown. We delay when shown in
// part for performance reasons: otherwise mousing over the bookmarks
// menu for example is very laggy.
this._overLinkDelayTimer = setTimeout(function overLinkIn(self) {
self._overLinkDelayTimer = null;
self._updateOverLink(aURL);
this._overLinkURL = aURL;
this._seenNewOverLink = true;
// If the user is continually mousing over links, make this method
// basically a no-op.
if (this._overLinkInterval)
return;
// Otherwise, the user has just moused over or focused a single link.
// Start the interval and signal that we should potentially show the
// over-link the first time it fires by unsetting _seenNewOverLink.
this._seenNewOverLink = false;
this._overLinkInterval = setInterval(this._overLinkIntervalCallback,
this._overLinkIntervalDelay,
this);
]]></body>
</method>
<method name="_overLinkIntervalCallback">
<parameter name="self"/>
<body><![CDATA[
// If the user is still mousing over links, bail out early.
if (self._seenNewOverLink) {
self._seenNewOverLink = false;
return;
}
// Otherwise, the user has stopped over a link. Clear the interval
// and update the over-link.
self._clearOverLinkInterval();
if (self._overLinkURL) {
self._updateOverLink(self._overLinkURL);
self._setOverLinkState("fade-in");
}, this._overLinkInDelay, this);
}
else {
self._setOverLinkState("fade-out");
}
]]></body>
</method>
@ -688,11 +697,11 @@
]]></body>
</method>
<method name="_cancelOverLinkDelayTimer">
<method name="_clearOverLinkInterval">
<body><![CDATA[
if (this._overLinkDelayTimer) {
clearTimeout(this._overLinkDelayTimer);
this._overLinkDelayTimer = null;
if (this._overLinkInterval) {
clearInterval(this._overLinkInterval);
this._overLinkInterval = null;
}
]]></body>
</method>

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

@ -2443,7 +2443,7 @@ SessionStoreService.prototype = {
// Determine if we can optimize & load visible tabs first
let maxVisibleTabs = Math.ceil(tabbrowser.tabContainer.mTabstrip.scrollClientSize /
aTabs[unhiddenTabs - 1].clientWidth);
aTabs[unhiddenTabs - 1].getBoundingClientRect().width);
// make sure we restore visible tabs first, if there are enough
if (maxVisibleTabs < unhiddenTabs && aSelectTab > 1) {

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

@ -132,7 +132,9 @@ function test() {
handleLoad: function (aEvent) {
let _this = this;
executeSoon(function () {
_this.window.resizeTo(_this.windowWidth, _this.window.outerHeight);
let extent = _this.window.outerWidth - _this.window.gBrowser.tabContainer.mTabstrip.scrollClientSize;
let windowWidth = _this.tabbarWidth + extent;
_this.window.resizeTo(windowWidth, _this.window.outerHeight);
ss.setWindowState(_this.window, JSON.stringify(_this.state), true);
});
},
@ -151,7 +153,7 @@ function test() {
// setup and actually run the test
run: function () {
this.windowWidth = Math.floor((this.numTabsToShow - 0.5) * tabMinWidth);
this.tabbarWidth = Math.floor((this.numTabsToShow - 0.5) * tabMinWidth);
this.window = openDialog(location, "_blank", "chrome,all,dialog=no");
this.window.addEventListener("SSTabRestoring", this, false);
this.window.addEventListener("load", this, false);

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

@ -23,6 +23,7 @@ fr
fy-NL
ga-IE
gd
gu-IN
he
hu
hy-AM
@ -41,6 +42,7 @@ nb-NO
nl
nn-NO
nso
or
pa-IN
pl
pt-BR
@ -48,10 +50,12 @@ pt-PT
rm
ro
ru
si
sk
son
sq
sv-SE
th
tr
uk
zh-CN

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

@ -237,6 +237,7 @@ menuitem:not([type]):not(.menuitem-tooltip):not(.menuitem-iconic-tooltip) {
-moz-binding: url("chrome://global/content/bindings/menu.xml#menuitem-iconic");
}
#appmenu_newNavigator,
#placesContext_open\:newwindow,
#menu_newNavigator,
#context-openlink,
@ -245,6 +246,8 @@ menuitem:not([type]):not(.menuitem-tooltip):not(.menuitem-iconic-tooltip) {
-moz-image-region: rect(0px 80px 16px 64px);
}
#appmenu_newTab,
#appmenu_newTab_popup,
#placesContext_open\:newtab,
#placesContext_openContainer\:tabs,
#menu_newNavigatorTab,
@ -254,6 +257,7 @@ menuitem:not([type]):not(.menuitem-tooltip):not(.menuitem-iconic-tooltip) {
-moz-image-region: rect(0px 64px 16px 48px);
}
#appmenu_openFile,
#menu_openFile {
list-style-image: url("moz-icon://stock/gtk-open?size=menu");
}
@ -270,6 +274,7 @@ menuitem:not([type]):not(.menuitem-tooltip):not(.menuitem-iconic-tooltip) {
list-style-image: url("moz-icon://stock/gtk-media-pause?size=menu");
}
#appmenu_savePage,
#menu_savePage,
#context-savelink,
#context-saveimage,
@ -280,15 +285,19 @@ menuitem:not([type]):not(.menuitem-tooltip):not(.menuitem-iconic-tooltip) {
list-style-image: url("moz-icon://stock/gtk-save-as?size=menu");
}
#appmenu_printPreview,
#menu_printPreview {
list-style-image: url("moz-icon://stock/gtk-print-preview?size=menu");
}
#appmenu_print,
#appmenu_print_popup,
#menu_print,
#context-printframe {
list-style-image: url("moz-icon://stock/gtk-print?size=menu");
}
#appmenu-quit,
#menu_FileQuitItem {
list-style-image: url("moz-icon://stock/gtk-quit?size=menu");
}
@ -371,6 +380,7 @@ menuitem:not([type]):not(.menuitem-tooltip):not(.menuitem-iconic-tooltip) {
list-style-image: url("moz-icon://stock/gtk-select-all?size=menu");
}
#appmenu_find,
#menu_find {
list-style-image: url("moz-icon://stock/gtk-find?size=menu");
}
@ -379,6 +389,8 @@ menuitem:not([type]):not(.menuitem-tooltip):not(.menuitem-iconic-tooltip) {
list-style-image: url("moz-icon://stock/gtk-find?size=menu&state=disabled");
}
#appmenu_customize,
#appmenu_preferences,
#menu_preferences {
list-style-image: url("moz-icon://stock/gtk-preferences?size=menu");
}
@ -462,11 +474,15 @@ menuitem:not([type]):not(.menuitem-tooltip):not(.menuitem-iconic-tooltip) {
list-style-image: url("moz-icon://stock/gtk-home?size=menu");
}
#appmenu_history,
#appmenu_showAllHistory,
#menu_showAllHistory {
list-style-image: url("chrome://browser/skin/Toolbar-small.png");
-moz-image-region: rect(0px 32px 16px 16px);
}
#appmenu_bookmarks,
#appmenu_showAllBookmarks,
#bookmarksShowAll {
list-style-image: url("chrome://browser/skin/Toolbar-small.png");
-moz-image-region: rect(0px 48px 16px 32px);
@ -492,6 +508,7 @@ menuitem:not([type]):not(.menuitem-tooltip):not(.menuitem-iconic-tooltip) {
list-style-image: url("chrome://browser/skin/places/unsortedBookmarks.png");
}
#appmenu_downloads,
#menu_openDownloads {
list-style-image: url("chrome://browser/skin/Toolbar-small.png");
-moz-image-region: rect(0px 16px 16px 0px);
@ -507,14 +524,18 @@ menuitem:not([type]):not(.menuitem-tooltip):not(.menuitem-iconic-tooltip) {
list-style-image: url("moz-icon://stock/gtk-properties?size=menu");
}
#appmenu_sanitizeHistory,
#sanitizeItem {
list-style-image: url("moz-icon://stock/gtk-clear?size=menu");
}
#appmenu_help,
#appmenu_openHelp,
#menu_openHelp {
list-style-image: url("moz-icon://stock/gtk-help?size=menu");
}
#appmenu_about,
#aboutName {
list-style-image: url("moz-icon://stock/gtk-about?size=menu");
}
@ -1693,6 +1714,32 @@ toolbar[mode="text"] toolbarbutton.chevron > .toolbarbutton-icon {
-moz-transform: translate(0, 2px);
}
/* Application menu toolbar button */
#appmenu-toolbar-button > .toolbarbutton-text {
margin-top: -2px !important;
margin-bottom: -2px !important;
}
#appmenuSecondaryPane {
-moz-border-start: 1px solid ThreeDShadow;
}
#appmenuSecondaryPane-spacer {
min-height: 1em;
}
#appmenu-cut {
list-style-image: url("moz-icon://stock/gtk-cut?size=menu");
}
#appmenu-copy {
list-style-image: url("moz-icon://stock/gtk-copy?size=menu");
}
#appmenu-paste {
list-style-image: url("moz-icon://stock/gtk-paste?size=menu");
}
#wrapper-appmenu-toolbar-button,
.appmenu-edit-button[disabled="true"] {
opacity: .3;
}
/* Inspector / Highlighter */
#highlighter-panel {
@ -1731,3 +1778,7 @@ panel[dimmed="true"] {
border-width: 0;
-moz-appearance: none;
}
browser[tabmodalPromptShowing] {
filter: url("chrome://browser/skin/effects.svg#blurAndDesaturate");
}

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

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
# ***** 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 effects.svg.
#
# 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 Dolske <dolske@mozilla.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 *****
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="0">
<filter id="blurAndDesaturate">
<feGaussianBlur stdDeviation="2"/>
<feColorMatrix type="saturate" values="0.7"/>
</filter>
</svg>

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

@ -12,6 +12,7 @@ browser.jar:
#endif
skin/classic/browser/actionicon-tab.png
* skin/classic/browser/browser.css (browser.css)
* skin/classic/browser/effects.svg (effects.svg)
* skin/classic/browser/engineManager.css (engineManager.css)
skin/classic/browser/fullscreen-video.css
skin/classic/browser/inspector.css

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

@ -2231,3 +2231,7 @@ panel[dimmed="true"] {
border-width: 0;
-moz-appearance: none;
}
browser[tabmodalPromptShowing] {
filter: url("chrome://browser/skin/effects.svg#blurAndDesaturate");
}

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

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
# ***** 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 effects.svg.
#
# 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 Dolske <dolske@mozilla.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 *****
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="0">
<filter id="blurAndDesaturate">
<feGaussianBlur stdDeviation="2"/>
<feColorMatrix type="saturate" values="0.7"/>
</filter>
</svg>

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

@ -11,6 +11,7 @@ browser.jar:
#endif
skin/classic/browser/actionicon-tab.png
* skin/classic/browser/browser.css (browser.css)
* skin/classic/browser/effects.svg (effects.svg)
* skin/classic/browser/engineManager.css (engineManager.css)
skin/classic/browser/fullscreen-video.css
skin/classic/browser/Geolocation-16.png

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

@ -3,7 +3,7 @@
%undef WINSTRIPE_AERO
%define customToolbarColor hsl(214,44%,87%)
%define glassToolbarBorderColor rgb(40%,40%,40%)
%define glassToolbarBorderColor rgba(10%,10%,10%,.4)
%define glassActiveBorderColor rgb(37, 44, 51)
%define glassInactiveBorderColor rgb(102, 102, 102)
@ -130,6 +130,7 @@
#navigator-toolbox,
#navigator-toolbox > toolbar {
border-color: @glassToolbarBorderColor@ !important;
background-clip: padding-box;
}
#main-window[sizemode="normal"]:not([inFullscreen="true"]) #navigator-toolbox[tabsontop="true"] > #nav-bar:not(:-moz-lwtheme),
@ -189,7 +190,8 @@
.tabbrowser-tab:not(:-moz-lwtheme):not([selected="true"]),
.tabs-newtab-button:not(:-moz-lwtheme) {
background-image: -moz-linear-gradient(hsla(214,15%,80%,.8), hsla(214,15%,65%,.8) 50%);
text-shadow: 0 1px 0 rgba(255,255,255,.4);
text-shadow: none;
color: black;
}
.tabbrowser-tab:not(:-moz-lwtheme):not([selected="true"]):hover,

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

@ -194,6 +194,10 @@
opacity: .3;
}
#appmenuPrimaryPane {
-moz-border-end: 1px solid ThreeDShadow;
}
@media all and (-moz-windows-default-theme) {
#appmenu-popup {
-moz-appearance: none;
@ -655,7 +659,8 @@ toolbar[mode="full"] .toolbarbutton-1 > .toolbarbutton-menubutton-button {
}
#back-button:-moz-locale-dir(rtl) > .toolbarbutton-icon,
#forward-button:-moz-locale-dir(rtl) {
#forward-button:-moz-locale-dir(rtl),
#forward-button:-moz-locale-dir(rtl) > .toolbarbutton-text {
-moz-transform: scaleX(-1);
}
@ -2116,3 +2121,7 @@ panel[dimmed="true"] {
border-width: 0;
-moz-appearance: none;
}
browser[tabmodalPromptShowing] {
filter: url("chrome://browser/skin/effects.svg#blurAndDesaturate");
}

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

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
# ***** 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 effects.svg.
#
# 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 Dolske <dolske@mozilla.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 *****
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="0">
<filter id="blurAndDesaturate">
<feGaussianBlur stdDeviation="2"/>
<feColorMatrix type="saturate" values="0.7"/>
</filter>
</svg>

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

@ -16,6 +16,7 @@ browser.jar:
skin/classic/browser/appmenu-icons.png
skin/classic/browser/appmenu-dropmarker.png
* skin/classic/browser/browser.css (browser.css)
* skin/classic/browser/effects.svg (effects.svg)
* skin/classic/browser/engineManager.css (engineManager.css)
skin/classic/browser/fullscreen-video.css
skin/classic/browser/Geolocation-16.png
@ -128,6 +129,7 @@ browser.jar:
skin/classic/aero/browser/appmenu-dropmarker.png
skin/classic/aero/browser/appmenu-icons.png
* skin/classic/aero/browser/browser.css (browser-aero.css)
* skin/classic/aero/browser/effects.svg (effects.svg)
* skin/classic/aero/browser/engineManager.css (engineManager.css)
skin/classic/aero/browser/fullscreen-video.css
skin/classic/aero/browser/Geolocation-16.png

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

@ -592,8 +592,6 @@ export CL_INCLUDES_PREFIX = @CL_INCLUDES_PREFIX@
MOZ_AUTO_DEPS = @MOZ_AUTO_DEPS@
COMPILER_DEPEND = @COMPILER_DEPEND@
MDDEPDIR := @MDDEPDIR@
CC_WRAPPER = @CC_WRAPPER@
CXX_WRAPPER = @CXX_WRAPPER@
MOZ_DEMANGLE_SYMBOLS = @MOZ_DEMANGLE_SYMBOLS@

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

@ -170,6 +170,19 @@ endif
endif
endif
ifndef NO_CXX_WRAPPER
ifdef _MSC_VER
ifndef .PYMAKE
CC_WRAPPER = $(PYTHON) -O $(topsrcdir)/build/cl.py
CXX_WRAPPER = $(PYTHON) -O $(topsrcdir)/build/cl.py
else
PYCOMMANDPATH += $(topsrcdir)/build
CC_WRAPPER = %cl InvokeClWithDependencyGeneration
CXX_WRAPPER = %cl InvokeClWithDependencyGeneration
endif # .PYMAKE
endif # _MSC_VER
endif # NO_CXX_WRAPPER
CC := $(CC_WRAPPER) $(CC)
CXX := $(CXX_WRAPPER) $(CXX)

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

@ -652,35 +652,31 @@ case "$target" in
if test "$_CC_MAJOR_VERSION" != "$_CXX_MAJOR_VERSION"; then
AC_MSG_ERROR([The major versions of \$CC and \$CXX do not match.])
fi
if test "$_CC_MAJOR_VERSION" = "13"; then
_CC_SUITE=7
elif test "$_CC_MAJOR_VERSION" = "14"; then
if test "$_CC_MAJOR_VERSION" = "14"; then
dnl Require VC8SP1 or newer.
dnl VC8 is 14.00.50727.42, VC8SP1 is 14.00.50727.762.
if test "$_CC_RELEASE" -lt 50727 -o \
\( "$_CC_RELEASE" -eq 50727 -a "$_CC_BUILD" -lt 762 \); then
AC_MSG_ERROR([This version ($CC_VERSION) of the MSVC compiler is unsupported. You probably need to install Service Pack 1 of Visual Studio 2005. See https://developer.mozilla.org/en/Windows_Build_Prerequisites.])
fi
_CC_SUITE=8
CXXFLAGS="$CXXFLAGS -Zc:wchar_t-"
dnl -DYNAMICBASE is only supported on VC8SP1 or newer,
dnl so be very specific here!
dnl VC8 is 14.00.50727.42, VC8SP1 is 14.00.50727.762
if test $_CC_RELEASE -gt 50727; then
_USE_DYNAMICBASE=1
elif test $_CC_BUILD -ge 762; then
_USE_DYNAMICBASE=1
fi
AC_DEFINE(_CRT_SECURE_NO_DEPRECATE)
AC_DEFINE(_CRT_NONSTDC_NO_DEPRECATE)
elif test "$_CC_MAJOR_VERSION" = "15"; then
_CC_SUITE=9
CXXFLAGS="$CXXFLAGS -Zc:wchar_t-"
_USE_DYNAMICBASE=1
AC_DEFINE(_CRT_SECURE_NO_WARNINGS)
AC_DEFINE(_CRT_NONSTDC_NO_WARNINGS)
elif test "$_CC_MAJOR_VERSION" = "16"; then
_CC_SUITE=10
CXXFLAGS="$CXXFLAGS -Zc:wchar_t-"
_USE_DYNAMICBASE=1
AC_DEFINE(_CRT_SECURE_NO_WARNINGS)
AC_DEFINE(_CRT_NONSTDC_NO_WARNINGS)
else
AC_MSG_ERROR([This version of the MSVC compiler, $CC_VERSION , is unsupported.])
AC_MSG_ERROR([This version ($CC_VERSION) of the MSVC compiler is unsupported. See https://developer.mozilla.org/en/Windows_Build_Prerequisites.])
fi
_MOZ_RTTI_FLAGS_ON='-GR'
@ -691,33 +687,32 @@ case "$target" in
if test -n "$WIN32_REDIST_DIR"; then
WIN32_REDIST_DIR=`cd "$WIN32_REDIST_DIR" && pwd`
fi
# bug #249782
# ensure that mt.exe is Microsoft (R) Manifest Tool and not magnetic tape manipulation utility (or something else)
if test "$_CC_SUITE" -ge "8"; then
changequote(,)
_MSMT_VER_FILTER='s|.* \([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*|\1|p'
changequote([,])
MSMT_TOOL=`mt 2>&1|grep 'Microsoft (R) Manifest Tool'`
if test -n "$MSMT_TOOL"; then
MSMANIFEST_TOOL_VERSION=`echo ${MSMT_TOOL}|sed -ne "$_MSMT_VER_FILTER"`
if test -z "$MSMANIFEST_TOOL_VERSION"; then
AC_MSG_WARN([Unknown version of the Microsoft (R) Manifest Tool.])
fi
MSMANIFEST_TOOL=1
unset MSMT_TOOL
else
AC_MSG_ERROR([Microsoft (R) Manifest Tool must be in your \$PATH.])
fi
dnl Ensure that mt.exe is 'Microsoft (R) Manifest Tool',
dnl not something else like "magnetic tape manipulation utility".
MSMT_TOOL=`mt 2>&1|grep 'Microsoft (R) Manifest Tool'`
if test -z "$MSMT_TOOL"; then
AC_MSG_ERROR([Microsoft (R) Manifest Tool must be in your \$PATH.])
fi
changequote(,)
_MSMT_VER_FILTER='s|.* \([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*|\1|p'
changequote([,])
MSMANIFEST_TOOL_VERSION=`echo ${MSMT_TOOL}|sed -ne "$_MSMT_VER_FILTER"`
if test -z "$MSMANIFEST_TOOL_VERSION"; then
AC_MSG_WARN([Unknown version of the Microsoft (R) Manifest Tool.])
fi
MSMANIFEST_TOOL=1
unset MSMT_TOOL
# Check linker version
_LD_FULL_VERSION=`"${LD}" -v 2>&1 | sed -nre "$_MSVC_VER_FILTER"`
_LD_MAJOR_VERSION=`echo ${_LD_FULL_VERSION} | $AWK -F\. '{ print $1 }'`
if test "$_LD_MAJOR_VERSION" != "$_CC_SUITE"; then
AC_MSG_ERROR([The linker major version, $_LD_FULL_VERSION, does not match the compiler suite version, $_CC_SUITE.])
fi
INCREMENTAL_LINKER=1
# Check midl version
@ -2430,9 +2425,7 @@ ia64*-hpux*)
dnl XXX: should be -LTCG:PGOPTIMIZE, but that fails on libxul.
dnl Probably also a compiler bug, but what can you do?
PROFILE_USE_LDFLAGS="-LTCG:PGUPDATE"
if test -n "$_USE_DYNAMICBASE"; then
LDFLAGS="$LDFLAGS -DYNAMICBASE"
fi
LDFLAGS="$LDFLAGS -DYNAMICBASE"
fi
fi
MOZ_JPEG_LIBS='$(call EXPAND_LIBNAME_PATH,jpeg32$(VERSION_NUMBER),$(DEPTH)/jpeg)'
@ -2493,7 +2486,7 @@ ia64*-hpux*)
case "$host_os" in
cygwin*|msvc*|mks*)
AC_MSG_WARN([Using a cygwin build environment is unsupported. Configure cannot check for the presence of necessary headers. Please upgrade to MozillaBuild; see http://developer.mozilla.org/en/docs/Windows_Build_Prerequisites])
AC_MSG_WARN([Using a cygwin build environment is unsupported. Configure cannot check for the presence of necessary headers. Please upgrade to MozillaBuild; see https://developer.mozilla.org/en/Windows_Build_Prerequisites.])
;;
*)
@ -6496,15 +6489,9 @@ if test "$MOZ_MATHML"; then
fi
dnl ========================================================
dnl SVG
dnl Keeping AC_DEFINE(MOZ_SVG) for the moment in case of something needs it.
dnl ========================================================
MOZ_ARG_DISABLE_BOOL(svg,
[ --disable-svg Disable SVG support],
MOZ_SVG=,
MOZ_SVG=1 )
if test -n "$MOZ_SVG"; then
AC_DEFINE(MOZ_SVG)
fi
AC_DEFINE(MOZ_SVG)
dnl ========================================================
dnl SMIL
@ -6514,10 +6501,6 @@ MOZ_ARG_DISABLE_BOOL(smil,
[ --disable-smil Disable SMIL animation support],
MOZ_SMIL=,
MOZ_SMIL=1 )
# Automatically disable SMIL if SVG is disabled
if test -z "$MOZ_SVG"; then
MOZ_SMIL=
fi
if test -n "$MOZ_SMIL"; then
AC_DEFINE(MOZ_SMIL)
fi
@ -7489,6 +7472,7 @@ if test -n "$_WRAP_MALLOC"; then
if test "$GNU_CC"; then
WRAP_MALLOC_CFLAGS="${LDFLAGS} ${WRAP_MALLOC_CFLAGS} -Wl,--wrap -Wl,malloc -Wl,--wrap -Wl,calloc -Wl,--wrap -Wl,valloc -Wl,--wrap -Wl,free -Wl,--wrap -Wl,realloc -Wl,--wrap -Wl,memalign -Wl,--wrap -Wl,__builtin_new -Wl,--wrap -Wl,__builtin_vec_new -Wl,--wrap -Wl,__builtin_delete -Wl,--wrap -Wl,__builtin_vec_delete -Wl,--wrap -Wl,PR_Free -Wl,--wrap -Wl,PR_Malloc -Wl,--wrap -Wl,PR_Calloc -Wl,--wrap -Wl,PR_Realloc -Wl,--wrap -Wl,strdup -Wl,--wrap -Wl,strndup -Wl,--wrap -Wl,posix_memalign"
MKSHLIB='$(CXX) $(DSO_LDOPTS) $(WRAP_MALLOC_CFLAGS) $(WRAP_MALLOC_LIB) -o $@'
MKCSHLIB='$(CC) $(DSO_LDOPTS) $(WRAP_MALLOC_CFLAGS) $(WRAP_MALLOC_LIB) -o $@'
fi
fi
@ -8172,10 +8156,7 @@ else
fi
AC_SUBST(CL_INCLUDES_PREFIX)
rm -f dummy-hello.c
_topsrcdirwin=`cd \`dirname $0\`; pwd -W`
dnl cl.py provides dependency generation for MSVC
CC_WRAPPER="$PYTHON -O $_topsrcdirwin/build/cl.py"
CXX_WRAPPER="$PYTHON -O $_topsrcdirwin/build/cl.py"
COMPILER_DEPEND=1
fi
fi
@ -8184,9 +8165,6 @@ MDDEPDIR='.deps'
AC_SUBST(MOZ_AUTO_DEPS)
AC_SUBST(COMPILER_DEPEND)
AC_SUBST(MDDEPDIR)
AC_SUBST(CC_WRAPPER)
AC_SUBST(CXX_WRAPPER)
dnl ========================================================
dnl =

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

@ -1708,6 +1708,12 @@ public:
*/
static void FlushLayoutForTree(nsIDOMWindow* aWindow);
/**
* Returns true if content with the given principal is allowed to use XUL
* and XBL and false otherwise.
*/
static bool AllowXULXBLForPrincipal(nsIPrincipal* aPrincipal);
private:
static PRBool InitializeEventTable();
@ -1797,6 +1803,7 @@ private:
static nsIInterfaceRequestor* sSameOriginChecker;
static PRBool sIsHandlingKeyBoardEvent;
static PRBool sAllowXULXBL_for_file;
};
#define NS_HOLD_JS_OBJECTS(obj, clazz) \

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

@ -98,6 +98,12 @@ interface nsIContentFrameMessageManager : nsISyncMessageSender
* Print a string to stdout.
*/
void dump(in DOMString aStr);
/**
* If leak detection is enabled, print a note to the leak log that this
* process will intentionally crash.
*/
void privateNoteIntentionalCrash();
};
[uuid(9c48d557-92fe-4edb-95fc-bfe97e77bdc3)]

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

@ -53,6 +53,7 @@ const Cu = Components.utils;
const CSP_VIOLATION_TOPIC = "csp-on-violate-policy";
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/CSPUtils.jsm");
/* ::::: Policy Parsing & Data structures :::::: */
@ -70,9 +71,6 @@ function ContentSecurityPolicy() {
this._requestHeaders = [];
this._request = "";
CSPdebug("CSP POLICY INITED TO 'allow *'");
this._observerService = Cc['@mozilla.org/observer-service;1']
.getService(Ci.nsIObserverService);
}
/*
@ -131,17 +129,8 @@ ContentSecurityPolicy.prototype = {
get allowsInlineScript() {
// trigger automatic report to go out when inline scripts are disabled.
if (!this._policy.allowsInlineScripts) {
var violation = 'violated base restriction: Inline Scripts will not execute';
// gotta wrap the violation string, since it's sent out to observers as
// an nsISupports.
let wrapper = Cc["@mozilla.org/supports-cstring;1"]
.createInstance(Ci.nsISupportsCString);
wrapper.data = violation;
this._observerService.notifyObservers(
wrapper,
CSP_VIOLATION_TOPIC,
'inline script base restriction');
this.sendReports('self', violation);
this._asyncReportViolation('self','inline script base restriction',
'violated base restriction: Inline Scripts will not execute');
}
return this._reportOnlyMode || this._policy.allowsInlineScripts;
},
@ -149,17 +138,8 @@ ContentSecurityPolicy.prototype = {
get allowsEval() {
// trigger automatic report to go out when eval and friends are disabled.
if (!this._policy.allowsEvalInScripts) {
var violation = 'violated base restriction: Code will not be created from strings';
// gotta wrap the violation string, since it's sent out to observers as
// an nsISupports.
let wrapper = Cc["@mozilla.org/supports-cstring;1"]
.createInstance(Ci.nsISupportsCString);
wrapper.data = violation;
this._observerService.notifyObservers(
wrapper,
CSP_VIOLATION_TOPIC,
'eval script base restriction');
this.sendReports('self', violation);
this._asyncReportViolation('self','eval script base restriction',
'violated base restriction: Code will not be created from strings');
}
return this._reportOnlyMode || this._policy.allowsEvalInScripts;
},
@ -369,12 +349,9 @@ ContentSecurityPolicy.prototype = {
let violatedPolicy = (directive._isImplicit
? 'allow' : 'frame-ancestors ')
+ directive.toString();
// send an nsIURI object to the observers (more interesting than a string)
this._observerService.notifyObservers(
ancestors[i],
CSP_VIOLATION_TOPIC,
violatedPolicy);
this.sendReports(ancestors[i].asciiSpec, violatedPolicy);
this._asyncReportViolation(ancestors[i], violatedPolicy);
// need to lie if we are testing in report-only mode
return this._reportOnlyMode;
}
@ -427,11 +404,7 @@ ContentSecurityPolicy.prototype = {
let violatedPolicy = (directive._isImplicit
? 'allow' : cspContext)
+ ' ' + directive.toString();
this._observerService.notifyObservers(
aContentLocation,
CSP_VIOLATION_TOPIC,
violatedPolicy);
this.sendReports(aContentLocation, violatedPolicy);
this._asyncReportViolation(aContentLocation, violatedPolicy);
} catch(e) {
CSPdebug('---------------- ERROR: ' + e);
}
@ -453,6 +426,46 @@ ContentSecurityPolicy.prototype = {
return res;
},
/**
* Asynchronously notifies any nsIObservers listening to the CSP violation
* topic that a violation occurred. Also triggers report sending. All
* asynchronous on the main thread.
*
* @param blockedContentSource
* Either a CSP Source (like 'self', as string) or nsIURI: the source
* of the violation.
* @param violatedDirective
* the directive that was violated (string).
* @param observerSubject
* optional, subject sent to the nsIObservers listening to the CSP
* violation topic.
*/
_asyncReportViolation:
function(blockedContentSource, violatedDirective, observerSubject) {
// if optional observerSubject isn't specified, default to the source of
// the violation.
if (!observerSubject)
observerSubject = blockedContentSource;
// gotta wrap things that aren't nsISupports, since it's sent out to
// observers as such. Objects that are not nsISupports are converted to
// strings and then wrapped into a nsISupportsCString.
if (!(observerSubject instanceof Ci.nsISupports)) {
let d = observerSubject;
observerSubject = Cc["@mozilla.org/supports-cstring;1"]
.createInstance(Ci.nsISupportsCString);
observerSubject.data = d;
}
var reportSender = this;
Services.tm.mainThread.dispatch(
function() {
Services.obs.notifyObservers(observerSubject,
CSP_VIOLATION_TOPIC,
violatedDirective);
reportSender.sendReports(blockedContentSource, violatedDirective);
}, Ci.nsIThread.DISPATCH_NORMAL);
},
};
var NSGetFactory = XPCOMUtils.generateNSGetFactory([ContentSecurityPolicy]);

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

@ -264,6 +264,7 @@ nsIJSRuntimeService *nsAutoGCRoot::sJSRuntimeService;
JSRuntime *nsAutoGCRoot::sJSScriptRuntime;
PRBool nsContentUtils::sIsHandlingKeyBoardEvent = PR_FALSE;
PRBool nsContentUtils::sAllowXULXBL_for_file = PR_FALSE;
PRBool nsContentUtils::sInitialized = PR_FALSE;
@ -506,6 +507,9 @@ nsContentUtils::Init()
sBlockedScriptRunners = new nsCOMArray<nsIRunnable>;
NS_ENSURE_TRUE(sBlockedScriptRunners, NS_ERROR_OUT_OF_MEMORY);
nsContentUtils::AddBoolPrefVarCache("dom.allow_XUL_XBL_for_file",
&sAllowXULXBL_for_file);
sInitialized = PR_TRUE;
return NS_OK;
@ -4941,12 +4945,9 @@ nsContentUtils::SetDataTransferInEvent(nsDragEvent* aDragEvent)
// A dataTransfer won't exist when a drag was started by some other
// means, for instance calling the drag service directly, or a drag
// from another application. In either case, a new dataTransfer should
// be created that reflects the data. Pass true to the constructor for
// the aIsExternal argument, so that only system access is allowed.
PRUint32 action = 0;
dragSession->GetDragAction(&action);
// be created that reflects the data.
initialDataTransfer =
new nsDOMDataTransfer(aDragEvent->message, action);
new nsDOMDataTransfer(aDragEvent->message);
NS_ENSURE_TRUE(initialDataTransfer, NS_ERROR_OUT_OF_MEMORY);
// now set it in the drag session so we don't need to create it again
@ -6416,6 +6417,20 @@ nsContentUtils::LayerManagerForDocument(nsIDocument *aDoc)
return manager.forget();
}
bool
nsContentUtils::AllowXULXBLForPrincipal(nsIPrincipal* aPrincipal)
{
if (IsSystemPrincipal(aPrincipal)) {
return true;
}
nsCOMPtr<nsIURI> princURI;
aPrincipal->GetURI(getter_AddRefs(princURI));
return princURI &&
((sAllowXULXBL_for_file && SchemeIs(princURI, "file")) ||
IsSitePermAllow(princURI, "allowXULXBL"));
}
NS_IMPL_ISUPPORTS1(nsIContentUtils, nsIContentUtils)

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

@ -3878,19 +3878,7 @@ nsDocument::ScriptLoader()
PRBool
nsDocument::InternalAllowXULXBL()
{
if (nsContentUtils::IsSystemPrincipal(NodePrincipal())) {
mAllowXULXBL = eTriTrue;
return PR_TRUE;
}
nsCOMPtr<nsIURI> princURI;
NodePrincipal()->GetURI(getter_AddRefs(princURI));
if (!princURI) {
mAllowXULXBL = eTriFalse;
return PR_FALSE;
}
if (nsContentUtils::IsSitePermAllow(princURI, "allowXULXBL")) {
if (nsContentUtils::AllowXULXBLForPrincipal(NodePrincipal())) {
mAllowXULXBL = eTriTrue;
return PR_TRUE;
}

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

@ -91,6 +91,22 @@ nsFileDataProtocolHandler::RemoveFileDataEntry(nsACString& aUri)
}
}
nsIPrincipal*
nsFileDataProtocolHandler::GetFileDataEntryPrincipal(nsACString& aUri)
{
if (!gFileDataTable) {
return nsnull;
}
FileDataInfo* res;
gFileDataTable->Get(aUri, &res);
if (!res) {
return nsnull;
}
return res->mPrincipal;
}
static FileDataInfo*
GetFileDataInfo(const nsACString& aUri)
{

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

@ -61,6 +61,7 @@ public:
nsIDOMBlob* aFile,
nsIPrincipal* aPrincipal);
static void RemoveFileDataEntry(nsACString& aUri);
static nsIPrincipal* GetFileDataEntryPrincipal(nsACString& aUri);
};

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

@ -87,6 +87,8 @@
#include "nsIDocShellHistory.h"
#include "nsIDOMNSHTMLDocument.h"
#include "nsIXULWindow.h"
#include "nsIEditor.h"
#include "nsIEditorDocShell.h"
#include "nsLayoutUtils.h"
#include "nsIView.h"
@ -686,6 +688,13 @@ nsFrameLoader::Show(PRInt32 marginWidth, PRInt32 marginHeight,
doc->GetDesignMode(designMode);
if (designMode.EqualsLiteral("on")) {
// Hold on to the editor object to let the document reattach to the
// same editor object, instead of creating a new one.
nsCOMPtr<nsIEditorDocShell> editorDocshell = do_QueryInterface(mDocShell);
nsCOMPtr<nsIEditor> editor;
nsresult rv = editorDocshell->GetEditor(getter_AddRefs(editor));
NS_ENSURE_SUCCESS(rv, PR_FALSE);
doc->SetDesignMode(NS_LITERAL_STRING("off"));
doc->SetDesignMode(NS_LITERAL_STRING("on"));
}

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

@ -307,6 +307,12 @@ nsFrameMessageManager::Dump(const nsAString& aStr)
return NS_OK;
}
NS_IMETHODIMP
nsFrameMessageManager::PrivateNoteIntentionalCrash()
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsFrameMessageManager::GetContent(nsIDOMWindow** aContent)
{

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

@ -258,9 +258,7 @@ GK_ATOM(count, "count")
GK_ATOM(crop, "crop")
GK_ATOM(curpos, "curpos")
GK_ATOM(current, "current")
#ifdef MOZ_MEDIA
GK_ATOM(currentloop, "currentloop")
#endif
GK_ATOM(cycler, "cycler")
GK_ATOM(data, "data")
GK_ATOM(datalist, "datalist")
@ -588,6 +586,7 @@ GK_ATOM(mouseover, "mouseover")
GK_ATOM(mousethrough, "mousethrough")
GK_ATOM(mouseup, "mouseup")
GK_ATOM(moz_opaque, "moz-opaque")
GK_ATOM(moz_action_hint, "mozactionhint")
GK_ATOM(x_moz_errormessage, "x-moz-errormessage")
GK_ATOM(msthemecompatible, "msthemecompatible")
GK_ATOM(multicol, "multicol")

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

@ -180,6 +180,12 @@ nsInProcessTabChildGlobal::GetDocShell(nsIDocShell** aDocShell)
return NS_OK;
}
NS_IMETHODIMP
nsInProcessTabChildGlobal::PrivateNoteIntentionalCrash()
{
return NS_ERROR_NOT_IMPLEMENTED;
}
void
nsInProcessTabChildGlobal::Disconnect()
{

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

@ -77,6 +77,7 @@ public:
{
return mMessageManager ? mMessageManager->Dump(aStr) : NS_OK;
}
NS_IMETHOD PrivateNoteIntentionalCrash();
NS_DECL_NSIINPROCESSCONTENTFRAMEMESSAGEMANAGER
virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);

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

@ -100,6 +100,7 @@
#include "nsIContentSecurityPolicy.h"
#include "nsAsyncRedirectVerifyHelper.h"
#include "jstypedarray.h"
#include "nsStringBuffer.h"
#define LOAD_STR "load"
#define ERROR_STR "error"
@ -1174,13 +1175,14 @@ nsXMLHttpRequest::ConvertBodyToText(nsAString& aOutBuffer)
if (NS_FAILED(rv))
return rv;
PRUnichar * outBuffer =
static_cast<PRUnichar*>(nsMemory::Alloc((outBufferLength + 1) *
sizeof(PRUnichar)));
if (!outBuffer) {
nsStringBuffer* buf =
nsStringBuffer::Alloc((outBufferLength + 1) * sizeof(PRUnichar));
if (!buf) {
return NS_ERROR_OUT_OF_MEMORY;
}
PRUnichar* outBuffer = static_cast<PRUnichar*>(buf->Data());
PRInt32 totalChars = 0,
outBufferIndex = 0,
outLen = outBufferLength;
@ -1212,10 +1214,18 @@ nsXMLHttpRequest::ConvertBodyToText(nsAString& aOutBuffer)
}
} while ( NS_FAILED(rv) && (dataLen > 0) );
mResponseBodyUnicode.Assign(outBuffer, totalChars);
// Use the string buffer if it is small, or doesn't contain
// too much extra data.
if (outBufferLength < 127 ||
(outBufferLength * 0.9) < totalChars) {
outBuffer[totalChars] = PRUnichar(0);
// Move ownership to mResponseBodyUnicode.
buf->ToString(totalChars, mResponseBodyUnicode, PR_TRUE);
} else {
mResponseBodyUnicode.Assign(outBuffer, totalChars);
buf->Release();
}
aOutBuffer = mResponseBodyUnicode;
nsMemory::Free(outBuffer);
return NS_OK;
}

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

@ -197,7 +197,7 @@ function imageLoadHandler(event) {
var imgfile = createFileWithData(testBinaryData + fileData + testBinaryData);
is(imgfile.size, size + testBinaryData.length * 2, "correct file size");
var img = new Image;
img.src = createBlobURL(imgfile.slice(testBinaryData.length, size));
img.src = URL.createObjectURL(imgfile.slice(testBinaryData.length, size));
img.onload = imageLoadHandler;
expectedTestCount++;
@ -205,7 +205,7 @@ expectedTestCount++;
var imgfile = createFileWithData(fileData + testBinaryData);
is(imgfile.size, size + testBinaryData.length, "correct file size");
var img = new Image;
img.src = createBlobURL(imgfile.slice(0, size));
img.src = URL.createObjectURL(imgfile.slice(0, size));
img.onload = imageLoadHandler;
expectedTestCount++;
@ -213,7 +213,7 @@ expectedTestCount++;
var imgfile = createFileWithData(testBinaryData + fileData);
is(imgfile.size, size + testBinaryData.length, "correct file size");
var img = new Image;
img.src = createBlobURL(imgfile.slice(testBinaryData.length, size));
img.src = URL.createObjectURL(imgfile.slice(testBinaryData.length, size));
img.onload = imageLoadHandler;
expectedTestCount++;
@ -221,7 +221,7 @@ expectedTestCount++;
var imgfile = createFileWithData(testBinaryData + fileData);
is(imgfile.size, size + testBinaryData.length, "correct file size");
var img = new Image;
img.src = createBlobURL(imgfile.slice(testBinaryData.length, size + 1000));
img.src = URL.createObjectURL(imgfile.slice(testBinaryData.length, size + 1000));
img.onload = imageLoadHandler;
expectedTestCount++;
@ -234,9 +234,9 @@ function testFile(file, contents, test) {
r.readAsBinaryString(file);
expectedTestCount++;
// Load file using createBlobURL and XMLHttpRequest
// Load file using URL.createObjectURL and XMLHttpRequest
var xhr = new XMLHttpRequest;
xhr.open("GET", createBlobURL(file));
xhr.open("GET", URL.createObjectURL(file));
xhr.onload = getXHRLoadHandler(contents, contents.length, false,
"XMLHttpRequest load of " + test);
xhr.overrideMimeType('text/plain; charset=x-user-defined');

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

@ -22,7 +22,7 @@
<script class="testbody" type="application/javascript;version=1.8">
try {
createBlobURL(undefined);
URL.createObjectURL(undefined);
} catch(e) { }
window.addEventListener("message", function(e) {
@ -44,7 +44,7 @@ function runTest() {
// Attempt to load a image in this document
var file = getFile("file_mozfiledataurl_img.jpg");
var fileurl = createBlobURL(file);
var fileurl = URL.createObjectURL(file);
img.src = fileurl;
var e = (yield);
is(e.type, "load", "loaded successfully");
@ -54,7 +54,7 @@ function runTest() {
// Revoke url and attempt to load a image in this document
img.src = "file_mozfiledataurl_img.jpg";
is((yield).type, "load", "successfull reset image");
revokeBlobURL(fileurl);
URL.revokeObjectURL(fileurl);
todo(false, "urls need to act like 404s, not fail to parse");
/* img.src = fileurl;
var e = (yield);
@ -64,8 +64,8 @@ function runTest() {
*/
// Generate new fileurl and make sure it's different from the old
var oldFileurl = fileurl;
var fileurl = createBlobURL(file);
isnot(fileurl, oldFileurl, "createBlobURL generated the same url twice");
var fileurl = URL.createObjectURL(file);
isnot(fileurl, oldFileurl, "URL.createObjectURL generated the same url twice");
// Attempt to load an image in a different same-origin document
inner.src = innerSameSiteURI;
@ -87,7 +87,7 @@ function runTest() {
// Attempt to load an audio in this document
var file = getFile("file_mozfiledataurl_audio.ogg");
var fileurl = createBlobURL(file);
var fileurl = URL.createObjectURL(file);
audio.src = fileurl;
var e = (yield);
is(e.type, "canplay", "loaded successfully");
@ -95,7 +95,7 @@ function runTest() {
// Revoke url and attempt to load a audio in this document
audio.src = "file_mozfiledataurl_audio.ogg";
is((yield).type, "canplay", "successfully reset audio");
revokeBlobURL(fileurl);
URL.revokeObjectURL(fileurl);
todo(false, "urls need to act like 404s, not fail to parse");
/* img.src = fileurl;
var e = (yield);
@ -105,8 +105,8 @@ function runTest() {
*/
// Generate new fileurl and make sure it's different from the old
var oldFileurl = fileurl;
var fileurl = createBlobURL(file);
isnot(fileurl, oldFileurl, "createBlobURL generated the same url twice");
var fileurl = URL.createObjectURL(file);
isnot(fileurl, oldFileurl, "URL.createObjectURL generated the same url twice");
// Attempt to load an audio in a different same-origin document
inner.src = innerSameSiteURI;
@ -136,7 +136,7 @@ function runTest() {
// Attempt to load a HTML document in an iframe in this document, using file url
file = getFile("file_mozfiledataurl_doc.html");
fileurl = createBlobURL(file);
fileurl = URL.createObjectURL(file);
iframe.src = fileurl;
yield;
is(iframe.contentDocument.getElementsByTagName("p")[0].textContent,
@ -172,7 +172,7 @@ function runTest() {
// Attempt to load file url using XHR
file = getFile("file_mozfiledataurl_text.txt");
fileurl = createBlobURL(file);
fileurl = URL.createObjectURL(file);
xhr = new XMLHttpRequest;
xhr.onload = function() { gen.send("XHR finished"); };
xhr.open("GET", fileurl);

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

@ -38,6 +38,8 @@
#ifndef nsEventStates_h__
#define nsEventStates_h__
#include "nsDebug.h"
/**
* nsEventStates is the class used to represent the event states of nsIContent
* instances. These states are calculated by IntrinsicState() and
@ -257,6 +259,10 @@ private:
#define NS_EVENT_STATE_MOZ_PLACEHOLDER NS_DEFINE_EVENT_STATE_MACRO(30)
// Content is a submit control and the form isn't valid.
#define NS_EVENT_STATE_MOZ_SUBMITINVALID NS_DEFINE_EVENT_STATE_MACRO(31)
// UI friendly version of :invalid pseudo-class.
#define NS_EVENT_STATE_MOZ_UI_INVALID NS_DEFINE_EVENT_STATE_MACRO(32)
// UI friendly version of :valid pseudo-class.
#define NS_EVENT_STATE_MOZ_UI_VALID NS_DEFINE_EVENT_STATE_MACRO(33)
/**
* NOTE: do not go over 63 without updating nsEventStates::InternalType!

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

@ -84,9 +84,10 @@ nsDOMDataTransfer::nsDOMDataTransfer()
{
}
nsDOMDataTransfer::nsDOMDataTransfer(PRUint32 aEventType, PRUint32 aAction)
nsDOMDataTransfer::nsDOMDataTransfer(PRUint32 aEventType)
: mEventType(aEventType),
mDropEffect(nsIDragService::DRAGDROP_ACTION_NONE),
mEffectAllowed(nsIDragService::DRAGDROP_ACTION_UNINITIALIZED),
mCursorState(PR_FALSE),
mReadOnly(PR_TRUE),
mIsExternal(PR_TRUE),
@ -94,11 +95,6 @@ nsDOMDataTransfer::nsDOMDataTransfer(PRUint32 aEventType, PRUint32 aAction)
mDragImageX(0),
mDragImageY(0)
{
mEffectAllowed = aAction &
(nsIDragService::DRAGDROP_ACTION_COPY |
nsIDragService::DRAGDROP_ACTION_LINK |
nsIDragService::DRAGDROP_ACTION_MOVE);
CacheExternalFormats();
}

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

@ -93,7 +93,7 @@ protected:
// that was started without using a data transfer, either an external drag,
// that is, a drag where the source is another application, or a drag
// started by calling the drag service directly.
nsDOMDataTransfer(PRUint32 aEventType, PRUint32 aAction);
nsDOMDataTransfer(PRUint32 aEventType);
// this constructor is used only by the Clone method to copy the fields as
// needed to a new data transfer.

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

@ -2790,6 +2790,7 @@ nsEventStateManager::DecideGestureEvent(nsGestureNotifyEvent* aEvent,
aEvent->panDirection = panDirection;
}
#ifdef XP_MACOSX
static bool
NodeAllowsClickThrough(nsINode* aNode)
{
@ -2810,6 +2811,7 @@ NodeAllowsClickThrough(nsINode* aNode)
}
return true;
}
#endif
NS_IMETHODIMP
nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext,

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

@ -85,7 +85,7 @@ nsIMEStateManager::OnDestroyPresContext(nsPresContext* aPresContext)
nsCOMPtr<nsIWidget> widget = GetWidget(sPresContext);
if (widget) {
PRUint32 newState = GetNewIMEState(sPresContext, nsnull);
SetIMEState(newState, widget);
SetIMEState(newState, nsnull, widget);
}
sContent = nsnull;
sPresContext = nsnull;
@ -110,7 +110,7 @@ nsIMEStateManager::OnRemoveContent(nsPresContext* aPresContext,
if (NS_FAILED(rv))
widget->ResetInputState();
PRUint32 newState = GetNewIMEState(sPresContext, nsnull);
SetIMEState(newState, widget);
SetIMEState(newState, nsnull, widget);
}
sContent = nsnull;
@ -139,12 +139,13 @@ nsIMEStateManager::OnChangeFocus(nsPresContext* aPresContext,
// the enabled state isn't changing, we should do nothing.
return NS_OK;
}
PRUint32 enabled;
if (NS_FAILED(widget->GetIMEEnabled(&enabled))) {
nsIWidget_MOZILLA_2_0_BRANCH* widget2 = static_cast<nsIWidget_MOZILLA_2_0_BRANCH*>(widget.get());
IMEContext context;
if (!widget2 || NS_FAILED(widget2->GetInputMode(context))) {
// this platform doesn't support IME controlling
return NS_OK;
}
if (enabled ==
if (context.mStatus ==
nsContentUtils::GetWidgetStatusFromIMEStatus(newEnabledState)) {
// the enabled state isn't changing.
return NS_OK;
@ -164,7 +165,7 @@ nsIMEStateManager::OnChangeFocus(nsPresContext* aPresContext,
if (newState != nsIContent::IME_STATUS_NONE) {
// Update IME state for new focus widget
SetIMEState(newState, widget);
SetIMEState(newState, aContent, widget);
}
sPresContext = aPresContext;
@ -181,7 +182,7 @@ nsIMEStateManager::OnInstalledMenuKeyboardListener(PRBool aInstalling)
}
void
nsIMEStateManager::UpdateIMEState(PRUint32 aNewIMEState)
nsIMEStateManager::UpdateIMEState(PRUint32 aNewIMEState, nsIContent* aContent)
{
if (!sPresContext) {
NS_WARNING("ISM doesn't know which editor has focus");
@ -195,13 +196,14 @@ nsIMEStateManager::UpdateIMEState(PRUint32 aNewIMEState)
}
// Don't update IME state when enabled state isn't actually changed.
PRUint32 currentEnabledState;
nsresult rv = widget->GetIMEEnabled(&currentEnabledState);
nsIWidget_MOZILLA_2_0_BRANCH* widget2 = static_cast<nsIWidget_MOZILLA_2_0_BRANCH*>(widget.get());
IMEContext context;
nsresult rv = widget2->GetInputMode(context);
if (NS_FAILED(rv)) {
return; // This platform doesn't support controling the IME state.
}
PRUint32 newEnabledState = aNewIMEState & nsIContent::IME_STATUS_MASK_ENABLED;
if (currentEnabledState ==
if (context.mStatus ==
nsContentUtils::GetWidgetStatusFromIMEStatus(newEnabledState)) {
return;
}
@ -209,7 +211,7 @@ nsIMEStateManager::UpdateIMEState(PRUint32 aNewIMEState)
// commit current composition
widget->ResetInputState();
SetIMEState(aNewIMEState, widget);
SetIMEState(aNewIMEState, aContent, widget);
}
PRUint32
@ -261,12 +263,28 @@ private:
void
nsIMEStateManager::SetIMEState(PRUint32 aState,
nsIContent* aContent,
nsIWidget* aWidget)
{
if (aState & nsIContent::IME_STATUS_MASK_ENABLED) {
PRUint32 state =
nsContentUtils::GetWidgetStatusFromIMEStatus(aState);
aWidget->SetIMEEnabled(state);
nsIWidget_MOZILLA_2_0_BRANCH* widget2 = static_cast<nsIWidget_MOZILLA_2_0_BRANCH*>(aWidget);
if (!widget2)
return;
PRUint32 state = nsContentUtils::GetWidgetStatusFromIMEStatus(aState);
IMEContext context;
context.mStatus = state;
if (aContent && aContent->GetNameSpaceID() == kNameSpaceID_XHTML &&
(aContent->Tag() == nsGkAtoms::input ||
aContent->Tag() == nsGkAtoms::textarea)) {
aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::type,
context.mHTMLInputType);
aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::moz_action_hint,
context.mActionHint);
}
widget2->SetInputMode(context);
nsContentUtils::AddScriptRunner(new IMEEnabledStateChangedEvent(state));
}

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

@ -86,10 +86,11 @@ public:
// widget. So, the caller must have focus.
// aNewIMEState must have an enabled state of nsIContent::IME_STATUS_*.
// And optionally, it can have an open state of nsIContent::IME_STATUS_*.
static void UpdateIMEState(PRUint32 aNewIMEState);
static void UpdateIMEState(PRUint32 aNewIMEState, nsIContent* aContent);
protected:
static void SetIMEState(PRUint32 aState, nsIWidget* aWidget);
static void SetIMEState(PRUint32 aState, nsIContent* aContent,
nsIWidget* aWidget);
static PRUint32 GetNewIMEState(nsPresContext* aPresContext,
nsIContent* aContent);

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

@ -0,0 +1,21 @@
<!DOCTYPE html>
<html>
<head>
<script>
function boom()
{
var a = document.createElementNS("http://www.w3.org/1999/xhtml", "fieldset");
var b = document.createElementNS("http://www.w3.org/1999/xhtml", "legend");
var c = document.createElementNS("http://www.w3.org/1999/xhtml", "input");
a.appendChild(b);
a.appendChild(c);
a.removeChild(b);
c.expandoQ = a;
}
</script>
</head>
<body onload="boom();"></body>
</html>

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

@ -22,3 +22,4 @@ load 596785-1.html
load 596785-2.html
load 606430-1.html
load 602117.html
load 613027.html

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

@ -162,9 +162,12 @@ public:
* if there is no encoder).
* @param aStr the string to encode
* @param aResult the encoded string [OUT]
* @param aHeaderEncode If true, turns all linebreaks into spaces and escapes
* all quotes
* @throws an error if UnicodeToNewBytes fails
*/
nsresult EncodeVal(const nsAString& aStr, nsACString& aResult);
nsresult EncodeVal(const nsAString& aStr, nsCString& aResult,
bool aHeaderEncode);
private:
// The encoder that will encode Unicode names and values

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

@ -49,7 +49,6 @@
#include "nsILoadGroup.h"
#include "nsIObserver.h"
#include "ImageLayers.h"
#include "nsAudioStream.h"
// Define to output information on decoding and painting framerate
@ -64,6 +63,10 @@ class nsHTMLMediaElement : public nsGenericHTMLElement,
typedef mozilla::layers::ImageContainer ImageContainer;
public:
typedef mozilla::TimeStamp TimeStamp;
typedef mozilla::TimeDuration TimeDuration;
enum CanPlayStatus {
CANPLAY_NO,
CANPLAY_MAYBE,
@ -339,6 +342,14 @@ public:
*/
void SetRequestHeaders(nsIHttpChannel* aChannel);
/**
* Fires a timeupdate event. If aPeriodic is PR_TRUE, the event will only
* be fired if we've not fired a timeupdate event (for any reason) in the
* last 250ms, as required by the spec when the current time is periodically
* increasing during playback.
*/
void FireTimeUpdate(PRBool aPeriodic);
protected:
class MediaLoadListener;
@ -591,6 +602,14 @@ protected:
// it changes. Defaults to a width and height of -1 inot set.
nsIntSize mMediaSize;
// Time that the last timeupdate event was fired. Read/Write from the
// main thread only.
TimeStamp mTimeUpdateTime;
// Media 'currentTime' value when the last timeupdate event occurred.
// Read/Write from the main thread only.
float mLastCurrentTime;
nsRefPtr<gfxASurface> mPrintSurface;
// Reference to the source element last returned by GetNextSource().

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

@ -391,7 +391,7 @@ nsFSURLEncoded::URLEncode(const nsAString& aStr, nsCString& aEncoded)
NS_ENSURE_TRUE(convertedBuf, NS_ERROR_OUT_OF_MEMORY);
nsCAutoString encodedBuf;
nsresult rv = EncodeVal(nsDependentString(convertedBuf), encodedBuf);
nsresult rv = EncodeVal(nsDependentString(convertedBuf), encodedBuf, false);
nsMemory::Free(convertedBuf);
NS_ENSURE_SUCCESS(rv, rv);
@ -441,7 +441,7 @@ nsFSMultipartFormData::AddNameValuePair(const nsAString& aName,
{
nsCString valueStr;
nsCAutoString encodedVal;
nsresult rv = EncodeVal(aValue, encodedVal);
nsresult rv = EncodeVal(aValue, encodedVal, false);
NS_ENSURE_SUCCESS(rv, rv);
valueStr.Adopt(nsLinebreakConverter::
@ -450,7 +450,7 @@ nsFSMultipartFormData::AddNameValuePair(const nsAString& aName,
nsLinebreakConverter::eLinebreakNet));
nsCAutoString nameStr;
rv = EncodeVal(aName, nameStr);
rv = EncodeVal(aName, nameStr, true);
NS_ENSURE_SUCCESS(rv, rv);
// Make MIME block for name/value pair
@ -473,34 +473,32 @@ nsFSMultipartFormData::AddNameFilePair(const nsAString& aName,
{
// Encode the control name
nsCAutoString nameStr;
nsresult rv = EncodeVal(aName, nameStr);
nsresult rv = EncodeVal(aName, nameStr, true);
NS_ENSURE_SUCCESS(rv, rv);
nsCString filenameStr;
nsAutoString contentType;
nsCString filename, contentType;
nsCOMPtr<nsIInputStream> fileStream;
if (aBlob) {
// Get and encode the filename
nsAutoString filename;
nsAutoString filename16;
nsCOMPtr<nsIDOMFile> file = do_QueryInterface(aBlob);
if (file) {
rv = file->GetName(filename);
rv = file->GetName(filename16);
NS_ENSURE_SUCCESS(rv, rv);
}
nsCAutoString encodedFileName;
rv = EncodeVal(filename, encodedFileName);
rv = EncodeVal(filename16, filename, true);
NS_ENSURE_SUCCESS(rv, rv);
filenameStr.Adopt(nsLinebreakConverter::
ConvertLineBreaks(encodedFileName.get(),
nsLinebreakConverter::eLinebreakAny,
nsLinebreakConverter::eLinebreakNet));
// Get content type
rv = aBlob->GetType(contentType);
if (NS_FAILED(rv) || contentType.IsEmpty()) {
contentType.AssignLiteral("application/octet-stream");
nsAutoString contentType16;
rv = aBlob->GetType(contentType16);
if (NS_FAILED(rv) || contentType16.IsEmpty()) {
contentType16.AssignLiteral("application/octet-stream");
}
contentType.Adopt(nsLinebreakConverter::
ConvertLineBreaks(NS_ConvertUTF16toUTF8(contentType16).get(),
nsLinebreakConverter::eLinebreakAny,
nsLinebreakConverter::eLinebreakSpace));
// Get input stream
rv = aBlob->GetInternalStream(getter_AddRefs(fileStream));
@ -531,10 +529,9 @@ nsFSMultipartFormData::AddNameFilePair(const nsAString& aName,
mPostDataChunk +=
NS_LITERAL_CSTRING("Content-Disposition: form-data; name=\"")
+ nameStr + NS_LITERAL_CSTRING("\"; filename=\"")
+ filenameStr + NS_LITERAL_CSTRING("\"" CRLF)
+ NS_LITERAL_CSTRING("Content-Type: ");
AppendUTF16toUTF8(contentType, mPostDataChunk);
mPostDataChunk += NS_LITERAL_CSTRING(CRLF CRLF);
+ filename + NS_LITERAL_CSTRING("\"" CRLF)
+ NS_LITERAL_CSTRING("Content-Type: ")
+ contentType + NS_LITERAL_CSTRING(CRLF CRLF);
// Add the file to the stream
if (fileStream) {
@ -669,10 +666,20 @@ nsFSTextPlain::GetEncodedSubmission(nsIURI* aURI,
rv = aURI->SetPath(path);
} else {
// Create data stream
// Create data stream.
// We do want to send the data through the charset encoder and we want to
// normalize linebreaks to use the "standard net" format (\r\n), but we
// don't want to perform any other encoding. This means that names and
// values which contains '=' or newlines are potentially ambigiously
// encoded, but that how text/plain is specced.
nsCString cbody;
EncodeVal(mBody, cbody, false);
cbody.Adopt(nsLinebreakConverter::
ConvertLineBreaks(cbody.get(),
nsLinebreakConverter::eLinebreakAny,
nsLinebreakConverter::eLinebreakNet));
nsCOMPtr<nsIInputStream> bodyStream;
rv = NS_NewStringInputStream(getter_AddRefs(bodyStream),
mBody);
rv = NS_NewCStringInputStream(getter_AddRefs(bodyStream), cbody);
if (!bodyStream) {
return NS_ERROR_OUT_OF_MEMORY;
}
@ -730,17 +737,30 @@ nsEncodingFormSubmission::~nsEncodingFormSubmission()
// i18n helper routines
nsresult
nsEncodingFormSubmission::EncodeVal(const nsAString& aStr, nsACString& aOut)
nsEncodingFormSubmission::EncodeVal(const nsAString& aStr, nsCString& aOut,
bool aHeaderEncode)
{
if (mEncoder) {
if (mEncoder && !aStr.IsEmpty()) {
aOut.Truncate();
return aStr.IsEmpty() ? NS_OK :
mEncoder->Convert(PromiseFlatString(aStr).get(),
getter_Copies(aOut));
nsresult rv = mEncoder->Convert(PromiseFlatString(aStr).get(),
getter_Copies(aOut));
NS_ENSURE_SUCCESS(rv, rv);
}
else {
// fall back to UTF-8
CopyUTF16toUTF8(aStr, aOut);
}
// fall back to UTF-8
CopyUTF16toUTF8(aStr, aOut);
if (aHeaderEncode) {
aOut.Adopt(nsLinebreakConverter::
ConvertLineBreaks(aOut.get(),
nsLinebreakConverter::eLinebreakAny,
nsLinebreakConverter::eLinebreakSpace));
aOut.ReplaceSubstring(NS_LITERAL_CSTRING("\""),
NS_LITERAL_CSTRING("\\\""));
}
return NS_OK;
}

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

@ -653,10 +653,12 @@ nsHTMLButtonElement::AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
UpdateBarredFromConstraintValidation();
states |= NS_EVENT_STATE_VALID | NS_EVENT_STATE_INVALID |
NS_EVENT_STATE_MOZ_UI_VALID | NS_EVENT_STATE_MOZ_UI_INVALID |
NS_EVENT_STATE_MOZ_SUBMITINVALID;
} else if (aName == nsGkAtoms::disabled) {
UpdateBarredFromConstraintValidation();
states |= NS_EVENT_STATE_VALID | NS_EVENT_STATE_INVALID;
states |= NS_EVENT_STATE_VALID | NS_EVENT_STATE_INVALID |
NS_EVENT_STATE_MOZ_UI_VALID | NS_EVENT_STATE_MOZ_UI_INVALID;
}
if (aNotify && !states.IsEmpty()) {
@ -706,7 +708,8 @@ nsHTMLButtonElement::IntrinsicState() const
nsEventStates state = nsGenericHTMLFormElement::IntrinsicState();
if (IsCandidateForConstraintValidation()) {
state |= IsValid() ? NS_EVENT_STATE_VALID : NS_EVENT_STATE_INVALID;
state |= IsValid() ? NS_EVENT_STATE_VALID | NS_EVENT_STATE_MOZ_UI_VALID
: NS_EVENT_STATE_INVALID | NS_EVENT_STATE_MOZ_UI_INVALID;
}
if (mForm && !mForm->GetValidity() && IsSubmitControl()) {
@ -727,7 +730,9 @@ nsHTMLButtonElement::SetCustomValidity(const nsAString& aError)
if (doc) {
MOZ_AUTO_DOC_UPDATE(doc, UPDATE_CONTENT_STATE, PR_TRUE);
doc->ContentStatesChanged(this, nsnull, NS_EVENT_STATE_INVALID |
NS_EVENT_STATE_VALID);
NS_EVENT_STATE_VALID |
NS_EVENT_STATE_MOZ_UI_INVALID |
NS_EVENT_STATE_MOZ_UI_VALID);
}
return NS_OK;
@ -746,7 +751,8 @@ nsHTMLButtonElement::FieldSetDisabledChanged(nsEventStates aStates, PRBool aNoti
{
UpdateBarredFromConstraintValidation();
aStates |= NS_EVENT_STATE_VALID | NS_EVENT_STATE_INVALID;
aStates |= NS_EVENT_STATE_VALID | NS_EVENT_STATE_INVALID |
NS_EVENT_STATE_MOZ_UI_VALID | NS_EVENT_STATE_MOZ_UI_INVALID;
nsGenericHTMLFormElement::FieldSetDisabledChanged(aStates, aNotify);
}

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

@ -66,7 +66,8 @@ nsHTMLFieldSetElement::~nsHTMLFieldSetElement()
// nsISupports
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsHTMLFieldSetElement)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsHTMLFieldSetElement,
nsGenericHTMLFormElement)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mElements)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
@ -82,7 +83,7 @@ NS_IMPL_RELEASE_INHERITED(nsHTMLFieldSetElement, nsGenericElement)
DOMCI_NODE_DATA(HTMLFieldSetElement, nsHTMLFieldSetElement)
// QueryInterface implementation for nsHTMLFieldSetElement
NS_INTERFACE_TABLE_HEAD(nsHTMLFieldSetElement)
NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(nsHTMLFieldSetElement)
NS_HTML_CONTENT_INTERFACE_TABLE2(nsHTMLFieldSetElement,
nsIDOMHTMLFieldSetElement,
nsIConstraintValidation)

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

@ -55,7 +55,7 @@ public:
virtual ~nsHTMLFieldSetElement();
// nsISupports
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_ISUPPORTS_INHERITED
// nsIDOMNode
NS_FORWARD_NSIDOMNODE(nsGenericHTMLFormElement::)

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

@ -265,7 +265,8 @@ nsHTMLFormElement::nsHTMLFormElement(already_AddRefed<nsINodeInfo> aNodeInfo)
mDefaultSubmitElement(nsnull),
mFirstSubmitInElements(nsnull),
mFirstSubmitNotInElements(nsnull),
mInvalidElementsCount(0)
mInvalidElementsCount(0),
mEverTriedInvalidSubmit(false)
{
}
@ -477,6 +478,10 @@ CollectOrphans(nsINode* aRemovalRoot, nsTArray<nsGenericHTMLFormElement*> aArray
#endif
)
{
// Prepare document update batch.
nsIDocument* doc = aArray.IsEmpty() ? nsnull : aArray[0]->GetCurrentDoc();
MOZ_AUTO_DOC_UPDATE(doc, UPDATE_CONTENT_STATE, PR_TRUE);
// Walk backwards so that if we remove elements we can just keep iterating
PRUint32 length = aArray.Length();
for (PRUint32 i = length; i > 0; --i) {
@ -495,14 +500,19 @@ CollectOrphans(nsINode* aRemovalRoot, nsTArray<nsGenericHTMLFormElement*> aArray
if (!nsContentUtils::ContentIsDescendantOf(node, aRemovalRoot)) {
node->ClearForm(PR_TRUE);
// When submit controls have no more form, they need to be updated.
// When a form control loses its form owner, :-moz-ui-invalid and
// :-moz-ui-valid might not apply any more.
nsEventStates states = NS_EVENT_STATE_MOZ_UI_VALID |
NS_EVENT_STATE_MOZ_UI_INVALID;
// In addition, submit controls shouldn't have
// NS_EVENT_STATE_MOZ_SUBMITINVALID applying if they do not have a form.
if (node->IsSubmitControl()) {
nsIDocument* doc = node->GetCurrentDoc();
if (doc) {
MOZ_AUTO_DOC_UPDATE(doc, UPDATE_CONTENT_STATE, PR_TRUE);
doc->ContentStatesChanged(node, nsnull,
NS_EVENT_STATE_MOZ_SUBMITINVALID);
}
states |= NS_EVENT_STATE_MOZ_SUBMITINVALID;
}
if (doc) {
doc->ContentStatesChanged(node, nsnull, states);
}
#ifdef DEBUG
removed = PR_TRUE;
@ -1624,10 +1634,6 @@ nsHTMLFormElement::CheckFormValidity(nsIMutableArray* aInvalidElements) const
}
for (PRUint32 i = 0; i < len; ++i) {
if (!sortedControls[i]->IsSubmittableControl()) {
continue;
}
nsCOMPtr<nsIConstraintValidation> cvElmt =
do_QueryInterface((nsGenericHTMLElement*)sortedControls[i]);
if (cvElmt && cvElmt->IsCandidateForConstraintValidation() &&
@ -1701,6 +1707,41 @@ nsHTMLFormElement::CheckValidFormSubmission()
NS_ENSURE_SUCCESS(rv, rv);
if (!CheckFormValidity(invalidElements.get())) {
// For the first invalid submission, we should update element states.
// We have to do that _before_ calling the observers so we are sure they
// will not interfere (like focusing the element).
if (!mEverTriedInvalidSubmit) {
mEverTriedInvalidSubmit = true;
nsIDocument* doc = GetCurrentDoc();
if (doc) {
/*
* We are going to call ContentStatesChanged assuming elements want to
* be notified because we can't know.
* Submissions shouldn't happen during parsing so it _should_ be safe.
*/
MOZ_AUTO_DOC_UPDATE(doc, UPDATE_CONTENT_STATE, PR_TRUE);
for (PRUint32 i = 0, length = mControls->mElements.Length();
i < length; ++i) {
doc->ContentStatesChanged(mControls->mElements[i], nsnull,
NS_EVENT_STATE_MOZ_UI_VALID |
NS_EVENT_STATE_MOZ_UI_INVALID);
}
// Because of backward compatibility, <input type='image'> is not in
// elements but can be invalid.
// TODO: should probably be removed when bug 606491 will be fixed.
for (PRUint32 i = 0, length = mControls->mNotInElements.Length();
i < length; ++i) {
doc->ContentStatesChanged(mControls->mNotInElements[i], nsnull,
NS_EVENT_STATE_MOZ_UI_VALID |
NS_EVENT_STATE_MOZ_UI_INVALID);
}
}
}
nsCOMPtr<nsISupports> inst;
nsCOMPtr<nsIFormSubmitObserver> observer;
PRBool more = PR_TRUE;
@ -1709,10 +1750,8 @@ nsHTMLFormElement::CheckValidFormSubmission()
observer = do_QueryInterface(inst);
if (observer) {
rv = observer->
NotifyInvalidSubmit(this,
static_cast<nsIArray*>(invalidElements));
NS_ENSURE_SUCCESS(rv, rv);
observer->NotifyInvalidSubmit(this,
static_cast<nsIArray*>(invalidElements));
}
}

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