зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to tracemonkey.
This commit is contained in:
Коммит
88e6ba5ed6
|
@ -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)
|
||||
|
||||
|
|
86
configure.in
86
configure.in
|
@ -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(¤tEnabledState);
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче