diff --git a/accessible/public/nsIAccessibilityService.idl b/accessible/public/nsIAccessibilityService.idl index 5dafbaa1eb69..49d4bf2ad98d 100644 --- a/accessible/public/nsIAccessibilityService.idl +++ b/accessible/public/nsIAccessibilityService.idl @@ -46,7 +46,7 @@ interface nsObjectFrame; interface nsIContent; interface nsITimer; -[uuid(29384ba1-f9ce-425d-afb5-54e2ee949d87)] +[uuid(61098f48-4fcc-4b05-9cf3-c11b8efbe682)] interface nsIAccessibilityService : nsIAccessibleRetrieval { nsIAccessible createOuterDocAccessible(in nsIDOMNode aNode); @@ -76,9 +76,18 @@ interface nsIAccessibilityService : nsIAccessibleRetrieval nsIAccessible createHTMLTextFieldAccessible(in nsIFrame aFrame); nsIAccessible createHTMLCaptionAccessible(in nsIFrame aFrame); - nsIAccessible getAccessible(in nsIDOMNode aNode, in nsIPresShell aPresShell, - in nsIWeakReference aWeakShell, - inout nsIFrame frameHint, out boolean aIsHidden); + /** + * Return an accessible for the given DOM node. + * + * @param aNode [in] the given node + * @param aPresShell [in] the pres shell of the node + * @param aWeakShell [in] the weak shell for the pres shell + * @param aFrameHint [in] the frame of the given node + * @param aIsHidden [out] indicates whether the node's frame is hidden + */ + nsIAccessible getAccessible(in nsIDOMNode aNode, in nsIPresShell aPresShell, + in nsIWeakReference aWeakShell, + in nsIFrame aFrameHint, out boolean aIsHidden); // For gtk+ native window accessible nsIAccessible addNativeRootAccessible(in voidPtr aAtkAccessible); diff --git a/accessible/src/atk/nsApplicationAccessibleWrap.cpp b/accessible/src/atk/nsApplicationAccessibleWrap.cpp index 4d059cb70fd7..592776054a18 100644 --- a/accessible/src/atk/nsApplicationAccessibleWrap.cpp +++ b/accessible/src/atk/nsApplicationAccessibleWrap.cpp @@ -647,8 +647,7 @@ nsApplicationAccessibleWrap::AddRootAccessible(nsIAccessible *aRootAccWrap) AtkObject *atkAccessible = nsAccessibleWrap::GetAtkObject(aRootAccWrap); atk_object_set_parent(atkAccessible, mAtkObject); - PRUint32 count = 0; - mChildren->GetLength(&count); + PRUint32 count = mChildren.Count(); g_signal_emit_by_name(mAtkObject, "children_changed::add", count - 1, atkAccessible, NULL); @@ -670,36 +669,27 @@ nsApplicationAccessibleWrap::RemoveRootAccessible(nsIAccessible *aRootAccWrap) { NS_ENSURE_ARG_POINTER(aRootAccWrap); - PRUint32 index = 0; - nsresult rv = NS_ERROR_FAILURE; - - // we must use weak ref to get the index - nsCOMPtr weakPtr = do_GetWeakReference(aRootAccWrap); - rv = mChildren->IndexOf(0, weakPtr, &index); + PRInt32 index = mChildren.IndexOf(aRootAccWrap); AtkObject *atkAccessible = nsAccessibleWrap::GetAtkObject(aRootAccWrap); atk_object_set_parent(atkAccessible, NULL); g_signal_emit_by_name(mAtkObject, "children_changed::remove", index, atkAccessible, NULL); + nsresult rv = nsApplicationAccessible::RemoveRootAccessible(aRootAccWrap); + #ifdef MAI_LOGGING - PRUint32 count = 0; - mChildren->GetLength(&count); + PRUint32 count = mChildren.Count(); if (NS_SUCCEEDED(rv)) { - rv = mChildren->RemoveElementAt(index); MAI_LOG_DEBUG(("\nRemove RootAcc=%p, count=%d\n", (void*)aRootAccWrap, (count-1))); } else MAI_LOG_DEBUG(("\nFail to Remove RootAcc=%p, count=%d\n", (void*)aRootAccWrap, count)); -#else - NS_ENSURE_SUCCESS(rv, rv); - rv = mChildren->RemoveElementAt(index); - #endif - InvalidateChildren(); + return rv; } diff --git a/accessible/src/base/nsAccUtils.cpp b/accessible/src/base/nsAccUtils.cpp index faf287e008dd..65be3a3d5d1d 100644 --- a/accessible/src/base/nsAccUtils.cpp +++ b/accessible/src/base/nsAccUtils.cpp @@ -502,6 +502,46 @@ nsAccUtils::GetARIATreeItemParent(nsIAccessible *aStartTreeItem, } } +already_AddRefed +nsAccUtils::GetSelectableContainer(nsIAccessible *aAccessible, PRUint32 aState) +{ + if (!aAccessible) + return nsnull; + + if (!(aState & nsIAccessibleStates::STATE_SELECTABLE)) + return nsnull; + + nsCOMPtr container; + nsCOMPtr parent, accessible(aAccessible); + while (!container) { + accessible->GetParent(getter_AddRefs(parent)); + + if (!parent || Role(parent) == nsIAccessibleRole::ROLE_PANE) + return nsnull; + + container = do_QueryInterface(parent); + parent.swap(accessible); + } + + return accessible.forget(); +} + +already_AddRefed +nsAccUtils::GetMultiSelectableContainer(nsIDOMNode *aNode) +{ + nsCOMPtr accessible; + nsAccessNode::GetAccService()->GetAccessibleFor(aNode, + getter_AddRefs(accessible)); + + nsCOMPtr container = + GetSelectableContainer(accessible, State(accessible)); + + if (State(container) & nsIAccessibleStates::STATE_MULTISELECTABLE) + return container.forget(); + + return nsnull; +} + PRBool nsAccUtils::IsARIASelected(nsIAccessible *aAccessible) { @@ -927,37 +967,6 @@ nsAccUtils::IsNodeRelevant(nsIDOMNode *aNode) return aNode == relevantNode; } -already_AddRefed -nsAccUtils::GetMultiSelectFor(nsIDOMNode *aNode) -{ - if (!aNode) - return nsnull; - - nsCOMPtr accessible; - nsAccessNode::GetAccService()->GetAccessibleFor(aNode, - getter_AddRefs(accessible)); - if (!accessible) - return nsnull; - - PRUint32 state = State(accessible); - if (0 == (state & nsIAccessibleStates::STATE_SELECTABLE)) - return nsnull; - - while (0 == (state & nsIAccessibleStates::STATE_MULTISELECTABLE)) { - nsIAccessible *current = accessible; - current->GetParent(getter_AddRefs(accessible)); - if (!accessible || - nsAccUtils::Role(accessible) == nsIAccessibleRole::ROLE_PANE) { - return nsnull; - } - state = State(accessible); - } - - nsIAccessible *returnAccessible = nsnull; - accessible.swap(returnAccessible); - return returnAccessible; -} - nsresult nsAccUtils::GetHeaderCellsFor(nsIAccessibleTable *aTable, nsIAccessibleTableCell *aCell, diff --git a/accessible/src/base/nsAccUtils.h b/accessible/src/base/nsAccUtils.h index 282b14a951c7..675c7397bb4e 100644 --- a/accessible/src/base/nsAccUtils.h +++ b/accessible/src/base/nsAccUtils.h @@ -179,6 +179,21 @@ public: nsIContent *aStartTreeItemContent, nsIAccessible **aTreeItemParent); + /** + * Return single or multi selectable container for the given item. + * + * @param aAccessible [in] the item accessible + * @param aState [in] the state of the item accessible + */ + static already_AddRefed + GetSelectableContainer(nsIAccessible *aAccessible, PRUint32 aState); + + /** + * Return multi selectable container for the given item. + */ + static already_AddRefed + GetMultiSelectableContainer(nsIDOMNode *aNode); + /** * Return true if the DOM node of given accessible has aria-selected="true" * attribute. @@ -467,11 +482,6 @@ public: */ static PRBool IsNodeRelevant(nsIDOMNode *aNode); - /** - * Return multiselectable parent for the given selectable accessible if any. - */ - static already_AddRefed GetMultiSelectFor(nsIDOMNode *aNode); - /** * Search hint enum constants. Used by GetHeaderCellsFor() method. */ diff --git a/accessible/src/base/nsAccessibilityService.cpp b/accessible/src/base/nsAccessibilityService.cpp index df05ef6b63ec..48770a5798ac 100644 --- a/accessible/src/base/nsAccessibilityService.cpp +++ b/accessible/src/base/nsAccessibilityService.cpp @@ -1242,10 +1242,9 @@ NS_IMETHODIMP nsAccessibilityService::GetAccessibleInShell(nsIDOMNode *aNode, NS_ENSURE_ARG(aPresShell); nsCOMPtr weakShell(do_GetWeakReference(aPresShell)); - nsIFrame *outFrameUnused = NULL; PRBool isHiddenUnused = false; return GetAccessible(aNode, aPresShell, weakShell, - &outFrameUnused, &isHiddenUnused, aAccessible); + nsnull, &isHiddenUnused, aAccessible); } NS_IMETHODIMP nsAccessibilityService::GetAccessibleInWeakShell(nsIDOMNode *aNode, @@ -1259,10 +1258,9 @@ NS_IMETHODIMP nsAccessibilityService::GetAccessibleInWeakShell(nsIDOMNode *aNode NS_ENSURE_ARG(aWeakShell); nsCOMPtr presShell(do_QueryReferent(aWeakShell)); - nsIFrame *outFrameUnused = NULL; PRBool isHiddenUnused = false; return GetAccessible(aNode, presShell, aWeakShell, - &outFrameUnused, &isHiddenUnused, aAccessible); + nsnull, &isHiddenUnused, aAccessible); } nsresult nsAccessibilityService::InitAccessible(nsIAccessible *aAccessibleIn, @@ -1315,13 +1313,13 @@ static PRBool HasRelatedContent(nsIContent *aContent) NS_IMETHODIMP nsAccessibilityService::GetAccessible(nsIDOMNode *aNode, nsIPresShell *aPresShell, nsIWeakReference *aWeakShell, - nsIFrame **aFrameHint, + nsIFrame *aFrameHint, PRBool *aIsHidden, nsIAccessible **aAccessible) { NS_ENSURE_ARG_POINTER(aAccessible); - NS_ENSURE_ARG_POINTER(aFrameHint); *aAccessible = nsnull; + if (!aPresShell || !aWeakShell || gIsShutdown) { return NS_ERROR_FAILURE; } @@ -1334,7 +1332,7 @@ NS_IMETHODIMP nsAccessibilityService::GetAccessible(nsIDOMNode *aNode, // that can flush layout, either directly, or via DOM manipulation, or some // CSS styles like :hover. We use the weak frame checks to avoid calling // methods on a dead frame pointer. - nsWeakFrame weakFrame(*aFrameHint); + nsWeakFrame weakFrame(aFrameHint); #ifdef DEBUG_A11Y // Please leave this in for now, it's a convenient debugging method @@ -1391,7 +1389,6 @@ NS_IMETHODIMP nsAccessibilityService::GetAccessible(nsIDOMNode *aNode, CreateRootAccessible(aPresShell, nodeIsDoc, getter_AddRefs(newAcc)); // Does Init() for us } - *aFrameHint = aPresShell->GetRootFrame(); NS_IF_ADDREF(*aAccessible = newAcc); return NS_OK; } @@ -1421,7 +1418,7 @@ NS_IMETHODIMP nsAccessibilityService::GetAccessible(nsIDOMNode *aNode, if (content->IsNodeOfType(nsINode::eTEXT)) { ++frameHintFailedForText; } - frameHintNonexistant += !*aFrameHint; + frameHintNonexistant += !aFrameHint; printf("Frame hint failures: %d / %d . Text fails = %d. No hint fails = %d \n", frameHintFailed, frameHintTried, frameHintFailedForText, frameHintNonexistant); if (frameHintTried >= 354) { printf("* "); // Aaron's break point @@ -1450,7 +1447,6 @@ NS_IMETHODIMP nsAccessibilityService::GetAccessible(nsIDOMNode *aNode, return NS_OK; } - *aFrameHint = weakFrame.GetFrame(); } } @@ -1460,10 +1456,8 @@ NS_IMETHODIMP nsAccessibilityService::GetAccessible(nsIDOMNode *aNode, *aIsHidden = PR_TRUE; } - if (*aIsHidden) { - *aFrameHint = weakFrame.GetFrame(); + if (*aIsHidden) return NS_OK; - } /** * Attempt to create an accessible based on what we know @@ -1477,7 +1471,6 @@ NS_IMETHODIMP nsAccessibilityService::GetAccessible(nsIDOMNode *aNode, if (renderedWhitespace.IsEmpty()) { // Really empty -- nothing is rendered *aIsHidden = PR_TRUE; - *aFrameHint = weakFrame.GetFrame(); return NS_OK; } } @@ -1485,9 +1478,7 @@ NS_IMETHODIMP nsAccessibilityService::GetAccessible(nsIDOMNode *aNode, weakFrame.GetFrame()->GetAccessible(getter_AddRefs(newAcc)); } - nsresult rv = InitAccessible(newAcc, aAccessible, nsnull); - *aFrameHint = weakFrame.GetFrame(); - return rv; + return InitAccessible(newAcc, aAccessible, nsnull); } PRBool isHTML = content->IsHTML(); @@ -1504,16 +1495,12 @@ NS_IMETHODIMP nsAccessibilityService::GetAccessible(nsIDOMNode *aNode, content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::name, name); if (!name.IsEmpty()) { *aIsHidden = PR_TRUE; - *aFrameHint = weakFrame.GetFrame(); return NS_OK; } nsresult rv = CreateHyperTextAccessible(weakFrame.GetFrame(), getter_AddRefs(newAcc)); - if (NS_FAILED(rv)) { - *aFrameHint = weakFrame.GetFrame(); - return rv; - } + NS_ENSURE_SUCCESS(rv, rv); } nsRoleMapEntry *roleMapEntry = nsAccUtils::GetRoleMapEntry(aNode); @@ -1522,7 +1509,6 @@ NS_IMETHODIMP nsAccessibilityService::GetAccessible(nsIDOMNode *aNode, // Only create accessible for role of "presentation" if it is focusable -- // in that case we need an accessible in case it gets focused, we // don't want focus ever to be 'lost' - *aFrameHint = weakFrame.GetFrame(); return NS_OK; } @@ -1580,7 +1566,6 @@ NS_IMETHODIMP nsAccessibilityService::GetAccessible(nsIDOMNode *aNode, // presentation if they aren't focusable and have not explicit ARIA // role (don't create accessibles for them unless they need to fire // focus events). - *aFrameHint = weakFrame.GetFrame(); return NS_OK; } @@ -1628,10 +1613,7 @@ NS_IMETHODIMP nsAccessibilityService::GetAccessible(nsIDOMNode *aNode, nsresult rv = CreateHTMLAccessibleByMarkup(weakFrame.GetFrame(), aWeakShell, aNode, getter_AddRefs(newAcc)); - if (NS_FAILED(rv)) { - *aFrameHint = weakFrame.GetFrame(); - return rv; - } + NS_ENSURE_SUCCESS(rv, rv); if (!newAcc) { // Do not create accessible object subtrees for non-rendered table @@ -1649,7 +1631,6 @@ NS_IMETHODIMP nsAccessibilityService::GetAccessible(nsIDOMNode *aNode, // XXX This is not the ideal place for this code, but right now there // is no better place: *aIsHidden = PR_TRUE; - *aFrameHint = weakFrame.GetFrame(); return NS_OK; } f->GetAccessible(getter_AddRefs(newAcc)); // Try using frame to do it @@ -1661,10 +1642,7 @@ NS_IMETHODIMP nsAccessibilityService::GetAccessible(nsIDOMNode *aNode, // Elements may implement nsIAccessibleProvider via XBL. This allows them to // say what kind of accessible to create. nsresult rv = GetAccessibleByType(aNode, getter_AddRefs(newAcc)); - if (NS_FAILED(rv)) { - *aFrameHint = weakFrame.GetFrame(); - return rv; - } + NS_ENSURE_SUCCESS(rv, rv); } if (!newAcc) { @@ -1707,9 +1685,7 @@ NS_IMETHODIMP nsAccessibilityService::GetAccessible(nsIDOMNode *aNode, } } - nsresult rv = InitAccessible(newAcc, aAccessible, roleMapEntry); - *aFrameHint = weakFrame.GetFrame(); - return rv; + return InitAccessible(newAcc, aAccessible, roleMapEntry); } PRBool diff --git a/accessible/src/base/nsAccessible.cpp b/accessible/src/base/nsAccessible.cpp index 6280ef672ab2..e657556e329b 100644 --- a/accessible/src/base/nsAccessible.cpp +++ b/accessible/src/base/nsAccessible.cpp @@ -149,14 +149,12 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(nsAccessible) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsAccessible, nsAccessNode) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mParent) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mFirstChild) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mNextSibling) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mChildren) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsAccessible, nsAccessNode) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mParent) - NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mFirstChild) - NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mNextSibling) + NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mChildren) NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_ADDREF_INHERITED(nsAccessible, nsAccessNode) @@ -186,23 +184,19 @@ nsresult nsAccessible::QueryInterface(REFNSIID aIID, void** aInstancePtr) } if (aIID.Equals(NS_GET_IID(nsIAccessibleSelectable))) { - nsCOMPtr content(do_QueryInterface(mDOMNode)); - if (!content) { - return NS_ERROR_FAILURE; // This accessible has been shut down - } - if (content->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::role)) { - // If we have an XHTML role attribute present and the - // aria-multiselectable attribute is true, then we need - // to support nsIAccessibleSelectable + if (mRoleMapEntry && + (mRoleMapEntry->attributeMap1 == eARIAMultiSelectable || + mRoleMapEntry->attributeMap2 == eARIAMultiSelectable || + mRoleMapEntry->attributeMap3 == eARIAMultiSelectable)) { + + // If we have an ARIA role attribute present and the role allows multi + // selectable state, then we need to support nsIAccessibleSelectable. // If either attribute (role or multiselectable) change, then we'll // destroy this accessible so that we can follow COM identity rules. - nsAutoString multiselectable; - if (content->AttrValueIs(kNameSpaceID_None, nsAccessibilityAtoms::aria_multiselectable, - nsAccessibilityAtoms::_true, eCaseMatters)) { - *aInstancePtr = static_cast(this); - NS_ADDREF_THIS(); - return NS_OK; - } + + *aInstancePtr = static_cast(this); + NS_ADDREF_THIS(); + return NS_OK; } } @@ -229,8 +223,8 @@ nsresult nsAccessible::QueryInterface(REFNSIID aIID, void** aInstancePtr) } nsAccessible::nsAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell): nsAccessNodeWrap(aNode, aShell), - mParent(nsnull), mFirstChild(nsnull), mNextSibling(nsnull), mRoleMapEntry(nsnull), - mAccChildCount(eChildCountUninitialized) + mParent(nsnull), mRoleMapEntry(nsnull), + mAreChildrenInitialized(PR_FALSE) { #ifdef NS_DEBUG_X { @@ -482,39 +476,9 @@ nsAccessible::GetKeyboardShortcut(nsAString& aAccessKey) return NS_OK; } -void -nsAccessible::SetParent(nsIAccessible *aParent) -{ - if (mParent != aParent) { - // Adopt a child -- we allow this now. the new parent - // may be a dom node which wasn't previously accessible but now is. - // The old parent's children now need to be invalidated, since - // it no longer owns the child, the new parent does - nsRefPtr oldParent = nsAccUtils::QueryAccessible(mParent); - if (oldParent) - oldParent->InvalidateChildren(); - } - - mParent = aParent; -} - -void -nsAccessible::SetFirstChild(nsIAccessible *aFirstChild) -{ - mFirstChild = aFirstChild; -} - -void -nsAccessible::SetNextSibling(nsIAccessible *aNextSibling) -{ - mNextSibling = aNextSibling; -} - nsresult nsAccessible::Shutdown() { - mNextSibling = nsnull; - // Invalidate the child count and pointers to other accessibles, also make // sure none of its children point to this parent InvalidateChildren(); @@ -527,198 +491,112 @@ nsAccessible::Shutdown() return nsAccessNodeWrap::Shutdown(); } -void -nsAccessible::InvalidateChildren() -{ - // Document has transformed, reset our invalid children and child count - - // Reset the sibling pointers, they will be set up again the next time - // CacheChildren() is called. - // Note: we don't want to start creating accessibles at this point, - // so don't use GetNextSibling() here. (bug 387252) - nsRefPtr child = nsAccUtils::QueryAccessible(mFirstChild); - while (child) { - child->mParent = nsnull; - - nsCOMPtr next = child->mNextSibling; - child->mNextSibling = nsnull; - child = nsAccUtils::QueryAccessible(next); - } - - mAccChildCount = eChildCountUninitialized; - mFirstChild = nsnull; -} - NS_IMETHODIMP nsAccessible::GetParent(nsIAccessible **aParent) { - if (IsDefunct()) - return NS_ERROR_FAILURE; + NS_ENSURE_ARG_POINTER(aParent); - nsCOMPtr cachedParent = GetCachedParent(); - if (cachedParent) { - cachedParent.swap(*aParent); - return NS_OK; - } - - nsCOMPtr docAccessible(GetDocAccessible()); - NS_ENSURE_TRUE(docAccessible, NS_ERROR_FAILURE); - - return docAccessible->GetAccessibleInParentChain(mDOMNode, PR_TRUE, aParent); -} - -already_AddRefed -nsAccessible::GetCachedParent() -{ - if (IsDefunct()) - return nsnull; - - nsCOMPtr cachedParent = mParent; - return cachedParent.forget(); -} - -already_AddRefed -nsAccessible::GetCachedFirstChild() -{ - if (IsDefunct()) - return nsnull; - - nsCOMPtr cachedFirstChild = mFirstChild; - return cachedFirstChild.forget(); + NS_IF_ADDREF(*aParent = GetParent()); + return *aParent ? NS_OK : NS_ERROR_FAILURE; } /* readonly attribute nsIAccessible nextSibling; */ -NS_IMETHODIMP nsAccessible::GetNextSibling(nsIAccessible * *aNextSibling) -{ - *aNextSibling = nsnull; - if (!mWeakShell) { - // This node has been shut down - return NS_ERROR_FAILURE; - } - if (!mParent) { - nsCOMPtr parent(GetParent()); - if (parent) { - PRInt32 numChildren; - parent->GetChildCount(&numChildren); // Make sure we cache all of the children - } - } +NS_IMETHODIMP +nsAccessible::GetNextSibling(nsIAccessible **aNextSibling) +{ + NS_ENSURE_ARG_POINTER(aNextSibling); - if (mNextSibling || !mParent) { - // If no parent, don't try to calculate a new sibling - // It either means we're at the root or shutting down the parent - NS_IF_ADDREF(*aNextSibling = mNextSibling); - - return NS_OK; - } - - return NS_ERROR_FAILURE; + nsresult rv = NS_OK; + NS_IF_ADDREF(*aNextSibling = GetSiblingAtOffset(1, &rv)); + return rv; } /* readonly attribute nsIAccessible previousSibling; */ -NS_IMETHODIMP nsAccessible::GetPreviousSibling(nsIAccessible * *aPreviousSibling) +NS_IMETHODIMP +nsAccessible::GetPreviousSibling(nsIAccessible * *aPreviousSibling) { - *aPreviousSibling = nsnull; + NS_ENSURE_ARG_POINTER(aPreviousSibling); - if (!mWeakShell) { - // This node has been shut down - return NS_ERROR_FAILURE; - } - - nsCOMPtr parent; - if (NS_FAILED(GetParent(getter_AddRefs(parent))) || !parent) { - return NS_ERROR_FAILURE; - } - - nsCOMPtr testAccessible, prevSibling; - parent->GetFirstChild(getter_AddRefs(testAccessible)); - while (testAccessible && this != testAccessible) { - prevSibling = testAccessible; - prevSibling->GetNextSibling(getter_AddRefs(testAccessible)); - } - - if (!prevSibling) { - return NS_ERROR_FAILURE; - } - - NS_ADDREF(*aPreviousSibling = prevSibling); - return NS_OK; + nsresult rv = NS_OK; + NS_IF_ADDREF(*aPreviousSibling = GetSiblingAtOffset(-1, &rv)); + return rv; } /* readonly attribute nsIAccessible firstChild; */ -NS_IMETHODIMP nsAccessible::GetFirstChild(nsIAccessible * *aFirstChild) -{ - if (gIsCacheDisabled) { +NS_IMETHODIMP +nsAccessible::GetFirstChild(nsIAccessible **aFirstChild) +{ + NS_ENSURE_ARG_POINTER(aFirstChild); + *aFirstChild = nsnull; + + if (gIsCacheDisabled) InvalidateChildren(); - } - PRInt32 numChildren; - GetChildCount(&numChildren); // Make sure we cache all of the children -#ifdef DEBUG - nsRefPtr firstChild(nsAccUtils::QueryAccessible(mFirstChild)); - if (firstChild) { - nsCOMPtr realParent = firstChild->GetCachedParent(); - NS_ASSERTION(!realParent || realParent == this, - "Two accessibles have the same first child accessible."); - } -#endif + PRInt32 childCount = GetChildCount(); + NS_ENSURE_TRUE(childCount != -1, NS_ERROR_FAILURE); - NS_IF_ADDREF(*aFirstChild = mFirstChild); + if (childCount > 0) + NS_ADDREF(*aFirstChild = GetChildAt(0)); - return NS_OK; -} - - /* readonly attribute nsIAccessible lastChild; */ -NS_IMETHODIMP nsAccessible::GetLastChild(nsIAccessible * *aLastChild) -{ - GetChildAt(-1, aLastChild); return NS_OK; } -NS_IMETHODIMP nsAccessible::GetChildAt(PRInt32 aChildNum, nsIAccessible **aChild) + /* readonly attribute nsIAccessible lastChild; */ +NS_IMETHODIMP +nsAccessible::GetLastChild(nsIAccessible **aLastChild) { - // aChildNum is a zero-based index + NS_ENSURE_ARG_POINTER(aLastChild); + *aLastChild = nsnull; - PRInt32 numChildren; - GetChildCount(&numChildren); + PRInt32 childCount = GetChildCount(); + NS_ENSURE_TRUE(childCount != -1, NS_ERROR_FAILURE); - // If no children or aChildNum is larger than numChildren, return null - if (aChildNum >= numChildren || numChildren == 0 || !mWeakShell) { - *aChild = nsnull; - return NS_ERROR_FAILURE; - // If aChildNum is less than zero, set aChild to last index - } else if (aChildNum < 0) { - aChildNum = numChildren - 1; - } + NS_IF_ADDREF(*aLastChild = GetChildAt(childCount - 1)); + return NS_OK; +} - nsCOMPtr current(mFirstChild), nextSibling; - PRInt32 index = 0; +NS_IMETHODIMP +nsAccessible::GetChildAt(PRInt32 aChildIndex, nsIAccessible **aChild) +{ + NS_ENSURE_ARG_POINTER(aChild); + *aChild = nsnull; - while (current) { - nextSibling = current; - if (++index > aChildNum) { - break; - } - nextSibling->GetNextSibling(getter_AddRefs(current)); - } + PRInt32 childCount = GetChildCount(); + NS_ENSURE_TRUE(childCount != -1, NS_ERROR_FAILURE); - NS_IF_ADDREF(*aChild = nextSibling); + // If child index is negative, then return last child. + // XXX: do we really need this? + if (aChildIndex < 0) + aChildIndex = childCount - 1; + nsIAccessible* child = GetChildAt(aChildIndex); + if (!child) + return NS_ERROR_INVALID_ARG; + + NS_ADDREF(*aChild = child); return NS_OK; } // readonly attribute nsIArray children; -NS_IMETHODIMP nsAccessible::GetChildren(nsIArray **aOutChildren) +NS_IMETHODIMP +nsAccessible::GetChildren(nsIArray **aOutChildren) { + NS_ENSURE_ARG_POINTER(aOutChildren); *aOutChildren = nsnull; - nsCOMPtr children = do_CreateInstance(NS_ARRAY_CONTRACTID); - if (!children) - return NS_ERROR_FAILURE; - nsCOMPtr curChild; - while (NextChild(curChild)) { - children->AppendElement(curChild, PR_FALSE); + PRInt32 childCount = GetChildCount(); + NS_ENSURE_TRUE(childCount != -1, NS_ERROR_FAILURE); + + nsresult rv = NS_OK; + nsCOMPtr children = + do_CreateInstance(NS_ARRAY_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + + for (PRInt32 childIdx = 0; childIdx < childCount; childIdx++) { + nsIAccessible* child = GetChildAt(childIdx); + children->AppendElement(child, PR_FALSE); } - + NS_ADDREF(*aOutChildren = children); return NS_OK; } @@ -735,39 +613,6 @@ nsIAccessible *nsAccessible::NextChild(nsCOMPtr& aAccessible) return (aAccessible = nextChild); } -void nsAccessible::CacheChildren() -{ - if (!mWeakShell) { - // This node has been shut down - mAccChildCount = eChildCountUninitialized; - return; - } - - if (mAccChildCount == eChildCountUninitialized) { - mAccChildCount = 0;// Prevent reentry - PRBool allowsAnonChildren = GetAllowsAnonChildAccessibles(); - nsAccessibleTreeWalker walker(mWeakShell, mDOMNode, allowsAnonChildren); - // Seed the frame hint early while we're still on a container node. - // This is better than doing the GetPrimaryFrameFor() later on - // a text node, because text nodes aren't in the frame map. - walker.mState.frame = GetFrame(); - - nsRefPtr prevAcc; - PRInt32 childCount = 0; - walker.GetFirstChild(); - SetFirstChild(walker.mState.accessible); - - while (walker.mState.accessible) { - ++ childCount; - prevAcc = nsAccUtils::QueryAccessible(walker.mState.accessible); - prevAcc->SetParent(this); - walker.GetNextSibling(); - prevAcc->SetNextSibling(walker.mState.accessible); - } - mAccChildCount = childCount; - } -} - PRBool nsAccessible::GetAllowsAnonChildAccessibles() { @@ -775,73 +620,23 @@ nsAccessible::GetAllowsAnonChildAccessibles() } /* readonly attribute long childCount; */ -NS_IMETHODIMP nsAccessible::GetChildCount(PRInt32 *aAccChildCount) +NS_IMETHODIMP +nsAccessible::GetChildCount(PRInt32 *aChildCount) { - CacheChildren(); - *aAccChildCount = mAccChildCount; - return NS_OK; + NS_ENSURE_ARG_POINTER(aChildCount); + + *aChildCount = GetChildCount(); + return *aChildCount != -1 ? NS_OK : NS_ERROR_FAILURE; } /* readonly attribute long indexInParent; */ -NS_IMETHODIMP nsAccessible::GetIndexInParent(PRInt32 *aIndexInParent) +NS_IMETHODIMP +nsAccessible::GetIndexInParent(PRInt32 *aIndexInParent) { - *aIndexInParent = -1; - if (!mWeakShell) { - return NS_ERROR_FAILURE; - } + NS_ENSURE_ARG_POINTER(aIndexInParent); - nsCOMPtr parent; - GetParent(getter_AddRefs(parent)); - if (!parent) { - return NS_ERROR_FAILURE; - } - - nsCOMPtr sibling; - parent->GetFirstChild(getter_AddRefs(sibling)); - if (!sibling) { - return NS_ERROR_FAILURE; - } - - *aIndexInParent = 0; - while (sibling != this) { - NS_ASSERTION(sibling, "Never ran into the same child that we started from"); - - if (!sibling) - return NS_ERROR_FAILURE; - - ++*aIndexInParent; - nsCOMPtr tempAccessible; - sibling->GetNextSibling(getter_AddRefs(tempAccessible)); - sibling = tempAccessible; - } - - return NS_OK; -} - -void -nsAccessible::TestChildCache(nsIAccessible *aCachedChild) -{ -#ifdef DEBUG_A11Y - // All cached accessible nodes should be in the parent - // It will assert if not all the children were created - // when they were first cached, and no invalidation - // ever corrected parent accessible's child cache. - if (mAccChildCount <= 0) - return; - - nsCOMPtr sibling = mFirstChild; - - while (sibling != aCachedChild) { - NS_ASSERTION(sibling, "[TestChildCache] Never ran into the same child that we started from"); - if (!sibling) - return; - - nsCOMPtr tempAccessible; - sibling->GetNextSibling(getter_AddRefs(tempAccessible)); - sibling = tempAccessible; - } - -#endif + *aIndexInParent = GetIndexInParent(); + return *aIndexInParent != -1 ? NS_OK : NS_ERROR_FAILURE; } nsresult nsAccessible::GetTranslatedString(const nsAString& aKey, nsAString& aStringOut) @@ -1384,7 +1179,7 @@ NS_IMETHODIMP nsAccessible::SetSelected(PRBool aSelect) PRUint32 state = nsAccUtils::State(this); if (state & nsIAccessibleStates::STATE_SELECTABLE) { nsCOMPtr multiSelect = - nsAccUtils::GetMultiSelectFor(mDOMNode); + nsAccUtils::GetMultiSelectableContainer(mDOMNode); if (!multiSelect) { return aSelect ? TakeFocus() : NS_ERROR_FAILURE; } @@ -1414,7 +1209,7 @@ NS_IMETHODIMP nsAccessible::TakeSelection() PRUint32 state = nsAccUtils::State(this); if (state & nsIAccessibleStates::STATE_SELECTABLE) { nsCOMPtr multiSelect = - nsAccUtils::GetMultiSelectFor(mDOMNode); + nsAccUtils::GetMultiSelectableContainer(mDOMNode); if (multiSelect) { nsCOMPtr selectable = do_QueryInterface(multiSelect); selectable->ClearSelection(); @@ -3113,8 +2908,247 @@ nsAccessible::GetNameInternal(nsAString& aName) return NS_OK; } +void +nsAccessible::SetParent(nsIAccessible *aParent) +{ + NS_PRECONDITION(aParent, "This method isn't used to set null parent!"); + + if (mParent && mParent != aParent) { + // Adopt a child -- we allow this now. the new parent + // may be a dom node which wasn't previously accessible but now is. + // The old parent's children now need to be invalidated, since + // it no longer owns the child, the new parent does + NS_ASSERTION(PR_FALSE, "Adopting child!"); + nsRefPtr oldParent = nsAccUtils::QueryAccessible(mParent); + if (oldParent) + oldParent->InvalidateChildren(); + } + + mParent = aParent; +} + +void +nsAccessible::InvalidateChildren() +{ + PRInt32 childCount = mChildren.Count(); + for (PRInt32 childIdx = 0; childIdx < childCount; childIdx++) { + nsRefPtr child = + nsAccUtils::QueryObject(mChildren.ObjectAt(childIdx)); + child->mParent = nsnull; + } + + mChildren.Clear(); + mAreChildrenInitialized = PR_FALSE; +} + +nsIAccessible* +nsAccessible::GetParent() +{ + if (IsDefunct()) + return nsnull; + + if (mParent) + return mParent; + + nsCOMPtr docAccessible(GetDocAccessible()); + NS_ASSERTION(docAccessible, "No document accessible for valid accessible!"); + + if (!docAccessible) + return nsnull; + + nsCOMPtr parent; + docAccessible->GetAccessibleInParentChain(mDOMNode, PR_TRUE, + getter_AddRefs(parent)); + +#ifdef DEBUG + nsRefPtr parentAcc = nsAccUtils::QueryAccessible(parent); + NS_ASSERTION(!parentAcc->IsDefunct(), "Defunct parent!"); + + parentAcc->EnsureChildren(); + if (parent != mParent) + NS_WARNING("Bad accessible tree!"); +#endif + + return parent; +} + +nsIAccessible* +nsAccessible::GetChildAt(PRUint32 aIndex) +{ + if (EnsureChildren()) + return nsnull; + + nsIAccessible *child = mChildren.SafeObjectAt(aIndex); + if (!child) + return nsnull; + +#ifdef DEBUG + nsRefPtr childAcc = nsAccUtils::QueryAccessible(child); + nsCOMPtr realParent = childAcc->mParent; + NS_ASSERTION(!realParent || realParent == this, + "Two accessibles have the same first child accessible!"); +#endif + + return child; +} + +PRInt32 +nsAccessible::GetChildCount() +{ + return EnsureChildren() ? -1 : mChildren.Count(); +} + +PRInt32 +nsAccessible::GetIndexOf(nsIAccessible *aChild) +{ + return EnsureChildren() ? -1 : mChildren.IndexOf(aChild); +} + +PRInt32 +nsAccessible::GetIndexInParent() +{ + nsIAccessible *parent = GetParent(); + if (!parent) + return -1; + + nsRefPtr parentAcc = + nsAccUtils::QueryObject(parent); + return parentAcc->GetIndexOf(this); +} + +already_AddRefed +nsAccessible::GetCachedParent() +{ + if (IsDefunct()) + return nsnull; + + nsCOMPtr cachedParent = mParent; + return cachedParent.forget(); +} + +already_AddRefed +nsAccessible::GetCachedFirstChild() +{ + if (IsDefunct()) + return nsnull; + + nsCOMPtr cachedFirstChild = GetChildAt(0); + return cachedFirstChild.forget(); +} + + //////////////////////////////////////////////////////////////////////////////// -// nsAccessible private methods +// nsAccessible protected methods + +void +nsAccessible::CacheChildren() +{ + PRBool allowsAnonChildren = GetAllowsAnonChildAccessibles(); + nsAccessibleTreeWalker walker(mWeakShell, mDOMNode, allowsAnonChildren); + + // Seed the frame hint early while we're still on a container node. + // This is better than doing the GetPrimaryFrameFor() later on + // a text node, because text nodes aren't in the frame map. + walker.mState.frame = GetFrame(); + + walker.GetFirstChild(); + while (walker.mState.accessible) { + mChildren.AppendObject(walker.mState.accessible); + + nsRefPtr acc = + nsAccUtils::QueryObject(walker.mState.accessible); + acc->SetParent(this); + + walker.GetNextSibling(); + } +} + +void +nsAccessible::TestChildCache(nsIAccessible *aCachedChild) +{ +#ifdef DEBUG_A11Y + // All cached accessible nodes should be in the parent + // It will assert if not all the children were created + // when they were first cached, and no invalidation + // ever corrected parent accessible's child cache. + PRUint32 childCount = mChildren.Count(); + if (childCount == 0) { + NS_ASSERTION(mAreChildrenInitialized, + "Children are stored but not initailzied!"); + return; + } + + for (PRInt32 childIdx = 0; childIdx < childCount; childIdx++) { + nsIAccessible *child = GetChildAt(childIdx); + if (child == aCachedChild) + break; + } + + NS_ASSERTION(child == aCachedChild, + "[TestChildCache] cached accessible wasn't found. Wrong accessible tree!"); +#endif +} + +PRBool +nsAccessible::EnsureChildren() +{ + if (IsDefunct()) { + mAreChildrenInitialized = PR_FALSE; + return PR_TRUE; + } + + if (mAreChildrenInitialized) + return PR_FALSE; + + mAreChildrenInitialized = PR_TRUE; // Prevent reentry + CacheChildren(); + + return PR_FALSE; +} + +nsIAccessible* +nsAccessible::GetSiblingAtOffset(PRInt32 aOffset, nsresult* aError) +{ + if (IsDefunct()) { + if (aError) + *aError = NS_ERROR_FAILURE; + + return nsnull; + } + + nsIAccessible *parent = GetParent(); + if (!parent) { + if (aError) + *aError = NS_ERROR_UNEXPECTED; + + return nsnull; + } + + nsRefPtr parentAcc = + nsAccUtils::QueryObject(parent); + + PRInt32 indexInParent = parentAcc->GetIndexOf(this); + if (indexInParent == -1) { + if (aError) + *aError = NS_ERROR_UNEXPECTED; + + return nsnull; + } + + if (aError) { + PRInt32 childCount = parentAcc->GetChildCount(); + if (indexInParent + aOffset >= childCount) { + *aError = NS_OK; // fail peacefully + return nsnull; + } + } + + nsIAccessible *child = parentAcc->GetChildAt(indexInParent + aOffset); + if (aError && !child) + *aError = NS_ERROR_UNEXPECTED; + + return child; +} already_AddRefed nsAccessible::GetFirstAvailableAccessible(nsIDOMNode *aStartNode) diff --git a/accessible/src/base/nsAccessible.h b/accessible/src/base/nsAccessible.h index ee5a49859179..f68c6c3beac7 100644 --- a/accessible/src/base/nsAccessible.h +++ b/accessible/src/base/nsAccessible.h @@ -103,11 +103,11 @@ private: #define NS_ACCESSIBLE_IMPL_CID \ -{ /* 53cfa871-be42-47fc-b416-0033653b3151 */ \ - 0x53cfa871, \ - 0xbe42, \ - 0x47fc, \ - { 0xb4, 0x16, 0x00, 0x33, 0x65, 0x3b, 0x31, 0x51 } \ +{ /* 07c5a6d6-4e87-4b57-8613-4c39e1b5150a */ \ + 0x07c5a6d6, \ + 0x4e87, \ + 0x4b57, \ + { 0x86, 0x13, 0x4c, 0x39, 0xe1, 0xb5, 0x15, 0x0a } \ } class nsAccessible : public nsAccessNodeWrap, @@ -199,22 +199,7 @@ public: nsIAccessible **aChild); ////////////////////////////////////////////////////////////////////////////// - // Initializing and cache methods - - /** - * Set accessible parent. - */ - void SetParent(nsIAccessible *aParent); - - /** - * Set first accessible child. - */ - void SetFirstChild(nsIAccessible *aFirstChild); - - /** - * Set next sibling accessible. - */ - void SetNextSibling(nsIAccessible *aNextSibling); + // Initializing methods /** * Set the ARIA role map entry for a new accessible. @@ -226,10 +211,45 @@ public: virtual void SetRoleMapEntry(nsRoleMapEntry *aRoleMapEntry); /** - * Set the child count to -1 (unknown) and null out cached child pointers + * Set accessible parent. + */ + void SetParent(nsIAccessible *aParent); + + /** + * Set the child count to -1 (unknown) and null out cached child pointers. + * Should be called when accessible tree is changed because document has + * transformed. */ virtual void InvalidateChildren(); + ////////////////////////////////////////////////////////////////////////////// + // Accessible tree traverse methods + + /** + * Return parent accessible. + */ + virtual nsIAccessible* GetParent(); + + /** + * Return child accessible at the given index. + */ + virtual nsIAccessible* GetChildAt(PRUint32 aIndex); + + /** + * Return child accessible count. + */ + virtual PRInt32 GetChildCount(); + + /** + * Return index of the given child accessible. + */ + virtual PRInt32 GetIndexOf(nsIAccessible *aChild); + + /** + * Return index in parent accessible. + */ + PRInt32 GetIndexInParent(); + /** * Return parent accessible only if cached. */ @@ -240,13 +260,8 @@ public: */ already_AddRefed GetCachedFirstChild(); - /** - * Assert if child not in parent's cache. - */ - void TestChildCache(nsIAccessible *aCachedChild); - ////////////////////////////////////////////////////////////////////////////// - // Miscellaneous methods. + // Miscellaneous methods /** * Fire accessible event. @@ -269,22 +284,41 @@ public: virtual nsresult AppendTextTo(nsAString& aText, PRUint32 aStartOffset, PRUint32 aLength); - ////////////////////////////////////////////////////////////////////////////// - // Helper methods - - already_AddRefed GetParent() { - nsIAccessible *parent = nsnull; - GetParent(&parent); - return parent; - } - protected: + + ////////////////////////////////////////////////////////////////////////////// + // Initializing, cache and tree traverse methods + + /** + * Cache accessible children. + */ + virtual void CacheChildren(); + + /** + * Assert if child not in parent's cache. + */ + void TestChildCache(nsIAccessible *aCachedChild); + + /** + * Cache children if necessary. Return true if the accessible is defunct. + */ + PRBool EnsureChildren(); + + /** + * Return sibling accessible at the given offset. + */ + virtual nsIAccessible* GetSiblingAtOffset(PRInt32 aOffset, + nsresult* aError = nsnull); + + ////////////////////////////////////////////////////////////////////////////// + // Miscellaneous helpers + virtual nsIFrame* GetBoundsFrame(); virtual void GetBoundsRect(nsRect& aRect, nsIFrame** aRelativeFrame); PRBool IsVisible(PRBool *aIsOffscreen); ////////////////////////////////////////////////////////////////////////////// - // Name helpers. + // Name helpers /** * Compute the name of HTML node. @@ -300,25 +334,6 @@ protected: static nsresult GetFullKeyName(const nsAString& aModifierName, const nsAString& aKeyName, nsAString& aStringOut); static nsresult GetTranslatedString(const nsAString& aKey, nsAString& aStringOut); - /** - * Walk into subtree and calculate the string which is used as the accessible - * name or description. - * - * @param aContent [in] traversed content - * @param aFlatString [in, out] result string - * @param aIsRootHidden [in] specifies whether root content (we started to - * traverse from) is hidden, in this case the result - * string is calculated from hidden children - * (this is used when hidden root content is explicitly - * specified as label or description by author) - */ - nsresult AppendFlatStringFromSubtreeRecurse(nsIContent *aContent, - nsAString *aFlatString, - PRBool aIsRootHidden); - - // Helpers for dealing with children - virtual void CacheChildren(); - // nsCOMPtr<>& is useful here, because getter_AddRefs() nulls the comptr's value, and NextChild // depends on the passed-in comptr being null or already set to a child (finding the next sibling). nsIAccessible *NextChild(nsCOMPtr& aAccessible); @@ -436,11 +451,10 @@ protected: // Data Members nsCOMPtr mParent; - nsCOMPtr mFirstChild; - nsCOMPtr mNextSibling; + nsCOMArray mChildren; + PRBool mAreChildrenInitialized; nsRoleMapEntry *mRoleMapEntry; // Non-null indicates author-supplied role; possibly state & value as well - PRInt32 mAccChildCount; }; NS_DEFINE_STATIC_IID_ACCESSOR(nsAccessible, diff --git a/accessible/src/base/nsAccessibleTreeWalker.cpp b/accessible/src/base/nsAccessibleTreeWalker.cpp index dece7a3cbfff..b6df6491a100 100644 --- a/accessible/src/base/nsAccessibleTreeWalker.cpp +++ b/accessible/src/base/nsAccessibleTreeWalker.cpp @@ -77,7 +77,7 @@ void nsAccessibleTreeWalker::GetKids(nsIDOMNode *aParentNode) mState.frame = nsnull; // Don't walk frames in non-HTML content, just walk the DOM. } - UpdateFrame(PR_TRUE); + WalkFrames(); // Walk frames? UpdateFrame() sets this when it sees anonymous frames if (mState.siblingIndex == eSiblingsWalkFrames) { @@ -160,20 +160,40 @@ NS_IMETHODIMP nsAccessibleTreeWalker::PushState() void nsAccessibleTreeWalker::GetNextDOMNode() { - // Get next DOM node + // Get next DOM node and its frame. if (mState.parentContent) { - mState.domNode = do_QueryInterface(mState.parentContent->GetChildAt(++mState.siblingIndex)); - } - else if (mState.siblingIndex == eSiblingsWalkFrames) { - if (mState.frame.GetFrame()) { - mState.domNode = do_QueryInterface(mState.frame.GetFrame()->GetContent()); - } else { - mState.domNode = nsnull; + mState.domNode = + do_QueryInterface(mState.parentContent->GetChildAt(++mState.siblingIndex)); + + } else if (mState.siblingIndex == eSiblingsWalkFrames) { + if (mState.frame.IsAlive()) { + mState.frame = mState.frame.GetFrame()->GetNextSibling(); + + if (mState.frame.IsAlive()) { + mState.domNode = do_QueryInterface(mState.frame.GetFrame()->GetContent()); + return; + } } + + mState.domNode = nsnull; + return; + + } else { + mState.siblingList->Item(++mState.siblingIndex, + getter_AddRefs(mState.domNode)); } - else { - mState.siblingList->Item(++mState.siblingIndex, getter_AddRefs(mState.domNode)); - } + + // Update the frame. + nsCOMPtr presShell(do_QueryReferent(mWeakShell)); + NS_ASSERTION(presShell, "Huh? No presshell?"); + if (!presShell) + return; + + nsCOMPtr content = do_QueryInterface(mState.domNode); + if (content) + mState.frame = presShell->GetRealPrimaryFrameFor(content); + else + mState.frame = presShell->GetRootFrame(); } NS_IMETHODIMP nsAccessibleTreeWalker::GetNextSibling() @@ -185,7 +205,6 @@ NS_IMETHODIMP nsAccessibleTreeWalker::GetNextSibling() while (PR_TRUE) { // Get next frame - UpdateFrame(PR_FALSE); GetNextDOMNode(); if (!mState.domNode) { // Done with current siblings @@ -219,7 +238,7 @@ NS_IMETHODIMP nsAccessibleTreeWalker::GetFirstChild() while (mState.domNode) { if ((mState.domNode != parent && GetAccessible()) || NS_SUCCEEDED(GetFirstChild())) return NS_OK; - UpdateFrame(PR_FALSE); + GetNextDOMNode(); } @@ -227,50 +246,46 @@ NS_IMETHODIMP nsAccessibleTreeWalker::GetFirstChild() return NS_ERROR_FAILURE; } -void nsAccessibleTreeWalker::UpdateFrame(PRBool aTryFirstChild) +void +nsAccessibleTreeWalker::WalkFrames() { nsIFrame *curFrame = mState.frame.GetFrame(); if (!curFrame) { return; } - if (aTryFirstChild) { - // If the frame implements nsIAnonymousContentCreator interface then go down - // through the frames and obtain anonymous nodes for them. - nsIAnonymousContentCreator* creator = do_QueryFrame(curFrame); - nsIFrame *child = curFrame->GetFirstChild(nsnull); - mState.frame = child; + // If the frame implements nsIAnonymousContentCreator interface then go down + // through the frames and obtain anonymous nodes for them. + nsIAnonymousContentCreator* creator = do_QueryFrame(curFrame); + nsIFrame *child = curFrame->GetFirstChild(nsnull); - if (creator && child && mState.siblingIndex < 0) { - mState.domNode = do_QueryInterface(child->GetContent()); - mState.siblingIndex = eSiblingsWalkFrames; - } + if (creator && child && mState.siblingIndex < 0) { + mState.frame = child; + mState.domNode = do_QueryInterface(child->GetContent()); + mState.siblingIndex = eSiblingsWalkFrames; + } // temporary workaround for Bug 359210. We never want to walk frames. // Aaron Leventhal will refix :before and :after content later without walking frames. #if 0 - if (mState.frame && mState.siblingIndex < 0) { - // Container frames can contain generated content frames from - // :before and :after style rules, so we walk their frame trees - // instead of content trees - // XXX Walking the frame tree doesn't get us Aural CSS nodes, e.g. - // @media screen { display: none; } - // Asking the style system might be better (with ProbePseudoStyleFor(), - // except that we need to ask only for those display types that support - // :before and :after (which roughly means non-replaced elements) - // Here's some code to see if there is an :after rule for an element - // nsRefPtr pseudoContext; - // nsStyleContext *styleContext = primaryFrame->GetStyleContext(); - // if (aContent) { - // pseudoContext = presContext->StyleSet()-> - // ProbePseudoStyleFor(content, nsAccessibilityAtoms::after, aStyleContext); - mState.domNode = do_QueryInterface(mState.frame->GetContent()); - mState.siblingIndex = eSiblingsWalkFrames; - } + if (mState.frame && mState.siblingIndex < 0) { + // Container frames can contain generated content frames from + // :before and :after style rules, so we walk their frame trees + // instead of content trees + // XXX Walking the frame tree doesn't get us Aural CSS nodes, e.g. + // @media screen { display: none; } + // Asking the style system might be better (with ProbePseudoStyleFor(), + // except that we need to ask only for those display types that support + // :before and :after (which roughly means non-replaced elements) + // Here's some code to see if there is an :after rule for an element + // nsRefPtr pseudoContext; + // nsStyleContext *styleContext = primaryFrame->GetStyleContext(); + // if (aContent) { + // pseudoContext = presContext->StyleSet()-> + // ProbePseudoStyleFor(content, nsAccessibilityAtoms::after, aStyleContext); + mState.domNode = do_QueryInterface(mState.frame->GetContent()); + mState.siblingIndex = eSiblingsWalkFrames; + } #endif - } - else { - mState.frame = curFrame->GetNextSibling(); - } } /** @@ -286,11 +301,10 @@ PRBool nsAccessibleTreeWalker::GetAccessible() mState.accessible = nsnull; nsCOMPtr presShell(do_QueryReferent(mWeakShell)); - nsIFrame *frame = mState.frame.GetFrame(); mAccService->GetAccessible(mState.domNode, presShell, mWeakShell, - &frame, &mState.isHidden, + mState.frame.GetFrame(), &mState.isHidden, getter_AddRefs(mState.accessible)); - mState.frame = frame; + return mState.accessible ? PR_TRUE : PR_FALSE; } diff --git a/accessible/src/base/nsAccessibleTreeWalker.h b/accessible/src/base/nsAccessibleTreeWalker.h index 58a2028df77b..b74b09a743c5 100644 --- a/accessible/src/base/nsAccessibleTreeWalker.h +++ b/accessible/src/base/nsAccessibleTreeWalker.h @@ -121,12 +121,9 @@ protected: NS_IMETHOD PopState(); /** - * Change current state so that its frame is changed to next frame. - * - * @param aTryFirstChild [in] points whether we should move to child or - * sibling frame + * Make treewalker traverse by frame tree if necessary. */ - void UpdateFrame(PRBool aTryFirstChild); + void WalkFrames(); /** * Change current state so that its node is changed to next node. diff --git a/accessible/src/base/nsApplicationAccessible.cpp b/accessible/src/base/nsApplicationAccessible.cpp index 2af2b4e99678..e2ec604f5fff 100644 --- a/accessible/src/base/nsApplicationAccessible.cpp +++ b/accessible/src/base/nsApplicationAccessible.cpp @@ -42,64 +42,22 @@ #include "nsApplicationAccessible.h" +#include "nsAccessibilityService.h" + #include "nsIComponentManager.h" #include "nsServiceManagerUtils.h" -nsApplicationAccessible::nsApplicationAccessible(): - nsAccessibleWrap(nsnull, nsnull), mChildren(nsnull) +nsApplicationAccessible::nsApplicationAccessible() : + nsAccessibleWrap(nsnull, nsnull) { } //////////////////////////////////////////////////////////////////////////////// // nsISupports -NS_IMPL_CYCLE_COLLECTION_CLASS(nsApplicationAccessible) - -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsApplicationAccessible, - nsAccessible) - - nsCOMPtr enumerator; - tmp->mChildren->Enumerate(getter_AddRefs(enumerator)); - - nsCOMPtr childWeakRef; - nsCOMPtr accessible; - - PRBool hasMoreElements; - while(NS_SUCCEEDED(enumerator->HasMoreElements(&hasMoreElements)) - && hasMoreElements) { - - enumerator->GetNext(getter_AddRefs(childWeakRef)); - accessible = do_QueryReferent(childWeakRef); - if (accessible) { - NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "nsApplicationAccessible child"); - cb.NoteXPCOMChild(accessible); - } - } - -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END - -NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsApplicationAccessible, - nsAccessible) - tmp->mChildren->Clear(); -NS_IMPL_CYCLE_COLLECTION_UNLINK_END - -NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsApplicationAccessible) -NS_INTERFACE_MAP_END_INHERITING(nsAccessible) - -NS_IMPL_ADDREF_INHERITED(nsApplicationAccessible, nsAccessible) -NS_IMPL_RELEASE_INHERITED(nsApplicationAccessible, nsAccessible) +NS_IMPL_ISUPPORTS_INHERITED0(nsApplicationAccessible, nsAccessible) //////////////////////////////////////////////////////////////////////////////// -// nsIAccessNode - -nsresult -nsApplicationAccessible::Init() -{ - nsresult rv; - mChildren = do_CreateInstance(NS_ARRAY_CONTRACTID, &rv); - return rv; -} - // nsIAccessible NS_IMETHODIMP @@ -130,19 +88,67 @@ nsApplicationAccessible::GetName(nsAString& aName) return NS_OK; } -nsresult -nsApplicationAccessible::GetRoleInternal(PRUint32 *aRole) +NS_IMETHODIMP +nsApplicationAccessible::GetDescription(nsAString& aValue) { - *aRole = nsIAccessibleRole::ROLE_APP_ROOT; + aValue.Truncate(); return NS_OK; } NS_IMETHODIMP nsApplicationAccessible::GetRole(PRUint32 *aRole) { + NS_ENSURE_ARG_POINTER(aRole); + return GetRoleInternal(aRole); } +NS_IMETHODIMP +nsApplicationAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState) +{ + NS_ENSURE_ARG_POINTER(aState); + *aState = 0; + + if (aExtraState) + *aExtraState = 0; + + return NS_OK; +} + +NS_IMETHODIMP +nsApplicationAccessible::GetParent(nsIAccessible **aAccessible) +{ + NS_ENSURE_ARG_POINTER(aAccessible); + *aAccessible = nsnull; + + return IsDefunct() ? NS_ERROR_FAILURE : NS_OK; +} + +//////////////////////////////////////////////////////////////////////////////// +// nsAccessNode public methods + +PRBool +nsApplicationAccessible::IsDefunct() +{ + return nsAccessibilityService::gIsShutdown; +} + +nsresult +nsApplicationAccessible::Init() +{ + return NS_OK; +} + +//////////////////////////////////////////////////////////////////////////////// +// nsAccessible public methods + +nsresult +nsApplicationAccessible::GetRoleInternal(PRUint32 *aRole) +{ + *aRole = nsIAccessibleRole::ROLE_APP_ROOT; + return NS_OK; +} + nsresult nsApplicationAccessible::GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState) @@ -154,124 +160,59 @@ nsApplicationAccessible::GetStateInternal(PRUint32 *aState, return NS_OK; } -NS_IMETHODIMP -nsApplicationAccessible::GetParent(nsIAccessible **aParent) +nsIAccessible* +nsApplicationAccessible::GetParent() { - *aParent = nsnull; - return NS_OK; + return nsnull; } -NS_IMETHODIMP -nsApplicationAccessible::GetChildAt(PRInt32 aChildNum, nsIAccessible **aChild) +void +nsApplicationAccessible::InvalidateChildren() { - NS_ENSURE_ARG_POINTER(aChild); - *aChild = nsnull; - - PRUint32 count = 0; - nsresult rv = NS_OK; - - if (mChildren) { - rv = mChildren->GetLength(&count); - NS_ENSURE_SUCCESS(rv, rv); - } - - if (aChildNum >= static_cast(count) || count == 0) - return NS_ERROR_INVALID_ARG; - - if (aChildNum < 0) - aChildNum = count - 1; - - nsCOMPtr childWeakRef; - rv = mChildren->QueryElementAt(aChildNum, NS_GET_IID(nsIWeakReference), - getter_AddRefs(childWeakRef)); - NS_ENSURE_SUCCESS(rv, rv); - - if (childWeakRef) { - nsCOMPtr childAcc(do_QueryReferent(childWeakRef)); - NS_IF_ADDREF(*aChild = childAcc); - } - - return NS_OK; + // Do nothing because application children are kept updated by + // AddRootAccessible() and RemoveRootAccessible() method calls. } -NS_IMETHODIMP -nsApplicationAccessible::GetNextSibling(nsIAccessible **aNextSibling) -{ - NS_ENSURE_ARG_POINTER(aNextSibling); - - *aNextSibling = nsnull; - return NS_OK; -} - -NS_IMETHODIMP -nsApplicationAccessible::GetPreviousSibling(nsIAccessible **aPreviousSibling) -{ - NS_ENSURE_ARG_POINTER(aPreviousSibling); - - *aPreviousSibling = nsnull; - return NS_OK; -} - -NS_IMETHODIMP -nsApplicationAccessible::GetIndexInParent(PRInt32 *aIndexInParent) -{ - NS_ENSURE_ARG_POINTER(aIndexInParent); - - *aIndexInParent = -1; - return NS_OK; -} +//////////////////////////////////////////////////////////////////////////////// +// nsAccessible protected methods void nsApplicationAccessible::CacheChildren() { - if (!mChildren) { - mAccChildCount = eChildCountUninitialized; - return; - } - - if (mAccChildCount == eChildCountUninitialized) { - mAccChildCount = 0;// Prevent reentry - nsCOMPtr enumerator; - mChildren->Enumerate(getter_AddRefs(enumerator)); - - nsCOMPtr childWeakRef; - nsCOMPtr accessible; - nsRefPtr prevAcc; - PRBool hasMoreElements; - - while(NS_SUCCEEDED(enumerator->HasMoreElements(&hasMoreElements)) && - hasMoreElements) { - enumerator->GetNext(getter_AddRefs(childWeakRef)); - accessible = do_QueryReferent(childWeakRef); - if (accessible) { - if (prevAcc) - prevAcc->SetNextSibling(accessible); - else - SetFirstChild(accessible); - - prevAcc = nsAccUtils::QueryAccessible(accessible); - prevAcc->SetParent(this); - } - } - - PRUint32 count = 0; - mChildren->GetLength(&count); - mAccChildCount = static_cast(count); - } + // Nothing to do. Children are keeped up to dated by Add/RemoveRootAccessible + // method calls. } -// nsApplicationAccessible +nsIAccessible* +nsApplicationAccessible::GetSiblingAtOffset(PRInt32 aOffset, nsresult* aError) +{ + if (IsDefunct()) { + if (aError) + *aError = NS_ERROR_FAILURE; + + return nsnull; + } + + if (aError) + *aError = NS_OK; // fail peacefully + + return nsnull; +} + +//////////////////////////////////////////////////////////////////////////////// +// Public methods nsresult nsApplicationAccessible::AddRootAccessible(nsIAccessible *aRootAccessible) { NS_ENSURE_ARG_POINTER(aRootAccessible); - // add by weak reference - nsresult rv = mChildren->AppendElement(aRootAccessible, PR_TRUE); - NS_ENSURE_SUCCESS(rv, rv); + if (!mChildren.AppendObject(aRootAccessible)) + return NS_ERROR_FAILURE; + + nsRefPtr rootAcc = nsAccUtils::QueryAccessible(aRootAccessible); + rootAcc->SetParent(this); - InvalidateChildren(); return NS_OK; } @@ -280,17 +221,8 @@ nsApplicationAccessible::RemoveRootAccessible(nsIAccessible *aRootAccessible) { NS_ENSURE_ARG_POINTER(aRootAccessible); - PRUint32 index = 0; - - // we must use weak ref to get the index - nsCOMPtr weakPtr = do_GetWeakReference(aRootAccessible); - nsresult rv = mChildren->IndexOf(0, weakPtr, &index); - NS_ENSURE_SUCCESS(rv, rv); - - rv = mChildren->RemoveElementAt(index); - NS_ENSURE_SUCCESS(rv, rv); - - InvalidateChildren(); - return NS_OK; + // It's not needed to void root accessible parent because this method is + // called on root accessible shutdown and its parent will be cleared + // properly. + return mChildren.RemoveObject(aRootAccessible) ? NS_OK : NS_ERROR_FAILURE; } - diff --git a/accessible/src/base/nsApplicationAccessible.h b/accessible/src/base/nsApplicationAccessible.h index e45898e8e558..6668df5708bc 100644 --- a/accessible/src/base/nsApplicationAccessible.h +++ b/accessible/src/base/nsApplicationAccessible.h @@ -63,34 +63,36 @@ public: // nsISupports NS_DECL_ISUPPORTS_INHERITED - NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsApplicationAccessible, - nsAccessible) - - // nsAccessNode - virtual nsresult Init(); // nsIAccessible - NS_IMETHOD GetName(nsAString & aName); + NS_IMETHOD GetName(nsAString& aName); + NS_IMETHOD GetDescription(nsAString& aValue); NS_IMETHOD GetRole(PRUint32 *aRole); - NS_IMETHOD GetParent(nsIAccessible * *aParent); - NS_IMETHOD GetNextSibling(nsIAccessible * *aNextSibling); - NS_IMETHOD GetPreviousSibling(nsIAccessible **aPreviousSibling); - NS_IMETHOD GetIndexInParent(PRInt32 *aIndexInParent); - NS_IMETHOD GetChildAt(PRInt32 aChildNum, nsIAccessible **aChild); + NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState); + + NS_IMETHOD GetParent(nsIAccessible **aAccessible); + + // nsAccessNode + virtual PRBool IsDefunct(); + virtual nsresult Init(); // nsAccessible virtual nsresult GetRoleInternal(PRUint32 *aRole); virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState); + virtual nsIAccessible* GetParent(); + + virtual void InvalidateChildren(); // nsApplicationAccessible virtual nsresult AddRootAccessible(nsIAccessible *aRootAccWrap); virtual nsresult RemoveRootAccessible(nsIAccessible *aRootAccWrap); protected: + // nsAccessible virtual void CacheChildren(); - - nsCOMPtr mChildren; + virtual nsIAccessible* GetSiblingAtOffset(PRInt32 aOffset, + nsresult *aError = nsnull); }; #endif diff --git a/accessible/src/base/nsBaseWidgetAccessible.cpp b/accessible/src/base/nsBaseWidgetAccessible.cpp index 5bd4d105ca3d..eea11a3e0b29 100644 --- a/accessible/src/base/nsBaseWidgetAccessible.cpp +++ b/accessible/src/base/nsBaseWidgetAccessible.cpp @@ -65,7 +65,9 @@ nsAccessibleWrap(aNode, aShell) NS_IMPL_ISUPPORTS_INHERITED0(nsLeafAccessible, nsAccessible) -// nsAccessible::GetChildAtPoint() +//////////////////////////////////////////////////////////////////////////////// +// nsLeafAccessible: nsAccessible public + nsresult nsLeafAccessible::GetChildAtPoint(PRInt32 aX, PRInt32 aY, PRBool aDeepestChild, @@ -76,12 +78,13 @@ nsLeafAccessible::GetChildAtPoint(PRInt32 aX, PRInt32 aY, return NS_OK; } -// nsAccessible::CacheChildren() +//////////////////////////////////////////////////////////////////////////////// +// nsLeafAccessible: nsAccessible private + void nsLeafAccessible::CacheChildren() { // No children for leaf accessible. - mAccChildCount = IsDefunct() ? eChildCountUninitialized : 0; } diff --git a/accessible/src/base/nsCoreUtils.cpp b/accessible/src/base/nsCoreUtils.cpp index 3d5a88d2e222..0b32085ad579 100644 --- a/accessible/src/base/nsCoreUtils.cpp +++ b/accessible/src/base/nsCoreUtils.cpp @@ -1027,7 +1027,7 @@ nsCoreUtils::GetLastSensibleColumn(nsITreeBoxObject *aTree) } PRUint32 -nsCoreUtils::GetSensiblecolumnCount(nsITreeBoxObject *aTree) +nsCoreUtils::GetSensibleColumnCount(nsITreeBoxObject *aTree) { PRUint32 count = 0; diff --git a/accessible/src/base/nsCoreUtils.h b/accessible/src/base/nsCoreUtils.h index 4fa693ad2a9a..1eb7a2ee693b 100644 --- a/accessible/src/base/nsCoreUtils.h +++ b/accessible/src/base/nsCoreUtils.h @@ -413,7 +413,7 @@ public: /** * Return sensible columns count for the given tree box object. */ - static PRUint32 GetSensiblecolumnCount(nsITreeBoxObject *aTree); + static PRUint32 GetSensibleColumnCount(nsITreeBoxObject *aTree); /** * Return sensible column at the given index for the given tree box object. diff --git a/accessible/src/base/nsDocAccessible.cpp b/accessible/src/base/nsDocAccessible.cpp index 15f30508ad3d..7bf74c9251f1 100644 --- a/accessible/src/base/nsDocAccessible.cpp +++ b/accessible/src/base/nsDocAccessible.cpp @@ -73,16 +73,16 @@ #include "nsIXULDocument.h" #endif -//=============================// -// nsDocAccessible // -//=============================// +//////////////////////////////////////////////////////////////////////////////// +// Static member initialization PRUint32 nsDocAccessible::gLastFocusedAccessiblesState = 0; nsIAtom *nsDocAccessible::gLastFocusedFrameType = nsnull; -//----------------------------------------------------- -// construction -//----------------------------------------------------- + +//////////////////////////////////////////////////////////////////////////////// +// Constructor/desctructor + nsDocAccessible::nsDocAccessible(nsIDOMNode *aDOMNode, nsIWeakReference* aShell): nsHyperTextAccessibleWrap(aDOMNode, aShell), mWnd(nsnull), mScrollPositionChangedTicks(0), mIsContentLoaded(PR_FALSE), @@ -129,15 +129,13 @@ nsDocAccessible::nsDocAccessible(nsIDOMNode *aDOMNode, nsIWeakReference* aShell) } } -//----------------------------------------------------- -// destruction -//----------------------------------------------------- nsDocAccessible::~nsDocAccessible() { } + //////////////////////////////////////////////////////////////////////////////// -// nsDocAccessible. nsISupports +// nsISupports static PLDHashOperator ElementTraverser(const void *aKey, nsIAccessNode *aAccessNode, @@ -182,6 +180,10 @@ NS_INTERFACE_MAP_END_INHERITING(nsHyperTextAccessible) NS_IMPL_ADDREF_INHERITED(nsDocAccessible, nsHyperTextAccessible) NS_IMPL_RELEASE_INHERITED(nsDocAccessible, nsHyperTextAccessible) + +//////////////////////////////////////////////////////////////////////////////// +// nsIAccessible + NS_IMETHODIMP nsDocAccessible::GetName(nsAString& aName) { @@ -204,6 +206,7 @@ nsDocAccessible::GetName(nsAString& aName) return rv; } +// nsAccessible public method nsresult nsDocAccessible::GetRoleInternal(PRUint32 *aRole) { @@ -242,6 +245,7 @@ nsDocAccessible::GetRoleInternal(PRUint32 *aRole) return NS_OK; } +// nsAccessible public method void nsDocAccessible::SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry) { @@ -282,6 +286,7 @@ nsDocAccessible::GetDescription(nsAString& aDescription) return NS_OK; } +// nsAccessible public method nsresult nsDocAccessible::GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState) { @@ -332,6 +337,7 @@ nsDocAccessible::GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState) return NS_OK; } +// nsAccessible public method nsresult nsDocAccessible::GetARIAState(PRUint32 *aState, PRUint32 *aExtraState) { @@ -396,7 +402,9 @@ NS_IMETHODIMP nsDocAccessible::TakeFocus() return NS_ERROR_FAILURE; } -// ------- nsIAccessibleDocument Methods (5) --------------- + +//////////////////////////////////////////////////////////////////////////////// +// nsIAccessibleDocument NS_IMETHODIMP nsDocAccessible::GetURL(nsAString& aURL) { @@ -499,6 +507,7 @@ NS_IMETHODIMP nsDocAccessible::GetDocument(nsIDOMDocument **aDOMDoc) return NS_ERROR_FAILURE; } +// nsIAccessibleHyperText method NS_IMETHODIMP nsDocAccessible::GetAssociatedEditor(nsIEditor **aEditor) { NS_ENSURE_ARG_POINTER(aEditor); @@ -557,6 +566,7 @@ NS_IMETHODIMP nsDocAccessible::GetCachedAccessNode(void *aUniqueID, nsIAccessNod return NS_OK; } +// nsDocAccessible public method void nsDocAccessible::CacheAccessNode(void *aUniqueID, nsIAccessNode *aAccessNode) { @@ -574,6 +584,7 @@ nsDocAccessible::CacheAccessNode(void *aUniqueID, nsIAccessNode *aAccessNode) PutCacheEntry(mAccessNodeCache, aUniqueID, aAccessNode); } +// nsDocAccessible public method void nsDocAccessible::RemoveAccessNodeFromCache(nsIAccessNode *aAccessNode) { @@ -585,31 +596,8 @@ nsDocAccessible::RemoveAccessNodeFromCache(nsIAccessNode *aAccessNode) mAccessNodeCache.Remove(uniqueID); } -NS_IMETHODIMP nsDocAccessible::GetParent(nsIAccessible **aParent) -{ - // Hook up our new accessible with our parent - *aParent = nsnull; - NS_ENSURE_TRUE(mDocument, NS_ERROR_FAILURE); - if (!mParent) { - nsIDocument *parentDoc = mDocument->GetParentDocument(); - NS_ENSURE_TRUE(parentDoc, NS_ERROR_FAILURE); - nsIContent *ownerContent = parentDoc->FindContentForSubDocument(mDocument); - nsCOMPtr ownerNode(do_QueryInterface(ownerContent)); - if (ownerNode) { - nsCOMPtr accService = - do_GetService("@mozilla.org/accessibilityService;1"); - if (accService) { - // XXX aaronl: ideally we would traverse the presshell chain - // Since there's no easy way to do that, we cheat and use - // the document hierarchy. GetAccessibleFor() is bad because - // it doesn't support our concept of multiple presshells per doc. - // It should be changed to use GetAccessibleInWeakShell() - accService->GetAccessibleFor(ownerNode, getter_AddRefs(mParent)); - } - } - } - return mParent ? nsAccessible::GetParent(aParent) : NS_ERROR_FAILURE; -} +//////////////////////////////////////////////////////////////////////////////// +// nsAccessNode nsresult nsDocAccessible::Init() @@ -618,8 +606,7 @@ nsDocAccessible::Init() AddEventListeners(); - nsCOMPtr parentAccessible; // Ensure outer doc mParent accessible - GetParent(getter_AddRefs(parentAccessible)); + GetParent(); // Ensure outer doc mParent accessible. nsresult rv = nsHyperTextAccessibleWrap::Init(); NS_ENSURE_SUCCESS(rv, rv); @@ -680,6 +667,7 @@ nsDocAccessible::Shutdown() return NS_OK; } +// nsDocAccessible protected member void nsDocAccessible::ShutdownChildDocuments(nsIDocShellTreeItem *aStart) { nsCOMPtr treeNode(do_QueryInterface(aStart)); @@ -725,6 +713,7 @@ nsDocAccessible::IsDefunct() return !mDocument; } +// nsDocAccessible protected member void nsDocAccessible::GetBoundsRect(nsRect& aBounds, nsIFrame** aRelativeFrame) { *aRelativeFrame = GetFrame(); @@ -768,7 +757,7 @@ void nsDocAccessible::GetBoundsRect(nsRect& aBounds, nsIFrame** aRelativeFrame) } } - +// nsDocAccessible protected member nsresult nsDocAccessible::AddEventListeners() { // 1) Set up scroll position listener @@ -814,6 +803,7 @@ nsresult nsDocAccessible::AddEventListeners() return NS_OK; } +// nsDocAccessible protected member nsresult nsDocAccessible::RemoveEventListeners() { // Remove listeners associated with content documents @@ -860,6 +850,7 @@ nsresult nsDocAccessible::RemoveEventListeners() return NS_OK; } +// nsDocAccessible public member void nsDocAccessible::FireDocLoadEvents(PRUint32 aEventType) { @@ -889,8 +880,7 @@ nsDocAccessible::FireDocLoadEvents(PRUint32 aEventType) if (isFinished) { // Need to wait until scrollable view is available AddScrollListener(); - nsCOMPtr parent(nsAccessible::GetParent()); - nsRefPtr acc(nsAccUtils::QueryAccessible(parent)); + nsRefPtr acc(nsAccUtils::QueryAccessible(GetParent())); if (acc) { // Make the parent forget about the old document as a child acc->InvalidateChildren(); @@ -954,6 +944,7 @@ void nsDocAccessible::ScrollTimerCallback(nsITimer *aTimer, void *aClosure) } } +// nsDocAccessible protected member void nsDocAccessible::AddScrollListener() { nsCOMPtr presShell(do_QueryReferent(mWeakShell)); @@ -970,6 +961,7 @@ void nsDocAccessible::AddScrollListener() scrollableView->AddScrollPositionListener(this); } +// nsDocAccessible protected member void nsDocAccessible::RemoveScrollListener() { nsCOMPtr presShell(do_QueryReferent(mWeakShell)); @@ -986,6 +978,9 @@ void nsDocAccessible::RemoveScrollListener() scrollableView->RemoveScrollPositionListener(this); } +//////////////////////////////////////////////////////////////////////////////// +// nsIScrollPositionListener + NS_IMETHODIMP nsDocAccessible::ScrollPositionWillChange(nsIScrollableView *aView, nscoord aX, nscoord aY) { return NS_OK; @@ -1012,6 +1007,9 @@ NS_IMETHODIMP nsDocAccessible::ScrollPositionDidChange(nsIScrollableView *aScrol return NS_OK; } +//////////////////////////////////////////////////////////////////////////////// +// nsIObserver + NS_IMETHODIMP nsDocAccessible::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *aData) { @@ -1026,7 +1024,7 @@ NS_IMETHODIMP nsDocAccessible::Observe(nsISupports *aSubject, const char *aTopic return NS_OK; } - /////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// // nsIDocumentObserver NS_IMPL_NSIDOCUMENTOBSERVER_CORE_STUB(nsDocAccessible) @@ -1047,7 +1045,7 @@ nsDocAccessible::AttributeWillChange(nsIDocument *aDocument, void nsDocAccessible::AttributeChanged(nsIDocument *aDocument, nsIContent* aContent, PRInt32 aNameSpaceID, nsIAtom* aAttribute, - PRInt32 aModType, PRUint32 aStateMask) + PRInt32 aModType) { AttributeChangedImpl(aContent, aNameSpaceID, aAttribute); @@ -1062,7 +1060,7 @@ nsDocAccessible::AttributeChanged(nsIDocument *aDocument, nsIContent* aContent, } } - +// nsDocAccessible protected member void nsDocAccessible::AttributeChangedImpl(nsIContent* aContent, PRInt32 aNameSpaceID, nsIAtom* aAttribute) { @@ -1171,7 +1169,7 @@ nsDocAccessible::AttributeChangedImpl(nsIContent* aContent, PRInt32 aNameSpaceID aAttribute == nsAccessibilityAtoms::aria_selected) { // ARIA or XUL selection nsCOMPtr multiSelect = - nsAccUtils::GetMultiSelectFor(targetNode); + nsAccUtils::GetMultiSelectableContainer(targetNode); // Multi selects use selection_add and selection_remove // Single select widgets just mirror event_selection for // whatever gets event_focus, which is done in @@ -1213,6 +1211,7 @@ nsDocAccessible::AttributeChangedImpl(nsIContent* aContent, PRInt32 aNameSpaceID } } +// nsDocAccessible protected member void nsDocAccessible::ARIAAttributeChanged(nsIContent* aContent, nsIAtom* aAttribute) { @@ -1362,6 +1361,7 @@ void nsDocAccessible::ContentAppended(nsIDocument *aDocument, } } + void nsDocAccessible::ContentStatesChanged(nsIDocument* aDocument, nsIContent* aContent1, nsIContent* aContent2, @@ -1417,6 +1417,45 @@ nsDocAccessible::ParentChainChanged(nsIContent *aContent) { } + +//////////////////////////////////////////////////////////////////////////////// +// nsAccessible + +nsIAccessible* +nsDocAccessible::GetParent() +{ + if (IsDefunct()) + return nsnull; + + if (mParent) + return mParent; + + nsIDocument* parentDoc = mDocument->GetParentDocument(); + if (!parentDoc) + return nsnull; + + nsIContent* ownerContent = parentDoc->FindContentForSubDocument(mDocument); + nsCOMPtr ownerNode(do_QueryInterface(ownerContent)); + if (ownerNode) { + nsCOMPtr accService = GetAccService(); + if (accService) { + // XXX aaronl: ideally we would traverse the presshell chain. Since + // there's no easy way to do that, we cheat and use the document + // hierarchy. GetAccessibleFor() is bad because it doesn't support our + // concept of multiple presshells per doc. + // It should be changed to use GetAccessibleInWeakShell() + accService->GetAccessibleFor(ownerNode, getter_AddRefs(mParent)); + } + } + + NS_ASSERTION(mParent, "No parent for not root document accessible!"); + return mParent; +} + + +//////////////////////////////////////////////////////////////////////////////// +// Protected members + void nsDocAccessible::FireValueChangeForTextFields(nsIAccessible *aPossibleTextFieldAccessible) { @@ -1571,7 +1610,8 @@ nsDocAccessible::CreateTextChangeEventForNode(nsIAccessible *aContainerAccessibl return event; } - + +// nsDocAccessible public member nsresult nsDocAccessible::FireDelayedAccessibleEvent(PRUint32 aEventType, nsIDOMNode *aDOMNode, @@ -1585,6 +1625,7 @@ nsDocAccessible::FireDelayedAccessibleEvent(PRUint32 aEventType, return FireDelayedAccessibleEvent(event); } +// nsDocAccessible public member nsresult nsDocAccessible::FireDelayedAccessibleEvent(nsIAccessibleEvent *aEvent) { @@ -1953,6 +1994,7 @@ void nsDocAccessible::RefreshNodes(nsIDOMNode *aStartNode) mAccessNodeCache.Remove(uniqueID); } +// nsDocAccessible public member void nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild, PRUint32 aChangeType) @@ -2180,6 +2222,7 @@ nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild, FireDelayedAccessibleEvent(reorderEvent); } +// nsIAccessibleDocument method NS_IMETHODIMP nsDocAccessible::GetAccessibleInParentChain(nsIDOMNode *aNode, PRBool aCanCreate, diff --git a/accessible/src/base/nsDocAccessible.h b/accessible/src/base/nsDocAccessible.h index 7926dccd90f7..d351be665a16 100644 --- a/accessible/src/base/nsDocAccessible.h +++ b/accessible/src/base/nsDocAccessible.h @@ -87,7 +87,6 @@ public: NS_IMETHOD GetDescription(nsAString& aDescription); NS_IMETHOD GetAttributes(nsIPersistentProperties **aAttributes); NS_IMETHOD GetFocusedChild(nsIAccessible **aFocusedChild); - NS_IMETHOD GetParent(nsIAccessible **aParent); NS_IMETHOD TakeFocus(void); // nsIScrollPositionListener @@ -111,7 +110,9 @@ public: virtual nsresult GetRoleInternal(PRUint32 *aRole); virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState); virtual nsresult GetARIAState(PRUint32 *aState, PRUint32 *aExtraState); + virtual void SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry); + virtual nsIAccessible* GetParent(); // nsIAccessibleText NS_IMETHOD GetAssociatedEditor(nsIEditor **aEditor); diff --git a/accessible/src/base/nsOuterDocAccessible.cpp b/accessible/src/base/nsOuterDocAccessible.cpp index b42b062c03f0..df962beffa7b 100644 --- a/accessible/src/base/nsOuterDocAccessible.cpp +++ b/accessible/src/base/nsOuterDocAccessible.cpp @@ -99,25 +99,11 @@ nsOuterDocAccessible::GetChildAtPoint(PRInt32 aX, PRInt32 aY, return NS_OK; } -void nsOuterDocAccessible::CacheChildren() -{ - // An outer doc accessible usually has 1 nsDocAccessible child, - // but could have none if we can't get to the inner documnet - if (!mWeakShell) { - mAccChildCount = eChildCountUninitialized; - return; // This outer doc node has been shut down - } - if (mAccChildCount != eChildCountUninitialized) { - return; - } - - InvalidateChildren(); - mAccChildCount = 0; - - // In these variable names, "outer" relates to the nsOuterDocAccessible - // as opposed to the nsDocAccessibleWrap which is "inner". - // The outer node is a something like a , , + +
+
+
+ + diff --git a/content/canvas/src/Makefile.in b/content/canvas/src/Makefile.in index e7aeee7a8c4d..0cd319e96f14 100644 --- a/content/canvas/src/Makefile.in +++ b/content/canvas/src/Makefile.in @@ -64,6 +64,30 @@ endif ifdef MOZ_WEBGL +ifeq (1_1,$(MOZ_X11)_$(NS_OSSO)) +WEBGL_PLATFORM = EGL +DEFINES += -DUSE_GLES2 +endif + +ifeq (1_,$(MOZ_X11)_$(NS_OSSO)) +WEBGL_PLATFORM = GLX +EXTRA_DSO_LIBS += X11 +endif + + +ifeq (windows,$(MOZ_WIDGET_TOOLKIT)) +ifdef WINCE +WEBGL_PLATFORM = EGL +DEFINES += -DUSE_GLES2 +else +WEBGL_PLATFORM = WGL +endif +endif + +ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT)) +WEBGL_PLATFORM = CGL +endif + CPPSRCS += \ WebGLArrays.cpp \ WebGLContext.cpp \ @@ -77,26 +101,8 @@ CPPSRCS += \ SimpleBuffer.cpp \ $(NULL) -ifdef MOZ_X11 -EXTRA_DSO_LIBS += X11 -CPPSRCS += nsGLPbufferGLX.cpp -DEFINES += -DUSE_GLX -endif - -ifeq ($(MOZ_WIDGET_TOOLKIT),windows) -ifdef WINCE -CPPSRCS += nsGLPbufferEGL.cpp -DEFINES += -DUSE_EGL -else -CPPSRCS += nsGLPbufferWGL.cpp -DEFINES += -DUSE_WGL -endif -endif - -ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT)) -CPPSRCS += nsGLPbufferCGL.cpp -DEFINES += -DUSE_CGL -endif +CPPSRCS += nsGLPbuffer$(WEBGL_PLATFORM).cpp +DEFINES += -DUSE_$(WEBGL_PLATFORM) else diff --git a/content/canvas/src/WebGLContext.cpp b/content/canvas/src/WebGLContext.cpp index 8d804a15181c..1d13f611d5da 100644 --- a/content/canvas/src/WebGLContext.cpp +++ b/content/canvas/src/WebGLContext.cpp @@ -100,13 +100,13 @@ WebGLContext::SetCanvasElement(nsICanvasElement* aParentCanvas) LogMessage("Canvas 3D: creating PBuffer..."); if (!forceSoftware) { -#if defined(WINCE) +#if defined(USE_EGL) mGLPbuffer = new nsGLPbufferEGL(); -#elif defined(XP_WIN) +#elif defined(USE_WGL) mGLPbuffer = new nsGLPbufferWGL(); -#elif defined(XP_UNIX) && defined(MOZ_X11) +#elif defined(USE_GLX) mGLPbuffer = new nsGLPbufferGLX(); -#elif defined(XP_MACOSX) +#elif defined(USE_CGL) mGLPbuffer = new nsGLPbufferCGL(); #else mGLPbuffer = nsnull; @@ -253,14 +253,20 @@ WebGLContext::Render(gfxContext *ctx, gfxPattern::GraphicsFilter f) nsRefPtr surf = mGLPbuffer->ThebesSurface(); if (!surf) return NS_OK; - // XXX we can optimize this on win32 at least, by creating an upside-down // DIB. nsRefPtr pat = new gfxPattern(surf); + +#if defined(USE_EGL) && defined(MOZ_X11) + if (getenv("IMAGE")) { +#endif gfxMatrix m; m.Translate(gfxPoint(0.0, mGLPbuffer->Height())); m.Scale(1.0, -1.0); pat->SetMatrix(m); +#if defined(USE_EGL) && defined(MOZ_X11) + } +#endif // XXX I don't want to use PixelSnapped here, but layout doesn't guarantee // pixel alignment for this stuff! diff --git a/content/canvas/src/WebGLContext.h b/content/canvas/src/WebGLContext.h index 60720cb08e94..8f6680ffb542 100644 --- a/content/canvas/src/WebGLContext.h +++ b/content/canvas/src/WebGLContext.h @@ -285,10 +285,12 @@ protected: WebGLObjectRefPtr mBoundElementArrayBuffer; WebGLObjectRefPtr mCurrentProgram; - nsTArray > mBoundColorFramebuffers; - nsRefPtr mBoundDepthFramebuffer; - nsRefPtr mBoundStencilFramebuffer; + // XXX these 3 are wrong types, and aren't used atm (except for the length of the attachments) + nsTArray > mFramebufferColorAttachments; + nsRefPtr mFramebufferDepthAttachment; + nsRefPtr mFramebufferStencilAttachment; + nsRefPtr mBoundFramebuffer; nsRefPtr mBoundRenderbuffer; // lookup tables for GL name -> object wrapper diff --git a/content/canvas/src/WebGLContextGL.cpp b/content/canvas/src/WebGLContextGL.cpp index 6fee5328f3fe..fceabd6c8fe5 100644 --- a/content/canvas/src/WebGLContextGL.cpp +++ b/content/canvas/src/WebGLContextGL.cpp @@ -382,6 +382,8 @@ WebGLContext::BindBuffer(GLenum target, nsIWebGLBuffer *buffer) MakeContextCurrent(); + //printf ("BindBuffer0: %04x\n", gl->fGetError()); + if (target == LOCAL_GL_ARRAY_BUFFER) { mBoundArrayBuffer = wbuf; } else if (target == LOCAL_GL_ELEMENT_ARRAY_BUFFER) { @@ -392,6 +394,8 @@ WebGLContext::BindBuffer(GLenum target, nsIWebGLBuffer *buffer) gl->fBindBuffer(target, wbuf ? wbuf->GLName() : 0); + //printf ("BindBuffer: %04x\n", gl->fGetError()); + return NS_OK; } @@ -405,17 +409,8 @@ WebGLContext::BindFramebuffer(GLenum target, nsIWebGLFramebuffer *fb) MakeContextCurrent(); - if (target >= LOCAL_GL_COLOR_ATTACHMENT0 && - target < (LOCAL_GL_COLOR_ATTACHMENT0 + mBoundColorFramebuffers.Length())) - { - int targetOffset = target - LOCAL_GL_COLOR_ATTACHMENT0; - mBoundColorFramebuffers[targetOffset] = wfb; - } else if (target == LOCAL_GL_DEPTH_ATTACHMENT) { - mBoundDepthFramebuffer = wfb; - } else if (target == LOCAL_GL_STENCIL_ATTACHMENT) { - mBoundStencilFramebuffer = wfb; - } else { - return ErrorMessage("glBindFramebuffer: invalid target"); + if (target != LOCAL_GL_FRAMEBUFFER) { + return ErrorMessage("glBindFramebuffer: target must be GL_FRAMEBUFFER"); } gl->fBindFramebuffer(target, wfb ? wfb->GLName() : 0); @@ -432,7 +427,7 @@ WebGLContext::BindRenderbuffer(GLenum target, nsIWebGLRenderbuffer *rb) return ErrorMessage("glBindRenderbuffer: renderbuffer has already been deleted!"); if (target != LOCAL_GL_RENDERBUFFER) - return ErrorMessage("glBindRenderbuffer: invalid target"); + return ErrorMessage("glBindRenderbuffer: target must be GL_RENDERBUFFER"); MakeContextCurrent(); @@ -605,7 +600,7 @@ WebGLContext::BufferSubData(GLenum target, GLsizeiptr offset) boundBuffer->Count(), offset, arrayBuf->NativeSize()); return NS_ERROR_FAILURE; } -#ifdef DEBUG +#ifdef DEBUG_mwsteele LogMessage("bufferSubData: buffer (%d) for data at offset (%d+%d)", boundBuffer->Count(), offset, arrayBuf->NativeSize()); #endif // all good @@ -621,7 +616,7 @@ WebGLContext::BufferSubData(GLenum target, GLsizeiptr offset) boundBuffer->Count(), offset, canvasArrayObj->NativeCount()); return NS_ERROR_FAILURE; } -#ifdef DEBUG +#ifdef DEBUG_mwsteele LogMessage("bufferSubData: buffer (%d) for data at offset (%d+%d)", boundBuffer->Count(), offset, canvasArrayObj->NativeSize()); #endif // all good @@ -981,8 +976,12 @@ WebGLContext::DrawArrays(GLenum mode, GLint offset, GLsizei count) MakeContextCurrent(); + //printf ("DrawArrays0: %04x\n", gl->fGetError()); + gl->fDrawArrays(mode, offset, count); + //printf ("DrawArrays: %04x\n", gl->fGetError()); + Invalidate(); return NS_OK; @@ -991,6 +990,8 @@ WebGLContext::DrawArrays(GLenum mode, GLint offset, GLsizei count) NS_IMETHODIMP WebGLContext::DrawElements(GLenum mode, GLuint count, GLenum type, GLuint offset) { + int elementSize = 0; + switch (mode) { case LOCAL_GL_TRIANGLES: case LOCAL_GL_TRIANGLE_STRIP: @@ -1006,9 +1007,17 @@ WebGLContext::DrawElements(GLenum mode, GLuint count, GLenum type, GLuint offset switch (type) { case LOCAL_GL_UNSIGNED_SHORT: + elementSize = 2; + if (offset % 2 != 0) + return ErrorMessage("drawElements: invalid offset (must be a multiple of 2) for UNSIGNED_SHORT"); break; + + case LOCAL_GL_UNSIGNED_BYTE: + elementSize = 1; + break; + default: - return ErrorMessage("drawElements: type must be UNSIGNED_SHORT"); + return ErrorMessage("drawElements: type must be UNSIGNED_SHORT or UNSIGNED_BYTE"); } if (!mBoundElementArrayBuffer) @@ -1017,12 +1026,13 @@ WebGLContext::DrawElements(GLenum mode, GLuint count, GLenum type, GLuint offset if (offset+count < offset || offset+count < count) return ErrorMessage("glDrawElements: overflow in offset+count"); - if (count + offset > mBoundElementArrayBuffer->Count()) + if (count*elementSize + offset > mBoundElementArrayBuffer->ByteCount()) return ErrorMessage("glDrawElements: bound element array buffer is too small for given count and offset"); MakeContextCurrent(); // XXXmark fix validation + // XXX either GLushort or GLubyte; just put this calculation as a method on the array object #if 0 GLuint maxindex = 0; GLushort *ubuf = (GLushort*) gl->fMapBuffer(LOCAL_GL_ELEMENT_ARRAY_BUFFER, LOCAL_GL_READ_ONLY); @@ -1040,7 +1050,7 @@ WebGLContext::DrawElements(GLenum mode, GLuint count, GLenum type, GLuint offset if (!ValidateBuffers(maxindex)) return ErrorMessage("glDrawElements: ValidateBuffers failed"); #endif - // XXX uh, is this offset, or offset * elementsize? + gl->fDrawElements(mode, count, type, (GLvoid*) (offset)); Invalidate(); @@ -1075,9 +1085,9 @@ WebGLContext::FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum r return ErrorMessage("glFramebufferRenderbuffer: renderbuffer has already been deleted!"); if (target != LOCAL_GL_FRAMEBUFFER) - return ErrorMessage("glFramebufferRenderbuffer: target must be LOCAL_GL_FRAMEBUFFER"); + return ErrorMessage("glFramebufferRenderbuffer: target must be GL_FRAMEBUFFER"); - if ((attachment < LOCAL_GL_COLOR_ATTACHMENT0 || attachment >= LOCAL_GL_COLOR_ATTACHMENT0 + mBoundColorFramebuffers.Length()) && + if ((attachment < LOCAL_GL_COLOR_ATTACHMENT0 || attachment >= LOCAL_GL_COLOR_ATTACHMENT0 + mFramebufferColorAttachments.Length()) && attachment != LOCAL_GL_DEPTH_ATTACHMENT && attachment != LOCAL_GL_STENCIL_ATTACHMENT) return ErrorMessage("glFramebufferRenderbuffer: invalid attachment"); @@ -1096,10 +1106,10 @@ WebGLContext::FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum r NS_IMETHODIMP WebGLContext::FramebufferTexture2D(GLenum target, - GLenum attachment, - GLenum textarget, - nsIWebGLTexture *wtex, - GLint level) + GLenum attachment, + GLenum textarget, + nsIWebGLTexture *wtex, + GLint level) { WebGLTexture *tex = static_cast(wtex); @@ -1109,7 +1119,7 @@ WebGLContext::FramebufferTexture2D(GLenum target, if (target != LOCAL_GL_FRAMEBUFFER) return ErrorMessage("glFramebufferTexture2D: target must be GL_FRAMEBUFFER"); - if ((attachment < LOCAL_GL_COLOR_ATTACHMENT0 || attachment >= LOCAL_GL_COLOR_ATTACHMENT0 + mBoundColorFramebuffers.Length()) && + if ((attachment < LOCAL_GL_COLOR_ATTACHMENT0 || attachment >= LOCAL_GL_COLOR_ATTACHMENT0 + mFramebufferColorAttachments.Length()) && attachment != LOCAL_GL_DEPTH_ATTACHMENT && attachment != LOCAL_GL_STENCIL_ATTACHMENT) return ErrorMessage("glFramebufferTexture2D: invalid attachment"); @@ -1122,6 +1132,8 @@ WebGLContext::FramebufferTexture2D(GLenum target, if (level != 0) return ErrorMessage("glFramebufferTexture2D: level must be 0"); + // XXXXX we need to store/reference this attachment! + MakeContextCurrent(); gl->fFramebufferTexture2D(target, attachment, textarget, tex->GLName(), level); @@ -2027,7 +2039,6 @@ WebGLContext::GetUniform(nsIWebGLProgram *prog, GLint location) GLint uArraySize = 0; GLenum uType = 0; - fprintf (stderr, "GetUniform: program: %d location: %d\n", program, location); gl->fGetActiveUniform(program, location, 0, NULL, &uArraySize, &uType, NULL); if (uArraySize == 0) return NS_ERROR_FAILURE; @@ -2891,15 +2902,40 @@ WebGLContext::ValidateGL() // make sure that the opengl stuff that we need is supported GLint val = 0; + // XXX this exposes some strange latent bug; what's going on? + //MakeContextCurrent(); + gl->fGetIntegerv(LOCAL_GL_MAX_VERTEX_ATTRIBS, &val); + if (val == 0) { + LogMessage("GL_MAX_VERTEX_ATTRIBS is 0!"); + return PR_FALSE; + } + mAttribBuffers.SetLength(val); + //fprintf(stderr, "GL_MAX_VERTEX_ATTRIBS: %d\n", val); + gl->fGetIntegerv(LOCAL_GL_MAX_TEXTURE_UNITS, &val); + if (val == 0) { + LogMessage("GL_MAX_TEXTURE_UNITS is 0!"); + return PR_FALSE; + } + mBound2DTextures.SetLength(val); mBoundCubeMapTextures.SetLength(val); + //fprintf(stderr, "GL_MAX_TEXTURE_UNITS: %d\n", val); + gl->fGetIntegerv(LOCAL_GL_MAX_COLOR_ATTACHMENTS, &val); - mBoundColorFramebuffers.SetLength(val); + mFramebufferColorAttachments.SetLength(val); + +#ifdef DEBUG_vladimir + gl->fGetIntegerv(LOCAL_GL_IMPLEMENTATION_COLOR_READ_FORMAT, &val); + fprintf(stderr, "GL_IMPLEMENTATION_COLOR_READ_FORMAT: 0x%04x\n", val); + + gl->fGetIntegerv(LOCAL_GL_IMPLEMENTATION_COLOR_READ_TYPE, &val); + fprintf(stderr, "GL_IMPLEMENTATION_COLOR_READ_TYPE: 0x%04x\n", val); +#endif #ifndef USE_GLES2 // gl_PointSize is always available in ES2 GLSL diff --git a/content/canvas/src/WebGLContextValidate.cpp b/content/canvas/src/WebGLContextValidate.cpp index 7e44217d19df..ab21f7a123bf 100644 --- a/content/canvas/src/WebGLContextValidate.cpp +++ b/content/canvas/src/WebGLContextValidate.cpp @@ -48,9 +48,6 @@ using namespace mozilla; PRBool WebGLContext::ValidateBuffers(PRUint32 count) { - GLint len = 0; - GLint enabled = 0, size = 4, type = LOCAL_GL_FLOAT, binding = 0; - PRBool someEnabled = PR_FALSE; GLint currentProgram = -1; GLint numAttributes = -1; diff --git a/content/canvas/src/glwrap.cpp b/content/canvas/src/glwrap.cpp index d979e00546ae..8f6a221d5a02 100644 --- a/content/canvas/src/glwrap.cpp +++ b/content/canvas/src/glwrap.cpp @@ -50,11 +50,6 @@ #define MAX_SYMBOL_LENGTH 128 #define MAX_SYMBOL_NAMES 5 -#ifdef MOZ_X11 -#define GLX_GLXEXT_LEGACY -#include -#endif - bool LibrarySymbolLoader::OpenLibrary(const char *library) { @@ -333,8 +328,10 @@ GLES20Wrap::InitWithPrefix(const char *prefix, bool trygl) { (PRFuncPtr*) &fIsFramebuffer, { "IsFramebuffer", "IsFramebufferEXT", NULL } }, { (PRFuncPtr*) &fIsRenderbuffer, { "IsRenderbuffer", "IsRenderbufferEXT", NULL } }, { (PRFuncPtr*) &fRenderbufferStorage, { "RenderbufferStorage", "RenderbufferStorageEXT", NULL } }, +#if 0 { (PRFuncPtr*) &fMapBuffer, { "MapBuffer", NULL } }, { (PRFuncPtr*) &fUnmapBuffer, { "UnmapBuffer", NULL } }, +#endif { NULL, { NULL } }, diff --git a/content/canvas/src/glwrap.h b/content/canvas/src/glwrap.h index e852dfe9b248..a1934b669239 100644 --- a/content/canvas/src/glwrap.h +++ b/content/canvas/src/glwrap.h @@ -56,10 +56,6 @@ #define GLAPI #endif -#ifdef WINCE -#define USE_GLES2 -#endif - typedef char realGLboolean; class LibrarySymbolLoader @@ -301,10 +297,12 @@ public: PFNGLLINEWIDTHPROC fLineWidth; typedef void (GLAPIENTRY * PFNGLLINKPROGRAMPROC) (GLuint program); PFNGLLINKPROGRAMPROC fLinkProgram; +#if 0 typedef void * (GLAPIENTRY * PFNGLMAPBUFFERPROC) (GLenum target, GLenum access); PFNGLMAPBUFFERPROC fMapBuffer; typedef realGLboolean (GLAPIENTRY * PFNGLUNAMPBUFFERPROC) (GLenum target); PFNGLUNAMPBUFFERPROC fUnmapBuffer; +#endif typedef void (GLAPIENTRY * PFNGLPIXELSTOREIPROC) (GLenum pname, GLint param); PFNGLPIXELSTOREIPROC fPixelStorei; typedef void (GLAPIENTRY * PFNGLPOLYGONOFFSETPROC) (GLfloat factor, GLfloat bias); diff --git a/content/canvas/src/localgl.h b/content/canvas/src/localgl.h index 1abc93caea9f..1773ea6ab73f 100644 --- a/content/canvas/src/localgl.h +++ b/content/canvas/src/localgl.h @@ -3025,6 +3025,9 @@ typedef PRInt32 GLintptr; #define LOCAL_GL_FOG_SPECULAR_TEXTURE_WIN 0x80EC #define LOCAL_GL_WIN_swap_hint 1 +#define LOCAL_GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A +#define LOCAL_GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B + #define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 #define WGL_DRAW_TO_WINDOW_ARB 0x2001 #define WGL_DRAW_TO_BITMAP_ARB 0x2002 @@ -3087,4 +3090,73 @@ typedef PRInt32 GLintptr; #define WGL_SAMPLE_BUFFERS_ARB 0x2041 #define WGL_SAMPLES_ARB 0x2042 + +#define EGL_BUFFER_SIZE 0x3020 +#define EGL_ALPHA_SIZE 0x3021 +#define EGL_BLUE_SIZE 0x3022 +#define EGL_GREEN_SIZE 0x3023 +#define EGL_RED_SIZE 0x3024 +#define EGL_DEPTH_SIZE 0x3025 +#define EGL_STENCIL_SIZE 0x3026 +#define EGL_CONFIG_CAVEAT 0x3027 +#define EGL_CONFIG_ID 0x3028 +#define EGL_LEVEL 0x3029 +#define EGL_MAX_PBUFFER_HEIGHT 0x302A +#define EGL_MAX_PBUFFER_PIXELS 0x302B +#define EGL_MAX_PBUFFER_WIDTH 0x302C +#define EGL_NATIVE_RENDERABLE 0x302D +#define EGL_NATIVE_VISUAL_ID 0x302E +#define EGL_NATIVE_VISUAL_TYPE 0x302F +#define EGL_PRESERVED_RESOURCES 0x3030 +#define EGL_SAMPLES 0x3031 +#define EGL_SAMPLE_BUFFERS 0x3032 +#define EGL_SURFACE_TYPE 0x3033 +#define EGL_TRANSPARENT_TYPE 0x3034 +#define EGL_TRANSPARENT_BLUE_VALUE 0x3035 +#define EGL_TRANSPARENT_GREEN_VALUE 0x3036 +#define EGL_TRANSPARENT_RED_VALUE 0x3037 +#define EGL_NONE 0x3038 +#define EGL_BIND_TO_TEXTURE_RGB 0x3039 +#define EGL_BIND_TO_TEXTURE_RGBA 0x303A +#define EGL_MIN_SWAP_INTERVAL 0x303B +#define EGL_MAX_SWAP_INTERVAL 0x303C +#define EGL_LUMINANCE_SIZE 0x303D +#define EGL_ALPHA_MASK_SIZE 0x303E +#define EGL_COLOR_BUFFER_TYPE 0x303F +#define EGL_RENDERABLE_TYPE 0x3040 +#define EGL_MATCH_NATIVE_PIXMAP 0x3041 +#define EGL_CONFORMANT 0x3042 +#define EGL_OPENGL_ES_BIT 0x0001 +#define EGL_OPENVG_BIT 0x0002 +#define EGL_OPENGL_ES2_BIT 0x0004 +#define EGL_OPENGL_ES_API 0x30A0 +#define EGL_PBUFFER_BIT 0x0001 +#define EGL_PIXMAP_BIT 0x0002 +#define EGL_WINDOW_BIT 0x0004 +#define EGL_MULTISAMPLE_RESOLVE_BOX_BIT 0x0200 +#define EGL_SWAP_BEHAVIOR_PRESERVED_BIT 0x0400 +#define EGL_VENDOR 0x3053 +#define EGL_VERSION 0x3054 +#define EGL_EXTENSIONS 0x3055 +#define EGL_CLIENT_APIS 0x308D +#define EGL_HEIGHT 0x3056 +#define EGL_WIDTH 0x3057 +#define EGL_LARGEST_PBUFFER 0x3058 +#define EGL_TEXTURE_FORMAT 0x3080 +#define EGL_TEXTURE_TARGET 0x3081 +#define EGL_MIPMAP_TEXTURE 0x3082 +#define EGL_MIPMAP_LEVEL 0x3083 +#define EGL_RENDER_BUFFER 0x3086 +#define EGL_VG_COLORSPACE 0x3087 +#define EGL_VG_ALPHA_FORMAT 0x3088 +#define EGL_HORIZONTAL_RESOLUTION 0x3090 +#define EGL_VERTICAL_RESOLUTION 0x3091 +#define EGL_PIXEL_ASPECT_RATIO 0x3092 +#define EGL_SWAP_BEHAVIOR 0x3093 +#define EGL_MULTISAMPLE_RESOLVE 0x3099 +#define EGL_CONTEXT_CLIENT_TYPE 0x3097 +#define EGL_CONTEXT_CLIENT_VERSION 0x3098 +#define EGL_FALSE 0 +#define EGL_TRUE 1 + #endif diff --git a/content/canvas/src/nsCanvasRenderingContext2D.cpp b/content/canvas/src/nsCanvasRenderingContext2D.cpp index 1c0e844b186c..873469d7d25b 100644 --- a/content/canvas/src/nsCanvasRenderingContext2D.cpp +++ b/content/canvas/src/nsCanvasRenderingContext2D.cpp @@ -1898,6 +1898,8 @@ CreateFontStyleRule(const nsAString& aFont, if (NS_FAILED(rv)) return rv; + rule->RuleMatched(); + rule.forget(aResult); return NS_OK; } @@ -1961,15 +1963,19 @@ nsCanvasRenderingContext2D::SetFont(const nsAString& font) return rv; nsCOMArray parentRules; parentRules.AppendObject(parentRule); - parentContext = styleSet->ResolveStyleForRules(nsnull, nsnull, - nsnull, parentRules); + parentContext = + styleSet->ResolveStyleForRules(nsnull, nsnull, + nsCSSPseudoElements::ePseudo_NotPseudoElement, + nsnull, parentRules); } if (!parentContext) return NS_ERROR_FAILURE; nsRefPtr sc = - styleSet->ResolveStyleForRules(parentContext, nsnull, nsnull, rules); + styleSet->ResolveStyleForRules(parentContext, nsnull, + nsCSSPseudoElements::ePseudo_NotPseudoElement, + nsnull, rules); if (!sc) return NS_ERROR_FAILURE; const nsStyleFont* fontStyle = sc->GetStyleFont(); diff --git a/content/canvas/src/nsGLPbuffer.h b/content/canvas/src/nsGLPbuffer.h index b2fce87e6a5e..03b24da7091e 100644 --- a/content/canvas/src/nsGLPbuffer.h +++ b/content/canvas/src/nsGLPbuffer.h @@ -48,21 +48,35 @@ #include "gfxASurface.h" #include "gfxImageSurface.h" -#if defined(WINCE) -#include -#include "gfxDDrawSurface.h" +#ifdef USE_EGL +typedef int EGLint; +typedef unsigned int EGLBoolean; +typedef unsigned int EGLenum; +typedef void *EGLConfig; +typedef void *EGLContext; +typedef void *EGLDisplay; +typedef void *EGLSurface; +typedef void *EGLClientBuffer; #endif -#if defined(XP_WIN) +#ifdef XP_WIN #include "gfxWindowsSurface.h" #endif -#if defined(XP_UNIX) && defined(MOZ_X11) +#ifdef MOZ_X11 +#include "gfxXlibSurface.h" +#endif + +#if defined(WINCE) && defined(CAIRO_HAS_DDRAW_SURFACE) +#include "gfxDDrawSurface.h" +#endif + +#ifdef USE_GLX #define GLX_GLXEXT_LEGACY #include "GL/glx.h" #endif -#ifdef XP_MACOSX +#ifdef USE_CGL #include "gfxQuartzImageSurface.h" #include #endif @@ -126,7 +140,7 @@ protected: PrivateOSMesaContext mMesaContext; }; -#ifdef XP_MACOSX +#ifdef USE_CGL class nsGLPbufferCGL : public nsGLPbuffer { @@ -161,7 +175,7 @@ protected: }; #endif -#if defined(XP_UNIX) && defined(MOZ_X11) +#ifdef USE_GLX class nsGLPbufferGLX : public nsGLPbuffer { @@ -188,7 +202,7 @@ protected: }; #endif -#if defined(WINCE) +#ifdef USE_EGL class nsGLPbufferEGL : public nsGLPbuffer { @@ -211,12 +225,18 @@ protected: EGLSurface mSurface; EGLContext mContext; +#if defined(XP_WIN) nsRefPtr mThebesSurface; nsRefPtr mWindowsSurface; +#elif defined(MOZ_X11) + nsRefPtr mThebesSurface; + nsRefPtr mXlibSurface; + Visual *mVisual; +#endif }; #endif -#if defined(XP_WIN) && !defined(WINCE) +#ifdef USE_WGL class nsGLPbufferWGL : public nsGLPbuffer { diff --git a/content/canvas/src/nsGLPbufferEGL.cpp b/content/canvas/src/nsGLPbufferEGL.cpp index f77b65ccb92f..a850578bfbfc 100644 --- a/content/canvas/src/nsGLPbufferEGL.cpp +++ b/content/canvas/src/nsGLPbufferEGL.cpp @@ -37,87 +37,275 @@ * ***** END LICENSE BLOCK ***** */ // this must be first, else windows.h breaks us -#include "nsICanvasRenderingContextGL.h" +#include "WebGLContext.h" +#include "nsGLPbuffer.h" #include "nsDirectoryServiceUtils.h" #include "nsAppDirectoryServiceDefs.h" #include "nsIPrefService.h" -#include "nsGLPbuffer.h" -#include "nsCanvasRenderingContextGL.h" - #include "gfxContext.h" #include "glwrap.h" -#include -#include -#include -#include +#ifdef MOZ_X11 +#include + +typedef Display* EGLNativeDisplayType; +typedef Window EGLNativeWindowType; +typedef Pixmap EGLNativePixmapType; +#endif + +#ifdef WINCE +typedef HDC EGLNativeDisplayType; +typedef HWND EGLNativeWindowType; +typedef HDC EGLNativePixmapType; +#endif + +// some EGL defines +#define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType)0) +#define EGL_NO_CONTEXT ((EGLContext)0) +#define EGL_NO_DISPLAY ((EGLDisplay)0) +#define EGL_NO_SURFACE ((EGLSurface)0) + +using namespace mozilla; static PRUint32 gActiveBuffers = 0; +class EGLWrap + : public LibrarySymbolLoader +{ +public: + EGLWrap() : fGetCurrentContext(0) { } + + bool Init(); + +public: + typedef EGLDisplay (*pfnGetDisplay)(void *display_id); + pfnGetDisplay fGetDisplay; + typedef EGLContext (*pfnGetCurrentContext)(void); + pfnGetCurrentContext fGetCurrentContext; + typedef EGLBoolean (*pfnMakeCurrent)(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx); + pfnMakeCurrent fMakeCurrent; + typedef EGLBoolean (*pfnDestroyContext)(EGLDisplay dpy, EGLContext ctx); + pfnDestroyContext fDestroyContext; + typedef EGLContext (*pfnCreateContext)(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list); + pfnCreateContext fCreateContext; + typedef EGLBoolean (*pfnDestroySurface)(EGLDisplay dpy, EGLSurface surface); + pfnDestroySurface fDestroySurface; + typedef EGLSurface (*pfnCreatePbufferSurface)(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list); + pfnCreatePbufferSurface fCreatePbufferSurface; + typedef EGLSurface (*pfnCreatePixmapSurface)(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list); + pfnCreatePixmapSurface fCreatePixmapSurface; + typedef EGLBoolean (*pfnBindAPI)(EGLenum api); + pfnBindAPI fBindAPI; + typedef EGLBoolean (*pfnInitialize)(EGLDisplay dpy, EGLint *major, EGLint *minor); + pfnInitialize fInitialize; + typedef EGLBoolean (*pfnChooseConfig)(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config); + pfnChooseConfig fChooseConfig; + typedef EGLint (*pfnGetError)(void); + pfnGetError fGetError; + typedef EGLBoolean (*pfnGetConfigAttrib)(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value); + pfnGetConfigAttrib fGetConfigAttrib; + typedef EGLBoolean (*pfnGetConfigs)(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config); + pfnGetConfigs fGetConfigs; + typedef EGLBoolean (*pfnWaitNative)(EGLint engine); + pfnWaitNative fWaitNative; +}; + +bool +EGLWrap::Init() +{ + if (fGetDisplay) + return true; + + SymLoadStruct symbols[] = { + { (PRFuncPtr*) &fGetDisplay, { "eglGetDisplay", NULL } }, + { (PRFuncPtr*) &fGetCurrentContext, { "eglGetCurrentContext", NULL } }, + { (PRFuncPtr*) &fMakeCurrent, { "eglMakeCurrent", NULL } }, + { (PRFuncPtr*) &fDestroyContext, { "eglDestroyContext", NULL } }, + { (PRFuncPtr*) &fCreateContext, { "eglCreateContext", NULL } }, + { (PRFuncPtr*) &fDestroySurface, { "eglDestroySurface", NULL } }, + { (PRFuncPtr*) &fCreatePbufferSurface, { "eglCreatePbufferSurface", NULL } }, + { (PRFuncPtr*) &fCreatePixmapSurface, { "eglCreatePixmapSurface", NULL } }, + { (PRFuncPtr*) &fBindAPI, { "eglBindAPI", NULL } }, + { (PRFuncPtr*) &fInitialize, { "eglInitialize", NULL } }, + { (PRFuncPtr*) &fChooseConfig, { "eglChooseConfig", NULL } }, + { (PRFuncPtr*) &fGetError, { "eglGetError", NULL } }, + { (PRFuncPtr*) &fGetConfigs, { "eglGetConfigs", NULL } }, + { (PRFuncPtr*) &fGetConfigAttrib, { "eglGetConfigAttrib", NULL } }, + { (PRFuncPtr*) &fWaitNative, { "eglWaitNative", NULL } }, + { NULL, { NULL } } + }; + + return LoadSymbols(&symbols[0], true); +} + +static EGLWrap gEGLWrap; + nsGLPbufferEGL::nsGLPbufferEGL() : mDisplay(0), mConfig(0), mSurface(0) { gActiveBuffers++; - fprintf (stderr, "nsGLPbufferEGL: gActiveBuffers: %d\n", gActiveBuffers); } +#ifdef WINCE +// XXX wrong +#define EGL_LIB "\\windows\\libEGL.dll" +#define GLES2_LIB "\\windows\\libGLESv2.dll" +#else +#define EGL_LIB "/usr/lib/libEGL.so" +#define GLES2_LIB "/usr/lib/libGLESv2.so" +#endif + PRBool -nsGLPbufferEGL::Init(nsCanvasRenderingContextGLPrivate *priv) +nsGLPbufferEGL::Init(mozilla::WebGLContext *priv) { mPriv = priv; - nsresult rv; +#ifdef NS_OSSO + // Maemo has missing DSO dependencies on their OpenGL libraries; + // so ensure that the prerequisite libs are loaded in the process + // before loading GL. An alternate approach is to use LD_PRELOAD. - mDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); + // We'll just leak these libs; pvr_um.so seems to have been + // present on an older OS image, and now pvr2d.so is used. + PRLibSpec lspec; + lspec.type = PR_LibSpec_Pathname; - if (!eglInitialize(mDisplay, NULL, NULL)) { - LogMessage(NS_LITERAL_CSTRING("egl init failed")); + lspec.value.pathname = "/usr/lib/libpvr_um.so"; + PR_LoadLibraryWithFlags(lspec, PR_LD_LAZY | PR_LD_GLOBAL); + + lspec.value.pathname = "/usr/lib/libpvr2d.so"; + PR_LoadLibraryWithFlags(lspec, PR_LD_LAZY | PR_LD_GLOBAL); +#endif + + if (!gEGLWrap.OpenLibrary(EGL_LIB)) { + LogMessage("egl OpenLibrary failed"); return PR_FALSE; } - eglBindAPI (EGL_OPENGL_ES_API); + if (!gEGLWrap.Init()) { + LogMessage("eglWrap init failed"); + return PR_FALSE; + } + mDisplay = gEGLWrap.fGetDisplay(0); + + if (!gEGLWrap.fInitialize(mDisplay, NULL, NULL)) { + LogMessage("egl init failed"); + return PR_FALSE; + } + + gEGLWrap.fBindAPI (EGL_OPENGL_ES_API); + +#if defined(MOZ_X11) && defined(NS_OSSO) EGLint attribs[] = { EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, - EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, -#if 0 + EGL_SURFACE_TYPE, EGL_PIXMAP_BIT, EGL_RED_SIZE, 3, EGL_GREEN_SIZE, 3, EGL_BLUE_SIZE, 3, - /* EGL_ALPHA_SIZE, 3, */ + EGL_ALPHA_SIZE, 3, EGL_DEPTH_SIZE, 1, -#endif EGL_NONE }; - EGLConfig cfg; EGLint ncfg = 0; + EGLConfig cfg; - if (!eglChooseConfig(mDisplay, attribs, &cfg, 1, &ncfg) || - ncfg != 1) + if (!gEGLWrap.fChooseConfig(mDisplay, attribs, &cfg, 1, &ncfg) || + ncfg < 1) { - LogMessage(NS_LITERAL_CSTRING("Canvas 3D: eglChooseConfig failed")); + LogMessage("Canvas 3D: eglChooseConfig failed (ncfg: %d err: 0x%04x)", ncfg, gEGLWrap.fGetError()); return PR_FALSE; } - mConfig = cfg; + EGLint visid; + gEGLWrap.fGetConfigAttrib(mDisplay, cfg, EGL_NATIVE_VISUAL_ID, &visid); + + XVisualInfo vinfo; + vinfo.visualid = visid; + int pad; + + LogMessage("Visual ID: %d\n", visid); + + XVisualInfo *vf = XGetVisualInfo(gdk_x11_get_default_xdisplay(), VisualIDMask, &vinfo, &pad); + + if (!vf) { + LogMessage("Null VisualInfo!"); + return PR_FALSE; + } + + LogMessage("Visual: 0x%08x\n", vf->visual); + + mVisual = vf->visual; + mConfig = cfg; +#elif defined(WINCE) +#define MAX_CONFIGS 32 + EGLConfig configs[MAX_CONFIGS]; + EGLint numConfigs; + + gEGLWrap.fGetConfigs(mDisplay, configs, MAX_CONFIGS, &numConfigs); + + mConfig = 0; + + for (int i = 0; i < numConfigs; ++i) { + EGLint id; + EGLint surfaces, renderables; + EGLint rsize, gsize, bsize, asize, dsize; + + gEGLWrap.fGetConfigAttrib(mDisplay, configs[i], EGL_CONFIG_ID, &id); + gEGLWrap.fGetConfigAttrib(mDisplay, configs[i], EGL_SURFACE_TYPE, &surfaces); + gEGLWrap.fGetConfigAttrib(mDisplay, configs[i], EGL_RENDERABLE_TYPE, &renderables); + gEGLWrap.fGetConfigAttrib(mDisplay, configs[i], EGL_RED_SIZE, &rsize); + gEGLWrap.fGetConfigAttrib(mDisplay, configs[i], EGL_GREEN_SIZE, &gsize); + gEGLWrap.fGetConfigAttrib(mDisplay, configs[i], EGL_BLUE_SIZE, &bsize); + gEGLWrap.fGetConfigAttrib(mDisplay, configs[i], EGL_ALPHA_SIZE, &asize); + gEGLWrap.fGetConfigAttrib(mDisplay, configs[i], EGL_DEPTH_SIZE, &dsize); + +#ifdef DEBUG_vladimir + fprintf(stderr, "config 0x%02x: s %x api %x rgba %d %d %d %d d %d\n", id, surfaces, renderables, rsize, gsize, bsize, asize, dsize); +#endif + + if ((surfaces & EGL_PBUFFER_BIT) && + (renderables & EGL_OPENGL_ES2_BIT) && + (rsize > 3) && + (gsize > 3) && + (bsize > 3) && + (asize > 3) && + (dsize > 1)) + { + mConfig = configs[i]; + break; + } + } + + if (mConfig == 0) { + LogMessage("Failed to find config!"); + return PR_FALSE; + } +#else +#error need some boilerplate code for EGL +#endif + + LogMessage("Resize 2,2"); Resize(2, 2); - if (!mGLWrap.OpenLibrary("\\windows\\libglesv2.dll")) { - LogMessage(NS_LITERAL_CSTRING("Canvas 3D: Couldn't open opengl lib [1]")); + LogMessage("OpenLibrary"); + if (!mGLWrap.OpenLibrary(GLES2_LIB)) { + LogMessage("Canvas 3D: Couldn't open EGL lib [1]"); return PR_FALSE; } + LogMessage("GLWrap.Init"); if (!mGLWrap.Init(GLES20Wrap::TRY_NATIVE_GL)) { - LogMessage(NS_LITERAL_CSTRING("Canvas 3D: GLWrap init failed")); + LogMessage("Canvas 3D: GLWrap init failed"); return PR_FALSE; } - + LogMessage("Init done"); return PR_TRUE; } @@ -130,12 +318,19 @@ nsGLPbufferEGL::Resize(PRInt32 width, PRInt32 height) return PR_TRUE; } + LogMessage("Resize %d %d start", width, height); + Destroy(); + LogMessage("Destroyed"); + +#ifdef XP_WIN mWindowsSurface = new gfxWindowsSurface(gfxIntSize(width, height), gfxASurface::ImageFormatARGB32); if (mWindowsSurface->CairoStatus() != 0) { +#ifdef DEBUG_vladimir fprintf (stderr, "image surface failed\n"); +#endif return PR_FALSE; } @@ -147,20 +342,56 @@ nsGLPbufferEGL::Resize(PRInt32 width, PRInt32 height) EGL_NONE }; - mSurface = eglCreatePbufferSurface(mDisplay, mConfig, attrs); + mSurface = gEGLWrap.fCreatePbufferSurface(mDisplay, mConfig, attrs); if (!mSurface) { - LogMessage(NS_LITERAL_CSTRING("Canvas 3D: eglCreatePbufferSurface failed")); + LogMessage("Canvas 3D: eglCreatePbufferSurface failed"); + return PR_FALSE; + } +#else + + mXlibSurface = new gfxXlibSurface(gdk_x11_get_default_xdisplay(), + mVisual, + gfxIntSize(width, height), + 32); + if (!mXlibSurface || mXlibSurface->CairoStatus() != 0) { +#ifdef DEBUG_vladimir + fprintf (stderr, "Failed to create gfxXlibSurface"); +#endif return PR_FALSE; } - eglBindAPI(EGL_OPENGL_ES_API); + LogMessage("Created gfxXlibSurface, Drawable: 0x%08x", mXlibSurface->XDrawable()); + + // we need to XSync to ensure that the Pixmap is created on the server side, + // otherwise eglCreatePixmapSurface will fail (because it isn't part of the normal + // X protocol). + XSync(gdk_x11_get_default_xdisplay(), 0); + + EGLint attrs[] = { + EGL_NONE + }; + + Pixmap px = (Pixmap) mXlibSurface->XDrawable(); + + mSurface = gEGLWrap.fCreatePixmapSurface(mDisplay, mConfig, (EGLNativePixmapType) px, attrs); + if (!mSurface) { +#ifdef DEBUG_vladimir + fprintf (stderr, "Failed to create Pixmap EGLSurface\n"); +#endif + return PR_FALSE; + } + + LogMessage("mSurface: %p", mSurface); +#endif + + gEGLWrap.fBindAPI(EGL_OPENGL_ES_API); EGLint cxattrs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; - mContext = eglCreateContext(mDisplay, mConfig, EGL_NO_CONTEXT, cxattrs); + mContext = gEGLWrap.fCreateContext(mDisplay, mConfig, EGL_NO_CONTEXT, cxattrs); if (!mContext) { Destroy(); return PR_FALSE; @@ -169,7 +400,10 @@ nsGLPbufferEGL::Resize(PRInt32 width, PRInt32 height) mWidth = width; mHeight = height; - fprintf (stderr, "Resize: %d %d\n", width, height); +#ifdef MOZ_X11 + mThebesSurface = new gfxImageSurface(gfxIntSize(width, height), gfxASurface::ImageFormatARGB32); +#endif + return PR_TRUE; } @@ -177,17 +411,27 @@ void nsGLPbufferEGL::Destroy() { if (mContext) { - eglDestroyContext(mDisplay, mContext); + gEGLWrap.fDestroyContext(mDisplay, mContext); mContext = 0; } if (mSurface) { - eglDestroySurface(mDisplay, mSurface); + gEGLWrap.fDestroySurface(mDisplay, mSurface); mSurface = 0; } sCurrentContextToken = nsnull; + + // leak this +#ifdef MOZ_X11 + NS_IF_ADDREF(mXlibSurface.get()); + mXlibSurface = nsnull; +#else + mWindowsSurface = nsnull; +#endif + mThebesSurface = nsnull; + } nsGLPbufferEGL::~nsGLPbufferEGL() @@ -195,17 +439,16 @@ nsGLPbufferEGL::~nsGLPbufferEGL() Destroy(); gActiveBuffers--; - fprintf (stderr, "nsGLPbufferEGL: gActiveBuffers: %d\n", gActiveBuffers); fflush (stderr); } void nsGLPbufferEGL::MakeContextCurrent() { - if (eglGetCurrentContext() == mContext) + if (gEGLWrap.fGetCurrentContext() == mContext) return; - eglMakeCurrent(mDisplay, mSurface, mSurface, mContext); + gEGLWrap.fMakeCurrent(mDisplay, mSurface, mSurface, mContext); } void @@ -213,7 +456,15 @@ nsGLPbufferEGL::SwapBuffers() { // eglCopyBuffers(mDisplay, mSurface, mWindowsSurface->GetDC()); MakeContextCurrent(); - mGLWrap.fReadPixels (0, 0, mWidth, mHeight, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, mThebesSurface->Data()); + + //printf ("SwapBuffers0: %04x\n", mGLWrap.fGetError()); + + // this is wrong, we need to figure out a way to swap this, but we don't do anything here + mGLWrap.fFinish (); + + mGLWrap.fReadPixels (0, 0, mWidth, mHeight, LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE, mThebesSurface->Data()); + + //printf ("SwapBuffers: %04x\n", mGLWrap.fGetError()); #if 0 // premultiply the image @@ -226,5 +477,11 @@ nsGLPbufferEGL::SwapBuffers() gfxASurface* nsGLPbufferEGL::ThebesSurface() { +#if defined(MOZ_X11) && defined(NS_OSSO) + if (getenv("IMAGE")) + return mThebesSurface; + return mXlibSurface; +#elif defined(WINCE) return mThebesSurface; +#endif } diff --git a/content/events/src/nsXMLEventsManager.cpp b/content/events/src/nsXMLEventsManager.cpp index 8af698622c10..5dd1fa7f8287 100644 --- a/content/events/src/nsXMLEventsManager.cpp +++ b/content/events/src/nsXMLEventsManager.cpp @@ -366,8 +366,7 @@ nsXMLEventsManager::AttributeChanged(nsIDocument* aDocument, nsIContent* aContent, PRInt32 aNameSpaceID, nsIAtom* aAttribute, - PRInt32 aModType, - PRUint32 aStateMask) + PRInt32 aModType) { if (aNameSpaceID == kNameSpaceID_XMLEvents && (aAttribute == nsGkAtoms::event || diff --git a/content/html/content/public/nsHTMLMediaElement.h b/content/html/content/public/nsHTMLMediaElement.h index e00e63210a8d..36888748cd13 100644 --- a/content/html/content/public/nsHTMLMediaElement.h +++ b/content/html/content/public/nsHTMLMediaElement.h @@ -267,8 +267,9 @@ public: * Returns PR_TRUE if the media has played or completed a seek. * Used by video frame to determine whether to paint the poster. */ - PRBool GetPlayedOrSeeked() { return mHasPlayedOrSeeked; } + PRBool GetPlayedOrSeeked() const { return mHasPlayedOrSeeked; } + nsresult CopyInnerTo(nsGenericElement* aDest) const; protected: class MediaLoadListener; class LoadNextSourceEvent; @@ -519,4 +520,6 @@ protected: // alive while no-one is referencing it but the element may still fire // events of its own accord. PRPackedBool mHasSelfReference; + + nsRefPtr mPrintSurface; }; diff --git a/content/html/content/src/Makefile.in b/content/html/content/src/Makefile.in index 0a7eb0715daa..337cd88ce87c 100644 --- a/content/html/content/src/Makefile.in +++ b/content/html/content/src/Makefile.in @@ -127,6 +127,8 @@ INCLUDES += \ -I$(srcdir)/../../../xbl/src \ -I$(srcdir)/../../../../layout/style \ -I$(srcdir)/../../../../layout/tables \ + -I$(srcdir)/../../../../layout/xul/base/src \ + -I$(srcdir)/../../../../layout/generic \ -I$(srcdir)/../../../../dom/base \ -I$(srcdir) \ $(NULL) diff --git a/content/html/content/src/nsGenericHTMLElement.cpp b/content/html/content/src/nsGenericHTMLElement.cpp index 5ebcee1958f4..1408a0870d6b 100644 --- a/content/html/content/src/nsGenericHTMLElement.cpp +++ b/content/html/content/src/nsGenericHTMLElement.cpp @@ -2869,6 +2869,25 @@ nsGenericHTMLFrameElement::DestroyContent() nsGenericHTMLElement::DestroyContent(); } +nsresult +nsGenericHTMLFrameElement::CopyInnerTo(nsGenericElement* aDest) const +{ + nsresult rv = nsGenericHTMLElement::CopyInnerTo(aDest); + NS_ENSURE_SUCCESS(rv, rv); + + nsIDocument* doc = aDest->GetOwnerDoc(); + if (doc->IsStaticDocument() && mFrameLoader) { + nsGenericHTMLFrameElement* dest = + static_cast(aDest); + nsFrameLoader* fl = nsFrameLoader::Create(dest); + NS_ENSURE_STATE(fl); + dest->mFrameLoader = fl; + static_cast(mFrameLoader.get())->CreateStaticClone(fl); + } + + return rv; +} + //---------------------------------------------------------------------- nsresult diff --git a/content/html/content/src/nsGenericHTMLElement.h b/content/html/content/src/nsGenericHTMLElement.h index e200415a372c..588367e03e1f 100644 --- a/content/html/content/src/nsGenericHTMLElement.h +++ b/content/html/content/src/nsGenericHTMLElement.h @@ -917,6 +917,8 @@ public: PRBool aNotify); virtual void DestroyContent(); + nsresult CopyInnerTo(nsGenericElement* aDest) const; + // nsIDOMNSHTMLElement NS_IMETHOD GetTabIndex(PRInt32 *aTabIndex); NS_IMETHOD SetTabIndex(PRInt32 aTabIndex); diff --git a/content/html/content/src/nsHTMLCanvasElement.cpp b/content/html/content/src/nsHTMLCanvasElement.cpp index f1fe78ddf1a9..d9a6e8e564cb 100644 --- a/content/html/content/src/nsHTMLCanvasElement.cpp +++ b/content/html/content/src/nsHTMLCanvasElement.cpp @@ -58,7 +58,7 @@ #include "nsIRenderingContext.h" #include "nsICanvasRenderingContextInternal.h" - +#include "nsIDOMCanvasRenderingContext2D.h" #include "nsLayoutUtils.h" #define DEFAULT_CANVAS_WIDTH 300 @@ -118,7 +118,7 @@ public: nsIAtom* aPrefix, const nsAString& aValue, PRBool aNotify); virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const; - + nsresult CopyInnerTo(nsGenericElement* aDest) const; protected: nsIntSize GetWidthHeight(); @@ -218,6 +218,24 @@ nsHTMLCanvasElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName, return rv; } +nsresult +nsHTMLCanvasElement::CopyInnerTo(nsGenericElement* aDest) const +{ + nsresult rv = nsGenericHTMLElement::CopyInnerTo(aDest); + NS_ENSURE_SUCCESS(rv, rv); + if (aDest->GetOwnerDoc()->IsStaticDocument()) { + nsHTMLCanvasElement* dest = static_cast(aDest); + nsCOMPtr cxt; + dest->GetContext(NS_LITERAL_STRING("2d"), getter_AddRefs(cxt)); + nsCOMPtr context2d = do_QueryInterface(cxt); + if (context2d) { + context2d->DrawImage(const_cast(this), + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0); + } + } + return rv; +} + nsChangeHint nsHTMLCanvasElement::GetAttributeChangeHint(const nsIAtom* aAttribute, PRInt32 aModType) const diff --git a/content/html/content/src/nsHTMLImageElement.cpp b/content/html/content/src/nsHTMLImageElement.cpp index 53833cd3af72..f3ab6c7f3b21 100644 --- a/content/html/content/src/nsHTMLImageElement.cpp +++ b/content/html/content/src/nsHTMLImageElement.cpp @@ -148,6 +148,8 @@ public: virtual PRInt32 IntrinsicState() const; virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const; + nsresult CopyInnerTo(nsGenericElement* aDest) const; + void MaybeLoadImage(); protected: nsPoint GetXY(); @@ -658,4 +660,11 @@ nsHTMLImageElement::GetNaturalWidth(PRInt32* aNaturalWidth) return NS_OK; } - +nsresult +nsHTMLImageElement::CopyInnerTo(nsGenericElement* aDest) const +{ + if (aDest->GetOwnerDoc()->IsStaticDocument()) { + CreateStaticImageClone(static_cast(aDest)); + } + return nsGenericHTMLElement::CopyInnerTo(aDest); +} diff --git a/content/html/content/src/nsHTMLInputElement.cpp b/content/html/content/src/nsHTMLInputElement.cpp index 56a952f10ede..affee9e83588 100644 --- a/content/html/content/src/nsHTMLInputElement.cpp +++ b/content/html/content/src/nsHTMLInputElement.cpp @@ -557,6 +557,11 @@ nsHTMLInputElement::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const it->DoSetChecked(checked, PR_FALSE); } break; + case NS_FORM_INPUT_IMAGE: + if (it->GetOwnerDoc()->IsStaticDocument()) { + CreateStaticImageClone(it); + } + break; default: break; } diff --git a/content/html/content/src/nsHTMLMediaElement.cpp b/content/html/content/src/nsHTMLMediaElement.cpp index af94a31c3570..7e8ba773f485 100644 --- a/content/html/content/src/nsHTMLMediaElement.cpp +++ b/content/html/content/src/nsHTMLMediaElement.cpp @@ -78,6 +78,8 @@ #include "nsContentErrors.h" #include "nsCrossSiteListenerProxy.h" #include "nsCycleCollectionParticipant.h" +#include "nsLayoutUtils.h" +#include "nsVideoFrame.h" #ifdef MOZ_OGG #include "nsOggDecoder.h" @@ -1084,7 +1086,8 @@ nsresult nsHTMLMediaElement::BindToTree(nsIDocument* aDocument, nsIContent* aPar PRBool aCompileEventHandlers) { mIsBindingToTree = PR_TRUE; - mAutoplayEnabled = IsAutoplayEnabled(); + mAutoplayEnabled = + IsAutoplayEnabled() && (!aDocument || !aDocument->IsStaticDocument()); nsresult rv = nsGenericHTMLElement::BindToTree(aDocument, aParent, aBindingParent, @@ -1711,8 +1714,22 @@ void nsHTMLMediaElement::Paint(gfxContext* aContext, gfxPattern::GraphicsFilter aFilter, const gfxRect& aRect) { - if (mDecoder) + if (mPrintSurface) { + nsRefPtr pat = new gfxPattern(mPrintSurface); + if (!pat) + return; + // Make the source image fill the rectangle completely + pat->SetMatrix(gfxMatrix().Scale(mMediaSize.width/aRect.Width(), + mMediaSize.height/aRect.Height())); + + pat->SetFilter(aFilter); + + aContext->NewPath(); + aContext->PixelSnappedRectangleAndSetPattern(aRect, pat); + aContext->Fill(); + } else if (mDecoder) { mDecoder->Paint(aContext, aFilter, aRect); + } } nsresult nsHTMLMediaElement::DispatchSimpleEvent(const nsAString& aName) @@ -1995,3 +2012,36 @@ already_AddRefed nsHTMLMediaElement::GetDocumentLoadGroup() nsIDocument* doc = GetOwnerDoc(); return doc ? doc->GetDocumentLoadGroup() : nsnull; } + +nsresult +nsHTMLMediaElement::CopyInnerTo(nsGenericElement* aDest) const +{ + nsresult rv = nsGenericHTMLElement::CopyInnerTo(aDest); + NS_ENSURE_SUCCESS(rv, rv); + if (aDest->GetOwnerDoc()->IsStaticDocument()) { + nsHTMLMediaElement* dest = static_cast(aDest); + if (mPrintSurface) { + dest->mPrintSurface = mPrintSurface; + dest->mMediaSize = mMediaSize; + } else { + nsIFrame* frame = + GetPrimaryFrameFor(const_cast(this), + GetOwnerDoc()); + nsCOMPtr elem; + if (frame && frame->GetType() == nsGkAtoms::HTMLVideoFrame && + static_cast(frame)->ShouldDisplayPoster()) { + elem = do_QueryInterface(static_cast(frame)-> + GetPosterImage()); + } else { + elem = do_QueryInterface(const_cast(this)); + } + + nsLayoutUtils::SurfaceFromElementResult res = + nsLayoutUtils::SurfaceFromElement(elem, + nsLayoutUtils::SFE_WANT_NEW_SURFACE); + dest->mPrintSurface = res.mSurface; + dest->mMediaSize = nsIntSize(res.mSize.width, res.mSize.height); + } + } + return rv; +} diff --git a/content/html/content/src/nsHTMLObjectElement.cpp b/content/html/content/src/nsHTMLObjectElement.cpp index b4123f40e992..910b7cef8b89 100644 --- a/content/html/content/src/nsHTMLObjectElement.cpp +++ b/content/html/content/src/nsHTMLObjectElement.cpp @@ -123,6 +123,8 @@ public: virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const; + nsresult CopyInnerTo(nsGenericElement* aDest) const; + void StartObjectLoad() { StartObjectLoad(PR_TRUE); } NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(nsHTMLObjectElement, @@ -478,3 +480,16 @@ nsHTMLObjectElement::DestroyContent() RemovedFromDocument(); nsGenericHTMLFormElement::DestroyContent(); } + +nsresult +nsHTMLObjectElement::CopyInnerTo(nsGenericElement* aDest) const +{ + nsresult rv = nsGenericHTMLFormElement::CopyInnerTo(aDest); + NS_ENSURE_SUCCESS(rv, rv); + + if (aDest->GetOwnerDoc()->IsStaticDocument()) { + CreateStaticClone(static_cast(aDest)); + } + + return rv; +} diff --git a/content/html/content/src/nsHTMLOptionElement.cpp b/content/html/content/src/nsHTMLOptionElement.cpp index af4fcf952282..8a4164993037 100644 --- a/content/html/content/src/nsHTMLOptionElement.cpp +++ b/content/html/content/src/nsHTMLOptionElement.cpp @@ -120,6 +120,8 @@ public: virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const; + nsresult CopyInnerTo(nsGenericElement* aDest) const; + protected: /** * Get the select content element that contains this option, this @@ -528,3 +530,18 @@ nsHTMLOptionElement::Initialize(nsISupports* aOwner, return result; } + +nsresult +nsHTMLOptionElement::CopyInnerTo(nsGenericElement* aDest) const +{ + nsresult rv = nsGenericHTMLElement::CopyInnerTo(aDest); + NS_ENSURE_SUCCESS(rv, rv); + + if (aDest->GetOwnerDoc()->IsStaticDocument()) { + PRBool selected = PR_FALSE; + const_cast(this)->GetSelected(&selected); + static_cast(aDest)->SetSelected(selected); + } + return NS_OK; +} + diff --git a/content/html/content/src/nsHTMLScriptElement.cpp b/content/html/content/src/nsHTMLScriptElement.cpp index d4d381ce6f16..4436c5e7ce08 100644 --- a/content/html/content/src/nsHTMLScriptElement.cpp +++ b/content/html/content/src/nsHTMLScriptElement.cpp @@ -329,11 +329,9 @@ public: // nsIScriptElement virtual void GetScriptType(nsAString& type); - virtual already_AddRefed GetScriptURI(); virtual void GetScriptText(nsAString& text); virtual void GetScriptCharset(nsAString& charset); - virtual PRBool GetScriptDeferred(); - virtual PRBool GetScriptAsync(); + virtual void FreezeUriAsyncDefer(); // nsIContent virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent, @@ -477,7 +475,14 @@ nsresult nsHTMLScriptElement::DoneAddingChildren(PRBool aHaveNotified) { mDoneAddingChildren = PR_TRUE; - return MaybeProcessScript(); + nsresult rv = MaybeProcessScript(); + if (!mIsEvaluated) { + // Need to thaw the script uri here to allow another script to cause + // execution later. + mFrozen = PR_FALSE; + mUri = nsnull; + } + return rv; } PRBool @@ -495,20 +500,6 @@ nsHTMLScriptElement::GetScriptType(nsAString& type) GetType(type); } -// variation of this code in nsSVGScriptElement - check if changes -// need to be transfered when modifying - -already_AddRefed -nsHTMLScriptElement::GetScriptURI() -{ - nsIURI *uri = nsnull; - nsAutoString src; - GetSrc(src); - if (!src.IsEmpty()) - NS_NewURI(&uri, src); - return uri; -} - void nsHTMLScriptElement::GetScriptText(nsAString& text) { @@ -521,31 +512,35 @@ nsHTMLScriptElement::GetScriptCharset(nsAString& charset) GetCharset(charset); } -PRBool -nsHTMLScriptElement::GetScriptDeferred() +void +nsHTMLScriptElement::FreezeUriAsyncDefer() { - PRBool defer, async; - GetAsync(&async); - GetDefer(&defer); - nsCOMPtr uri = GetScriptURI(); + if (mFrozen) { + return; + } + + // variation of this code in nsSVGScriptElement - check if changes + // need to be transfered when modifying + if (HasAttr(kNameSpaceID_None, nsGkAtoms::src)) { + nsAutoString src; + GetSrc(src); + NS_NewURI(getter_AddRefs(mUri), src); - return !async && defer && uri; -} + PRBool defer, async; + GetAsync(&async); + GetDefer(&defer); -PRBool -nsHTMLScriptElement::GetScriptAsync() -{ - PRBool async; - GetAsync(&async); - nsCOMPtr uri = GetScriptURI(); - - return async && uri; + mDefer = !async && defer; + mAsync = async; + } + + mFrozen = PR_TRUE; } PRBool nsHTMLScriptElement::HasScriptContent() { - return HasAttr(kNameSpaceID_None, nsGkAtoms::src) || + return (mFrozen ? !!mUri : HasAttr(kNameSpaceID_None, nsGkAtoms::src)) || nsContentUtils::HasNonEmptyTextContent(this); } diff --git a/content/html/content/src/nsHTMLSharedObjectElement.cpp b/content/html/content/src/nsHTMLSharedObjectElement.cpp index 3ecc832df15c..686af5d9085e 100644 --- a/content/html/content/src/nsHTMLSharedObjectElement.cpp +++ b/content/html/content/src/nsHTMLSharedObjectElement.cpp @@ -130,6 +130,8 @@ public: virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const; + nsresult CopyInnerTo(nsGenericElement* aDest) const; + void StartObjectLoad() { StartObjectLoad(PR_TRUE); } NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(nsHTMLSharedObjectElement, @@ -460,3 +462,16 @@ nsHTMLSharedObjectElement::DestroyContent() RemovedFromDocument(); nsGenericHTMLElement::DestroyContent(); } + +nsresult +nsHTMLSharedObjectElement::CopyInnerTo(nsGenericElement* aDest) const +{ + nsresult rv = nsGenericHTMLElement::CopyInnerTo(aDest); + NS_ENSURE_SUCCESS(rv, rv); + + if (aDest->GetOwnerDoc()->IsStaticDocument()) { + CreateStaticClone(static_cast(aDest)); + } + + return rv; +} diff --git a/content/html/content/src/nsHTMLTextAreaElement.cpp b/content/html/content/src/nsHTMLTextAreaElement.cpp index 1b52d4e86872..7b5a4e9b9c15 100644 --- a/content/html/content/src/nsHTMLTextAreaElement.cpp +++ b/content/html/content/src/nsHTMLTextAreaElement.cpp @@ -150,6 +150,8 @@ public: virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const; + nsresult CopyInnerTo(nsGenericElement* aDest) const; + /** * Called when an attribute is about to be changed */ @@ -975,3 +977,18 @@ nsHTMLTextAreaElement::AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName, return nsGenericHTMLFormElement::AfterSetAttr(aNameSpaceID, aName, aValue, aNotify); } + +nsresult +nsHTMLTextAreaElement::CopyInnerTo(nsGenericElement* aDest) const +{ + nsresult rv = nsGenericHTMLFormElement::CopyInnerTo(aDest); + NS_ENSURE_SUCCESS(rv, rv); + + if (aDest->GetOwnerDoc()->IsStaticDocument()) { + nsAutoString value; + const_cast(this)->GetValue(value); + static_cast(aDest)->SetValue(value); + } + return NS_OK; +} + diff --git a/content/html/document/src/nsHTMLDocument.cpp b/content/html/document/src/nsHTMLDocument.cpp index adad4e302515..0e0b0a7b609c 100644 --- a/content/html/document/src/nsHTMLDocument.cpp +++ b/content/html/document/src/nsHTMLDocument.cpp @@ -2635,11 +2635,6 @@ nsHTMLDocument::ResolveName(const nsAString& aName, { *aResult = nsnull; - if (!mIsRegularHTML) { - // We don't dynamically resolve names on non-HTML documents. - return NS_OK; - } - nsCOMPtr name(do_GetAtom(aName)); // We have built a table and cache the named items. The table will diff --git a/content/html/document/test/Makefile.in b/content/html/document/test/Makefile.in index 5d56ef8d8561..aa0932e250ff 100644 --- a/content/html/document/test/Makefile.in +++ b/content/html/document/test/Makefile.in @@ -97,6 +97,7 @@ _TEST_FILES = test_bug1682.html \ test_bug486741.html \ test_bug497242.xhtml \ test_bug512367.html \ + test_bug340017.xhtml \ $(NULL) libs:: $(_TEST_FILES) diff --git a/content/html/document/test/test_bug340017.xhtml b/content/html/document/test/test_bug340017.xhtml new file mode 100644 index 000000000000..1768640d3c7d --- /dev/null +++ b/content/html/document/test/test_bug340017.xhtml @@ -0,0 +1,28 @@ + + + + Test for Bug 340017 + + + + + +Mozilla Bug 340017 +

+ +
+
+
+ + diff --git a/content/smil/crashtests/529387-1-helper.svg b/content/smil/crashtests/529387-1-helper.svg new file mode 100644 index 000000000000..7885ab71fd4a --- /dev/null +++ b/content/smil/crashtests/529387-1-helper.svg @@ -0,0 +1,5 @@ + + abc + + + diff --git a/content/smil/crashtests/529387-1.xhtml b/content/smil/crashtests/529387-1.xhtml new file mode 100644 index 000000000000..de3dbec34cff --- /dev/null +++ b/content/smil/crashtests/529387-1.xhtml @@ -0,0 +1,7 @@ + + + diff --git a/content/smil/crashtests/crashtests.list b/content/smil/crashtests/crashtests.list index 4ca09fa7ac0d..2533a13b5aa1 100644 --- a/content/smil/crashtests/crashtests.list +++ b/content/smil/crashtests/crashtests.list @@ -2,3 +2,4 @@ load 523188-1.svg load 525099-1.svg load 526875-1.svg load 526875-2.svg +load 529387-1.xhtml diff --git a/content/smil/nsISMILCSSValueType.h b/content/smil/nsISMILCSSValueType.h deleted file mode 100644 index 8b6b2b24d352..000000000000 --- a/content/smil/nsISMILCSSValueType.h +++ /dev/null @@ -1,118 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is the Mozilla SMIL module. - * - * The Initial Developer of the Original Code is the Mozilla Corporation. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Daniel Holbert - * - * 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 ***** */ - -/* interface for accessing CSS values stored in nsSMILValue objects */ - -#ifndef NS_ISMILCSSVALUETYPE_H_ -#define NS_ISMILCSSVALUETYPE_H_ - -#include "nsISMILType.h" -#include "nsCSSProperty.h" -#include "nscore.h" // For NS_OVERRIDE - -class nsPresContext; -class nsIContent; -class nsAString; - -////////////////////////////////////////////////////////////////////////////// -// nsISMILCSSValueType: Customized version of the nsISMILType interface, with -// some additional methods for parsing & extracting CSS values, so that the -// details of the value-storage representation can be abstracted away. - -class nsISMILCSSValueType : public nsISMILType -{ -public: - // Methods inherited from nsISMILType - // ---------------------------------- - NS_OVERRIDE virtual nsresult Init(nsSMILValue& aValue) const = 0; - NS_OVERRIDE virtual void Destroy(nsSMILValue& aValue) const = 0; - NS_OVERRIDE virtual nsresult Assign(nsSMILValue& aDest, - const nsSMILValue& aSrc) const = 0; - NS_OVERRIDE virtual nsresult Add(nsSMILValue& aDest, - const nsSMILValue& aValueToAdd, - PRUint32 aCount) const = 0; - NS_OVERRIDE virtual nsresult ComputeDistance(const nsSMILValue& aFrom, - const nsSMILValue& aTo, - double& aDistance) const = 0; - NS_OVERRIDE virtual nsresult Interpolate(const nsSMILValue& aStartVal, - const nsSMILValue& aEndVal, - double aUnitDistance, - nsSMILValue& aResult) const = 0; - - /* - * Virtual destructor: nothing to do here, but subclasses - * may need it. - */ - virtual ~nsISMILCSSValueType() {}; - - // Methods introduced in this interface - // ------------------------------------ - // These are helper methods used by nsSMILCSSProperty - these let us keep - // our data representation private. - - /** - * Sets up the given nsSMILValue to represent the given string value. The - * string is interpreted as a value for the given property on the given - * element. - * - * Note: aValue is expected to be freshly initialized (i.e. it should have - * been passed into the "Init()" method of some nsISMILCSSValueType subclass) - * - * @param aPropID The property for which we're parsing a value. - * @param aTargetElement The target element to whom the property/value - * setting applies. - * @param aString The string to be parsed as a CSS value. - * @param [out] aValue The nsSMILValue to be populated. - * @return PR_TRUE on success, PR_FALSE on failure. - */ - virtual PRBool ValueFromString(nsCSSProperty aPropID, - nsIContent* aTargetElement, - const nsAString& aString, - nsSMILValue& aValue) const = 0; - - /** - * Creates a string representation of the given nsSMILValue. - * - * @param aValue The nsSMILValue to be converted into a string. - * @param [out] aString The string to be populated with the given value. - * @return PR_TRUE on success, PR_FALSE on failure. - */ - virtual PRBool ValueToString(const nsSMILValue& aValue, - nsAString& aString) const = 0; -}; - -#endif // NS_ISMILCSSVALUETYPE_H_ diff --git a/content/smil/nsSMILAnimationFunction.h b/content/smil/nsSMILAnimationFunction.h index 80ec0f6abd7e..877b002b9bbf 100644 --- a/content/smil/nsSMILAnimationFunction.h +++ b/content/smil/nsSMILAnimationFunction.h @@ -85,7 +85,7 @@ public: * parsed result. * @param aParseResult Outparam used for reporting parse errors. Will be set * to NS_OK if everything succeeds. - * @returns PR_TRUE if aAttribute is a recognized animation-related + * @return PR_TRUE if aAttribute is a recognized animation-related * attribute; PR_FALSE otherwise. */ virtual PRBool SetAttr(nsIAtom* aAttribute, const nsAString& aValue, @@ -139,8 +139,8 @@ public: * the animation function that it should no longer add its result to the * animation sandwich. * - * @param aIsFrozen True if this animation should continue to contribute to - * the animation sandwich using the most recent sample + * @param aIsFrozen PR_TRUE if this animation should continue to contribute + * to the animation sandwich using the most recent sample * parameters. */ void Inactivate(PRBool aIsFrozen); @@ -179,7 +179,7 @@ public: * Indicates if the animation is currently active or frozen. Inactive * animations will not contribute to the composed result. * - * @return True if the animation is active or frozen, false otherwise. + * @return PR_TRUE if the animation is active or frozen, PR_FALSE otherwise. */ PRBool IsActiveOrFrozen() const { @@ -210,7 +210,8 @@ public: * Note that the caller is responsible for determining if the animation target * has changed. * - * @return True if the animation parameters have changed, false otherwise. + * @return PR_TRUE if the animation parameters have changed, PR_FALSE + * otherwise. */ PRBool HasChanged() const; diff --git a/content/smil/nsSMILCSSProperty.cpp b/content/smil/nsSMILCSSProperty.cpp index aa4b00c853ac..195394a8b50f 100644 --- a/content/smil/nsSMILCSSProperty.cpp +++ b/content/smil/nsSMILCSSProperty.cpp @@ -38,7 +38,6 @@ /* representation of a SMIL-animatable CSS property on an element */ #include "nsSMILCSSProperty.h" -#include "nsISMILCSSValueType.h" #include "nsSMILCSSValueType.h" #include "nsSMILValue.h" #include "nsCSSDeclaration.h" @@ -47,20 +46,6 @@ #include "nsIContent.h" #include "nsPIDOMWindow.h" -// Helper Functions -static nsISMILCSSValueType* -GetSMILTypeForProperty(nsCSSProperty aPropID) -{ - if (!nsSMILCSSProperty::IsPropertyAnimatable(aPropID)) { - NS_NOTREACHED("Attempting to animate an un-animatable property"); - return nsnull; - } - if (aPropID < eCSSProperty_COUNT_no_shorthands) { - return &nsSMILCSSValueType::sSingleton; - } - return nsnull; // XXXdholbert Return shorthand type here, when we add it -} - static PRBool GetCSSComputedValue(nsIContent* aElem, nsCSSProperty aPropID, @@ -125,13 +110,12 @@ nsSMILCSSProperty::GetBaseValue() const nsSMILValue baseValue; if (didGetComputedVal) { // (4) Create the nsSMILValue from the computed style value - nsISMILCSSValueType* smilType = GetSMILTypeForProperty(mPropID); - NS_ABORT_IF_FALSE(smilType, "animating an unsupported type"); - - smilType->Init(baseValue); - if (!smilType->ValueFromString(mPropID, mElement, - computedStyleVal, baseValue)) { - smilType->Destroy(baseValue); + nsSMILCSSValueType::sSingleton.Init(baseValue); + if (!nsCSSProps::IsShorthand(mPropID) && + !nsSMILCSSValueType::sSingleton.ValueFromString(mPropID, mElement, + computedStyleVal, + baseValue)) { + nsSMILCSSValueType::sSingleton.Destroy(baseValue); NS_ABORT_IF_FALSE(baseValue.IsNull(), "Destroy should leave us with null-typed value"); } @@ -145,11 +129,12 @@ nsSMILCSSProperty::ValueFromString(const nsAString& aStr, nsSMILValue& aValue) const { NS_ENSURE_TRUE(IsPropertyAnimatable(mPropID), NS_ERROR_FAILURE); - nsISMILCSSValueType* smilType = GetSMILTypeForProperty(mPropID); - smilType->Init(aValue); - PRBool success = smilType->ValueFromString(mPropID, mElement, aStr, aValue); + nsSMILCSSValueType::sSingleton.Init(aValue); + PRBool success = + nsSMILCSSValueType::sSingleton.ValueFromString(mPropID, mElement, + aStr, aValue); if (!success) { - smilType->Destroy(aValue); + nsSMILCSSValueType::sSingleton.Destroy(aValue); } return success ? NS_OK : NS_ERROR_FAILURE; } @@ -161,9 +146,8 @@ nsSMILCSSProperty::SetAnimValue(const nsSMILValue& aValue) nsresult rv = NS_OK; nsAutoString valStr; - nsISMILCSSValueType* smilType = GetSMILTypeForProperty(mPropID); - if (smilType->ValueToString(aValue, valStr)) { + if (nsSMILCSSValueType::sSingleton.ValueToString(aValue, valStr)) { // Apply the style to the target element nsCOMPtr overrideStyle; mElement->GetSMILOverrideStyle(getter_AddRefs(overrideStyle)); @@ -215,43 +199,28 @@ nsSMILCSSProperty::IsPropertyAnimatable(nsCSSProperty aPropID) case eCSSProperty_font: case eCSSProperty_marker: case eCSSProperty_overflow: - // XXXdholbert Shorthand types not yet supported - return PR_FALSE; + return PR_TRUE; // PROPERTIES OF TYPE eCSSType_Rect case eCSSProperty_clip: // XXXdholbert Rect type not yet supported by nsStyleAnimation return PR_FALSE; - // PROPERTIES OF TYPE eCSSType_ValueList - case eCSSProperty_cursor: - case eCSSProperty_stroke_dasharray: - // XXXdholbert List type not yet supported by nsStyleAnimation - return PR_FALSE; - - // PROPERTIES OF TYPE eCSSType_ValuePair - case eCSSProperty_fill: - case eCSSProperty_stroke: - return PR_TRUE; - - // PROPERTIES OF TYPE eCSSType_Value - // XXXdholbert: Some properties' types aren't yet supported by - // nsStyleAnimation (due to using URI values or string values). I'm - // commenting those properties out here for the time being, so that we - // don't try to animate them yet. case eCSSProperty_clip_rule: - // case eCSSProperty_clip_path: + case eCSSProperty_clip_path: case eCSSProperty_color: case eCSSProperty_color_interpolation: case eCSSProperty_color_interpolation_filters: + case eCSSProperty_cursor: case eCSSProperty_display: case eCSSProperty_dominant_baseline: + case eCSSProperty_fill: case eCSSProperty_fill_opacity: case eCSSProperty_fill_rule: - // case eCSSProperty_filter: + case eCSSProperty_filter: case eCSSProperty_flood_color: case eCSSProperty_flood_opacity: - // case eCSSProperty_font_family: + case eCSSProperty_font_family: case eCSSProperty_font_size: case eCSSProperty_font_size_adjust: case eCSSProperty_font_stretch: @@ -261,15 +230,17 @@ nsSMILCSSProperty::IsPropertyAnimatable(nsCSSProperty aPropID) case eCSSProperty_image_rendering: case eCSSProperty_letter_spacing: case eCSSProperty_lighting_color: - // case eCSSProperty_marker_end: - // case eCSSProperty_marker_mid: - // case eCSSProperty_marker_start: - // case eCSSProperty_mask: + case eCSSProperty_marker_end: + case eCSSProperty_marker_mid: + case eCSSProperty_marker_start: + case eCSSProperty_mask: case eCSSProperty_opacity: case eCSSProperty_pointer_events: case eCSSProperty_shape_rendering: case eCSSProperty_stop_color: case eCSSProperty_stop_opacity: + case eCSSProperty_stroke: + case eCSSProperty_stroke_dasharray: case eCSSProperty_stroke_dashoffset: case eCSSProperty_stroke_linecap: case eCSSProperty_stroke_linejoin: diff --git a/content/smil/nsSMILCSSValueType.cpp b/content/smil/nsSMILCSSValueType.cpp index b92dd907091e..8962371e38e9 100644 --- a/content/smil/nsSMILCSSValueType.cpp +++ b/content/smil/nsSMILCSSValueType.cpp @@ -52,11 +52,12 @@ /*static*/ nsSMILCSSValueType nsSMILCSSValueType::sSingleton; struct ValueWrapper { - ValueWrapper() : mCSSValue(), mPropID(eCSSProperty_UNKNOWN), - mPresContext(nsnull) {} + ValueWrapper(nsCSSProperty aPropID, const nsStyleAnimation::Value& aValue, + nsPresContext* aPresContext) : + mPropID(aPropID), mCSSValue(aValue), mPresContext(aPresContext) {} + nsCSSProperty mPropID; nsStyleAnimation::Value mCSSValue; - nsCSSProperty mPropID; nsPresContext* mPresContext; }; @@ -128,14 +129,9 @@ ExtractValueWrapper(const nsSMILValue& aValue) nsresult nsSMILCSSValueType::Init(nsSMILValue& aValue) const { - NS_ABORT_IF_FALSE(aValue.IsNull(), - "Unexpected value type"); - - aValue.mU.mPtr = new ValueWrapper(); - if (!aValue.mU.mPtr) { - return NS_ERROR_OUT_OF_MEMORY; - } + NS_ABORT_IF_FALSE(aValue.IsNull(), "Unexpected SMIL value type"); + aValue.mU.mPtr = nsnull; aValue.mType = this; return NS_OK; } @@ -144,12 +140,8 @@ void nsSMILCSSValueType::Destroy(nsSMILValue& aValue) const { NS_ABORT_IF_FALSE(aValue.mType == this, "Unexpected SMIL value type"); - NS_ABORT_IF_FALSE(aValue.mU.mPtr, - "nsSMILValue for CSS val should have non-null pointer"); - delete static_cast(aValue.mU.mPtr); - aValue.mU.mPtr = nsnull; - aValue.mType = &nsSMILNullType::sSingleton; + aValue.mType = &nsSMILNullType::sSingleton; } nsresult @@ -157,13 +149,25 @@ nsSMILCSSValueType::Assign(nsSMILValue& aDest, const nsSMILValue& aSrc) const { NS_ABORT_IF_FALSE(aDest.mType == aSrc.mType, "Incompatible SMIL types"); NS_ABORT_IF_FALSE(aDest.mType == this, "Unexpected SMIL value type"); - NS_ABORT_IF_FALSE(aDest.mU.mPtr, - "nsSMILValue for CSS val should have non-null pointer"); - NS_ABORT_IF_FALSE(aSrc.mU.mPtr, - "nsSMILValue for CSS val should have non-null pointer"); const ValueWrapper* srcWrapper = ExtractValueWrapper(aSrc); ValueWrapper* destWrapper = ExtractValueWrapper(aDest); - *destWrapper = *srcWrapper; // Directly copy prop ID & CSS value + + if (srcWrapper) { + if (!destWrapper) { + // barely-initialized dest -- need to alloc & copy + aDest.mU.mPtr = new ValueWrapper(*srcWrapper); + if (!aDest.mU.mPtr) { + return NS_ERROR_OUT_OF_MEMORY; + } + } else { + // both already fully-initialized -- just copy straight across + *destWrapper = *srcWrapper; + } + } else if (destWrapper) { + // fully-initialized dest, barely-initialized src -- clear dest + delete destWrapper; + aDest.mU.mPtr = destWrapper = nsnull; + } // else, both are barely-initialized -- nothing to do. return NS_OK; } @@ -178,41 +182,44 @@ nsSMILCSSValueType::Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd, ValueWrapper* destWrapper = ExtractValueWrapper(aDest); const ValueWrapper* valueToAddWrapper = ExtractValueWrapper(aValueToAdd); + NS_ABORT_IF_FALSE(destWrapper || valueToAddWrapper, + "need at least one fully-initialized value"); - NS_ABORT_IF_FALSE(destWrapper && valueToAddWrapper, - "these pointers shouldn't be null"); + nsCSSProperty property = (valueToAddWrapper ? valueToAddWrapper->mPropID : + destWrapper->mPropID); + // Special case: font-size-adjust and stroke-dasharray are explicitly + // non-additive (even though nsStyleAnimation *could* support adding them) + if (property == eCSSProperty_font_size_adjust || + property == eCSSProperty_stroke_dasharray) { + return NS_ERROR_FAILURE; + } - const nsStyleAnimation::Value* realValueToAdd = &valueToAddWrapper->mCSSValue; - if (destWrapper->mPropID == eCSSProperty_UNKNOWN) { - NS_ABORT_IF_FALSE(destWrapper->mCSSValue.IsNull() && - !destWrapper->mPresContext, - "Partially-initialized ValueWrapper"); - // We need to update destWrapper, since it's part of an outparam. + // Handle barely-initialized "zero" added value. + const nsStyleAnimation::Value* realValueToAdd = valueToAddWrapper ? + &valueToAddWrapper->mCSSValue : + GetZeroValueForUnit(destWrapper->mCSSValue.GetUnit()); + if (!realValueToAdd) { + // No zero value for this unit --> doesn't support addition. + return NS_ERROR_FAILURE; + } + + // Handle barely-initialized "zero" destination. + if (!destWrapper) { + // Need to fully initialize destination, since it's an outparam const nsStyleAnimation::Value* zeroVal = GetZeroValueForUnit(valueToAddWrapper->mCSSValue.GetUnit()); if (!zeroVal) { // No zero value for this unit --> doesn't support addition. return NS_ERROR_FAILURE; } - destWrapper->mCSSValue = *zeroVal; - destWrapper->mPropID = valueToAddWrapper->mPropID; - destWrapper->mPresContext = valueToAddWrapper->mPresContext; - } else if (valueToAddWrapper->mPropID == eCSSProperty_UNKNOWN) { - NS_ABORT_IF_FALSE(valueToAddWrapper->mCSSValue.IsNull() && - !valueToAddWrapper->mPresContext, - "Partially-initialized ValueWrapper"); - realValueToAdd = GetZeroValueForUnit(destWrapper->mCSSValue.GetUnit()); - if (!realValueToAdd) { - // No zero value for this unit --> doesn't support addition. - return NS_ERROR_FAILURE; - } + aDest.mU.mPtr = destWrapper = + new ValueWrapper(property, *zeroVal, valueToAddWrapper->mPresContext); + if (!destWrapper) { + return NS_ERROR_OUT_OF_MEMORY; + } } - // Special case: font-size-adjust is explicitly non-additive - if (destWrapper->mPropID == eCSSProperty_font_size_adjust) { - return NS_ERROR_FAILURE; - } - return nsStyleAnimation::Add(destWrapper->mPropID, destWrapper->mCSSValue, + return nsStyleAnimation::Add(property, destWrapper->mCSSValue, *realValueToAdd, aCount) ? NS_OK : NS_ERROR_FAILURE; } @@ -228,29 +235,18 @@ nsSMILCSSValueType::ComputeDistance(const nsSMILValue& aFrom, const ValueWrapper* fromWrapper = ExtractValueWrapper(aFrom); const ValueWrapper* toWrapper = ExtractValueWrapper(aTo); - NS_ABORT_IF_FALSE(fromWrapper && toWrapper, - "These pointers shouldn't be null"); + NS_ABORT_IF_FALSE(toWrapper, "expecting non-null endpoint"); - const nsStyleAnimation::Value* fromCSSValue; - if (fromWrapper->mPropID == eCSSProperty_UNKNOWN) { - NS_ABORT_IF_FALSE(fromWrapper->mCSSValue.IsNull() && - !fromWrapper->mPresContext, - "Partially-initialized ValueWrapper"); - fromCSSValue = GetZeroValueForUnit(toWrapper->mCSSValue.GetUnit()); - if (!fromCSSValue) { - // No zero value for this unit --> doesn't support distance-computation. - return NS_ERROR_FAILURE; - } - } else { - fromCSSValue = &fromWrapper->mCSSValue; + const nsStyleAnimation::Value* fromCSSValue = fromWrapper ? + &fromWrapper->mCSSValue : + GetZeroValueForUnit(toWrapper->mCSSValue.GetUnit()); + if (!fromCSSValue) { + // No zero value for this unit --> doesn't support distance-computation. + return NS_ERROR_FAILURE; } - NS_ABORT_IF_FALSE(toWrapper->mPropID != eCSSProperty_UNKNOWN && - !toWrapper->mCSSValue.IsNull() && toWrapper->mPresContext, - "ComputeDistance endpoint should be a parsed value"); - return nsStyleAnimation::ComputeDistance(toWrapper->mPropID, - *fromCSSValue, toWrapper->mCSSValue, - aDistance) ? + return nsStyleAnimation::ComputeDistance(toWrapper->mPropID, *fromCSSValue, + toWrapper->mCSSValue, aDistance) ? NS_OK : NS_ERROR_FAILURE; } @@ -270,40 +266,39 @@ nsSMILCSSValueType::Interpolate(const nsSMILValue& aStartVal, const ValueWrapper* startWrapper = ExtractValueWrapper(aStartVal); const ValueWrapper* endWrapper = ExtractValueWrapper(aEndVal); - ValueWrapper* resultWrapper = ExtractValueWrapper(aResult); + NS_ABORT_IF_FALSE(endWrapper, "expecting non-null endpoint"); + NS_ABORT_IF_FALSE(!aResult.mU.mPtr, "expecting barely-initialized outparam"); - NS_ABORT_IF_FALSE(startWrapper && endWrapper && resultWrapper, - "These pointers shouldn't be null"); - - const nsStyleAnimation::Value* startCSSValue; - if (startWrapper->mPropID == eCSSProperty_UNKNOWN) { - NS_ABORT_IF_FALSE(startWrapper->mCSSValue.IsNull() && - !startWrapper->mPresContext, - "Partially-initialized ValueWrapper"); - startCSSValue = GetZeroValueForUnit(endWrapper->mCSSValue.GetUnit()); - if (!startCSSValue) { - // No zero value for this unit --> doesn't support interpolation. - return NS_ERROR_FAILURE; - } - } else { - startCSSValue = &startWrapper->mCSSValue; + const nsStyleAnimation::Value* startCSSValue = startWrapper ? + &startWrapper->mCSSValue : + GetZeroValueForUnit(endWrapper->mCSSValue.GetUnit()); + if (!startCSSValue) { + // No zero value for this unit --> doesn't support interpolation. + return NS_ERROR_FAILURE; } - NS_ABORT_IF_FALSE(endWrapper->mPropID != eCSSProperty_UNKNOWN && - !endWrapper->mCSSValue.IsNull() && endWrapper->mPresContext, - "Interpolate endpoint should be a parsed value"); - - if (nsStyleAnimation::Interpolate(endWrapper->mPropID, - *startCSSValue, - endWrapper->mCSSValue, - aUnitDistance, - resultWrapper->mCSSValue)) { - resultWrapper->mPropID = endWrapper->mPropID; - resultWrapper->mPresContext = endWrapper->mPresContext; - return NS_OK; + + nsStyleAnimation::Value resultValue; + if (nsStyleAnimation::Interpolate(endWrapper->mPropID, *startCSSValue, + endWrapper->mCSSValue, aUnitDistance, + resultValue)) { + aResult.mU.mPtr = new ValueWrapper(endWrapper->mPropID, resultValue, + endWrapper->mPresContext); + return aResult.mU.mPtr ? NS_OK : NS_ERROR_OUT_OF_MEMORY; } return NS_ERROR_FAILURE; } +// Helper function to extract presContext +static nsPresContext* +GetPresContextForElement(nsIContent* aElem) +{ + nsIDocument* doc = aElem->GetCurrentDoc(); + NS_ABORT_IF_FALSE(doc, "active animations should only be able to " + "target elements that are in a document"); + nsIPresShell* shell = doc->GetPrimaryShell(); + return shell ? shell->GetPresContext() : nsnull; +} + PRBool nsSMILCSSValueType::ValueFromString(nsCSSProperty aPropID, nsIContent* aTargetElement, @@ -312,9 +307,13 @@ nsSMILCSSValueType::ValueFromString(nsCSSProperty aPropID, { NS_ABORT_IF_FALSE(aValue.mType == &nsSMILCSSValueType::sSingleton, "Passed-in value is wrong type"); - NS_ABORT_IF_FALSE(aPropID < eCSSProperty_COUNT_no_shorthands, - "nsSMILCSSValueType shouldn't be used with " - "shorthand properties"); + NS_ABORT_IF_FALSE(!aValue.mU.mPtr, "expecting barely-initialized outparam"); + + nsPresContext* presContext = GetPresContextForElement(aTargetElement); + if (!presContext) { + NS_WARNING("Not parsing animation value; unable to get PresContext"); + return PR_FALSE; + } // If value is negative, we'll strip off the "-" so the CSS parser won't // barf, and then manually make the parsed value negative. (This is a partial @@ -328,40 +327,21 @@ nsSMILCSSValueType::ValueFromString(nsCSSProperty aPropID, isNegative = PR_TRUE; } nsDependentSubstring subString(aString, subStringBegin); - ValueWrapper* wrapper = ExtractValueWrapper(aValue); - NS_ABORT_IF_FALSE(wrapper, "Wrapper should be non-null if type is set."); - + nsStyleAnimation::Value parsedValue; if (nsStyleAnimation::ComputeValue(aPropID, aTargetElement, - subString, wrapper->mCSSValue)) { - wrapper->mPropID = aPropID; + subString, parsedValue)) { if (isNegative) { - InvertSign(wrapper->mCSSValue); + InvertSign(parsedValue); } - // Cache a reference to the PresContext, if we've got one - nsIDocument* doc = aTargetElement->GetCurrentDoc(); - NS_ABORT_IF_FALSE(doc, "active animations should only be able to " - "target elements that are in a document"); - nsIPresShell* shell = doc->GetPrimaryShell(); - if (shell) { - wrapper->mPresContext = shell->GetPresContext(); - } - if (wrapper->mPresContext) { + if (aPropID == eCSSProperty_font_size) { // Divide out text-zoom, since SVG is supposed to ignore it - if (aPropID == eCSSProperty_font_size) { - NS_ABORT_IF_FALSE(wrapper->mCSSValue.GetUnit() == - nsStyleAnimation::eUnit_Coord, - "'font-size' value with unexpected style unit"); - wrapper->mCSSValue.SetCoordValue(wrapper->mCSSValue.GetCoordValue() / - wrapper->mPresContext->TextZoom()); - } - return PR_TRUE; + NS_ABORT_IF_FALSE(parsedValue.GetUnit() == nsStyleAnimation::eUnit_Coord, + "'font-size' value with unexpected style unit"); + parsedValue.SetCoordValue(parsedValue.GetCoordValue() / + presContext->TextZoom()); } - // Crap! We lack a PresContext or a PresShell - NS_NOTREACHED("Not parsing animation value; unable to get PresContext"); - // Destroy & re-initialize aValue to make sure we leave it in a - // consistent state - Destroy(aValue); - Init(aValue); + aValue.mU.mPtr = new ValueWrapper(aPropID, parsedValue, presContext); + return aValue.mU.mPtr != nsnull; } return PR_FALSE; } @@ -372,9 +352,8 @@ nsSMILCSSValueType::ValueToString(const nsSMILValue& aValue, { NS_ABORT_IF_FALSE(aValue.mType == &nsSMILCSSValueType::sSingleton, "Passed-in value is wrong type"); - const ValueWrapper* wrapper = ExtractValueWrapper(aValue); - return nsStyleAnimation::UncomputeValue(wrapper->mPropID, - wrapper->mPresContext, - wrapper->mCSSValue, aString); + return !wrapper || + nsStyleAnimation::UncomputeValue(wrapper->mPropID, wrapper->mPresContext, + wrapper->mCSSValue, aString); } diff --git a/content/smil/nsSMILCSSValueType.h b/content/smil/nsSMILCSSValueType.h index 9a79b27bfc5e..e97d226ed73d 100644 --- a/content/smil/nsSMILCSSValueType.h +++ b/content/smil/nsSMILCSSValueType.h @@ -40,16 +40,18 @@ #ifndef NS_SMILCSSVALUETYPE_H_ #define NS_SMILCSSVALUETYPE_H_ -#include "nsISMILCSSValueType.h" +#include "nsISMILType.h" +#include "nsCSSProperty.h" #include "nscore.h" // For NS_OVERRIDE +class nsPresContext; class nsIContent; +class nsAString; /* - * nsSMILCSSValueType: Represents a SMIL-animated simple (non-shorthand) CSS - * value. + * nsSMILCSSValueType: Represents a SMIL-animated CSS value. */ -class nsSMILCSSValueType : public nsISMILCSSValueType +class nsSMILCSSValueType : public nsISMILType { public: // nsISMILValueType Methods @@ -69,15 +71,38 @@ public: double aUnitDistance, nsSMILValue& aResult) const; - // nsISMILCSSValueType Methods - // --------------------------- - NS_OVERRIDE virtual PRBool ValueFromString(nsCSSProperty aPropID, - nsIContent* aTargetElement, - const nsAString& aString, - nsSMILValue& aValue) const; + /** + * Sets up the given nsSMILValue to represent the given string value. The + * string is interpreted as a value for the given property on the given + * element. + * + * Note: aValue is expected to be freshly initialized (i.e. it should already + * have been passed into nsSMILCSSValueType::Init(), and it should not have + * been set up further via e.g. Assign() or another ValueFromString() call.) + * + * @param aPropID The property for which we're parsing a value. + * @param aTargetElement The target element to whom the property/value + * setting applies. + * @param aString The string to be parsed as a CSS value. + * @param [out] aValue The nsSMILValue to be populated. + * @return PR_TRUE on success, PR_FALSE on failure. + */ + PRBool ValueFromString(nsCSSProperty aPropID, nsIContent* aTargetElement, + const nsAString& aString, nsSMILValue& aValue) const; - NS_OVERRIDE virtual PRBool ValueToString(const nsSMILValue& aValue, - nsAString& aString) const; + /** + * Creates a string representation of the given nsSMILValue. + * + * Note: aValue is expected to be of this type (that is, it's expected to + * have been initialized by nsSMILCSSValueType::sSingleton). If aValue is a + * freshly-initialized value, this method will succeed, though the resulting + * string will be empty. + * + * @param aValue The nsSMILValue to be converted into a string. + * @param [out] aString The string to be populated with the given value. + * @return PR_TRUE on success, PR_FALSE on failure. + */ + PRBool ValueToString(const nsSMILValue& aValue, nsAString& aString) const; // Singleton for nsSMILValue objects to hold onto. static nsSMILCSSValueType sSingleton; diff --git a/content/smil/test/Makefile.in b/content/smil/test/Makefile.in index 8ff8c40e0e04..fbbca01663d3 100644 --- a/content/smil/test/Makefile.in +++ b/content/smil/test/Makefile.in @@ -50,10 +50,12 @@ _TEST_FILES = \ db_smilCSSPaced.js \ db_smilCSSPropertyList.js \ smilTestUtils.js \ + smilXHR_helper.svg \ test_smilCSSFontStretchRelative.xhtml \ test_smilCSSFromBy.xhtml \ test_smilCSSFromTo.xhtml \ test_smilCSSInherit.xhtml \ + test_smilCSSInvalidValues.xhtml \ test_smilCSSPaced.xhtml \ test_smilRestart.xhtml \ test_smilGetStartTime.xhtml \ @@ -65,6 +67,7 @@ _TEST_FILES = \ test_smilTextZoom.xhtml \ test_smilTiming.xhtml \ test_smilTimingZeroIntervals.xhtml \ + test_smilXHR.xhtml \ $(NULL) libs:: $(_TEST_FILES) diff --git a/content/smil/test/db_smilCSSFromBy.js b/content/smil/test/db_smilCSSFromBy.js index 9fb68bf12089..c5b86e7a075f 100644 --- a/content/smil/test/db_smilCSSFromBy.js +++ b/content/smil/test/db_smilCSSFromBy.js @@ -74,14 +74,31 @@ var _fromByTestLists = new AnimTestcaseFromBy("url(#gradA)", "url(#gradB) red", { noEffect: 1 }), new AnimTestcaseFromBy("url(#gradA)", "none", { noEffect: 1 }), new AnimTestcaseFromBy("red", "url(#gradA)", { noEffect: 1 }), - ] + ], + URIsAndNone: [ + // No need to specify { noEffect: 1 }, since plain URI-valued properties + // aren't additive + new AnimTestcaseFromBy("url(#idA)", "url(#idB)"), + new AnimTestcaseFromBy("none", "url(#idB)"), + new AnimTestcaseFromBy("url(#idB)", "inherit"), + ], }; // List of attribute/testcase-list bundles to be tested var gFromByBundles = [ + // Check that 'by' animations for 'cursor' has no effect + new TestcaseBundle(gPropList.cursor, [ + new AnimTestcaseFromBy("crosshair", "move"), + ]), new TestcaseBundle(gPropList.fill, [].concat(_fromByTestLists.color, _fromByTestLists.paint)), + // Check that 'by' animations involving URIs have no effect + new TestcaseBundle(gPropList.filter, _fromByTestLists.URIsAndNone), + new TestcaseBundle(gPropList.font, [ + new AnimTestcaseFromBy("10px serif", + "normal normal 400 100px / 10px monospace"), + ]), new TestcaseBundle(gPropList.font_size, _fromByTestLists.lengthPx), new TestcaseBundle(gPropList.font_size_adjust, [ // These testcases implicitly have no effect, because font-size-adjust is @@ -91,10 +108,25 @@ var gFromByBundles = new AnimTestcaseFromBy("0.1", "none") ]), new TestcaseBundle(gPropList.lighting_color, _fromByTestLists.color), + new TestcaseBundle(gPropList.marker, _fromByTestLists.URIsAndNone), + new TestcaseBundle(gPropList.marker_end, _fromByTestLists.URIsAndNone), + new TestcaseBundle(gPropList.marker_mid, _fromByTestLists.URIsAndNone), + new TestcaseBundle(gPropList.marker_start, _fromByTestLists.URIsAndNone), + new TestcaseBundle(gPropList.overflow, [ + new AnimTestcaseFromBy("inherit", "auto"), + new AnimTestcaseFromBy("scroll", "hidden") + ]), new TestcaseBundle(gPropList.opacity, _fromByTestLists.opacity), new TestcaseBundle(gPropList.stroke_miterlimit, [ new AnimTestcaseFromBy("1", "1", { midComp: "1.5", toComp: "2" }), new AnimTestcaseFromBy("20.1", "-10", { midComp: "15.1", toComp: "10.1" }), ]), + new TestcaseBundle(gPropList.stroke_dasharray, [ + // These testcases implicitly have no effect, because stroke-dasharray is + // non-additive (and is declared as such in db_smilCSSPropertyList.js) + new AnimTestcaseFromBy("none", "5"), + new AnimTestcaseFromBy("10", "5"), + new AnimTestcaseFromBy("1", "2, 3"), + ]), new TestcaseBundle(gPropList.stroke_width, _fromByTestLists.lengthPx), ]; diff --git a/content/smil/test/db_smilCSSFromTo.js b/content/smil/test/db_smilCSSFromTo.js index 4cd7a6ca8e07..78b79138fb29 100644 --- a/content/smil/test/db_smilCSSFromTo.js +++ b/content/smil/test/db_smilCSSFromTo.js @@ -139,15 +139,12 @@ var _fromToTestLists = { URIsAndNone: [ new AnimTestcaseFromTo("url(#idA)", "url(#idB)", { fromComp: "url(\"" + document.URL + "#idA\")", - toComp: "url(\"" + document.URL + "#idB\")"}, - "need support for URI values"), + toComp: "url(\"" + document.URL + "#idB\")"}), new AnimTestcaseFromTo("none", "url(#idB)", - { toComp: "url(\"" + document.URL + "#idB\")"}, - "need support for URI values"), + { toComp: "url(\"" + document.URL + "#idB\")"}), new AnimTestcaseFromTo("url(#idB)", "inherit", { fromComp: "url(\"" + document.URL + "#idB\")", - toComp: "none"}, - "need support for URI values"), + toComp: "none"}), ], }; @@ -186,8 +183,8 @@ var gFromToBundles = [ new AnimTestcaseFromTo("url('a.cur'), url('b.cur'), nw-resize", "sw-resize", { fromComp: "url(\"" + _testPath + "/a.cur\"), " + "url(\"" + _testPath + "/b.cur\"), " + - "nw-resize"}) - ], "need support for CSS value-lists and URI values"), + "nw-resize"}), + ]), new TestcaseBundle(gPropList.direction, [ new AnimTestcaseFromTo("ltr", "rtl"), new AnimTestcaseFromTo("rtl", "inherit"), @@ -251,11 +248,11 @@ var gFromToBundles = [ toComp: "normal normal 400 100px / 10px monospace"}), new AnimTestcaseFromTo("oblique normal 200 30px / 10px cursive", "normal small-caps 800 40px / 10px serif"), - ], "need support for 'font' shorthand"), + ]), new TestcaseBundle(gPropList.font_family, [ new AnimTestcaseFromTo("serif", "sans-serif"), new AnimTestcaseFromTo("cursive", "monospace"), - ], "need support for all properties that get stored in nsFont"), + ]), new TestcaseBundle(gPropList.font_size, [].concat(_fromToTestLists.lengthPx, [ new AnimTestcaseFromTo("10px", "40%", { midComp: "15px", toComp: "20px" }), @@ -339,8 +336,9 @@ var gFromToBundles = [ new TestcaseBundle(gPropList.opacity, _fromToTestLists.opacity), new TestcaseBundle(gPropList.overflow, [ new AnimTestcaseFromTo("auto", "visible"), + new AnimTestcaseFromTo("inherit", "visible", { fromComp: "hidden" }), new AnimTestcaseFromTo("scroll", "auto"), - ], "need support for 'overflow' shorthand"), + ]), new TestcaseBundle(gPropList.pointer_events, [ new AnimTestcaseFromTo("visibleFill", "stroke", { fromComp: "visiblefill" }), @@ -365,14 +363,18 @@ var gFromToBundles = [ new AnimTestcaseFromTo("inherit", "rgb(200, 200, 200)", { fromComp: "none"})])), new TestcaseBundle(gPropList.stroke_dasharray, - [].concat(_fromToTestLists.lengthPx, - _fromToTestLists.lengthPxPctSVG, - _fromToTestLists.lengthPctSVG, + [].concat(_fromToTestLists.lengthPctSVG, [ - new AnimTestcaseFromTo("10px", "20px"), - new AnimTestcaseFromTo("1px, 5px", "1px"), - new AnimTestcaseFromTo("1px, 15px", "1px, 2px, 3px, 4px, 5px"), - ]), "need support for CSS value-lists"), + new AnimTestcaseFromTo("inherit", "20", { fromComp: "none"}), + new AnimTestcaseFromTo("1", "none"), + new AnimTestcaseFromTo("10", "20", { midComp: "15"}), + new AnimTestcaseFromTo("1", "2, 3", { fromComp: "1, 1", + midComp: "1.5, 2"}), + new AnimTestcaseFromTo("2, 8", "6", { midComp: "4, 7"}), + new AnimTestcaseFromTo("1, 3", "1, 3, 5, 7, 9", + { fromComp: "1, 3, 1, 3, 1, 3, 1, 3, 1, 3", + midComp: "1, 3, 3, 5, 5, 2, 2, 4, 4, 6"}), + ])), new TestcaseBundle(gPropList.stroke_dashoffset, [].concat(_fromToTestLists.lengthPx, _fromToTestLists.lengthPxPctSVG, diff --git a/content/smil/test/db_smilCSSPaced.js b/content/smil/test/db_smilCSSPaced.js index 4db515d64d8f..7747813c21ad 100644 --- a/content/smil/test/db_smilCSSPaced.js +++ b/content/smil/test/db_smilCSSPaced.js @@ -227,6 +227,16 @@ var gPacedBundles = "need support for more font properties"), ]), new TestcaseBundle(gPropList.opacity, _pacedTestLists.opacity), + new TestcaseBundle(gPropList.stroke_dasharray, + [].concat(_pacedTestLists.lengthPctSVG, [ + new AnimTestcasePaced("7, 7, 7; 7, 10, 3; 1, 2, 3", + { comp0: "7, 7, 7", + comp1_6: "7, 8.5, 5", + comp1_3: "7, 10, 3", + comp2_3: "4, 6, 3", + comp1: "1, 2, 3" + }), + ])), new TestcaseBundle(gPropList.stroke_dashoffset, [].concat(_pacedTestLists.lengthPx, _pacedTestLists.lengthPctSVG, diff --git a/content/smil/test/db_smilCSSPropertyList.js b/content/smil/test/db_smilCSSPropertyList.js index 4b9438098ce6..c98bc227440f 100644 --- a/content/smil/test/db_smilCSSPropertyList.js +++ b/content/smil/test/db_smilCSSPropertyList.js @@ -105,7 +105,7 @@ var gPropList = stop_color: new AdditiveAttribute("stop-color", "CSS", "stop"), stop_opacity: new AdditiveAttribute("stop-opacity", "CSS", "stop"), stroke: new AdditiveAttribute("stroke", "CSS", "rect"), - stroke_dasharray: new AdditiveAttribute("stroke-dasharray", "CSS", "rect"), + stroke_dasharray: new NonAdditiveAttribute("stroke-dasharray", "CSS", "rect"), stroke_dashoffset: new AdditiveAttribute("stroke-dashoffset", "CSS", "rect"), stroke_linecap: new NonAdditiveAttribute("stroke-linecap", "CSS", "rect"), stroke_linejoin: new NonAdditiveAttribute("stroke-linejoin", "CSS", "rect"), diff --git a/content/smil/test/smilTestUtils.js b/content/smil/test/smilTestUtils.js index 95a145d0cf14..32a5e045602b 100644 --- a/content/smil/test/smilTestUtils.js +++ b/content/smil/test/smilTestUtils.js @@ -359,6 +359,10 @@ AnimTestcase.prototype = return this.buildSeekListStatic(aAnimAttr, aBaseVal, aTimeData, "defined as non-animatable in SVG spec"); } + if (this.computedValMap.noEffect) { + return this.buildSeekListStatic(aAnimAttr, aBaseVal, aTimeData, + "testcase specified to have no effect"); + } return this.buildSeekListAnimated(aAnimAttr, aBaseVal, aTimeData, aIsFreeze) }, @@ -457,6 +461,9 @@ extend(AnimTestcaseFrom, AnimTestcase); * - midComp: Computed value that we expect to visit halfway through the * animation (if different from |aTo|) * - toComp: Computed value version of |aTo| (if different from |aTo|) + * - noEffect: Special flag -- if set, indicates that this testcase is + * expected to have no effect on the computed value. (e.g. the + * given values are invalid.) * @param aSkipReason If this test-case is known to currently fail, this * parameter should be a string explaining why. * Otherwise, this value should be null (or omitted). @@ -498,9 +505,10 @@ extend(AnimTestcaseFromTo, AnimTestcaseFrom); * animation (|aFrom| + |aBy|/2) * - toComp: Computed value of the animation endpoint (|aFrom| + |aBy|) * - noEffect: Special flag -- if set, indicates that this testcase is - * expected to have no effect on the computed value. (i.e. the - * attribute may be animatable and additive, but the particular - * "from" & "by" values that are used don't support addition.) + * expected to have no effect on the computed value. (e.g. the + * given values are invalid. Or the attribute may be animatable + * and additive, but the particular "from" & "by" values that + * are used don't support addition.) * @param aSkipReason If this test-case is known to currently fail, this * parameter should be a string explaining why. * Otherwise, this value should be null (or omitted). @@ -532,7 +540,7 @@ AnimTestcaseFromBy.prototype = }, buildSeekList : function(aAnimAttr, aBaseVal, aTimeData, aIsFreeze) { - if (!aAnimAttr.isAdditive || this.computedValMap.noEffect) { + if (!aAnimAttr.isAdditive) { return this.buildSeekListStatic(aAnimAttr, aBaseVal, aTimeData, "defined as non-additive in SVG spec"); } diff --git a/content/smil/test/smilXHR_helper.svg b/content/smil/test/smilXHR_helper.svg new file mode 100644 index 000000000000..cb0b51c36052 --- /dev/null +++ b/content/smil/test/smilXHR_helper.svg @@ -0,0 +1,8 @@ + + + + + + diff --git a/content/smil/test/test_smilCSSFromBy.xhtml b/content/smil/test/test_smilCSSFromBy.xhtml index 90ad54632c08..859867a7831e 100644 --- a/content/smil/test/test_smilCSSFromBy.xhtml +++ b/content/smil/test/test_smilCSSFromBy.xhtml @@ -18,6 +18,7 @@ more predictable. (otherwise, line-height varies depending on platform) --> testing 123 + diff --git a/content/smil/test/test_smilCSSInvalidValues.xhtml b/content/smil/test/test_smilCSSInvalidValues.xhtml new file mode 100644 index 000000000000..d00770c79b97 --- /dev/null +++ b/content/smil/test/test_smilCSSInvalidValues.xhtml @@ -0,0 +1,65 @@ + + + Test for Animation Behavior on CSS Properties + + + + + + + +

+
+ + + +
+
+
+
+ + diff --git a/content/smil/test/test_smilXHR.xhtml b/content/smil/test/test_smilXHR.xhtml new file mode 100644 index 000000000000..85c86114d94a --- /dev/null +++ b/content/smil/test/test_smilXHR.xhtml @@ -0,0 +1,89 @@ + + + Test for SMIL Behavior in Data Documents + + + + + + +Mozilla Bug 529387 +

+ +
+
+
+ + diff --git a/content/svg/content/src/nsSVGElement.cpp b/content/svg/content/src/nsSVGElement.cpp index 87e60484bbdf..b668e9e12785 100644 --- a/content/svg/content/src/nsSVGElement.cpp +++ b/content/svg/content/src/nsSVGElement.cpp @@ -726,8 +726,10 @@ nsSVGElement::WalkContentStyleRules(nsRuleWalker* aRuleWalker) if (!mContentStyleRule) UpdateContentStyleRule(); - if (mContentStyleRule) + if (mContentStyleRule) { + mContentStyleRule->RuleMatched(); aRuleWalker->Forward(mContentStyleRule); + } return NS_OK; } diff --git a/content/svg/content/src/nsSVGImageElement.cpp b/content/svg/content/src/nsSVGImageElement.cpp index 7990ab8e5c1c..aca2959a6753 100644 --- a/content/svg/content/src/nsSVGImageElement.cpp +++ b/content/svg/content/src/nsSVGImageElement.cpp @@ -269,3 +269,12 @@ nsSVGImageElement::GetStringInfo() return StringAttributesInfo(mStringAttributes, sStringInfo, NS_ARRAY_LENGTH(sStringInfo)); } + +nsresult +nsSVGImageElement::CopyInnerTo(nsGenericElement* aDest) const +{ + if (aDest->GetOwnerDoc()->IsStaticDocument()) { + CreateStaticImageClone(static_cast(aDest)); + } + return nsSVGImageElementBase::CopyInnerTo(aDest); +} diff --git a/content/svg/content/src/nsSVGImageElement.h b/content/svg/content/src/nsSVGImageElement.h index 6b527d477483..2ee68fedd6e5 100644 --- a/content/svg/content/src/nsSVGImageElement.h +++ b/content/svg/content/src/nsSVGImageElement.h @@ -90,6 +90,8 @@ public: virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const; + nsresult CopyInnerTo(nsGenericElement* aDest) const; + void MaybeLoadSVGImage(); protected: nsresult LoadSVGImage(PRBool aForce, PRBool aNotify); diff --git a/content/svg/content/src/nsSVGScriptElement.cpp b/content/svg/content/src/nsSVGScriptElement.cpp index f6a51bcf996c..0e8df93ee363 100644 --- a/content/svg/content/src/nsSVGScriptElement.cpp +++ b/content/svg/content/src/nsSVGScriptElement.cpp @@ -76,12 +76,10 @@ public: // nsIScriptElement virtual void GetScriptType(nsAString& type); - virtual already_AddRefed GetScriptURI(); virtual void GetScriptText(nsAString& text); virtual void GetScriptCharset(nsAString& charset); - virtual PRBool GetScriptDeferred(); - virtual PRBool GetScriptAsync(); - + virtual void FreezeUriAsyncDefer(); + // nsScriptElement virtual PRBool HasScriptContent(); @@ -199,22 +197,6 @@ nsSVGScriptElement::GetScriptType(nsAString& type) GetType(type); } -// variation of this code in nsHTMLScriptElement - check if changes -// need to be transfered when modifying - -already_AddRefed -nsSVGScriptElement::GetScriptURI() -{ - nsIURI *uri = nsnull; - nsAutoString src; - mStringAttributes[HREF].GetAnimValue(src, this); - if (!src.IsEmpty()) { - nsCOMPtr baseURI = GetBaseURI(); - NS_NewURI(&uri, src, nsnull, baseURI); - } - return uri; -} - void nsSVGScriptElement::GetScriptText(nsAString& text) { @@ -227,16 +209,24 @@ nsSVGScriptElement::GetScriptCharset(nsAString& charset) charset.Truncate(); } -PRBool -nsSVGScriptElement::GetScriptDeferred() +void +nsSVGScriptElement::FreezeUriAsyncDefer() { - return PR_FALSE; -} + if (mFrozen) { + return; + } -PRBool -nsSVGScriptElement::GetScriptAsync() -{ - return PR_FALSE; + // variation of this code in nsHTMLScriptElement - check if changes + // need to be transfered when modifying + nsAutoString src; + mStringAttributes[HREF].GetAnimValue(src, this); + // preserving bug 528444 here due to being unsure how to fix correctly + if (!src.IsEmpty()) { + nsCOMPtr baseURI = GetBaseURI(); + NS_NewURI(getter_AddRefs(mUri), src, nsnull, baseURI); + } + + mFrozen = PR_TRUE; } //---------------------------------------------------------------------- @@ -245,9 +235,10 @@ nsSVGScriptElement::GetScriptAsync() PRBool nsSVGScriptElement::HasScriptContent() { - nsAutoString str; - mStringAttributes[HREF].GetAnimValue(str, this); - return !str.IsEmpty() || + nsAutoString src; + mStringAttributes[HREF].GetAnimValue(src, this); + // preserving bug 528444 here due to being unsure how to fix correctly + return (mFrozen ? !!mUri : !src.IsEmpty()) || nsContentUtils::HasNonEmptyTextContent(this); } @@ -278,7 +269,14 @@ nsresult nsSVGScriptElement::DoneAddingChildren(PRBool aHaveNotified) { mDoneAddingChildren = PR_TRUE; - return MaybeProcessScript(); + nsresult rv = MaybeProcessScript(); + if (!mIsEvaluated) { + // Need to thaw the script uri here to allow another script to cause + // execution later. + mFrozen = PR_FALSE; + mUri = nsnull; + } + return rv; } nsresult diff --git a/content/svg/content/src/nsSVGUseElement.cpp b/content/svg/content/src/nsSVGUseElement.cpp index ecbd1204ee1b..efa80dae0768 100644 --- a/content/svg/content/src/nsSVGUseElement.cpp +++ b/content/svg/content/src/nsSVGUseElement.cpp @@ -186,8 +186,7 @@ nsSVGUseElement::AttributeChanged(nsIDocument *aDocument, nsIContent *aContent, PRInt32 aNameSpaceID, nsIAtom *aAttribute, - PRInt32 aModType, - PRUint32 aStateMask) + PRInt32 aModType) { if (nsContentUtils::IsInSameAnonymousTree(this, aContent)) { TriggerReclone(); diff --git a/content/svg/document/src/nsSVGDocument.cpp b/content/svg/document/src/nsSVGDocument.cpp index fee0c7aad175..efada1260e78 100644 --- a/content/svg/document/src/nsSVGDocument.cpp +++ b/content/svg/document/src/nsSVGDocument.cpp @@ -129,6 +129,20 @@ nsSVGDocument::GetRootElement(nsIDOMSVGSVGElement** aRootElement) return root ? CallQueryInterface(root, aRootElement) : NS_OK; } +nsresult +nsSVGDocument::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const +{ + NS_ASSERTION(aNodeInfo->NodeInfoManager() == mNodeInfoManager, + "Can't import this document into another document!"); + + nsRefPtr clone = new nsSVGDocument(); + NS_ENSURE_TRUE(clone, NS_ERROR_OUT_OF_MEMORY); + nsresult rv = CloneDocHelper(clone.get()); + NS_ENSURE_SUCCESS(rv, rv); + + return CallQueryInterface(clone.get(), aResult); +} + //////////////////////////////////////////////////////////////////////// // Exported creation functions diff --git a/content/svg/document/src/nsSVGDocument.h b/content/svg/document/src/nsSVGDocument.h index 03724a5958ea..f72aa8f555d1 100644 --- a/content/svg/document/src/nsSVGDocument.h +++ b/content/svg/document/src/nsSVGDocument.h @@ -54,7 +54,7 @@ class nsSVGDocument : public nsXMLDocument, NS_FORWARD_NSIDOMNODE(nsXMLDocument::) NS_FORWARD_NSIDOMDOCUMENTEVENT(nsXMLDocument::) NS_DECL_ISUPPORTS_INHERITED - + virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const; }; #endif diff --git a/content/xbl/src/nsBindingManager.cpp b/content/xbl/src/nsBindingManager.cpp index 899592932384..f75ea1f0c579 100644 --- a/content/xbl/src/nsBindingManager.cpp +++ b/content/xbl/src/nsBindingManager.cpp @@ -1272,8 +1272,7 @@ nsBindingManager::WalkRules(nsIStyleRuleProcessor::EnumFunc aFunc, { *aCutOffInheritance = PR_FALSE; - if (!aData->mContent) - return NS_OK; + NS_ASSERTION(aData->mContent, "How did that happen?"); // Walk the binding scope chain, starting with the binding attached to our // content, up till we run out of scopes or we get cut off. diff --git a/content/xml/document/src/nsXMLPrettyPrinter.cpp b/content/xml/document/src/nsXMLPrettyPrinter.cpp index f8247763cc08..6051519bc425 100644 --- a/content/xml/document/src/nsXMLPrettyPrinter.cpp +++ b/content/xml/document/src/nsXMLPrettyPrinter.cpp @@ -238,8 +238,7 @@ nsXMLPrettyPrinter::AttributeChanged(nsIDocument* aDocument, nsIContent* aContent, PRInt32 aNameSpaceID, nsIAtom* aAttribute, - PRInt32 aModType, - PRUint32 aStateMask) + PRInt32 aModType) { MaybeUnhook(aContent); } diff --git a/content/xslt/src/xpath/nsXPathResult.cpp b/content/xslt/src/xpath/nsXPathResult.cpp index 5c6daf4bc9e3..e83723162800 100644 --- a/content/xslt/src/xpath/nsXPathResult.cpp +++ b/content/xslt/src/xpath/nsXPathResult.cpp @@ -247,8 +247,7 @@ nsXPathResult::AttributeChanged(nsIDocument* aDocument, nsIContent* aContent, PRInt32 aNameSpaceID, nsIAtom* aAttribute, - PRInt32 aModType, - PRUint32 aStateMask) + PRInt32 aModType) { Invalidate(aContent); } diff --git a/content/xslt/src/xslt/txMozillaXSLTProcessor.cpp b/content/xslt/src/xslt/txMozillaXSLTProcessor.cpp index f0bc8c91edae..6c7d770d6bfb 100644 --- a/content/xslt/src/xslt/txMozillaXSLTProcessor.cpp +++ b/content/xslt/src/xslt/txMozillaXSLTProcessor.cpp @@ -1227,8 +1227,7 @@ txMozillaXSLTProcessor::AttributeChanged(nsIDocument* aDocument, nsIContent* aContent, PRInt32 aNameSpaceID, nsIAtom* aAttribute, - PRInt32 aModType, - PRUint32 aStateMask) + PRInt32 aModType) { mStylesheet = nsnull; } diff --git a/content/xul/content/src/nsXULElement.cpp b/content/xul/content/src/nsXULElement.cpp index 7979368a13f4..01bd0573a033 100644 --- a/content/xul/content/src/nsXULElement.cpp +++ b/content/xul/content/src/nsXULElement.cpp @@ -1431,8 +1431,7 @@ nsXULElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aName, PRBool aNotify) doc->ContentStatesChanged(this, nsnull, stateMask); } nsNodeUtils::AttributeChanged(this, aNameSpaceID, aName, - nsIDOMMutationEvent::REMOVAL, - stateMask); + nsIDOMMutationEvent::REMOVAL); } if (hasMutationListeners) { diff --git a/content/xul/document/src/nsXULDocument.cpp b/content/xul/document/src/nsXULDocument.cpp index 280c3ef34f90..9d0a848fd21a 100644 --- a/content/xul/document/src/nsXULDocument.cpp +++ b/content/xul/document/src/nsXULDocument.cpp @@ -987,14 +987,13 @@ nsXULDocument::AttributeWillChange(nsIDocument* aDocument, void nsXULDocument::AttributeChanged(nsIDocument* aDocument, nsIContent* aElement, PRInt32 aNameSpaceID, - nsIAtom* aAttribute, PRInt32 aModType, - PRUint32 aStateMask) + nsIAtom* aAttribute, PRInt32 aModType) { NS_ASSERTION(aDocument == this, "unexpected doc"); // Do this here so that all the exit paths below don't leave this undone nsXMLDocument::AttributeChanged(aDocument, aElement, aNameSpaceID, - aAttribute, aModType, aStateMask); + aAttribute, aModType); // XXXbz check aNameSpaceID, dammit! // See if we need to update our ref map. diff --git a/content/xul/templates/src/crashtests/257752-1-recursion.rdf b/content/xul/templates/src/crashtests/257752-1-recursion.rdf new file mode 100644 index 000000000000..a6eeb104bedf --- /dev/null +++ b/content/xul/templates/src/crashtests/257752-1-recursion.rdf @@ -0,0 +1,13 @@ + + + + + + + + + + + + diff --git a/content/xul/templates/src/crashtests/257752-1-recursion.xul b/content/xul/templates/src/crashtests/257752-1-recursion.xul new file mode 100644 index 000000000000..fad5abfb601b --- /dev/null +++ b/content/xul/templates/src/crashtests/257752-1-recursion.xul @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + diff --git a/content/xul/templates/src/crashtests/crashtests.list b/content/xul/templates/src/crashtests/crashtests.list index badb4eaae4b5..8c09672dc27e 100644 --- a/content/xul/templates/src/crashtests/crashtests.list +++ b/content/xul/templates/src/crashtests/crashtests.list @@ -1,3 +1,4 @@ +load 257752-1-recursion.xul load 329335-1.xul load 329884-1.xul HTTP load 330010-1.xul diff --git a/content/xul/templates/src/nsXULContentBuilder.cpp b/content/xul/templates/src/nsXULContentBuilder.cpp index 846a661cdba4..8418c7a20452 100644 --- a/content/xul/templates/src/nsXULContentBuilder.cpp +++ b/content/xul/templates/src/nsXULContentBuilder.cpp @@ -1566,8 +1566,7 @@ nsXULContentBuilder::AttributeChanged(nsIDocument* aDocument, nsIContent* aContent, PRInt32 aNameSpaceID, nsIAtom* aAttribute, - PRInt32 aModType, - PRUint32 aStateMask) + PRInt32 aModType) { // Handle "open" and "close" cases. We do this handling before // we've notified the observer, so that content is already created @@ -1591,7 +1590,7 @@ nsXULContentBuilder::AttributeChanged(nsIDocument* aDocument, // Pass along to the generic template builder. nsXULTemplateBuilder::AttributeChanged(aDocument, aContent, aNameSpaceID, - aAttribute, aModType, aStateMask); + aAttribute, aModType); } void diff --git a/content/xul/templates/src/nsXULTemplateBuilder.cpp b/content/xul/templates/src/nsXULTemplateBuilder.cpp index 79e13279fe32..a94aeffae09b 100644 --- a/content/xul/templates/src/nsXULTemplateBuilder.cpp +++ b/content/xul/templates/src/nsXULTemplateBuilder.cpp @@ -1101,8 +1101,7 @@ nsXULTemplateBuilder::AttributeChanged(nsIDocument* aDocument, nsIContent* aContent, PRInt32 aNameSpaceID, nsIAtom* aAttribute, - PRInt32 aModType, - PRUint32 aStateMask) + PRInt32 aModType) { if (aContent == mRoot && aNameSpaceID == kNameSpaceID_None) { // Check for a change to the 'ref' attribute on an atom, in which diff --git a/docshell/base/Makefile.in b/docshell/base/Makefile.in index 4c0e53ab6aa9..be152a5bcc08 100644 --- a/docshell/base/Makefile.in +++ b/docshell/base/Makefile.in @@ -103,4 +103,6 @@ FORCE_STATIC_LIB = 1 include $(topsrcdir)/config/rules.mk -LOCAL_INCLUDES += -I$(srcdir)/../shistory/src +LOCAL_INCLUDES += -I$(srcdir)/../shistory/src \ + -I$(srcdir)/../../layout/base \ + $(NULL) diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 2dc5f5bad807..0b4d0d107aa6 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -202,6 +202,11 @@ // for embedding #include "nsIWebBrowserChromeFocus.h" +#if NS_PRINT_PREVIEW +#include "nsIDocumentViewerPrint.h" +#include "nsIWebBrowserPrint.h" +#endif + #include "nsPluginError.h" static NS_DEFINE_CID(kDOMScriptObjectFactoryCID, @@ -11075,6 +11080,32 @@ nsDocShell::SetRendering(PRBool aRender) return NS_ERROR_DOCSHELL_REQUEST_REJECTED; } +NS_IMETHODIMP +nsDocShell::GetPrintPreview(nsIWebBrowserPrint** aPrintPreview) +{ + *aPrintPreview = nsnull; +#if NS_PRINT_PREVIEW + nsCOMPtr print = do_QueryInterface(mContentViewer); + if (!print || !print->IsInitializedForPrintPreview()) { + Stop(nsIWebNavigation::STOP_ALL); + nsCOMPtr principal = + do_CreateInstance("@mozilla.org/nullprincipal;1"); + NS_ENSURE_STATE(principal); + nsresult rv = CreateAboutBlankContentViewer(principal, nsnull); + NS_ENSURE_SUCCESS(rv, rv); + print = do_QueryInterface(mContentViewer); + NS_ENSURE_STATE(print); + print->InitializeForPrintPreview(); + } + nsCOMPtr result = do_QueryInterface(print); + result.forget(aPrintPreview); + return NS_OK; +#else + return NS_ERROR_NOT_IMPLEMENTED; +#endif +} + + #ifdef DEBUG unsigned long nsDocShell::gNumberOfDocShells = 0; #endif diff --git a/docshell/base/nsIDocShell.idl b/docshell/base/nsIDocShell.idl index 73499b01005b..26634a9d603b 100644 --- a/docshell/base/nsIDocShell.idl +++ b/docshell/base/nsIDocShell.idl @@ -68,8 +68,9 @@ interface nsILayoutHistoryState; interface nsISecureBrowserUI; interface nsIDOMStorage; interface nsIPrincipal; +interface nsIWebBrowserPrint; -[scriptable, uuid(8ADFB831-1053-4A19-884D-BCDAD7277B4B)] +[scriptable, uuid(1067ee1a-08e8-455d-9b12-19eeeee56b8e)] interface nsIDocShell : nsISupports { /** @@ -488,4 +489,11 @@ interface nsIDocShell : nsISupports * and should be treated accordingly. **/ attribute boolean isOffScreenBrowser; + + /** + * If the current content viewer isn't initialized for print preview, + * it is replaced with one which is and to which an about:blank document + * is loaded. + */ + readonly attribute nsIWebBrowserPrint printPreview; }; diff --git a/docshell/shistory/src/nsSHEntry.cpp b/docshell/shistory/src/nsSHEntry.cpp index aec263728f16..7873cb95a0cf 100644 --- a/docshell/shistory/src/nsSHEntry.cpp +++ b/docshell/shistory/src/nsSHEntry.cpp @@ -765,8 +765,7 @@ nsSHEntry::AttributeChanged(nsIDocument* aDocument, nsIContent* aContent, PRInt32 aNameSpaceID, nsIAtom* aAttribute, - PRInt32 aModType, - PRUint32 aStateMask) + PRInt32 aModType) { DocumentMutated(); } diff --git a/dom/base/nsDOMClassInfo.cpp b/dom/base/nsDOMClassInfo.cpp index 989bab09b2ae..7e8c81177a55 100644 --- a/dom/base/nsDOMClassInfo.cpp +++ b/dom/base/nsDOMClassInfo.cpp @@ -4325,14 +4325,6 @@ nsDOMClassInfo::PostCreatePrototype(JSContext * cx, JSObject * proto) JS_ClearPendingException(cx); } - static const nsIID *sSupportsIID = &NS_GET_IID(nsISupports); - - // This is safe because... - if (mData->mProtoChainInterface == sSupportsIID || - !mData->mProtoChainInterface) { - return NS_OK; - } - // This is called before any other location that requires // sObjectClass, so compute it here. We assume that nobody has had a // chance to monkey around with proto's prototype chain before this. @@ -4345,9 +4337,10 @@ nsDOMClassInfo::PostCreatePrototype(JSContext * cx, JSObject * proto) NS_ASSERTION(::JS_GetPrototype(cx, proto) && JS_GET_CLASS(cx, ::JS_GetPrototype(cx, proto)) == sObjectClass, "Hmm, somebody did something evil?"); - + #ifdef DEBUG - if (mData->mHasClassInterface) { + if (mData->mHasClassInterface && mData->mProtoChainInterface && + mData->mProtoChainInterface != &NS_GET_IID(nsISupports)) { nsCOMPtr iim(do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID)); @@ -5516,7 +5509,7 @@ private: static PRBool IsConstructable(const nsDOMClassInfoData *aData) { - if (IS_EXTERNAL(aData)) { + if (IS_EXTERNAL(aData->mCachedClassInfo)) { const nsExternalDOMClassInfoData* data = static_cast(aData); return data->mConstructorCID != nsnull; diff --git a/dom/base/nsFocusManager.cpp b/dom/base/nsFocusManager.cpp index b3cd2f41d4ae..37fdd564549c 100644 --- a/dom/base/nsFocusManager.cpp +++ b/dom/base/nsFocusManager.cpp @@ -1075,7 +1075,24 @@ nsFocusManager::SetFocusInner(nsIContent* aNewContent, PRInt32 aFlags, // if the element is in the active window, frame switching is allowed and // the content is in a visible window, fire blur and focus events. - if (isElementInActiveWindow && allowFrameSwitch && IsWindowVisible(newWindow)) { + PRBool sendFocusEvent = + isElementInActiveWindow && allowFrameSwitch && IsWindowVisible(newWindow); + + // When the following conditions are true: + // * an element has focus + // * isn't called by trusted event (i.e., called by untrusted event or by js) + // * the focus is moved to another document's element + // we need to check the permission. + if (sendFocusEvent && mFocusedContent && + mFocusedContent->GetOwnerDoc() != aNewContent->GetOwnerDoc()) { + // If the caller cannot access the current focused node, the caller should + // not be able to steal focus from it. E.g., When the current focused node + // is in chrome, any web contents should not be able to steal the focus. + nsCOMPtr domNode(do_QueryInterface(mFocusedContent)); + sendFocusEvent = nsContentUtils::CanCallerAccess(domNode); + } + + if (sendFocusEvent) { // return if blurring fails or the focus changes during the blur if (mFocusedWindow) { // if the focus is being moved to another element in the same document, @@ -1109,10 +1126,10 @@ nsFocusManager::SetFocusInner(nsIContent* aNewContent, PRInt32 aFlags, aFocusChanged, PR_FALSE); } else { - // otherwise, for inactive windows, update the node in the window, and - // raise the window if desired. + // otherwise, for inactive windows and when the caller cannot steal the + // focus, update the node in the window, and raise the window if desired. if (allowFrameSwitch) - AdjustWindowFocus(newWindow); + AdjustWindowFocus(newWindow, PR_TRUE); // set the focus node and method as needed PRUint32 focusMethod = aFocusChanged ? aFlags & FOCUSMETHOD_MASK : @@ -1201,7 +1218,8 @@ nsFocusManager::GetCommonAncestor(nsPIDOMWindow* aWindow1, } void -nsFocusManager::AdjustWindowFocus(nsPIDOMWindow* aWindow) +nsFocusManager::AdjustWindowFocus(nsPIDOMWindow* aWindow, + PRBool aCheckPermission) { PRBool isVisible = IsWindowVisible(aWindow); @@ -1227,6 +1245,12 @@ nsFocusManager::AdjustWindowFocus(nsPIDOMWindow* aWindow) if (IsWindowVisible(window) != isVisible) break; + // When aCheckPermission is true, we should check whether the caller can + // access the window or not. If it cannot access, we should stop the + // adjusting. + if (aCheckPermission && !nsContentUtils::CanCallerAccess(window)) + break; + window->SetFocusedNode(frameContent); } } @@ -1528,7 +1552,7 @@ nsFocusManager::Focus(nsPIDOMWindow* aWindow, // focus can be traversed from the top level down to the newly focused // window. if (aIsNewDocument) - AdjustWindowFocus(aWindow); + AdjustWindowFocus(aWindow, PR_FALSE); // indicate that the window has taken focus. if (aWindow->TakeFocus(PR_TRUE, focusMethod)) diff --git a/dom/base/nsFocusManager.h b/dom/base/nsFocusManager.h index 019b3f6d4ec8..4aed027819c7 100644 --- a/dom/base/nsFocusManager.h +++ b/dom/base/nsFocusManager.h @@ -150,7 +150,7 @@ protected: * the active top-level window and navigate down the currently focused * elements for each frame in the tree to get to aNewWindow. */ - void AdjustWindowFocus(nsPIDOMWindow* aNewWindow); + void AdjustWindowFocus(nsPIDOMWindow* aNewWindow, PRBool aCheckPermission); /** * Returns true if aWindow is visible. diff --git a/dom/locales/en-US/chrome/layout/css.properties b/dom/locales/en-US/chrome/layout/css.properties index 845950b8bcff..f0cc589f30ce 100644 --- a/dom/locales/en-US/chrome/layout/css.properties +++ b/dom/locales/en-US/chrome/layout/css.properties @@ -137,3 +137,4 @@ PEMQNoMinMaxWithoutValue=Media features with min- or max- must have a value. PEMQExpectedFeatureValue=Found invalid value for media feature. PEBadFontBlockStart=Expected '{' to begin @font-face rule but found '%1$S'. PEBadFontBlockEnd=Expected '}' to end @font-face rule but found '%1$S'. +PEAnonBoxNotAlone=Did not expect anonymous box. \ No newline at end of file diff --git a/dom/src/threads/nsDOMThreadService.cpp b/dom/src/threads/nsDOMThreadService.cpp index 894069f15ba3..4b388f9b1eb2 100644 --- a/dom/src/threads/nsDOMThreadService.cpp +++ b/dom/src/threads/nsDOMThreadService.cpp @@ -995,9 +995,11 @@ nsDOMThreadService::CreateJSContext() nsDOMWorkerSecurityManager::JSTranscodePrincipals, nsDOMWorkerSecurityManager::JSFindPrincipal }; - JS_SetContextSecurityCallbacks(cx, &securityCallbacks); + static JSDebugHooks debugHooks; + JS_SetContextDebugHooks(cx, &debugHooks); + nsresult rv = nsContentUtils::XPConnect()-> SetSecurityManagerForJSContext(cx, gWorkerSecurityManager, 0); NS_ENSURE_SUCCESS(rv, nsnull); diff --git a/dom/src/threads/nsDOMWorker.cpp b/dom/src/threads/nsDOMWorker.cpp index bbb21407a0ba..7cfe52a148a3 100644 --- a/dom/src/threads/nsDOMWorker.cpp +++ b/dom/src/threads/nsDOMWorker.cpp @@ -1489,6 +1489,8 @@ nsDOMWorker::SetGlobalForContext(JSContext* aCx) return PR_FALSE; } + JSAutoRequest ar(aCx); + JS_SetGlobalObject(aCx, mGlobal); return PR_TRUE; } diff --git a/dom/tests/Makefile.in b/dom/tests/Makefile.in index eb734a074165..8750807ccb33 100644 --- a/dom/tests/Makefile.in +++ b/dom/tests/Makefile.in @@ -44,7 +44,9 @@ include $(DEPTH)/config/autoconf.mk MODULE = test_dom -DIRS += mochitest +DIRS += mochitest \ + browser \ + $(NULL) XPCSHELL_TESTS = unit include $(topsrcdir)/config/rules.mk diff --git a/dom/tests/browser/Makefile.in b/dom/tests/browser/Makefile.in new file mode 100644 index 000000000000..7f49129d12cf --- /dev/null +++ b/dom/tests/browser/Makefile.in @@ -0,0 +1,51 @@ +# +# ***** 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) 2007 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# +# 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 = dom/tests/browser + +include $(DEPTH)/config/autoconf.mk +include $(topsrcdir)/config/rules.mk + +_BROWSER_FILES = \ + browser_focus_steal_from_chrome.js \ + +libs:: $(_BROWSER_FILES) + $(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir) diff --git a/dom/tests/browser/browser_focus_steal_from_chrome.js b/dom/tests/browser/browser_focus_steal_from_chrome.js new file mode 100644 index 000000000000..4f4e20e8e4b0 --- /dev/null +++ b/dom/tests/browser/browser_focus_steal_from_chrome.js @@ -0,0 +1,169 @@ +function test() { + waitForExplicitFinish(); + + let fm = Components.classes["@mozilla.org/focus-manager;1"] + .getService(Components.interfaces.nsIFocusManager); + + let tabs = [ gBrowser.mCurrentTab, gBrowser.addTab() ]; + gBrowser.selectedTab = tabs[0]; + + let testingList = [ + { uri: "data:text/html,", + tagName: "INPUT", methodName: "focus" }, + { uri: "data:text/html,", + tagName: "INPUT", methodName: "select" }, + { uri: "data:text/html,anchor", + tagName: "A", methodName: "focus" }, + { uri: "data:text/html,", + tagName: "BUTTON", methodName: "focus" }, + { uri: "data:text/html,", + tagName: "SELECT", methodName: "focus" }, + { uri: "data:text/html,", + tagName: "TEXTAREA", methodName: "focus" }, + { uri: "data:text/html,", + tagName: "TEXTAREA", methodName: "select" }, + { uri: "data:text/html,", + tagName: "INPUT", methodName: "focus of label element" }, + { uri: "data:text/html,
legend
", + tagName: "INPUT", methodName: "focus of legend element" }, + { uri: "data:text/html," + + "", + tagName: "BUTTON", methodName: "mousedown event on the button element" }, + { uri: "data:text/html," + + "", + tagName: "INPUT", methodName: "click event on the label element" }, + ]; + + let testingIndex = -1; + let canRetry; + let callback; + let loadedCount; + + function runNextTest() { + if (++testingIndex >= testingList.length) { + // cleaning-up... + let cleanTab = gBrowser.addTab(); + gBrowser.selectedTab = cleanTab; + for (let i = 0; i < tabs.length; i++) { + gBrowser.removeTab(tabs[i]); + } + finish(); + return; + } + callback = doTest1; + loadTestPage(); + } + + function loadTestPage() { + loadedCount = 0; + canRetry = 10; + // Set the focus to the contents. + tabs[0].linkedBrowser.focus(); + for (let i = 0; i < tabs.length; i++) { + tabs[i].linkedBrowser.addEventListener("load", onLoad, true); + tabs[i].linkedBrowser.loadURI(testingList[testingIndex].uri); + } + } + + function onLoad() { + if (++loadedCount == tabs.length) { + for (let i = 0; i < tabs.length; i++) { + tabs[i].linkedBrowser.removeEventListener("load", onLoad, true); + } + setTimeout(callback, 20); + } + } + + function isPrepared() { + for (let i = 0; i < tabs.length; i++) { + if (tabs[i].linkedBrowser.contentDocument.activeElement.tagName != + testingList[testingIndex].tagName) { + return false; + } + } + return true; + } + + function doTest1() { + if (canRetry-- > 0 && !isPrepared()) { + setTimeout(callback, 10); // retry + return; + } + + // The contents should be able to steal the focus from content. + + // in foreground tab + let e = tabs[0].linkedBrowser.contentDocument.activeElement; + is(e.tagName, testingList[testingIndex].tagName, + "the foreground tab's " + testingList[testingIndex].tagName + + " element is not active by the " + testingList[testingIndex].methodName + + " (Test1: content can steal focus)"); + is(fm.focusedElement, e, + "the " + testingList[testingIndex].tagName + + " element isn't focused by the " + testingList[testingIndex].methodName + + " (Test1: content can steal focus)"); + + // in background tab + e = tabs[1].linkedBrowser.contentDocument.activeElement; + is(e.tagName, testingList[testingIndex].tagName, + "the background tab's " + testingList[testingIndex].tagName + + " element is not active by the " + testingList[testingIndex].methodName + + " (Test1: content can steal focus)"); + isnot(fm.focusedElement, e, + "the " + testingList[testingIndex].tagName + + " element is focused by the " + testingList[testingIndex].methodName + + " (Test1: content can steal focus)"); + + callback = doTest2; + loadTestPage(); + + // Set focus to chrome element before onload events of the loading contents. + BrowserSearch.searchBar.focus(); + } + + + function doTest2() { + if (canRetry-- > 0 && !isPrepared()) { + setTimeout(callback, 10); // retry + return; + } + + // The contents shouldn't be able to steal the focus from chrome. + + // in foreground tab + let e = tabs[0].linkedBrowser.contentDocument.activeElement; + is(e.tagName, testingList[testingIndex].tagName, + "the foreground tab's " + testingList[testingIndex].tagName + + " element is not active by the " + testingList[testingIndex].methodName + + " (Test2: content can NOT steal focus)"); + isnot(fm.focusedElement, e, + "the " + testingList[testingIndex].tagName + + " element is focused by the " + testingList[testingIndex].methodName + + " (Test2: content can NOT steal focus)"); + + // in background tab + e = tabs[1].linkedBrowser.contentDocument.activeElement; + is(e.tagName, testingList[testingIndex].tagName, + "the background tab's " + testingList[testingIndex].tagName + + " element is not active by the " + testingList[testingIndex].methodName + + " (Test2: content can NOT steal focus)"); + isnot(fm.focusedElement, e, + "the " + testingList[testingIndex].tagName + + " element is focused by the " + testingList[testingIndex].methodName + + " (Test2: content can NOT steal focus)"); + + runNextTest(); + } + + runNextTest(); +} \ No newline at end of file diff --git a/embedding/browser/webBrowser/nsDocShellTreeOwner.cpp b/embedding/browser/webBrowser/nsDocShellTreeOwner.cpp index 7c62c71a290b..2bcf5380caa8 100644 --- a/embedding/browser/webBrowser/nsDocShellTreeOwner.cpp +++ b/embedding/browser/webBrowser/nsDocShellTreeOwner.cpp @@ -241,37 +241,27 @@ nsDocShellTreeOwner::FindItemWithName(const PRUnichar* aName, return NS_OK; // _main is an IE target which should be case-insensitive but isn't // see bug 217886 for details + // XXXbz what if our browser isn't targetable? We need to handle that somehow. if(name.LowerCaseEqualsLiteral("_content") || name.EqualsLiteral("_main")) { *aFoundItem = mWebBrowser->mDocShellAsItem; NS_IF_ADDREF(*aFoundItem); return NS_OK; } - // first, is it us? - { - nsCOMPtr domWindow; - mWebBrowser->GetContentDOMWindow(getter_AddRefs(domWindow)); - if (domWindow) { - nsAutoString ourName; - domWindow->GetName(ourName); - if (name.Equals(ourName, nsCaseInsensitiveStringComparator())) { - *aFoundItem = mWebBrowser->mDocShellAsItem; - NS_IF_ADDREF(*aFoundItem); - return NS_OK; - } + if (!SameCOMIdentity(aRequestor, mWebBrowser->mDocShellAsItem)) { + // This isn't a request coming up from our kid, so check with said kid + nsISupports* thisSupports = static_cast(this); + rv = + mWebBrowser->mDocShellAsItem->FindItemWithName(aName, thisSupports, + aOriginalRequestor, aFoundItem); + if (NS_FAILED(rv) || *aFoundItem) { + return rv; } } - // next, check our children - rv = FindChildWithName(aName, PR_TRUE, aRequestor, aOriginalRequestor, - aFoundItem); - if(NS_FAILED(rv) || *aFoundItem) - return rv; - // next, if we have a parent and it isn't the requestor, ask it - nsCOMPtr reqAsTreeOwner(do_QueryInterface(aRequestor)); - if(mTreeOwner) { + nsCOMPtr reqAsTreeOwner(do_QueryInterface(aRequestor)); if (mTreeOwner != reqAsTreeOwner) return mTreeOwner->FindItemWithName(aName, mWebBrowser->mDocShellAsItem, aOriginalRequestor, aFoundItem); @@ -283,47 +273,6 @@ nsDocShellTreeOwner::FindItemWithName(const PRUnichar* aName, aFoundItem); } -nsresult -nsDocShellTreeOwner::FindChildWithName(const PRUnichar *aName, PRBool aRecurse, - nsIDocShellTreeItem* aRequestor, - nsIDocShellTreeItem* aOriginalRequestor, - nsIDocShellTreeItem **aFoundItem) -{ - if (!mWebBrowser) - return NS_OK; - - nsresult rv = NS_OK; - - nsCOMPtr domWindow; - mWebBrowser->GetContentDOMWindow(getter_AddRefs(domWindow)); - if (!domWindow) - return NS_OK; - - nsCOMPtr frames; - domWindow->GetFrames(getter_AddRefs(frames)); - if (!frames) - return NS_OK; - - PRUint32 ctr, count; - frames->GetLength(&count); - for (ctr = 0; ctr < count; ctr++) { - nsCOMPtr frame; - frames->Item(ctr, getter_AddRefs(frame)); - nsCOMPtr w(do_QueryInterface(frame)); - if (w) { - nsCOMPtr item = do_QueryInterface(w->GetDocShell()); - if (item && item != aRequestor) { - rv = item->FindItemWithName(aName, mWebBrowser->mDocShellAsItem, - aOriginalRequestor, aFoundItem); - if (NS_FAILED(rv) || *aFoundItem) - break; - } - } - } - - return rv; -} - nsresult nsDocShellTreeOwner::FindItemWithNameAcrossWindows(const PRUnichar* aName, nsIDocShellTreeItem* aRequestor, diff --git a/embedding/browser/webBrowser/nsDocShellTreeOwner.h b/embedding/browser/webBrowser/nsDocShellTreeOwner.h index 3f9be54d1beb..de48b51c84f5 100644 --- a/embedding/browser/webBrowser/nsDocShellTreeOwner.h +++ b/embedding/browser/webBrowser/nsDocShellTreeOwner.h @@ -123,10 +123,6 @@ protected: NS_IMETHOD AddChromeListeners(); NS_IMETHOD RemoveChromeListeners(); - nsresult FindChildWithName(const PRUnichar *aName, - PRBool aRecurse, nsIDocShellTreeItem* aRequestor, - nsIDocShellTreeItem* aOriginalRequestor, - nsIDocShellTreeItem **aFoundItem); nsresult FindItemWithNameAcrossWindows(const PRUnichar* aName, nsIDocShellTreeItem* aRequestor, nsIDocShellTreeItem* aOriginalRequestor, diff --git a/embedding/browser/webBrowser/nsIWebBrowserPrint.idl b/embedding/browser/webBrowser/nsIWebBrowserPrint.idl index 587a6db062ff..c85b39b15643 100644 --- a/embedding/browser/webBrowser/nsIWebBrowserPrint.idl +++ b/embedding/browser/webBrowser/nsIWebBrowserPrint.idl @@ -144,7 +144,7 @@ interface nsIWebBrowserPrint : nsISupports * * @param aThePrintSettings - Printer Settings for the print preview, if aThePrintSettings is null * then the global PS will be used. - * @param aChildDOMWin - DOM Window of the child document to be PP (FrameSet frames) + * @param aChildDOMWin - DOM Window to be print previewed. * @param aWPListener - is updated during the printpreview * @return void */ diff --git a/gfx/thebes/crashtests/334735-1.html b/gfx/thebes/crashtests/334735-1.html new file mode 100644 index 000000000000..f1a2c04a5a46 --- /dev/null +++ b/gfx/thebes/crashtests/334735-1.html @@ -0,0 +1,11 @@ + + + +demo 1 + + +These unusual characters, 􀂉, +cause Firefox to crash 􀂉 + + + \ No newline at end of file diff --git a/gfx/thebes/crashtests/crashtests.list b/gfx/thebes/crashtests/crashtests.list index 7d26b46f6386..89219a85c980 100644 --- a/gfx/thebes/crashtests/crashtests.list +++ b/gfx/thebes/crashtests/crashtests.list @@ -6,6 +6,7 @@ load 206561-1.html load 248518-1.html load 306649-1.xml load 333861-1.html +load 334735-1.html load 345576-1.html load 345629-1.html load 369688-1.html diff --git a/gfx/thebes/public/gfxAtsuiFonts.h b/gfx/thebes/public/gfxAtsuiFonts.h index 2bc9f73ccc62..590147252ffe 100644 --- a/gfx/thebes/public/gfxAtsuiFonts.h +++ b/gfx/thebes/public/gfxAtsuiFonts.h @@ -55,6 +55,9 @@ class gfxAtsuiFontGroup; class MacOSFontEntry; +#define kLiGothicBadCharUnicode 0x775B // ATSUI failure on 10.6 (bug 532346) +#define kLiGothicBadCharGlyph 3774 // the expected glyph for this char + class gfxAtsuiFont : public gfxFont { public: diff --git a/gfx/thebes/public/gfxFont.h b/gfx/thebes/public/gfxFont.h index ad46d08dd6f4..afc4fa900f8b 100644 --- a/gfx/thebes/public/gfxFont.h +++ b/gfx/thebes/public/gfxFont.h @@ -268,9 +268,12 @@ public: THEBES_INLINE_DECL_REFCOUNTING(gfxFontFamily) gfxFontFamily(const nsAString& aName) : - mName(aName), mOtherFamilyNamesInitialized(PR_FALSE), mHasOtherFamilyNames(PR_FALSE), + mName(aName), + mOtherFamilyNamesInitialized(PR_FALSE), + mHasOtherFamilyNames(PR_FALSE), + mHasStyles(PR_FALSE), mIsSimpleFamily(PR_FALSE), - mHasStyles(PR_FALSE) + mIsBadUnderlineFamily(PR_FALSE) { } virtual ~gfxFontFamily() { } @@ -303,7 +306,8 @@ public: // read in other family names, if any, and use functor to add each into cache virtual void ReadOtherFamilyNames(AddOtherFamilyNameFunctor& aOtherFamilyFunctor); - // find faces belonging to this family (temporary, for Windows FontFamily to override) + // find faces belonging to this family (platform implementations override this; + // should be made pure virtual once all subclasses have been updated) virtual void FindStyleVariations() { } // search for a specific face using the Postscript name @@ -318,14 +322,12 @@ public: mAvailableFonts[i]->ReadCMAP(); } - // set whether this font family is in "bad" underline offset blacklist. - void SetBadUnderlineFont(PRBool aIsBadUnderlineFont) { - PRUint32 i, numFonts = mAvailableFonts.Length(); - // this is only used when initially setting up the family, - // so CheckForSimpleFamily has not yet been called and there cannot - // be any NULL entries in mAvailableFonts - for (i = 0; i < numFonts; i++) - mAvailableFonts[i]->mIsBadUnderlineFont = aIsBadUnderlineFont; + // mark this family as being in the "bad" underline offset blacklist + void SetBadUnderlineFamily() { + mIsBadUnderlineFamily = PR_TRUE; + if (mHasStyles) { + SetBadUnderlineFonts(); + } } // sort available fonts to put preferred (standard) faces towards the end @@ -346,12 +348,23 @@ protected: gfxFontEntry *aFontEntry, PRBool useFullName = PR_FALSE); + // set whether this font family is in "bad" underline offset blacklist. + void SetBadUnderlineFonts() { + PRUint32 i, numFonts = mAvailableFonts.Length(); + for (i = 0; i < numFonts; i++) { + if (mAvailableFonts[i]) { + mAvailableFonts[i]->mIsBadUnderlineFont = PR_TRUE; + } + } + } + nsString mName; nsTArray > mAvailableFonts; PRPackedBool mOtherFamilyNamesInitialized; PRPackedBool mHasOtherFamilyNames; - PRPackedBool mIsSimpleFamily; PRPackedBool mHasStyles; + PRPackedBool mIsSimpleFamily; + PRPackedBool mIsBadUnderlineFamily; enum { // for "simple" families, the faces are stored in mAvailableFonts diff --git a/gfx/thebes/public/gfxFontUtils.h b/gfx/thebes/public/gfxFontUtils.h index fb69bef940c6..a9b3f58eb8e5 100644 --- a/gfx/thebes/public/gfxFontUtils.h +++ b/gfx/thebes/public/gfxFontUtils.h @@ -476,10 +476,20 @@ public: ReadCMAPTableFormat4(PRUint8 *aBuf, PRUint32 aLength, gfxSparseBitSet& aCharacterMap); + static PRUint32 + FindPreferredSubtable(PRUint8 *aBuf, PRUint32 aBufLength, + PRUint32 *aTableOffset, PRBool *aSymbolEncoding); + static nsresult ReadCMAP(PRUint8 *aBuf, PRUint32 aBufLength, gfxSparseBitSet& aCharacterMap, PRPackedBool& aUnicodeFont, PRPackedBool& aSymbolFont); + static PRUint32 + MapCharToGlyphFormat4(const PRUint8 *aBuf, PRUnichar aCh); + + static PRUint32 + MapCharToGlyph(PRUint8 *aBuf, PRUint32 aBufLength, PRUnichar aCh); + #ifdef XP_WIN // given a TrueType/OpenType data file, produce a EOT-format header diff --git a/gfx/thebes/public/gfxPlatformMac.h b/gfx/thebes/public/gfxPlatformMac.h index e13366b44183..0eba993c9c4a 100644 --- a/gfx/thebes/public/gfxPlatformMac.h +++ b/gfx/thebes/public/gfxPlatformMac.h @@ -44,6 +44,9 @@ #define MAC_OS_X_VERSION_10_4_HEX 0x00001040 #define MAC_OS_X_VERSION_10_5_HEX 0x00001050 +#define MAC_OS_X_VERSION_10_6_HEX 0x00001060 + +#define MAC_OS_X_MAJOR_VERSION_MASK 0xFFFFFFF0U class gfxTextRun; diff --git a/gfx/thebes/public/gfxXlibSurface.h b/gfx/thebes/public/gfxXlibSurface.h index 078dc73b9168..9dfdccce4d5b 100644 --- a/gfx/thebes/public/gfxXlibSurface.h +++ b/gfx/thebes/public/gfxXlibSurface.h @@ -54,10 +54,12 @@ public: // with explicitly provided width/height. gfxXlibSurface(Display *dpy, Drawable drawable, Visual *visual, const gfxIntSize& size); - // create a new Pixmap on the display dpy, with - // the root window as the parent and the default depth - // for the default screen, and attach the given visual - gfxXlibSurface(Display *dpy, Visual *visual, const gfxIntSize& size); + // create a new Pixmap on the display dpy, with the root window as + // the parent and the default depth for the default screen, and + // attach the given visual. The depth argument is optional, and + // if not specified (or 0), the default depth of the default + // screen of dpy is used. + gfxXlibSurface(Display *dpy, Visual *visual, const gfxIntSize& size, int depth = 0); gfxXlibSurface(Display* dpy, Drawable drawable, XRenderPictFormat *format, const gfxIntSize& size); diff --git a/gfx/thebes/src/gfxAtsuiFonts.cpp b/gfx/thebes/src/gfxAtsuiFonts.cpp index c429c7b2bf78..c25dd0d0bce6 100644 --- a/gfx/thebes/src/gfxAtsuiFonts.cpp +++ b/gfx/thebes/src/gfxAtsuiFonts.cpp @@ -1468,6 +1468,14 @@ gfxAtsuiFontGroup::InitTextRun(gfxTextRun *aRun, PRUint32 r, numRanges = fontRanges.Length(); + // Bug 532346: Work around rendering failure with Apple LiGothic font on 10.6, + // triggered by U+775B. + // We record the offset(s) in layoutString where this character occurs, and replace + // them with U+775C, which has the same metrics but doesn't disrupt ATSUI layout. + // Then after layout is complete, we poke the correct glyph for U+775B into the + // text run at the recorded positions. + nsTArray hackForLiGothic; + for (r = 0; r < numRanges; r++) { const gfxTextRange& range = fontRanges[r]; @@ -1518,6 +1526,19 @@ gfxAtsuiFontGroup::InitTextRun(gfxTextRun *aRun, // add a glyph run for the matched substring aRun->AddGlyphRun(matchedFont, aOffsetInTextRun + runStart - aLayoutStart, PR_TRUE); + + if (matchedFont->GetFontEntry()->UseLiGothicAtsuiHack()) { + PRUnichar *text = const_cast(layoutString); + for (PRUint32 i = 0; i < matchedLength; ++i) { + if (text[aOffsetInTextRun + runStart + i] == + kLiGothicBadCharUnicode) { + hackForLiGothic.AppendElement(aOffsetInTextRun + + runStart + i); + text[aOffsetInTextRun + runStart + i] = + kLiGothicBadCharUnicode + 1; + } + } + } } runStart += matchedLength; @@ -1542,6 +1563,16 @@ gfxAtsuiFontGroup::InitTextRun(gfxTextRun *aRun, aRun->AdjustAdvancesForSyntheticBold(aOffsetInTextRun, aLengthInTextRun); + for (PRUint32 i = 0; i < hackForLiGothic.Length(); ++i) { + gfxTextRun::CompressedGlyph glyph = + aRun->GetCharacterGlyphs()[hackForLiGothic[i]]; + if (glyph.IsSimpleGlyph()) { + aRun->SetSimpleGlyph(hackForLiGothic[i], + glyph.SetSimpleGlyph(glyph.GetSimpleAdvance(), + kLiGothicBadCharGlyph)); + } + } + PRUint32 i; for (i = 0; i < stylesToDispose.Length(); ++i) { ATSUDisposeStyle(stylesToDispose[i]); diff --git a/gfx/thebes/src/gfxCoreTextFonts.cpp b/gfx/thebes/src/gfxCoreTextFonts.cpp index 8abd2788da32..b4ac6889adce 100644 --- a/gfx/thebes/src/gfxCoreTextFonts.cpp +++ b/gfx/thebes/src/gfxCoreTextFonts.cpp @@ -1364,6 +1364,7 @@ gfxCoreTextFontGroup::UpdateFontList() if (mUserFontSet && mCurrGeneration != GetGeneration()) { // xxx - can probably improve this to detect when all fonts were found, so no need to update list mFonts.Clear(); + mUnderlineOffset = UNDERLINE_OFFSET_NOT_SET; ForEachFont(FindCTFont, this); mCurrGeneration = GetGeneration(); } diff --git a/gfx/thebes/src/gfxFont.cpp b/gfx/thebes/src/gfxFont.cpp index bdc877bc348a..1d352725c8e9 100644 --- a/gfx/thebes/src/gfxFont.cpp +++ b/gfx/thebes/src/gfxFont.cpp @@ -412,6 +412,9 @@ void gfxFontFamily::LocalizedName(nsAString& aLocalizedName) void gfxFontFamily::FindFontForChar(FontSearch *aMatchData) { + if (!mHasStyles) + FindStyleVariations(); + // xxx - optimization point - keep a bit vector with the union of supported unicode ranges // by all fonts for this family and bail immediately if the character is not in any of // this family's cmaps @@ -547,6 +550,8 @@ gfxFontFamily::ReadOtherFamilyNames(AddOtherFamilyNameFunctor& aOtherFamilyFunct return; mOtherFamilyNamesInitialized = PR_TRUE; + FindStyleVariations(); + // read in other family names for the first face in the list PRUint32 numFonts = mAvailableFonts.Length(); PRUint32 i; diff --git a/gfx/thebes/src/gfxFontUtils.cpp b/gfx/thebes/src/gfxFontUtils.cpp index 675822ce36c1..f5d71d0500f0 100644 --- a/gfx/thebes/src/gfxFontUtils.cpp +++ b/gfx/thebes/src/gfxFontUtils.cpp @@ -371,11 +371,12 @@ gfxFontUtils::ReadCMAPTableFormat4(PRUint8 *aBuf, PRUint32 aLength, gfxSparseBit #define acceptableUCS4Encoding(p, e) \ ((platformID == PLATFORM_ID_MICROSOFT && encodingID == EncodingIDUCS4ForMicrosoftPlatform) || \ - (platformID == PLATFORM_ID_UNICODE && encodingID == EncodingIDUCS4ForUnicodePlatform)) + (platformID == PLATFORM_ID_UNICODE && \ + (encodingID == EncodingIDDefaultForUnicodePlatform || encodingID >= EncodingIDUCS4ForUnicodePlatform))) -nsresult -gfxFontUtils::ReadCMAP(PRUint8 *aBuf, PRUint32 aBufLength, gfxSparseBitSet& aCharacterMap, - PRPackedBool& aUnicodeFont, PRPackedBool& aSymbolFont) +PRUint32 +gfxFontUtils::FindPreferredSubtable(PRUint8 *aBuf, PRUint32 aBufLength, + PRUint32 *aTableOffset, PRBool *aSymbolEncoding) { enum { OffsetVersion = 0, @@ -392,6 +393,7 @@ gfxFontUtils::ReadCMAP(PRUint8 *aBuf, PRUint32 aBufLength, gfxSparseBitSet& aCha enum { EncodingIDSymbol = 0, EncodingIDMicrosoft = 1, + EncodingIDDefaultForUnicodePlatform = 0, EncodingIDUCS4ForUnicodePlatform = 3, EncodingIDUCS4ForMicrosoftPlatform = 10 }; @@ -399,8 +401,7 @@ gfxFontUtils::ReadCMAP(PRUint8 *aBuf, PRUint32 aBufLength, gfxSparseBitSet& aCha // PRUint16 version = ReadShortAt(aBuf, OffsetVersion); // Unused: self-documenting. PRUint16 numTables = ReadShortAt(aBuf, OffsetNumTables); - // save the format and offset we want here - PRUint32 keepOffset = 0; + // save the format we want here PRUint32 keepFormat = 0; PRUint8 *table = aBuf + SizeOfHeader; @@ -419,33 +420,144 @@ gfxFontUtils::ReadCMAP(PRUint8 *aBuf, PRUint32 aBufLength, gfxSparseBitSet& aCha const PRUint16 format = ReadShortAt(subtable, SubtableOffsetFormat); if (isSymbol(platformID, encodingID)) { - aUnicodeFont = PR_FALSE; - aSymbolFont = PR_TRUE; keepFormat = format; - keepOffset = offset; + *aTableOffset = offset; + *aSymbolEncoding = PR_TRUE; break; } else if (format == 4 && acceptableFormat4(platformID, encodingID, keepFormat)) { - aUnicodeFont = PR_TRUE; - aSymbolFont = PR_FALSE; keepFormat = format; - keepOffset = offset; + *aTableOffset = offset; + *aSymbolEncoding = PR_FALSE; } else if (format == 12 && acceptableUCS4Encoding(platformID, encodingID)) { - aUnicodeFont = PR_TRUE; - aSymbolFont = PR_FALSE; keepFormat = format; - keepOffset = offset; + *aTableOffset = offset; + *aSymbolEncoding = PR_FALSE; break; // we don't want to try anything else when this format is available. } } - nsresult rv = NS_ERROR_FAILURE; + return keepFormat; +} - if (keepFormat == 12) - rv = ReadCMAPTableFormat12(aBuf + keepOffset, aBufLength - keepOffset, aCharacterMap); - else if (keepFormat == 4) - rv = ReadCMAPTableFormat4(aBuf + keepOffset, aBufLength - keepOffset, aCharacterMap); +nsresult +gfxFontUtils::ReadCMAP(PRUint8 *aBuf, PRUint32 aBufLength, gfxSparseBitSet& aCharacterMap, + PRPackedBool& aUnicodeFont, PRPackedBool& aSymbolFont) +{ + PRUint32 offset; + PRBool symbol; + PRUint32 format = FindPreferredSubtable(aBuf, aBufLength, &offset, &symbol); - return rv; + if (format == 4) { + if (symbol) { + aUnicodeFont = PR_FALSE; + aSymbolFont = PR_TRUE; + } else { + aUnicodeFont = PR_TRUE; + aSymbolFont = PR_FALSE; + } + return ReadCMAPTableFormat4(aBuf + offset, aBufLength - offset, aCharacterMap); + } + + if (format == 12) { + aUnicodeFont = PR_TRUE; + aSymbolFont = PR_FALSE; + return ReadCMAPTableFormat12(aBuf + offset, aBufLength - offset, aCharacterMap); + } + + return NS_ERROR_FAILURE; +} + +using namespace mozilla; // for the AutoSwap_* types + +#pragma pack(1) + +typedef struct { + AutoSwap_PRUint16 format; + AutoSwap_PRUint16 length; + AutoSwap_PRUint16 language; + AutoSwap_PRUint16 segCountX2; + AutoSwap_PRUint16 searchRange; + AutoSwap_PRUint16 entrySelector; + AutoSwap_PRUint16 rangeShift; + + AutoSwap_PRUint16 arrays[1]; +} Format4Cmap; + +PRUint32 +gfxFontUtils::MapCharToGlyphFormat4(const PRUint8 *aBuf, PRUnichar aCh) +{ + const Format4Cmap *cmap4 = reinterpret_cast(aBuf); + PRUint16 segCount; + const AutoSwap_PRUint16 *endCodes; + const AutoSwap_PRUint16 *startCodes; + const AutoSwap_PRUint16 *idDelta; + const AutoSwap_PRUint16 *idRangeOffset; + PRUint16 probe; + PRUint16 rangeShiftOver2; + PRUint16 index; + +// not needed because PRUnichar cannot exceed 0xFFFF +// if (aCh >= 0x10000) { +// return 0; +// } + + segCount = (PRUint16)(cmap4->segCountX2) / 2; + + endCodes = &cmap4->arrays[0]; + startCodes = &cmap4->arrays[segCount + 1]; // +1 for reserved word between arrays + idDelta = &startCodes[segCount]; + idRangeOffset = &idDelta[segCount]; + + probe = 1 << (PRUint16)(cmap4->entrySelector); + rangeShiftOver2 = (PRUint16)(cmap4->rangeShift) / 2; + + if ((PRUint16)(startCodes[rangeShiftOver2]) <= aCh) { + index = rangeShiftOver2; + } else { + index = 0; + } + + while (probe > 1) { + probe >>= 1; + if ((PRUint16)(startCodes[index + probe]) <= aCh) { + index += probe; + } + } + + if (aCh >= (PRUint16)(startCodes[index]) && aCh <= (PRUint16)(endCodes[index])) { + PRUint16 result; + if ((PRUint16)(idRangeOffset[index]) == 0) { + result = aCh; + } else { + PRUint16 offset = aCh - (PRUint16)(startCodes[index]); + const AutoSwap_PRUint16 *glyphIndexTable = + (const AutoSwap_PRUint16*)((const char*)&idRangeOffset[index] + + (PRUint16)(idRangeOffset[index])); + result = glyphIndexTable[offset]; + } + + // note that this is unsigned 16-bit arithmetic, and may wrap around + result += (PRUint16)(idDelta[index]); + return result; + } + + return 0; +} + +PRUint32 +gfxFontUtils::MapCharToGlyph(PRUint8 *aBuf, PRUint32 aBufLength, PRUnichar aCh) +{ + PRUint32 offset; + PRBool symbol; + PRUint32 format = FindPreferredSubtable(aBuf, aBufLength, &offset, &symbol); + + if (format == 4) + return MapCharToGlyphFormat4(aBuf + offset, aCh); + + // other formats not currently supported; this is used only for the + // Mac OS X 10.6 LiGothic font hack (bug 532346) + + return 0; } PRUint8 gfxFontUtils::CharRangeBit(PRUint32 ch) { @@ -538,8 +650,6 @@ nsresult gfxFontUtils::MakeUniqueUserFontName(nsAString& aName) // TrueType/OpenType table handling code -using namespace mozilla; // for the AutoSwap_* types - // need byte aligned structs #pragma pack(1) diff --git a/gfx/thebes/src/gfxMacPlatformFontList.h b/gfx/thebes/src/gfxMacPlatformFontList.h index e69f4f46db6d..a7e824ee2f35 100644 --- a/gfx/thebes/src/gfxMacPlatformFontList.h +++ b/gfx/thebes/src/gfxMacPlatformFontList.h @@ -70,6 +70,8 @@ public: ATSFontRef GetFontRef(); nsresult ReadCMAP(); + PRBool UseLiGothicAtsuiHack() { return mUseLiGothicAtsuiHack; } + protected: // for use with data fonts MacOSFontEntry(const nsAString& aPostscriptName, ATSFontRef aFontRef, @@ -80,6 +82,7 @@ protected: ATSFontRef mATSFontRef; PRPackedBool mATSFontRefInitialized; + PRPackedBool mUseLiGothicAtsuiHack; }; class gfxMacPlatformFontList : public gfxPlatformFontList { diff --git a/gfx/thebes/src/gfxMacPlatformFontList.mm b/gfx/thebes/src/gfxMacPlatformFontList.mm index adee57533bee..6aa5abcb7e3a 100644 --- a/gfx/thebes/src/gfxMacPlatformFontList.mm +++ b/gfx/thebes/src/gfxMacPlatformFontList.mm @@ -9,7 +9,7 @@ * Masayuki Nakano * John Daggett * Jonathan Kew - * + * * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -75,7 +75,7 @@ static const int kAppleUltraLightWeight = 2; static const int gAppleWeightToCSSWeight[] = { 0, - 1, // 1. + 1, // 1. 1, // 2. W1, ultralight 2, // 3. W2, extralight 3, // 4. W3, light @@ -91,6 +91,8 @@ static const int gAppleWeightToCSSWeight[] = { 9 // 14 }; +// cache Cocoa's "shared font manager" for performance +static NSFontManager *sFontManager; static void GetStringForNSString(const NSString *aSrc, nsAString& aDist) { @@ -109,13 +111,14 @@ static PRLogModuleInfo *gFontInfoLog = PR_NewLogModule("fontInfoLog"); /* MacOSFontEntry */ #pragma mark- -MacOSFontEntry::MacOSFontEntry(const nsAString& aPostscriptName, +MacOSFontEntry::MacOSFontEntry(const nsAString& aPostscriptName, PRInt32 aWeight, gfxFontFamily *aFamily, PRBool aIsStandardFace) : gfxFontEntry(aPostscriptName, aFamily, aIsStandardFace), mATSFontRef(0), - mATSFontRefInitialized(PR_FALSE) + mATSFontRefInitialized(PR_FALSE), + mUseLiGothicAtsuiHack(PR_FALSE) { mWeight = aWeight; } @@ -125,7 +128,8 @@ MacOSFontEntry::MacOSFontEntry(const nsAString& aPostscriptName, ATSFontRef aFon gfxUserFontData *aUserFontData) : gfxFontEntry(aPostscriptName), mATSFontRef(aFontRef), - mATSFontRefInitialized(PR_TRUE) + mATSFontRefInitialized(PR_TRUE), + mUseLiGothicAtsuiHack(PR_FALSE) { // xxx - stretch is basically ignored for now @@ -138,7 +142,7 @@ MacOSFontEntry::MacOSFontEntry(const nsAString& aPostscriptName, ATSFontRef aFon } ATSFontRef -MacOSFontEntry::GetFontRef() +MacOSFontEntry::GetFontRef() { if (!mATSFontRefInitialized) { mATSFontRefInitialized = PR_TRUE; @@ -186,16 +190,15 @@ MacOSFontEntry::ReadCMAP() mCmapInitialized = PR_TRUE; PRUint32 kCMAP = TRUETYPE_TAG('c','m','a','p'); - - nsAutoTArray buffer; - if (GetFontTable(kCMAP, buffer) != NS_OK) + + nsAutoTArray cmap; + if (GetFontTable(kCMAP, cmap) != NS_OK) return NS_ERROR_FAILURE; - PRUint8 *cmap = buffer.Elements(); PRPackedBool unicodeFont, symbolFont; // currently ignored - nsresult rv = gfxFontUtils::ReadCMAP(cmap, buffer.Length(), + nsresult rv = gfxFontUtils::ReadCMAP(cmap.Elements(), cmap.Length(), mCharacterMap, unicodeFont, symbolFont); - + if (NS_FAILED(rv)) { mCharacterMap.reset(); return rv; @@ -209,7 +212,7 @@ MacOSFontEntry::ReadCMAP() for (s = 0; s < numScripts; s++) { eComplexScript whichScript = gScriptsThatRequireShaping[s].script; - + // check to see if the cmap includes complex script codepoints if (mCharacterMap.TestRange(gScriptsThatRequireShaping[s].rangeStart, gScriptsThatRequireShaping[s].rangeEnd)) { @@ -248,7 +251,7 @@ MacOSFontEntry::ReadCMAP() } } - // rude hack - the Chinese STxxx fonts on 10.4 contain morx tables and Arabic glyphs but + // rude hack - the Chinese STxxx fonts on 10.4 contain morx tables and Arabic glyphs but // lack the proper info for shaping Arabic, so exclude explicitly, ick if (mName.CharAt(0) == 'S' && mName.CharAt(1) == 'T') { omitRange = PR_TRUE; @@ -262,9 +265,25 @@ MacOSFontEntry::ReadCMAP() } } - PR_LOG(gFontInfoLog, PR_LOG_DEBUG, ("(fontinit-cmap) psname: %s, size: %d\n", + if ((gfxPlatformMac::GetPlatform()->OSXVersion() & + MAC_OS_X_MAJOR_VERSION_MASK) == MAC_OS_X_VERSION_10_6_HEX) { + // even ruder hack - LiGothic font on 10.6 has a bad glyph for U+775B + // that causes ATSUI failure, so we set a flag to tell our layout code + // to hack around that character + if (mName.EqualsLiteral("LiGothicMed")) { + // check whether the problem char maps to the expected glyph; + // if not, we'll assume this isn't the problem version of the font + if (gfxFontUtils::MapCharToGlyph(cmap.Elements(), cmap.Length(), + kLiGothicBadCharUnicode) == + kLiGothicBadCharGlyph) { + mUseLiGothicAtsuiHack = PR_TRUE; + } + } + } + + PR_LOG(gFontInfoLog, PR_LOG_DEBUG, ("(fontinit-cmap) psname: %s, size: %d\n", NS_ConvertUTF16toUTF8(mName).get(), mCharacterMap.GetSize())); - + return rv; } @@ -303,6 +322,10 @@ public: virtual ~gfxMacFontFamily() {} virtual void LocalizedName(nsAString& aLocalizedName); + + virtual void FindStyleVariations(); + + void EliminateDuplicateFaces(); }; void @@ -314,7 +337,7 @@ gfxMacFontFamily::LocalizedName(nsAString& aLocalizedName) } NSString *family = GetNSStringForString(mName); - NSString *localized = [[NSFontManager sharedFontManager] + NSString *localized = [sFontManager localizedNameForFamily:family face:nil]; @@ -327,6 +350,137 @@ gfxMacFontFamily::LocalizedName(nsAString& aLocalizedName) aLocalizedName = mName; } +void +gfxMacFontFamily::FindStyleVariations() +{ + if (mHasStyles) + return; + + NSString *family = GetNSStringForString(mName); + + // create a font entry for each face + NSArray *fontfaces = [sFontManager + availableMembersOfFontFamily:family]; // returns an array of [psname, style name, weight, traits] elements, goofy api + int faceCount = [fontfaces count]; + int faceIndex; + + // Bug 420981 - under 10.5, UltraLight and Light have the same weight value + PRBool needToCheckLightFaces = + (gfxPlatformMac::GetPlatform()->OSXVersion() >= MAC_OS_X_VERSION_10_5_HEX); + + for (faceIndex = 0; faceIndex < faceCount; faceIndex++) { + NSArray *face = [fontfaces objectAtIndex:faceIndex]; + NSString *psname = [face objectAtIndex:INDEX_FONT_POSTSCRIPT_NAME]; + PRInt32 appKitWeight = [[face objectAtIndex:INDEX_FONT_WEIGHT] unsignedIntValue]; + PRUint32 macTraits = [[face objectAtIndex:INDEX_FONT_TRAITS] unsignedIntValue]; + NSString *facename = [face objectAtIndex:INDEX_FONT_FACE_NAME]; + PRBool isStandardFace = PR_FALSE; + + if (needToCheckLightFaces && appKitWeight == kAppleExtraLightWeight) { + // if the facename contains UltraLight, set the weight to the ultralight weight value + NSRange range = [facename rangeOfString:@"ultralight" options:NSCaseInsensitiveSearch]; + if (range.location != NSNotFound) { + appKitWeight = kAppleUltraLightWeight; + } + } + + PRInt32 cssWeight = gfxMacPlatformFontList::AppleWeightToCSSWeight(appKitWeight) * 100; + + PR_LOG(gFontInfoLog, PR_LOG_DEBUG, ("(fontinit) family: %s, psname: %s, face: %s, apple-weight: %d, css-weight: %d, macTraits: %8.8x\n", + [family UTF8String], [psname UTF8String], [facename UTF8String], appKitWeight, cssWeight, macTraits)); + + // make a nsString + nsAutoString postscriptFontName; + GetStringForNSString(psname, postscriptFontName); + + if ([facename isEqualToString:@"Regular"] || + [facename isEqualToString:@"Bold"] || + [facename isEqualToString:@"Italic"] || + [facename isEqualToString:@"Oblique"] || + [facename isEqualToString:@"Bold Italic"] || + [facename isEqualToString:@"Bold Oblique"]) + { + isStandardFace = PR_TRUE; + } + + // create a font entry + MacOSFontEntry *fontEntry = new MacOSFontEntry(postscriptFontName, + cssWeight, this, isStandardFace); + if (!fontEntry) break; + + // set additional properties based on the traits reported by Cocoa + if (macTraits & (NSCondensedFontMask | NSNarrowFontMask | NSCompressedFontMask)) { + fontEntry->mStretch = NS_FONT_STRETCH_CONDENSED; + } else if (macTraits & NSExpandedFontMask) { + fontEntry->mStretch = NS_FONT_STRETCH_EXPANDED; + } + if (macTraits & NSItalicFontMask) { + fontEntry->mItalic = PR_TRUE; + } + if (macTraits & NSFixedPitchFontMask) { + fontEntry->mFixedPitch = PR_TRUE; + } + + // insert into font entry array of family + AddFontEntry(fontEntry); + } + + SortAvailableFonts(); + SetHasStyles(PR_TRUE); + + if (mIsBadUnderlineFamily) { + SetBadUnderlineFonts(); + } +} + +void +gfxMacFontFamily::EliminateDuplicateFaces() +{ + PRUint32 i, bold, numFonts, italicIndex; + MacOSFontEntry *italic, *nonitalic; + + FindStyleVariations(); + + // if normal and italic have the same ATS font ref, delete italic + // if bold and bold-italic have the same ATS font ref, delete bold-italic + + // two iterations, one for normal, one for bold + for (bold = 0; bold < 2; bold++) { + numFonts = mAvailableFonts.Length(); + + // find the non-italic face + nonitalic = nsnull; + for (i = 0; i < numFonts; i++) { + if ((mAvailableFonts[i]->IsBold() == (bold == 1)) && + !mAvailableFonts[i]->IsItalic()) { + nonitalic = static_cast(mAvailableFonts[i].get()); + break; + } + } + + // find the italic face + if (nonitalic) { + italic = nsnull; + for (i = 0; i < numFonts; i++) { + if ((mAvailableFonts[i]->IsBold() == (bold == 1)) && + mAvailableFonts[i]->IsItalic()) { + italic = static_cast(mAvailableFonts[i].get()); + italicIndex = i; + break; + } + } + + // if italic face and non-italic face have matching ATS refs, + // or if the italic returns 0 rather than an actual ATSFontRef, + // then the italic face is bogus so remove it + if (italic && (italic->GetFontRef() == 0 || + italic->GetFontRef() == nonitalic->GetFontRef())) { + mAvailableFonts.RemoveElementAt(italicIndex); + } + } + } +} + /* gfxSingleFaceMacFontFamily */ #pragma mark- @@ -371,7 +525,7 @@ gfxSingleFaceMacFontFamily::LocalizedName(nsAString& aLocalizedName) void gfxSingleFaceMacFontFamily::ReadOtherFamilyNames(AddOtherFamilyNameFunctor& aOtherFamilyFunctor) { - if (mOtherFamilyNamesInitialized) + if (mOtherFamilyNamesInitialized) return; mHasOtherFamilyNames = ReadOtherFamilyNamesForFace(aOtherFamilyFunctor, @@ -384,10 +538,9 @@ gfxSingleFaceMacFontFamily::ReadOtherFamilyNames(AddOtherFamilyNameFunctor& aOth /* gfxMacPlatformFontList */ #pragma mark- -gfxMacPlatformFontList::gfxMacPlatformFontList() +gfxMacPlatformFontList::gfxMacPlatformFontList() : + mATSGeneration(PRUint32(kATSGenerationInitial)) { - mATSGeneration = PRUint32(kATSGenerationInitial); - ::ATSFontNotificationSubscribe(ATSNotification, kATSFontNotifyOptionDefault, (void*)this, nsnull); @@ -395,26 +548,24 @@ gfxMacPlatformFontList::gfxMacPlatformFontList() // this should always be available (though we won't actually fail if it's missing, // we'll just end up doing a search and then caching the new result instead) mReplacementCharFallbackFamily = NS_LITERAL_STRING("Lucida Grande"); + + // cache this in a static variable so that MacOSFontFamily objects + // don't have to repeatedly look it up + sFontManager = [NSFontManager sharedFontManager]; } void gfxMacPlatformFontList::InitFontList() { ATSGeneration currentGeneration = ::ATSGetGeneration(); - + // need to ignore notifications after adding each font if (mATSGeneration == currentGeneration) return; mATSGeneration = currentGeneration; - PR_LOG(gFontInfoLog, PR_LOG_DEBUG, ("(fontinit) updating to generation: %d", mATSGeneration)); - - // Bug 420981 - under 10.5, UltraLight and Light have the same weight value - PRBool needToCheckLightFaces = PR_FALSE; - if (gfxPlatformMac::GetPlatform()->OSXVersion() >= MAC_OS_X_VERSION_10_5_HEX) { - needToCheckLightFaces = PR_TRUE; - } - + PR_LOG(gFontInfoLog, PR_LOG_DEBUG, ("(fontinit) updating to generation: %d", mATSGeneration)); + mFontFamilies.Clear(); mOtherFamilyNames.Clear(); mOtherFamilyNamesInitialized = PR_FALSE; @@ -423,84 +574,20 @@ gfxMacPlatformFontList::InitFontList() CancelLoader(); // iterate over available families - NSFontManager *fontManager = [NSFontManager sharedFontManager]; - NSEnumerator *families = [[fontManager availableFontFamilies] objectEnumerator]; // returns "canonical", non-localized family name + NSEnumerator *families = [[sFontManager availableFontFamilies] + objectEnumerator]; // returns "canonical", non-localized family name + + nsAutoString availableFamilyName; - nsAutoString availableFamilyName, postscriptFontName; - NSString *availableFamily = nil; while ((availableFamily = [families nextObject])) { // make a nsString GetStringForNSString(availableFamily, availableFamilyName); - + // create a family entry gfxFontFamily *familyEntry = new gfxMacFontFamily(availableFamilyName); if (!familyEntry) break; - - // create a font entry for each face - NSArray *fontfaces = [fontManager availableMembersOfFontFamily:availableFamily]; // returns an array of [psname, style name, weight, traits] elements, goofy api - int faceCount = [fontfaces count]; - int faceIndex; - - for (faceIndex = 0; faceIndex < faceCount; faceIndex++) { - NSArray *face = [fontfaces objectAtIndex:faceIndex]; - NSString *psname = [face objectAtIndex:INDEX_FONT_POSTSCRIPT_NAME]; - PRInt32 appKitWeight = [[face objectAtIndex:INDEX_FONT_WEIGHT] unsignedIntValue]; - PRUint32 macTraits = [[face objectAtIndex:INDEX_FONT_TRAITS] unsignedIntValue]; - NSString *facename = [face objectAtIndex:INDEX_FONT_FACE_NAME]; - PRBool isStandardFace = PR_FALSE; - - if (needToCheckLightFaces && appKitWeight == kAppleExtraLightWeight) { - // if the facename contains UltraLight, set the weight to the ultralight weight value - NSRange range = [facename rangeOfString:@"ultralight" options:NSCaseInsensitiveSearch]; - if (range.location != NSNotFound) { - appKitWeight = kAppleUltraLightWeight; - } - } - - PRInt32 cssWeight = gfxMacPlatformFontList::AppleWeightToCSSWeight(appKitWeight) * 100; - - PR_LOG(gFontInfoLog, PR_LOG_DEBUG, ("(fontinit) family: %s, psname: %s, face: %s, apple-weight: %d, css-weight: %d, macTraits: %8.8x\n", - [availableFamily UTF8String], [psname UTF8String], [facename UTF8String], appKitWeight, cssWeight, macTraits)); - - // make a nsString - GetStringForNSString(psname, postscriptFontName); - - if ([facename isEqualToString:@"Regular"] || - [facename isEqualToString:@"Bold"] || - [facename isEqualToString:@"Italic"] || - [facename isEqualToString:@"Oblique"] || - [facename isEqualToString:@"Bold Italic"] || - [facename isEqualToString:@"Bold Oblique"]) - { - isStandardFace = PR_TRUE; - } - - // create a font entry - MacOSFontEntry *fontEntry = new MacOSFontEntry(postscriptFontName, - cssWeight, familyEntry, isStandardFace); - if (!fontEntry) break; - - // set additional properties based on the traits reported by Cocoa - if (macTraits & (NSCondensedFontMask | NSNarrowFontMask | NSCompressedFontMask)) { - fontEntry->mStretch = NS_FONT_STRETCH_CONDENSED; - } else if (macTraits & NSExpandedFontMask) { - fontEntry->mStretch = NS_FONT_STRETCH_EXPANDED; - } - if (macTraits & NSItalicFontMask) { - fontEntry->mItalic = PR_TRUE; - } - if (macTraits & NSFixedPitchFontMask) { - fontEntry->mFixedPitch = PR_TRUE; - } - - // insert into font entry array of family - familyEntry->AddFontEntry(fontEntry); - } - - familyEntry->SortAvailableFonts(); - familyEntry->SetHasStyles(PR_TRUE); // add the family entry to the hash table ToLowerCase(availableFamilyName); @@ -509,7 +596,7 @@ gfxMacPlatformFontList::InitFontList() InitSingleFaceList(); - // to avoid full search of font name tables, seed the other names table with localized names from + // to avoid full search of font name tables, seed the other names table with localized names from // some of the prefs fonts which are accessed via their localized names. changes in the pref fonts will only cause // a font lookup miss earlier. this is a simple optimization, it's not required for correctness PreloadNamesList(); @@ -520,7 +607,7 @@ gfxMacPlatformFontList::InitFontList() // even though only bold faces exist so test for this using ATS font refs (10.5 has proper faces) EliminateDuplicateFaces(NS_LITERAL_STRING("Courier")); EliminateDuplicateFaces(NS_LITERAL_STRING("Helvetica")); - + // Cocoa reports that Courier and Monaco are not fixed-pitch fonts // so explicitly tweak these settings SetFixedPitch(NS_LITERAL_STRING("Courier")); @@ -534,7 +621,7 @@ gfxMacPlatformFontList::InitFontList() InitBadUnderlineList(); // start the delayed cmap loader - StartLoader(kDelayBeforeLoadingCmaps, kIntervalBetweenLoadingCmaps); + StartLoader(kDelayBeforeLoadingCmaps, kIntervalBetweenLoadingCmaps); } @@ -572,53 +659,14 @@ gfxMacPlatformFontList::InitSingleFaceList() } } -void +void gfxMacPlatformFontList::EliminateDuplicateFaces(const nsAString& aFamilyName) { - gfxFontFamily *family = FindFamily(aFamilyName); - if (!family) return; + gfxMacFontFamily *family = + static_cast(FindFamily(aFamilyName)); - nsTArray >& fontlist = family->GetFontList(); - - PRUint32 i, bold, numFonts, italicIndex; - MacOSFontEntry *italic, *nonitalic; - - // if normal and italic have the same ATS font ref, delete italic - // if bold and bold-italic have the same ATS font ref, delete bold-italic - - // two iterations, one for normal, one for bold - for (bold = 0; bold < 2; bold++) { - numFonts = fontlist.Length(); - - // find the non-italic face - nonitalic = nsnull; - for (i = 0; i < numFonts; i++) { - if ((fontlist[i]->IsBold() == (bold == 1)) && !fontlist[i]->IsItalic()) { - nonitalic = static_cast(fontlist[i].get()); - break; - } - } - - // find the italic face - if (nonitalic) { - italic = nsnull; - for (i = 0; i < numFonts; i++) { - if ((fontlist[i]->IsBold() == (bold == 1)) && fontlist[i]->IsItalic()) { - italic = static_cast(fontlist[i].get()); - italicIndex = i; - break; - } - } - - // if italic face and non-italic face have matching ATS refs, - // or if the italic returns 0 rather than an actual ATSFontRef, - // then the italic face is bogus so remove it - if (italic && (italic->GetFontRef() == 0 || - italic->GetFontRef() == nonitalic->GetFontRef())) { - fontlist.RemoveElementAt(italicIndex); - } - } - } + if (family) + family->EliminateDuplicateFaces(); } PRBool @@ -686,7 +734,7 @@ gfxMacPlatformFontList::GetDefaultFont(const gfxFontStyle* aStyle, PRBool& aNeed return FindFontForFamily(familyName, aStyle, aNeedsBold); } -PRInt32 +PRInt32 gfxMacPlatformFontList::AppleWeightToCSSWeight(PRInt32 aAppleWeight) { if (aAppleWeight < 1) @@ -696,22 +744,22 @@ gfxMacPlatformFontList::AppleWeightToCSSWeight(PRInt32 aAppleWeight) return gAppleWeightToCSSWeight[aAppleWeight]; } -gfxFontEntry* +gfxFontEntry* gfxMacPlatformFontList::LookupLocalFont(const gfxProxyFontEntry *aProxyEntry, const nsAString& aFontName) { NSString *faceName = GetNSStringForString(aFontName); - + // first lookup a single face based on postscript name - ATSFontRef fontRef = ::ATSFontFindFromPostScriptName(CFStringRef(faceName), + ATSFontRef fontRef = ::ATSFontFindFromPostScriptName(CFStringRef(faceName), kATSOptionFlagsDefault); // if not found, lookup using full font name if (fontRef == kInvalidFont) - fontRef = ::ATSFontFindFromName(CFStringRef(faceName), + fontRef = ::ATSFontFindFromName(CFStringRef(faceName), kATSOptionFlagsDefault); - - // not found + + // not found if (fontRef == kInvalidFont) return nsnull; @@ -722,7 +770,7 @@ gfxMacPlatformFontList::LookupLocalFont(const gfxProxyFontEntry *aProxyEntry, newFontEntry = new MacOSFontEntry(aFontName, fontRef, - w, aProxyEntry->mStretch, + w, aProxyEntry->mStretch, aProxyEntry->mItalic ? FONT_STYLE_ITALIC : FONT_STYLE_NORMAL, nsnull); @@ -760,13 +808,13 @@ public: ATSFontContainerRef mContainerRef; }; -gfxFontEntry* +gfxFontEntry* gfxMacPlatformFontList::MakePlatformFont(const gfxFontEntry *aProxyEntry, const PRUint8 *aFontData, PRUint32 aLength) { OSStatus err; - + NS_ASSERTION(aFontData, "MakePlatformFont called with null data"); ATSFontRef fontRef; @@ -780,41 +828,41 @@ gfxMacPlatformFontList::MakePlatformFont(const gfxFontEntry *aProxyEntry, err = ::ATSFontActivateFromMemory(const_cast(aFontData), aLength, kPrivateATSFontContextPrivate, kATSFontFormatUnspecified, - NULL, - kATSOptionFlagsDoNotNotify, + NULL, + kATSOptionFlagsDoNotNotify, &containerRef); mATSGeneration = ::ATSGetGeneration(); if (err != noErr) { #if DEBUG char warnBuf[1024]; - const gfxProxyFontEntry *proxyEntry = + const gfxProxyFontEntry *proxyEntry = static_cast (aProxyEntry); sprintf(warnBuf, "downloaded font error, ATSFontActivateFromMemory err: %d for (%s)", PRInt32(err), NS_ConvertUTF16toUTF8(proxyEntry->mFamily->Name()).get()); NS_WARNING(warnBuf); -#endif +#endif return nsnull; } // ignoring containers with multiple fonts, use the first face only for now - err = ::ATSFontFindFromContainer(containerRef, kATSOptionFlagsDefault, 1, + err = ::ATSFontFindFromContainer(containerRef, kATSOptionFlagsDefault, 1, &fontRef, NULL); if (err != noErr) { #if DEBUG char warnBuf[1024]; - const gfxProxyFontEntry *proxyEntry = + const gfxProxyFontEntry *proxyEntry = static_cast (aProxyEntry); sprintf(warnBuf, "downloaded font error, ATSFontFindFromContainer err: %d for (%s)", PRInt32(err), NS_ConvertUTF16toUTF8(proxyEntry->mFamily->Name()).get()); NS_WARNING(warnBuf); -#endif +#endif ::ATSFontDeactivate(containerRef, NULL, kATSOptionFlagsDefault); return nsnull; } - + // now lookup the Postscript name; this may fail if the font cache is bad OSStatus err; NSString *psname = NULL; @@ -824,7 +872,7 @@ gfxMacPlatformFontList::MakePlatformFont(const gfxFontEntry *aProxyEntry, } else { #ifdef DEBUG char warnBuf[1024]; - const gfxProxyFontEntry *proxyEntry = + const gfxProxyFontEntry *proxyEntry = static_cast (aProxyEntry); sprintf(warnBuf, "ATSFontGetPostScriptName err = %d for (%s), retries = %d", (PRInt32)err, NS_ConvertUTF16toUTF8(proxyEntry->mFamily->Name()).get(), retryCount); @@ -855,13 +903,13 @@ gfxMacPlatformFontList::MakePlatformFont(const gfxFontEntry *aProxyEntry, delete userFontData; return nsnull; } - - MacOSFontEntry *newFontEntry = + + MacOSFontEntry *newFontEntry = new MacOSFontEntry(uniqueName, fontRef, - w, aProxyEntry->mStretch, + w, aProxyEntry->mStretch, aProxyEntry->mItalic ? - FONT_STYLE_ITALIC : FONT_STYLE_NORMAL, + FONT_STYLE_ITALIC : FONT_STYLE_NORMAL, userFontData); if (!newFontEntry) { @@ -876,12 +924,12 @@ gfxMacPlatformFontList::MakePlatformFont(const gfxFontEntry *aProxyEntry, // if something is funky about this font, delete immediately #if DEBUG char warnBuf[1024]; - const gfxProxyFontEntry *proxyEntry = + const gfxProxyFontEntry *proxyEntry = static_cast (aProxyEntry); - sprintf(warnBuf, "downloaded font not loaded properly, removed face for (%s)", + sprintf(warnBuf, "downloaded font not loaded properly, removed face for (%s)", NS_ConvertUTF16toUTF8(proxyEntry->mFamily->Name()).get()); NS_WARNING(warnBuf); -#endif +#endif delete newFontEntry; // We don't retry from here; the ATS font cache issue would have caused failure earlier diff --git a/gfx/thebes/src/gfxPangoFonts.cpp b/gfx/thebes/src/gfxPangoFonts.cpp index 8090ffb6a088..d89ec58c2448 100644 --- a/gfx/thebes/src/gfxPangoFonts.cpp +++ b/gfx/thebes/src/gfxPangoFonts.cpp @@ -1948,6 +1948,7 @@ gfxPangoFontGroup::UpdateFontList() mFonts[0] = NULL; mFontSets.Clear(); + mUnderlineOffset = UNDERLINE_OFFSET_NOT_SET; mCurrGeneration = newGeneration; } diff --git a/gfx/thebes/src/gfxPlatformFontList.cpp b/gfx/thebes/src/gfxPlatformFontList.cpp index 084e5dae629d..f0446bdd3c68 100644 --- a/gfx/thebes/src/gfxPlatformFontList.cpp +++ b/gfx/thebes/src/gfxPlatformFontList.cpp @@ -191,6 +191,7 @@ gfxPlatformFontList::SetFixedPitch(const nsAString& aFamilyName) gfxFontFamily *family = FindFamily(aFamilyName); if (!family) return; + family->FindStyleVariations(); nsTArray >& fontlist = family->GetFontList(); PRUint32 i, numFonts = fontlist.Length(); @@ -213,7 +214,7 @@ gfxPlatformFontList::InitBadUnderlineList() gfxFontFamily *familyEntry = mFontFamilies.GetWeak(key, &found); if (familyEntry) - familyEntry->SetBadUnderlineFont(PR_TRUE); + familyEntry->SetBadUnderlineFamily(); } } @@ -430,17 +431,21 @@ gfxPlatformFontList::RunLoader() PRUint32 i, endIndex = (mStartIndex + mIncrement < mNumFamilies ? mStartIndex + mIncrement : mNumFamilies); // for each font family, load in various font info + AddOtherFamilyNameFunctor addOtherNames(this); for (i = mStartIndex; i < endIndex; i++) { - AddOtherFamilyNameFunctor addOtherNames(this); + gfxFontFamily* familyEntry = mFontFamiliesToLoad[i]; - // load the cmap - mFontFamiliesToLoad[i]->ReadCMAP(); + // find all faces that are members of this family + familyEntry->FindStyleVariations(); + + // load the cmaps + familyEntry->ReadCMAP(); // read in other family names - mFontFamiliesToLoad[i]->ReadOtherFamilyNames(addOtherNames); + familyEntry->ReadOtherFamilyNames(addOtherNames); // check whether the family can be considered "simple" for style matching - mFontFamiliesToLoad[i]->CheckForSimpleFamily(); + familyEntry->CheckForSimpleFamily(); } mStartIndex += mIncrement; diff --git a/gfx/thebes/src/gfxXlibSurface.cpp b/gfx/thebes/src/gfxXlibSurface.cpp index dc2a19f6b9f6..356acf1732b5 100644 --- a/gfx/thebes/src/gfxXlibSurface.cpp +++ b/gfx/thebes/src/gfxXlibSurface.cpp @@ -71,7 +71,7 @@ gfxXlibSurface::gfxXlibSurface(Display *dpy, Drawable drawable, Visual *visual, Init(surf); } -gfxXlibSurface::gfxXlibSurface(Display *dpy, Visual *visual, const gfxIntSize& size) +gfxXlibSurface::gfxXlibSurface(Display *dpy, Visual *visual, const gfxIntSize& size, int depth) : mPixmapTaken(PR_FALSE), mDisplay(dpy), mSize(size) { @@ -81,7 +81,7 @@ gfxXlibSurface::gfxXlibSurface(Display *dpy, Visual *visual, const gfxIntSize& s mDrawable = (Drawable)XCreatePixmap(dpy, RootWindow(dpy, DefaultScreen(dpy)), mSize.width, mSize.height, - DefaultDepth(dpy, DefaultScreen(dpy))); + depth ? depth : DefaultDepth(dpy, DefaultScreen(dpy))); cairo_surface_t *surf = cairo_xlib_surface_create(dpy, mDrawable, visual, mSize.width, mSize.height); diff --git a/js/src/build/autoconf/config.sub b/js/src/build/autoconf/config.sub index 8ca084bf3340..724382959124 100755 --- a/js/src/build/autoconf/config.sub +++ b/js/src/build/autoconf/config.sub @@ -4,7 +4,7 @@ # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 # Free Software Foundation, Inc. -timestamp='2009-08-19' +timestamp='2009-12-04' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software @@ -126,7 +126,7 @@ case $maybe_os in nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ kopensolaris*-gnu* | \ - storm-chaos* | os2-emx* | rtmk-nova*) + storm-chaos* | os2-emx* | rtmk-nova* | wince-winmo*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; @@ -1296,7 +1296,7 @@ case $os in | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ - | -skyos* | -haiku* | -rdos* | -toppers* | -drops*) + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -winmo*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) @@ -1338,6 +1338,9 @@ case $os in -os400*) os=-os400 ;; + -wince-winmo*) + os=-wince-winmo + ;; -wince*) os=-wince ;; diff --git a/js/src/config/rules.mk b/js/src/config/rules.mk index 2c38fe37b0ee..c022b082d63a 100644 --- a/js/src/config/rules.mk +++ b/js/src/config/rules.mk @@ -699,7 +699,7 @@ ifneq (,$(filter WINCE,$(OS_ARCH))) OUTOPTION = -Fo# eol endif -ifeq ($(OS_TARGET), WINCE) +ifeq ($(OS_ARCH), WINCE) OUTOPTION = -Fo# eol HOST_OUTOPTION = -Fo# eol else diff --git a/js/src/configure.in b/js/src/configure.in index 3ffead04a3d7..4b2d97873708 100644 --- a/js/src/configure.in +++ b/js/src/configure.in @@ -417,7 +417,7 @@ fi dnl Special win32 checks dnl ======================================================== case "$target" in -*-wince) +*-wince|*-winmo) WINVER=500 ;; *) @@ -430,7 +430,7 @@ case "$target" in esac case "$target" in -*-cygwin*|*-mingw*|*-msvc*|*-mks*|*-wince) +*-cygwin*|*-mingw*|*-msvc*|*-mks*|*-wince|*-winmo) if test "$GCC" != "yes"; then # Check to see if we are really running in a msvc environemnt _WIN32_MSVC=1 @@ -605,7 +605,7 @@ if test -n "$_WIN32_MSVC"; then AC_DEFINE(JS_HAVE___INTN) case "$target" in - *-wince) + *-wince|*-winmo) AC_DEFINE(HAVE_SYSTEMTIMETOFILETIME) AC_DEFINE(JS_CRTDEFS_H_HAS_INTPTR_T) ;; @@ -905,6 +905,7 @@ if test -n "$CROSS_COMPILE"; then solaris*) OS_ARCH=SunOS OS_RELEASE=5 ;; mingw*) OS_ARCH=WINNT ;; wince*) OS_ARCH=WINCE ;; + winmo*) OS_ARCH=WINCE ;; darwin*) OS_ARCH=Darwin OS_TARGET=Darwin ;; esac else @@ -1116,7 +1117,11 @@ UnixWare) WINCE) WINCE=1 OS_ARCH=WINCE - OS_TARGET=WINCE + if test "$WINCE_WINDOWS_MOBILE"; then + OS_TARGET=WINMO + else + OS_TARGET=WINCE + fi ;; Darwin) case "${target_cpu}" in @@ -1172,7 +1177,7 @@ x86_64 | ia64) ;; arm) - if test "$OS_TARGET" = "WINCE"; then + if test "$OS_ARCH" = "WINCE"; then CPU_ARCH="$OS_TEST" fi ;; @@ -1451,7 +1456,7 @@ case "$host" in HOST_OPTIMIZE_FLAGS="${HOST_OPTIMIZE_FLAGS=-O3}" ;; -*cygwin*|*mingw*|*mks*|*msvc*|*wince) +*cygwin*|*mingw*|*mks*|*msvc*|*wince|*winmo) if test -n "$_WIN32_MSVC"; then HOST_AR=lib HOST_AR_FLAGS='-NOLOGO -OUT:"$@"' @@ -1790,7 +1795,7 @@ case "$target" in esac ;; -*-wince*) +*-wince*|*-winmo*) TARGET_COMPILER_ABI=msvc MOZ_TOOLS_DIR=`echo $MOZ_TOOLS` AR_LIST="$AR -list" @@ -2421,7 +2426,7 @@ case "$target" in *-openvms*) NO_LD_ARCHIVE_FLAGS= ;; -*-msvc*|*-mks*|*-mingw*|*-cygwin*|*-wince) +*-msvc*|*-mks*|*-mingw*|*-cygwin*|*-wince|*-winmo) if test -z "$GNU_CC"; then NO_LD_ARCHIVE_FLAGS= fi @@ -2464,7 +2469,7 @@ case "$target" in *-darwin*) MOZ_COMPONENTS_VERSION_SCRIPT_LDFLAGS='-Wl,-exported_symbols_list -Wl,$(BUILD_TOOLS)/gnu-ld-scripts/components-export-list' ;; - *-cygwin*|*-mingw*|*-mks*|*-msvc|*-wince) + *-cygwin*|*-mingw*|*-mks*|*-msvc|*-wince|*-winmo) if test -n "$GNU_CC"; then MOZ_COMPONENTS_VERSION_SCRIPT_LDFLAGS='-Wl,--version-script,$(BUILD_TOOLS)/gnu-ld-scripts/components-version-script' fi @@ -2536,7 +2541,7 @@ solaris*) freebsd*|kfreebsd*) AC_DEFINE(AVMPLUS_UNIX) ;; -*cygwin*|*mingw*|*mks*|*msvc*|*wince) +*cygwin*|*mingw*|*mks*|*msvc*|*wince|*winmo) AC_DEFINE(AVMPLUS_WIN32) ;; *os2*) @@ -3248,7 +3253,7 @@ if test "$ac_cv_func_gnu_get_libc_version" = "yes"; then fi case $target_os in - os2*|msvc*|mks*|cygwin*|mingw*|darwin*|wince*|beos*) + os2*|msvc*|mks*|cygwin*|mingw*|darwin*|wince*|winmo*|beos*) ;; *) @@ -3987,7 +3992,7 @@ MOZ_DEBUG_ENABLE_DEFS="-DDEBUG -D_DEBUG" beos*) MOZ_DEBUG_ENABLE_DEFS="$MOZ_DEBUG_ENABLE_DEFS -DDEBUG_${USER}" ;; - msvc*|mks*|cygwin*|mingw*|os2*|wince*) + msvc*|mks*|cygwin*|mingw*|os2*|wince*|winmo*) MOZ_DEBUG_ENABLE_DEFS="$MOZ_DEBUG_ENABLE_DEFS -DDEBUG_`echo ${USERNAME} | sed -e 's| |_|g'`" ;; *) @@ -4173,7 +4178,7 @@ if test "$MOZ_MEMORY"; then AC_DEFINE(MOZ_MEMORY_WINDOWS) # the interesting bits will get passed down in MOZ_MEMORY_LDFLAGS ;; - *wince) + *wince|*winmo) AC_DEFINE(MOZ_MEMORY_WINCE) AC_DEFINE(MOZ_MEMORY_WINDOWS) ;; @@ -4792,7 +4797,7 @@ EDITLINE_LIBS= JS_DISABLE_SHELL= case "$target" in -*-wince*|*-mingw*|*-cygwin*|*-msvc*|*-mks*) +*-wince*|*-winmo*|*-mingw*|*-cygwin*|*-msvc*|*-mks*) NO_EDITLINE=1 ;; *-symbian*) diff --git a/js/src/jsapi-tests/Makefile.in b/js/src/jsapi-tests/Makefile.in index 341ecec27abb..48ff8baa141a 100644 --- a/js/src/jsapi-tests/Makefile.in +++ b/js/src/jsapi-tests/Makefile.in @@ -51,6 +51,7 @@ CPPSRCS = \ testContexts.cpp \ testDebugger.cpp \ testDefineGetterSetterNonEnumerable.cpp \ + testExtendedEq.cpp \ testIntString.cpp \ testLookup.cpp \ testPropCache.cpp \ diff --git a/js/src/jsapi-tests/testExtendedEq.cpp b/js/src/jsapi-tests/testExtendedEq.cpp new file mode 100644 index 000000000000..649c0cd630b1 --- /dev/null +++ b/js/src/jsapi-tests/testExtendedEq.cpp @@ -0,0 +1,45 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * vim: set ts=4 sw=4 et tw=99: + * + * This tests user-specified (via JSExtendedClass) equality operations on + * trace. + */ + +#include "tests.h" + +static JSBool +my_Equality(JSContext *cx, JSObject *obj, jsval v, JSBool *bp) +{ + *bp = JS_TRUE; + return JS_TRUE; +} + +JSExtendedClass TestExtendedEq_JSClass = { + { "TestExtendedEq", + JSCLASS_IS_EXTENDED, + JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, + JS_EnumerateStub, JS_ResolveStub, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL + }, + // JSExtendedClass initialization + my_Equality, + NULL, NULL, NULL, NULL, JSCLASS_NO_RESERVED_MEMBERS +}; + +BEGIN_TEST(testExtendedEq_bug530489) +{ + JSClass *clasp = (JSClass *) &TestExtendedEq_JSClass; + + JSObject *global = JS_GetGlobalObject(cx); + JS_InitClass(cx, global, global, clasp, NULL, 0, NULL, NULL, NULL, NULL); + + JS_DefineObject(cx, global, "obj1", clasp, NULL, 0); + JS_DefineObject(cx, global, "obj2", clasp, NULL, 0); + + jsval v; + EVAL("(function() { var r; for (var i = 0; i < 10; ++i) r = obj1 == obj2; return r; })()", &v); + CHECK_SAME(v, JSVAL_TRUE); + return true; +} +END_TEST(testExtendedEq_bug530489) diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index 61a26a382e9c..4f86761630ab 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -1216,6 +1216,7 @@ JS_GetGlobalObject(JSContext *cx) JS_PUBLIC_API(void) JS_SetGlobalObject(JSContext *cx, JSObject *obj) { + CHECK_REQUEST(cx); cx->globalObject = obj; #if JS_HAS_XML_SUPPORT @@ -1618,15 +1619,11 @@ JS_ResolveStandardClass(JSContext *cx, JSObject *obj, jsval id, static JSBool AlreadyHasOwnProperty(JSContext *cx, JSObject *obj, JSAtom *atom) { - JSScopeProperty *sprop; - JSScope *scope; - - JS_ASSERT(OBJ_IS_NATIVE(obj)); JS_LOCK_OBJ(cx, obj); - scope = OBJ_SCOPE(obj); - sprop = scope->lookup(ATOM_TO_JSID(atom)); + JSScope *scope = OBJ_SCOPE(obj); + bool found = scope->hasProperty(ATOM_TO_JSID(atom)); JS_UNLOCK_SCOPE(cx, scope); - return sprop != NULL; + return found; } JS_PUBLIC_API(JSBool) @@ -3402,7 +3399,7 @@ AlreadyHasOwnPropertyHelper(JSContext *cx, JSObject *obj, jsid id, JS_LOCK_OBJ(cx, obj); scope = OBJ_SCOPE(obj); - *foundp = (scope->lookup(id) != NULL); + *foundp = scope->hasProperty(id); JS_UNLOCK_SCOPE(cx, scope); return JS_TRUE; } @@ -4086,7 +4083,7 @@ JS_NewPropertyIterator(JSContext *cx, JSObject *obj) if (OBJ_IS_NATIVE(obj)) { /* Native case: start with the last property in obj's own scope. */ scope = OBJ_SCOPE(obj); - pdata = scope->lastProp; + pdata = scope->lastProperty(); index = -1; } else { /* @@ -4129,15 +4126,12 @@ JS_NextProperty(JSContext *cx, JSObject *iterobj, jsid *idp) /* * If the next property mapped by scope in the property tree ancestor - * line is not enumerable, or it's an alias, or one or more properties - * were deleted from the "middle" of the scope-mapped ancestor line - * and the next property was among those deleted, skip it and keep on - * trying to find an enumerable property that is still in scope. + * line is not enumerable, or it's an alias, skip it and keep on trying + * to find an enumerable property that is still in scope. */ while (sprop && (!(sprop->attrs & JSPROP_ENUMERATE) || - (sprop->flags & SPROP_IS_ALIAS) || - (scope->hadMiddleDelete() && !scope->has(sprop)))) { + (sprop->flags & SPROP_IS_ALIAS))) { sprop = sprop->parent; } diff --git a/js/src/jsarray.cpp b/js/src/jsarray.cpp index 974aca10507d..935423886560 100644 --- a/js/src/jsarray.cpp +++ b/js/src/jsarray.cpp @@ -1327,8 +1327,8 @@ js_MakeArraySlow(JSContext *cx, JSObject *obj) continue; } - sprop = scope->add(cx, id, NULL, NULL, i + JS_INITIAL_NSLOTS, - JSPROP_ENUMERATE, 0, 0); + sprop = scope->addDataProperty(cx, id, JS_INITIAL_NSLOTS + i, + JSPROP_ENUMERATE); if (!sprop) goto out_bad; } diff --git a/js/src/jsatom.cpp b/js/src/jsatom.cpp index 6b6eaf953b33..8ccbfde0a8ee 100644 --- a/js/src/jsatom.cpp +++ b/js/src/jsatom.cpp @@ -748,7 +748,7 @@ js_AtomizeString(JSContext *cx, JSString *str, uintN flags) if (!key) return NULL; } - } else { + } else { JS_ASSERT(str->isDependent()); if (!js_UndependString(cx, str)) return NULL; diff --git a/js/src/jsbuiltins.cpp b/js/src/jsbuiltins.cpp index 8b03f748ab81..717aac0120c0 100644 --- a/js/src/jsbuiltins.cpp +++ b/js/src/jsbuiltins.cpp @@ -209,7 +209,7 @@ js_StringToInt32(JSContext* cx, JSString* str) const jschar* end; const jschar* ep; jsdouble d; - + if (str->length() == 1) { jschar c = str->chars()[0]; if ('0' <= c && c <= '9') @@ -231,21 +231,22 @@ JS_DEFINE_CALLINFO_2(extern, INT32, js_StringToInt32, CONTEXT, STRING, 1, 1) JSBool FASTCALL js_AddProperty(JSContext* cx, JSObject* obj, JSScopeProperty* sprop) { - JS_ASSERT(OBJ_IS_NATIVE(obj)); JS_LOCK_OBJ(cx, obj); + uint32 slot = sprop->slot; JSScope* scope = OBJ_SCOPE(obj); - uint32 slot; + JS_ASSERT(slot == scope->freeslot); + JS_ASSERT(sprop->parent == scope->lastProperty()); + if (scope->owned()) { - JS_ASSERT(!scope->has(sprop)); + JS_ASSERT(!scope->hasProperty(sprop)); } else { scope = js_GetMutableScope(cx, obj); if (!scope) goto exit_trace; } - slot = sprop->slot; - if (!scope->table && sprop->parent == scope->lastProp && slot == scope->freeslot) { + if (!scope->table) { if (slot < STOBJ_NSLOTS(obj) && !OBJ_GET_CLASS(cx, obj)->reserveSlots) { JS_ASSERT(JSVAL_IS_VOID(STOBJ_GET_SLOT(obj, scope->freeslot))); ++scope->freeslot; @@ -261,10 +262,9 @@ js_AddProperty(JSContext* cx, JSObject* obj, JSScopeProperty* sprop) scope->extend(cx, sprop); } else { - JSScopeProperty *sprop2 = scope->add(cx, sprop->id, - sprop->getter, sprop->setter, - SPROP_INVALID_SLOT, sprop->attrs, - sprop->flags, sprop->shortid); + JSScopeProperty *sprop2 = + scope->addProperty(cx, sprop->id, sprop->getter, sprop->setter, SPROP_INVALID_SLOT, + sprop->attrs, sprop->flags, sprop->shortid); if (sprop2 != sprop) goto exit_trace; } @@ -400,11 +400,13 @@ js_PopInterpFrame(JSContext* cx, InterpState* state) return JS_FALSE; if (cx->fp->imacpc) return JS_FALSE; + + cx->fp->putActivationObjects(cx); /* Update display table. */ if (cx->fp->script->staticLevel < JS_DISPLAY_SIZE) cx->display[cx->fp->script->staticLevel] = cx->fp->displaySave; - + /* Pop the frame and its memory. */ cx->fp = cx->fp->down; JS_ASSERT(cx->fp->regs == &ifp->callerRegs); diff --git a/js/src/jscntxt.h b/js/src/jscntxt.h index 830024b47dbe..978f8723873d 100644 --- a/js/src/jscntxt.h +++ b/js/src/jscntxt.h @@ -820,7 +820,7 @@ struct JSRuntime { JSBasicStats loopStats; #endif -#if defined DEBUG || defined JS_DUMP_PROPTREE_STATS +#ifdef DEBUG /* Function invocation metering. */ jsrefcount inlineCalls; jsrefcount nativeCalls; @@ -842,7 +842,6 @@ struct JSRuntime { jsrefcount duplicatePropTreeNodes; jsrefcount totalPropTreeNodes; jsrefcount propTreeKidsChunks; - jsrefcount middleDeleteFixups; /* String instrumentation. */ jsrefcount liveStrings; @@ -860,7 +859,7 @@ struct JSRuntime { jsrefcount totalScripts; jsrefcount liveEmptyScripts; jsrefcount totalEmptyScripts; -#endif /* DEBUG || JS_DUMP_PROPTREE_STATS */ +#endif /* DEBUG */ #ifdef JS_SCOPE_DEPTH_METER /* diff --git a/js/src/jsdbgapi.cpp b/js/src/jsdbgapi.cpp index 0da2bab11ed3..bb25c4492745 100644 --- a/js/src/jsdbgapi.cpp +++ b/js/src/jsdbgapi.cpp @@ -64,6 +64,7 @@ #include "jsstr.h" #include "jsatominlines.h" +#include "jsscopeinlines.h" #include "jsautooplen.h" @@ -422,13 +423,16 @@ typedef struct JSWatchPoint { #define JSWP_LIVE 0x1 /* live because set and not cleared */ #define JSWP_HELD 0x2 /* held while running handler/setter */ +static bool +IsWatchedProperty(JSContext *cx, JSScopeProperty *sprop); + /* * NB: DropWatchPointAndUnlock releases cx->runtime->debuggerLock in all cases. */ static JSBool DropWatchPointAndUnlock(JSContext *cx, JSWatchPoint *wp, uintN flag) { - JSBool ok, found; + JSBool ok; JSScopeProperty *sprop; JSScope *scope; JSPropertyOp setter; @@ -459,20 +463,22 @@ DropWatchPointAndUnlock(JSContext *cx, JSWatchPoint *wp, uintN flag) if (!setter) { JS_LOCK_OBJ(cx, wp->object); scope = OBJ_SCOPE(wp->object); - found = (scope->lookup(sprop->id) != NULL); - JS_UNLOCK_SCOPE(cx, scope); /* - * If the property wasn't found on wp->object or didn't exist, then - * someone else has dealt with this sprop, and we don't need to change - * the property attributes. + * If the property wasn't found on wp->object, or it isn't still being + * watched, then someone else must have deleted or unwatched it, and we + * don't need to change the property attributes. */ - if (found) { - sprop = scope->change(cx, sprop, 0, sprop->attrs, - sprop->getter, wp->setter); + JSScopeProperty *wprop = scope->lookup(sprop->id); + if (wprop && + ((wprop->attrs ^ sprop->attrs) & JSPROP_SETTER) == 0 && + IsWatchedProperty(cx, wprop)) { + sprop = scope->changeProperty(cx, wprop, 0, wprop->attrs, + wprop->getter, wp->setter); if (!sprop) ok = JS_FALSE; } + JS_UNLOCK_SCOPE(cx, scope); } cx->free(wp); @@ -762,6 +768,18 @@ js_watch_set_wrapper(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, return js_watch_set(cx, obj, userid, rval); } +static bool +IsWatchedProperty(JSContext *cx, JSScopeProperty *sprop) +{ + if (sprop->attrs & JSPROP_SETTER) { + JSObject *funobj = js_CastAsObject(sprop->setter); + JSFunction *fun = GET_FUNCTION_PRIVATE(cx, funobj); + + return FUN_NATIVE(fun) == js_watch_set_wrapper; + } + return sprop->setter == js_watch_set; +} + JSPropertyOp js_WrapWatchedSetter(JSContext *cx, jsid id, uintN attrs, JSPropertyOp setter) { @@ -1218,7 +1236,7 @@ JS_GetFrameThis(JSContext *cx, JSStackFrame *fp) afp = NULL; } - if (JSVAL_IS_NULL(fp->thisv) && fp->argv) + if (fp->argv) fp->thisv = OBJECT_TO_JSVAL(js_ComputeThis(cx, JS_TRUE, fp->argv)); if (afp) { @@ -1432,16 +1450,7 @@ JS_PropertyIterator(JSObject *obj, JSScopeProperty **iteratorp) scope = OBJ_SCOPE(obj); /* XXXbe minor(?) incompatibility: iterate in reverse definition order */ - if (!sprop) { - sprop = SCOPE_LAST_PROP(scope); - } else { - while ((sprop = sprop->parent) != NULL) { - if (!scope->hadMiddleDelete()) - break; - if (scope->has(sprop)) - break; - } - } + sprop = sprop ? sprop->parent : scope->lastProperty(); *iteratorp = sprop; return sprop; } @@ -1490,7 +1499,7 @@ JS_GetPropertyDesc(JSContext *cx, JSObject *obj, JSScopeProperty *sprop, JSScope *scope = OBJ_SCOPE(obj); if (SPROP_HAS_VALID_SLOT(sprop, scope)) { JSScopeProperty *aprop; - for (aprop = SCOPE_LAST_PROP(scope); aprop; aprop = aprop->parent) { + for (aprop = scope->lastProperty(); aprop; aprop = aprop->parent) { if (aprop != sprop && aprop->slot == sprop->slot) { pd->alias = ID_TO_VALUE(aprop->id); break; @@ -1531,9 +1540,7 @@ JS_GetPropertyDescArray(JSContext *cx, JSObject *obj, JSPropertyDescArray *pda) if (!pd) return JS_FALSE; i = 0; - for (sprop = SCOPE_LAST_PROP(scope); sprop; sprop = sprop->parent) { - if (scope->hadMiddleDelete() && !scope->has(sprop)) - continue; + for (sprop = scope->lastProperty(); sprop; sprop = sprop->parent) { if (!js_AddRoot(cx, &pd[i].id, NULL)) goto bad; if (!js_AddRoot(cx, &pd[i].value, NULL)) diff --git a/js/src/jsemit.h b/js/src/jsemit.h index b94dcdcc5703..5593ce0e1a3b 100644 --- a/js/src/jsemit.h +++ b/js/src/jsemit.h @@ -257,7 +257,6 @@ struct JSTreeContext { /* tree context for semantic checks */ #define TCF_NO_SCRIPT_RVAL 0x4000 /* API caller does not want result value from global script */ #define TCF_HAS_SHARPS 0x8000 /* source contains sharp defs or uses */ -#define TCF_FUN_PARAM_EVAL 0x10000 /* function has parameter named 'eval' */ /* * Set when parsing a declaration-like destructuring pattern. This @@ -286,7 +285,10 @@ struct JSTreeContext { /* tree context for semantic checks */ * the use of 'with'. See also TSF_STRICT_MODE_CODE, * JSScript::strictModeCode, and JSREPORT_STRICT_ERROR. */ -#define TCF_STRICT_MODE_CODE 0x40000 +#define TCF_STRICT_MODE_CODE 0x40000 + +/* Function has parameter named 'eval'. */ +#define TCF_FUN_PARAM_EVAL 0x80000 /* * Flags to propagate out of the blocks. diff --git a/js/src/jsfun.h b/js/src/jsfun.h index 5b44391237a9..77c49be8cdba 100644 --- a/js/src/jsfun.h +++ b/js/src/jsfun.h @@ -207,6 +207,7 @@ struct JSFunction : public JSObject { extern JSClass js_ArgumentsClass; extern JS_FRIEND_DATA(JSClass) js_CallClass; extern JSClass js_DeclEnvClass; +extern const uint32 CALL_CLASS_FIXED_RESERVED_SLOTS; /* JS_FRIEND_DATA so that VALUE_IS_FUNCTION is callable from the shell. */ extern JS_FRIEND_DATA(JSClass) js_FunctionClass; diff --git a/js/src/jsinterp.cpp b/js/src/jsinterp.cpp index 925f3e41f217..a87fdef75a0e 100644 --- a/js/src/jsinterp.cpp +++ b/js/src/jsinterp.cpp @@ -122,7 +122,7 @@ js_FillPropertyCache(JSContext *cx, JSObject *obj, * from pobj's scope (via unwatch or delete, e.g.). */ scope = OBJ_SCOPE(pobj); - if (!scope->has(sprop)) { + if (!scope->hasProperty(sprop)) { PCMETER(cache->oddfills++); return JS_NO_PROP_CACHE_FILL; } @@ -132,8 +132,8 @@ js_FillPropertyCache(JSContext *cx, JSObject *obj, * and setter hooks can change the prototype chain using JS_SetPrototype * after js_LookupPropertyWithFlags has returned the nominal protoIndex, * we have to validate protoIndex if it is non-zero. If it is zero, then - * we know thanks to the scope->has test above, combined with the fact that - * obj == pobj, that protoIndex is invariant. + * we know thanks to the scope->hasProperty test above, combined with the + * fact that obj == pobj, that protoIndex is invariant. * * The scopeIndex can't be wrong. We require JS_SetParent calls to happen * before any running script might consult a parent-linked scope chain. If @@ -251,7 +251,7 @@ js_FillPropertyCache(JSContext *cx, JSObject *obj, /* Best we can do is to cache sprop (still a nice speedup). */ vword = SPROP_TO_PCVAL(sprop); if (adding && - sprop == scope->lastProp && + sprop == scope->lastProperty() && scope->shape == sprop->shape) { /* * Our caller added a new property. We also know that a setter diff --git a/js/src/jsiter.cpp b/js/src/jsiter.cpp index 46772cc3739a..82f6b45551a4 100644 --- a/js/src/jsiter.cpp +++ b/js/src/jsiter.cpp @@ -766,7 +766,7 @@ js_NewGenerator(JSContext *cx, JSStackFrame *fp) /* Copy rval, argv and vars. */ gen->frame.rval = fp->rval; memcpy(slots, fp->argv - 2, (2 + nargs) * sizeof(jsval)); - gen->frame.argc = nargs; + gen->frame.argc = fp->argc; gen->frame.argv = slots + 2; slots += 2 + nargs; memcpy(slots, fp->slots, fp->script->nfixed * sizeof(jsval)); diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index d06fdd064edf..8ef1433cf9e1 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -1404,7 +1404,9 @@ obj_eval(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) * with object to maintain invariants in the engine (see bug 520164). */ if (scopeobj->getParent()) { - withObject = js_NewWithObject(cx, scopeobj, scopeobj->getParent(), 0); + withObject = js_NewWithObject(cx, scopeobj, + JS_GetGlobalForObject(cx, scopeobj), + 0); if (!withObject) { ok = JS_FALSE; goto out; @@ -1442,13 +1444,14 @@ obj_eval(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) * calls to eval from global code are not cached. */ bucket = EvalCacheHash(cx, str); - if (!indirectCall && argc == 1 && caller->fun) { + if (!indirectCall && caller->fun) { uintN count = 0; JSScript **scriptp = bucket; EVAL_CACHE_METER(probe); while ((script = *scriptp) != NULL) { if (script->savedCallerFun && + script->staticLevel == staticLevel && script->version == cx->version && (script->principals == principals || (principals->subsume(principals, script->principals) && @@ -2958,7 +2961,7 @@ js_XDRBlockObject(JSXDRState *xdr, JSObject **objp) /* Find a property to XDR. */ do { /* If sprop is NULL, this is the first property. */ - sprop = sprop ? sprop->parent : OBJ_SCOPE(obj)->lastProp; + sprop = sprop ? sprop->parent : OBJ_SCOPE(obj)->lastProperty(); } while (!(sprop->flags & SPROP_HAS_SHORTID)); JS_ASSERT(sprop->getter == block_getProperty); @@ -3726,7 +3729,7 @@ js_AddNativeProperty(JSContext *cx, JSObject *obj, jsid id, } else { /* Convert string indices to integers if appropriate. */ id = js_CheckForStringIndex(id); - sprop = scope->add(cx, id, getter, setter, slot, attrs, flags, shortid); + sprop = scope->putProperty(cx, id, getter, setter, slot, attrs, flags, shortid); } JS_UNLOCK_OBJ(cx, obj); return sprop; @@ -3744,7 +3747,7 @@ js_ChangeNativePropertyAttrs(JSContext *cx, JSObject *obj, if (!scope) { sprop = NULL; } else { - sprop = scope->change(cx, sprop, attrs, mask, getter, setter); + sprop = scope->changeProperty(cx, sprop, attrs, mask, getter, setter); } JS_UNLOCK_OBJ(cx, obj); return sprop; @@ -3823,14 +3826,14 @@ js_DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, jsval value, if (sprop && pobj == obj && (sprop->attrs & (JSPROP_GETTER | JSPROP_SETTER))) { - sprop = OBJ_SCOPE(obj)->change(cx, sprop, attrs, - JSPROP_GETTER | JSPROP_SETTER, - (attrs & JSPROP_GETTER) - ? getter - : sprop->getter, - (attrs & JSPROP_SETTER) - ? setter - : sprop->setter); + sprop = OBJ_SCOPE(obj)->changeProperty(cx, sprop, attrs, + JSPROP_GETTER | JSPROP_SETTER, + (attrs & JSPROP_GETTER) + ? getter + : sprop->getter, + (attrs & JSPROP_SETTER) + ? setter + : sprop->setter); /* NB: obj == pobj, so we can share unlock code at the bottom. */ if (!sprop) @@ -3896,9 +3899,9 @@ js_DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, jsval value, } } - added = !scope->lookup(id); - sprop = scope->add(cx, id, getter, setter, SPROP_INVALID_SLOT, attrs, - flags, shortid); + added = !scope->hasProperty(id); + sprop = scope->putProperty(cx, id, getter, setter, SPROP_INVALID_SLOT, + attrs, flags, shortid); if (!sprop) goto error; } @@ -3909,7 +3912,7 @@ js_DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, jsval value, /* XXXbe called with lock held */ if (!AddPropertyHelper(cx, clasp, obj, scope, sprop, &value)) { - scope->remove(cx, id); + scope->removeProperty(cx, id); goto error; } @@ -4330,7 +4333,7 @@ js_NativeGet(JSContext *cx, JSObject *obj, JSObject *pobj, JS_LOCK_SCOPE(cx, scope); if (SLOT_IN_SCOPE(slot, scope) && (JS_LIKELY(cx->runtime->propertyRemovals == sample) || - scope->has(sprop))) { + scope->hasProperty(sprop))) { jsval v = *vp; if (!scope->methodWriteBarrier(cx, sprop, v)) { JS_UNLOCK_SCOPE(cx, scope); @@ -4392,7 +4395,7 @@ js_NativeSet(JSContext *cx, JSObject *obj, JSScopeProperty *sprop, bool added, JS_LOCK_SCOPE(cx, scope); if (SLOT_IN_SCOPE(slot, scope) && (JS_LIKELY(cx->runtime->propertyRemovals == sample) || - scope->has(sprop))) { + scope->hasProperty(sprop))) { jsval v = *vp; if (!added && !scope->methodWriteBarrier(cx, sprop, v)) { JS_UNLOCK_SCOPE(cx, scope); @@ -4760,8 +4763,8 @@ js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, uintN defineHow, } } - sprop = scope->add(cx, id, getter, setter, SPROP_INVALID_SLOT, attrs, - flags, shortid); + sprop = scope->putProperty(cx, id, getter, setter, SPROP_INVALID_SLOT, + attrs, flags, shortid); if (!sprop) { JS_UNLOCK_SCOPE(cx, scope); return JS_FALSE; @@ -4777,7 +4780,7 @@ js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, uintN defineHow, /* XXXbe called with obj locked */ if (!AddPropertyHelper(cx, clasp, obj, scope, sprop, vp)) { - scope->remove(cx, id); + scope->removeProperty(cx, id); JS_UNLOCK_SCOPE(cx, scope); return JS_FALSE; } @@ -4924,7 +4927,7 @@ js_DeleteProperty(JSContext *cx, JSObject *obj, jsid id, jsval *rval) if (SPROP_HAS_VALID_SLOT(sprop, scope)) GC_POKE(cx, LOCKED_OBJ_GET_SLOT(obj, sprop->slot)); - ok = scope->remove(cx, id); + ok = scope->removeProperty(cx, id); obj->dropProperty(cx, prop); return ok; } @@ -5159,12 +5162,9 @@ js_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op, /* Count all enumerable properties in object's scope. */ JSScope *scope = OBJ_SCOPE(obj); length = 0; - for (JSScopeProperty *sprop = SCOPE_LAST_PROP(scope); - sprop; - sprop = sprop->parent) { + for (JSScopeProperty *sprop = scope->lastProperty(); sprop; sprop = sprop->parent) { if ((sprop->attrs & JSPROP_ENUMERATE) && - !(sprop->flags & SPROP_IS_ALIAS) && - (!scope->hadMiddleDelete() || scope->has(sprop))) { + !(sprop->flags & SPROP_IS_ALIAS)) { length++; } } @@ -5195,12 +5195,9 @@ js_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op, ne->shape = shape; jsid *ids = ne->ids; - for (JSScopeProperty *sprop = SCOPE_LAST_PROP(scope); - sprop; - sprop = sprop->parent) { + for (JSScopeProperty *sprop = scope->lastProperty(); sprop; sprop = sprop->parent) { if ((sprop->attrs & JSPROP_ENUMERATE) && - !(sprop->flags & SPROP_IS_ALIAS) && - (!scope->hadMiddleDelete() || scope->has(sprop))) { + !(sprop->flags & SPROP_IS_ALIAS)) { JS_ASSERT(ids < ne->ids + length); *ids++ = sprop->id; } @@ -5869,7 +5866,7 @@ js_PrintObjectSlotName(JSTracer *trc, char *buf, size_t bufsize) JSScopeProperty *sprop; if (OBJ_IS_NATIVE(obj)) { JSScope *scope = OBJ_SCOPE(obj); - sprop = SCOPE_LAST_PROP(scope); + sprop = scope->lastProperty(); while (sprop && sprop->slot != slot) sprop = sprop->parent; } else { @@ -6300,10 +6297,9 @@ js_DumpObject(JSObject *obj) fprintf(stderr, "sealed\n"); fprintf(stderr, "properties:\n"); - for (JSScopeProperty *sprop = SCOPE_LAST_PROP(scope); sprop; + for (JSScopeProperty *sprop = scope->lastProperty(); sprop; sprop = sprop->parent) { - if (!scope->hadMiddleDelete() || scope->has(sprop)) - dumpScopeProp(sprop); + dumpScopeProp(sprop); } } else { if (!OBJ_IS_NATIVE(obj)) diff --git a/js/src/jsopcode.cpp b/js/src/jsopcode.cpp index 7b0f87c6a909..f16e0ee74e13 100644 --- a/js/src/jsopcode.cpp +++ b/js/src/jsopcode.cpp @@ -277,7 +277,7 @@ ToDisassemblySource(JSContext *cx, jsval v) if (clasp == &js_BlockClass) { char *source = JS_sprintf_append(NULL, "depth %d {", OBJ_BLOCK_DEPTH(cx, obj)); - for (JSScopeProperty *sprop = OBJ_SCOPE(obj)->lastProp; + for (JSScopeProperty *sprop = OBJ_SCOPE(obj)->lastProperty(); sprop; sprop = sprop->parent) { const char *bytes = js_AtomToPrintableString(cx, JSID_TO_ATOM(sprop->id)); @@ -1316,7 +1316,7 @@ GetLocal(SprintStack *ss, jsint i) } i -= depth; - for (sprop = OBJ_SCOPE(obj)->lastProp; sprop; sprop = sprop->parent) { + for (sprop = OBJ_SCOPE(obj)->lastProperty(); sprop; sprop = sprop->parent) { if (sprop->shortid == i) break; } @@ -2634,7 +2634,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop) MUST_FLOW_THROUGH("enterblock_out"); #define LOCAL_ASSERT_OUT(expr) LOCAL_ASSERT_CUSTOM(expr, ok = JS_FALSE; \ goto enterblock_out) - for (sprop = OBJ_SCOPE(obj)->lastProp; sprop; + for (sprop = OBJ_SCOPE(obj)->lastProperty(); sprop; sprop = sprop->parent) { if (!(sprop->flags & SPROP_HAS_SHORTID)) continue; diff --git a/js/src/jsops.cpp b/js/src/jsops.cpp index 6c49ef3759a6..997bc9e542cf 100644 --- a/js/src/jsops.cpp +++ b/js/src/jsops.cpp @@ -1756,7 +1756,7 @@ BEGIN_CASE(JSOP_SETMETHOD) /* The cache entry doesn't apply. vshape mismatch. */ checkForAdd = false; } else if (scope->owned()) { - if (sprop == scope->lastProp || scope->has(sprop)) { + if (sprop == scope->lastProperty() || scope->hasProperty(sprop)) { fast_set_propcache_hit: PCMETER(cache->pchits++); PCMETER(cache->setpchits++); @@ -1766,8 +1766,7 @@ BEGIN_CASE(JSOP_SETMETHOD) } checkForAdd = !(sprop->attrs & JSPROP_SHARED) && - sprop->parent == scope->lastProp && - !scope->hadMiddleDelete(); + sprop->parent == scope->lastProperty(); } else { scope = js_GetMutableScope(cx, obj); if (!scope) { @@ -1814,7 +1813,7 @@ BEGIN_CASE(JSOP_SETMETHOD) /* * If this obj's number of reserved slots differed, or * if something created a hash table for scope, we must - * pay the price of JSScope::add. + * pay the price of JSScope::putProperty. * * If slot does not match the cached sprop's slot, * update the cache entry in the hope that obj and @@ -1823,10 +1822,10 @@ BEGIN_CASE(JSOP_SETMETHOD) */ if (slot != sprop->slot || scope->table) { JSScopeProperty *sprop2 = - scope->add(cx, sprop->id, - sprop->getter, sprop->setter, - slot, sprop->attrs, - sprop->flags, sprop->shortid); + scope->putProperty(cx, sprop->id, + sprop->getter, sprop->setter, + slot, sprop->attrs, + sprop->flags, sprop->shortid); if (!sprop2) { js_FreeSlot(cx, obj, slot); JS_UNLOCK_SCOPE(cx, scope); @@ -3537,10 +3536,10 @@ BEGIN_CASE(JSOP_INITMETHOD) /* * Detect a repeated property name and force a miss to share the - * strict warning code and cope with complexity managed by - * JSScope::add. + * strict warning code and consolidate all the complexity managed + * by JSScope::addProperty. */ - if (sprop->parent != scope->lastProp) + if (sprop->parent != scope->lastProperty()) goto do_initprop_miss; /* @@ -3548,8 +3547,8 @@ BEGIN_CASE(JSOP_INITMETHOD) * proto-property, and there cannot have been any deletions of * prior properties. */ - JS_ASSERT(!scope->hadMiddleDelete()); - JS_ASSERT_IF(scope->table, !scope->has(sprop)); + JS_ASSERT(!scope->inDictionaryMode()); + JS_ASSERT_IF(scope->table, !scope->hasProperty(sprop)); slot = sprop->slot; JS_ASSERT(slot == scope->freeslot); @@ -3563,14 +3562,11 @@ BEGIN_CASE(JSOP_INITMETHOD) JS_ASSERT(slot == sprop->slot); } - JS_ASSERT(!scope->lastProp || - scope->shape == scope->lastProp->shape); + JS_ASSERT(!scope->lastProperty() || + scope->shape == scope->lastProperty()->shape); if (scope->table) { JSScopeProperty *sprop2 = - scope->add(cx, sprop->id, - sprop->getter, sprop->setter, - slot, sprop->attrs, - sprop->flags, sprop->shortid); + scope->addDataProperty(cx, sprop->id, slot, sprop->attrs); if (!sprop2) { js_FreeSlot(cx, obj, slot); JS_UNLOCK_SCOPE(cx, scope); diff --git a/js/src/jsparse.cpp b/js/src/jsparse.cpp index 15a76bd8b61d..2e0fbcd4b42b 100644 --- a/js/src/jsparse.cpp +++ b/js/src/jsparse.cpp @@ -3262,7 +3262,7 @@ PopStatement(JSTreeContext *tc) JSScope *scope = OBJ_SCOPE(obj); JS_ASSERT(!OBJ_IS_CLONED_BLOCK(obj)); - for (JSScopeProperty *sprop = scope->lastProp; sprop; sprop = sprop->parent) { + for (JSScopeProperty *sprop = scope->lastProperty(); sprop; sprop = sprop->parent) { JSAtom *atom = JSID_TO_ATOM(sprop->id); /* Beware the empty destructuring dummy. */ diff --git a/js/src/jsscope.cpp b/js/src/jsscope.cpp index ba15a07c86ea..ad39c6f58786 100644 --- a/js/src/jsscope.cpp +++ b/js/src/jsscope.cpp @@ -146,6 +146,14 @@ JSScope::initMinimal(JSContext *cx, uint32 newShape) lastProp = NULL; } +#ifdef DEBUG +JS_FRIEND_DATA(JSScopeStats) js_scope_stats = {0}; + +# define METER(x) JS_ATOMIC_INCREMENT(&js_scope_stats.x) +#else +# define METER(x) /* nothing */ +#endif + bool JSScope::createTable(JSContext *cx, bool report) { @@ -174,6 +182,7 @@ JSScope::createTable(JSContext *cx, bool report) if (!table) { if (report) JS_ReportOutOfMemory(cx); + METER(tableAllocFails); return false; } cx->updateMallocCounter(JS_BIT(sizeLog2) * sizeof(JSScopeProperty *)); @@ -200,7 +209,6 @@ JSScope::create(JSContext *cx, const JSObjectOps *ops, JSClass *clasp, scope->nrefs = 1; scope->freeslot = JSSLOT_FREE(clasp); scope->flags = cx->runtime->gcRegenShapesScopeFlag; - js_LeaveTraceIfGlobalObject(cx, obj); scope->initMinimal(cx, shape); #ifdef JS_THREADSAFE @@ -238,7 +246,7 @@ JSScope::createEmptyScope(JSContext *cx, JSClass *clasp) return scope; } -#if defined DEBUG || defined JS_DUMP_PROPTREE_STATS +#ifdef DEBUG # include "jsprf.h" # define LIVE_SCOPE_METER(cx,expr) JS_LOCK_RUNTIME_VOID(cx->runtime,expr) #else @@ -261,14 +269,6 @@ JSScope::destroy(JSContext *cx, JSScope *scope) cx->free(scope); } -#ifdef JS_DUMP_PROPTREE_STATS -JS_FRIEND_DATA(JSScopeStats) js_scope_stats = {0}; - -# define METER(x) JS_ATOMIC_INCREMENT(&js_scope_stats.x) -#else -# define METER(x) /* nothing */ -#endif - JS_STATIC_ASSERT(sizeof(JSHashNumber) == 4); JS_STATIC_ASSERT(sizeof(jsid) == JS_BYTES_PER_WORD); @@ -326,6 +326,10 @@ JSScope::searchTable(jsid id, bool adding) hash2 = SCOPE_HASH2(hash0, sizeLog2, hashShift); sizeMask = JS_BITMASK(sizeLog2); +#ifdef DEBUG + jsuword collision_flag = SPROP_COLLISION; +#endif + /* Save the first removed entry pointer so we can recycle it if adding. */ if (SPROP_IS_REMOVED(stored)) { firstRemoved = spp; @@ -333,6 +337,9 @@ JSScope::searchTable(jsid id, bool adding) firstRemoved = NULL; if (adding && !SPROP_HAD_COLLISION(stored)) SPROP_FLAG_COLLISION(spp, sprop); +#ifdef DEBUG + collision_flag &= jsuword(*spp) & SPROP_COLLISION; +#endif } for (;;) { @@ -350,6 +357,7 @@ JSScope::searchTable(jsid id, bool adding) sprop = SPROP_CLEAR_COLLISION(stored); if (sprop && sprop->id == id) { METER(stepHits); + JS_ASSERT(collision_flag); return spp; } @@ -359,6 +367,9 @@ JSScope::searchTable(jsid id, bool adding) } else { if (adding && !SPROP_HAD_COLLISION(stored)) SPROP_FLAG_COLLISION(spp, sprop); +#ifdef DEBUG + collision_flag &= jsuword(*spp) & SPROP_COLLISION; +#endif } } @@ -383,8 +394,10 @@ JSScope::changeTable(JSContext *cx, int change) newsize = JS_BIT(newlog2); nbytes = SCOPE_TABLE_NBYTES(newsize); newtable = (JSScopeProperty **) cx->calloc(nbytes); - if (!newtable) + if (!newtable) { + METER(tableAllocFails); return false; + } /* Now that we have newtable allocated, update members. */ hashShift = JS_DHASH_BITS - newlog2; @@ -830,7 +843,7 @@ HashChunks(PropTreeKidsChunk *chunk, uintN n) */ static JSScopeProperty * GetPropertyTreeChild(JSContext *cx, JSScopeProperty *parent, - JSScopeProperty *child) + const JSScopeProperty &child) { JSRuntime *rt; JSDHashTable *table; @@ -839,15 +852,13 @@ GetPropertyTreeChild(JSContext *cx, JSScopeProperty *parent, PropTreeKidsChunk *chunk; uintN i, n; - JS_ASSERT(!JSVAL_IS_NULL(child->id)); - rt = cx->runtime; if (!parent) { JS_LOCK_GC(rt); table = &rt->propertyTreeHash; entry = (JSPropertyTreeEntry *) - JS_DHashTableOperate(table, child, JS_DHASH_ADD); + JS_DHashTableOperate(table, &child, JS_DHASH_ADD); if (!entry) goto out_of_memory; @@ -880,12 +891,10 @@ GetPropertyTreeChild(JSContext *cx, JSScopeProperty *parent, if (table) { JS_LOCK_GC(rt); entry = (JSPropertyTreeEntry *) - JS_DHashTableOperate(table, child, JS_DHASH_LOOKUP); + JS_DHashTableOperate(table, &child, JS_DHASH_LOOKUP); sprop = entry->child; - if (sprop) { - JS_UNLOCK_GC(rt); - return sprop; - } + if (sprop) + goto out; goto locked_not_found; } @@ -912,13 +921,13 @@ GetPropertyTreeChild(JSContext *cx, JSScopeProperty *parent, goto not_found; } - if (SPROP_MATCH(sprop, child)) + if (SPROP_MATCH(sprop, &child)) return sprop; } n += MAX_KIDS_PER_CHUNK; } while ((chunk = chunk->next) != NULL); } else { - if (SPROP_MATCH(sprop, child)) + if (SPROP_MATCH(sprop, &child)) return sprop; } } @@ -932,13 +941,13 @@ locked_not_found: if (!sprop) goto out_of_memory; - sprop->id = child->id; - sprop->getter = child->getter; - sprop->setter = child->setter; - sprop->slot = child->slot; - sprop->attrs = child->attrs; - sprop->flags = child->flags; - sprop->shortid = child->shortid; + sprop->id = child.id; + sprop->getter = child.getter; + sprop->setter = child.setter; + sprop->slot = child.slot; + sprop->attrs = child.attrs; + sprop->flags = child.flags; + sprop->shortid = child.shortid; sprop->parent = sprop->kids = NULL; sprop->shape = js_GenerateShape(cx, true); @@ -949,32 +958,89 @@ locked_not_found: goto out_of_memory; } -out: + out: JS_UNLOCK_GC(rt); return sprop; -out_of_memory: + out_of_memory: JS_UNLOCK_GC(rt); JS_ReportOutOfMemory(cx); return NULL; } +/* + * Get or create a property-tree or dictionary child property of parent, which + * must be lastProp if inDictionaryMode(), else parent must be one of lastProp + * or lastProp->parent. + */ +JSScopeProperty * +JSScope::getChildProperty(JSContext *cx, JSScopeProperty *parent, + JSScopeProperty &child) +{ + JS_ASSERT(!JSVAL_IS_NULL(child.id)); + + /* + * Aliases share another property's slot, passed in the |slot| parameter. + * Shared properties have no slot. Unshared properties that do not alias + * another property's slot allocate a slot here, but may lose it due to a + * JS_ClearScope call. + */ + if (!(child.flags & SPROP_IS_ALIAS)) { + if (child.attrs & JSPROP_SHARED) { + child.slot = SPROP_INVALID_SLOT; + } else { + /* + * We may have set slot from a nearly-matching sprop, above. + * If so, we're overwriting that nearly-matching sprop, so we + * can reuse its slot -- we don't need to allocate a new one. + * Similarly, we use a specific slot if provided by the caller. + */ + if (child.slot == SPROP_INVALID_SLOT && + !js_AllocSlot(cx, object, &child.slot)) { + return NULL; + } + } + } + + if (inDictionaryMode()) { + JS_ASSERT(parent == lastProp); + if (newDictionaryProperty(cx, child, &lastProp)) { + updateShape(cx); + return lastProp; + } + return NULL; + } + + JSScopeProperty *sprop = GetPropertyTreeChild(cx, parent, child); + if (sprop) { + JS_ASSERT(sprop->parent == parent); + if (parent == lastProp) { + extend(cx, sprop); + } else { + JS_ASSERT(parent == lastProp->parent); + setLastProperty(sprop); + updateShape(cx); + } + } + return sprop; +} + #ifdef DEBUG_notbrendan #define CHECK_ANCESTOR_LINE(scope, sparse) \ JS_BEGIN_MACRO \ - if ((scope)->table) CheckAncestorLine(scope, sparse); \ + if ((scope)->table) CheckAncestorLine(scope); \ JS_END_MACRO static void -CheckAncestorLine(JSScope *scope, bool sparse) +CheckAncestorLine(JSScope *scope) { uint32 size; JSScopeProperty **spp, **start, **end, *ancestorLine, *sprop, *aprop; uint32 entryCount, ancestorCount; - ancestorLine = SCOPE_LAST_PROP(scope); + ancestorLine = scope->lastProperty(); if (ancestorLine) - JS_ASSERT(scope->has(ancestorLine)); + JS_ASSERT(scope->hasProperty(ancestorLine)); entryCount = 0; size = SCOPE_CAPACITY(scope); @@ -982,7 +1048,7 @@ CheckAncestorLine(JSScope *scope, bool sparse) for (spp = start, end = start + size; spp < end; spp++) { sprop = SPROP_FETCH(spp); if (sprop) { - entryCount++; + ++entryCount; for (aprop = ancestorLine; aprop; aprop = aprop->parent) { if (aprop == sprop) break; @@ -993,13 +1059,8 @@ CheckAncestorLine(JSScope *scope, bool sparse) JS_ASSERT(entryCount == scope->entryCount); ancestorCount = 0; - for (sprop = ancestorLine; sprop; sprop = sprop->parent) { - if (scope->hadMiddleDelete() && !scope->has(sprop)) { - JS_ASSERT(sparse); - continue; - } + for (sprop = ancestorLine; sprop; sprop = sprop->parent) ancestorCount++; - } JS_ASSERT(ancestorCount == scope->entryCount); } #else @@ -1051,27 +1112,122 @@ JSScope::generateOwnShape(JSContext *cx) } JSScopeProperty * -JSScope::add(JSContext *cx, jsid id, - JSPropertyOp getter, JSPropertyOp setter, - uint32 slot, uintN attrs, - uintN flags, intN shortid) +JSScope::newDictionaryProperty(JSContext *cx, const JSScopeProperty &child, + JSScopeProperty **childp) { - JSScopeProperty **spp, *sprop, *overwriting, **spvec, **spp2, child; - uint32 size, splen, i; - int change; - JSTempValueRooter tvr; + JSScopeProperty *dprop = NewScopeProperty(cx->runtime); + if (!dprop) { + JS_ReportOutOfMemory(cx); + return NULL; + } + dprop->id = child.id; + dprop->getter = child.getter; + dprop->setter = child.setter; + dprop->slot = child.slot; + dprop->attrs = child.attrs; + dprop->flags = child.flags | SPROP_IN_DICTIONARY; + dprop->shortid = child.shortid; + dprop->shape = js_GenerateShape(cx, false); + + dprop->childp = NULL; + insertDictionaryProperty(dprop, childp); + return dprop; +} + +bool +JSScope::toDictionaryMode(JSContext *cx, JSScopeProperty *&aprop) +{ + JS_ASSERT(!inDictionaryMode()); + + JSScopeProperty **oldTable = table; + uint32 saveRemovedCount = removedCount; + if (oldTable) { + int sizeLog2 = JS_DHASH_BITS - hashShift; + JSScopeProperty **newTable = (JSScopeProperty **) + js_calloc(JS_BIT(sizeLog2) * sizeof(JSScopeProperty *)); + + if (!newTable) { + JS_ReportOutOfMemory(cx); + METER(toDictFails); + return false; + } + table = newTable; + removedCount = 0; + } + + /* + * We are committed from here on. If we fail due to OOM in the loop below, + * we'll restore saveEntryCount, oldTable, oldLastProp. + */ + JSScopeProperty *oldLastProp = lastProp; + lastProp = NULL; + + /* + * Clear entryCount because JSScope::insertDictionaryProperty called from + * JSScope::newDictionaryProperty bumps it. + */ + uint32 saveEntryCount = entryCount; + entryCount = 0; + + for (JSScopeProperty *sprop = oldLastProp, **childp = &lastProp; sprop; sprop = sprop->parent) { + JSScopeProperty *dprop = newDictionaryProperty(cx, *sprop, childp); + if (!dprop) { + entryCount = saveEntryCount; + removedCount = saveRemovedCount; + if (table) + js_free(table); + table = oldTable; + lastProp = oldLastProp; + METER(toDictFails); + return false; + } + + if (table) { + JSScopeProperty **spp = search(dprop->id, true); + JS_ASSERT(!SPROP_FETCH(spp)); + SPROP_STORE_PRESERVING_COLLISION(spp, dprop); + } + + if (aprop == sprop) + aprop = dprop; + childp = &dprop->parent; + } + + if (oldTable) + js_free(oldTable); + setDictionaryMode(); + clearOwnShape(); + + if (lastProp) { + /* + * This scope may get OWN_SHAPE set again, but for now its shape must + * be the shape of its lastProp. If it is empty, its initial shape is + * still valid. See JSScope::updateShape's definition in jsscope.h. + */ + shape = lastProp->shape; + } + return true; +} + +JSScopeProperty * +JSScope::addProperty(JSContext *cx, jsid id, + JSPropertyOp getter, JSPropertyOp setter, + uint32 slot, uintN attrs, + uintN flags, intN shortid) +{ JS_ASSERT(JS_IS_SCOPE_LOCKED(cx, this)); CHECK_ANCESTOR_LINE(this, true); JS_ASSERT(!JSVAL_IS_NULL(id)); JS_ASSERT_IF(attrs & JSPROP_GETTER, getter); JS_ASSERT_IF(attrs & JSPROP_SETTER, setter); + JS_ASSERT_IF(!cx->runtime->gcRegenShapes, hasRegenFlag(cx->runtime->gcRegenShapesScopeFlag)); /* - * You can't add properties to a sealed scope. But note well that you can + * You can't add properties to a sealed scope. But note well that you can * change property attributes in a sealed scope, even though that replaces * a JSScopeProperty * in the scope's hash table -- but no id is added, so * the scope remains sealed. @@ -1081,10 +1237,22 @@ JSScope::add(JSContext *cx, jsid id, return NULL; } - /* - * Normalize stub getter and setter values for faster is-stub testing in - * the SPROP_CALL_[GS]ETTER macros. - */ + /* Search for id with adding = true in order to claim its entry. */ + JSScopeProperty **spp = search(id, true); + JS_ASSERT(!SPROP_FETCH(spp)); + return addPropertyHelper(cx, id, getter, setter, slot, attrs, flags, shortid, spp); +} + +/* + * Normalize stub getter and setter values for faster is-stub testing in the + * SPROP_CALL_[GS]ETTER macros. + */ +static inline bool +NormalizeGetterAndSetter(JSContext *cx, JSScope *scope, + jsid id, uintN attrs, uintN flags, + JSPropertyOp &getter, + JSPropertyOp &setter) +{ if (setter == JS_PropertyStub) setter = NULL; if (flags & SPROP_IS_METHOD) { @@ -1098,240 +1266,49 @@ JSScope::add(JSContext *cx, jsid id, } /* - * Search for id in order to claim its entry, allocating a property tree - * node if one doesn't already exist for our parameters. + * Check for a watchpoint on a deleted property; if one exists, change + * setter to js_watch_set or js_watch_set_wrapper. + * XXXbe this could get expensive with lots of watchpoints... */ - spp = search(id, true); - sprop = overwriting = SPROP_FETCH(spp); - if (!sprop) { - /* Check whether we need to grow, if the load factor is >= .75. */ - size = SCOPE_CAPACITY(this); - if (entryCount + removedCount >= size - (size >> 2)) { - if (removedCount >= size >> 2) { - METER(compresses); - change = 0; - } else { - METER(grows); - change = 1; - } - if (!changeTable(cx, change) && - entryCount + removedCount == size - 1) { - METER(addFailures); - return NULL; - } - spp = search(id, true); - JS_ASSERT(!SPROP_FETCH(spp)); + if (!JS_CLIST_IS_EMPTY(&cx->runtime->watchPointList) && + js_FindWatchPoint(cx->runtime, scope, id)) { + setter = js_WrapWatchedSetter(cx, id, attrs, setter); + if (!setter) { + METER(wrapWatchFails); + return false; } - } else { - /* Property exists: JSScope::search must have returned a valid *spp. */ - JS_ASSERT(!SPROP_IS_REMOVED(*spp)); + } + return true; +} - /* - * If all property members match, this is a redundant add and we can - * return early. If the caller wants to allocate a slot, but doesn't - * care which slot, copy sprop->slot into slot so we can match sprop, - * if all other members match. - */ - if (!(attrs & JSPROP_SHARED) && - slot == SPROP_INVALID_SLOT && - SPROP_HAS_VALID_SLOT(sprop, this)) { - slot = sprop->slot; - } - if (SPROP_MATCH_PARAMS_AFTER_ID(sprop, getter, setter, slot, attrs, - flags, shortid)) { - METER(redundantAdds); - return sprop; - } +JSScopeProperty * +JSScope::addPropertyHelper(JSContext *cx, jsid id, + JSPropertyOp getter, JSPropertyOp setter, + uint32 slot, uintN attrs, + uintN flags, intN shortid, + JSScopeProperty **spp) +{ + NormalizeGetterAndSetter(cx, this, id, attrs, flags, getter, setter); - /* - * If we are clearing sprop to force the existing property that it - * describes to be overwritten, then we have to unlink sprop from the - * ancestor line at this->lastProp, lazily if sprop is not lastProp. - * And we must remove the entry at *spp, precisely so the lazy "middle - * delete" fixup code further below won't find sprop in this->table, - * in spite of sprop being on the ancestor line. - * - * When we finally succeed in finding or creating a new sprop - * and storing its pointer at *spp, we'll use the |overwriting| - * local saved when we first looked up id to decide whether we're - * indeed creating a new entry, or merely overwriting an existing - * property. - */ - if (sprop == SCOPE_LAST_PROP(this)) { - do { - SCOPE_REMOVE_LAST_PROP(this); - if (!hadMiddleDelete()) - break; - sprop = SCOPE_LAST_PROP(this); - } while (sprop && !has(sprop)); - } else if (!hadMiddleDelete()) { - /* - * If we have no hash table yet, we need one now. The middle - * delete code is simple-minded that way! - */ - if (!table) { - if (!createTable(cx, true)) - return NULL; - spp = search(id, true); - sprop = overwriting = SPROP_FETCH(spp); - } - setMiddleDelete(); - } - - /* - * If we fail later on trying to find or create a new sprop, we will - * goto fail_overwrite and restore *spp from |overwriting|. Note that - * we don't bother to keep this->removedCount in sync, because we'll - * fix up *spp and this->entryCount shortly, no matter how control - * flow returns from this function. - */ - if (table) - SPROP_STORE_PRESERVING_COLLISION(spp, NULL); - entryCount--; - CHECK_ANCESTOR_LINE(this, true); - sprop = NULL; + /* Check whether we need to grow, if the load factor is >= .75. */ + uint32 size = SCOPE_CAPACITY(this); + if (entryCount + removedCount >= size - (size >> 2)) { + int change = removedCount < size >> 2; + if (!change) + METER(compresses); + else + METER(grows); + if (!changeTable(cx, change) && entryCount + removedCount == size - 1) + return NULL; + spp = search(id, true); + JS_ASSERT(!SPROP_FETCH(spp)); } - if (!sprop) { - /* - * If properties were deleted from the middle of the list starting at - * this->lastProp, we may need to fork the property tree and squeeze - * all deleted properties out of this scope's ancestor line. Otherwise - * we risk adding a node with the same id as a "middle" node, violating - * the rule that properties along an ancestor line have distinct ids. - */ - if (hadMiddleDelete()) { - JS_ASSERT(table); - CHECK_ANCESTOR_LINE(this, true); + /* Find or create a property tree node labeled by our arguments. */ + JSScopeProperty *sprop; + { + JSScopeProperty child; - /* - * Our forking heuristic tries to balance the desire to avoid - * over-compacting (over-forking) against the desire to - * *periodically* fork anyways, in order to prevent paying scan - * penalties on each insert indefinitely, on a lineage with only - * a few old middle-deletions. So we fork if either: - * - * - A quick scan finds a true conflict. - * - We are passing through a doubling-threshold in size and - * have accumulated a nonzero count of uncompacted deletions. - */ - - bool conflicts = false; - uint32 count = 0; - uint32 threshold = JS_BIT(JS_CeilingLog2(entryCount)); - for (sprop = SCOPE_LAST_PROP(this); sprop; sprop = sprop->parent) { - ++count; - if (sprop->id == id) { - conflicts = true; - break; - } - } - - if (conflicts || count > threshold) { - /* - * Enumerate live entries in this->table using a temporary - * vector, by walking the (possibly sparse, due to deletions) - * ancestor line from this->lastProp. - */ - splen = entryCount; - JS_ASSERT(splen != 0); - spvec = (JSScopeProperty **) - cx->malloc(SCOPE_TABLE_NBYTES(splen)); - if (!spvec) - goto fail_overwrite; - i = splen; - sprop = SCOPE_LAST_PROP(this); - JS_ASSERT(sprop); - do { - /* - * NB: use JSScope::lookup, not JSScope::has, as the latter - * macro insists that sprop->id maps to sprop, while the - * former simply tests whether sprop->id is bound in this - * scope. - */ - if (!lookup(sprop->id)) - continue; - - JS_ASSERT(sprop != overwriting); - JS_ASSERT(i != 0); - spvec[--i] = sprop; - } while ((sprop = sprop->parent) != NULL); - JS_ASSERT(i == 0); - - /* - * Now loop forward through spvec, forking the property tree - * whenever we see a "parent gap" due to deletions from this - * scope. NB: sprop is null on first entry to the loop body. - */ - do { - if (spvec[i]->parent == sprop) { - sprop = spvec[i]; - } else { - sprop = GetPropertyTreeChild(cx, sprop, spvec[i]); - if (!sprop) { - cx->free(spvec); - goto fail_overwrite; - } - - spp2 = search(sprop->id, false); - JS_ASSERT(SPROP_FETCH(spp2) == spvec[i]); - SPROP_STORE_PRESERVING_COLLISION(spp2, sprop); - } - } while (++i < splen); - cx->free(spvec); - - /* - * Now sprop points to the last property in this scope, where - * the ancestor line from sprop to the root is dense w.r.t. - * this scope: it contains no nodes not mapped by this->table. - */ - lastProp = sprop; - CHECK_ANCESTOR_LINE(this, false); - JS_RUNTIME_METER(cx->runtime, middleDeleteFixups); - clearMiddleDelete(); - } - } - - /* - * Aliases share another property's slot, passed in the |slot| param. - * Shared properties have no slot. Unshared properties that do not - * alias another property's slot get one here, but may lose it due to - * a JS_ClearScope call. - */ - if (!(flags & SPROP_IS_ALIAS)) { - if (attrs & JSPROP_SHARED) { - slot = SPROP_INVALID_SLOT; - } else { - /* - * We may have set slot from a nearly-matching sprop, above. - * If so, we're overwriting that nearly-matching sprop, so we - * can reuse its slot -- we don't need to allocate a new one. - * Similarly, we use a specific slot if provided by the caller. - */ - if (slot == SPROP_INVALID_SLOT && - !js_AllocSlot(cx, object, &slot)) { - goto fail_overwrite; - } - } - } - - /* - * Check for a watchpoint on a deleted property; if one exists, change - * setter to js_watch_set. - * XXXbe this could get expensive with lots of watchpoints... - */ - if (!JS_CLIST_IS_EMPTY(&cx->runtime->watchPointList) && - js_FindWatchPoint(cx->runtime, this, id)) { - if (overwriting) - JS_PUSH_TEMP_ROOT_SPROP(cx, overwriting, &tvr); - setter = js_WrapWatchedSetter(cx, id, attrs, setter); - if (overwriting) - JS_POP_TEMP_ROOT(cx, &tvr); - if (!setter) - goto fail_overwrite; - } - - /* Find or create a property tree node labeled by our arguments. */ child.id = id; child.getter = getter; child.setter = setter; @@ -1339,26 +1316,17 @@ JSScope::add(JSContext *cx, jsid id, child.attrs = attrs; child.flags = flags; child.shortid = shortid; - sprop = GetPropertyTreeChild(cx, lastProp, &child); - if (!sprop) - goto fail_overwrite; - - /* - * This scope's shape defaults to its last property's shape, but may be - * regenerated later as this scope diverges (from the property cache - * point of view) from the structural type associated with sprop. - */ - extend(cx, sprop); + sprop = getChildProperty(cx, lastProp, child); + } + if (sprop) { /* Store the tree node pointer in the table entry for id. */ if (table) SPROP_STORE_PRESERVING_COLLISION(spp, sprop); CHECK_ANCESTOR_LINE(this, false); #ifdef DEBUG - if (!overwriting) { - LIVE_SCOPE_METER(cx, ++cx->runtime->liveScopeProps); - JS_RUNTIME_METER(cx->runtime, totalScopeProps); - } + LIVE_SCOPE_METER(cx, ++cx->runtime->liveScopeProps); + JS_RUNTIME_METER(cx->runtime, totalScopeProps); #endif /* @@ -1371,65 +1339,157 @@ JSScope::add(JSContext *cx, jsid id, */ if (!table && entryCount >= SCOPE_HASH_THRESHOLD) (void) createTable(cx, false); + + METER(adds); + return sprop; } - METER(adds); - return sprop; - -fail_overwrite: - if (overwriting) { - /* - * We may or may not have forked overwriting out of this scope's - * ancestor line, so we must check (the alternative is to set a flag - * above, but that hurts the common, non-error case). If we did fork - * overwriting out, we'll add it back at scope->lastProp. This means - * enumeration order can change due to a failure to overwrite an id. - * XXXbe minor(?) incompatibility - */ - for (sprop = SCOPE_LAST_PROP(this); ; sprop = sprop->parent) { - if (!sprop) { - sprop = SCOPE_LAST_PROP(this); - if (overwriting->parent == sprop) { - lastProp = overwriting; - } else { - sprop = GetPropertyTreeChild(cx, sprop, overwriting); - if (sprop) { - JS_ASSERT(sprop != overwriting); - lastProp = sprop; - } - overwriting = sprop; - } - break; - } - if (sprop == overwriting) - break; - } - if (overwriting) { - if (table) - SPROP_STORE_PRESERVING_COLLISION(spp, overwriting); - entryCount++; - } - CHECK_ANCESTOR_LINE(this, true); - } - METER(addFailures); + METER(addFails); return NULL; } JSScopeProperty * -JSScope::change(JSContext *cx, JSScopeProperty *sprop, - uintN attrs, uintN mask, - JSPropertyOp getter, JSPropertyOp setter) +JSScope::putProperty(JSContext *cx, jsid id, + JSPropertyOp getter, JSPropertyOp setter, + uint32 slot, uintN attrs, + uintN flags, intN shortid) { - JSScopeProperty child, *newsprop, **spp; + JSScopeProperty **spp, *sprop, *overwriting; + JS_ASSERT(JS_IS_SCOPE_LOCKED(cx, this)); + CHECK_ANCESTOR_LINE(this, true); + + JS_ASSERT(!JSVAL_IS_NULL(id)); + JS_ASSERT_IF(attrs & JSPROP_GETTER, getter); + JS_ASSERT_IF(attrs & JSPROP_SETTER, setter); + + JS_ASSERT_IF(!cx->runtime->gcRegenShapes, + hasRegenFlag(cx->runtime->gcRegenShapesScopeFlag)); + + if (sealed()) { + reportReadOnlyScope(cx); + return NULL; + } + + /* Search for id in order to claim its entry if table has been allocated. */ + spp = search(id, true); + sprop = SPROP_FETCH(spp); + if (!sprop) + return addPropertyHelper(cx, id, getter, setter, slot, attrs, flags, shortid, spp); + + /* Property exists: JSScope::search must have returned a valid *spp. */ + JS_ASSERT(!SPROP_IS_REMOVED(*spp)); + overwriting = sprop; + + NormalizeGetterAndSetter(cx, this, id, attrs, flags, getter, setter); + + /* + * If all property members match, this is a redundant add and we can + * return early. If the caller wants to allocate a slot, but doesn't + * care which slot, copy sprop->slot into slot so we can match sprop, + * if all other members match. + */ + if (!(attrs & JSPROP_SHARED) && + slot == SPROP_INVALID_SLOT && + SPROP_HAS_VALID_SLOT(sprop, this)) { + slot = sprop->slot; + } + if (SPROP_MATCH_PARAMS_AFTER_ID(sprop, getter, setter, slot, attrs, + flags, shortid)) { + METER(redundantPuts); + return sprop; + } + + /* + * If we are clearing sprop to force the existing property that it + * describes to be overwritten, then we have to unlink sprop from the + * ancestor line at this->lastProp. + * + * If sprop is not lastProp and this scope is not in dictionary mode, + * we must switch to dictionary mode so we can unlink the non-terminal + * sprop without breaking anyone sharing the property lineage via the + * runtime's property tree. + */ + if (sprop == lastProp && !inDictionaryMode()) { + removeLastProperty(); + } else { + if (!inDictionaryMode()) { + if (!toDictionaryMode(cx, sprop)) + return NULL; + spp = search(id, false); + } + removeDictionaryProperty(sprop); + } + + /* + * If we fail later on trying to find or create a new sprop, we will + * restore *spp from |overwriting|. Note that we don't bother to keep + * this->removedCount in sync, because we will fix up both *spp and + * this->entryCount shortly. + */ + if (table) + SPROP_STORE_PRESERVING_COLLISION(spp, NULL); + CHECK_ANCESTOR_LINE(this, true); + + { + JSScopeProperty child; + + /* Find or create a property tree node labeled by our arguments. */ + child.id = id; + child.getter = getter; + child.setter = setter; + child.slot = slot; + child.attrs = attrs; + child.flags = flags; + child.shortid = shortid; + sprop = getChildProperty(cx, lastProp, child); + } + + if (sprop) { + CHECK_ANCESTOR_LINE(this, false); + + if (table) { + /* Store the tree node pointer in the table entry for id. */ + SPROP_STORE_PRESERVING_COLLISION(spp, sprop); + } else if (entryCount >= SCOPE_HASH_THRESHOLD) { + /* See comment in JSScope::addPropertyHelper about ignoring OOM here. */ + (void) createTable(cx, false); + } + + METER(puts); + return sprop; + } + + if (table) + SPROP_STORE_PRESERVING_COLLISION(spp, overwriting); + ++entryCount; + CHECK_ANCESTOR_LINE(this, true); + METER(putFails); + return NULL; +} + +JSScopeProperty * +JSScope::changeProperty(JSContext *cx, JSScopeProperty *sprop, + uintN attrs, uintN mask, + JSPropertyOp getter, JSPropertyOp setter) +{ + JSScopeProperty child, *newsprop; + + JS_ASSERT(JS_IS_SCOPE_LOCKED(cx, this)); CHECK_ANCESTOR_LINE(this, true); JS_ASSERT(!JSVAL_IS_NULL(sprop->id)); + JS_ASSERT(hasProperty(sprop)); + + attrs |= sprop->attrs & mask; /* Allow only shared (slot-less) => unshared (slot-full) transition. */ - attrs |= sprop->attrs & mask; JS_ASSERT(!((attrs ^ sprop->attrs) & JSPROP_SHARED) || !(attrs & JSPROP_SHARED)); + + /* Don't allow method properties to be changed to accessor properties. */ + JS_ASSERT(!(sprop->flags & SPROP_IS_METHOD)); + if (getter == JS_PropertyStub) getter = NULL; if (setter == JS_PropertyStub) @@ -1448,55 +1508,50 @@ JSScope::change(JSContext *cx, JSScopeProperty *sprop, child.flags = sprop->flags; child.shortid = sprop->shortid; - if (SCOPE_LAST_PROP(this) == sprop) { - /* - * Optimize the case where the last property added to this scope is - * changed to have a different attrs, getter, or setter. In the last - * property case, we need not fork the property tree. But since we do - * not call JSScope::add, we may need to allocate a new slot directly. - */ - if ((sprop->attrs & JSPROP_SHARED) && !(attrs & JSPROP_SHARED)) { - JS_ASSERT(child.slot == SPROP_INVALID_SLOT); - if (!js_AllocSlot(cx, object, &child.slot)) - return NULL; - } - - newsprop = GetPropertyTreeChild(cx, sprop->parent, &child); + if (inDictionaryMode()) { + removeDictionaryProperty(sprop); + newsprop = newDictionaryProperty(cx, child, &lastProp); if (newsprop) { - spp = search(sprop->id, false); - JS_ASSERT(SPROP_FETCH(spp) == sprop); - - if (table) + if (table) { + JSScopeProperty **spp = search(sprop->id, false); SPROP_STORE_PRESERVING_COLLISION(spp, newsprop); - lastProp = newsprop; + } + updateShape(cx); + } + } else if (sprop == lastProp) { + newsprop = getChildProperty(cx, sprop->parent, child); + if (newsprop) { + if (table) { + JSScopeProperty **spp = search(sprop->id, false); + JS_ASSERT(SPROP_FETCH(spp) == sprop); + SPROP_STORE_PRESERVING_COLLISION(spp, newsprop); + } CHECK_ANCESTOR_LINE(this, true); } } else { /* - * Let JSScope::add handle this |overwriting| case, including the - * conservation of sprop->slot (if it's valid). We must not call - * JSScope::remove here, because it will free a valid sprop->slot and - * JSScope::add won't re-allocate it. + * Let JSScope::putProperty handle this |overwriting| case, including + * the conservation of sprop->slot (if it's valid). We must not call + * JSScope::removeProperty because it will free a valid sprop->slot and + * JSScope::putProperty won't re-allocate it. */ - newsprop = add(cx, child.id, child.getter, child.setter, child.slot, - child.attrs, child.flags, child.shortid); + newsprop = putProperty(cx, child.id, child.getter, child.setter, child.slot, + child.attrs, child.flags, child.shortid); } - if (newsprop) { - js_LeaveTraceIfGlobalObject(cx, object); - replacingShapeChange(cx, sprop, newsprop); - } -#ifdef JS_DUMP_PROPTREE_STATS +#ifdef DEBUG + if (newsprop) + METER(changes); else - METER(changeFailures); + METER(changeFails); #endif return newsprop; } bool -JSScope::remove(JSContext *cx, jsid id) +JSScope::removeProperty(JSContext *cx, jsid id) { - JSScopeProperty **spp, *stored, *sprop; + JSScopeProperty **spp, *sprop; uint32 size; JS_ASSERT(JS_IS_SCOPE_LOCKED(cx, this)); @@ -1505,23 +1560,22 @@ JSScope::remove(JSContext *cx, jsid id) reportReadOnlyScope(cx); return false; } - METER(removes); spp = search(id, false); - stored = *spp; - sprop = SPROP_CLEAR_COLLISION(stored); + sprop = SPROP_CLEAR_COLLISION(*spp); if (!sprop) { METER(uselessRemoves); return true; } - /* Convert from a list to a hash so we can handle "middle deletes". */ - if (!table && sprop != lastProp) { - if (!createTable(cx, true)) - return false; - spp = search(id, false); - stored = *spp; - sprop = SPROP_CLEAR_COLLISION(stored); + /* If sprop is not the last property added, switch to dictionary mode. */ + if (sprop != lastProp) { + if (!inDictionaryMode()) { + if (!toDictionaryMode(cx, sprop)) + return false; + spp = search(id, false); + } + JS_ASSERT(SPROP_FETCH(spp) == sprop); } /* First, if sprop is unshared and not cleared, free its slot number. */ @@ -1531,32 +1585,36 @@ JSScope::remove(JSContext *cx, jsid id) } /* Next, remove id by setting its entry to a removed or free sentinel. */ - if (SPROP_HAD_COLLISION(stored)) { + if (SPROP_HAD_COLLISION(*spp)) { JS_ASSERT(table); *spp = SPROP_REMOVED; - removedCount++; + ++removedCount; } else { METER(removeFrees); - if (table) + if (table) { *spp = NULL; +#ifdef DEBUG + for (JSScopeProperty *aprop = lastProp; aprop; aprop = aprop->parent) + JS_ASSERT_IF(aprop != sprop, hasProperty(aprop)); +#endif + } } - entryCount--; LIVE_SCOPE_METER(cx, --cx->runtime->liveScopeProps); - /* Update this->lastProp directly, or set its deferred update flag. */ - if (sprop == SCOPE_LAST_PROP(this)) { - do { - SCOPE_REMOVE_LAST_PROP(this); - if (!hadMiddleDelete()) - break; - sprop = SCOPE_LAST_PROP(this); - } while (sprop && !has(sprop)); - if (!SCOPE_LAST_PROP(this)) - clearMiddleDelete(); - } else if (!hadMiddleDelete()) { - setMiddleDelete(); + if (inDictionaryMode()) { + /* + * Remove sprop from its scope-owned doubly linked list, setting this + * scope's OWN_SHAPE flag first if sprop is lastProp so updateShape(cx) + * after this if-else will generate a fresh shape for this scope. + */ + if (sprop != lastProp) + setOwnShape(); + removeDictionaryProperty(sprop); + } else { + JS_ASSERT(sprop == lastProp); + removeLastProperty(); } - generateOwnShape(cx); + updateShape(cx); CHECK_ANCESTOR_LINE(this, true); /* Last, consider shrinking this->table if its load factor is <= .25. */ @@ -1566,6 +1624,7 @@ JSScope::remove(JSContext *cx, jsid id) (void) changeTable(cx, -1); } + METER(removes); return true; } @@ -1577,7 +1636,8 @@ JSScope::clear(JSContext *cx) if (table) js_free(table); - clearMiddleDelete(); + clearDictionaryMode(); + clearOwnShape(); js_LeaveTraceIfGlobalObject(cx, object); JSClass *clasp = object->getClass(); @@ -1629,9 +1689,9 @@ JSScope::methodShapeChange(JSContext *cx, JSScopeProperty *sprop, jsval toval) * despecializing from a method memoized in the property tree to a * plain old function-valued property. */ - sprop = add(cx, sprop->id, NULL, sprop->setter, sprop->slot, - sprop->attrs, sprop->flags & ~SPROP_IS_METHOD, - sprop->shortid); + sprop = putProperty(cx, sprop->id, NULL, sprop->setter, sprop->slot, + sprop->attrs, sprop->flags & ~SPROP_IS_METHOD, + sprop->shortid); if (!sprop) return false; } @@ -1648,7 +1708,7 @@ JSScope::methodShapeChange(JSContext *cx, uint32 slot, jsval toval) } else { for (JSScopeProperty *sprop = lastProp; sprop; sprop = sprop->parent) { JS_ASSERT(!JSVAL_IS_NULL(sprop->id)); - if (sprop->slot == slot && (!hadMiddleDelete() || has(sprop))) + if (sprop->slot == slot) return methodShapeChange(cx, sprop, toval); } } @@ -1661,16 +1721,6 @@ JSScope::protoShapeChange(JSContext *cx) generateOwnShape(cx); } -void -JSScope::replacingShapeChange(JSContext *cx, JSScopeProperty *sprop, JSScopeProperty *newsprop) -{ - JS_ASSERT(!JSVAL_IS_NULL(sprop->id)); - if (shape == sprop->shape) - shape = newsprop->shape; - else - generateOwnShape(cx); -} - void JSScope::sealingShapeChange(JSContext *cx) { @@ -1765,7 +1815,7 @@ JSScopeProperty::trace(JSTracer *trc) } } -#ifdef JS_DUMP_PROPTREE_STATS +#ifdef DEBUG #include @@ -1868,7 +1918,7 @@ DumpSubtree(JSContext *cx, JSScopeProperty *sprop, int level, FILE *fp) } } -#endif /* JS_DUMP_PROPTREE_STATS */ +#endif /* DEBUG */ void js_SweepScopeProperties(JSContext *cx) @@ -1880,18 +1930,20 @@ js_SweepScopeProperties(JSContext *cx) PropTreeKidsChunk *chunk, *nextChunk, *freeChunk; uintN i; -#ifdef JS_DUMP_PROPTREE_STATS +#ifdef DEBUG JSBasicStats bs; uint32 livePropCapacity = 0, totalLiveCount = 0; static FILE *logfp; - if (!logfp) - logfp = fopen("/tmp/proptree.stats", "w"); + if (!logfp) { + if (const char *filename = getenv("JS_PROPTREE_STATFILE")) + logfp = fopen(filename, "w"); + } - JS_BASIC_STATS_INIT(&bs); - MeterKidCount(&bs, rt->propertyTreeHash.entryCount); - JS_DHashTableEnumerate(&rt->propertyTreeHash, js_MeterPropertyTree, &bs); + if (logfp) { + JS_BASIC_STATS_INIT(&bs); + MeterKidCount(&bs, rt->propertyTreeHash.entryCount); + JS_DHashTableEnumerate(&rt->propertyTreeHash, js_MeterPropertyTree, &bs); - { double props, nodes, mean, sigma; props = rt->liveScopePropsPreSweep; @@ -1902,9 +1954,9 @@ js_SweepScopeProperties(JSContext *cx) fprintf(logfp, "props %g nodes %g beta %g meankids %g sigma %g max %u\n", props, nodes, nodes / props, mean, sigma, bs.max); - } - JS_DumpHistogram(&bs, logfp); + JS_DumpHistogram(&bs, logfp); + } #endif ap = &rt->propertyArenaPool.first.next; @@ -1936,90 +1988,92 @@ js_SweepScopeProperties(JSContext *cx) continue; } - /* Ok, sprop is garbage to collect: unlink it from its parent. */ - freeChunk = RemovePropertyTreeChild(rt, sprop); + if (!(sprop->flags & SPROP_IN_DICTIONARY)) { + /* Ok, sprop is garbage to collect: unlink it from its parent. */ + freeChunk = RemovePropertyTreeChild(rt, sprop); - /* - * Take care to reparent all sprop's kids to their grandparent. - * InsertPropertyTreeChild can potentially fail for two reasons: - * - * 1. If parent is null, insertion into the root property hash - * table may fail. We are forced to leave the kid out of the - * table (as can already happen with duplicates) but ensure - * that the kid's parent pointer is set to null. - * - * 2. If parent is non-null, allocation of a new KidsChunk can - * fail. To prevent this from happening, we allow sprops's own - * chunks to be reused by the grandparent, which removes the - * need for InsertPropertyTreeChild to malloc a new KidsChunk. - * - * If sprop does not have chunky kids, then we rely on the - * RemovePropertyTreeChild call above (which removed sprop from - * its parent) either leaving one free entry, or else returning - * the now-unused chunk to us so we can reuse it. - * - * We also require the grandparent to have either no kids or else - * chunky kids. A single non-chunky kid would force a new chunk to - * be malloced in some cases (if sprop had a single non-chunky - * kid, or a multiple of MAX_KIDS_PER_CHUNK kids). Note that - * RemovePropertyTreeChild never converts a single-entry chunky - * kid back to a non-chunky kid, so we are assured of correct - * behaviour. - */ - kids = sprop->kids; - if (kids) { - sprop->kids = NULL; - parent = sprop->parent; + /* + * Take care to reparent all sprop's kids to their grandparent. + * InsertPropertyTreeChild can potentially fail for two reasons: + * + * 1. If parent is null, insertion into the root property hash + * table may fail. We are forced to leave the kid out of the + * table (as can already happen with duplicates) but ensure + * that the kid's parent pointer is set to null. + * + * 2. If parent is non-null, allocation of a new KidsChunk can + * fail. To prevent this from happening, we allow sprops's own + * chunks to be reused by the grandparent, which removes the + * need for InsertPropertyTreeChild to malloc a new KidsChunk. + * + * If sprop does not have chunky kids, then we rely on the + * RemovePropertyTreeChild call above (which removed sprop from + * its parent) either leaving one free entry, or else returning + * the now-unused chunk to us so we can reuse it. + * + * We also require the grandparent to have either no kids or else + * chunky kids. A single non-chunky kid would force a new chunk to + * be malloced in some cases (if sprop had a single non-chunky + * kid, or a multiple of MAX_KIDS_PER_CHUNK kids). Note that + * RemovePropertyTreeChild never converts a single-entry chunky + * kid back to a non-chunky kid, so we are assured of correct + * behaviour. + */ + kids = sprop->kids; + if (kids) { + sprop->kids = NULL; + parent = sprop->parent; - /* The grandparent must have either no kids or chunky kids. */ - JS_ASSERT(!parent || !parent->kids || - KIDS_IS_CHUNKY(parent->kids)); - if (KIDS_IS_CHUNKY(kids)) { - chunk = KIDS_TO_CHUNK(kids); - do { - nextChunk = chunk->next; - chunk->next = NULL; - for (i = 0; i < MAX_KIDS_PER_CHUNK; i++) { - kid = chunk->kids[i]; - if (!kid) - break; - JS_ASSERT(kid->parent == sprop); + /* The grandparent must have either no kids or chunky kids. */ + JS_ASSERT(!parent || !parent->kids || + KIDS_IS_CHUNKY(parent->kids)); + if (KIDS_IS_CHUNKY(kids)) { + chunk = KIDS_TO_CHUNK(kids); + do { + nextChunk = chunk->next; + chunk->next = NULL; + for (i = 0; i < MAX_KIDS_PER_CHUNK; i++) { + kid = chunk->kids[i]; + if (!kid) + break; + JS_ASSERT(kid->parent == sprop); - /* - * Clear a space in the kids array for possible - * re-use by InsertPropertyTreeChild. - */ - chunk->kids[i] = NULL; - if (!InsertPropertyTreeChild(rt, parent, kid, chunk)) { /* - * This can happen only if we failed to add an - * entry to the root property hash table. + * Clear a space in the kids array for possible + * re-use by InsertPropertyTreeChild. */ - JS_ASSERT(!parent); - kid->parent = NULL; + chunk->kids[i] = NULL; + if (!InsertPropertyTreeChild(rt, parent, kid, chunk)) { + /* + * This can happen only if we failed to add an + * entry to the root property hash table. + */ + JS_ASSERT(!parent); + kid->parent = NULL; + } } + if (!chunk->kids[0]) { + /* The chunk wasn't reused, so we must free it. */ + DestroyPropTreeKidsChunk(rt, chunk); + } + } while ((chunk = nextChunk) != NULL); + } else { + kid = kids; + if (!InsertPropertyTreeChild(rt, parent, kid, freeChunk)) { + /* + * This can happen only if we failed to add an entry + * to the root property hash table. + */ + JS_ASSERT(!parent); + kid->parent = NULL; } - if (!chunk->kids[0]) { - /* The chunk wasn't reused, so we must free it. */ - DestroyPropTreeKidsChunk(rt, chunk); - } - } while ((chunk = nextChunk) != NULL); - } else { - kid = kids; - if (!InsertPropertyTreeChild(rt, parent, kid, freeChunk)) { - /* - * This can happen only if we failed to add an entry - * to the root property hash table. - */ - JS_ASSERT(!parent); - kid->parent = NULL; } } - } - if (freeChunk && !freeChunk->kids[0]) { - /* The chunk wasn't reused, so we must free it. */ - DestroyPropTreeKidsChunk(rt, freeChunk); + if (freeChunk && !freeChunk->kids[0]) { + /* The chunk wasn't reused, so we must free it. */ + DestroyPropTreeKidsChunk(rt, freeChunk); + } } /* Clear id so we know (above) that sprop is on the freelist. */ @@ -2034,7 +2088,7 @@ js_SweepScopeProperties(JSContext *cx) FREENODE_REMOVE(sprop); JS_ARENA_DESTROY(&rt->propertyArenaPool, a, ap); } else { -#ifdef JS_DUMP_PROPTREE_STATS +#ifdef DEBUG livePropCapacity += limit - (JSScopeProperty *) a->base; totalLiveCount += liveCount; #endif @@ -2042,60 +2096,79 @@ js_SweepScopeProperties(JSContext *cx) } } -#ifdef JS_DUMP_PROPTREE_STATS - fprintf(logfp, "arenautil %g%%\n", - (totalLiveCount && livePropCapacity) - ? (totalLiveCount * 100.0) / livePropCapacity - : 0.0); +#ifdef DEBUG + if (logfp) { + fprintf(logfp, + "\nProperty tree stats for gcNumber %lu\n", + (unsigned long) rt->gcNumber); + + fprintf(logfp, "arenautil %g%%\n", + (totalLiveCount && livePropCapacity) + ? (totalLiveCount * 100.0) / livePropCapacity + : 0.0); #define RATE(f1, f2) (((double)js_scope_stats.f1 / js_scope_stats.f2) * 100.0) - fprintf(logfp, "Scope search stats:\n" - " searches: %6u\n" - " hits: %6u %5.2f%% of searches\n" - " misses: %6u %5.2f%%\n" - " hashes: %6u %5.2f%%\n" - " steps: %6u %5.2f%% %5.2f%% of hashes\n" - " stepHits: %6u %5.2f%% %5.2f%%\n" - " stepMisses: %6u %5.2f%% %5.2f%%\n" - " adds: %6u\n" - " redundantAdds: %6u\n" - " addFailures: %6u\n" - " changeFailures: %6u\n" - " compresses: %6u\n" - " grows: %6u\n" - " removes: %6u\n" - " removeFrees: %6u\n" - " uselessRemoves: %6u\n" - " shrinks: %6u\n", - js_scope_stats.searches, - js_scope_stats.hits, RATE(hits, searches), - js_scope_stats.misses, RATE(misses, searches), - js_scope_stats.hashes, RATE(hashes, searches), - js_scope_stats.steps, RATE(steps, searches), RATE(steps, hashes), - js_scope_stats.stepHits, - RATE(stepHits, searches), RATE(stepHits, hashes), - js_scope_stats.stepMisses, - RATE(stepMisses, searches), RATE(stepMisses, hashes), - js_scope_stats.adds, - js_scope_stats.redundantAdds, - js_scope_stats.addFailures, - js_scope_stats.changeFailures, - js_scope_stats.compresses, - js_scope_stats.grows, - js_scope_stats.removes, - js_scope_stats.removeFrees, - js_scope_stats.uselessRemoves, - js_scope_stats.shrinks); + fprintf(logfp, + "Scope search stats:\n" + " searches: %6u\n" + " hits: %6u %5.2f%% of searches\n" + " misses: %6u %5.2f%%\n" + " hashes: %6u %5.2f%%\n" + " steps: %6u %5.2f%% %5.2f%% of hashes\n" + " stepHits: %6u %5.2f%% %5.2f%%\n" + " stepMisses: %6u %5.2f%% %5.2f%%\n" + " tableAllocFails %6u\n" + " toDictFails %6u\n" + " wrapWatchFails %6u\n" + " adds: %6u\n" + " addFails: %6u\n" + " puts: %6u\n" + " redundantPuts: %6u\n" + " putFails: %6u\n" + " changes: %6u\n" + " changeFails: %6u\n" + " compresses: %6u\n" + " grows: %6u\n" + " removes: %6u\n" + " removeFrees: %6u\n" + " uselessRemoves: %6u\n" + " shrinks: %6u\n", + js_scope_stats.searches, + js_scope_stats.hits, RATE(hits, searches), + js_scope_stats.misses, RATE(misses, searches), + js_scope_stats.hashes, RATE(hashes, searches), + js_scope_stats.steps, RATE(steps, searches), RATE(steps, hashes), + js_scope_stats.stepHits, + RATE(stepHits, searches), RATE(stepHits, hashes), + js_scope_stats.stepMisses, + RATE(stepMisses, searches), RATE(stepMisses, hashes), + js_scope_stats.tableAllocFails, + js_scope_stats.toDictFails, + js_scope_stats.wrapWatchFails, + js_scope_stats.adds, + js_scope_stats.addFails, + js_scope_stats.puts, + js_scope_stats.redundantPuts, + js_scope_stats.putFails, + js_scope_stats.changes, + js_scope_stats.changeFails, + js_scope_stats.compresses, + js_scope_stats.grows, + js_scope_stats.removes, + js_scope_stats.removeFrees, + js_scope_stats.uselessRemoves, + js_scope_stats.shrinks); #undef RATE - fflush(logfp); -#endif + fflush(logfp); + } -#ifdef DUMP_PROPERTY_TREE - { - FILE *dumpfp = fopen("/tmp/proptree.dump", "w"); + if (const char *filename = getenv("JS_PROPTREE_DUMPFILE")) { + char pathname[1024]; + JS_snprintf(pathname, sizeof pathname, "%s.%lu", filename, (unsigned long)rt->gcNumber); + FILE *dumpfp = fopen(pathname, "w"); if (dumpfp) { JSPropertyTreeEntry *pte, *end; @@ -2109,7 +2182,7 @@ js_SweepScopeProperties(JSContext *cx) fclose(dumpfp); } } -#endif +#endif /* DEBUG */ } bool diff --git a/js/src/jsscope.h b/js/src/jsscope.h index 0988606a4ed4..9044c49b796b 100644 --- a/js/src/jsscope.h +++ b/js/src/jsscope.h @@ -114,10 +114,10 @@ JS_BEGIN_EXTERN_C * skipping nodes that lack entries. * * What if we add Y again? X->Y->Z->Y is wrong and we'll enumerate Y twice. - * Therefore we must fork in such a case, if not earlier. Because delete is - * "bursty", we should not fork eagerly. Delaying a fork till we are at risk - * of adding Y after it was deleted already requires a flag in the JSScope, to - * wit, SCOPE_MIDDLE_DELETE. + * Therefore we must fork in such a case if not earlier, or do something else. + * We used to fork on the theory that set after delete is rare, but the Web is + * a harsh mistress, and we now convert the scope to a "dictionary" on first + * delete, to avoid O(n^2) growth in the property tree. * * What about thread safety? If the property tree operations done by requests * are find-node and insert-node, then the only hazard is duplicate insertion. @@ -195,13 +195,15 @@ JS_BEGIN_EXTERN_C * in Mozilla is < 5, with a large standard deviation (~8). Instead of always * allocating scope->table, we leave it null while initializing all the other * scope members as if it were non-null and minimal-length. Until a property - * is added that crosses the threshold of 6 or more entries for hashing, or - * until a "middle delete" occurs, we use linear search from scope->lastProp - * to find a given id, and save on the space overhead of a hash table. + * is added that crosses the threshold of 6 or more entries for hashing, we use + * linear search from scope->lastProp to find a given id, and save on the space + * overhead of a hash table. */ struct JSEmptyScope; +#define SPROP_INVALID_SLOT 0xffffffff + struct JSScope : public JSObjectMap { #ifdef JS_THREADSAFE @@ -218,9 +220,44 @@ struct JSScope : public JSObjectMap uint32 entryCount; /* number of entries in table */ uint32 removedCount; /* removed entry sentinels in table */ JSScopeProperty **table; /* table of ptrs to shared tree nodes */ - JSScopeProperty *lastProp; /* pointer to last property added */ + + /* + * A little information hiding for scope->lastProp, in case it ever becomes + * a tagged pointer again. + */ + inline JSScopeProperty *lastProperty() const; private: + JSScopeProperty *getChildProperty(JSContext *cx, JSScopeProperty *parent, + JSScopeProperty &child); + + JSScopeProperty *newDictionaryProperty(JSContext *cx, const JSScopeProperty &child, + JSScopeProperty **childp); + + bool toDictionaryMode(JSContext *cx, JSScopeProperty *&aprop); + + /* + * Private pointer to the last added property and methods to manipulate the + * list it links among properties in this scope. The {remove,insert} pair + * for DictionaryProperties assert that the scope is in dictionary mode and + * any reachable properties are flagged as dictionary properties. + * + * NB: these private methods do *not* update this scope's shape to track + * lastProp->shape after they finish updating the linked list in the case + * where lastProp is updated. It is up to calling code in jsscope.cpp to + * call updateShape(cx) after updating lastProp. + */ + JSScopeProperty *lastProp; + + /* These four inline methods are defined further below in this .h file. */ + inline void setLastProperty(JSScopeProperty *sprop); + inline void removeLastProperty(); + inline void removeDictionaryProperty(JSScopeProperty *sprop); + inline void insertDictionaryProperty(JSScopeProperty *sprop, JSScopeProperty **childp); + + /* Defined in jsscopeinlines.h to avoid including implementation dependencies here. */ + inline void updateShape(JSContext *cx); + void initMinimal(JSContext *cx, uint32 newShape); bool createTable(JSContext *cx, bool report); bool changeTable(JSContext *cx, int change); @@ -230,6 +267,12 @@ struct JSScope : public JSObjectMap inline JSScopeProperty **search(jsid id, bool adding); JSEmptyScope *createEmptyScope(JSContext *cx, JSClass *clasp); + JSScopeProperty *addPropertyHelper(JSContext *cx, jsid id, + JSPropertyOp getter, JSPropertyOp setter, + uint32 slot, uintN attrs, + uintN flags, intN shortid, + JSScopeProperty **spp); + public: explicit JSScope(const JSObjectOps *ops, JSObject *obj = NULL) : JSObjectMap(ops, 0), object(obj) {} @@ -253,27 +296,48 @@ struct JSScope : public JSObjectMap inline JSEmptyScope *getEmptyScope(JSContext *cx, JSClass *clasp); inline bool canProvideEmptyScope(JSObjectOps *ops, JSClass *clasp); - + JSScopeProperty *lookup(jsid id); - bool has(JSScopeProperty *sprop); - JSScopeProperty *add(JSContext *cx, jsid id, - JSPropertyOp getter, JSPropertyOp setter, - uint32 slot, uintN attrs, - uintN flags, intN shortid); + inline bool hasProperty(jsid id) { return lookup(id) != NULL; } + inline bool hasProperty(JSScopeProperty *sprop); - JSScopeProperty *change(JSContext *cx, JSScopeProperty *sprop, - uintN attrs, uintN mask, - JSPropertyOp getter, JSPropertyOp setter); + /* Add a property whose id is not yet in this scope. */ + JSScopeProperty *addProperty(JSContext *cx, jsid id, + JSPropertyOp getter, JSPropertyOp setter, + uint32 slot, uintN attrs, + uintN flags, intN shortid); - bool remove(JSContext *cx, jsid id); + /* Add a data property whose id is not yet in this scope. */ + JSScopeProperty *addDataProperty(JSContext *cx, jsid id, uint32 slot, uintN attrs) { + JS_ASSERT(!(attrs & (JSPROP_GETTER | JSPROP_SETTER))); + return addProperty(cx, id, NULL, NULL, slot, attrs, 0, 0); + } + + /* Add or overwrite a property for id in this scope. */ + JSScopeProperty *putProperty(JSContext *cx, jsid id, + JSPropertyOp getter, JSPropertyOp setter, + uint32 slot, uintN attrs, + uintN flags, intN shortid); + + /* Change the given property into a sibling with the same id in this scope. */ + JSScopeProperty *changeProperty(JSContext *cx, JSScopeProperty *sprop, + uintN attrs, uintN mask, + JSPropertyOp getter, JSPropertyOp setter); + + /* Remove id from this scope. */ + bool removeProperty(JSContext *cx, jsid id); + + /* Clear the scope, making it empty. */ void clear(JSContext *cx); + /* Extend this scope to have sprop as its last-added property. */ void extend(JSContext *cx, JSScopeProperty *sprop); /* * Read barrier to clone a joined function object stored as a method. - * Defined inline further below. + * Defined in jsscopeinlines.h, but not declared inline per standard style + * in order to avoid gcc warnings. */ bool methodReadBarrier(JSContext *cx, JSScopeProperty *sprop, jsval *vp); @@ -294,15 +358,14 @@ struct JSScope : public JSObjectMap bool methodShapeChange(JSContext *cx, JSScopeProperty *sprop, jsval toval); bool methodShapeChange(JSContext *cx, uint32 slot, jsval toval); void protoShapeChange(JSContext *cx); - void replacingShapeChange(JSContext *cx, JSScopeProperty *sprop, JSScopeProperty *newsprop); void sealingShapeChange(JSContext *cx); void shadowingShapeChange(JSContext *cx, JSScopeProperty *sprop); /* By definition, hashShift = JS_DHASH_BITS - log2(capacity). */ -#define SCOPE_CAPACITY(scope) JS_BIT(JS_DHASH_BITS-(scope)->hashShift) +#define SCOPE_CAPACITY(scope) JS_BIT(JS_DHASH_BITS-(scope)->hashShift) enum { - MIDDLE_DELETE = 0x0001, + DICTIONARY_MODE = 0x0001, SEALED = 0x0002, BRANDED = 0x0004, INDEXED_PROPERTIES = 0x0008, @@ -316,9 +379,9 @@ struct JSScope : public JSObjectMap SHAPE_REGEN = 0x0040 }; - bool hadMiddleDelete() { return flags & MIDDLE_DELETE; } - void setMiddleDelete() { flags |= MIDDLE_DELETE; } - void clearMiddleDelete() { flags &= ~MIDDLE_DELETE; } + bool inDictionaryMode() { return flags & DICTIONARY_MODE; } + void setDictionaryMode() { flags |= DICTIONARY_MODE; } + void clearDictionaryMode() { flags &= ~DICTIONARY_MODE; } /* * Don't define clearSealed, as it can't be done safely because JS_LOCK_OBJ @@ -341,6 +404,7 @@ struct JSScope : public JSObjectMap bool hasOwnShape() { return flags & OWN_SHAPE; } void setOwnShape() { flags |= OWN_SHAPE; } + void clearOwnShape() { flags &= ~OWN_SHAPE; } bool hasRegenFlag(uint8 regenFlag) { return (flags & SHAPE_REGEN) == regenFlag; } @@ -427,18 +491,6 @@ OBJ_SHAPE(JSObject *obj) return obj->map->shape; } -/* - * A little information hiding for scope->lastProp, in case it ever becomes - * a tagged pointer again. - */ -#define SCOPE_LAST_PROP(scope) \ - (JS_ASSERT_IF((scope)->lastProp, !JSVAL_IS_NULL((scope)->lastProp->id)), \ - (scope)->lastProp) -#define SCOPE_REMOVE_LAST_PROP(scope) \ - (JS_ASSERT_IF((scope)->lastProp->parent, \ - !JSVAL_IS_NULL((scope)->lastProp->parent->id)), \ - (scope)->lastProp = (scope)->lastProp->parent) - /* * Helpers for reinterpreting JSPropertyOp as JSObject* for scripted getters * and setters. @@ -471,8 +523,14 @@ struct JSScopeProperty { uint8 flags; /* flags, see below for defines */ int16 shortid; /* tinyid, or local arg/var index */ JSScopeProperty *parent; /* parent node, reverse for..in order */ - JSScopeProperty *kids; /* null, single child, or a tagged ptr + union { + JSScopeProperty *kids; /* null, single child, or a tagged ptr to many-kids data structure */ + JSScopeProperty **childp; /* dictionary list starting at lastProp + has a double-indirect back pointer, + either to sprop->parent if not last, + else to scope->lastProp */ + }; uint32 shape; /* property cache shape identifier */ /* Bits stored in sprop->flags. */ @@ -481,6 +539,7 @@ struct JSScopeProperty { #define SPROP_HAS_SHORTID 0x04 #define SPROP_FLAG_SHAPE_REGEN 0x08 #define SPROP_IS_METHOD 0x10 +#define SPROP_IN_DICTIONARY 0x20 bool isMethod() const { return flags & SPROP_IS_METHOD; @@ -551,11 +610,85 @@ JSScope::lookup(jsid id) } inline bool -JSScope::has(JSScopeProperty *sprop) +JSScope::hasProperty(JSScopeProperty *sprop) { return lookup(sprop->id) == sprop; } +inline JSScopeProperty * +JSScope::lastProperty() const +{ + JS_ASSERT_IF(lastProp, !JSVAL_IS_NULL(lastProp->id)); + return lastProp; +} + +/* + * Note that sprop must not be null, as emptying a scope requires extra work + * done only by methods in jsscope.cpp. + */ +inline void +JSScope::setLastProperty(JSScopeProperty *sprop) +{ + JS_ASSERT(!JSVAL_IS_NULL(sprop->id)); + JS_ASSERT_IF(lastProp, !JSVAL_IS_NULL(lastProp->id)); + + lastProp = sprop; +} + +inline void +JSScope::removeLastProperty() +{ + JS_ASSERT(!inDictionaryMode()); + JS_ASSERT_IF(lastProp->parent, !JSVAL_IS_NULL(lastProp->parent->id)); + + lastProp = lastProp->parent; + --entryCount; +} + +inline void +JSScope::removeDictionaryProperty(JSScopeProperty *sprop) +{ + JS_ASSERT(inDictionaryMode()); + JS_ASSERT(sprop->flags & SPROP_IN_DICTIONARY); + JS_ASSERT(sprop->childp); + JS_ASSERT(!JSVAL_IS_NULL(sprop->id)); + + JS_ASSERT(lastProp->flags & SPROP_IN_DICTIONARY); + JS_ASSERT(lastProp->childp == &lastProp); + JS_ASSERT_IF(lastProp != sprop, !JSVAL_IS_NULL(lastProp->id)); + JS_ASSERT_IF(lastProp->parent, !JSVAL_IS_NULL(lastProp->parent->id)); + + if (sprop->parent) + sprop->parent->childp = sprop->childp; + *sprop->childp = sprop->parent; + --entryCount; + sprop->childp = NULL; +} + +inline void +JSScope::insertDictionaryProperty(JSScopeProperty *sprop, JSScopeProperty **childp) +{ + /* + * Don't assert inDictionaryMode() here because we may be called from + * toDictionaryMode via newDictionaryProperty. + */ + JS_ASSERT(sprop->flags & SPROP_IN_DICTIONARY); + JS_ASSERT(!sprop->childp); + JS_ASSERT(!JSVAL_IS_NULL(sprop->id)); + + JS_ASSERT_IF(*childp, (*childp)->flags & SPROP_IN_DICTIONARY); + JS_ASSERT_IF(lastProp, lastProp->flags & SPROP_IN_DICTIONARY); + JS_ASSERT_IF(lastProp, lastProp->childp == &lastProp); + JS_ASSERT_IF(lastProp, !JSVAL_IS_NULL(lastProp->id)); + + sprop->parent = *childp; + *childp = sprop; + if (sprop->parent) + sprop->parent->childp = &sprop->parent; + sprop->childp = childp; + ++entryCount; +} + /* * If SPROP_HAS_SHORTID is set in sprop->flags, we use sprop->shortid rather * than id when calling sprop's getter or setter. @@ -564,8 +697,6 @@ JSScope::has(JSScopeProperty *sprop) (((sprop)->flags & SPROP_HAS_SHORTID) ? INT_TO_JSVAL((sprop)->shortid) \ : ID_TO_VALUE((sprop)->id)) -#define SPROP_INVALID_SLOT 0xffffffff - #define SLOT_IN_SCOPE(slot,scope) ((slot) < (scope)->freeslot) #define SPROP_HAS_VALID_SLOT(sprop,scope) SLOT_IN_SCOPE((sprop)->slot, scope) @@ -582,7 +713,7 @@ JSScope::has(JSScopeProperty *sprop) extern uint32 js_GenerateShape(JSContext *cx, bool gcLocked); -#ifdef JS_DUMP_PROPTREE_STATS +#ifdef DEBUG struct JSScopeStats { jsrefcount searches; jsrefcount hits; @@ -591,10 +722,16 @@ struct JSScopeStats { jsrefcount steps; jsrefcount stepHits; jsrefcount stepMisses; + jsrefcount tableAllocFails; + jsrefcount toDictFails; + jsrefcount wrapWatchFails; jsrefcount adds; - jsrefcount redundantAdds; - jsrefcount addFailures; - jsrefcount changeFailures; + jsrefcount addFails; + jsrefcount puts; + jsrefcount redundantPuts; + jsrefcount putFails; + jsrefcount changes; + jsrefcount changeFails; jsrefcount compresses; jsrefcount grows; jsrefcount removes; @@ -618,7 +755,6 @@ JSScope::search(jsid id, bool adding) METER(searches); if (!table) { /* Not enough properties to justify hashing: search from lastProp. */ - JS_ASSERT(!hadMiddleDelete()); for (spp = &lastProp; (sprop = *spp); spp = &sprop->parent) { if (sprop->id == id) { METER(hits); diff --git a/js/src/jsscopeinlines.h b/js/src/jsscopeinlines.h index 46c7b960a744..b572d332b038 100644 --- a/js/src/jsscopeinlines.h +++ b/js/src/jsscopeinlines.h @@ -41,20 +41,26 @@ #define jsscopeinlines_h___ #include "jscntxt.h" +#include "jsdbgapi.h" #include "jsfun.h" -#include "jsinterp.h" #include "jsobj.h" #include "jsscope.h" +inline void +JSScope::updateShape(JSContext *cx) +{ + JS_ASSERT(object); + js_LeaveTraceIfGlobalObject(cx, object); + + shape = (hasOwnShape() || !lastProp) ? js_GenerateShape(cx, false) : lastProp->shape; +} + inline void JSScope::extend(JSContext *cx, JSScopeProperty *sprop) { - js_LeaveTraceIfGlobalObject(cx, object); - shape = (!lastProp || shape == lastProp->shape) - ? sprop->shape - : js_GenerateShape(cx, false); ++entryCount; - lastProp = sprop; + setLastProperty(sprop); + updateShape(cx); jsuint index; if (js_IdIsIndex(sprop->id, &index)) @@ -72,7 +78,7 @@ inline bool JSScope::methodReadBarrier(JSContext *cx, JSScopeProperty *sprop, jsval *vp) { JS_ASSERT(hasMethodBarrier()); - JS_ASSERT(has(sprop)); + JS_ASSERT(hasProperty(sprop)); JS_ASSERT(sprop->isMethod()); JS_ASSERT(sprop->methodValue() == *vp); JS_ASSERT(object->getClass() == &js_ObjectClass); @@ -148,12 +154,10 @@ JSScope::trace(JSTracer *trc) } } if (sprop) { - JS_ASSERT(has(sprop)); + JS_ASSERT(hasProperty(sprop)); /* Trace scope's property tree ancestor line. */ do { - if (hadMiddleDelete() && !has(sprop)) - continue; sprop->trace(trc); } while ((sprop = sprop->parent) != NULL); } diff --git a/js/src/jsstr.cpp b/js/src/jsstr.cpp index 50afdd6ef9bd..d7534fdb2894 100644 --- a/js/src/jsstr.cpp +++ b/js/src/jsstr.cpp @@ -101,13 +101,8 @@ MinimizeDependentStrings(JSString *str, int level, JSString **basep) base = base->dependentBase(); } while (base->isDependent()); } - if (start == 0) { - JS_ASSERT(str->dependentIsPrefix()); - str->prefixSetBase(base); - } else if (start <= JSString::MAX_DEPENDENT_START) { - length = str->dependentLength(); - str->reinitDependent(base, start, length); - } + length = str->dependentLength(); + str->reinitDependent(base, start, length); } *basep = base; return start; @@ -188,9 +183,9 @@ js_ConcatStrings(JSContext *cx, JSString *left, JSString *right) } else { str->flatSetMutable(); - /* Morph left into a dependent prefix if we realloc'd its buffer. */ + /* Morph left into a dependent string if we realloc'd its buffer. */ if (ldep) { - ldep->reinitPrefix(str, ln); + ldep->reinitDependent(str, 0, ln); #ifdef DEBUG { JSRuntime *rt = cx->runtime; @@ -654,6 +649,21 @@ NormalizeThis(JSContext *cx, jsval *vp) if (JSVAL_IS_NULL(vp[1]) && JSVAL_IS_NULL(JS_THIS(cx, vp))) return NULL; + + /* + * js_GetPrimitiveThis seems to do a bunch of work (like calls to + * JS_THIS_OBJECT) which we don't need in the common case (where + * vp[1] is a String object) here. Note that vp[1] can still be a + * primitive value at this point. + */ + if (!JSVAL_IS_PRIMITIVE(vp[1])) { + JSObject *obj = JSVAL_TO_OBJECT(vp[1]); + if (obj->getClass() == &js_StringClass) { + vp[1] = obj->fslots[JSSLOT_PRIMITIVE_THIS]; + return JSVAL_TO_STRING(vp[1]); + } + } + str = js_ValueToString(cx, vp[1]); if (!str) return NULL; @@ -933,9 +943,7 @@ str_charAt(JSContext *cx, uintN argc, jsval *vp) if ((size_t)i >= str->length()) goto out_of_range; } else { - str = NormalizeThis(cx, vp); - if (!str) - return JS_FALSE; + NORMALIZE_THIS(cx, vp, str); if (argc == 0) { d = 0.0; @@ -977,9 +985,7 @@ str_charCodeAt(JSContext *cx, uintN argc, jsval *vp) if ((size_t)i >= str->length()) goto out_of_range; } else { - str = NormalizeThis(cx, vp); - if (!str) - return JS_FALSE; + NORMALIZE_THIS(cx, vp, str); if (argc == 0) { d = 0.0; @@ -2636,7 +2642,7 @@ static const jschar UnitStringData[] = { C(0xf8), C(0xf9), C(0xfa), C(0xfb), C(0xfc), C(0xfd), C(0xfe), C(0xff) }; -#define U(c) { 1 | JSString::ATOMIZED, {(jschar *)UnitStringData + (c) * 2} } +#define U(c) { 1, 0, JSString::ATOMIZED, {(jschar *)UnitStringData + (c) * 2} } #ifdef __SUNPRO_CC #pragma pack(8) @@ -2743,9 +2749,9 @@ static const jschar Hundreds[] = { O25(0x30), O25(0x31), O25(0x32), O25(0x33), O25(0x34), O25(0x35) }; -#define L1(c) { 1 | JSString::ATOMIZED, {(jschar *)Hundreds + 2 + (c) * 4} } /* length 1: 0..9 */ -#define L2(c) { 2 | JSString::ATOMIZED, {(jschar *)Hundreds + 41 + (c - 10) * 4} } /* length 2: 10..99 */ -#define L3(c) { 3 | JSString::ATOMIZED, {(jschar *)Hundreds + (c - 100) * 4} } /* length 3: 100..255 */ +#define L1(c) { 1, 0, JSString::ATOMIZED, {(jschar *)Hundreds + 2 + (c) * 4} } /* length 1: 0..9 */ +#define L2(c) { 2, 0, JSString::ATOMIZED, {(jschar *)Hundreds + 41 + (c - 10) * 4} } /* length 2: 10..99 */ +#define L3(c) { 3, 0, JSString::ATOMIZED, {(jschar *)Hundreds + (c - 100) * 4} } /* length 3: 100..255 */ #ifdef __SUNPRO_CC #pragma pack(8) @@ -3156,18 +3162,10 @@ js_NewDependentString(JSContext *cx, JSString *base, size_t start, if (start == 0 && length == base->length()) return base; - if (start > JSString::MAX_DEPENDENT_START || - (start != 0 && length > JSString::MAX_DEPENDENT_LENGTH)) { - return js_NewStringCopyN(cx, base->chars() + start, length); - } - ds = js_NewGCString(cx); if (!ds) return NULL; - if (start == 0) - ds->initPrefix(base, length); - else - ds->initDependent(base, start, length); + ds->initDependent(base, start, length); #ifdef DEBUG { JSRuntime *rt = cx->runtime; @@ -5482,7 +5480,7 @@ Utf8ToOneUcs4Char(const uint8 *utf8Buffer, int utf8Length) return ucs4Char; } -#if defined DEBUG || defined JS_DUMP_PROPTREE_STATS +#ifdef DEBUG JS_FRIEND_API(size_t) js_PutEscapedStringImpl(char *buffer, size_t bufferSize, FILE *fp, diff --git a/js/src/jsstr.h b/js/src/jsstr.h index e9bd8059c2e9..f031a3d87e3e 100644 --- a/js/src/jsstr.h +++ b/js/src/jsstr.h @@ -73,7 +73,7 @@ JS_STATIC_ASSERT(JS_BITS_PER_WORD >= 32); /* * The GC-thing "string" type. * - * When the DEPENDENT bit of the mLength field is unset, the mChars field + * When the DEPENDENT bit of the mFlags field is unset, the mChars field * points to a flat character array owned by its GC-thing descriptor. The * array is terminated at index length by a zero character and the size of the * array in bytes is (length + 1) * sizeof(jschar). The terminator is purely a @@ -97,16 +97,6 @@ JS_STATIC_ASSERT(JS_BITS_PER_WORD >= 32); * string strongly referenced by the mBase field. The base member may point to * another dependent string if chars() has not been called yet. * - * The PREFIX flag determines the kind of the dependent string. When the flag - * is unset, the mLength field encodes both starting position relative to the - * base string and the number of characters in the dependent string, see - * DEPENDENT_START_MASK and DEPENDENT_LENGTH_MASK below for details. - * - * When the PREFIX flag is set, the dependent string is a prefix of the base - * string. The number of characters in the prefix is encoded using all non-flag - * bits of the mLength field and spans the same 0 .. SIZE_T_MAX/4 range as the - * length of the flat string. - * * NB: Always use the length() and chars() accessor methods. */ struct JSString { @@ -118,46 +108,33 @@ struct JSString { friend JSString * JS_FASTCALL js_ConcatStrings(JSContext *cx, JSString *left, JSString *right); + // Not private because we want to be able to use static + // initializers for them. Don't use these directly! size_t mLength; + size_t mOffset; + jsword mFlags; union { jschar *mChars; JSString *mBase; }; /* - * Definitions for flags stored in the high order bits of mLength. - * - * PREFIX and MUTABLE are two aliases for the same bit. PREFIX should be - * used only if DEPENDENT is set and MUTABLE should be used only if the - * string is flat. + * Definitions for flags stored in mFlags. * * ATOMIZED is used only with flat, immutable strings. */ - static const size_t DEPENDENT = JSSTRING_BIT(JS_BITS_PER_WORD - 1); - static const size_t PREFIX = JSSTRING_BIT(JS_BITS_PER_WORD - 2); - static const size_t MUTABLE = PREFIX; - static const size_t ATOMIZED = JSSTRING_BIT(JS_BITS_PER_WORD - 3); - static const size_t DEFLATED = JSSTRING_BIT(JS_BITS_PER_WORD - 4); -#if JS_BITS_PER_WORD > 32 - static const size_t LENGTH_BITS = 28; -#else - static const size_t LENGTH_BITS = JS_BITS_PER_WORD - 4; -#endif - static const size_t LENGTH_MASK = JSSTRING_BITMASK(LENGTH_BITS); - static const size_t DEPENDENT_LENGTH_BITS = 8; - static const size_t DEPENDENT_LENGTH_MASK = JSSTRING_BITMASK(DEPENDENT_LENGTH_BITS); - static const size_t DEPENDENT_START_BITS = LENGTH_BITS - DEPENDENT_LENGTH_BITS; - static const size_t DEPENDENT_START_SHIFT = DEPENDENT_LENGTH_BITS; - static const size_t DEPENDENT_START_MASK = JSSTRING_BITMASK(DEPENDENT_START_BITS); + static const size_t DEPENDENT = JSSTRING_BIT(1); + static const size_t MUTABLE = JSSTRING_BIT(2); + static const size_t ATOMIZED = JSSTRING_BIT(3); + static const size_t DEFLATED = JSSTRING_BIT(4); bool hasFlag(size_t flag) const { - return (mLength & flag) != 0; + return (mFlags & flag) != 0; } public: - static const size_t MAX_LENGTH = LENGTH_MASK; - static const size_t MAX_DEPENDENT_START = DEPENDENT_START_MASK; - static const size_t MAX_DEPENDENT_LENGTH = DEPENDENT_LENGTH_MASK; + /* Generous but sane length bound. */ + static const size_t MAX_LENGTH = (1 << 28); bool isDependent() const { return hasFlag(DEPENDENT); @@ -172,7 +149,7 @@ struct JSString { } void setDeflated() { - JS_ATOMIC_SET_MASK((jsword *) &mLength, DEFLATED); + JS_ATOMIC_SET_MASK(&mFlags, DEFLATED); } bool isMutable() const { @@ -188,7 +165,7 @@ struct JSString { } JS_ALWAYS_INLINE size_t length() const { - return isDependent() ? dependentLength() : flatLength(); + return mLength; } JS_ALWAYS_INLINE bool empty() const { @@ -196,25 +173,20 @@ struct JSString { } JS_ALWAYS_INLINE void getCharsAndLength(const jschar *&chars, size_t &length) { - if (isDependent()) { - length = dependentLength(); - chars = dependentChars(); - } else { - length = flatLength(); - chars = flatChars(); - } + chars = this->chars(); + length = this->length(); } JS_ALWAYS_INLINE void getCharsAndEnd(const jschar *&chars, const jschar *&end) { - end = isDependent() - ? dependentLength() + (chars = dependentChars()) - : flatLength() + (chars = flatChars()); + end = length() + (chars = this->chars()); } /* Specific flat string initializer and accessor methods. */ void initFlat(jschar *chars, size_t length) { JS_ASSERT(length <= MAX_LENGTH); mLength = length; + mOffset = 0; + mFlags = 0; mChars = chars; } @@ -223,19 +195,20 @@ struct JSString { return mChars; } - size_t flatLength() const { + JS_ALWAYS_INLINE size_t flatLength() const { JS_ASSERT(isFlat()); - return mLength & LENGTH_MASK; + return length(); } /* - * Special flat string initializer that preserves the JSSTR_DEFLATED flag. + * Special flat string initializer that preserves the DEFLATED flag. * Use this method when reinitializing an existing string which may be * hashed to its deflated bytes. Newborn strings must use initFlat. */ void reinitFlat(jschar *chars, size_t length) { - JS_ASSERT(length <= MAX_LENGTH); - mLength = (mLength & DEFLATED) | (length & ~DEFLATED); + mLength = length; + mOffset = 0; + mFlags = mFlags & DEFLATED; mChars = chars; } @@ -255,7 +228,7 @@ struct JSString { * only one thread can access the string (see previous property). * * Thus, when multiple threads access the string, JSString::flatSetAtomized - * is the only function that can update the mLength field of the string by + * is the only function that can update the mFlags field of the string by * changing the mutable bit from 0 to 1. We call the method only after the * string has been hashed. When some threads in js_ValueToStringId see that * the flag is set, it knows that the string was atomized. @@ -268,33 +241,34 @@ struct JSString { */ void flatSetAtomized() { JS_ASSERT(isFlat() && !isMutable()); - JS_STATIC_ASSERT(sizeof(mLength) == sizeof(jsword)); - JS_ATOMIC_SET_MASK((jsword *) &mLength, ATOMIZED); + JS_ATOMIC_SET_MASK(&mFlags, ATOMIZED); } void flatSetMutable() { JS_ASSERT(isFlat() && !isAtomized()); - mLength |= MUTABLE; + mFlags |= MUTABLE; } void flatClearMutable() { JS_ASSERT(isFlat()); if (hasFlag(MUTABLE)) - mLength &= ~MUTABLE; + mFlags &= ~MUTABLE; } void initDependent(JSString *bstr, size_t off, size_t len) { - JS_ASSERT(off <= MAX_DEPENDENT_START); - JS_ASSERT(len <= MAX_DEPENDENT_LENGTH); - mLength = DEPENDENT | (off << DEPENDENT_START_SHIFT) | len; + JS_ASSERT(len <= MAX_LENGTH); + mLength = len; + mOffset = off; + mFlags = DEPENDENT; mBase = bstr; } /* See JSString::reinitFlat. */ void reinitDependent(JSString *bstr, size_t off, size_t len) { - JS_ASSERT(off <= MAX_DEPENDENT_START); - JS_ASSERT(len <= MAX_DEPENDENT_LENGTH); - mLength = DEPENDENT | (mLength & DEFLATED) | (off << DEPENDENT_START_SHIFT) | len; + JS_ASSERT(len <= MAX_LENGTH); + mLength = len; + mOffset = off; + mFlags = DEPENDENT | (mFlags & DEFLATED); mBase = bstr; } @@ -303,11 +277,6 @@ struct JSString { return mBase; } - bool dependentIsPrefix() const { - JS_ASSERT(isDependent()); - return hasFlag(PREFIX); - } - JS_ALWAYS_INLINE jschar *dependentChars() { return dependentBase()->isDependent() ? js_GetDependentStringChars(this) @@ -315,39 +284,12 @@ struct JSString { } JS_ALWAYS_INLINE size_t dependentStart() const { - return dependentIsPrefix() - ? 0 - : ((mLength >> DEPENDENT_START_SHIFT) & DEPENDENT_START_MASK); + return mOffset; } JS_ALWAYS_INLINE size_t dependentLength() const { JS_ASSERT(isDependent()); - if (dependentIsPrefix()) - return mLength & LENGTH_MASK; - return mLength & DEPENDENT_LENGTH_MASK; - } - - void initPrefix(JSString *bstr, size_t len) { - JS_ASSERT(len <= MAX_LENGTH); - mLength = DEPENDENT | PREFIX | len; - mBase = bstr; - } - - /* See JSString::reinitFlat. */ - void reinitPrefix(JSString *bstr, size_t len) { - JS_ASSERT(len <= MAX_LENGTH); - mLength = DEPENDENT | PREFIX | (mLength & DEFLATED) | len; - mBase = bstr; - } - - JSString *prefixBase() const { - JS_ASSERT(isDependent() && dependentIsPrefix()); - return dependentBase(); - } - - void prefixSetBase(JSString *bstr) { - JS_ASSERT(isDependent() && dependentIsPrefix()); - mBase = bstr; + return length(); } static inline bool isUnitString(void *ptr) { diff --git a/js/src/jstracer.cpp b/js/src/jstracer.cpp index 15ac37d6ca36..2d98bce14044 100644 --- a/js/src/jstracer.cpp +++ b/js/src/jstracer.cpp @@ -3232,10 +3232,10 @@ GetUpvarStackOnTrace(JSContext* cx, uint32 upvarLevel, int32 slot, uint32 callDe // Parameters needed to access a value from a closure on trace. struct ClosureVarInfo { - jsid id; uint32 slot; +#ifdef DEBUG uint32 callDepth; - uint32 resolveFlags; +#endif }; /* @@ -3286,13 +3286,15 @@ GetFromClosure(JSContext* cx, JSObject* call, const ClosureVarInfo* cv, double* if (fp) { v = T::slots(fp)[slot]; } else { - JS_ASSERT(cv->resolveFlags != JSRESOLVE_INFER); - JSAutoResolveFlags rf(cx, cv->resolveFlags); -#ifdef DEBUG - JSBool rv = -#endif - js_GetPropertyHelper(cx, call, cv->id, JSGET_METHOD_BARRIER, &v); - JS_ASSERT(rv); + /* + * Get the value from the object. We know we have a Call object, and + * that our slot index is fine, so don't monkey around with calling the + * property getter (which just looks in the slot) or calling + * js_GetReservedSlot. Just get the slot directly. Note the static + * asserts in jsfun.cpp which make sure Call objects use dslots. + */ + JS_ASSERT(slot < T::slot_count(call)); + v = T::slots(call)[slot]; } JSTraceType type = getCoercedType(v); ValueToNative(cx, v, type, result); @@ -3301,8 +3303,28 @@ GetFromClosure(JSContext* cx, JSObject* call, const ClosureVarInfo* cv, double* struct ArgClosureTraits { - static inline uint32 adj_slot(JSStackFrame* fp, uint32 slot) { return fp->argc + slot; } + // Adjust our slot to point to the correct slot on the native stack. + // See also UpvarArgTraits. + static inline uint32 adj_slot(JSStackFrame* fp, uint32 slot) { return 2 + slot; } + + // Get the right frame slots to use our slot index with. + // See also UpvarArgTraits. static inline jsval* slots(JSStackFrame* fp) { return fp->argv; } + + // Get the right object slots to use our slot index with. + static inline jsval* slots(JSObject* obj) { + // We know Call objects use dslots. + return obj->dslots + slot_offset(obj); + } + // Get the offset of our object slots from the object's dslots pointer. + static inline uint32 slot_offset(JSObject* obj) { + return JSSLOT_START(&js_CallClass) + + CALL_CLASS_FIXED_RESERVED_SLOTS - JS_INITIAL_NSLOTS; + } + // Get the maximum slot index of this type that should be allowed + static inline uint16 slot_count(JSObject* obj) { + return js_GetCallObjectFunction(obj)->nargs; + } private: ArgClosureTraits(); }; @@ -3315,8 +3337,25 @@ GetClosureArg(JSContext* cx, JSObject* callee, const ClosureVarInfo* cv, double* struct VarClosureTraits { - static inline uint32 adj_slot(JSStackFrame* fp, uint32 slot) { return slot; } + // See documentation on ArgClosureTraits for what these functions + // should be doing. + // See also UpvarVarTraits. + static inline uint32 adj_slot(JSStackFrame* fp, uint32 slot) { return 3 + fp->argc + slot; } + + // See also UpvarVarTraits. static inline jsval* slots(JSStackFrame* fp) { return fp->slots; } + static inline jsval* slots(JSObject* obj) { + // We know Call objects use dslots. + return obj->dslots + slot_offset(obj); + } + static inline uint32 slot_offset(JSObject* obj) { + return JSSLOT_START(&js_CallClass) + + CALL_CLASS_FIXED_RESERVED_SLOTS - JS_INITIAL_NSLOTS + + js_GetCallObjectFunction(obj)->nargs; + } + static inline uint16 slot_count(JSObject* obj) { + return js_GetCallObjectFunction(obj)->u.i.nvars; + } private: VarClosureTraits(); }; @@ -6657,7 +6696,7 @@ LeaveTree(InterpState& state, VMSideExit* lr) op == JSOP_GETLOCALPROP || op == JSOP_LENGTH || op == JSOP_GETELEM || op == JSOP_CALLELEM || op == JSOP_SETPROP || op == JSOP_SETNAME || op == JSOP_SETMETHOD || - op == JSOP_SETELEM || op == JSOP_INITELEM || + op == JSOP_SETELEM || op == JSOP_INITELEM || op == JSOP_ENUMELEM || op == JSOP_INSTANCEOF); /* @@ -7941,8 +7980,12 @@ TraceRecorder::scopeChainProp(JSObject* chainHead, jsval*& vp, LIns*& ins, NameR return ARECORD_CONTINUE; } - if (obj == obj2 && OBJ_GET_CLASS(cx, obj) == &js_CallClass) - return InjectStatus(callProp(obj, prop, ATOM_TO_JSID(atom), vp, ins, nr)); + if (obj == obj2 && OBJ_GET_CLASS(cx, obj) == &js_CallClass) { + AbortableRecordingStatus status = + InjectStatus(callProp(obj, prop, ATOM_TO_JSID(atom), vp, ins, nr)); + obj->dropProperty(cx, prop); + return status; + } obj2->dropProperty(cx, prop); RETURN_STOP_A("fp->scopeChain is not global or active call object"); @@ -7962,7 +8005,7 @@ TraceRecorder::callProp(JSObject* obj, JSProperty* prop, jsid id, jsval*& vp, if (setflags && (sprop->attrs & JSPROP_READONLY)) RETURN_STOP("writing to a read-only property"); - uintN slot = sprop->shortid; + uintN slot = uint16(sprop->shortid); vp = NULL; uintN upvar_slot = SPROP_INVALID_SLOT; @@ -7973,7 +8016,8 @@ TraceRecorder::callProp(JSObject* obj, JSProperty* prop, jsid id, jsval*& vp, vp = &cfp->argv[slot]; upvar_slot = slot; nr.v = *vp; - } else if (sprop->getter == js_GetCallVar) { + } else if (sprop->getter == js_GetCallVar || + sprop->getter == js_GetCallVarChecked) { JS_ASSERT(slot < cfp->script->nslots); vp = &cfp->slots[slot]; upvar_slot = cx->fp->fun->nargs + slot; @@ -7981,7 +8025,9 @@ TraceRecorder::callProp(JSObject* obj, JSProperty* prop, jsid id, jsval*& vp, } else { RETURN_STOP("dynamic property of Call object"); } - obj->dropProperty(cx, prop); + + // Now assert that our use of sprop->shortid was in fact kosher. + JS_ASSERT(sprop->flags & SPROP_HAS_SHORTID); if (frameIfInRange(obj)) { // At this point we are guaranteed to be looking at an active call oject @@ -8003,7 +8049,6 @@ TraceRecorder::callProp(JSObject* obj, JSProperty* prop, jsid id, jsval*& vp, : JSGET_METHOD_BARRIER, &nr.v); JS_ASSERT(rv); - obj->dropProperty(cx, prop); } LIns* obj_ins; @@ -8011,34 +8056,67 @@ TraceRecorder::callProp(JSObject* obj, JSProperty* prop, jsid id, jsval*& vp, LIns* parent_ins = stobj_get_parent(get(&cx->fp->argv[-2])); CHECK_STATUS(traverseScopeChain(parent, parent_ins, obj, obj_ins)); - ClosureVarInfo* cv = new (traceAlloc()) ClosureVarInfo(); - cv->id = id; - cv->slot = slot; - cv->callDepth = callDepth; - cv->resolveFlags = cx->resolveFlags == JSRESOLVE_INFER - ? js_InferFlags(cx, 0) - : cx->resolveFlags; + LIns* call_ins; + if (!cfp) { + // Because the parent guard in guardCallee ensures this Call object + // will be the same object now and on trace, and because once a Call + // object loses its frame it never regains one, on trace we will also + // have a null private in the Call object. So all we need to do is + // write the value to the Call object's slot. + int32 dslot_index = slot; + if (sprop->getter == js_GetCallArg) { + JS_ASSERT(dslot_index < ArgClosureTraits::slot_count(obj)); + dslot_index += ArgClosureTraits::slot_offset(obj); + } else if (sprop->getter == js_GetCallVar || + sprop->getter == js_GetCallVarChecked) { + JS_ASSERT(dslot_index < VarClosureTraits::slot_count(obj)); + dslot_index += VarClosureTraits::slot_offset(obj); + } else { + RETURN_STOP("dynamic property of Call object"); + } - LIns* outp = lir->insAlloc(sizeof(double)); - LIns* args[] = { - outp, - INS_CONSTPTR(cv), - obj_ins, - cx_ins - }; - const CallInfo* ci; - if (sprop->getter == js_GetCallArg) - ci = &GetClosureArg_ci; - else - ci = &GetClosureVar_ci; + // Now assert that our use of sprop->shortid was in fact kosher. + JS_ASSERT(sprop->flags & SPROP_HAS_SHORTID); - LIns* call_ins = lir->insCall(ci, args); - JSTraceType type = getCoercedType(nr.v); - guard(true, - addName(lir->ins2(LIR_eq, call_ins, lir->insImm(type)), - "guard(type-stable name access)"), - BRANCH_EXIT); - ins = stackLoad(outp, type); + LIns* base = lir->insLoad(LIR_ldp, obj_ins, offsetof(JSObject, dslots)); + LIns* val_ins = lir->insLoad(LIR_ldp, base, dslot_index * sizeof(jsval)); + ins = unbox_jsval(obj->dslots[dslot_index], val_ins, snapshot(BRANCH_EXIT)); + } else { + ClosureVarInfo* cv = new (traceAlloc()) ClosureVarInfo(); + cv->slot = slot; +#ifdef DEBUG + cv->callDepth = callDepth; +#endif + + LIns* outp = lir->insAlloc(sizeof(double)); + LIns* args[] = { + outp, + INS_CONSTPTR(cv), + obj_ins, + cx_ins + }; + const CallInfo* ci; + if (sprop->getter == js_GetCallArg) { + ci = &GetClosureArg_ci; + } else if (sprop->getter == js_GetCallVar || + sprop->getter == js_GetCallVarChecked) { + ci = &GetClosureVar_ci; + } else { + RETURN_STOP("dynamic property of Call object"); + } + + // Now assert that our use of sprop->shortid was in fact kosher. + JS_ASSERT(sprop->flags & SPROP_HAS_SHORTID); + + call_ins = lir->insCall(ci, args); + + JSTraceType type = getCoercedType(nr.v); + guard(true, + addName(lir->ins2(LIR_eq, call_ins, lir->insImm(type)), + "guard(type-stable name access)"), + BRANCH_EXIT); + ins = stackLoad(outp, type); + } nr.tracked = false; nr.obj = obj; nr.obj_ins = obj_ins; @@ -8324,11 +8402,7 @@ TraceRecorder::ifop() lir->ins_eq0(lir->ins2(LIR_feq, v_ins, lir->insImmf(0)))); } else if (JSVAL_IS_STRING(v)) { cond = JSVAL_TO_STRING(v)->length() != 0; - x = lir->ins2(LIR_piand, - lir->insLoad(LIR_ldp, - v_ins, - (int)offsetof(JSString, mLength)), - INS_CONSTWORD(JSString::LENGTH_MASK)); + x = lir->insLoad(LIR_ldp, v_ins, offsetof(JSString, mLength)); } else { JS_NOT_REACHED("ifop"); return ARECORD_STOP; @@ -8641,6 +8715,11 @@ TraceRecorder::equalityHelper(jsval l, jsval r, LIns* l_ins, LIns* r_ins, if (GetPromotedType(l) == GetPromotedType(r)) { if (JSVAL_TAG(l) == JSVAL_OBJECT || JSVAL_IS_SPECIAL(l)) { + if (JSVAL_TAG(l) == JSVAL_OBJECT && l) { + JSClass *clasp = OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(l)); + if ((clasp->flags & JSCLASS_IS_EXTENDED) && ((JSExtendedClass*) clasp)->equality) + RETURN_STOP_A("Can't trace extended class equality operator"); + } if (JSVAL_TAG(l) == JSVAL_OBJECT) op = LIR_peq; cond = (l == r); @@ -9002,7 +9081,7 @@ DumpShape(JSObject* obj, const char* prefix) } fprintf(shapefp, "\n%s: shape %u flags %x\n", prefix, scope->shape, scope->flags); - for (JSScopeProperty* sprop = scope->lastProp; sprop; sprop = sprop->parent) { + for (JSScopeProperty* sprop = scope->lastProperty(); sprop; sprop = sprop->parent) { if (JSID_IS_ATOM(sprop->id)) { fprintf(shapefp, " %s", JS_GetStringBytes(JSVAL_TO_STRING(ID_TO_VALUE(sprop->id)))); } else { @@ -9552,31 +9631,6 @@ TraceRecorder::getThis(LIns*& this_ins) } -LIns* -TraceRecorder::getStringLength(LIns* str_ins) -{ - LIns* len_ins = lir->insLoad(LIR_ldp, str_ins, (int)offsetof(JSString, mLength)); - - LIns* masked_len_ins = lir->ins2(LIR_piand, - len_ins, - INS_CONSTWORD(JSString::LENGTH_MASK)); - - LIns* real_len = - lir->ins_choose(lir->ins_peq0(lir->ins2(LIR_piand, - len_ins, - INS_CONSTWORD(JSString::DEPENDENT))), - masked_len_ins, - lir->ins_choose(lir->ins_peq0(lir->ins2(LIR_piand, - len_ins, - INS_CONSTWORD(JSString::PREFIX))), - lir->ins2(LIR_piand, - len_ins, - INS_CONSTWORD(JSString::DEPENDENT_LENGTH_MASK)), - masked_len_ins, avmplus::AvmCore::use_cmov()), - avmplus::AvmCore::use_cmov()); - return p2i(real_len); -} - JS_REQUIRES_STACK bool TraceRecorder::guardClass(JSObject* obj, LIns* obj_ins, JSClass* clasp, VMSideExit* exit) { @@ -10189,9 +10243,8 @@ TraceRecorder::record_JSOP_NOT() return ARECORD_CONTINUE; } JS_ASSERT(JSVAL_IS_STRING(v)); - set(&v, lir->ins_peq0(lir->ins2(LIR_piand, - lir->insLoad(LIR_ldp, get(&v), (int)offsetof(JSString, mLength)), - INS_CONSTWORD(JSString::LENGTH_MASK)))); + set(&v, lir->ins_peq0(lir->insLoad(LIR_ldp, get(&v), + offsetof(JSString, mLength)))); return ARECORD_CONTINUE; } @@ -11215,7 +11268,7 @@ TraceRecorder::setProp(jsval &l, JSPropCacheEntry* entry, JSScopeProperty* sprop LIns* obj_ins = get(&l); JSScope* scope = OBJ_SCOPE(obj); - JS_ASSERT_IF(entry->vcap == PCVCAP_MAKE(entry->kshape, 0, 0), scope->has(sprop)); + JS_ASSERT_IF(entry->vcap == PCVCAP_MAKE(entry->kshape, 0, 0), scope->hasProperty(sprop)); // Fast path for CallClass. This is about 20% faster than the general case. v_ins = get(&v); @@ -11237,7 +11290,7 @@ TraceRecorder::setProp(jsval &l, JSPropCacheEntry* entry, JSScopeProperty* sprop jsuword pcval; CHECK_STATUS(guardPropertyCacheHit(obj_ins, map_ins, obj, obj2, entry, pcval)); JS_ASSERT(scope->object == obj2); - JS_ASSERT(scope->has(sprop)); + JS_ASSERT(scope->hasProperty(sprop)); JS_ASSERT_IF(obj2 != obj, sprop->attrs & JSPROP_SHARED); /* @@ -11279,13 +11332,15 @@ TraceRecorder::setCallProp(JSObject *callobj, LIns *callobj_ins, JSScopeProperty JSStackFrame *fp = frameIfInRange(callobj); if (fp) { if (sprop->setter == SetCallArg) { - jsint slot = JSVAL_TO_INT(SPROP_USERID(sprop)); + JS_ASSERT(sprop->flags & SPROP_HAS_SHORTID); + uintN slot = uint16(sprop->shortid); jsval *vp2 = &fp->argv[slot]; set(vp2, v_ins); return RECORD_CONTINUE; } if (sprop->setter == SetCallVar) { - jsint slot = JSVAL_TO_INT(SPROP_USERID(sprop)); + JS_ASSERT(sprop->flags & SPROP_HAS_SHORTID); + uintN slot = uint16(sprop->shortid); jsval *vp2 = &fp->slots[slot]; set(vp2, v_ins); return RECORD_CONTINUE; @@ -11293,6 +11348,37 @@ TraceRecorder::setCallProp(JSObject *callobj, LIns *callobj_ins, JSScopeProperty RETURN_STOP("can't trace special CallClass setter"); } + if (!callobj->getPrivate()) { + // Because the parent guard in guardCallee ensures this Call object + // will be the same object now and on trace, and because once a Call + // object loses its frame it never regains one, on trace we will also + // have a null private in the Call object. So all we need to do is + // write the value to the Call object's slot. + int32 dslot_index = uint16(sprop->shortid); + if (sprop->setter == SetCallArg) { + JS_ASSERT(dslot_index < ArgClosureTraits::slot_count(callobj)); + dslot_index += ArgClosureTraits::slot_offset(callobj); + } else if (sprop->setter == SetCallVar) { + JS_ASSERT(dslot_index < VarClosureTraits::slot_count(callobj)); + dslot_index += VarClosureTraits::slot_offset(callobj); + } else { + RETURN_STOP("can't trace special CallClass setter"); + } + + // Now assert that the shortid get we did above was ok. Have to do it + // after the RETURN_STOP above, since in that case we may in fact not + // have a valid shortid; but we don't use it in that case anyway. + JS_ASSERT(sprop->flags & SPROP_HAS_SHORTID); + + LIns* base = lir->insLoad(LIR_ldp, callobj_ins, offsetof(JSObject, dslots)); + lir->insStorei(box_jsval(v, v_ins), base, dslot_index * sizeof(jsval)); + return RECORD_CONTINUE; + } + + // This is the hard case: we have a JSStackFrame private, but it's not in + // range. During trace execution we may or may not have a JSStackFrame + // anymore. Call the standard builtins, which handle that situation. + // Set variables in off-trace-stack call objects by calling standard builtins. const CallInfo* ci = NULL; if (sprop->setter == SetCallArg) @@ -11825,11 +11911,11 @@ TraceRecorder::initOrSetPropertyByIndex(LIns* obj_ins, LIns* index_ins, jsval* r } JS_REQUIRES_STACK AbortableRecordingStatus -TraceRecorder::record_JSOP_SETELEM() +TraceRecorder::setElem(int lval_spindex, int idx_spindex, int v_spindex) { - jsval& v = stackval(-1); - jsval& idx = stackval(-2); - jsval& lval = stackval(-3); + jsval& v = stackval(v_spindex); + jsval& idx = stackval(idx_spindex); + jsval& lval = stackval(lval_spindex); if (JSVAL_IS_PRIMITIVE(lval)) RETURN_STOP_A("left JSOP_SETELEM operand is not an object"); @@ -11889,6 +11975,12 @@ TraceRecorder::record_JSOP_SETELEM() return ARECORD_CONTINUE; } +JS_REQUIRES_STACK AbortableRecordingStatus +TraceRecorder::record_JSOP_SETELEM() +{ + return setElem(-3, -2, -1); +} + JS_REQUIRES_STACK AbortableRecordingStatus TraceRecorder::record_JSOP_CALLNAME() { @@ -12082,6 +12174,16 @@ TraceRecorder::guardCallee(jsval& callee) stobj_get_private(callee_ins), INS_CONSTPTR(callee_obj->getPrivate())), branchExit); + + /* + * As long as we have this parent guard, we're guaranteed that if we record + * with a Call object which has a null getPrivate(), then on trace that + * Call object will continue to have a null private, because we're + * effectively guarding on Call object identity and Call objects can't pick + * up a stack frame once they have none. callProp and setCallProp depend + * on this and document where; if this guard is removed make sure to fix + * those methods. Search for the "parent guard" comments in them. + */ guard(true, lir->ins2(LIR_peq, stobj_get_parent(callee_ins), @@ -12543,7 +12645,7 @@ TraceRecorder::prop(JSObject* obj, LIns* obj_ins, uint32 *slotp, LIns** v_insp, if (PCVAL_IS_SPROP(pcval)) { sprop = PCVAL_TO_SPROP(pcval); - JS_ASSERT(OBJ_SCOPE(obj2)->has(sprop)); + JS_ASSERT(OBJ_SCOPE(obj2)->hasProperty(sprop)); if (setflags && !SPROP_HAS_STUB_SETTER(sprop)) RETURN_STOP_A("non-stub setter"); @@ -12957,7 +13059,7 @@ TraceRecorder::record_JSOP_INITPROP() JS_REQUIRES_STACK AbortableRecordingStatus TraceRecorder::record_JSOP_INITELEM() { - return record_JSOP_SETELEM(); + return setElem(-3, -2, -1); } JS_REQUIRES_STACK AbortableRecordingStatus @@ -13415,7 +13517,11 @@ TraceRecorder::record_JSOP_EVAL() JS_REQUIRES_STACK AbortableRecordingStatus TraceRecorder::record_JSOP_ENUMELEM() { - return ARECORD_STOP; + /* + * To quote from jsops.cpp's JSOP_ENUMELEM case: + * Funky: the value to set is under the [obj, id] pair. + */ + return setElem(-2, -1, -3); } JS_REQUIRES_STACK AbortableRecordingStatus @@ -14456,7 +14562,9 @@ TraceRecorder::record_JSOP_LENGTH() if (JSVAL_IS_PRIMITIVE(l)) { if (!JSVAL_IS_STRING(l)) RETURN_STOP_A("non-string primitive JSOP_LENGTH unsupported"); - set(&l, lir->ins1(LIR_i2f, getStringLength(get(&l)))); + set(&l, lir->ins1(LIR_i2f, + p2i(lir->insLoad(LIR_ldp, get(&l), + offsetof(JSString, mLength))))); return ARECORD_CONTINUE; } diff --git a/js/src/jstracer.h b/js/src/jstracer.h index 285bf71c6591..830bf8338d88 100644 --- a/js/src/jstracer.h +++ b/js/src/jstracer.h @@ -1231,8 +1231,6 @@ class TraceRecorder return stobj_get_fslot(obj_ins, JSSLOT_PARENT); } - nanojit::LIns* getStringLength(nanojit::LIns* str_ins); - JS_REQUIRES_STACK AbortableRecordingStatus name(jsval*& vp, nanojit::LIns*& ins, NameResult& nr); JS_REQUIRES_STACK AbortableRecordingStatus prop(JSObject* obj, nanojit::LIns* obj_ins, uint32 *slotp, nanojit::LIns** v_insp, jsval* outp); @@ -1273,6 +1271,8 @@ class TraceRecorder JS_REQUIRES_STACK RecordingStatus initOrSetPropertyByIndex(nanojit::LIns* obj_ins, nanojit::LIns* index_ins, jsval* rvalp, bool init); + JS_REQUIRES_STACK AbortableRecordingStatus setElem(int lval_spindex, int idx_spindex, + int v_spindex); JS_REQUIRES_STACK nanojit::LIns* box_jsval(jsval v, nanojit::LIns* v_ins); JS_REQUIRES_STACK nanojit::LIns* unbox_jsval(jsval v, nanojit::LIns* v_ins, VMSideExit* exit); diff --git a/js/src/tests/e4x/Regress/jstests.list b/js/src/tests/e4x/Regress/jstests.list index 331a3861fdb0..5a5793a1afb3 100644 --- a/js/src/tests/e4x/Regress/jstests.list +++ b/js/src/tests/e4x/Regress/jstests.list @@ -52,7 +52,7 @@ script regress-354145-03.js script regress-354145-04.js script regress-354145-05.js script regress-354145-07.js -script regress-354998.js +skip-if(!xulRuntime.shell&&isDebugBuild) script regress-354998.js # very slow; test needs revising script regress-355474-02.js script regress-355478.js script regress-355569.js diff --git a/js/src/tests/ecma_5/jstests.list b/js/src/tests/ecma_5/jstests.list index 7af95c439566..e6b81cbd7e7a 100644 --- a/js/src/tests/ecma_5/jstests.list +++ b/js/src/tests/ecma_5/jstests.list @@ -1,2 +1,3 @@ include Date/jstests.list include Object/jstests.list +include strict/jstests.list diff --git a/js/src/tests/ecma_5/strict/10.4.2.js b/js/src/tests/ecma_5/strict/10.4.2.js index 9500c7eccef4..1ddbe3535f3e 100644 --- a/js/src/tests/ecma_5/strict/10.4.2.js +++ b/js/src/tests/ecma_5/strict/10.4.2.js @@ -34,3 +34,5 @@ assertEq(completesNormally("Function('010')"), true); assertEq(raisesException(SyntaxError)("Function('\"use strict\"; 010')"), true); + +reportCompare(true, true); diff --git a/js/src/tests/ecma_5/strict/11.1.5.js b/js/src/tests/ecma_5/strict/11.1.5.js index f14b8ed34702..9c8bb597d630 100644 --- a/js/src/tests/ecma_5/strict/11.1.5.js +++ b/js/src/tests/ecma_5/strict/11.1.5.js @@ -138,3 +138,5 @@ assertEq(testLenientAndStrict('({x getter: function() {}, x getter: function() { parsesSuccessfully, parseRaisesException(SyntaxError)), true); + +reportCompare(true, true); diff --git a/js/src/tests/ecma_5/strict/11.13.1.js b/js/src/tests/ecma_5/strict/11.13.1.js index af26edbece79..299a24018c09 100644 --- a/js/src/tests/ecma_5/strict/11.13.1.js +++ b/js/src/tests/ecma_5/strict/11.13.1.js @@ -25,3 +25,5 @@ assertEq(testLenientAndStrict('(eval)=1', parsesSuccessfully, parseRaisesException(SyntaxError)), true); + +reportCompare(true, true); diff --git a/js/src/tests/ecma_5/strict/11.13.2.js b/js/src/tests/ecma_5/strict/11.13.2.js index 61fa49a219e0..b4cf054c9de8 100644 --- a/js/src/tests/ecma_5/strict/11.13.2.js +++ b/js/src/tests/ecma_5/strict/11.13.2.js @@ -25,3 +25,5 @@ assertEq(testLenientAndStrict('(eval)+=1', parsesSuccessfully, parseRaisesException(SyntaxError)), true); + +reportCompare(true, true); diff --git a/js/src/tests/ecma_5/strict/11.3.1.js b/js/src/tests/ecma_5/strict/11.3.1.js index afbcd81ed022..62a97e1721aa 100644 --- a/js/src/tests/ecma_5/strict/11.3.1.js +++ b/js/src/tests/ecma_5/strict/11.3.1.js @@ -25,3 +25,5 @@ assertEq(testLenientAndStrict('(eval)++', parsesSuccessfully, parseRaisesException(SyntaxError)), true); + +reportCompare(true, true); diff --git a/js/src/tests/ecma_5/strict/11.3.2.js b/js/src/tests/ecma_5/strict/11.3.2.js index 7a21a85fd68e..b44d5a4dbe31 100644 --- a/js/src/tests/ecma_5/strict/11.3.2.js +++ b/js/src/tests/ecma_5/strict/11.3.2.js @@ -25,3 +25,5 @@ assertEq(testLenientAndStrict('(eval)--', parsesSuccessfully, parseRaisesException(SyntaxError)), true); + +reportCompare(true, true); diff --git a/js/src/tests/ecma_5/strict/11.4.1.js b/js/src/tests/ecma_5/strict/11.4.1.js index fc4ff0b5be5c..f882555f33d0 100644 --- a/js/src/tests/ecma_5/strict/11.4.1.js +++ b/js/src/tests/ecma_5/strict/11.4.1.js @@ -37,3 +37,5 @@ assertEq(testLenientAndStrict('function f() { "use strict"; delete x; }', parseRaisesException(SyntaxError), parseRaisesException(SyntaxError)), true); + +reportCompare(true, true); diff --git a/js/src/tests/ecma_5/strict/11.4.4.js b/js/src/tests/ecma_5/strict/11.4.4.js index 319ec4731c1f..5d4cbb9377e1 100644 --- a/js/src/tests/ecma_5/strict/11.4.4.js +++ b/js/src/tests/ecma_5/strict/11.4.4.js @@ -25,3 +25,5 @@ assertEq(testLenientAndStrict('++(eval)', parsesSuccessfully, parseRaisesException(SyntaxError)), true); + +reportCompare(true, true); diff --git a/js/src/tests/ecma_5/strict/11.4.5.js b/js/src/tests/ecma_5/strict/11.4.5.js index 5dc689e103c9..d4cfba89e87b 100644 --- a/js/src/tests/ecma_5/strict/11.4.5.js +++ b/js/src/tests/ecma_5/strict/11.4.5.js @@ -25,3 +25,5 @@ assertEq(testLenientAndStrict('--(eval)', parsesSuccessfully, parseRaisesException(SyntaxError)), true); + +reportCompare(true, true); diff --git a/js/src/tests/ecma_5/strict/12.10.1.js b/js/src/tests/ecma_5/strict/12.10.1.js index 6cb4b6ed681a..161c08016201 100644 --- a/js/src/tests/ecma_5/strict/12.10.1.js +++ b/js/src/tests/ecma_5/strict/12.10.1.js @@ -26,3 +26,5 @@ assertEq(testLenientAndStrict('function f() { "use strict"; with (1) {} }', */ assertEq(parsesSuccessfully('function f() { "use strict"; }; with (1) {}'), true); + +reportCompare(true, true); diff --git a/js/src/tests/ecma_5/strict/12.14.1.js b/js/src/tests/ecma_5/strict/12.14.1.js index 8c5bb58e0a64..e6227884b6d2 100644 --- a/js/src/tests/ecma_5/strict/12.14.1.js +++ b/js/src/tests/ecma_5/strict/12.14.1.js @@ -33,3 +33,5 @@ assertEq(testLenientAndStrict('try{}catch({x:arguments}){}', parsesSuccessfully, parseRaisesException(SyntaxError)), true); + +reportCompare(true, true); diff --git a/js/src/tests/ecma_5/strict/12.2.1.js b/js/src/tests/ecma_5/strict/12.2.1.js index 63f2e5cad6e4..376c40bbe60d 100644 --- a/js/src/tests/ecma_5/strict/12.2.1.js +++ b/js/src/tests/ecma_5/strict/12.2.1.js @@ -21,3 +21,5 @@ assertEq(testLenientAndStrict('var x,arguments;', parsesSuccessfully, parseRaisesException(SyntaxError)), true); + +reportCompare(true, true); diff --git a/js/src/tests/ecma_5/strict/13.1.js b/js/src/tests/ecma_5/strict/13.1.js index c4438173c641..d9f0d65517c7 100644 --- a/js/src/tests/ecma_5/strict/13.1.js +++ b/js/src/tests/ecma_5/strict/13.1.js @@ -14,21 +14,21 @@ * The parameters of ordinary function definitions should not contain * duplicate identifiers. */ -assertEq(testLenientAndStrict('function(x,y) {}', +assertEq(testLenientAndStrict('function f(x,y) {}', parsesSuccessfully, parsesSuccessfully), true); -assertEq(testLenientAndStrict('function(x,x) {}', +assertEq(testLenientAndStrict('function f(x,x) {}', parsesSuccessfully, parseRaisesException(SyntaxError)), true); -assertEq(testLenientAndStrict('function(x,y,z,y) {}', +assertEq(testLenientAndStrict('function f(x,y,z,y) {}', parsesSuccessfully, parseRaisesException(SyntaxError)), true); /* Exercise the hashed local name map case. */ -assertEq(testLenientAndStrict('function(a,b,c,d,e,f,g,h,d) {}', +assertEq(testLenientAndStrict('function f(a,b,c,d,e,f,g,h,d) {}', parsesSuccessfully, parseRaisesException(SyntaxError)), true); @@ -37,15 +37,15 @@ assertEq(testLenientAndStrict('function(a,b,c,d,e,f,g,h,d) {}', * SpiderMonkey has always treated duplicates in destructuring * patterns as an error. Strict mode should not affect this. */ -assertEq(testLenientAndStrict('function([x,y]) {}', +assertEq(testLenientAndStrict('function f([x,y]) {}', parsesSuccessfully, parsesSuccessfully), true); -assertEq(testLenientAndStrict('function([x,x]){}', +assertEq(testLenientAndStrict('function f([x,x]){}', parseRaisesException(SyntaxError), parseRaisesException(SyntaxError)), true); -assertEq(testLenientAndStrict('function(x,[x]){}', +assertEq(testLenientAndStrict('function f(x,[x]){}', parseRaisesException(SyntaxError), parseRaisesException(SyntaxError)), true); @@ -54,7 +54,7 @@ assertEq(testLenientAndStrict('function(x,[x]){}', * Strict rules apply to the parameters if the function's body is * strict. */ -assertEq(testLenientAndStrict('function(x,x) { "use strict" };', +assertEq(testLenientAndStrict('function f(x,x) { "use strict" };', parseRaisesException(SyntaxError), parseRaisesException(SyntaxError)), true); @@ -410,3 +410,5 @@ assertEq(testLenientAndStrict('Function("arguments","\'use strict\';")', raisesException(SyntaxError)), true); + +reportCompare(true, true); diff --git a/js/src/tests/ecma_5/strict/8.7.2.js b/js/src/tests/ecma_5/strict/8.7.2.js index 0d9bff1f36bc..835ca7f9abc7 100644 --- a/js/src/tests/ecma_5/strict/8.7.2.js +++ b/js/src/tests/ecma_5/strict/8.7.2.js @@ -35,3 +35,5 @@ assertEq(testLenientAndStrict('undeclared_at_compiletime=1', parsesSuccessfully, parsesSuccessfully), true); + +reportCompare(true, true); diff --git a/js/src/tests/ecma_5/strict/B.1.1.js b/js/src/tests/ecma_5/strict/B.1.1.js index 63d5c4a101a3..bda0ba54d4a4 100644 --- a/js/src/tests/ecma_5/strict/B.1.1.js +++ b/js/src/tests/ecma_5/strict/B.1.1.js @@ -27,3 +27,5 @@ assertEq(parsesSuccessfully('function f() { "use strict"; }; 010'), /* Octal integer literal in function body */ assertEq(parsesSuccessfully('function f() { 010; }'), true); + +reportCompare(true, true); diff --git a/js/src/tests/ecma_5/strict/B.1.2.js b/js/src/tests/ecma_5/strict/B.1.2.js index a1a51d4376cb..570741e7655b 100644 --- a/js/src/tests/ecma_5/strict/B.1.2.js +++ b/js/src/tests/ecma_5/strict/B.1.2.js @@ -34,3 +34,5 @@ assertEq(testLenientAndStrict('"\\0x"', parsesSuccessfully, parsesSuccessfully), true); + +reportCompare(true, true); diff --git a/js/src/tests/ecma_5/strict/jstests.list b/js/src/tests/ecma_5/strict/jstests.list index 280f921b334f..43588b8ce29f 100644 --- a/js/src/tests/ecma_5/strict/jstests.list +++ b/js/src/tests/ecma_5/strict/jstests.list @@ -15,3 +15,5 @@ script 12.14.1.js script 13.1.js script B.1.1.js script B.1.2.js +script regress-532254.js +script regress-532041.js diff --git a/js/src/tests/ecma_5/strict/regress-532041.js b/js/src/tests/ecma_5/strict/regress-532041.js new file mode 100644 index 000000000000..5591264bf079 --- /dev/null +++ b/js/src/tests/ecma_5/strict/regress-532041.js @@ -0,0 +1,17 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ + +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + + +/* + * JSFunction::findDuplicateFormal (nee js_FindDuplicateFormal), used + * by strict checks, sometimes failed to choose the correct branch of + * the fun->u.i.names union: it used the argument count, not the + * overall name count. + */ +function f(a1,a2,a3,a4,a5) { "use strict"; var v1, v2, v3, v4, v5, v6, v7; } + +reportCompare(true, true); diff --git a/js/src/tests/ecma_5/strict/regress-532254.js b/js/src/tests/ecma_5/strict/regress-532254.js new file mode 100644 index 000000000000..e91e05b1a6a5 --- /dev/null +++ b/js/src/tests/ecma_5/strict/regress-532254.js @@ -0,0 +1,13 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ + +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +assertEq(testLenientAndStrict('function f(eval,[x]){}', + parsesSuccessfully, + parseRaisesException(SyntaxError)), + true); + +reportCompare(true, true); diff --git a/js/src/tests/js1_4/Eval/regress-531682.js b/js/src/tests/js1_4/Eval/regress-531682.js new file mode 100644 index 000000000000..25f5778807a8 --- /dev/null +++ b/js/src/tests/js1_4/Eval/regress-531682.js @@ -0,0 +1,35 @@ +/* -*- Mode: java; tab-width:8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var gTestfile = 'regress-531682.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 531682; +var summary = 'Checking proper wrapping of scope in eval(source, scope)'; +var actual; +var expect; + +//----------------------------------------------------------------------------- +var x = 0; + +test(); +//----------------------------------------------------------------------------- + +function scope1() { + eval('var x = 1;'); + return function() { return x; } +} + +function test() { + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + + // The scope chain in eval should be just scope1() and the global object. + actual = eval('x', scope1()); + expect = 0; + reportCompare(expect, actual, summary); + exitFunc ('test'); +} diff --git a/js/src/tests/js1_5/Regress/jstests.list b/js/src/tests/js1_5/Regress/jstests.list index 5e967d21d29d..29208f6c5fc2 100644 --- a/js/src/tests/js1_5/Regress/jstests.list +++ b/js/src/tests/js1_5/Regress/jstests.list @@ -209,7 +209,7 @@ script regress-360969-06.js script regress-361467.js script regress-361617.js skip script regress-362583.js # obsolete test -fails-if(xulRuntime.OS=="WINNT") random-if(xulRuntime.OS=="Linux"&&!xulRuntime.XPCOMABI.match(/x86_64/)) skip-if(xulRuntime.OS=="Linux"&&xulRuntime.XPCOMABI.match(/x86_64/)) script regress-3649-n.js # No test results on windows, sometimes no test results on 32 bit linux, hangs os/consumes ram/swap on 64bit linux. +skip script regress-3649-n.js # skip test due to random oom related errors. script regress-366122.js script regress-366468.js script regress-366601.js diff --git a/js/src/tests/js1_8/regress/regress-499524.js b/js/src/tests/js1_8/regress/regress-499524.js index c45508ece604..6c7a09d8093a 100644 --- a/js/src/tests/js1_8/regress/regress-499524.js +++ b/js/src/tests/js1_8/regress/regress-499524.js @@ -45,4 +45,6 @@ assertEq(isSyntaxError("function f(a,b,c,d,e,f,g,h,b,[y]){}"), true); assertEq(isSyntaxError("function f([y],a,b,c,d,e,f,g,h,a){}"), true); assertEq(isSyntaxError("function f([a],b,c,d,e,f,g,h,i,a){}"), true); assertEq(isSyntaxError("function f(a,b,c,d,e,f,g,h,i,[a]){}"), true); -reportCompare(isSyntaxError("function f(a,b,c,d,e,f,g,h,i,[a]){}"), true); +assertEq(isSyntaxError("function f(a,b,c,d,e,f,g,h,i,[a]){}"), true); + +reportCompare(true, true); diff --git a/js/src/tests/js1_8/regress/regress-532491.js b/js/src/tests/js1_8/regress/regress-532491.js new file mode 100644 index 000000000000..6a65a5124732 --- /dev/null +++ b/js/src/tests/js1_8/regress/regress-532491.js @@ -0,0 +1,71 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2008 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Andreas Gal + * + * 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 ***** */ + +var gTestfile = 'regress-532491.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 466128; +var summary = 'Assertion failure: staticLevel == script->staticLevel, at ../jsobj.cpp'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + + jit(false); + function f(foo) { + if (a % 2 == 1) { + try { + eval(foo); + } catch(e) {} + } + } + a = 1; + f("eval(\"x\")"); + f("x"); + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/src/tests/js1_8_1/jstests.list b/js/src/tests/js1_8_1/jstests.list index 1c313d3a70a3..8973b1c576e4 100644 --- a/js/src/tests/js1_8_1/jstests.list +++ b/js/src/tests/js1_8_1/jstests.list @@ -3,4 +3,5 @@ include extensions/jstests.list include JSON/jstests.list include regress/jstests.list include String/jstests.list +include strict/jstests.list include trace/jstests.list diff --git a/js/src/tests/js1_8_1/regress/jstests.list b/js/src/tests/js1_8_1/regress/jstests.list index 979779255031..5ec1a4917afd 100644 --- a/js/src/tests/js1_8_1/regress/jstests.list +++ b/js/src/tests/js1_8_1/regress/jstests.list @@ -83,3 +83,4 @@ script regress-515885.js skip-if(isDebugBuild&&!xulRuntime.shell) script regress-524743.js # hang script regress-522123.js script regress-524264.js +script regress-530879.js diff --git a/js/src/tests/js1_8_1/regress/regress-522123.js b/js/src/tests/js1_8_1/regress/regress-522123.js index 9704a967ad99..5d92ae8d3d74 100644 --- a/js/src/tests/js1_8_1/regress/regress-522123.js +++ b/js/src/tests/js1_8_1/regress/regress-522123.js @@ -66,3 +66,5 @@ function test() exitFunc ('test'); } + +reportCompare(true, true); diff --git a/js/src/tests/js1_8_1/regress/regress-530879.js b/js/src/tests/js1_8_1/regress/regress-530879.js new file mode 100644 index 000000000000..23dd1c73d065 --- /dev/null +++ b/js/src/tests/js1_8_1/regress/regress-530879.js @@ -0,0 +1,10 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributor: Jason Orendorff + */ +gTestfile = 'regress-530879'; +function f(a, b, c, d) { + yield arguments.length; +} +reportCompare(0, f().next(), "bug 530879"); diff --git a/js/src/tests/js1_8_1/strict/12.2.1.js b/js/src/tests/js1_8_1/strict/12.2.1.js index afd069b6c4e4..7cde4d0e63a0 100644 --- a/js/src/tests/js1_8_1/strict/12.2.1.js +++ b/js/src/tests/js1_8_1/strict/12.2.1.js @@ -70,3 +70,5 @@ assertEq(testLenientAndStrict('for (let {x:arguments} in [])break;', parsesSuccessfully, parseRaisesException(SyntaxError)), true); + +reportCompare(true, true); diff --git a/js/src/tests/js1_8_1/strict/8.7.2.js b/js/src/tests/js1_8_1/strict/8.7.2.js index 4f12fe3969dd..dbf0b50f0fe5 100644 --- a/js/src/tests/js1_8_1/strict/8.7.2.js +++ b/js/src/tests/js1_8_1/strict/8.7.2.js @@ -12,3 +12,5 @@ assertEq(testLenientAndStrict('let let_declared; let_declared=1', completesNormally, completesNormally), true); + +reportCompare(true, true); diff --git a/js/src/tests/js1_8_1/strict/generator-eval-arguments.js b/js/src/tests/js1_8_1/strict/generator-eval-arguments.js index b705700a9821..60470f9e1790 100644 --- a/js/src/tests/js1_8_1/strict/generator-eval-arguments.js +++ b/js/src/tests/js1_8_1/strict/generator-eval-arguments.js @@ -33,3 +33,5 @@ assertEq(testLenientAndStrict('(1 for ({x:arguments} in []))', parsesSuccessfully, parseRaisesException(SyntaxError)), true); + +reportCompare(true, true); diff --git a/js/src/tests/js1_8_1/strict/let-block-eval-arguments.js b/js/src/tests/js1_8_1/strict/let-block-eval-arguments.js index e8a506ce204f..295ee8091835 100644 --- a/js/src/tests/js1_8_1/strict/let-block-eval-arguments.js +++ b/js/src/tests/js1_8_1/strict/let-block-eval-arguments.js @@ -30,3 +30,5 @@ assertEq(testLenientAndStrict('let ({x:arguments}=1) {}', parsesSuccessfully, parseRaisesException(SyntaxError)), true); + +reportCompare(true, true); diff --git a/js/src/tests/js1_8_1/trace/regress-452498-01.js b/js/src/tests/js1_8_1/trace/regress-452498-01.js index 59a04c8434cb..862c3dc004b3 100644 --- a/js/src/tests/js1_8_1/trace/regress-452498-01.js +++ b/js/src/tests/js1_8_1/trace/regress-452498-01.js @@ -99,7 +99,7 @@ var timenonjit = f(false); var timejit = f(true); expect = true; -actual = timejit < timenonjit/2; +actual = timejit < timenonjit; print('time nonjit: ' + timenonjit + ', time jit: ' + timejit); diff --git a/js/src/tests/js1_8_1/trace/regress-469927.js b/js/src/tests/js1_8_1/trace/regress-469927.js index 1c3579a2bac4..4d0651f0dbdf 100644 --- a/js/src/tests/js1_8_1/trace/regress-469927.js +++ b/js/src/tests/js1_8_1/trace/regress-469927.js @@ -71,7 +71,7 @@ function test() print('time: nonjit = ' + timenonjit + ', jit = ' + timejit); expect = true; - actual = timejit < timenonjit/2; + actual = timejit < timenonjit; reportCompare(expect, actual, summary); diff --git a/js/src/tests/js1_8_1/trace/regress-470739.js b/js/src/tests/js1_8_1/trace/regress-470739.js index 0ad2b9a2f5bb..f48c66c1ae1b 100644 --- a/js/src/tests/js1_8_1/trace/regress-470739.js +++ b/js/src/tests/js1_8_1/trace/regress-470739.js @@ -73,7 +73,7 @@ function test() print('time: nonjit = ' + timenonjit + ', jit = ' + timejit); expect = true; - actual = timejit < timenonjit/2; + actual = timejit < timenonjit; reportCompare(expect, actual, summary); diff --git a/js/src/trace-test/tests/basic/bug532823.js b/js/src/trace-test/tests/basic/bug532823.js new file mode 100644 index 000000000000..c2b2dc6d5fbc --- /dev/null +++ b/js/src/trace-test/tests/basic/bug532823.js @@ -0,0 +1,23 @@ +function loop(f) { + var p; + for (var i = 0; i < 10; ++i) { + p = f(); + } + return p; +} + +function f(j, k) { + var g = function() { return k; } + + var ans = ''; + + for (k = 0; k < 5; ++k) { + ans += loop(g); + } + return ans; +} + +var t0 = new Date; +var actual = f(1); + +assertEq(actual, '01234'); diff --git a/js/src/trace-test/tests/basic/testGroupAssignment.js b/js/src/trace-test/tests/basic/testGroupAssignment.js new file mode 100644 index 000000000000..11ef77ae0727 --- /dev/null +++ b/js/src/trace-test/tests/basic/testGroupAssignment.js @@ -0,0 +1,22 @@ +assertEq( + (function () { + var arr = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32 ]; + + for (var i = 0; i < 4; ++i) { + var src = i * 8; + var dst = i * 8 + 7; + for (var j = 0; j < 4; ++j) { + [arr[dst--], arr[src++]] = [arr[src], arr[dst]]; + } + } + return arr; + })().toSource(), + "[7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8, 23, 22, 21, 20, 19, 18, 17, 16, 31, 30, 29, 28, 27, 26, 25, 24, 32]"); + +checkStats({ + recorderStarted: 2, + traceCompleted: 2, + sideExitIntoInterpreter: 3, + traceTriggered: 3 +}); diff --git a/js/src/xpconnect/src/XPCWrapper.h b/js/src/xpconnect/src/XPCWrapper.h index d88b1156fd8a..c81d5278ef6e 100644 --- a/js/src/xpconnect/src/XPCWrapper.h +++ b/js/src/xpconnect/src/XPCWrapper.h @@ -221,10 +221,8 @@ public: static JSBool IsSecurityWrapper(JSObject *wrapper) { JSClass *clasp = STOBJ_GET_CLASS(wrapper); - return clasp == &sXPC_COW_JSClass.base || - clasp == &sXPC_SJOW_JSClass.base || - clasp == &sXPC_SOW_JSClass.base || - clasp == &sXPC_XOW_JSClass.base; + return (clasp->flags & JSCLASS_IS_EXTENDED) && + ((JSExtendedClass*)clasp)->wrappedObject; } /** diff --git a/js/src/xpconnect/src/xpccomponents.cpp b/js/src/xpconnect/src/xpccomponents.cpp index 3c2b5b1a405a..a459ae77292d 100644 --- a/js/src/xpconnect/src/xpccomponents.cpp +++ b/js/src/xpconnect/src/xpccomponents.cpp @@ -3416,6 +3416,7 @@ ContextHolder::ContextHolder(JSContext *aOuterCx, JSObject *aSandbox) { if(mJSContext) { + JSAutoRequest ar(mJSContext); JS_SetOptions(mJSContext, JSOPTION_DONT_REPORT_UNCAUGHT | JSOPTION_PRIVATE_IS_NSISUPPORTS); diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index 32676923643c..82d135528418 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -87,7 +87,6 @@ #include "nsStyleChangeList.h" #include "nsIFormControl.h" #include "nsCSSAnonBoxes.h" -#include "nsCSSPseudoElements.h" #include "nsIDeviceContext.h" #include "nsTextFragment.h" #include "nsIAnonymousContentCreator.h" @@ -1380,9 +1379,10 @@ PRBool IsBorderCollapse(nsIFrame* aFrame) * Moves aFrameList from aOldParent to aNewParent. This updates the parent * pointer of the frames in the list, reparents their views as needed, and sets * the NS_FRAME_HAS_VIEW bit on aNewParent and its ancestors as needed. Then - * it sets the list as the initial child list on aNewParent. Note that this - * method differs from ReparentFrames in that it doesn't change the kids' style - * contexts. + * it sets the list as the initial child list on aNewParent, unless aNewParent + * either already has kids or has been reflowed; in that case it appends the + * new frames. Note that this method differs from ReparentFrames in that it + * doesn't change the kids' style contexts. */ // XXXbz Since this is only used for {ib} splits, could we just copy the view // bits from aOldParent to aNewParent and then use the @@ -1398,10 +1398,6 @@ MoveChildrenTo(nsPresContext* aPresContext, { NS_PRECONDITION(aOldParent->GetParent() == aNewParent->GetParent(), "Unexpected old and new parents"); - NS_PRECONDITION(aNewParent->GetChildList(nsnull).IsEmpty(), - "New parent should have no kids"); - NS_PRECONDITION(aNewParent->GetStateBits() & NS_FRAME_FIRST_REFLOW, - "New parent shouldn't have been reflowed yet"); if (aNewParent->HasView() || aOldParent->HasView()) { // Move the frames into the new view @@ -1425,7 +1421,12 @@ MoveChildrenTo(nsPresContext* aPresContext, aNewParent->AddStateBits(NS_FRAME_HAS_CHILD_WITH_VIEW); } - aNewParent->SetInitialChildList(nsnull, aFrameList); + if (aNewParent->GetChildList(nsnull).IsEmpty() && + (aNewParent->GetStateBits() & NS_FRAME_FIRST_REFLOW)) { + aNewParent->SetInitialChildList(nsnull, aFrameList); + } else { + aNewParent->AppendFrames(nsnull, aFrameList); + } } // ----------------------------------------------------------- @@ -1825,7 +1826,7 @@ nsCSSFrameConstructor::CreateGeneratedContentItem(nsFrameConstructorState& aStat nsIFrame* aParentFrame, nsIContent* aParentContent, nsStyleContext* aStyleContext, - nsIAtom* aPseudoElement, + nsCSSPseudoElements::Type aPseudoElement, FrameConstructionItemList& aItems) { // XXXbz is this ever true? @@ -1836,15 +1837,15 @@ nsCSSFrameConstructor::CreateGeneratedContentItem(nsFrameConstructorState& aStat // Probe for the existence of the pseudo-element nsRefPtr pseudoStyleContext; - pseudoStyleContext = styleSet->ProbePseudoStyleFor(aParentContent, - aPseudoElement, - aStyleContext); + pseudoStyleContext = styleSet->ProbePseudoElementStyle(aParentContent, + aPseudoElement, + aStyleContext); if (!pseudoStyleContext) return; // |ProbePseudoStyleFor| checked the 'display' property and the // |ContentCount()| of the 'content' property for us. nsCOMPtr nodeInfo; - nsIAtom* elemName = aPseudoElement == nsCSSPseudoElements::before ? + nsIAtom* elemName = aPseudoElement == nsCSSPseudoElements::ePseudo_before ? nsGkAtoms::mozgeneratedcontentbefore : nsGkAtoms::mozgeneratedcontentafter; nodeInfo = mDocument->NodeInfoManager()->GetNodeInfo(elemName, nsnull, kNameSpaceID_None); @@ -2031,7 +2032,7 @@ nsCSSFrameConstructor::ConstructTable(nsFrameConstructorState& aState, // create the pseudo SC for the outer table as a child of the inner SC nsRefPtr outerStyleContext; outerStyleContext = mPresShell->StyleSet()-> - ResolvePseudoStyleFor(content, nsCSSAnonBoxes::tableOuter, styleContext); + ResolveAnonymousBoxStyle(nsCSSAnonBoxes::tableOuter, styleContext); // Create the outer table frame which holds the caption and inner table frame nsIFrame* newFrame; @@ -2235,7 +2236,7 @@ nsCSSFrameConstructor::ConstructTableCell(nsFrameConstructorState& aState, // Resolve pseudo style and initialize the body cell frame nsRefPtr innerPseudoStyle; innerPseudoStyle = mPresShell->StyleSet()-> - ResolvePseudoStyleFor(content, nsCSSAnonBoxes::cellContent, styleContext); + ResolveAnonymousBoxStyle(nsCSSAnonBoxes::cellContent, styleContext); // Create a block frame that will format the cell's content PRBool isBlock; @@ -2670,9 +2671,8 @@ nsCSSFrameConstructor::ConstructRootFrame(nsIFrame** aNewFrame) nsIFrame* viewportFrame = nsnull; nsRefPtr viewportPseudoStyle; - viewportPseudoStyle = styleSet->ResolvePseudoStyleFor(nsnull, - nsCSSAnonBoxes::viewport, - nsnull); + viewportPseudoStyle = + styleSet->ResolveAnonymousBoxStyle(nsCSSAnonBoxes::viewport, nsnull); viewportFrame = NS_NewViewportFrame(mPresShell, viewportPseudoStyle); @@ -2864,9 +2864,8 @@ nsCSSFrameConstructor::SetUpDocElementContainingBlock(nsIContent* aDocElement) nsStyleSet* styleSet = mPresShell->StyleSet(); // If paginated, make sure we don't put scrollbars in if (!isScrollable) { - rootPseudoStyle = styleSet->ResolvePseudoStyleFor(nsnull, - rootPseudo, - viewportPseudoStyle); + rootPseudoStyle = styleSet->ResolveAnonymousBoxStyle(rootPseudo, + viewportPseudoStyle); } else { if (rootPseudo == nsCSSAnonBoxes::canvas) { rootPseudo = nsCSSAnonBoxes::scrolledCanvas; @@ -2883,9 +2882,8 @@ nsCSSFrameConstructor::SetUpDocElementContainingBlock(nsIContent* aDocElement) // resolve a context for the scrollframe nsRefPtr styleContext; - styleContext = styleSet->ResolvePseudoStyleFor(nsnull, - nsCSSAnonBoxes::viewportScroll, - viewportPseudoStyle); + styleContext = styleSet->ResolveAnonymousBoxStyle(nsCSSAnonBoxes::viewportScroll, + viewportPseudoStyle); // Note that the viewport scrollframe is always built with // overflow:auto style. This forces the scroll frame to create @@ -2958,9 +2956,8 @@ nsCSSFrameConstructor::ConstructPageFrame(nsIPresShell* aPresShell, nsStyleSet *styleSet = aPresShell->StyleSet(); nsRefPtr pagePseudoStyle; - pagePseudoStyle = styleSet->ResolvePseudoStyleFor(nsnull, - nsCSSAnonBoxes::page, - parentStyleContext); + pagePseudoStyle = styleSet->ResolveAnonymousBoxStyle(nsCSSAnonBoxes::page, + parentStyleContext); aPageFrame = NS_NewPageFrame(aPresShell, pagePseudoStyle); if (NS_UNLIKELY(!aPageFrame)) @@ -2971,9 +2968,9 @@ nsCSSFrameConstructor::ConstructPageFrame(nsIPresShell* aPresShell, aPageFrame->Init(nsnull, aParentFrame, aPrevPageFrame); nsRefPtr pageContentPseudoStyle; - pageContentPseudoStyle = styleSet->ResolvePseudoStyleFor(nsnull, - nsCSSAnonBoxes::pageContent, - pagePseudoStyle); + pageContentPseudoStyle = + styleSet->ResolveAnonymousBoxStyle(nsCSSAnonBoxes::pageContent, + pagePseudoStyle); nsIFrame* pageContentFrame = NS_NewPageContentFrame(aPresShell, pageContentPseudoStyle); if (NS_UNLIKELY(!pageContentFrame)) @@ -2991,9 +2988,8 @@ nsCSSFrameConstructor::ConstructPageFrame(nsIPresShell* aPresShell, mFixedContainingBlock = pageContentFrame; nsRefPtr canvasPseudoStyle; - canvasPseudoStyle = styleSet->ResolvePseudoStyleFor(nsnull, - nsCSSAnonBoxes::canvas, - pageContentPseudoStyle); + canvasPseudoStyle = styleSet->ResolveAnonymousBoxStyle(nsCSSAnonBoxes::canvas, + pageContentPseudoStyle); aCanvasFrame = NS_NewCanvasFrame(aPresShell, canvasPseudoStyle); if (NS_UNLIKELY(!aCanvasFrame)) @@ -3084,9 +3080,8 @@ nsCSSFrameConstructor::ConstructButtonFrame(nsFrameConstructorState& aState, nsRefPtr innerBlockContext; innerBlockContext = - mPresShell->StyleSet()->ResolvePseudoStyleFor(content, - nsCSSAnonBoxes::buttonContent, - styleContext); + mPresShell->StyleSet()->ResolveAnonymousBoxStyle(nsCSSAnonBoxes::buttonContent, + styleContext); nsIFrame* blockFrame = NS_NewBlockFrame(mPresShell, innerBlockContext, NS_BLOCK_FLOAT_MGR); @@ -3224,9 +3219,8 @@ nsCSSFrameConstructor::ConstructSelectFrame(nsFrameConstructorState& aState, // Resolve pseudo element style for the dropdown list nsRefPtr listStyle; - listStyle = mPresShell->StyleSet()->ResolvePseudoStyleFor(content, - nsCSSAnonBoxes::dropDownList, - styleContext); + listStyle = mPresShell->StyleSet()-> + ResolveAnonymousBoxStyle(nsCSSAnonBoxes::dropDownList, styleContext); // Create a listbox nsIFrame* listFrame = NS_NewListControlFrame(mPresShell, listStyle); @@ -3422,10 +3416,8 @@ nsCSSFrameConstructor::ConstructFieldSetFrame(nsFrameConstructorState& aState, // Resolve style and initialize the frame nsRefPtr fieldsetContentStyle; - fieldsetContentStyle = - mPresShell->StyleSet()->ResolvePseudoStyleFor(content, - nsCSSAnonBoxes::fieldsetContent, - styleContext); + fieldsetContentStyle = mPresShell->StyleSet()-> + ResolveAnonymousBoxStyle(nsCSSAnonBoxes::fieldsetContent, styleContext); nsIFrame* blockFrame = NS_NewBlockFrame(mPresShell, fieldsetContentStyle, NS_BLOCK_FLOAT_MGR | @@ -4391,9 +4383,8 @@ nsCSSFrameConstructor::BeginBuildingScrollFrame(nsFrameConstructorState& aState, // we used the style that was passed in. So resolve another one. nsStyleSet *styleSet = mPresShell->StyleSet(); - nsStyleContext* aScrolledChildStyle = styleSet->ResolvePseudoStyleFor(aContent, - aScrolledPseudo, - contentStyle).get(); + nsStyleContext* aScrolledChildStyle = + styleSet->ResolveAnonymousBoxStyle(aScrolledPseudo, contentStyle).get(); if (gfxScrollFrame) { gfxScrollFrame->SetInitialChildList(nsnull, anonymousItems); @@ -4752,9 +4743,9 @@ nsCSSFrameConstructor::FlushAccumulatedBlock(nsFrameConstructorState& aState, nsCSSAnonBoxes::mozMathMLAnonymousBlock)->GetStyleContext(); nsStyleSet *styleSet = mPresShell->StyleSet(); nsRefPtr blockContext; - blockContext = styleSet->ResolvePseudoStyleFor(aContent, - nsCSSAnonBoxes::mozMathMLAnonymousBlock, - parentContext); + blockContext = styleSet-> + ResolveAnonymousBoxStyle(nsCSSAnonBoxes::mozMathMLAnonymousBlock, + parentContext); // then, create a block frame that will wrap the child frames. Make it a // MathML frame so that Get(Absolute/Float)ContainingBlockFor know that this @@ -5067,8 +5058,7 @@ nsCSSFrameConstructor::ConstructSVGForeignObjectFrame(nsFrameConstructorState& a nsRefPtr innerPseudoStyle; innerPseudoStyle = mPresShell->StyleSet()-> - ResolvePseudoStyleFor(content, - nsCSSAnonBoxes::mozSVGForeignContent, styleContext); + ResolveAnonymousBoxStyle(nsCSSAnonBoxes::mozSVGForeignContent, styleContext); nsIFrame* blockFrame = NS_NewBlockFrame(mPresShell, innerPseudoStyle, NS_BLOCK_FLOAT_MGR | @@ -5111,8 +5101,8 @@ nsCSSFrameConstructor::AddPageBreakItem(nsIContent* aContent, // for user-modify.) pseudoStyle = mPresShell->StyleSet()-> - ResolvePseudoStyleFor(nsnull, nsCSSAnonBoxes::pageBreak, - aMainStyleContext->GetParent()); + ResolveAnonymousBoxStyle(nsCSSAnonBoxes::pageBreak, + aMainStyleContext->GetParent()); NS_ASSERTION(pseudoStyle->GetStyleDisplay()->mDisplay == NS_STYLE_DISPLAY_BLOCK, "Unexpected display"); @@ -5712,7 +5702,7 @@ AdjustAppendParentForAfterContent(nsPresContext* aPresContext, // of style first, since nsLayoutUtils::GetAfterFrame is sorta expensive. nsStyleContext* parentStyle = aParentFrame->GetStyleContext(); if (nsLayoutUtils::HasPseudoStyle(aContainer, parentStyle, - nsCSSPseudoElements::after, + nsCSSPseudoElements::ePseudo_after, aPresContext)) { nsIFrame* afterFrame = nsLayoutUtils::GetAfterFrame(aParentFrame); if (afterFrame) { @@ -5811,6 +5801,32 @@ nsCSSFrameConstructor::AppendFrames(nsFrameConstructorState& aState, // of an {ib} split, we may need to create additional {ib} siblings to parent // them. if (!nextSibling && IsFrameSpecial(aParentFrame)) { + // When we get here, our frame list might start with a block. If it does + // so, and aParentFrame is an inline, and it and all its previous + // continuations have no siblings, then put the initial blocks from the + // frame list into the previous block of the {ib} split. Note that we + // didn't want to stop at the block part of the split when figuring out + // initial parent, because that could screw up float parenting; it's easier + // to do this little fixup here instead. + if (aFrameList.NotEmpty() && !IsInlineOutside(aFrameList.FirstChild())) { + // See whether out trailing inline is empty + nsIFrame* firstContinuation = aParentFrame->GetFirstContinuation(); + if (firstContinuation->GetChildList(nsnull).IsEmpty()) { + // Our trailing inline is empty. Collect our starting blocks from + // aFrameList, get the right parent frame for them, and put them in. + nsFrameList::FrameLinkEnumerator firstNonBlockEnumerator = + FindFirstNonBlock(aFrameList); + nsFrameList blockKids = aFrameList.ExtractHead(firstNonBlockEnumerator); + NS_ASSERTION(blockKids.NotEmpty(), "No blocks?"); + + nsIFrame* prevBlock = + GetSpecialPrevSibling(firstContinuation)->GetLastContinuation(); + NS_ASSERTION(prevBlock, "Should have previous block here"); + + MoveChildrenTo(aState.mPresContext, aParentFrame, prevBlock, blockKids); + } + } + // We want to put some of the frames into this inline frame. nsFrameList::FrameLinkEnumerator firstBlockEnumerator(aFrameList); FindFirstBlock(firstBlockEnumerator); @@ -5836,8 +5852,9 @@ nsCSSFrameConstructor::AppendFrames(nsFrameConstructorState& aState, nsIPresShell::eTreeChange, NS_FRAME_HAS_DIRTY_CHILDREN); - return aState.mFrameManager->InsertFrames(aParentFrame->GetParent(), - nsnull, aParentFrame, ibSiblings); + // Recurse so we create new ib siblings as needed for aParentFrame's parent + return AppendFrames(aState, aParentFrame->GetParent(), ibSiblings, + aParentFrame); } return NS_OK; @@ -8021,15 +8038,26 @@ nsCSSFrameConstructor::DoContentStateChanged(nsIContent* aContent, } } -nsresult +void +nsCSSFrameConstructor::AttributeWillChange(nsIContent* aContent, + PRInt32 aNameSpaceID, + nsIAtom* aAttribute, + PRInt32 aModType) +{ + nsReStyleHint rshint = + mPresShell->FrameManager()->HasAttributeDependentStyle(aContent, + aAttribute, + aModType, + PR_FALSE); + PostRestyleEvent(aContent, rshint, NS_STYLE_HINT_NONE); +} + +void nsCSSFrameConstructor::AttributeChanged(nsIContent* aContent, PRInt32 aNameSpaceID, nsIAtom* aAttribute, - PRInt32 aModType, - PRUint32 aStateMask) + PRInt32 aModType) { - nsresult result = NS_OK; - // Hold onto the PresShell to prevent ourselves from being destroyed. // XXXbz how, exactly, would this attribute change cause us to be // destroyed from inside this function? @@ -8061,7 +8089,7 @@ nsCSSFrameConstructor::AttributeChanged(nsIContent* aContent, if (namespaceID == kNameSpaceID_XUL && (tag == nsGkAtoms::listitem || tag == nsGkAtoms::listcell)) - return NS_OK; + return; } if (aAttribute == nsGkAtoms::tooltiptext || @@ -8093,8 +8121,7 @@ nsCSSFrameConstructor::AttributeChanged(nsIContent* aContent, } // let the frame deal with it now, so we don't have to deal later - result = primaryFrame->AttributeChanged(aNameSpaceID, aAttribute, - aModType); + primaryFrame->AttributeChanged(aNameSpaceID, aAttribute, aModType); // XXXwaterson should probably check for special IB siblings // here, and propagate the AttributeChanged notification to // them, as well. Currently, inline frames don't do anything on @@ -8107,11 +8134,9 @@ nsCSSFrameConstructor::AttributeChanged(nsIContent* aContent, nsReStyleHint rshint = frameManager->HasAttributeDependentStyle(aContent, aAttribute, aModType, - aStateMask); + PR_TRUE); PostRestyleEvent(aContent, rshint, hint); - - return result; } void @@ -9239,8 +9264,9 @@ nsCSSFrameConstructor::GetFirstLetterStyle(nsIContent* aContent, { if (aContent) { return mPresShell->StyleSet()-> - ResolvePseudoStyleFor(aContent, - nsCSSPseudoElements::firstLetter, aStyleContext); + ResolvePseudoElementStyle(aContent, + nsCSSPseudoElements::ePseudo_firstLetter, + aStyleContext); } return nsnull; } @@ -9251,8 +9277,9 @@ nsCSSFrameConstructor::GetFirstLineStyle(nsIContent* aContent, { if (aContent) { return mPresShell->StyleSet()-> - ResolvePseudoStyleFor(aContent, - nsCSSPseudoElements::firstLine, aStyleContext); + ResolvePseudoElementStyle(aContent, + nsCSSPseudoElements::ePseudo_firstLine, + aStyleContext); } return nsnull; } @@ -9264,7 +9291,7 @@ nsCSSFrameConstructor::ShouldHaveFirstLetterStyle(nsIContent* aContent, nsStyleContext* aStyleContext) { return nsLayoutUtils::HasPseudoStyle(aContent, aStyleContext, - nsCSSPseudoElements::firstLetter, + nsCSSPseudoElements::ePseudo_firstLetter, mPresShell->GetPresContext()); } @@ -9284,7 +9311,7 @@ nsCSSFrameConstructor::ShouldHaveFirstLineStyle(nsIContent* aContent, { PRBool hasFirstLine = nsLayoutUtils::HasPseudoStyle(aContent, aStyleContext, - nsCSSPseudoElements::firstLine, + nsCSSPseudoElements::ePseudo_firstLine, mPresShell->GetPresContext()); if (hasFirstLine) { // But disable for fieldsets @@ -9510,9 +9537,7 @@ nsCSSFrameConstructor::CreateNeededTablePseudos(FrameConstructionItemList& aItem } nsRefPtr wrapperStyle = - mPresShell->StyleSet()->ResolvePseudoStyleFor(parentContent, - pseudoType, - parentStyle); + mPresShell->StyleSet()->ResolveAnonymousBoxStyle(pseudoType, parentStyle); FrameConstructionItem* newItem = new FrameConstructionItem(&pseudoData.mFCData, // Use the content of our parent frame @@ -9665,8 +9690,8 @@ nsCSSFrameConstructor::ProcessChildren(nsFrameConstructorState& aState, styleContext = nsFrame::CorrectStyleParentFrame(aFrame, nsnull)->GetStyleContext(); // Probe for generated content before - CreateGeneratedContentItem(aState, aFrame, aContent, - styleContext, nsCSSPseudoElements::before, + CreateGeneratedContentItem(aState, aFrame, aContent, styleContext, + nsCSSPseudoElements::ePseudo_before, itemsToConstruct); } @@ -9681,8 +9706,8 @@ nsCSSFrameConstructor::ProcessChildren(nsFrameConstructorState& aState, if (aCanHaveGeneratedContent) { // Probe for generated content after - CreateGeneratedContentItem(aState, aFrame, aContent, - styleContext, nsCSSPseudoElements::after, + CreateGeneratedContentItem(aState, aFrame, aContent, styleContext, + nsCSSPseudoElements::ePseudo_after, itemsToConstruct); } } @@ -9735,9 +9760,8 @@ nsCSSFrameConstructor::ProcessChildren(nsFrameConstructorState& aState, "FrameConstructor"); nsRefPtr blockSC = mPresShell->StyleSet()-> - ResolvePseudoStyleFor(aContent, - nsCSSAnonBoxes::mozXULAnonymousBlock, - frameStyleContext); + ResolveAnonymousBoxStyle(nsCSSAnonBoxes::mozXULAnonymousBlock, + frameStyleContext); nsIFrame *blockFrame = NS_NewBlockFrame(mPresShell, blockSC); // We might, in theory, want to set NS_BLOCK_FLOAT_MGR and // NS_BLOCK_MARGIN_ROOT, but I think it's a bad idea given that @@ -10687,8 +10711,7 @@ nsCSSFrameConstructor::ConstructBlock(nsFrameConstructorState& aState, // See if we need to create a view nsHTMLContainerFrame::CreateViewForFrame(columnSetFrame, PR_FALSE); blockStyle = mPresShell->StyleSet()-> - ResolvePseudoStyleFor(aContent, nsCSSAnonBoxes::columnContent, - aStyleContext); + ResolveAnonymousBoxStyle(nsCSSAnonBoxes::columnContent, aStyleContext); parent = columnSetFrame; *aNewFrame = columnSetFrame; @@ -10892,11 +10915,10 @@ nsCSSFrameConstructor::CreateIBSiblings(nsFrameConstructorState& aState, // Resolve the right style context for our anonymous blocks. nsRefPtr blockSC = mPresShell->StyleSet()-> - ResolvePseudoStyleFor(content, - aIsPositioned ? - nsCSSAnonBoxes::mozAnonymousPositionedBlock : - nsCSSAnonBoxes::mozAnonymousBlock, - styleContext); + ResolveAnonymousBoxStyle(aIsPositioned ? + nsCSSAnonBoxes::mozAnonymousPositionedBlock : + nsCSSAnonBoxes::mozAnonymousBlock, + styleContext); nsIFrame* lastNewInline = aInitialInline->GetFirstContinuation(); do { @@ -10974,8 +10996,8 @@ nsCSSFrameConstructor::BuildInlineChildItems(nsFrameConstructorState& aState, // Probe for generated content before nsStyleContext* const parentStyleContext = aParentItem.mStyleContext; nsIContent* const parentContent = aParentItem.mContent; - CreateGeneratedContentItem(aState, nsnull, parentContent, - parentStyleContext, nsCSSPseudoElements::before, + CreateGeneratedContentItem(aState, nsnull, parentContent, parentStyleContext, + nsCSSPseudoElements::ePseudo_before, aParentItem.mChildItems); ChildIterator iter, last; @@ -11002,13 +11024,33 @@ nsCSSFrameConstructor::BuildInlineChildItems(nsFrameConstructorState& aState, } // Probe for generated content after - CreateGeneratedContentItem(aState, nsnull, parentContent, - parentStyleContext, nsCSSPseudoElements::after, + CreateGeneratedContentItem(aState, nsnull, parentContent, parentStyleContext, + nsCSSPseudoElements::ePseudo_after, aParentItem.mChildItems); aParentItem.mIsAllInline = aParentItem.mChildItems.AreAllItemsInline(); } +// return whether it's ok to append (in the AppendFrames sense) to +// aParentFrame if our nextSibling is aNextSibling. aParentFrame must +// be an {ib} special inline. +static PRBool +IsSafeToAppendToSpecialInline(nsIFrame* aParentFrame, nsIFrame* aNextSibling) +{ + NS_PRECONDITION(IsInlineFrame(aParentFrame), + "Must have an inline parent here"); + do { + NS_ASSERTION(IsFrameSpecial(aParentFrame), "How is this not special?"); + if (aNextSibling || aParentFrame->GetNextContinuation() || + GetSpecialSibling(aParentFrame)) { + return PR_FALSE; + } + + aNextSibling = aParentFrame->GetNextSibling(); + aParentFrame = aParentFrame->GetParent(); + } while (IsInlineFrame(aParentFrame)); +} + PRBool nsCSSFrameConstructor::WipeContainingBlock(nsFrameConstructorState& aState, nsIFrame* aContainingBlock, @@ -11219,10 +11261,12 @@ nsCSSFrameConstructor::WipeContainingBlock(nsFrameConstructorState& aState, // Now we're adding kids including some blocks to an inline part of an // {ib} split. If we plan to call AppendFrames, and don't have a next // sibling for the new frames, and our parent is the last continuation of - // the last part of the {ib} split, then AppendFrames will handle things - // for us. Bail out in that case. - if (aIsAppend && !nextSibling && !aFrame->GetNextContinuation() && - !GetSpecialSibling(aFrame)) { + // the last part of the {ib} split, and the same is true of all our + // ancestor inlines (they have no following continuations and they're the + // last part of their {ib} splits and we'd be adding to the end for all + // of them), then AppendFrames will handle things for us. Bail out in + // that case. + if (aIsAppend && IsSafeToAppendToSpecialInline(aFrame, nextSibling)) { return PR_FALSE; } @@ -11621,8 +11665,7 @@ nsCSSFrameConstructor::RebuildAllStyleData(nsChangeHint aExtraHint) NS_UpdateHint(aExtraHint, mRebuildAllExtraHint); mRebuildAllExtraHint = nsChangeHint(0); - if (!mPresShell || !mPresShell->GetRootFrame() || - !mPresShell->GetPresContext()->IsDynamic()) + if (!mPresShell || !mPresShell->GetRootFrame()) return; nsAutoScriptBlocker scriptBlocker; diff --git a/layout/base/nsCSSFrameConstructor.h b/layout/base/nsCSSFrameConstructor.h index d947eab65373..6f9274190598 100644 --- a/layout/base/nsCSSFrameConstructor.h +++ b/layout/base/nsCSSFrameConstructor.h @@ -52,6 +52,7 @@ #include "nsHashKeys.h" #include "nsThreadUtils.h" #include "nsPageContentFrame.h" +#include "nsCSSPseudoElements.h" class nsIDocument; struct nsFrameItems; @@ -152,11 +153,14 @@ public: // WillDestroyFrameTree hasn't been called yet. void NotifyDestroyingFrame(nsIFrame* aFrame); - nsresult AttributeChanged(nsIContent* aContent, - PRInt32 aNameSpaceID, - nsIAtom* aAttribute, - PRInt32 aModType, - PRUint32 aStateMask); + void AttributeWillChange(nsIContent* aContent, + PRInt32 aNameSpaceID, + nsIAtom* aAttribute, + PRInt32 aModType); + void AttributeChanged(nsIContent* aContent, + PRInt32 aNameSpaceID, + nsIAtom* aAttribute, + PRInt32 aModType); void BeginUpdate(); void EndUpdate(); @@ -433,11 +437,11 @@ private: PRUint32 aContentIndex); // aFrame may be null; this method doesn't use it directly in any case. - void CreateGeneratedContentItem(nsFrameConstructorState& aState, - nsIFrame* aFrame, - nsIContent* aContent, - nsStyleContext* aStyleContext, - nsIAtom* aPseudoElement, + void CreateGeneratedContentItem(nsFrameConstructorState& aState, + nsIFrame* aFrame, + nsIContent* aContent, + nsStyleContext* aStyleContext, + nsCSSPseudoElements::Type aPseudoElement, FrameConstructionItemList& aItems); // This method can change aFrameList: it can chop off the beginning and put diff --git a/layout/base/nsDocumentViewer.cpp b/layout/base/nsDocumentViewer.cpp index 24e2512f0fe6..079b70fe6f2f 100644 --- a/layout/base/nsDocumentViewer.cpp +++ b/layout/base/nsDocumentViewer.cpp @@ -498,7 +498,7 @@ protected: PRPackedBool mIsPageMode; PRPackedBool mCallerIsClosingWindow; - + PRPackedBool mInitializedForPrintPreview; }; //------------------------------------------------------------------ @@ -540,11 +540,10 @@ void DocumentViewerImpl::PrepareToStartLoad() if (mPrintEngine) { mPrintEngine->Destroy(); mPrintEngine = nsnull; - } - #ifdef NS_PRINT_PREVIEW - SetIsPrintPreview(PR_FALSE); + SetIsPrintPreview(PR_FALSE); #endif + } #ifdef NS_DEBUG mDebugFile = nsnull; @@ -560,7 +559,8 @@ DocumentViewerImpl::DocumentViewerImpl() #ifdef NS_PRINT_PREVIEW mPrintPreviewZoom(1.0), #endif - mHintCharsetSource(kCharsetUninitialized) + mHintCharsetSource(kCharsetUninitialized), + mInitializedForPrintPreview(PR_FALSE) { PrepareToStartLoad(); } @@ -700,6 +700,9 @@ DocumentViewerImpl::Init(nsIWidget* aParentWidget, nsresult DocumentViewerImpl::InitPresentationStuff(PRBool aDoInitialReflow, PRBool aReenableRefresh) { + if (GetIsPrintPreview()) + return NS_OK; + NS_ASSERTION(!mPresShell, "Someone should have destroyed the presshell!"); @@ -1700,14 +1703,16 @@ DocumentViewerImpl::SetDOMDocument(nsIDOMDocument *aDocument) // Clear the list of old child docshells. CChild docshells for the new // document will be constructed as frames are created. - nsCOMPtr node = do_QueryInterface(container); - if (node) { - PRInt32 count; - node->GetChildCount(&count); - for (PRInt32 i = 0; i < count; ++i) { - nsCOMPtr child; - node->GetChildAt(0, getter_AddRefs(child)); - node->RemoveChild(child); + if (!newDoc->IsStaticDocument()) { + nsCOMPtr node = do_QueryInterface(container); + if (node) { + PRInt32 count; + node->GetChildCount(&count); + for (PRInt32 i = 0; i < count; ++i) { + nsCOMPtr child; + node->GetChildAt(0, getter_AddRefs(child)); + node->RemoveChild(child); + } } } } @@ -1767,37 +1772,19 @@ DocumentViewerImpl::GetDocument(nsIDocument** aResult) nsIPresShell* DocumentViewerImpl::GetPresShell() { - if (!GetIsPrintPreview()) { - return mPresShell; - } - NS_ENSURE_TRUE(mDocument, nsnull); - nsCOMPtr shell; - nsCOMPtr currentShell; - nsPresShellIterator iter(mDocument); - while ((shell = iter.GetNextShell())) { - currentShell.swap(shell); - } - return currentShell.get(); + return mPresShell; } nsPresContext* DocumentViewerImpl::GetPresContext() { - if (!GetIsPrintPreview()) { - return mPresContext; - } - nsIPresShell* shell = GetPresShell(); - return shell ? shell->GetPresContext() : nsnull; + return mPresContext; } nsIViewManager* DocumentViewerImpl::GetViewManager() { - if (!GetIsPrintPreview()) { - return mViewManager; - } - nsIPresShell* shell = GetPresShell(); - return shell ? shell->GetViewManager() : nsnull; + return mViewManager; } NS_IMETHODIMP @@ -2011,8 +1998,10 @@ DocumentViewerImpl::Show(void) // window is shown because some JS on the page caused it to be // shown... - nsCOMPtr shellDeathGrip(mPresShell); // bug 378682 - mPresShell->UnsuppressPainting(); + if (mPresShell) { + nsCOMPtr shellDeathGrip(mPresShell); // bug 378682 + mPresShell->UnsuppressPainting(); + } } return NS_OK; @@ -2285,8 +2274,10 @@ DocumentViewerImpl::ClearHistoryEntry() nsresult DocumentViewerImpl::MakeWindow(const nsSize& aSize, nsIView* aContainerView) { - nsresult rv; + if (GetIsPrintPreview()) + return NS_OK; + nsresult rv; mViewManager = do_CreateInstance(kViewManagerCID, &rv); if (NS_FAILED(rv)) return rv; @@ -3774,6 +3765,10 @@ DocumentViewerImpl::PrintPreview(nsIPrintSettings* aPrintSettings, nsIWebProgressListener* aWebProgressListener) { #if defined(NS_PRINTING) && defined(NS_PRINT_PREVIEW) + NS_WARN_IF_FALSE(IsInitializedForPrintPreview(), + "Using docshell.printPreview is the preferred way for print previewing!"); + + NS_ENSURE_ARG_POINTER(aChildDOMWin); nsresult rv = NS_OK; if (GetIsPrinting()) { @@ -3791,25 +3786,23 @@ DocumentViewerImpl::PrintPreview(nsIPrintSettings* aPrintSettings, } #endif - if (!mContainer) { - PR_PL(("Container was destroyed yet we are still trying to use it!")); - return NS_ERROR_FAILURE; - } - nsCOMPtr docShell(do_QueryReferent(mContainer)); NS_ASSERTION(docShell, "This has to be a docshell"); - nsCOMPtr presShell; - docShell->GetPresShell(getter_AddRefs(presShell)); - if (!presShell || !mDocument || !mDeviceContext || !mParentWidget) { - PR_PL(("Can't Print Preview without pres shell, document etc")); + if (!docShell ||! mDeviceContext || !mParentWidget) { + PR_PL(("Can't Print Preview without device context, docshell etc")); return NS_ERROR_FAILURE; } if (!mPrintEngine) { + nsCOMPtr domDoc; + aChildDOMWin->GetDocument(getter_AddRefs(domDoc)); + nsCOMPtr doc = do_QueryInterface(domDoc); + NS_ENSURE_STATE(doc); + mPrintEngine = new nsPrintEngine(); NS_ENSURE_TRUE(mPrintEngine, NS_ERROR_OUT_OF_MEMORY); - rv = mPrintEngine->Initialize(this, docShell, mDocument, + rv = mPrintEngine->Initialize(this, docShell, doc, float(mDeviceContext->AppUnitsPerInch()) / float(mDeviceContext->AppUnitsPerDevPixel()) / mPageZoom, @@ -4224,6 +4217,12 @@ DocumentViewerImpl::SetIsPrintPreview(PRBool aIsPrintPreview) SetIsPrintingInDocShellTree(docShellTreeNode, aIsPrintPreview, PR_TRUE); } #endif + if (!aIsPrintPreview) { + mWindow = nsnull; + mViewManager = nsnull; + mPresContext = nsnull; + mPresShell = nsnull; + } } //---------------------------------------------------------------------------------- @@ -4256,14 +4255,13 @@ DocumentViewerImpl::ReturnToGalleyPresentation() mPrintEngine->Destroy(); mPrintEngine = nsnull; - mViewManager->EnableRefresh(NS_VMREFRESH_DEFERRED); + if (mViewManager) { + mViewManager->EnableRefresh(NS_VMREFRESH_DEFERRED); + } nsCOMPtr docShell(do_QueryReferent(mContainer)); ResetFocusState(docShell); - if (mPresContext) - mPresContext->RestoreImageAnimationMode(); - SetTextZoom(mTextZoom); SetFullZoom(mPageZoom); Show(); @@ -4335,8 +4333,6 @@ DocumentViewerImpl::OnDonePrinting() } mClosingWhilePrinting = PR_FALSE; } - if (mPresContext) - mPresContext->RestoreImageAnimationMode(); } #endif // NS_PRINTING && NS_PRINT_PREVIEW } @@ -4402,3 +4398,31 @@ DocumentViewerImpl::DestroyPresShell() mPresShell->Destroy(); mPresShell = nsnull; } + +PRBool +DocumentViewerImpl::IsInitializedForPrintPreview() +{ + return mInitializedForPrintPreview; +} + +void +DocumentViewerImpl::InitializeForPrintPreview() +{ + mInitializedForPrintPreview = PR_TRUE; +} + +void +DocumentViewerImpl::SetPrintPreviewPresentation(nsIWidget* aWidget, + nsIViewManager* aViewManager, + nsPresContext* aPresContext, + nsIPresShell* aPresShell) +{ + if (mPresShell) { + DestroyPresShell(); + } + + mWindow = aWidget; + mViewManager = aViewManager; + mPresContext = aPresContext; + mPresShell = aPresShell; +} diff --git a/layout/base/nsFrameManager.cpp b/layout/base/nsFrameManager.cpp index 8cba1d283d31..3b4cf4952f84 100644 --- a/layout/base/nsFrameManager.cpp +++ b/layout/base/nsFrameManager.cpp @@ -949,6 +949,7 @@ TryStartingTransition(nsPresContext *aPresContext, nsIContent *aContent, *aNewStyleContext = aPresContext->StyleSet()->ResolveStyleForRules( (*aNewStyleContext)->GetParent(), (*aNewStyleContext)->GetPseudo(), + (*aNewStyleContext)->GetPseudoType(), (*aNewStyleContext)->GetRuleNode(), rules); } @@ -1233,6 +1234,7 @@ nsFrameManager::ReResolveStyleContext(nsPresContext *aPresContext, if (oldContext) { oldContext->AddRef(); nsIAtom* const pseudoTag = oldContext->GetPseudo(); + const nsCSSPseudoElements::Type pseudoType = oldContext->GetPseudoType(); nsIContent* localContent = aFrame->GetContent(); // |content| is the node that we used for rule matching of // normal elements (not pseudo-elements) and for which we generate @@ -1334,9 +1336,9 @@ nsFrameManager::ReResolveStyleContext(nsPresContext *aPresContext, if (pseudoTag == nsCSSPseudoElements::before || pseudoTag == nsCSSPseudoElements::after) { // XXX what other pseudos do we need to treat like this? - newContext = styleSet->ProbePseudoStyleFor(pseudoContent, - pseudoTag, - parentContext); + newContext = styleSet->ProbePseudoElementStyle(pseudoContent, + pseudoType, + parentContext); if (!newContext) { // This pseudo should no longer exist; gotta reframe NS_UpdateHint(aMinChange, nsChangeHint_ReconstructFrame); @@ -1345,18 +1347,24 @@ nsFrameManager::ReResolveStyleContext(nsPresContext *aPresContext, // We're reframing anyway; just keep the same context newContext = oldContext; } + } else if (pseudoType == nsCSSPseudoElements::ePseudo_AnonBox) { + newContext = styleSet->ResolveAnonymousBoxStyle(pseudoTag, + parentContext); } else { + // Don't expect XUL tree stuff here, since it needs a comparator and + // all. + NS_ASSERTION(pseudoType < + nsCSSPseudoElements::ePseudo_PseudoElementCount, + "Unexpected pseudo type"); if (pseudoTag == nsCSSPseudoElements::firstLetter) { NS_ASSERTION(aFrame->GetType() == nsGkAtoms::letterFrame, "firstLetter pseudoTag without a nsFirstLetterFrame"); nsBlockFrame* block = nsBlockFrame::GetNearestAncestorBlock(aFrame); pseudoContent = block->GetContent(); - } else if (pseudoTag == nsCSSAnonBoxes::pageBreak) { - pseudoContent = nsnull; } - newContext = styleSet->ResolvePseudoStyleFor(pseudoContent, - pseudoTag, - parentContext); + newContext = styleSet->ResolvePseudoElementStyle(pseudoContent, + pseudoType, + parentContext); } } else { @@ -1406,12 +1414,25 @@ nsFrameManager::ReResolveStyleContext(nsPresContext *aPresContext, if (oldExtraContext) { nsRefPtr newExtraContext; nsIAtom* const extraPseudoTag = oldExtraContext->GetPseudo(); + const nsCSSPseudoElements::Type extraPseudoType = + oldExtraContext->GetPseudoType(); NS_ASSERTION(extraPseudoTag && extraPseudoTag != nsCSSAnonBoxes::mozNonElement, "extra style context is not pseudo element"); - newExtraContext = styleSet->ResolvePseudoStyleFor(content, - extraPseudoTag, - newContext); + if (extraPseudoType == nsCSSPseudoElements::ePseudo_AnonBox) { + newExtraContext = styleSet->ResolveAnonymousBoxStyle(extraPseudoTag, + newContext); + } + else { + // Don't expect XUL tree stuff here, since it needs a comparator and + // all. + NS_ASSERTION(extraPseudoType < + nsCSSPseudoElements::ePseudo_PseudoElementCount, + "Unexpected type"); + newExtraContext = styleSet->ResolvePseudoElementStyle(content, + extraPseudoType, + newContext); + } if (newExtraContext) { if (oldExtraContext != newExtraContext) { aMinChange = CaptureChange(oldExtraContext, newExtraContext, @@ -1489,7 +1510,7 @@ nsFrameManager::ReResolveStyleContext(nsPresContext *aPresContext, // :before style context. if (!nsLayoutUtils::GetBeforeFrame(aFrame) && nsLayoutUtils::HasPseudoStyle(localContent, newContext, - nsCSSPseudoElements::before, + nsCSSPseudoElements::ePseudo_before, aPresContext)) { // Have to create the new :before frame NS_UpdateHint(aMinChange, nsChangeHint_ReconstructFrame); @@ -1515,7 +1536,7 @@ nsFrameManager::ReResolveStyleContext(nsPresContext *aPresContext, // Getting the :after frame is more expensive than getting the pseudo // context, so get the pseudo context first. if (nsLayoutUtils::HasPseudoStyle(localContent, newContext, - nsCSSPseudoElements::after, + nsCSSPseudoElements::ePseudo_after, aPresContext) && !nsLayoutUtils::GetAfterFrame(aFrame)) { // have to create the new :after frame @@ -1686,15 +1707,15 @@ nsReStyleHint nsFrameManager::HasAttributeDependentStyle(nsIContent *aContent, nsIAtom *aAttribute, PRInt32 aModType, - PRUint32 aStateMask) + PRBool aAttrHasChanged) { nsReStyleHint hint = mStyleSet->HasAttributeDependentStyle(GetPresContext(), aContent, aAttribute, aModType, - aStateMask); + aAttrHasChanged); - if (aAttribute == nsGkAtoms::style) { + if (aAttrHasChanged && aAttribute == nsGkAtoms::style) { // Perhaps should check that it's XUL, SVG, (or HTML) namespace, but // it doesn't really matter. Or we could even let // HTMLCSSStyleSheetImpl::HasAttributeDependentStyle handle it. diff --git a/layout/base/nsFrameManager.h b/layout/base/nsFrameManager.h index 1bc0d174c63d..b6f218621ed3 100644 --- a/layout/base/nsFrameManager.h +++ b/layout/base/nsFrameManager.h @@ -191,10 +191,12 @@ public: nsChangeHint aMinChange); // Determine whether an attribute affects style + // If aAttrHasChanged is false, the attribute's value is about to + // change. If it's true, it has already changed. NS_HIDDEN_(nsReStyleHint) HasAttributeDependentStyle(nsIContent *aContent, nsIAtom *aAttribute, PRInt32 aModType, - PRUint32 aStateMask); + PRBool aAttrHasChanged); /* * Capture/restore frame state for the frame subtree rooted at aFrame. diff --git a/layout/base/nsIDocumentViewerPrint.h b/layout/base/nsIDocumentViewerPrint.h index 57bebe8ce2c6..0f5ddb35cba7 100644 --- a/layout/base/nsIDocumentViewerPrint.h +++ b/layout/base/nsIDocumentViewerPrint.h @@ -41,10 +41,15 @@ class nsIDocument; class nsStyleSet; +class nsIPresShell; +class nsPresContext; +class nsIWidget; +class nsIViewManager; -// {D0B7F354-D575-43fd-903D-5AA35A193EDA} +// {c6f255cf-cadd-4382-b57f-cd2a9874169b} #define NS_IDOCUMENT_VIEWER_PRINT_IID \ - { 0xd0b7f354, 0xd575, 0x43fd, { 0x90, 0x3d, 0x5a, 0xa3, 0x5a, 0x19, 0x3e, 0xda } } +{ 0xc6f255cf, 0xcadd, 0x4382, \ + { 0xb5, 0x7f, 0xcd, 0x2a, 0x98, 0x74, 0x16, 0x9b } } /** * A DocumentViewerPrint is an INTERNAL Interface used for interaction @@ -72,6 +77,23 @@ public: virtual void OnDonePrinting() = 0; + /** + * Returns PR_TRUE is InitializeForPrintPreview() has been called. + */ + virtual PRBool IsInitializedForPrintPreview() = 0; + + /** + * Marks this viewer to be used for print preview. + */ + virtual void InitializeForPrintPreview() = 0; + + /** + * Replaces the current presentation with print preview presentation. + */ + virtual void SetPrintPreviewPresentation(nsIWidget* aWidget, + nsIViewManager* aViewManager, + nsPresContext* aPresContext, + nsIPresShell* aPresShell) = 0; }; NS_DEFINE_STATIC_IID_ACCESSOR(nsIDocumentViewerPrint, @@ -86,6 +108,12 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIDocumentViewerPrint, virtual nsresult CreateStyleSet(nsIDocument* aDocument, nsStyleSet** aStyleSet); \ virtual void IncrementDestroyRefCount(); \ virtual void ReturnToGalleyPresentation(); \ - virtual void OnDonePrinting(); + virtual void OnDonePrinting(); \ + virtual PRBool IsInitializedForPrintPreview(); \ + virtual void InitializeForPrintPreview(); \ + virtual void SetPrintPreviewPresentation(nsIWidget* aWidget, \ + nsIViewManager* aViewManager, \ + nsPresContext* aPresContext, \ + nsIPresShell* aPresShell); #endif /* nsIDocumentViewerPrint_h___ */ diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index c820fbaf6df0..cb943ab312a4 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -78,7 +78,6 @@ #include "gfxTypes.h" #include "gfxUserFontSet.h" #include "nsTArray.h" -#include "nsTextFragment.h" #include "nsICanvasElement.h" #include "nsICanvasRenderingContextInternal.h" #include "gfxPlatform.h" @@ -3275,48 +3274,6 @@ nsLayoutUtils::IsReallyFixedPos(nsIFrame* aFrame) parentType == nsGkAtoms::pageContentFrame; } -static void DeleteTextFragment(void* aObject, nsIAtom* aPropertyName, - void* aPropertyValue, void* aData) -{ - delete static_cast(aPropertyValue); -} - -/* static */ nsTextFragment* -nsLayoutUtils::GetTextFragmentForPrinting(const nsIFrame* aFrame) -{ - nsPresContext* presContext = aFrame->PresContext(); - NS_PRECONDITION(!presContext->IsDynamic(), - "Shouldn't call this with dynamic PresContext"); -#ifdef MOZ_SVG - NS_PRECONDITION(aFrame->GetType() == nsGkAtoms::textFrame || - aFrame->GetType() == nsGkAtoms::svgGlyphFrame, - "Wrong frame type!"); -#else - NS_PRECONDITION(aFrame->GetType() == nsGkAtoms::textFrame, - "Wrong frame type!"); -#endif // MOZ_SVG - - nsIContent* content = aFrame->GetContent(); - nsTextFragment* frag = - static_cast(presContext->PropertyTable()-> - GetProperty(content, nsGkAtoms::clonedTextForPrint)); - - if (!frag) { - frag = new nsTextFragment(); - NS_ENSURE_TRUE(frag, nsnull); - *frag = *content->GetText(); - nsresult rv = presContext->PropertyTable()-> - SetProperty(content, nsGkAtoms::clonedTextForPrint, frag, - DeleteTextFragment, nsnull); - if (NS_FAILED(rv)) { - delete frag; - return nsnull; - } - } - - return frag; -} - nsLayoutUtils::SurfaceFromElementResult nsLayoutUtils::SurfaceFromElement(nsIDOMElement *aElement, PRUint32 aSurfaceFlags) diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h index 58b5433c9dd2..805442bc9c0b 100644 --- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -64,9 +64,9 @@ class nsClientRectList; #include "nsIPrincipal.h" #include "gfxPattern.h" #include "imgIContainer.h" +#include "nsCSSPseudoElements.h" class nsBlockFrame; -class nsTextFragment; /** * nsLayoutUtils is a namespace class used for various helper @@ -327,22 +327,21 @@ public: * * @param aContent the content node we're looking at * @param aStyleContext aContent's style context - * @param aPseudoElement the name of the pseudo style we care about + * @param aPseudoElement the id of the pseudo style we care about * @param aPresContext the presentation context * @return whether aContent has aPseudoElement style attached to it */ static PRBool HasPseudoStyle(nsIContent* aContent, nsStyleContext* aStyleContext, - nsIAtom* aPseudoElement, + nsCSSPseudoElements::Type aPseudoElement, nsPresContext* aPresContext) { NS_PRECONDITION(aPresContext, "Must have a prescontext"); - NS_PRECONDITION(aPseudoElement, "Must have a pseudo name"); nsRefPtr pseudoContext; if (aContent) { pseudoContext = aPresContext->StyleSet()-> - ProbePseudoStyleFor(aContent, aPseudoElement, aStyleContext); + ProbePseudoElementStyle(aContent, aPseudoElement, aStyleContext); } return pseudoContext != nsnull; } @@ -1063,12 +1062,6 @@ public: */ static PRBool sDisableGetUsedXAssertions; - /** - * Returns the text fragment, which aFrame should use for printing. - * @param aFrame The nsIFrame object, which uses text fragment data. - */ - static nsTextFragment* GetTextFragmentForPrinting(const nsIFrame* aFrame); - /** * Return true if aFrame is in an {ib} split and is NOT one of the * continuations of the first inline in it. diff --git a/layout/base/nsPresContext.cpp b/layout/base/nsPresContext.cpp index b39777413b86..1393f85847cd 100644 --- a/layout/base/nsPresContext.cpp +++ b/layout/base/nsPresContext.cpp @@ -1229,7 +1229,7 @@ nsPresContext::GetDefaultFont(PRUint8 aFontID) const void nsPresContext::SetFullZoom(float aZoom) { - if (!mShell || mFullZoom == aZoom || !IsDynamic()) { + if (!mShell || mFullZoom == aZoom) { return; } // Re-fetch the view manager's window dimensions in case there's a deferred diff --git a/layout/base/nsPresContext.h b/layout/base/nsPresContext.h index b3da1075f056..1c4b03702195 100644 --- a/layout/base/nsPresContext.h +++ b/layout/base/nsPresContext.h @@ -103,6 +103,7 @@ class nsUserFontSet; struct nsFontFaceRuleContainer; class nsObjectFrame; class nsTransitionManager; +class imgIContainer; #ifdef MOZ_REFLOW_PERF class nsIRenderingContext; @@ -278,7 +279,6 @@ public: * Access the image animation mode for this context */ PRUint16 ImageAnimationMode() const { return mImageAnimationMode; } - void RestoreImageAnimationMode() { SetImageAnimationMode(mImageAnimationModePref); } virtual NS_HIDDEN_(void) SetImageAnimationModeExternal(PRUint16 aMode); NS_HIDDEN_(void) SetImageAnimationModeInternal(PRUint16 aMode); #ifdef _IMPL_NS_LAYOUT diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index 7100da93718a..516b585b5545 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -866,6 +866,7 @@ public: // nsIMutationObserver NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED + NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTEWILLCHANGE NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED @@ -1028,6 +1029,18 @@ protected: // Utility method to restore the root scrollframe state void RestoreRootScrollPosition(); + void MaybeReleaseCapturingContent() + { + nsCOMPtr frameSelection = FrameSelection(); + if (frameSelection) { + frameSelection->SetMouseDownState(PR_FALSE); + } + if (gCaptureInfo.mContent && + gCaptureInfo.mContent->GetOwnerDoc() == mDocument) { + SetCapturingContent(nsnull, 0); + } + } + nsCOMPtr mPrefStyleSheet; // mStyleSet owns it but we // maintain a ref, may be null #ifdef DEBUG @@ -1210,9 +1223,6 @@ protected: static PRBool sDisableNonTestMouseEvents; - - nsCOMPtr mDocumentObserverForNonDynamicContext; - // false if a check should be done for key/ime events that should be // retargeted to the currently focused presshell static PRBool sDontRetargetEvents; @@ -1327,123 +1337,6 @@ public: nsRefPtr mPresShell; }; -class nsDocumentObserverForNonDynamicPresContext : public nsStubDocumentObserver -{ -public: - nsDocumentObserverForNonDynamicPresContext(PresShell* aBaseObserver) - : mBaseObserver(aBaseObserver) - { - NS_ASSERTION(aBaseObserver, "Null document observer!"); - } - - NS_DECL_ISUPPORTS - - virtual void BeginUpdate(nsIDocument* aDocument, nsUpdateType aUpdateType) - { - mBaseObserver->BeginUpdate(aDocument, aUpdateType); - } - virtual void EndUpdate(nsIDocument* aDocument, nsUpdateType aUpdateType) - { - mBaseObserver->EndUpdate(aDocument, aUpdateType); - } - virtual void BeginLoad(nsIDocument* aDocument) - { - mBaseObserver->BeginLoad(aDocument); - } - virtual void EndLoad(nsIDocument* aDocument) - { - mBaseObserver->EndLoad(aDocument); - } - virtual void ContentStatesChanged(nsIDocument* aDocument, - nsIContent* aContent1, - nsIContent* aContent2, - PRInt32 aStateMask) - { - if ((!aContent1 || AllowMutation(aContent1)) && - (!aContent2 || AllowMutation(aContent2))) { - mBaseObserver->ContentStatesChanged(aDocument, aContent1, aContent2, - aStateMask); - } - } - - // nsIMutationObserver - virtual void CharacterDataChanged(nsIDocument* aDocument, - nsIContent* aContent, - CharacterDataChangeInfo* aInfo) - { - if (AllowMutation(aContent)) { - mBaseObserver->CharacterDataChanged(aDocument, aContent, aInfo); - } - } - virtual void AttributeChanged(nsIDocument* aDocument, - nsIContent* aContent, - PRInt32 aNameSpaceID, - nsIAtom* aAttribute, - PRInt32 aModType, - PRUint32 aStateMask) - { - if (AllowMutation(aContent)) { - mBaseObserver->AttributeChanged(aDocument, aContent, aNameSpaceID, - aAttribute, aModType, aStateMask); - } - } - virtual void ContentAppended(nsIDocument* aDocument, - nsIContent* aContainer, - PRInt32 aNewIndexInContainer) - { - if (AllowMutation(aContainer)) { - mBaseObserver->ContentAppended(aDocument, aContainer, - aNewIndexInContainer); - } - } - virtual void ContentInserted(nsIDocument* aDocument, - nsIContent* aContainer, - nsIContent* aChild, - PRInt32 aIndexInContainer) - { - if (AllowMutation(aContainer)) { - mBaseObserver->ContentInserted(aDocument, aContainer, aChild, - aIndexInContainer); - } - } - virtual void ContentRemoved(nsIDocument* aDocument, - nsIContent* aContainer, - nsIContent* aChild, - PRInt32 aIndexInContainer) - { - if (AllowMutation(aContainer)) { - mBaseObserver->ContentRemoved(aDocument, aContainer, aChild, - aIndexInContainer); - } - } - - PRBool AllowMutation(nsIContent* aContent) { - if(aContent && aContent->IsInDoc()) { - if (mBaseObserver->ObservesNativeAnonMutationsForPrint() && - aContent->IsInNativeAnonymousSubtree()) { - return PR_TRUE; - } - // Changes to scrollbar are always ok. - nsIContent* root = aContent->GetCurrentDoc()->GetRootContent(); - while (aContent && aContent->IsInNativeAnonymousSubtree()) { - nsIContent* parent = aContent->GetParent(); - if (parent == root && aContent->IsXUL()) { - nsIAtom* tag = aContent->Tag(); - return tag == nsGkAtoms::scrollbar || tag == nsGkAtoms::scrollcorner; - } - aContent = parent; - } - } - return PR_FALSE; - } -protected: - nsRefPtr mBaseObserver; -}; - -NS_IMPL_ISUPPORTS2(nsDocumentObserverForNonDynamicPresContext, - nsIDocumentObserver, - nsIMutationObserver) - PRBool PresShell::sDisableNonTestMouseEvents = PR_FALSE; PRBool PresShell::sDontRetargetEvents = PR_FALSE; @@ -1832,6 +1725,8 @@ PresShell::Destroy() if (mHaveShutDown) return NS_OK; + MaybeReleaseCapturingContent(); + mContentToScrollTo = nsnull; if (mPresContext) { @@ -2518,14 +2413,7 @@ NS_IMETHODIMP PresShell::BeginObservingDocument() { if (mDocument && !mIsDestroying) { - if (mPresContext->IsDynamic()) { - mDocument->AddObserver(this); - } else { - mDocumentObserverForNonDynamicContext = - new nsDocumentObserverForNonDynamicPresContext(this); - NS_ENSURE_TRUE(mDocumentObserverForNonDynamicContext, NS_ERROR_OUT_OF_MEMORY); - mDocument->AddObserver(mDocumentObserverForNonDynamicContext); - } + mDocument->AddObserver(this); if (mIsDocumentGone) { NS_WARNING("Adding a presshell that was disconnected from the document " "as a document observer? Sounds wrong..."); @@ -2543,10 +2431,7 @@ PresShell::EndObservingDocument() // is gone, perhaps? Except for printing it's NOT gone, sometimes. mIsDocumentGone = PR_TRUE; if (mDocument) { - mDocument->RemoveObserver(mDocumentObserverForNonDynamicContext ? - mDocumentObserverForNonDynamicContext.get() : - this); - mDocumentObserverForNonDynamicContext = nsnull; + mDocument->RemoveObserver(this); } return NS_OK; } @@ -3610,10 +3495,6 @@ PresShell::RecreateFramesFor(nsIContent* aContent) return NS_OK; } - if (!mPresContext->IsDynamic()) { - return NS_OK; - } - // Don't call RecreateFramesForContent since that is not exported and we want // to keep the number of entrypoints down. @@ -5016,14 +4897,33 @@ PresShell::ContentStatesChanged(nsIDocument* aDocument, } } +void +PresShell::AttributeWillChange(nsIDocument* aDocument, + nsIContent* aContent, + PRInt32 aNameSpaceID, + nsIAtom* aAttribute, + PRInt32 aModType) +{ + NS_PRECONDITION(!mIsDocumentGone, "Unexpected AttributeChanged"); + NS_PRECONDITION(aDocument == mDocument, "Unexpected aDocument"); + + // XXXwaterson it might be more elegant to wait until after the + // initial reflow to begin observing the document. That would + // squelch any other inappropriate notifications as well. + if (mDidInitialReflow) { + nsAutoCauseReflowNotifier crNotifier(this); + mFrameConstructor->AttributeWillChange(aContent, aNameSpaceID, + aAttribute, aModType); + VERIFY_STYLE_TREE; + } +} void PresShell::AttributeChanged(nsIDocument* aDocument, nsIContent* aContent, PRInt32 aNameSpaceID, nsIAtom* aAttribute, - PRInt32 aModType, - PRUint32 aStateMask) + PRInt32 aModType) { NS_PRECONDITION(!mIsDocumentGone, "Unexpected AttributeChanged"); NS_PRECONDITION(aDocument == mDocument, "Unexpected aDocument"); @@ -5034,7 +4934,7 @@ PresShell::AttributeChanged(nsIDocument* aDocument, if (mDidInitialReflow) { nsAutoCauseReflowNotifier crNotifier(this); mFrameConstructor->AttributeChanged(aContent, aNameSpaceID, - aAttribute, aModType, aStateMask); + aAttribute, aModType); VERIFY_STYLE_TREE; } } @@ -5126,9 +5026,6 @@ PresShell::ContentRemoved(nsIDocument *aDocument, nsresult PresShell::ReconstructFrames(void) { - if (!mPresContext || !mPresContext->IsDynamic()) { - return NS_OK; - } nsAutoCauseReflowNotifier crNotifier(this); mFrameConstructor->BeginUpdate(); nsresult rv = mFrameConstructor->ReconstructDocElementHierarchy(); @@ -7075,6 +6972,8 @@ FreezeSubDocument(nsIDocument *aDocument, void *aData) void PresShell::Freeze() { + MaybeReleaseCapturingContent(); + mDocument->EnumerateFreezableElements(FreezeElement, this); if (mCaret) diff --git a/layout/base/tests/chrome/bug396024_helper.xul b/layout/base/tests/chrome/bug396024_helper.xul index 9ee34c72ddbc..8d246aa51167 100644 --- a/layout/base/tests/chrome/bug396024_helper.xul +++ b/layout/base/tests/chrome/bug396024_helper.xul @@ -8,6 +8,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=396024 + + + + + + +
+a b c d
+ + diff --git a/layout/generic/crashtests/513394-1.html b/layout/generic/crashtests/513394-1.html new file mode 100644 index 000000000000..7296695d7dcb --- /dev/null +++ b/layout/generic/crashtests/513394-1.html @@ -0,0 +1,16 @@ + + + + + + +
+ + diff --git a/layout/generic/crashtests/crashtests.list b/layout/generic/crashtests/crashtests.list index 67534c05d47e..75e2f02abdcb 100644 --- a/layout/generic/crashtests/crashtests.list +++ b/layout/generic/crashtests/crashtests.list @@ -271,10 +271,12 @@ load 494300-1.xul load 494332-1.html load 495875-1.html load 495875-2.html +load 499857-1.html load 501535-1.html load 503961-1.xhtml load 503961-2.html load 508908-1.html load 505912-1.html load 511482.html +load 513394-1.html load 517968.html diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp index 2c2c56348c95..211ba1b88da7 100644 --- a/layout/generic/nsBlockFrame.cpp +++ b/layout/generic/nsBlockFrame.cpp @@ -6187,7 +6187,8 @@ NS_IMETHODIMP nsBlockFrame::GetAccessible(nsIAccessible** aAccessible) // Create special list bullet accessible const nsStyleList* myList = GetStyleList(); nsAutoString bulletText; - if (myList->mListStyleImage || myList->mListStyleType == NS_STYLE_LIST_STYLE_DISC || + if (myList->GetListStyleImage() || + myList->mListStyleType == NS_STYLE_LIST_STYLE_DISC || myList->mListStyleType == NS_STYLE_LIST_STYLE_CIRCLE || myList->mListStyleType == NS_STYLE_LIST_STYLE_SQUARE) { bulletText.Assign(PRUnichar(0x2022));; // Unicode bullet character @@ -6365,24 +6366,25 @@ nsBlockFrame::SetInitialChildList(nsIAtom* aListName, (nsnull == mBullet)) { // Resolve style for the bullet frame const nsStyleList* styleList = GetStyleList(); - nsIAtom *pseudoElement; + nsCSSPseudoElements::Type pseudoType; switch (styleList->mListStyleType) { case NS_STYLE_LIST_STYLE_DISC: case NS_STYLE_LIST_STYLE_CIRCLE: case NS_STYLE_LIST_STYLE_SQUARE: - pseudoElement = nsCSSPseudoElements::mozListBullet; + pseudoType = nsCSSPseudoElements::ePseudo_mozListBullet; break; default: - pseudoElement = nsCSSPseudoElements::mozListNumber; + pseudoType = nsCSSPseudoElements::ePseudo_mozListNumber; break; } nsIPresShell *shell = presContext->PresShell(); nsStyleContext* parentStyle = - CorrectStyleParentFrame(this, pseudoElement)->GetStyleContext(); + CorrectStyleParentFrame(this, + nsCSSPseudoElements::GetPseudoAtom(pseudoType))->GetStyleContext(); nsRefPtr kidSC = shell->StyleSet()-> - ResolvePseudoStyleFor(mContent, pseudoElement, parentStyle); + ResolvePseudoElementStyle(mContent, pseudoType, parentStyle); // Create bullet frame nsBulletFrame* bullet = new (shell) nsBulletFrame(kidSC); @@ -6418,7 +6420,7 @@ nsBlockFrame::BulletIsEmpty() const "should only care when we have an outside bullet"); const nsStyleList* list = GetStyleList(); return list->mListStyleType == NS_STYLE_LIST_STYLE_NONE && - !list->mListStyleImage; + !list->GetListStyleImage(); } // static diff --git a/layout/generic/nsBlockFrame.h b/layout/generic/nsBlockFrame.h index 46d56c0f4127..5aa6c27f783e 100644 --- a/layout/generic/nsBlockFrame.h +++ b/layout/generic/nsBlockFrame.h @@ -337,8 +337,9 @@ protected: already_AddRefed GetFirstLetterStyle(nsPresContext* aPresContext) { return aPresContext->StyleSet()-> - ProbePseudoStyleFor(mContent, - nsCSSPseudoElements::firstLetter, mStyleContext); + ProbePseudoElementStyle(mContent, + nsCSSPseudoElements::ePseudo_firstLetter, + mStyleContext); } #endif diff --git a/layout/generic/nsBulletFrame.cpp b/layout/generic/nsBulletFrame.cpp index 2ab438ff591a..599b2ade000a 100644 --- a/layout/generic/nsBulletFrame.cpp +++ b/layout/generic/nsBulletFrame.cpp @@ -137,7 +137,7 @@ nsBulletFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext) { nsFrame::DidSetStyleContext(aOldStyleContext); - imgIRequest *newRequest = GetStyleList()->mListStyleImage; + imgIRequest *newRequest = GetStyleList()->GetListStyleImage(); if (newRequest) { @@ -228,7 +228,7 @@ nsBulletFrame::PaintBullet(nsIRenderingContext& aRenderingContext, nsPoint aPt, const nsStyleList* myList = GetStyleList(); PRUint8 listStyleType = myList->mListStyleType; - if (myList->mListStyleImage && mImageRequest) { + if (myList->GetListStyleImage() && mImageRequest) { PRUint32 status; mImageRequest->GetImageStatus(&status); if (status & imgIRequest::STATUS_LOAD_COMPLETE && @@ -1258,7 +1258,7 @@ nsBulletFrame::GetDesiredSize(nsPresContext* aCX, const nsStyleList* myList = GetStyleList(); nscoord ascent; - if (myList->mListStyleImage && mImageRequest) { + if (myList->GetListStyleImage() && mImageRequest) { PRUint32 status; mImageRequest->GetImageStatus(&status); if (status & imgIRequest::STATUS_SIZE_AVAILABLE && diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 308a89535992..cd56ca16ff79 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -121,7 +121,7 @@ #include "nsBoxLayoutState.h" #include "nsBlockFrame.h" #include "nsDisplayList.h" - +#include "nsIObjectLoadingContent.h" #ifdef MOZ_SVG #include "nsSVGIntegrationUtils.h" #include "nsSVGEffects.h" diff --git a/layout/generic/nsFrameSelection.h b/layout/generic/nsFrameSelection.h index 8f6d0fd9fee2..db0f3d3b8dde 100644 --- a/layout/generic/nsFrameSelection.h +++ b/layout/generic/nsFrameSelection.h @@ -658,7 +658,6 @@ private: void InvalidateDesiredX(); //do not listen to mDesiredX you must get another. void SetDesiredX(nscoord aX); //set the mDesiredX - nsresult GetRootForContentSubtree(nsIContent *aContent, nsIContent **aParent); nsresult ConstrainFrameAndPointToAnchorSubtree(nsIFrame *aFrame, nsPoint& aPoint, nsIFrame **aRetFrame, nsPoint& aRetPoint); PRUint32 GetBatching() const {return mBatching; } diff --git a/layout/generic/nsFrameSetFrame.cpp b/layout/generic/nsFrameSetFrame.cpp index 8249696f52bb..040636c4c9d8 100644 --- a/layout/generic/nsFrameSetFrame.cpp +++ b/layout/generic/nsFrameSetFrame.cpp @@ -68,7 +68,6 @@ #include "nsIServiceManager.h" #include "nsIDOMMutationEvent.h" #include "nsINameSpaceManager.h" -#include "nsCSSPseudoElements.h" #include "nsCSSAnonBoxes.h" #include "nsAutoPtr.h" #include "nsStyleSet.h" @@ -285,7 +284,7 @@ nsHTMLFramesetFrame::FrameResizePrefCallback(const char* aPref, void* aClosure) nsNodeUtils::AttributeChanged(frame->GetContent(), kNameSpaceID_None, nsGkAtoms::frameborder, - nsIDOMMutationEvent::MODIFICATION, 0); + nsIDOMMutationEvent::MODIFICATION); } return 0; @@ -430,7 +429,7 @@ nsHTMLFramesetFrame::Init(nsIContent* aContent, for (int blankX = mChildCount; blankX < numCells; blankX++) { nsRefPtr pseudoStyleContext; pseudoStyleContext = shell->StyleSet()-> - ResolvePseudoStyleFor(nsnull, nsCSSAnonBoxes::framesetBlank, mStyleContext); + ResolveAnonymousBoxStyle(nsCSSAnonBoxes::framesetBlank, mStyleContext); if (!pseudoStyleContext) { return NS_ERROR_OUT_OF_MEMORY; } @@ -1042,9 +1041,9 @@ nsHTMLFramesetFrame::Reflow(nsPresContext* aPresContext, if (firstTime) { // create horizontal border nsRefPtr pseudoStyleContext; - pseudoStyleContext = styleSet->ResolvePseudoStyleFor(mContent, - nsCSSPseudoElements::horizontalFramesetBorder, - mStyleContext); + pseudoStyleContext = styleSet-> + ResolveAnonymousBoxStyle(nsCSSAnonBoxes::horizontalFramesetBorder, + mStyleContext); borderFrame = new (shell) nsHTMLFramesetBorderFrame(pseudoStyleContext, borderWidth, @@ -1078,9 +1077,9 @@ nsHTMLFramesetFrame::Reflow(nsPresContext* aPresContext, if (firstTime) { // create vertical border nsRefPtr pseudoStyleContext; - pseudoStyleContext = styleSet->ResolvePseudoStyleFor(mContent, - nsCSSPseudoElements::verticalFramesetBorder, - mStyleContext); + pseudoStyleContext = styleSet-> + ResolveAnonymousBoxStyle(nsCSSAnonBoxes::verticalFramesetBorder, + mStyleContext); borderFrame = new (shell) nsHTMLFramesetBorderFrame(pseudoStyleContext, borderWidth, diff --git a/layout/generic/nsImageMap.cpp b/layout/generic/nsImageMap.cpp index 1bda0dc7a6f8..f9492821dc00 100644 --- a/layout/generic/nsImageMap.cpp +++ b/layout/generic/nsImageMap.cpp @@ -950,8 +950,7 @@ nsImageMap::AttributeChanged(nsIDocument* aDocument, nsIContent* aContent, PRInt32 aNameSpaceID, nsIAtom* aAttribute, - PRInt32 aModType, - PRUint32 aStateMask) + PRInt32 aModType) { // If the parent of the changing content node is our map then update // the map. But only do this if the node is an HTML or diff --git a/layout/generic/nsInlineFrame.cpp b/layout/generic/nsInlineFrame.cpp index f6ffec499502..d6ec262e1666 100644 --- a/layout/generic/nsInlineFrame.cpp +++ b/layout/generic/nsInlineFrame.cpp @@ -1057,8 +1057,7 @@ nsFirstLineFrame::Reflow(nsPresContext* aPresContext, // of the parent frame. nsRefPtr newSC; newSC = aPresContext->StyleSet()-> - ResolvePseudoStyleFor(nsnull, - nsCSSAnonBoxes::mozLineFrame, parentContext); + ResolveAnonymousBoxStyle(nsCSSAnonBoxes::mozLineFrame, parentContext); if (newSC) { // Switch to the new style context. SetStyleContext(newSC); diff --git a/layout/generic/nsObjectFrame.cpp b/layout/generic/nsObjectFrame.cpp index 2f9eeb62abd5..0891f6a68299 100644 --- a/layout/generic/nsObjectFrame.cpp +++ b/layout/generic/nsObjectFrame.cpp @@ -416,7 +416,7 @@ public: return strncmp(GetPluginName(), aPluginName, strlen(aPluginName)) == 0; } -#ifdef MOZ_PLATFORM_HILDON +#if defined(MOZ_PLATFORM_HILDON) && defined(MOZ_WIDGET_GTK2) nsresult SetAbsoluteScreenPosition(nsIDOMElement* element, nsIDOMClientRect* position, nsIDOMClientRect* clip); @@ -512,7 +512,8 @@ private: const nsIntRect& mDirtyRect; }; #endif -#ifdef MOZ_PLATFORM_HILDON + +#if defined(MOZ_PLATFORM_HILDON) && defined(MOZ_WIDGET_GTK2) // On hildon, we attempt to use NPImageExpose which allows us faster // painting. @@ -1230,7 +1231,7 @@ nsObjectFrame::SetAbsoluteScreenPosition(nsIDOMElement* element, nsIDOMClientRect* position, nsIDOMClientRect* clip) { -#ifdef MOZ_PLATFORM_HILDON +#if defined(MOZ_PLATFORM_HILDON) && defined(MOZ_WIDGET_GTK2) if (!mInstanceOwner) return NS_ERROR_NOT_AVAILABLE; return mInstanceOwner->SetAbsoluteScreenPosition(element, position, clip); @@ -1327,22 +1328,12 @@ void nsObjectFrame::PrintPlugin(nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect) { - // if we are printing, we need to get the correct nsIPluginInstance - // for THIS content node in order to call ->Print() on the right plugin - - // first, we need to get the document - nsIDocument* doc = mContent->GetCurrentDoc(); - if (!doc) + nsCOMPtr obj(do_QueryInterface(mContent)); + if (!obj) return; - // now we need to get the shell for the screen - // XXX assuming that the shell at zero will always be the screen one - nsIPresShell *shell = doc->GetPrimaryShell(); - if (!shell) - return; - - // then the shell can give us the screen frame for this content node - nsIFrame* frame = shell->GetPrimaryFrameFor(mContent); + nsIFrame* frame = nsnull; + obj->GetPrintFrame(&frame); if (!frame) return; @@ -2134,7 +2125,7 @@ GetMIMEType(nsIPluginInstance *aPluginInstance) static PRBool DoDelayedStop(nsPluginInstanceOwner *aInstanceOwner, PRBool aDelayedStop) { -#ifdef MOZ_PLATFORM_HILDON +#if defined(MOZ_PLATFORM_HILDON) && defined(MOZ_WIDGET_GTK2) // Don't delay stop on Maemo/Hildon (bug 530739). if (aDelayedStop && aInstanceOwner->MatchPluginName("Shockwave Flash")) return PR_FALSE; @@ -2447,7 +2438,7 @@ nsPluginInstanceOwner::nsPluginInstanceOwner() mLastPoint = nsIntPoint(0,0); #endif -#ifdef MOZ_PLATFORM_HILDON +#if defined(MOZ_PLATFORM_HILDON) && defined(MOZ_WIDGET_GTK2) mPluginSize = nsIntSize(0,0); mXlibSurfGC = None; mSharedXImage = nsnull; @@ -2515,7 +2506,7 @@ nsPluginInstanceOwner::~nsPluginInstanceOwner() mInstance->InvalidateOwner(); } -#ifdef MOZ_PLATFORM_HILDON +#if defined(MOZ_PLATFORM_HILDON) && defined(MOZ_WIDGET_GTK2) ReleaseXShm(); #endif } @@ -2737,7 +2728,7 @@ NS_IMETHODIMP nsPluginInstanceOwner::InvalidateRect(NPRect *invalidRect) if (!mObjectFrame || !invalidRect || !mWidgetVisible) return NS_ERROR_FAILURE; -#ifdef MOZ_PLATFORM_HILDON +#if defined(MOZ_PLATFORM_HILDON) && defined(MOZ_WIDGET_GTK2) PRBool simpleImageRender = PR_FALSE; mInstance->GetValueFromPlugin(NPPVpluginWindowlessLocalBool, &simpleImageRender); @@ -4826,7 +4817,7 @@ void nsPluginInstanceOwner::Paint(gfxContext* aContext, if (!mInstance || !mObjectFrame) return; -#ifdef MOZ_PLATFORM_HILDON +#if defined(MOZ_PLATFORM_HILDON) && defined(MOZ_WIDGET_GTK2) // through to be able to paint the context passed in. This allows // us to handle plugins that do not self invalidate (slowly, but // accurately), and it allows us to reduce flicker. @@ -4915,7 +4906,7 @@ DepthOfVisual(const Screen* screen, const Visual* visual) } #endif -#ifdef MOZ_PLATFORM_HILDON +#if defined(MOZ_PLATFORM_HILDON) && defined(MOZ_WIDGET_GTK2) static GdkWindow* GetClosestWindow(nsIDOMElement *element) { @@ -5628,7 +5619,7 @@ void nsPluginInstanceOwner::SetPluginHost(nsIPluginHost* aHost) mPluginHost = aHost; } -#ifdef MOZ_PLATFORM_HILDON +#if defined(MOZ_PLATFORM_HILDON) && defined(MOZ_WIDGET_GTK2) PRBool nsPluginInstanceOwner::UpdateVisibility() { if (!mInstance) @@ -5785,7 +5776,7 @@ void nsPluginInstanceOwner::FixUpURLS(const nsString &name, nsAString &value) } } -#ifdef MOZ_PLATFORM_HILDON +#if defined(MOZ_PLATFORM_HILDON) && defined(MOZ_WIDGET_GTK2) nsresult nsPluginInstanceOwner::SetAbsoluteScreenPosition(nsIDOMElement* element, nsIDOMClientRect* position, diff --git a/layout/generic/nsSelection.cpp b/layout/generic/nsSelection.cpp index d6f4c2496f5c..4e1e5c66f3e0 100644 --- a/layout/generic/nsSelection.cpp +++ b/layout/generic/nsSelection.cpp @@ -851,52 +851,6 @@ nsFrameSelection::SetDesiredX(nscoord aX) //set the mDesiredX mDesiredXSet = PR_TRUE; } -nsresult -nsFrameSelection::GetRootForContentSubtree(nsIContent *aContent, - nsIContent **aParent) -{ - // This method returns the root of the sub-tree containing aContent. - // We do this by searching up through the parent hierarchy, and stopping - // when there are no more parents, or we hit a situation where the - // parent/child relationship becomes invalid. - // - // An example of an invalid parent/child relationship is anonymous content. - // Anonymous content has a pointer to its parent, but it is not listed - // as a child of its parent. In this case, the anonymous content would - // be considered the root of the subtree. - - if (!aContent || !aParent) - return NS_ERROR_NULL_POINTER; - - *aParent = 0; - - nsIContent* child = aContent; - - while (child) - { - nsIContent* parent = child->GetParent(); - - if (!parent) - break; - - PRUint32 childCount = parent->GetChildCount(); - - if (childCount < 1) - break; - - PRInt32 childIndex = parent->IndexOf(child); - - if (childIndex < 0 || ((PRUint32)childIndex) >= childCount) - break; - - child = parent; - } - - NS_IF_ADDREF(*aParent = child); - - return NS_OK; -} - nsresult nsFrameSelection::ConstrainFrameAndPointToAnchorSubtree(nsIFrame *aFrame, nsPoint& aPoint, @@ -956,11 +910,8 @@ nsFrameSelection::ConstrainFrameAndPointToAnchorSubtree(nsIFrame *aFrame, // Now find the root of the subtree containing the anchor's content. // - nsCOMPtr anchorRoot; - result = GetRootForContentSubtree(anchorContent, getter_AddRefs(anchorRoot)); - - if (NS_FAILED(result)) - return result; + NS_ENSURE_STATE(mShell); + nsIContent* anchorRoot = anchorContent->GetSelectionRootContent(mShell); // // Now find the root of the subtree containing aFrame's content. @@ -970,29 +921,53 @@ nsFrameSelection::ConstrainFrameAndPointToAnchorSubtree(nsIFrame *aFrame, if (content) { - nsCOMPtr contentRoot; - - result = GetRootForContentSubtree(content, getter_AddRefs(contentRoot)); + nsIContent* contentRoot = content->GetSelectionRootContent(mShell); if (anchorRoot == contentRoot) { - // - // The anchor and AFrame's root are the same. There - // is no need to constrain, simply return aFrame. - // - *aRetFrame = aFrame; - return NS_OK; + // If the aFrame's content isn't the capturing content, it should be + // a descendant. At this time, we can return simply. + nsIContent* capturedContent = nsIPresShell::GetCapturingContent(); + if (capturedContent != content) + { + return NS_OK; + } + + // Find the frame under the mouse cursor with the root frame. + // At this time, don't use the anchor's frame because it may not have + // fixed positioned frames. + nsIFrame* rootFrame = mShell->FrameManager()->GetRootFrame(); + nsPoint ptInRoot = aPoint + aFrame->GetOffsetTo(rootFrame); + nsIFrame* cursorFrame = + nsLayoutUtils::GetFrameForPoint(rootFrame, ptInRoot); + + // If the mouse cursor in on a frame which is descendant of same + // selection root, we can expand the selection to the frame. + if (cursorFrame && cursorFrame->PresContext()->PresShell() == mShell) + { + nsIContent* cursorContent = cursorFrame->GetContent(); + NS_ENSURE_TRUE(cursorContent, NS_ERROR_FAILURE); + nsIContent* cursorContentRoot = + cursorContent->GetSelectionRootContent(mShell); + if (cursorContentRoot == anchorRoot) + { + *aRetFrame = cursorFrame; + aRetPoint = aPoint + aFrame->GetOffsetTo(cursorFrame); + return NS_OK; + } + } + // Otherwise, e.g., the cursor isn't on any frames (e.g., the mouse + // cursor is out of the window), we should use the frame of the anchor + // root. } } // - // aFrame's root does not match the anchor's root, or there is no - // content associated with aFrame. Just return the primary frame - // for the anchor's root. We'll let GetContentAndOffsetsFromPoint() - // find the closest frame aPoint. + // When we can't find a frame which is under the mouse cursor and has a same + // selection root as the anchor node's, we should return the selection root + // frame. // - NS_ENSURE_STATE(mShell); *aRetFrame = mShell->GetPrimaryFrameFor(anchorRoot); if (!*aRetFrame) diff --git a/layout/generic/nsTextFrame.h b/layout/generic/nsTextFrame.h index 8dd98bdb8bba..b97dcd556a7d 100644 --- a/layout/generic/nsTextFrame.h +++ b/layout/generic/nsTextFrame.h @@ -60,10 +60,6 @@ class nsTextPaintStyle; class PropertyProvider; -// This bit is set while the frame is registered as a blinking frame or if -// frame is within a non-dynamic PresContext. -#define TEXT_BLINK_ON_OR_PRINTING 0x20000000 - // This state bit is set on frames that have some non-collapsed characters after // reflow #define TEXT_HAS_NONCOLLAPSED_CHARACTERS 0x80000000 @@ -369,17 +365,9 @@ public: TrimmedOffsets GetTrimmedOffsets(const nsTextFragment* aFrag, PRBool aTrimAfter); - const nsTextFragment* GetFragment() const - { - return !(GetStateBits() & TEXT_BLINK_ON_OR_PRINTING) ? - mContent->GetText() : GetFragmentInternal(); - } - protected: virtual ~nsTextFrame(); - const nsTextFragment* GetFragmentInternal() const; - nsIFrame* mNextContinuation; // The key invariant here is that mContentOffset never decreases along // a next-continuation chain. And of course mContentOffset is always <= the diff --git a/layout/generic/nsTextFrameThebes.cpp b/layout/generic/nsTextFrameThebes.cpp index c2ed65b38aaf..8014f1af15b6 100644 --- a/layout/generic/nsTextFrameThebes.cpp +++ b/layout/generic/nsTextFrameThebes.cpp @@ -165,9 +165,8 @@ #define TEXT_ISNOT_ONLY_WHITESPACE 0x10000000 #define TEXT_WHITESPACE_FLAGS 0x18000000 - -// nsTextFrame.h has -// #define TEXT_BLINK_ON_OR_PRINTING 0x20000000 +// This bit is set while the frame is registered as a blinking frame. +#define TEXT_BLINK_ON 0x20000000 // Set when this text frame is mentioned in the userdata for a textrun #define TEXT_IN_TEXTRUN_USER_DATA 0x40000000 @@ -484,7 +483,7 @@ nsTextFrameTextRunCache::Shutdown() { PRInt32 nsTextFrame::GetContentEnd() const { nsTextFrame* next = static_cast(GetNextContinuation()); - return next ? next->GetContentOffset() : GetFragment()->GetLength(); + return next ? next->GetContentOffset() : mContent->GetText()->GetLength(); } PRInt32 nsTextFrame::GetInFlowContentLength() { @@ -500,7 +499,7 @@ PRInt32 nsTextFrame::GetInFlowContentLength() { } } #endif //IBMBIDI - return GetFragment()->GetLength() - mContentOffset; + return mContent->TextLength() - mContentOffset; } // Smarter versions of XP_IS_SPACE. @@ -729,7 +728,7 @@ public: PRInt32 GetContentEnd() { return mEndFrame ? mEndFrame->GetContentOffset() - : mStartFrame->GetFragment()->GetLength(); + : mStartFrame->GetContent()->GetText()->GetLength(); } }; @@ -947,7 +946,7 @@ BuildTextRunsScanner::FindBoundaries(nsIFrame* aFrame, FindBoundaryState* aState if (textFrame) { if (!aState->mSeenSpaceForLineBreakingOnThisLine) { - const nsTextFragment* frag = textFrame->GetFragment(); + const nsTextFragment* frag = textFrame->GetContent()->GetText(); PRUint32 start = textFrame->GetContentOffset(); const void* text = frag->Is2b() ? static_cast(frag->Get2b() + start) @@ -1272,7 +1271,7 @@ void BuildTextRunsScanner::AccumulateRunInfo(nsTextFrame* aFrame) { NS_ASSERTION(mMaxTextLength <= mMaxTextLength + aFrame->GetContentLength(), "integer overflow"); mMaxTextLength += aFrame->GetContentLength(); - mDoubleByteText |= aFrame->GetFragment()->Is2b(); + mDoubleByteText |= aFrame->GetContent()->GetText()->Is2b(); mLastFrame = aFrame; mCommonAncestorWithLastFrame = aFrame->GetParent(); @@ -1305,7 +1304,7 @@ HasTerminalNewline(const nsTextFrame* aFrame) { if (aFrame->GetContentLength() == 0) return PR_FALSE; - const nsTextFragment* frag = aFrame->GetFragment(); + const nsTextFragment* frag = aFrame->GetContent()->GetText(); return frag->CharAt(aFrame->GetContentEnd() - 1) == '\n'; } @@ -1626,7 +1625,7 @@ BuildTextRunsScanner::BuildTextRunForFrames(void* aTextBuffer) // Figure out what content is included in this flow. nsIContent* content = f->GetContent(); - const nsTextFragment* frag = f->GetFragment(); + const nsTextFragment* frag = content->GetText(); PRInt32 contentStart = mappedFlow->mStartFrame->GetContentOffset(); PRInt32 contentEnd = mappedFlow->GetContentEnd(); PRInt32 contentLength = contentEnd - contentStart; @@ -1855,7 +1854,7 @@ HasCompressedLeadingWhitespace(nsTextFrame* aFrame, const nsStyleText* aStyleTex gfxSkipCharsIterator iter = aIterator; PRInt32 frameContentOffset = aFrame->GetContentOffset(); - const nsTextFragment* frag = aFrame->GetFragment(); + const nsTextFragment* frag = aFrame->GetContent()->GetText(); while (frameContentOffset < aContentEndOffset && iter.IsOriginalCharSkipped()) { if (IsTrimmableSpace(frag, frameContentOffset, aStyleText)) return PR_TRUE; @@ -2223,7 +2222,7 @@ public: PropertyProvider(nsTextFrame* aFrame, const gfxSkipCharsIterator& aStart) : mTextRun(aFrame->GetTextRun()), mFontGroup(nsnull), mTextStyle(aFrame->GetStyleText()), - mFrag(aFrame->GetFragment()), + mFrag(aFrame->GetContent()->GetText()), mLineContainer(nsnull), mFrame(aFrame), mStart(aStart), mTempIterator(aStart), mTabWidths(nsnull), @@ -3162,8 +3161,9 @@ nsTextPaintStyle::InitSelectionColors() selectionStatus == nsISelectionController::SELECTION_ON) { nsRefPtr sc = nsnull; sc = mPresContext->StyleSet()-> - ProbePseudoStyleFor(selectionContent, nsCSSPseudoElements::mozSelection, - mFrame->GetStyleContext()); + ProbePseudoElementStyle(selectionContent, + nsCSSPseudoElements::ePseudo_mozSelection, + mFrame->GetStyleContext()); // Use -moz-selection pseudo class. if (sc) { const nsStyleBackground* bg = sc->GetStyleBackground(); @@ -3408,11 +3408,6 @@ nsTextFrame::Init(nsIContent* aContent, NS_ASSERTION(!aPrevInFlow, "Can't be a continuation!"); NS_PRECONDITION(aContent->IsNodeOfType(nsINode::eTEXT), "Bogus content!"); - - if (!PresContext()->IsDynamic()) { - AddStateBits(TEXT_BLINK_ON_OR_PRINTING); - } - // Since our content has a frame now, this flag is no longer needed. aContent->UnsetFlags(NS_CREATE_FRAME_IF_NON_WHITESPACE); // We're not a continuing frame. @@ -3497,11 +3492,6 @@ nsContinuingTextFrame::Init(nsIContent* aContent, nsIFrame* aPrevInFlow) { NS_ASSERTION(aPrevInFlow, "Must be a continuation!"); - - if (!PresContext()->IsDynamic()) { - AddStateBits(TEXT_BLINK_ON_OR_PRINTING); - } - // NOTE: bypassing nsTextFrame::Init!!! nsresult rv = nsFrame::Init(aContent, aParent, aPrevInFlow); @@ -3514,7 +3504,7 @@ nsContinuingTextFrame::Init(nsIContent* aContent, aPrevInFlow->SetNextInFlow(this); nsTextFrame* prev = static_cast(aPrevInFlow); mContentOffset = prev->GetContentOffset() + prev->GetContentLengthHint(); - NS_ASSERTION(mContentOffset < PRInt32(GetFragment()->GetLength()), + NS_ASSERTION(mContentOffset < PRInt32(aContent->GetText()->GetLength()), "Creating ContinuingTextFrame, but there is no more content"); if (prev->GetStyleContext() != GetStyleContext()) { // We're taking part of prev's text, and its style may be different @@ -3703,7 +3693,7 @@ NS_IMPL_FRAMEARENA_HELPERS(nsContinuingTextFrame) nsTextFrame::~nsTextFrame() { - if (0 != (mState & TEXT_BLINK_ON_OR_PRINTING) && PresContext()->IsDynamic()) + if (0 != (mState & TEXT_BLINK_ON)) { nsBlinkTimer::RemoveBlinkFrame(this); } @@ -3911,7 +3901,7 @@ nsTextFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, DO_GLOBAL_REFLOW_COUNT_DSP("nsTextFrame"); - if ((0 != (mState & TEXT_BLINK_ON_OR_PRINTING)) && nsBlinkTimer::GetBlinkIsOff() && + if ((0 != (mState & TEXT_BLINK_ON)) && nsBlinkTimer::GetBlinkIsOff() && PresContext()->IsDynamic() && !aBuilder->IsForEventDelivery()) return NS_OK; @@ -5245,7 +5235,7 @@ nsTextFrame::PeekOffsetNoAmount(PRBool aForward, PRInt32* aOffset) if (!mTextRun) return PR_FALSE; - TrimmedOffsets trimmed = GetTrimmedOffsets(GetFragment(), PR_TRUE); + TrimmedOffsets trimmed = GetTrimmedOffsets(mContent->GetText(), PR_TRUE); // Check whether there are nonskipped characters in the trimmmed range return iter.ConvertOriginalToSkipped(trimmed.GetEnd()) > iter.ConvertOriginalToSkipped(trimmed.mStart); @@ -5312,7 +5302,7 @@ nsTextFrame::PeekOffsetCharacter(PRBool aForward, PRInt32* aOffset) if (!mTextRun) return PR_FALSE; - TrimmedOffsets trimmed = GetTrimmedOffsets(GetFragment(), PR_FALSE); + TrimmedOffsets trimmed = GetTrimmedOffsets(mContent->GetText(), PR_FALSE); // A negative offset means "end of frame". PRInt32 startOffset = GetContentOffset() + (*aOffset < 0 ? contentLength : *aOffset); @@ -5427,7 +5417,7 @@ ClusterIterator::ClusterIterator(nsTextFrame* aTextFrame, PRInt32 aPosition, mCategories = do_GetService(NS_UNICHARCATEGORY_CONTRACTID); - mFrag = aTextFrame->GetFragment(); + mFrag = aTextFrame->GetContent()->GetText(); mTrimmed = aTextFrame->GetTrimmedOffsets(mFrag, PR_TRUE); PRInt32 textOffset = aTextFrame->GetContentOffset(); @@ -5668,7 +5658,7 @@ nsTextFrame::AddInlineMinWidthForFlow(nsIRenderingContext *aRenderingContext, // Pass null for the line container. This will disable tab spacing, but that's // OK since we can't really handle tabs for intrinsic sizing anyway. const nsStyleText* textStyle = GetStyleText(); - const nsTextFragment* frag = GetFragment(); + const nsTextFragment* frag = mContent->GetText(); PropertyProvider provider(mTextRun, textStyle, frag, this, iter, PR_INT32_MAX, nsnull, 0); @@ -5796,7 +5786,7 @@ nsTextFrame::AddInlinePrefWidthForFlow(nsIRenderingContext *aRenderingContext, // OK since we can't really handle tabs for intrinsic sizing anyway. const nsStyleText* textStyle = GetStyleText(); - const nsTextFragment* frag = GetFragment(); + const nsTextFragment* frag = mContent->GetText(); PropertyProvider provider(mTextRun, textStyle, frag, this, iter, PR_INT32_MAX, nsnull, 0); @@ -6061,8 +6051,8 @@ nsTextFrame::Reflow(nsPresContext* aPresContext, ///////////////////////////////////////////////////////////////////// // Clear out the reflow state flags in mState (without destroying - // the TEXT_BLINK_ON_OR_PRINTING bit). We also clear the whitespace flags - // because this can change whether the frame maps whitespace-only text or not. + // the TEXT_BLINK_ON bit). We also clear the whitespace flags because this + // can change whether the frame maps whitespace-only text or not. RemoveStateBits(TEXT_REFLOW_FLAGS | TEXT_WHITESPACE_FLAGS); // Temporarily map all possible content while we construct our new textrun. @@ -6084,14 +6074,14 @@ nsTextFrame::Reflow(nsPresContext* aPresContext, nsLineLayout& lineLayout = *aReflowState.mLineLayout; if (aReflowState.mFlags.mBlinks) { - if (0 == (mState & TEXT_BLINK_ON_OR_PRINTING) && PresContext()->IsDynamic()) { - mState |= TEXT_BLINK_ON_OR_PRINTING; + if (0 == (mState & TEXT_BLINK_ON)) { + mState |= TEXT_BLINK_ON; nsBlinkTimer::AddBlinkFrame(aPresContext, this); } } else { - if (0 != (mState & TEXT_BLINK_ON_OR_PRINTING) && PresContext()->IsDynamic()) { - mState &= ~TEXT_BLINK_ON_OR_PRINTING; + if (0 != (mState & TEXT_BLINK_ON)) { + mState &= ~TEXT_BLINK_ON; nsBlinkTimer::RemoveBlinkFrame(this); } } @@ -6106,7 +6096,7 @@ nsTextFrame::Reflow(nsPresContext* aPresContext, PRUint32 flowEndInTextRun; nsIFrame* lineContainer = lineLayout.GetLineContainerFrame(); gfxContext* ctx = aReflowState.rendContext->ThebesContext(); - const nsTextFragment* frag = GetFragment(); + const nsTextFragment* frag = mContent->GetText(); // DOM offsets of the text range we need to measure, after trimming // whitespace, restricting to first-letter, and restricting preformatted text @@ -6526,7 +6516,7 @@ nsTextFrame::TrimTrailingWhiteSpace(nsIRenderingContext* aRC) PRUint32 trimmedStart = start.GetSkippedOffset(); - const nsTextFragment* frag = GetFragment(); + const nsTextFragment* frag = mContent->GetText(); TrimmedOffsets trimmed = GetTrimmedOffsets(frag, PR_TRUE); gfxSkipCharsIterator trimmedEndIter = start; const nsStyleText* textStyle = GetStyleText(); @@ -6663,7 +6653,7 @@ nsresult nsTextFrame::GetRenderedText(nsAString* aAppendToString, // The handling of aSkippedStartOffset and aSkippedMaxLength could be more efficient... gfxSkipCharsBuilder skipCharsBuilder; nsTextFrame* textFrame; - const nsTextFragment* textFrag = GetFragment(); + const nsTextFragment* textFrag = mContent->GetText(); PRUint32 keptCharsLength = 0; PRUint32 validCharsLength = 0; @@ -6729,7 +6719,7 @@ void nsTextFrame::ToCString(nsCString& aBuf, PRInt32* aTotalContentLength) const { // Get the frames text content - const nsTextFragment* frag = GetFragment(); + const nsTextFragment* frag = mContent->GetText(); if (!frag) { return; } @@ -6789,7 +6779,7 @@ nsTextFrame::IsEmpty() return PR_TRUE; } - PRBool isEmpty = IsAllWhitespace(GetFragment(), + PRBool isEmpty = IsAllWhitespace(mContent->GetText(), textStyle->mWhiteSpace != NS_STYLE_WHITESPACE_PRE_LINE); mState |= (isEmpty ? TEXT_IS_ONLY_WHITESPACE : TEXT_ISNOT_ONLY_WHITESPACE); return isEmpty; @@ -6926,10 +6916,3 @@ nsTextFrame::IsAtEndOfLine() const { return (GetStateBits() & TEXT_END_OF_LINE) != 0; } - -const nsTextFragment* -nsTextFrame::GetFragmentInternal() const -{ - return PresContext()->IsDynamic() ? mContent->GetText() : - nsLayoutUtils::GetTextFragmentForPrinting(this); -} diff --git a/layout/generic/nsVideoFrame.h b/layout/generic/nsVideoFrame.h index bc93cdf3d3a1..59ad77fe0f32 100644 --- a/layout/generic/nsVideoFrame.h +++ b/layout/generic/nsVideoFrame.h @@ -101,6 +101,12 @@ public: virtual nsresult CreateAnonymousContent(nsTArray& aElements); + nsIContent* GetPosterImage() { return mPosterImage; } + + // Returns PR_TRUE if we should display the poster. Note that once we show + // a video frame, the poster will never be displayed again. + PRBool ShouldDisplayPoster(); + #ifdef DEBUG NS_IMETHOD GetFrameName(nsAString& aResult) const; #endif @@ -115,10 +121,6 @@ protected: // when we're the frame for an audio element, or we've created a video // element for a media which is audio-only. PRBool HasVideoData(); - - // Returns PR_TRUE if we should display the poster. Note that once we show - // a video frame, the poster will never be displayed again. - PRBool ShouldDisplayPoster(); // Sets the mPosterImage's src attribute to be the video's poster attribute, // if we're the frame for a video element. Only call on frames for video diff --git a/layout/generic/test/Makefile.in b/layout/generic/test/Makefile.in index 994e1d813d38..59c8397da161 100644 --- a/layout/generic/test/Makefile.in +++ b/layout/generic/test/Makefile.in @@ -101,6 +101,8 @@ _TEST_FILES = \ test_plugin_focus.html \ test_plugin_mouse_coords.html \ test_plugin_position.xhtml \ + test_selection_expanding.html \ + selection_expanding_xbl.xml \ test_selection_underline.html \ file_BrokenImageReference.png \ file_Dolske.png \ diff --git a/layout/generic/test/selection_expanding_xbl.xml b/layout/generic/test/selection_expanding_xbl.xml new file mode 100644 index 000000000000..aade8f8bb6c3 --- /dev/null +++ b/layout/generic/test/selection_expanding_xbl.xml @@ -0,0 +1,11 @@ + + + + + +

xxxxxxx xxxxxxx xxxxxxx

+ +
+
+
+
diff --git a/layout/generic/test/test_selection_expanding.html b/layout/generic/test/test_selection_expanding.html new file mode 100644 index 000000000000..832030235c05 --- /dev/null +++ b/layout/generic/test/test_selection_expanding.html @@ -0,0 +1,413 @@ + + + +selection expanding test + + + + + + + + + +
+ aaaaaaa + + aaaaaaa aaaaaaa
aaaaaaa aaaaaaa aaaaaaa aaaaaaa
aaaaaaa +
+
+ bbbbbbb + + bbbbbbb bbbbbbb
bbbbbbb bbbbbbb bbbbbbb
bbbbbbb +
+
+ ccccccc + + ccccccc ccccccc
ccccccc ccccccc ccccccc ccccccc
ccccccc +
+ dddddd dddddd dddddd +
+
+
+

yyyyyyy yyyyyyy yyyyyyy

+
+
+ eeeeee eeeeee eeeeee +
+
+
+
+ + \ No newline at end of file diff --git a/layout/inspector/src/inDOMView.cpp b/layout/inspector/src/inDOMView.cpp index 3e60e242af4a..e3d4249908b5 100644 --- a/layout/inspector/src/inDOMView.cpp +++ b/layout/inspector/src/inDOMView.cpp @@ -703,7 +703,7 @@ inDOMView::NodeWillBeDestroyed(const nsINode* aNode) void inDOMView::AttributeChanged(nsIDocument *aDocument, nsIContent* aContent, PRInt32 aNameSpaceID, nsIAtom* aAttribute, - PRInt32 aModType, PRUint32 aStateMask) + PRInt32 aModType) { if (!mTree) { return; diff --git a/layout/mathml/mathml.css b/layout/mathml/mathml.css index 458cc56e10dc..61732586525a 100644 --- a/layout/mathml/mathml.css +++ b/layout/mathml/mathml.css @@ -65,9 +65,6 @@ math[mode="display"], math[display="block"] { math[display="inline"] { display: inline; } -::-moz-math-inline { - display: inline; -} /**************************************************************************/ /* Style switching during frame construction depending on the context of : @@ -408,8 +405,11 @@ mtd[-moz-math-columnline="dashed"] { font-family: serif; /* an empty family is ignored as an error and behaves like inherit */ /* background-color: #3C6; */ } +/* Don't actually style -moz-math-anonymous by default */ +/* ::-moz-math-anonymous { } +*/ /**********************************************************************/ /* Hide embedded semantic MathML content (as opposed to presentational diff --git a/layout/mathml/nsMathMLFrame.cpp b/layout/mathml/nsMathMLFrame.cpp index c8a4b8656efd..2e53d6fccbd7 100644 --- a/layout/mathml/nsMathMLFrame.cpp +++ b/layout/mathml/nsMathMLFrame.cpp @@ -39,7 +39,7 @@ #include "nsINameSpaceManager.h" #include "nsMathMLFrame.h" #include "nsMathMLChar.h" -#include "nsCSSAnonBoxes.h" +#include "nsCSSPseudoElements.h" // used to map attributes into CSS rules #include "nsIDocument.h" @@ -164,12 +164,12 @@ nsMathMLFrame::ResolveMathMLCharStyle(nsPresContext* aPresContext, nsMathMLChar* aMathMLChar, PRBool aIsMutableChar) { - nsIAtom* pseudoStyle = (aIsMutableChar) ? - nsCSSAnonBoxes::mozMathStretchy : - nsCSSAnonBoxes::mozMathAnonymous; // savings + nsCSSPseudoElements::Type pseudoType = (aIsMutableChar) ? + nsCSSPseudoElements::ePseudo_mozMathStretchy : + nsCSSPseudoElements::ePseudo_mozMathAnonymous; // savings nsRefPtr newStyleContext; newStyleContext = aPresContext->StyleSet()-> - ResolvePseudoStyleFor(aContent, pseudoStyle, aParentStyleContext); + ResolvePseudoElementStyle(aContent, pseudoType, aParentStyleContext); if (newStyleContext) aMathMLChar->SetStyleContext(newStyleContext); diff --git a/layout/printing/nsPrintEngine.cpp b/layout/printing/nsPrintEngine.cpp index ea162db12fdf..653da2d2e3f3 100644 --- a/layout/printing/nsPrintEngine.cpp +++ b/layout/printing/nsPrintEngine.cpp @@ -158,7 +158,7 @@ static const char kPrintingPromptService[] = "@mozilla.org/embedcomp/printingpro #include "nsPIDOMWindow.h" #include "nsFocusManager.h" - +#include "nsRange.h" #include "nsCDefaultURIFixup.h" #include "nsIURIFixup.h" @@ -439,9 +439,10 @@ static void DumpLayoutData(char* aTitleStr, char* aURLStr, nsresult nsPrintEngine::CommonPrint(PRBool aIsPrintPreview, nsIPrintSettings* aPrintSettings, - nsIWebProgressListener* aWebProgressListener) { + nsIWebProgressListener* aWebProgressListener, + nsIDOMDocument* aDoc) { nsresult rv = DoCommonPrint(aIsPrintPreview, aPrintSettings, - aWebProgressListener); + aWebProgressListener, aDoc); if (NS_FAILED(rv)) { if (aIsPrintPreview) { SetIsCreatingPrintPreview(PR_FALSE); @@ -463,7 +464,8 @@ nsPrintEngine::CommonPrint(PRBool aIsPrintPreview, nsresult nsPrintEngine::DoCommonPrint(PRBool aIsPrintPreview, nsIPrintSettings* aPrintSettings, - nsIWebProgressListener* aWebProgressListener) + nsIWebProgressListener* aWebProgressListener, + nsIDOMDocument* aDoc) { nsresult rv; @@ -540,7 +542,7 @@ nsPrintEngine::DoCommonPrint(PRBool aIsPrintPreview, mPrt->mPrintObject = new nsPrintObject(); NS_ENSURE_TRUE(mPrt->mPrintObject, NS_ERROR_OUT_OF_MEMORY); - rv = mPrt->mPrintObject->Init(webContainer); + rv = mPrt->mPrintObject->Init(webContainer, aDoc, aIsPrintPreview); NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_TRUE(mPrt->mPrintDocList.AppendElement(mPrt->mPrintObject), @@ -550,11 +552,13 @@ nsPrintEngine::DoCommonPrint(PRBool aIsPrintPreview, mPrt->mPrintObject->mFrameType = mPrt->mIsParentAFrameSet ? eFrameSet : eDoc; // Build the "tree" of PrintObjects - nsCOMPtr parentAsNode(do_QueryInterface(webContainer)); + nsCOMPtr parentAsNode = + do_QueryInterface(mPrt->mPrintObject->mDocShell); BuildDocTree(parentAsNode, &mPrt->mPrintDocList, mPrt->mPrintObject); // XXX This isn't really correct... - if (!mPrt->mPrintObject->mDocument->GetRootContent()) + if (!mPrt->mPrintObject->mDocument || + !mPrt->mPrintObject->mDocument->GetRootContent()) return NS_ERROR_GFX_PRINTER_STARTDOC; // Create the linkage from the sub-docs back to the content element @@ -749,7 +753,8 @@ NS_IMETHODIMP nsPrintEngine::Print(nsIPrintSettings* aPrintSettings, nsIWebProgressListener* aWebProgressListener) { - return CommonPrint(PR_FALSE, aPrintSettings, aWebProgressListener); + nsCOMPtr doc = do_QueryInterface(mDocument); + return CommonPrint(PR_FALSE, aPrintSettings, aWebProgressListener, doc); } NS_IMETHODIMP @@ -770,8 +775,13 @@ nsPrintEngine::PrintPreview(nsIPrintSettings* aPrintSettings, return NS_ERROR_FAILURE; } + NS_ENSURE_STATE(aChildDOMWin); + nsCOMPtr doc; + aChildDOMWin->GetDocument(getter_AddRefs(doc)); + NS_ENSURE_STATE(doc); + // Document is not busy -- go ahead with the Print Preview - return CommonPrint(PR_TRUE, aPrintSettings, aWebProgressListener); + return CommonPrint(PR_TRUE, aPrintSettings, aWebProgressListener, doc); } //---------------------------------------------------------------------------------- @@ -1089,12 +1099,6 @@ nsPrintEngine::IsThereARangeSelection(nsIDOMWindow* aDOMWin) PRBool nsPrintEngine::IsParentAFrameSet(nsIDocShell * aParent) { - NS_ASSERTION(aParent, "Pointer is null!"); - - nsCOMPtr shell; - aParent->GetPresShell(getter_AddRefs(shell)); - NS_ASSERTION(shell, "shell can't be null"); - // See if the incoming doc is the root document nsCOMPtr parentAsItem(do_QueryInterface(aParent)); if (!parentAsItem) return PR_FALSE; @@ -1114,13 +1118,12 @@ nsPrintEngine::IsParentAFrameSet(nsIDocShell * aParent) PRBool isFrameSet = PR_FALSE; // only check to see if there is a frameset if there is // NO parent doc for this doc. meaning this parent is the root doc - if (shell) { - nsIDocument *doc = shell->GetDocument(); - if (doc) { - nsIContent *rootContent = doc->GetRootContent(); - if (rootContent) { - isFrameSet = HasFramesetChild(rootContent); - } + nsCOMPtr domDoc = do_GetInterface(aParent); + nsCOMPtr doc = do_QueryInterface(domDoc); + if (doc) { + nsIContent *rootContent = doc->GetRootContent(); + if (rootContent) { + isFrameSet = HasFramesetChild(rootContent); } } return isFrameSet; @@ -1154,11 +1157,12 @@ nsPrintEngine::BuildDocTree(nsIDocShellTreeNode * aParentNode, if (viewerFile) { nsCOMPtr childDocShell(do_QueryInterface(child)); nsCOMPtr childNode(do_QueryInterface(child)); + nsCOMPtr doc = do_GetInterface(childDocShell); nsPrintObject * po = new nsPrintObject(); - nsresult rv = po->Init(childDocShell); + po->mParent = aPO; + nsresult rv = po->Init(childDocShell, doc, aPO->mPrintPreview); if (NS_FAILED(rv)) NS_NOTREACHED("Init failed?"); - po->mParent = aPO; aPO->mKids.AppendElement(po); aDocList->AppendElement(po); BuildDocTree(childNode, aDocList, po); @@ -1220,7 +1224,16 @@ nsPrintEngine::MapContentToWebShells(nsPrintObject* aRootPO, // Recursively walk the content from the root item // XXX Would be faster to enumerate the subdocuments, although right now // nsIDocument doesn't expose quite what would be needed. - nsIContent *rootContent = aPO->mDocument->GetRootContent(); + nsCOMPtr viewer; + aPO->mDocShell->GetContentViewer(getter_AddRefs(viewer)); + if (!viewer) return; + + nsCOMPtr domDoc; + viewer->GetDOMDocument(getter_AddRefs(domDoc)); + nsCOMPtr doc = do_QueryInterface(domDoc); + if (!doc) return; + + nsIContent* rootContent = doc->GetRootContent(); if (rootContent) { MapContentForPO(aPO, rootContent); } else { @@ -1313,7 +1326,6 @@ nsPrintEngine::MapContentForPO(nsPrintObject* aPO, // XXX If a subdocument has no onscreen presentation, there will be no PO // This is even if there should be a print presentation if (po) { - po->mContent = aContent; nsCOMPtr frame(do_QueryInterface(aContent)); // "frame" elements not in a frameset context should be treated @@ -1911,6 +1923,8 @@ nsPrintEngine::ReflowPrintObject(nsPrintObject * aPO) canCreateScrollbars = PR_FALSE; } + NS_ASSERTION(!aPO->mPresContext, "Recreating prescontext"); + // create the PresContext aPO->mPresContext = new nsRootPresContext(aPO->mDocument, mIsCreatingPrintPreview ? nsPresContext::eContext_PrintPreview: @@ -1991,6 +2005,13 @@ nsPrintEngine::ReflowPrintObject(nsPrintObject * aPO) float(mPrt->mPrintDC->AppUnitsPerDevPixel()); aPO->mPresContext->SetPrintPreviewScale(mScreenDPI / printDPI); + if (mIsCreatingPrintPreview && documentIsTopLevel) { + mDocViewerPrint->SetPrintPreviewPresentation(aPO->mWindow, + aPO->mViewManager, + aPO->mPresContext, + aPO->mPresShell); + } + rv = aPO->mPresShell->InitialReflow(adjSize.width, adjSize.height); NS_ENSURE_SUCCESS(rv, rv); @@ -2132,6 +2153,100 @@ nsPrintEngine::PrintDocContent(nsPrintObject* aPO, nsresult& aStatus) return PR_FALSE; } +static already_AddRefed +GetEqualNodeInCloneTree(nsIDOMNode* aNode, nsIDocument* aDoc) +{ + nsCOMPtr content = do_QueryInterface(aNode); + // Selections in anonymous subtrees aren't supported. + if (content && content->IsInAnonymousSubtree()) { + return nsnull; + } + + nsCOMPtr node = do_QueryInterface(aNode); + NS_ENSURE_TRUE(node, nsnull); + + nsTArray indexArray; + nsINode* current = node; + NS_ENSURE_TRUE(current, nsnull); + while (current) { + nsINode* parent = current->GetNodeParent(); + if (!parent) { + break; + } + PRInt32 index = parent->IndexOf(current); + NS_ENSURE_TRUE(index >= 0, nsnull); + indexArray.AppendElement(index); + current = parent; + } + NS_ENSURE_TRUE(current->IsNodeOfType(nsINode::eDOCUMENT), nsnull); + + current = aDoc; + for (PRInt32 i = indexArray.Length() - 1; i >= 0; --i) { + current = current->GetChildAt(indexArray[i]); + NS_ENSURE_TRUE(current, nsnull); + } + nsCOMPtr result = do_QueryInterface(current); + return result.forget(); +} + +static nsresult CloneRangeToSelection(nsIDOMRange* aRange, + nsIDocument* aDoc, + nsISelection* aSelection) +{ + PRBool collapsed = PR_FALSE; + aRange->GetCollapsed(&collapsed); + if (collapsed) { + return NS_OK; + } + + nsCOMPtr startContainer, endContainer; + PRInt32 startOffset = -1, endOffset = -1; + aRange->GetStartContainer(getter_AddRefs(startContainer)); + aRange->GetStartOffset(&startOffset); + aRange->GetEndContainer(getter_AddRefs(endContainer)); + aRange->GetEndOffset(&endOffset); + NS_ENSURE_STATE(startContainer && endContainer); + + nsCOMPtr newStart = GetEqualNodeInCloneTree(startContainer, aDoc); + nsCOMPtr newEnd = GetEqualNodeInCloneTree(endContainer, aDoc); + NS_ENSURE_STATE(newStart && newEnd); + + nsCOMPtr range; + NS_NewRange(getter_AddRefs(range)); + NS_ENSURE_TRUE(range, NS_ERROR_OUT_OF_MEMORY); + + nsresult rv = range->SetStart(newStart, startOffset); + NS_ENSURE_SUCCESS(rv, rv); + rv = range->SetEnd(newEnd, endOffset); + NS_ENSURE_SUCCESS(rv, rv); + + return aSelection->AddRange(range); +} + +static nsresult CloneSelection(nsIDocument* aOrigDoc, nsIDocument* aDoc) +{ + nsIPresShell* origShell = aOrigDoc->GetPrimaryShell(); + nsIPresShell* shell = aDoc->GetPrimaryShell(); + NS_ENSURE_STATE(origShell && shell); + + nsCOMPtr origSelection = + origShell->GetCurrentSelection(nsISelectionController::SELECTION_NORMAL); + nsCOMPtr selection = + shell->GetCurrentSelection(nsISelectionController::SELECTION_NORMAL); + NS_ENSURE_STATE(origSelection && selection); + + PRInt32 rangeCount = 0; + origSelection->GetRangeCount(&rangeCount); + for (PRInt32 i = 0; i < rangeCount; ++i) { + nsCOMPtr range; + origSelection->GetRangeAt(i, getter_AddRefs(range)); + if (range) { + CloneRangeToSelection(range, aDoc, selection); + } + } + return NS_OK; +} + //------------------------------------------------------- nsresult nsPrintEngine::DoPrint(nsPrintObject * aPO) @@ -2195,6 +2310,8 @@ nsPrintEngine::DoPrint(nsPrintObject * aPO) GetDisplayTitleAndURL(aPO, &docTitleStr, &docURLStr, eDocTitleDefBlank); if (nsIPrintSettings::kRangeSelection == printRangeType) { + CloneSelection(aPO->mDocument->GetOriginalDocument(), aPO->mDocument); + poPresContext->SetIsRenderingOnlySelection(PR_TRUE); // temporarily creating rendering context // which is needed to dinf the selection frames @@ -2796,8 +2913,10 @@ nsPrintEngine::FindPrintObjectByDOMWin(nsPrintObject* aPO, return nsnull; } - nsCOMPtr domWin(do_GetInterface(aPO->mDocShell)); - if (domWin && domWin == aDOMWin) { + nsCOMPtr domDoc; + aDOMWin->GetDocument(getter_AddRefs(domDoc)); + nsCOMPtr doc = do_QueryInterface(domDoc); + if (aPO->mDocument && aPO->mDocument->GetOriginalDocument() == doc) { return aPO; } @@ -2901,7 +3020,8 @@ nsPrintEngine::EnablePOsForPrinting() // // XXX this is sort of a hack right here to make the page // not try to reposition itself when printing selection - nsCOMPtr domWin = do_GetInterface(po->mDocShell); + nsCOMPtr domWin = + do_QueryInterface(po->mDocument->GetOriginalDocument()->GetWindow()); if (!IsThereARangeSelection(domWin)) { printRangeType = nsIPrintSettings::kRangeAllPages; mPrt->mPrintSettings->SetPrintRange(printRangeType); @@ -2948,7 +3068,8 @@ nsPrintEngine::EnablePOsForPrinting() // // XXX this is sort of a hack right here to make the page // not try to reposition itself when printing selection - nsCOMPtr domWin = do_GetInterface(po->mDocShell); + nsCOMPtr domWin = + do_QueryInterface(po->mDocument->GetOriginalDocument()->GetWindow()); if (!IsThereARangeSelection(domWin)) { printRangeType = nsIPrintSettings::kRangeAllPages; mPrt->mPrintSettings->SetPrintRange(printRangeType); diff --git a/layout/printing/nsPrintEngine.h b/layout/printing/nsPrintEngine.h index 15a6435e998f..7c901ef3605b 100644 --- a/layout/printing/nsPrintEngine.h +++ b/layout/printing/nsPrintEngine.h @@ -227,10 +227,12 @@ public: protected: nsresult CommonPrint(PRBool aIsPrintPreview, nsIPrintSettings* aPrintSettings, - nsIWebProgressListener* aWebProgressListener); + nsIWebProgressListener* aWebProgressListener, + nsIDOMDocument* aDoc); nsresult DoCommonPrint(PRBool aIsPrintPreview, nsIPrintSettings* aPrintSettings, - nsIWebProgressListener* aWebProgressListener); + nsIWebProgressListener* aWebProgressListener, + nsIDOMDocument* aDoc); void FirePrintCompletionEvent(); static nsresult GetSeqFrameAndCountPagesInternal(nsPrintObject* aPO, diff --git a/layout/printing/nsPrintObject.cpp b/layout/printing/nsPrintObject.cpp index 5fa36ab59cbe..5bc41d0ec690 100644 --- a/layout/printing/nsPrintObject.cpp +++ b/layout/printing/nsPrintObject.cpp @@ -39,6 +39,12 @@ #include "nsIContentViewer.h" #include "nsIDOMDocument.h" #include "nsContentUtils.h" +#include "nsIInterfaceRequestorUtils.h" +#include "nsPIDOMWindow.h" +#include "nsGkAtoms.h" +#include "nsComponentManagerUtils.h" +#include "nsIDocShellTreeOwner.h" +#include "nsIDocShellTreeItem.h" //--------------------------------------------------- //-- nsPrintObject Class Impl @@ -65,23 +71,49 @@ nsPrintObject::~nsPrintObject() //------------------------------------------------------------------ // Resets PO by destroying the presentation nsresult -nsPrintObject::Init(nsIDocShell* aDocShell) +nsPrintObject::Init(nsIDocShell* aDocShell, nsIDOMDocument* aDoc, + PRBool aPrintPreview) { - mDocShell = aDocShell; - NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE); - - nsresult rv; - nsCOMPtr viewer; - rv = mDocShell->GetContentViewer(getter_AddRefs(viewer)); - NS_ENSURE_SUCCESS(rv, rv); - - nsCOMPtr doc; - viewer->GetDOMDocument(getter_AddRefs(doc)); - NS_ENSURE_SUCCESS(rv, rv); - - mDocument = do_QueryInterface(doc); - NS_ENSURE_TRUE(mDocument, NS_ERROR_FAILURE); + mPrintPreview = aPrintPreview; + if (mPrintPreview || mParent) { + mDocShell = aDocShell; + } else { + nsCOMPtr owner = do_GetInterface(aDocShell); + nsCOMPtr item = do_QueryInterface(aDocShell); + PRInt32 itemType = 0; + item->GetItemType(&itemType); + // Create a container docshell for printing. + mDocShell = do_CreateInstance("@mozilla.org/docshell;1"); + NS_ENSURE_TRUE(mDocShell, NS_ERROR_OUT_OF_MEMORY); + nsCOMPtr newItem = do_QueryInterface(mDocShell); + newItem->SetItemType(itemType); + newItem->SetTreeOwner(owner); + } + NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE); + + nsCOMPtr dummy = do_GetInterface(mDocShell); + nsCOMPtr viewer; + mDocShell->GetContentViewer(getter_AddRefs(viewer)); + NS_ENSURE_STATE(viewer); + + nsCOMPtr doc = do_QueryInterface(aDoc); + NS_ENSURE_STATE(doc); + + if (mParent) { + nsCOMPtr window = doc->GetWindow(); + if (window) { + mContent = do_QueryInterface(window->GetFrameElementInternal()); + } + mDocument = doc; + return NS_OK; + } + + mDocument = doc->CreateStaticClone(mDocShell); + nsCOMPtr clonedDOMDoc = do_QueryInterface(mDocument); + NS_ENSURE_STATE(clonedDOMDoc); + + viewer->SetDOMDocument(clonedDOMDoc); return NS_OK; } diff --git a/layout/printing/nsPrintObject.h b/layout/printing/nsPrintObject.h index 5f666bfb63ca..cc573c941d77 100644 --- a/layout/printing/nsPrintObject.h +++ b/layout/printing/nsPrintObject.h @@ -62,7 +62,8 @@ public: ~nsPrintObject(); // non-virtual // Methods - nsresult Init(nsIDocShell* aDocShell); + nsresult Init(nsIDocShell* aDocShell, nsIDOMDocument* aDoc, + PRBool aPrintPreview); PRBool IsPrintable() { return !mDontPrint; } void DestroyPresentation(); @@ -76,7 +77,7 @@ public: nsCOMPtr mViewManager; nsCOMPtr mWindow; - nsIContent* mContent; + nsCOMPtr mContent; PrintObjectType mFrameType; nsTArray mKids; @@ -86,7 +87,7 @@ public: PRPackedBool mPrintAsIs; PRPackedBool mSharedPresShell; PRPackedBool mInvisible; // Indicates PO is set to not visible by CSS - + PRPackedBool mPrintPreview; float mShrinkRatio; float mZoomRatio; diff --git a/layout/reftests/css-transitions/transitions-inline-already-wrapped-1.html b/layout/reftests/css-transitions/transitions-inline-already-wrapped-1.html index fa97747616e8..d8c682b97d59 100644 --- a/layout/reftests/css-transitions/transitions-inline-already-wrapped-1.html +++ b/layout/reftests/css-transitions/transitions-inline-already-wrapped-1.html @@ -10,15 +10,8 @@ window.onload = run; function run() { var test = document.getElementById("test"); var unused = test.offsetWidth; - // FIXME (Bug 522595): It's a bug that we need to do this at all: the - // way we change style data essentially violates style rule - // immutability because we assume that all of the difference - // calculation will use PeekStyleData, which is no longer true with - // transitions. - unused = getComputedStyle(test, "").color; test.style.color = "red"; unused = test.offsetWidth; - unused = getComputedStyle(test, "").color; document.documentElement.removeAttribute("class"); } diff --git a/layout/reftests/css-transitions/transitions-inline-rewrap-1.html b/layout/reftests/css-transitions/transitions-inline-rewrap-1.html index 8e6b11207efb..5ff281701c37 100644 --- a/layout/reftests/css-transitions/transitions-inline-rewrap-1.html +++ b/layout/reftests/css-transitions/transitions-inline-rewrap-1.html @@ -10,18 +10,10 @@ window.onload = run; function run() { var test = document.getElementById("test"); var unused = test.offsetWidth; - // FIXME (Bug 522595): It's a bug that we need to do this at all: the - // way we change style data essentially violates style rule - // immutability because we assume that all of the difference - // calculation will use PeekStyleData, which is no longer true with - // transitions. - unused = getComputedStyle(test, "").color; test.style.color = "red"; unused = test.offsetWidth; - unused = getComputedStyle(test, "").color; test.parentNode.style.width = "3em"; unused = test.offsetWidth; - unused = getComputedStyle(test, "").color; document.documentElement.removeAttribute("class"); } diff --git a/layout/reftests/font-face/reftest.list b/layout/reftests/font-face/reftest.list index e4dca51326b3..0fba1b13149c 100644 --- a/layout/reftests/font-face/reftest.list +++ b/layout/reftests/font-face/reftest.list @@ -113,3 +113,8 @@ HTTP(..) != 507960-1-bad-sfnt-version-woff.html 507960-1-ref.html HTTP(..) != 507960-1-bad-woff-sig.html 507960-1-ref.html HTTP(..) != 507960-1-bad-offset-woff.html 507960-1-ref.html HTTP(..) != 507960-1-woff-bad-hint.html 507960-1-ref.html + +# Bug 523717 +HTTP(..) == underline-offset-change-1.html underline-offset-change-1-ref.html +HTTP(..) == underline-offset-change-2.html underline-offset-change-2-ref.html +fails-if(MOZ_WIDGET_TOOLKIT=="cocoa") fails-if(MOZ_WIDGET_TOOLKIT=="windows") HTTP(..) != underline-offset-change-1-ref.html underline-offset-change-2-ref.html # Bug 534132 diff --git a/layout/reftests/font-face/underline-offset-change-1-ref.html b/layout/reftests/font-face/underline-offset-change-1-ref.html new file mode 100644 index 000000000000..b3bd5c9ca01c --- /dev/null +++ b/layout/reftests/font-face/underline-offset-change-1-ref.html @@ -0,0 +1,25 @@ + + + + Switching first font to one with higher underline (reference) + + + + + +

A

+ + + diff --git a/layout/reftests/font-face/underline-offset-change-1.html b/layout/reftests/font-face/underline-offset-change-1.html new file mode 100644 index 000000000000..d4ccca7a343d --- /dev/null +++ b/layout/reftests/font-face/underline-offset-change-1.html @@ -0,0 +1,45 @@ + + + + Switching first font to one with higher underline + + + + + + + +

A

+ + + diff --git a/layout/reftests/font-face/underline-offset-change-2-ref.html b/layout/reftests/font-face/underline-offset-change-2-ref.html new file mode 100644 index 000000000000..17bf99d2c766 --- /dev/null +++ b/layout/reftests/font-face/underline-offset-change-2-ref.html @@ -0,0 +1,25 @@ + + + + Switching first font to one with lower underline (reference) + + + + + +

A

+ + + diff --git a/layout/reftests/font-face/underline-offset-change-2.html b/layout/reftests/font-face/underline-offset-change-2.html new file mode 100644 index 000000000000..57896d5932ea --- /dev/null +++ b/layout/reftests/font-face/underline-offset-change-2.html @@ -0,0 +1,45 @@ + + + + Switching first font to one with lower underline + + + + + + + +

A

+ + + diff --git a/layout/reftests/fonts/mark-generate.py b/layout/reftests/fonts/mark-generate.py index 9538e7058460..a7334faf0931 100755 --- a/layout/reftests/fonts/mark-generate.py +++ b/layout/reftests/fonts/mark-generate.py @@ -68,3 +68,25 @@ for codepoint in range(ord("A"), ord("D") + 1): f.generate("mark" + mark + charname + ".ttf") f.generate("mark" + mark + charname + ".otf") + +for codepoint in range(ord("A"), ord("A") + 1): + for (mark, width) in [("", 1500), ("2", 1800)]: + for (uposname, upos) in [("low", -350), ("high", -50)]: + charname = chr(codepoint) + f = fontforge.font() + n = "Mark" + mark + charname + f.fontname = n + f.familyname = n + f.fullname = n + f.descent = 400 + f.upos = upos + f.uwidth = 100 + f.copyright = "Copyright (c) 2008 Mozilla Corporation" + + g = f.createChar(codepoint, charname) + g.importOutlines("mark" + mark + "-glyph.svg") + g.width = width + + f.generate("mark" + mark + charname + "-" + uposname + + "underline.ttf") + diff --git a/layout/reftests/fonts/mark2A-highunderline.ttf b/layout/reftests/fonts/mark2A-highunderline.ttf new file mode 100644 index 000000000000..eb483093e1a5 Binary files /dev/null and b/layout/reftests/fonts/mark2A-highunderline.ttf differ diff --git a/layout/reftests/fonts/mark2A-lowunderline.ttf b/layout/reftests/fonts/mark2A-lowunderline.ttf new file mode 100644 index 000000000000..819d95ae0939 Binary files /dev/null and b/layout/reftests/fonts/mark2A-lowunderline.ttf differ diff --git a/layout/reftests/fonts/markA-highunderline.ttf b/layout/reftests/fonts/markA-highunderline.ttf new file mode 100644 index 000000000000..cbf22fc52719 Binary files /dev/null and b/layout/reftests/fonts/markA-highunderline.ttf differ diff --git a/layout/reftests/fonts/markA-lowunderline.ttf b/layout/reftests/fonts/markA-lowunderline.ttf new file mode 100644 index 000000000000..020ceb2af8db Binary files /dev/null and b/layout/reftests/fonts/markA-lowunderline.ttf differ diff --git a/layout/reftests/ib-split/append-to-empty-trailing-inline-1-ref.html b/layout/reftests/ib-split/append-to-empty-trailing-inline-1-ref.html new file mode 100644 index 000000000000..91dbb4659fc7 --- /dev/null +++ b/layout/reftests/ib-split/append-to-empty-trailing-inline-1-ref.html @@ -0,0 +1,19 @@ + + + + + + + + + + +AA + + + diff --git a/layout/reftests/ib-split/append-to-empty-trailing-inline-1.html b/layout/reftests/ib-split/append-to-empty-trailing-inline-1.html new file mode 100644 index 000000000000..8f080454f868 --- /dev/null +++ b/layout/reftests/ib-split/append-to-empty-trailing-inline-1.html @@ -0,0 +1,27 @@ + + + + + + + + + + + + +A + + + diff --git a/layout/reftests/ib-split/append-to-nested-split-inline-1-noib-ref.html b/layout/reftests/ib-split/append-to-nested-split-inline-1-noib-ref.html new file mode 100644 index 000000000000..3a7bcf5c7d9a --- /dev/null +++ b/layout/reftests/ib-split/append-to-nested-split-inline-1-noib-ref.html @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + before span + + + + span + + + + after span + + + + + diff --git a/layout/reftests/ib-split/append-to-nested-split-inline-1-ref.html b/layout/reftests/ib-split/append-to-nested-split-inline-1-ref.html new file mode 100644 index 000000000000..fd54f25327a2 --- /dev/null +++ b/layout/reftests/ib-split/append-to-nested-split-inline-1-ref.html @@ -0,0 +1,22 @@ + + + + + + + + + + + before span + span + after span + + + + + diff --git a/layout/reftests/ib-split/append-to-nested-split-inline-1.html b/layout/reftests/ib-split/append-to-nested-split-inline-1.html new file mode 100644 index 000000000000..14c54e1db118 --- /dev/null +++ b/layout/reftests/ib-split/append-to-nested-split-inline-1.html @@ -0,0 +1,32 @@ + + + + + + + + + + + + before span + + + + + diff --git a/layout/reftests/ib-split/insert-into-split-inline-14.html b/layout/reftests/ib-split/insert-into-split-inline-14.html index 8ce3da92c74f..3c0b5d5aaf23 100644 --- a/layout/reftests/ib-split/insert-into-split-inline-14.html +++ b/layout/reftests/ib-split/insert-into-split-inline-14.html @@ -8,7 +8,6 @@ diff --git a/layout/reftests/ib-split/reftest.list b/layout/reftests/ib-split/reftest.list index ecaa4139616a..779921d2100b 100644 --- a/layout/reftests/ib-split/reftest.list +++ b/layout/reftests/ib-split/reftest.list @@ -80,3 +80,6 @@ == ignored-margins-2a.html ignored-margins-2-ref.html == ignored-margins-2b.html ignored-margins-2-ref.html == trailing-inline-with-continuations-1.html trailing-inline-with-continuations-1-ref.html +== append-to-empty-trailing-inline-1.html append-to-empty-trailing-inline-1-ref.html +== append-to-nested-split-inline-1.html append-to-nested-split-inline-1-ref.html +== append-to-nested-split-inline-1-ref.html append-to-nested-split-inline-1-noib-ref.html diff --git a/layout/reftests/pixel-rounding/reftest.list b/layout/reftests/pixel-rounding/reftest.list index eb76cfc88868..3b0668e4ce7d 100644 --- a/layout/reftests/pixel-rounding/reftest.list +++ b/layout/reftests/pixel-rounding/reftest.list @@ -1,4 +1,4 @@ -random == check-image.html check-image-ref.html # bug 371232 +== check-image.html check-image-ref.html == check-image-blue.html check-image-blue-ref.html @@ -95,24 +95,22 @@ fails == collapsed-border-top-5.html border-top-10-ref.html fails == collapsed-border-top-6.html border-top-10-ref.html -# Mac failures covered by bug 371316, although perhaps a separate bug -# should be filed. != image-base-ref.html image-height-10-ref.html == image-height-4.html image-base-ref.html == image-height-5.html image-height-10-ref.html == image-height-6.html image-height-10-ref.html != image-base-ref.html image-top-10-ref.html -random-if(MOZ_WIDGET_TOOLKIT=="cocoa") == image-top-4.html image-base-ref.html -random-if(MOZ_WIDGET_TOOLKIT=="cocoa") == image-top-5.html image-top-10-ref.html -random-if(MOZ_WIDGET_TOOLKIT=="cocoa") == image-top-6.html image-top-10-ref.html +== image-top-4.html image-base-ref.html +== image-top-5.html image-top-10-ref.html +== image-top-6.html image-top-10-ref.html != image-base-ref.html image-width-10-ref.html -random-if(MOZ_WIDGET_TOOLKIT=="cocoa") == image-width-4.html image-base-ref.html +== image-width-4.html image-base-ref.html == image-width-5.html image-width-10-ref.html == image-width-6.html image-width-10-ref.html != image-base-ref.html image-left-10-ref.html -random-if(MOZ_WIDGET_TOOLKIT=="cocoa") == image-left-4.html image-base-ref.html -random-if(MOZ_WIDGET_TOOLKIT=="cocoa") == image-left-5.html image-left-10-ref.html -random-if(MOZ_WIDGET_TOOLKIT=="cocoa") == image-left-6.html image-left-10-ref.html +== image-left-4.html image-base-ref.html +== image-left-5.html image-left-10-ref.html +== image-left-6.html image-left-10-ref.html == image-top-height-4.html image-height-4.html == image-top-height-5.html image-height-5.html == image-top-height-6.html image-height-6.html @@ -136,9 +134,9 @@ random-if(MOZ_WIDGET_TOOLKIT=="cocoa") == image-left-6.html image-left-10-ref.ht == offscreen-image-pos-4.html offscreen-0-ref.html == offscreen-image-pos-5.html offscreen-10-ref.html == offscreen-image-pos-6.html offscreen-10-ref.html -== offscreen-image-size-4.html offscreen-0-ref.html # bug 371316 -== offscreen-image-size-5.html offscreen-10-ref.html # bug 371316 -== offscreen-image-size-6.html offscreen-10-ref.html # bug 371316 +== offscreen-image-size-4.html offscreen-0-ref.html +== offscreen-image-size-5.html offscreen-10-ref.html +== offscreen-image-size-6.html offscreen-10-ref.html != rounded-background-color-base-ref.html rounded-background-color-height-10-ref.html diff --git a/layout/reftests/svg/reftest.list b/layout/reftests/svg/reftest.list index 630802d87a4e..17d67c7981b4 100644 --- a/layout/reftests/svg/reftest.list +++ b/layout/reftests/svg/reftest.list @@ -125,6 +125,7 @@ random-if(MOZ_WIDGET_TOOLKIT=="gtk2") == text-font-weight-01.svg text-font-weigh == switch-01.svg pass.svg == text-gradient-01.svg text-gradient-01-ref.svg == text-in-link-01.svg text-in-link-01-ref.svg +== text-in-link-02.svg text-in-link-02-ref.svg == text-scale-01.svg text-scale-01-ref.svg == text-style-01a.svg text-style-01-ref.svg == text-style-01b.svg text-style-01-ref.svg diff --git a/layout/reftests/svg/smil/style/reftest.list b/layout/reftests/svg/smil/style/reftest.list index a385cfc71138..7ef343d6ed8e 100644 --- a/layout/reftests/svg/smil/style/reftest.list +++ b/layout/reftests/svg/smil/style/reftest.list @@ -66,8 +66,7 @@ fails == anim-css-fillopacity-3-clamp-big.svg anim-css-fillopacity-3-ref.svg == anim-css-fillopacity-3-clamp-small.svg anim-css-fillopacity-3-ref.svg # 'font' shorthand property -# XXXdholbert We don't yet support animating shorthand properties (bug 520239) -fails == anim-css-font-1.svg anim-css-font-1-ref.svg +== anim-css-font-1.svg anim-css-font-1-ref.svg # 'font-size' property, from/by/to with pixel values only == anim-css-fontsize-1-from-by-px-px.svg anim-css-fontsize-1-ref.svg diff --git a/layout/reftests/svg/text-in-link-02-ref.svg b/layout/reftests/svg/text-in-link-02-ref.svg new file mode 100644 index 000000000000..1ffb7356bb48 --- /dev/null +++ b/layout/reftests/svg/text-in-link-02-ref.svg @@ -0,0 +1,12 @@ + + + Reference to check that links with viewBoxes work + + + + AAAAABBBBBCCCCCDDDDD + + diff --git a/layout/reftests/svg/text-in-link-02.svg b/layout/reftests/svg/text-in-link-02.svg new file mode 100644 index 000000000000..ac86614b0cf2 --- /dev/null +++ b/layout/reftests/svg/text-in-link-02.svg @@ -0,0 +1,11 @@ + + + Testcase to check that links with viewBoxes work + + + + AAAAABBBBBCCCCCDDDDD + diff --git a/layout/style/forms.css b/layout/style/forms.css index ed0ab1d24ef9..08f75e80efd8 100644 --- a/layout/style/forms.css +++ b/layout/style/forms.css @@ -259,10 +259,6 @@ select:empty { -moz-box-sizing: border-box ! important; } -select::-moz-scrolled-content { - display: block !important; -} - option { display: block; float: none !important; diff --git a/layout/style/nsCSSAnonBoxList.h b/layout/style/nsCSSAnonBoxList.h index 2dc9b44df4f8..34438b8ff4f3 100644 --- a/layout/style/nsCSSAnonBoxList.h +++ b/layout/style/nsCSSAnonBoxList.h @@ -59,6 +59,10 @@ CSS_ANON_BOX(mozAnonymousPositionedBlock, ":-moz-anonymous-positioned-block") CSS_ANON_BOX(mozMathMLAnonymousBlock, ":-moz-mathml-anonymous-block") CSS_ANON_BOX(mozXULAnonymousBlock, ":-moz-xul-anonymous-block") +// Framesets +CSS_ANON_BOX(horizontalFramesetBorder, ":-moz-hframeset-border") +CSS_ANON_BOX(verticalFramesetBorder, ":-moz-vframeset-border") + CSS_ANON_BOX(mozLineFrame, ":-moz-line-frame") CSS_ANON_BOX(buttonContent, ":-moz-button-content") @@ -105,12 +109,6 @@ CSS_ANON_BOX(moztreeprogressmeter, ":-moz-tree-progressmeter") CSS_ANON_BOX(moztreedropfeedback, ":-moz-tree-drop-feedback") #endif -#ifdef MOZ_MATHML -CSS_ANON_BOX(mozMathStretchy, ":-moz-math-stretchy") -CSS_ANON_BOX(mozMathAnonymous, ":-moz-math-anonymous") -CSS_ANON_BOX(mozMathInline, ":-moz-math-inline") -#endif - #ifdef MOZ_SVG CSS_ANON_BOX(mozSVGForeignContent, ":-moz-svg-foreign-content") #endif diff --git a/layout/style/nsCSSDataBlock.cpp b/layout/style/nsCSSDataBlock.cpp index ffb239212579..465e3913abe2 100644 --- a/layout/style/nsCSSDataBlock.cpp +++ b/layout/style/nsCSSDataBlock.cpp @@ -410,7 +410,7 @@ nsCSSCompressedDataBlock::StorageFor(nsCSSProperty aProperty) const return nsnull; } -nsCSSCompressedDataBlock* +already_AddRefed nsCSSCompressedDataBlock::Clone() const { const char *cursor = Block(), *cursor_end = BlockEnd(); @@ -489,6 +489,8 @@ nsCSSCompressedDataBlock::Clone() const result->mBlockEnd = result_cursor; result->mStyleBits = mStyleBits; NS_ASSERTION(result->DataSize() == DataSize(), "wrong size"); + + result->AddRef(); return result; } @@ -544,13 +546,15 @@ nsCSSCompressedDataBlock::Destroy() delete this; } -/* static */ nsCSSCompressedDataBlock* +/* static */ already_AddRefed nsCSSCompressedDataBlock::CreateEmptyBlock() { nsCSSCompressedDataBlock *result = new(0) nsCSSCompressedDataBlock(); if (!result) return nsnull; result->mBlockEnd = result->Block(); + + result->AddRef(); return result; } @@ -584,10 +588,22 @@ nsCSSExpandedDataBlock::kOffsetTable[eCSSProperty_COUNT_no_shorthands] = { }; void -nsCSSExpandedDataBlock::DoExpand(nsCSSCompressedDataBlock *aBlock, +nsCSSExpandedDataBlock::DoExpand(nsRefPtr *aBlock, PRBool aImportant) { - NS_PRECONDITION(aBlock, "unexpected null block"); + NS_PRECONDITION(*aBlock, "unexpected null block"); + + if (!(*aBlock)->IsMutable()) { + // FIXME (maybe): We really don't need to clone the block + // itself, just all the data inside it. + *aBlock = (*aBlock)->Clone(); + if (!aBlock) { + // Not much we can do; just lose the properties. + NS_WARNING("out of memory"); + return; + } + NS_ABORT_IF_FALSE((*aBlock)->IsMutable(), "we just cloned it"); + } /* * Save needless copying and allocation by copying the memory @@ -595,8 +611,8 @@ nsCSSExpandedDataBlock::DoExpand(nsCSSCompressedDataBlock *aBlock, * then, to avoid destructors, deleting the compressed block by * calling |delete| instead of using its |Destroy| method. */ - const char* cursor = aBlock->Block(); - const char* cursor_end = aBlock->BlockEnd(); + const char* cursor = (*aBlock)->Block(); + const char* cursor_end = (*aBlock)->BlockEnd(); while (cursor < cursor_end) { nsCSSProperty iProp = PropertyAtCursor(cursor); NS_ASSERTION(0 <= iProp && iProp < eCSSProperty_COUNT_no_shorthands, @@ -663,21 +679,21 @@ nsCSSExpandedDataBlock::DoExpand(nsCSSCompressedDataBlock *aBlock, } NS_ASSERTION(cursor == cursor_end, "inconsistent data"); - delete aBlock; + NS_ASSERTION((*aBlock)->mRefCnt == 1, "unexpected reference count"); + delete aBlock->forget().get(); } void -nsCSSExpandedDataBlock::Expand(nsCSSCompressedDataBlock **aNormalBlock, - nsCSSCompressedDataBlock **aImportantBlock) +nsCSSExpandedDataBlock::Expand( + nsRefPtr *aNormalBlock, + nsRefPtr *aImportantBlock) { NS_PRECONDITION(*aNormalBlock, "unexpected null block"); AssertInitialState(); - DoExpand(*aNormalBlock, PR_FALSE); - *aNormalBlock = nsnull; + DoExpand(aNormalBlock, PR_FALSE); if (*aImportantBlock) { - DoExpand(*aImportantBlock, PR_TRUE); - *aImportantBlock = nsnull; + DoExpand(aImportantBlock, PR_TRUE); } } @@ -749,7 +765,7 @@ void nsCSSExpandedDataBlock::Compress(nsCSSCompressedDataBlock **aNormalBlock, nsCSSCompressedDataBlock **aImportantBlock) { - nsCSSCompressedDataBlock *result_normal, *result_important; + nsRefPtr result_normal, result_important; char *cursor_normal, *cursor_important; ComputeSizeResult size = ComputeSize(); @@ -765,7 +781,6 @@ nsCSSExpandedDataBlock::Compress(nsCSSCompressedDataBlock **aNormalBlock, if (size.important != 0) { result_important = new(size.important) nsCSSCompressedDataBlock(); if (!result_important) { - delete result_normal; *aNormalBlock = nsnull; *aImportantBlock = nsnull; return; @@ -861,8 +876,8 @@ nsCSSExpandedDataBlock::Compress(nsCSSCompressedDataBlock **aNormalBlock, ClearSets(); AssertInitialState(); - *aNormalBlock = result_normal; - *aImportantBlock = result_important; + result_normal.forget(aNormalBlock); + result_important.forget(aImportantBlock); } void diff --git a/layout/style/nsCSSDataBlock.h b/layout/style/nsCSSDataBlock.h index 45d48dfe7b75..f524d8117f9f 100644 --- a/layout/style/nsCSSDataBlock.h +++ b/layout/style/nsCSSDataBlock.h @@ -45,6 +45,7 @@ #include "nsCSSStruct.h" #include "nsCSSProps.h" #include "nsCSSPropertySet.h" +#include "nsAutoPtr.h" struct nsRuleData; @@ -56,6 +57,11 @@ class nsCSSDeclaration; * property-value data for a CSS declaration block (which we misname a * |nsCSSDeclaration|). Mutation is accomplished through * |nsCSSExpandedDataBlock| or in some cases via direct slot access. + * + * Mutation is forbidden when the reference count is greater than one, + * since once a style rule has used a compressed data block, mutation of + * that block is forbidden, and any declarations that want to mutate it + * need to clone it first. */ class nsCSSCompressedDataBlock { public: @@ -119,21 +125,36 @@ public: /** * Clone this block, or return null on out-of-memory. */ - nsCSSCompressedDataBlock* Clone() const; - - /** - * Delete all the data stored in this block, and the block itself. - */ - void Destroy(); + already_AddRefed Clone() const; /** * Create a new nsCSSCompressedDataBlock holding no declarations. */ - static nsCSSCompressedDataBlock* CreateEmptyBlock(); + static already_AddRefed CreateEmptyBlock(); + + void AddRef() { + NS_ASSERTION(mRefCnt == 0 || mRefCnt == 1, + "unexpected reference count"); + ++mRefCnt; + } + void Release() { + NS_ASSERTION(mRefCnt == 1 || mRefCnt == 2, + "unexpected reference count"); + if (--mRefCnt == 0) { + Destroy(); + } + } + + PRBool IsMutable() const { + NS_ASSERTION(mRefCnt == 1 || mRefCnt == 2, + "unexpected reference count"); + return mRefCnt < 2; + } private: PRInt32 mStyleBits; // the structs for which we have data, according to // |nsCachedStyleData::GetBitForSID|. + nsAutoRefCnt mRefCnt; enum { block_chars = 4 }; // put 4 chars in the definition of the class // to ensure size not inflated by alignment @@ -150,6 +171,11 @@ private: // |Expand|) can delete compressed data blocks. ~nsCSSCompressedDataBlock() { } + /** + * Delete all the data stored in this block, and the block itself. + */ + void Destroy(); + char* mBlockEnd; // the byte after the last valid byte char mBlock_[block_chars]; // must be the last member! @@ -162,6 +188,7 @@ private: // Direct slot access to our values. See StorageFor above. Can // return null. Must not be called for shorthand properties. void* SlotForValue(nsCSSProperty aProperty) { + NS_ABORT_IF_FALSE(IsMutable(), "must be mutable"); return const_cast(StorageFor(aProperty)); } }; @@ -199,13 +226,13 @@ public: * expanded block. The state of this expanded block must be clear * beforehand. * - * The compressed block passed in IS DESTROYED by this method and + * The compressed block passed in IS RELEASED by this method and * set to null, and thus cannot be used again. (This is necessary * because ownership of sub-objects is transferred to the expanded - * block.) + * block in many cases.) */ - void Expand(nsCSSCompressedDataBlock **aNormalBlock, - nsCSSCompressedDataBlock **aImportantBlock); + void Expand(nsRefPtr *aNormalBlock, + nsRefPtr *aImportantBlock); /** * Allocate a new compressed block and transfer all of the state @@ -242,7 +269,8 @@ private: }; ComputeSizeResult ComputeSize(); - void DoExpand(nsCSSCompressedDataBlock *aBlock, PRBool aImportant); + void DoExpand(nsRefPtr *aBlock, + PRBool aImportant); #ifdef DEBUG void DoAssertInitialState(); diff --git a/layout/style/nsCSSDeclaration.cpp b/layout/style/nsCSSDeclaration.cpp index aa2000890089..9617182f4f42 100644 --- a/layout/style/nsCSSDeclaration.cpp +++ b/layout/style/nsCSSDeclaration.cpp @@ -62,8 +62,6 @@ #include "nsCOMPtr.h" nsCSSDeclaration::nsCSSDeclaration() - : mData(nsnull), - mImportantData(nsnull) { // check that we can fit all the CSS properties into a PRUint8 // for the mOrder array - if not, might need to use PRUint16! @@ -74,22 +72,17 @@ nsCSSDeclaration::nsCSSDeclaration() nsCSSDeclaration::nsCSSDeclaration(const nsCSSDeclaration& aCopy) : mOrder(aCopy.mOrder), - mData(aCopy.mData ? aCopy.mData->Clone() : nsnull), - mImportantData(aCopy.mImportantData ? aCopy.mImportantData->Clone() - : nsnull) + mData(aCopy.mData ? aCopy.mData->Clone() + : already_AddRefed(nsnull)), + mImportantData(aCopy.mImportantData + ? aCopy.mImportantData->Clone() + : already_AddRefed(nsnull)) { MOZ_COUNT_CTOR(nsCSSDeclaration); } nsCSSDeclaration::~nsCSSDeclaration(void) { - if (mData) { - mData->Destroy(); - } - if (mImportantData) { - mImportantData->Destroy(); - } - MOZ_COUNT_DTOR(nsCSSDeclaration); } @@ -108,7 +101,7 @@ nsresult nsCSSDeclaration::RemoveProperty(nsCSSProperty aProperty) { nsCSSExpandedDataBlock data; - data.Expand(&mData, &mImportantData); + ExpandTo(&data); NS_ASSERTION(!mData && !mImportantData, "Expand didn't null things out"); if (nsCSSProps::IsShorthand(aProperty)) { @@ -121,7 +114,7 @@ nsCSSDeclaration::RemoveProperty(nsCSSProperty aProperty) mOrder.RemoveElement(aProperty); } - data.Compress(&mData, &mImportantData); + CompressFrom(&data); return NS_OK; } @@ -1324,3 +1317,23 @@ nsCSSDeclaration::InitializeEmpty() mData = nsCSSCompressedDataBlock::CreateEmptyBlock(); return mData != nsnull; } + +PRBool +nsCSSDeclaration::EnsureMutable() +{ + if (!mData->IsMutable()) { + nsRefPtr newBlock = mData->Clone(); + if (!newBlock) { + return PR_FALSE; + } + newBlock.swap(mData); + } + if (mImportantData && !mImportantData->IsMutable()) { + nsRefPtr newBlock = mImportantData->Clone(); + if (!newBlock) { + return PR_FALSE; + } + newBlock.swap(mImportantData); + } + return PR_TRUE; +} diff --git a/layout/style/nsCSSDeclaration.h b/layout/style/nsCSSDeclaration.h index 59fcb0ffc6c7..727e5b8be1f5 100644 --- a/layout/style/nsCSSDeclaration.h +++ b/layout/style/nsCSSDeclaration.h @@ -91,13 +91,8 @@ public: nsCSSDeclaration* Clone() const; - nsresult MapRuleInfoInto(nsRuleData *aRuleData) const { - return mData->MapRuleInfoInto(aRuleData); - } - - nsresult MapImportantRuleInfoInto(nsRuleData *aRuleData) const { - return mImportantData->MapRuleInfoInto(aRuleData); - } + nsCSSCompressedDataBlock* GetNormalBlock() const { return mData; } + nsCSSCompressedDataBlock* GetImportantBlock() const { return mImportantData; } /** * Initialize this declaration as holding no data. Return false on @@ -112,7 +107,8 @@ public: void CompressFrom(nsCSSExpandedDataBlock *aExpandedData) { NS_ASSERTION(!mData, "oops"); NS_ASSERTION(!mImportantData, "oops"); - aExpandedData->Compress(&mData, &mImportantData); + aExpandedData->Compress(getter_AddRefs(mData), + getter_AddRefs(mImportantData)); aExpandedData->AssertInitialState(); } @@ -137,6 +133,8 @@ public: * returns non-null if the property is set and it not !important. This * should only be called when not expanded. Always returns null for * shorthand properties. + * + * The caller must call EnsureMutable first. */ void* SlotForValue(nsCSSProperty aProperty) { NS_PRECONDITION(mData, "How did that happen?"); @@ -147,22 +145,30 @@ public: void* slot = mData->SlotForValue(aProperty); NS_ASSERTION(!slot || !mImportantData || - !mImportantData->SlotForValue(aProperty), + !mImportantData->StorageFor(aProperty), "Property both important and not?"); return slot; } + PRBool HasNonImportantValueFor(nsCSSProperty aProperty) const { + NS_ABORT_IF_FALSE(!nsCSSProps::IsShorthand(aProperty), "must be longhand"); + return !!mData->StorageFor(aProperty); + } + + /** + * Ensures that IsMutable on both data blocks will return true by + * cloning data blocks if needed. Returns false on out-of-memory + * (which means IsMutable won't return true). + */ + PRBool EnsureMutable(); + /** * Clear the data, in preparation for its replacement with entirely * new data by a call to |CompressFrom|. */ void ClearData() { - mData->Destroy(); mData = nsnull; - if (mImportantData) { - mImportantData->Destroy(); - mImportantData = nsnull; - } + mImportantData = nsnull; mOrder.Clear(); } @@ -237,8 +243,12 @@ private: private: nsAutoTArray mOrder; nsAutoRefCnt mRefCnt; - nsCSSCompressedDataBlock *mData; // never null, except while expanded - nsCSSCompressedDataBlock *mImportantData; // may be null + + // never null, except while expanded + nsRefPtr mData; + + // may be null + nsRefPtr mImportantData; }; #endif /* nsCSSDeclaration_h___ */ diff --git a/layout/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp index 64ecb55d8758..eb805226387c 100644 --- a/layout/style/nsCSSParser.cpp +++ b/layout/style/nsCSSParser.cpp @@ -354,7 +354,8 @@ protected: nsCSSSelector& aSelector, PRBool aIsNegated, nsIAtom** aPseudoElement, - nsPseudoClassList** aPseudoElementArgs); + nsPseudoClassList** aPseudoElementArgs, + nsCSSPseudoElements::Type* aPseudoElementType); nsSelectorParsingStatus ParseAttributeSelector(PRInt32& aDataMask, nsCSSSelector& aSelector); @@ -364,17 +365,20 @@ protected: PRBool aIsNegated); nsSelectorParsingStatus ParsePseudoClassWithIdentArg(nsCSSSelector& aSelector, - nsIAtom* aPseudo); + nsIAtom* aPseudo, + nsCSSPseudoClasses::Type aType); nsSelectorParsingStatus ParsePseudoClassWithNthPairArg(nsCSSSelector& aSelector, - nsIAtom* aPseudo); + nsIAtom* aPseudo, + nsCSSPseudoClasses::Type aType); nsSelectorParsingStatus ParseNegatedSimpleSelector(PRInt32& aDataMask, nsCSSSelector& aSelector); nsSelectorParsingStatus ParseSelector(nsCSSSelector& aSelectorResult, nsIAtom** aPseudoElement, - nsPseudoClassList** aPseudoElementArgs); + nsPseudoClassList** aPseudoElementArgs, + nsCSSPseudoElements::Type* aPseudoElementType); // If aTerminateAtBrace is true, the selector list is done when we // hit a '{'. Otherwise, it's done when we hit EOF. @@ -1120,6 +1124,10 @@ CSSParserImpl::ParseProperty(const nsCSSProperty aPropID, // a shorthand, we parse successfully, then we can just directly copy our // parsed value into the declaration without going through the whole // expand/compress thing. + if (!aDeclaration->EnsureMutable()) { + NS_WARNING("out of memory"); + return NS_ERROR_OUT_OF_MEMORY; + } void* valueSlot = aDeclaration->SlotForValue(aPropID); if (!valueSlot) { // Do it the slow way @@ -2497,9 +2505,12 @@ CSSParserImpl::ParseSelectorGroup(nsCSSSelectorList*& aList) } nsCOMPtr pseudoElement; nsAutoPtr pseudoElementArgs; + nsCSSPseudoElements::Type pseudoElementType = + nsCSSPseudoElements::ePseudo_NotPseudoElement; nsSelectorParsingStatus parsingStatus = ParseSelector(*newSelector, getter_AddRefs(pseudoElement), - getter_Transfers(pseudoElementArgs)); + getter_Transfers(pseudoElementArgs), + &pseudoElementType); if (parsingStatus == eSelectorParsingStatus_Empty) { if (!list) { REPORT_UNEXPECTED(PESelectorGroupNoSelector); @@ -2510,6 +2521,12 @@ CSSParserImpl::ParseSelectorGroup(nsCSSSelectorList*& aList) list = nsnull; break; } + if (pseudoElementType == nsCSSPseudoElements::ePseudo_AnonBox && + (list || !IsUniversalSelector(*newSelector))) { + REPORT_UNEXPECTED(PEAnonBoxNotAlone); + list = nsnull; + break; + } if (nsnull == list) { list = new nsCSSSelectorList(); if (nsnull == list) { @@ -2517,16 +2534,16 @@ CSSParserImpl::ParseSelectorGroup(nsCSSSelectorList*& aList) return PR_FALSE; } } + list->AddSelector(newSelector); nsCSSSelector* listSel = list->mSelectors; // We got a pseudo-element (or anonymous box). We actually // represent pseudo-elements as a child of the rest of the selector. if (pseudoElement) { - if (listSel->mNext || !IsUniversalSelector(*listSel)) { + if (pseudoElementType != nsCSSPseudoElements::ePseudo_AnonBox) { // We need to put the pseudo-element on a new selector that's a - // child of the current one. (If it's the only thing in the - // entire selector group, we can just put it on this one.) + // child of the current one. listSel->mOperator = PRUnichar('>'); nsAutoPtr empty(new nsCSSSelector()); if (!empty) { @@ -2544,6 +2561,7 @@ CSSParserImpl::ParseSelectorGroup(nsCSSSelectorList*& aList) "already initialized"); listSel->mLowercaseTag.swap(pseudoElement); listSel->mPseudoClassList = pseudoElementArgs.forget(); + listSel->SetPseudoType(pseudoElementType); havePseudoElement = PR_TRUE; } @@ -2991,7 +3009,8 @@ CSSParserImpl::ParsePseudoSelector(PRInt32& aDataMask, nsCSSSelector& aSelector, PRBool aIsNegated, nsIAtom** aPseudoElement, - nsPseudoClassList** aPseudoElementArgs) + nsPseudoClassList** aPseudoElementArgs, + nsCSSPseudoElements::Type* aPseudoElementType) { NS_ASSERTION(aIsNegated || (aPseudoElement && aPseudoElementArgs), "expected location to store pseudo element"); @@ -3035,8 +3054,10 @@ CSSParserImpl::ParsePseudoSelector(PRInt32& aDataMask, // stash away some info about this pseudo so we only have to get it once. PRBool isTreePseudo = PR_FALSE; + nsCSSPseudoElements::Type pseudoElementType = + nsCSSPseudoElements::GetPseudoType(pseudo); #ifdef MOZ_XUL - isTreePseudo = nsCSSAnonBoxes::IsTreePseudoElement(pseudo); + isTreePseudo = (pseudoElementType == nsCSSPseudoElements::ePseudo_XULTree); // If a tree pseudo-element is using the function syntax, it will // get isTree set here and will pass the check below that only // allows functions if they are in our list of things allowed to be @@ -3046,12 +3067,23 @@ CSSParserImpl::ParsePseudoSelector(PRInt32& aDataMask, // desired. PRBool isTree = (eCSSToken_Function == mToken.mType) && isTreePseudo; #endif - PRBool isPseudoElement = nsCSSPseudoElements::IsPseudoElement(pseudo); + PRBool isPseudoElement = + (pseudoElementType < nsCSSPseudoElements::ePseudo_PseudoElementCount); // anonymous boxes are only allowed if they're the tree boxes or we have // enabled unsafe rules - PRBool isAnonBox = nsCSSAnonBoxes::IsAnonBox(pseudo) && - (mUnsafeRulesEnabled || isTreePseudo); - PRBool isPseudoClass = nsCSSPseudoClasses::IsPseudoClass(pseudo); + PRBool isAnonBox = isTreePseudo || + (pseudoElementType == nsCSSPseudoElements::ePseudo_AnonBox && + mUnsafeRulesEnabled); + nsCSSPseudoClasses::Type pseudoClassType = + nsCSSPseudoClasses::GetPseudoType(pseudo); + PRBool isPseudoClass = + (pseudoClassType != nsCSSPseudoClasses::ePseudoClass_NotPseudoClass); + + NS_ASSERTION(!isPseudoClass || + pseudoElementType == nsCSSPseudoElements::ePseudo_NotPseudoElement, + "Why is this atom both a pseudo-class and a pseudo-element?"); + NS_ASSERTION(isPseudoClass + isPseudoElement + isAnonBox <= 1, + "Shouldn't be more than one of these"); if (!isPseudoClass && !isPseudoElement && !isAnonBox) { // Not a pseudo-class, not a pseudo-element.... forget it @@ -3102,20 +3134,20 @@ CSSParserImpl::ParsePseudoSelector(PRInt32& aDataMask, aDataMask |= SEL_MASK_PCLASS; if (nsCSSPseudoClasses::HasStringArg(pseudo)) { nsSelectorParsingStatus parsingStatus = - ParsePseudoClassWithIdentArg(aSelector, pseudo); + ParsePseudoClassWithIdentArg(aSelector, pseudo, pseudoClassType); if (eSelectorParsingStatus_Continue != parsingStatus) { return parsingStatus; } } else if (nsCSSPseudoClasses::HasNthPairArg(pseudo)) { nsSelectorParsingStatus parsingStatus = - ParsePseudoClassWithNthPairArg(aSelector, pseudo); + ParsePseudoClassWithNthPairArg(aSelector, pseudo, pseudoClassType); if (eSelectorParsingStatus_Continue != parsingStatus) { return parsingStatus; } } else { - aSelector.AddPseudoClass(pseudo); + aSelector.AddPseudoClass(pseudo, pseudoClassType); } } else if (isPseudoElement || isAnonBox) { @@ -3144,6 +3176,7 @@ CSSParserImpl::ParsePseudoSelector(PRInt32& aDataMask, if (0 == (aDataMask & SEL_MASK_PELEM)) { aDataMask |= SEL_MASK_PELEM; NS_ADDREF(*aPseudoElement = pseudo); + *aPseudoElementType = pseudoElementType; #ifdef MOZ_XUL if (isTree) { @@ -3235,7 +3268,7 @@ CSSParserImpl::ParseNegatedSimpleSelector(PRInt32& aDataMask, } else if (mToken.IsSymbol(':')) { // :pseudo parsingStatus = ParsePseudoSelector(aDataMask, *newSel, PR_TRUE, - nsnull, nsnull); + nsnull, nsnull, nsnull); } else if (mToken.IsSymbol('[')) { // [attribute parsingStatus = ParseAttributeSelector(aDataMask, *newSel); @@ -3267,7 +3300,8 @@ CSSParserImpl::ParseNegatedSimpleSelector(PRInt32& aDataMask, // CSSParserImpl::nsSelectorParsingStatus CSSParserImpl::ParsePseudoClassWithIdentArg(nsCSSSelector& aSelector, - nsIAtom* aPseudo) + nsIAtom* aPseudo, + nsCSSPseudoClasses::Type aType) { // Check if we have the first parenthesis if (!ExpectSymbol('(', PR_FALSE)) { @@ -3296,7 +3330,7 @@ CSSParserImpl::ParsePseudoClassWithIdentArg(nsCSSSelector& aSelector, } // Add the pseudo with the language parameter - aSelector.AddPseudoClass(aPseudo, mToken.mIdent.get()); + aSelector.AddPseudoClass(aPseudo, aType, mToken.mIdent.get()); // close the parenthesis if (!ExpectSymbol(')', PR_TRUE)) { @@ -3310,7 +3344,8 @@ CSSParserImpl::ParsePseudoClassWithIdentArg(nsCSSSelector& aSelector, CSSParserImpl::nsSelectorParsingStatus CSSParserImpl::ParsePseudoClassWithNthPairArg(nsCSSSelector& aSelector, - nsIAtom* aPseudo) + nsIAtom* aPseudo, + nsCSSPseudoClasses::Type aType) { PRInt32 numbers[2] = { 0, 0 }; PRBool lookForB = PR_TRUE; @@ -3433,7 +3468,7 @@ CSSParserImpl::ParsePseudoClassWithNthPairArg(nsCSSSelector& aSelector, // XXX Call SkipUntil to the next ")"? return eSelectorParsingStatus_Error; } - aSelector.AddPseudoClass(aPseudo, numbers); + aSelector.AddPseudoClass(aPseudo, aType, numbers); return eSelectorParsingStatus_Continue; } @@ -3445,7 +3480,8 @@ CSSParserImpl::ParsePseudoClassWithNthPairArg(nsCSSSelector& aSelector, CSSParserImpl::nsSelectorParsingStatus CSSParserImpl::ParseSelector(nsCSSSelector& aSelector, nsIAtom** aPseudoElement, - nsPseudoClassList** aPseudoElementArgs) + nsPseudoClassList** aPseudoElementArgs, + nsCSSPseudoElements::Type* aPseudoElementType) { if (! GetToken(PR_TRUE)) { REPORT_UNEXPECTED_EOF(PESelectorEOF); @@ -3468,7 +3504,8 @@ CSSParserImpl::ParseSelector(nsCSSSelector& aSelector, } else if (mToken.IsSymbol(':')) { // :pseudo parsingStatus = ParsePseudoSelector(dataMask, aSelector, PR_FALSE, - aPseudoElement, aPseudoElementArgs); + aPseudoElement, aPseudoElementArgs, + aPseudoElementType); } else if (mToken.IsSymbol('[')) { // [attribute parsingStatus = ParseAttributeSelector(dataMask, aSelector); @@ -3880,7 +3917,8 @@ CSSParserImpl::ParseTreePseudoElement(nsPseudoClassList **aPseudoElementArgs) } if (eCSSToken_Ident == mToken.mType) { nsCOMPtr pseudo = do_GetAtom(mToken.mIdent); - fakeSelector.AddPseudoClass(pseudo); + fakeSelector.AddPseudoClass(pseudo, + nsCSSPseudoClasses::ePseudoClass_NotPseudoClass); } else if (!mToken.IsSymbol(',')) { SkipUntil(')'); diff --git a/layout/style/nsCSSPropList.h b/layout/style/nsCSSPropList.h index 96d155ad0c1d..2534f521a095 100644 --- a/layout/style/nsCSSPropList.h +++ b/layout/style/nsCSSPropList.h @@ -1003,7 +1003,7 @@ CSS_PROP_TABLEBORDER( eCSSType_ValuePair, nsnull, CSS_PROP_NO_OFFSET, - eStyleAnimType_None) // XXX bug 3935 + eStyleAnimType_Custom) // XXX bug 3935 CSS_PROP_SHORTHAND( -moz-border-start, border_start, @@ -1213,8 +1213,8 @@ CSS_PROP_COLUMN( mColumnCount, eCSSType_Value, nsnull, - CSS_PROP_NO_OFFSET, - eStyleAnimType_None) + offsetof(nsStyleColumn, mColumnCount), + eStyleAnimType_Custom) CSS_PROP_COLUMN( -moz-column-width, _moz_column_width, @@ -1274,7 +1274,7 @@ CSS_PROP_COLUMN( eCSSType_Value, kBorderWidthKTable, CSS_PROP_NO_OFFSET, - eStyleAnimType_None) + eStyleAnimType_Custom) CSS_PROP_CONTENT( content, content, @@ -2347,7 +2347,7 @@ CSS_PROP_DISPLAY( eCSSType_ValuePair, kBackgroundPositionKTable, CSS_PROP_NO_OFFSET, - eStyleAnimType_None) + eStyleAnimType_Custom) CSS_PROP_POSITION( top, top, @@ -2612,8 +2612,8 @@ CSS_PROP_XUL( mBoxFlex, eCSSType_Value, nsnull, - CSS_PROP_NO_OFFSET, - eStyleAnimType_None) // XXX bug 3935 + offsetof(nsStyleXUL, mBoxFlex), + eStyleAnimType_float) // XXX bug 3935 CSS_PROP_XUL( -moz-box-orient, box_orient, diff --git a/layout/style/nsCSSPseudoClassList.h b/layout/style/nsCSSPseudoClassList.h index 99a3f2aa7193..ac2c834849b0 100644 --- a/layout/style/nsCSSPseudoClassList.h +++ b/layout/style/nsCSSPseudoClassList.h @@ -42,16 +42,29 @@ * This file contains the list of nsIAtoms and their values for CSS * pseudo-classes. It is designed to be used as inline input to * nsCSSPseudoClasses.cpp *only* through the magic of C preprocessing. - * All entries must be enclosed in the macro CSS_PSEUDO_CLASS which will - * have cruel and unusual things done to it. The entries should be kept - * in some sort of logical order. The first argument to - * CSS_PSEUDO_CLASS is the C++ identifier of the atom. The second - * argument is the string value of the atom. + * All entries must be enclosed in the macros CSS_PSEUDO_CLASS or + * CSS_STATE_PSEUDO_CLASS which will have cruel and unusual things + * done to it. The entries should be kept in some sort of logical + * order. The first argument to CSS_PSEUDO_CLASS is the C++ + * identifier of the atom. The second argument is the string value of + * the atom. CSS_STATE_PSEUDO_CLASS also takes the name of the state + * bit that the class corresponds to. If CSS_STATE_PSEUDO_CLASS is + * not defined, it'll be automatically defined to CSS_PSEUDO_CLASS. */ // OUTPUT_CLASS=nsCSSPseudoClasses // MACRO_NAME=CSS_PSEUDO_CLASS +#ifdef DEFINED_CSS_STATE_PSEUDO_CLASS +#error "This shouldn't be defined" +#endif + +#ifndef CSS_STATE_PSEUDO_CLASS +#define CSS_STATE_PSEUDO_CLASS(_name, _value, _bit) \ + CSS_PSEUDO_CLASS(_name, _value) +#define DEFINED_CSS_STATE_PSEUDO_CLASS +#endif + CSS_PSEUDO_CLASS(empty, ":empty") CSS_PSEUDO_CLASS(mozOnlyWhitespace, ":-moz-only-whitespace") CSS_PSEUDO_CLASS(mozEmptyExceptChildrenWithLocalname, ":-moz-empty-except-children-with-localname") @@ -64,15 +77,16 @@ CSS_PSEUDO_CLASS(link, ":link") CSS_PSEUDO_CLASS(mozAnyLink, ":-moz-any-link") // what matches :link or :visited CSS_PSEUDO_CLASS(visited, ":visited") -CSS_PSEUDO_CLASS(active, ":active") -CSS_PSEUDO_CLASS(checked, ":checked") -CSS_PSEUDO_CLASS(disabled, ":disabled") -CSS_PSEUDO_CLASS(enabled, ":enabled") -CSS_PSEUDO_CLASS(focus, ":focus") -CSS_PSEUDO_CLASS(hover, ":hover") -CSS_PSEUDO_CLASS(mozDragOver, ":-moz-drag-over") -CSS_PSEUDO_CLASS(target, ":target") -CSS_PSEUDO_CLASS(indeterminate, ":indeterminate") +CSS_STATE_PSEUDO_CLASS(active, ":active", NS_EVENT_STATE_ACTIVE) +CSS_STATE_PSEUDO_CLASS(checked, ":checked", NS_EVENT_STATE_CHECKED) +CSS_STATE_PSEUDO_CLASS(disabled, ":disabled", NS_EVENT_STATE_DISABLED) +CSS_STATE_PSEUDO_CLASS(enabled, ":enabled", NS_EVENT_STATE_ENABLED) +CSS_STATE_PSEUDO_CLASS(focus, ":focus", NS_EVENT_STATE_FOCUS) +CSS_STATE_PSEUDO_CLASS(hover, ":hover", NS_EVENT_STATE_HOVER) +CSS_STATE_PSEUDO_CLASS(mozDragOver, ":-moz-drag-over", NS_EVENT_STATE_DRAGOVER) +CSS_STATE_PSEUDO_CLASS(target, ":target", NS_EVENT_STATE_URLTARGET) +CSS_STATE_PSEUDO_CLASS(indeterminate, ":indeterminate", + NS_EVENT_STATE_INDETERMINATE) CSS_PSEUDO_CLASS(firstChild, ":first-child") CSS_PSEUDO_CLASS(firstNode, ":-moz-first-node") @@ -88,13 +102,18 @@ CSS_PSEUDO_CLASS(nthOfType, ":nth-of-type") CSS_PSEUDO_CLASS(nthLastOfType, ":nth-last-of-type") // Image, object, etc state pseudo-classes -CSS_PSEUDO_CLASS(mozBroken, ":-moz-broken") -CSS_PSEUDO_CLASS(mozUserDisabled, ":-moz-user-disabled") -CSS_PSEUDO_CLASS(mozSuppressed, ":-moz-suppressed") -CSS_PSEUDO_CLASS(mozLoading, ":-moz-loading") -CSS_PSEUDO_CLASS(mozTypeUnsupported, ":-moz-type-unsupported") -CSS_PSEUDO_CLASS(mozHandlerDisabled, ":-moz-handler-disabled") -CSS_PSEUDO_CLASS(mozHandlerBlocked, ":-moz-handler-blocked") +CSS_STATE_PSEUDO_CLASS(mozBroken, ":-moz-broken", NS_EVENT_STATE_BROKEN) +CSS_STATE_PSEUDO_CLASS(mozUserDisabled, ":-moz-user-disabled", + NS_EVENT_STATE_USERDISABLED) +CSS_STATE_PSEUDO_CLASS(mozSuppressed, ":-moz-suppressed", + NS_EVENT_STATE_SUPPRESSED) +CSS_STATE_PSEUDO_CLASS(mozLoading, ":-moz-loading", NS_EVENT_STATE_LOADING) +CSS_STATE_PSEUDO_CLASS(mozTypeUnsupported, ":-moz-type-unsupported", + NS_EVENT_STATE_TYPE_UNSUPPORTED) +CSS_STATE_PSEUDO_CLASS(mozHandlerDisabled, ":-moz-handler-disabled", + NS_EVENT_STATE_HANDLER_DISABLED) +CSS_STATE_PSEUDO_CLASS(mozHandlerBlocked, ":-moz-handler-blocked", + NS_EVENT_STATE_HANDLER_BLOCKED) CSS_PSEUDO_CLASS(mozHasHandlerRef, ":-moz-has-handlerref") @@ -118,17 +137,26 @@ CSS_PSEUDO_CLASS(mozLWThemeBrightText, ":-moz-lwtheme-brighttext") CSS_PSEUDO_CLASS(mozLWThemeDarkText, ":-moz-lwtheme-darktext") #ifdef MOZ_MATHML -CSS_PSEUDO_CLASS(mozMathIncrementScriptLevel, ":-moz-math-increment-script-level") +CSS_STATE_PSEUDO_CLASS(mozMathIncrementScriptLevel, + ":-moz-math-increment-script-level", + NS_EVENT_STATE_INCREMENT_SCRIPT_LEVEL) #endif // CSS 3 UI // http://www.w3.org/TR/2004/CR-css3-ui-20040511/#pseudo-classes -CSS_PSEUDO_CLASS(required, ":required") -CSS_PSEUDO_CLASS(optional, ":optional") -CSS_PSEUDO_CLASS(valid, ":valid") -CSS_PSEUDO_CLASS(invalid, ":invalid") -CSS_PSEUDO_CLASS(inRange, ":in-range") -CSS_PSEUDO_CLASS(outOfRange, ":out-of-range") -CSS_PSEUDO_CLASS(defaultPseudo, ":default") -CSS_PSEUDO_CLASS(mozReadOnly, ":-moz-read-only") -CSS_PSEUDO_CLASS(mozReadWrite, ":-moz-read-write") +CSS_STATE_PSEUDO_CLASS(required, ":required", NS_EVENT_STATE_REQUIRED) +CSS_STATE_PSEUDO_CLASS(optional, ":optional", NS_EVENT_STATE_OPTIONAL) +CSS_STATE_PSEUDO_CLASS(valid, ":valid", NS_EVENT_STATE_VALID) +CSS_STATE_PSEUDO_CLASS(invalid, ":invalid", NS_EVENT_STATE_INVALID) +CSS_STATE_PSEUDO_CLASS(inRange, ":in-range", NS_EVENT_STATE_INRANGE) +CSS_STATE_PSEUDO_CLASS(outOfRange, ":out-of-range", NS_EVENT_STATE_OUTOFRANGE) +CSS_STATE_PSEUDO_CLASS(defaultPseudo, ":default", NS_EVENT_STATE_DEFAULT) +CSS_STATE_PSEUDO_CLASS(mozReadOnly, ":-moz-read-only", + NS_EVENT_STATE_MOZ_READONLY) +CSS_STATE_PSEUDO_CLASS(mozReadWrite, ":-moz-read-write", + NS_EVENT_STATE_MOZ_READWRITE) + +#ifdef DEFINED_CSS_STATE_PSEUDO_CLASS +#undef DEFINED_CSS_STATE_PSEUDO_CLASS +#undef CSS_STATE_PSEUDO_CLASS +#endif diff --git a/layout/style/nsCSSPseudoClasses.cpp b/layout/style/nsCSSPseudoClasses.cpp index a37e17f1585f..d3fef1baf6ee 100644 --- a/layout/style/nsCSSPseudoClasses.cpp +++ b/layout/style/nsCSSPseudoClasses.cpp @@ -85,3 +85,15 @@ nsCSSPseudoClasses::HasNthPairArg(nsIAtom* aAtom) aAtom == nsCSSPseudoClasses::nthOfType || aAtom == nsCSSPseudoClasses::nthLastOfType; } + +nsCSSPseudoClasses::Type +nsCSSPseudoClasses::GetPseudoType(nsIAtom* aAtom) +{ + for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(CSSPseudoClasses_info); ++i) { + if (*CSSPseudoClasses_info[i].mAtom == aAtom) { + return Type(i); + } + } + + return nsCSSPseudoClasses::ePseudoClass_NotPseudoClass; +} diff --git a/layout/style/nsCSSPseudoClasses.h b/layout/style/nsCSSPseudoClasses.h index 96c87c2278b3..b2e13eed230c 100644 --- a/layout/style/nsCSSPseudoClasses.h +++ b/layout/style/nsCSSPseudoClasses.h @@ -59,6 +59,18 @@ public: #define CSS_PSEUDO_CLASS(_name, _value) static nsICSSPseudoClass* _name; #include "nsCSSPseudoClassList.h" #undef CSS_PSEUDO_CLASS + + enum Type { +#define CSS_PSEUDO_CLASS(_name, _value) \ + ePseudoClass_##_name, +#include "nsCSSPseudoClassList.h" +#undef CSS_PSEUDO_CLASS + ePseudoClass_Count, + ePseudoClass_NotPseudoClass /* This value MUST be last! SelectorMatches + depends on it. */ + }; + + static Type GetPseudoType(nsIAtom* aAtom); }; #endif /* nsCSSPseudoClasses_h___ */ diff --git a/layout/style/nsCSSPseudoElementList.h b/layout/style/nsCSSPseudoElementList.h index d1af745e44c1..14507e572a69 100644 --- a/layout/style/nsCSSPseudoElementList.h +++ b/layout/style/nsCSSPseudoElementList.h @@ -71,11 +71,18 @@ CSS_PSEUDO_ELEMENT(firstLine, ":first-line", CSS_PSEUDO_ELEMENT(mozSelection, ":-moz-selection", CSS_PSEUDO_ELEMENT_CONTAINS_ELEMENTS) +// XXXbz should we really allow random content to style these? Maybe +// use our flags to prevent that? CSS_PSEUDO_ELEMENT(mozFocusInner, ":-moz-focus-inner", 0) CSS_PSEUDO_ELEMENT(mozFocusOuter, ":-moz-focus-outer", 0) +// XXXbz should we really allow random content to style these? Maybe +// use our flags to prevent that? CSS_PSEUDO_ELEMENT(mozListBullet, ":-moz-list-bullet", 0) CSS_PSEUDO_ELEMENT(mozListNumber, ":-moz-list-number", 0) -CSS_PSEUDO_ELEMENT(horizontalFramesetBorder, ":-moz-hframeset-border", 0) -CSS_PSEUDO_ELEMENT(verticalFramesetBorder, ":-moz-vframeset-border", 0) +#ifdef MOZ_MATHML +CSS_PSEUDO_ELEMENT(mozMathStretchy, ":-moz-math-stretchy", 0) +CSS_PSEUDO_ELEMENT(mozMathAnonymous, ":-moz-math-anonymous", 0) +#endif + diff --git a/layout/style/nsCSSPseudoElements.cpp b/layout/style/nsCSSPseudoElements.cpp index 9462b6e41921..e825b3b98eb2 100644 --- a/layout/style/nsCSSPseudoElements.cpp +++ b/layout/style/nsCSSPseudoElements.cpp @@ -100,6 +100,36 @@ nsCSSPseudoElements::IsCSS2PseudoElement(nsIAtom *aAtom) return result; } +/* static */ nsCSSPseudoElements::Type +nsCSSPseudoElements::GetPseudoType(nsIAtom *aAtom) +{ + for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(CSSPseudoElements_info); ++i) { + if (*CSSPseudoElements_info[i].mAtom == aAtom) { + return Type(i); + } + } + + if (nsCSSAnonBoxes::IsAnonBox(aAtom)) { +#ifdef MOZ_XUL + if (nsCSSAnonBoxes::IsTreePseudoElement(aAtom)) { + return ePseudo_XULTree; + } +#endif + + return ePseudo_AnonBox; + } + + return ePseudo_NotPseudoElement; +} + +/* static */ nsIAtom* +nsCSSPseudoElements::GetPseudoAtom(Type aType) +{ + NS_ASSERTION(aType < nsCSSPseudoElements::ePseudo_PseudoElementCount, + "Unexpected type"); + return *CSSPseudoElements_info[aType].mAtom; +} + /* static */ PRUint32 nsCSSPseudoElements::FlagsForPseudoElement(nsIAtom *aAtom) { diff --git a/layout/style/nsCSSPseudoElements.h b/layout/style/nsCSSPseudoElements.h index 7133af735888..895e891ac856 100644 --- a/layout/style/nsCSSPseudoElements.h +++ b/layout/style/nsCSSPseudoElements.h @@ -79,6 +79,27 @@ public: #include "nsCSSPseudoElementList.h" #undef CSS_PSEUDO_ELEMENT + enum Type { + // If the actual pseudo-elements stop being first here, change + // GetPseudoType. +#define CSS_PSEUDO_ELEMENT(_name, _value_, _flags) \ + ePseudo_##_name, +#include "nsCSSPseudoElementList.h" +#undef CSS_PSEUDO_ELEMENT + ePseudo_PseudoElementCount, + ePseudo_AnonBox = ePseudo_PseudoElementCount, +#ifdef MOZ_XUL + ePseudo_XULTree, +#endif + ePseudo_NotPseudoElement, + ePseudo_MAX + }; + + static Type GetPseudoType(nsIAtom* aAtom); + + // Get the atom for a given Type. aType must be < ePseudo_PseudoElementCount + static nsIAtom* GetPseudoAtom(Type aType); + private: static PRUint32 FlagsForPseudoElement(nsIAtom *aAtom); diff --git a/layout/style/nsCSSRuleProcessor.cpp b/layout/style/nsCSSRuleProcessor.cpp index 9ce4711cb8a0..588b0578fca9 100644 --- a/layout/style/nsCSSRuleProcessor.cpp +++ b/layout/style/nsCSSRuleProcessor.cpp @@ -69,6 +69,7 @@ #include "nsDOMError.h" #include "nsRuleWalker.h" #include "nsCSSPseudoClasses.h" +#include "nsCSSPseudoElements.h" #include "nsIContent.h" #include "nsCOMPtr.h" #include "nsHashKeys.h" @@ -85,6 +86,7 @@ #include "nsCSSRules.h" #include "nsIPrincipal.h" #include "nsStyleSet.h" +#include "prlog.h" #define VISITED_PSEUDO_PREF "layout.css.visited_links_enabled" @@ -363,15 +365,13 @@ public: void PrependRule(RuleValue *aRuleInfo); void EnumerateAllRules(PRInt32 aNameSpace, nsIAtom* aTag, nsIAtom* aID, const nsAttrValue* aClassList, - RuleEnumFunc aFunc, void* aData); - void EnumerateTagRules(nsIAtom* aTag, - RuleEnumFunc aFunc, void* aData); + RuleEnumFunc aFunc, RuleProcessorData* aData); PLArenaPool& Arena() { return mArena; } protected: void PrependRuleToTable(PLDHashTable* aTable, const void* aKey, RuleValue* aRuleInfo); - void PrependRuleToTagTable(const void* aKey, RuleValue* aRuleInfo); + void PrependRuleToTagTable(nsIAtom* aKey, RuleValue* aRuleInfo); void PrependUniversalRule(RuleValue* aRuleInfo); // All rule values in these hashtables are arena allocated @@ -395,15 +395,12 @@ protected: PRUint32 mIdSelectors; PRUint32 mElementsMatched; - PRUint32 mPseudosMatched; PRUint32 mElementUniversalCalls; PRUint32 mElementNameSpaceCalls; PRUint32 mElementTagCalls; PRUint32 mElementClassCalls; PRUint32 mElementIdCalls; - - PRUint32 mPseudoTagCalls; #endif // RULE_HASH_STATS }; @@ -419,15 +416,14 @@ RuleHash::RuleHash(PRBool aQuirksMode) mClassSelectors(0), mIdSelectors(0), mElementsMatched(0), - mPseudosMatched(0), mElementUniversalCalls(0), mElementNameSpaceCalls(0), mElementTagCalls(0), mElementClassCalls(0), - mElementIdCalls(0), - mPseudoTagCalls(0) + mElementIdCalls(0) #endif { + MOZ_COUNT_CTOR(RuleHash); // Initialize our arena PL_INIT_ARENA_POOL(&mArena, "RuleHashArena", NS_RULEHASH_ARENA_BLOCK_SIZE); @@ -447,21 +443,19 @@ RuleHash::RuleHash(PRBool aQuirksMode) RuleHash::~RuleHash() { + MOZ_COUNT_DTOR(RuleHash); #ifdef RULE_HASH_STATS printf( "RuleHash(%p):\n" " Selectors: Universal (%u) NameSpace(%u) Tag(%u) Class(%u) Id(%u)\n" -" Content Nodes: Elements(%u) Pseudo-Elements(%u)\n" +" Content Nodes: Elements(%u)\n" " Element Calls: Universal(%u) NameSpace(%u) Tag(%u) Class(%u) Id(%u)\n" -" Pseudo-Element Calls: Tag(%u)\n", static_cast(this), mUniversalSelectors, mNameSpaceSelectors, mTagSelectors, mClassSelectors, mIdSelectors, mElementsMatched, - mPseudosMatched, mElementUniversalCalls, mElementNameSpaceCalls, mElementTagCalls, - mElementClassCalls, mElementIdCalls, - mPseudoTagCalls); + mElementClassCalls, mElementIdCalls); #ifdef PRINT_UNIVERSAL_RULES { RuleValue* value = mUniversalRules; @@ -508,19 +502,26 @@ void RuleHash::PrependRuleToTable(PLDHashTable* aTable, const void* aKey, entry->mRules = aRuleInfo->Add(mRuleCount++, entry->mRules); } -void RuleHash::PrependRuleToTagTable(const void* aKey, RuleValue* aRuleInfo) +static void +DoPrependRuleToTagTable(PLDHashTable* aTable, nsIAtom* aKey, + RuleValue* aRuleInfo, PRInt32 aBackwardsIndex) { // Get a new or exisiting entry - RuleHashTagTableEntry *entry = static_cast - (PL_DHashTableOperate(&mTagTable, aKey, PL_DHASH_ADD)); - if (!entry) - return; + RuleHashTagTableEntry *entry = static_cast + (PL_DHashTableOperate(aTable, aKey, PL_DHASH_ADD)); + if (!entry) + return; - entry->mTag = const_cast(static_cast(aKey)); + entry->mTag = aKey; - // This may give the same rule two different rule counts, but that is OK - // because we never combine two different entries in the tag table. - entry->mRules = aRuleInfo->Add(mRuleCount++, entry->mRules); + // This may give the same rule two different rule counts, but that is OK + // because we never combine two different entries in a tag table. + entry->mRules = aRuleInfo->Add(aBackwardsIndex, entry->mRules); +} + +void RuleHash::PrependRuleToTagTable(nsIAtom* aKey, RuleValue* aRuleInfo) +{ + DoPrependRuleToTagTable(&mTagTable, aKey, aRuleInfo, mRuleCount++); } void RuleHash::PrependUniversalRule(RuleValue *aRuleInfo) @@ -574,7 +575,7 @@ void RuleHash::PrependRule(RuleValue *aRuleInfo) void RuleHash::EnumerateAllRules(PRInt32 aNameSpace, nsIAtom* aTag, nsIAtom* aID, const nsAttrValue* aClassList, - RuleEnumFunc aFunc, void* aData) + RuleEnumFunc aFunc, RuleProcessorData* aData) { PRInt32 classCount = aClassList ? aClassList->GetAtomCount() : 0; @@ -599,7 +600,7 @@ void RuleHash::EnumerateAllRules(PRInt32 aNameSpace, nsIAtom* aTag, } } // universal rules within the namespace - if (kNameSpaceID_Unknown != aNameSpace) { + if (kNameSpaceID_Unknown != aNameSpace && mNameSpaceTable.entryCount) { RuleHashTableEntry *entry = static_cast (PL_DHashTableOperate(&mNameSpaceTable, NS_INT32_TO_PTR(aNameSpace), PL_DHASH_LOOKUP)); @@ -609,7 +610,7 @@ void RuleHash::EnumerateAllRules(PRInt32 aNameSpace, nsIAtom* aTag, RULE_HASH_STAT_INCREMENT_LIST_COUNT(value, mElementNameSpaceCalls); } } - if (nsnull != aTag) { + if (aTag && mTagTable.entryCount) { RuleHashTableEntry *entry = static_cast (PL_DHashTableOperate(&mTagTable, aTag, PL_DHASH_LOOKUP)); if (PL_DHASH_ENTRY_IS_BUSY(entry)) { @@ -618,7 +619,7 @@ void RuleHash::EnumerateAllRules(PRInt32 aNameSpace, nsIAtom* aTag, RULE_HASH_STAT_INCREMENT_LIST_COUNT(value, mElementTagCalls); } } - if (nsnull != aID) { + if (aID && mIdTable.entryCount) { RuleHashTableEntry *entry = static_cast (PL_DHashTableOperate(&mIdTable, aID, PL_DHASH_LOOKUP)); if (PL_DHASH_ENTRY_IS_BUSY(entry)) { @@ -627,7 +628,7 @@ void RuleHash::EnumerateAllRules(PRInt32 aNameSpace, nsIAtom* aTag, RULE_HASH_STAT_INCREMENT_LIST_COUNT(value, mElementIdCalls); } } - { // extra scope to work around compiler bugs with |for| scoping. + if (mClassTable.entryCount) { for (PRInt32 index = 0; index < classCount; ++index) { RuleHashTableEntry *entry = static_cast (PL_DHashTableOperate(&mClassTable, aClassList->AtomAt(index), @@ -668,22 +669,6 @@ void RuleHash::EnumerateAllRules(PRInt32 aNameSpace, nsIAtom* aTag, } } -void RuleHash::EnumerateTagRules(nsIAtom* aTag, RuleEnumFunc aFunc, void* aData) -{ - RuleHashTableEntry *entry = static_cast - (PL_DHashTableOperate(&mTagTable, aTag, PL_DHASH_LOOKUP)); - - RULE_HASH_STAT_INCREMENT(mPseudosMatched); - if (PL_DHASH_ENTRY_IS_BUSY(entry)) { - RuleValue *tagValue = entry->mRules; - do { - RULE_HASH_STAT_INCREMENT(mPseudoTagCalls); - (*aFunc)(tagValue->mRule, tagValue->mSelector, aData); - tagValue = tagValue->mNext; - } while (tagValue); - } -} - //-------------------------------- // Attribute selectors hash table. @@ -719,21 +704,40 @@ struct RuleCascadeData { : mRuleHash(aQuirksMode), mStateSelectors(), mCacheKey(aMedium), - mNext(nsnull) + mNext(nsnull), + mQuirksMode(aQuirksMode) { PL_DHashTableInit(&mAttributeSelectors, &AttributeSelectorOps, nsnull, sizeof(AttributeSelectorEntry), 16); + PL_DHashTableInit(&mAnonBoxRules, &RuleHash_TagTable_Ops, nsnull, + sizeof(RuleHashTagTableEntry), 16); + memset(mPseudoElementRuleHashes, 0, sizeof(mPseudoElementRuleHashes)); +#ifdef MOZ_XUL + PL_DHashTableInit(&mXULTreeRules, &RuleHash_TagTable_Ops, nsnull, + sizeof(RuleHashTagTableEntry), 16); +#endif } ~RuleCascadeData() { PL_DHashTableFinish(&mAttributeSelectors); + PL_DHashTableFinish(&mAnonBoxRules); + PL_DHashTableFinish(&mXULTreeRules); + for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(mPseudoElementRuleHashes); ++i) { + delete mPseudoElementRuleHashes[i]; + } } RuleHash mRuleHash; + RuleHash* + mPseudoElementRuleHashes[nsCSSPseudoElements::ePseudo_PseudoElementCount]; nsTArray mStateSelectors; nsTArray mClassSelectors; nsTArray mIDSelectors; PLDHashTable mAttributeSelectors; + PLDHashTable mAnonBoxRules; +#ifdef MOZ_XUL + PLDHashTable mXULTreeRules; +#endif nsTArray mFontFaceRules; @@ -743,6 +747,8 @@ struct RuleCascadeData { nsMediaQueryResultCacheKey mCacheKey; RuleCascadeData* mNext; // for a different medium + + const PRBool mQuirksMode; }; nsTArray* @@ -897,30 +903,21 @@ RuleProcessorData::RuleProcessorData(nsPresContext* aPresContext, nsIContent* aContent, nsRuleWalker* aRuleWalker, nsCompatibility* aCompat /*= nsnull*/) + : mPresContext(aPresContext), + mContent(aContent), + mRuleWalker(aRuleWalker), + mScopedRoot(nsnull), + mPreviousSiblingData(nsnull), + mParentData(nsnull), + mLanguage(nsnull), + mGotContentState(PR_FALSE), + mGotLinkInfo(PR_FALSE) { MOZ_COUNT_CTOR(RuleProcessorData); - NS_ASSERTION(!aContent || aContent->IsNodeOfType(nsINode::eELEMENT), + NS_ASSERTION(aContent && aContent->IsNodeOfType(nsINode::eELEMENT), "non-element leaked into SelectorMatches"); - mPresContext = aPresContext; - mContent = aContent; - mParentContent = nsnull; - mRuleWalker = aRuleWalker; - mScopedRoot = nsnull; - - mContentTag = nsnull; - mContentID = nsnull; - mHasAttributes = PR_FALSE; - mIsHTMLContent = PR_FALSE; - mIsLink = PR_FALSE; - mLinkState = eLinkState_Unknown; - mEventState = 0; - mNameSpaceID = kNameSpaceID_Unknown; - mPreviousSiblingData = nsnull; - mParentData = nsnull; - mLanguage = nsnull; - mClasses = nsnull; mNthIndices[0][0] = -2; mNthIndices[0][1] = -2; mNthIndices[1][0] = -2; @@ -938,57 +935,35 @@ RuleProcessorData::RuleProcessorData(nsPresContext* aPresContext, mCompatMode = aContent->GetOwnerDoc()->GetCompatibilityMode(); } - if (aContent) { - NS_ASSERTION(aContent->GetOwnerDoc(), "Document-less node here?"); + NS_ASSERTION(aContent->GetOwnerDoc(), "Document-less node here?"); - // get the tag and parent - mContentTag = aContent->Tag(); - mParentContent = aContent->GetParent(); - - // get the event state - if (mPresContext) { - mPresContext->EventStateManager()->GetContentState(aContent, mEventState); - } else { - mEventState = aContent->IntrinsicState(); - } + // get the tag and parent + mContentTag = aContent->Tag(); + mParentContent = aContent->GetParent(); + // see if there are attributes for the content + mHasAttributes = aContent->GetAttrCount() > 0; + if (mHasAttributes) { // get the ID and classes for the content mContentID = aContent->GetID(); mClasses = aContent->GetClasses(); - - // see if there are attributes for the content - mHasAttributes = aContent->GetAttrCount() > 0; - - // get the namespace - mNameSpaceID = aContent->GetNameSpaceID(); - - // check for HTMLContent and Link status - mIsHTMLContent = (mNameSpaceID == kNameSpaceID_XHTML); - - // if HTML content and it has some attributes, check for an HTML link - // NOTE: optimization: cannot be a link if no attributes (since it needs an href) - nsILinkHandler* linkHandler = - mPresContext ? mPresContext->GetLinkHandler() : nsnull; - if (mIsHTMLContent && mHasAttributes) { - // check if it is an HTML Link - if(nsStyleUtil::IsHTMLLink(aContent, linkHandler, &mLinkState)) { - mIsLink = PR_TRUE; - } - } - - // if not an HTML link, check for a simple xlink (cannot be both HTML link and xlink) - // NOTE: optimization: cannot be an XLink if no attributes (since it needs an - if(!mIsLink && - mHasAttributes && - !(mIsHTMLContent || aContent->IsXUL()) && - nsStyleUtil::IsLink(aContent, linkHandler, &mLinkState)) { - mIsLink = PR_TRUE; - } + } else { + mContentID = nsnull; + mClasses = nsnull; } - if (mLinkState == eLinkState_Visited && !gSupportVisitedPseudo) { - mLinkState = eLinkState_Unvisited; - } + // get the namespace + mNameSpaceID = aContent->GetNameSpaceID(); + + // check for HTMLContent status + mIsHTMLContent = (mNameSpaceID == kNameSpaceID_XHTML); + mIsHTML = mIsHTMLContent && aContent->IsInHTMLDocument(); + + // No need to initialize mIsLink or mLinkState; the IsLink() accessor will + // handle that. + + // No need to initialize mContentState; the ContentState() accessor will handle + // that. } RuleProcessorData::~RuleProcessorData() @@ -1051,6 +1026,58 @@ const nsString* RuleProcessorData::GetLang() return mLanguage; } +PRUint32 +RuleProcessorData::ContentState() +{ + if (!mGotContentState) { + mGotContentState = PR_TRUE; + mContentState = 0; + if (mPresContext) { + mPresContext->EventStateManager()->GetContentState(mContent, + mContentState); + } else { + mContentState = mContent->IntrinsicState(); + } + } + return mContentState; +} + +PRBool +RuleProcessorData::IsLink() +{ + if (!mGotLinkInfo) { + mGotLinkInfo = PR_TRUE; + mLinkState = eLinkState_Unknown; + mIsLink = PR_FALSE; + // if HTML content and it has some attributes, check for an HTML link + // NOTE: optimization: cannot be a link if no attributes (since it needs + // an href) + nsILinkHandler* linkHandler = + mPresContext ? mPresContext->GetLinkHandler() : nsnull; + if (mIsHTMLContent && mHasAttributes) { + // check if it is an HTML Link + if (nsStyleUtil::IsHTMLLink(mContent, linkHandler, &mLinkState)) { + mIsLink = PR_TRUE; + } + } + + // if not an HTML link, check for a simple xlink (cannot be both HTML + // link and xlink) NOTE: optimization: cannot be an XLink if no + // attributes (since it needs an href) + if(!mIsLink && + mHasAttributes && + !(mIsHTMLContent || mContent->IsXUL()) && + nsStyleUtil::IsLink(mContent, linkHandler, &mLinkState)) { + mIsLink = PR_TRUE; + } + + if (mLinkState == eLinkState_Visited && !gSupportVisitedPseudo) { + mLinkState = eLinkState_Unvisited; + } + } + return mIsLink; +} + PRInt32 RuleProcessorData::GetNthIndex(PRBool aIsOfType, PRBool aIsFromEnd, PRBool aCheckEdgeOnly) @@ -1157,16 +1184,9 @@ static PRBool ValueIncludes(const nsSubstring& aValueList, return PR_FALSE; } -inline PRBool IsLinkPseudo(nsIAtom* aAtom) -{ - return PRBool ((nsCSSPseudoClasses::link == aAtom) || - (nsCSSPseudoClasses::visited == aAtom) || - (nsCSSPseudoClasses::mozAnyLink == aAtom)); -} - // Return whether we should apply a "global" (i.e., universal-tag) // selector for event states in quirks mode. Note that -// |data.mIsLink| is checked separately by the caller, so we return +// |data.IsLink()| is checked separately by the caller, so we return // false for |nsGkAtoms::a|, which here means a named anchor. inline PRBool IsQuirkEventSensitive(nsIAtom *aContentTag) { @@ -1231,13 +1251,521 @@ static PRBool AttrMatchesValue(const nsAttrSelector* aAttrSelector, } } -// NOTE: For |aStateMask| and |aAttribute| to work correctly, it's -// important that any change that changes multiple state bits and -// maybe an attribute include all those state bits and the attribute -// in the notification. Otherwise, if multiple states change but we -// do separate notifications then we might determine the style is not -// state-dependent when it really is (e.g., determining that a -// :hover:active rule no longer matches when both states are unset). +static PRBool NS_FASTCALL +firstNodeMatches(RuleProcessorData& data, PRBool setNodeFlags, + nsPseudoClassList* pseudoClass) +{ + NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::firstNode, + "Unexpected atom"); + nsIContent *firstNode = nsnull; + nsIContent *parent = data.mParentContent; + if (parent) { + if (setNodeFlags) + parent->SetFlags(NODE_HAS_EDGE_CHILD_SELECTOR); + + PRInt32 index = -1; + do { + firstNode = parent->GetChildAt(++index); + // stop at first non-comment and non-whitespace node + } while (firstNode && + !IsSignificantChild(firstNode, PR_TRUE, PR_FALSE)); + } + return (data.mContent == firstNode); +} + +static PRBool NS_FASTCALL +lastNodeMatches(RuleProcessorData& data, PRBool setNodeFlags, + nsPseudoClassList* pseudoClass) +{ + NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::lastNode, + "Unexpected atom"); + nsIContent *lastNode = nsnull; + nsIContent *parent = data.mParentContent; + if (parent) { + if (setNodeFlags) + parent->SetFlags(NODE_HAS_EDGE_CHILD_SELECTOR); + + PRUint32 index = parent->GetChildCount(); + do { + lastNode = parent->GetChildAt(--index); + // stop at first non-comment and non-whitespace node + } while (lastNode && + !IsSignificantChild(lastNode, PR_TRUE, PR_FALSE)); + } + return (data.mContent == lastNode); +} + +static inline PRBool +edgeChildMatches(RuleProcessorData& data, PRBool setNodeFlags, + PRBool checkFirst, PRBool checkLast) +{ + nsIContent *parent = data.mParentContent; + if (!parent) { + return PR_FALSE; + } + + if (setNodeFlags) + parent->SetFlags(NODE_HAS_EDGE_CHILD_SELECTOR); + + return (!checkFirst || + data.GetNthIndex(PR_FALSE, PR_FALSE, PR_TRUE) == 1) && + (!checkLast || + data.GetNthIndex(PR_FALSE, PR_TRUE, PR_TRUE) == 1); +} + +static PRBool NS_FASTCALL +firstChildMatches(RuleProcessorData& data, PRBool setNodeFlags, + nsPseudoClassList* pseudoClass) +{ + NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::firstChild, + "Unexpected atom"); + return edgeChildMatches(data, setNodeFlags, PR_TRUE, PR_FALSE); +} + +static PRBool NS_FASTCALL +lastChildMatches(RuleProcessorData& data, PRBool setNodeFlags, + nsPseudoClassList* pseudoClass) +{ + NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::lastChild, + "Unexpected atom"); + return edgeChildMatches(data, setNodeFlags, PR_FALSE, PR_TRUE); +} + +static PRBool NS_FASTCALL +onlyChildMatches(RuleProcessorData& data, PRBool setNodeFlags, + nsPseudoClassList* pseudoClass) +{ + NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::onlyChild, + "Unexpected atom"); + return edgeChildMatches(data, setNodeFlags, PR_TRUE, PR_TRUE); +} + +static inline PRBool +nthChildGenericMatches(RuleProcessorData& data, PRBool setNodeFlags, + nsPseudoClassList* pseudoClass, + PRBool isOfType, PRBool isFromEnd) +{ + nsIContent *parent = data.mParentContent; + if (!parent) { + return PR_FALSE; + } + + if (setNodeFlags) { + if (isFromEnd) + parent->SetFlags(NODE_HAS_SLOW_SELECTOR); + else + parent->SetFlags(NODE_HAS_SLOW_SELECTOR_NOAPPEND); + } + + const PRInt32 index = data.GetNthIndex(isOfType, isFromEnd, PR_FALSE); + if (index <= 0) { + // Node is anonymous content (not really a child of its parent). + return PR_FALSE; + } + + const PRInt32 a = pseudoClass->u.mNumbers[0]; + const PRInt32 b = pseudoClass->u.mNumbers[1]; + // result should be true if there exists n >= 0 such that + // a * n + b == index. + if (a == 0) { + return b == index; + } + + // Integer division in C does truncation (towards 0). So + // check that the result is nonnegative, and that there was no + // truncation. + const PRInt32 n = (index - b) / a; + return n >= 0 && (a * n == index - b); +} + +static PRBool NS_FASTCALL +nthChildMatches(RuleProcessorData& data, PRBool setNodeFlags, + nsPseudoClassList* pseudoClass) +{ + NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::nthChild, + "Unexpected atom"); + return nthChildGenericMatches(data, setNodeFlags, pseudoClass, + PR_FALSE, PR_FALSE); +} + +static PRBool NS_FASTCALL +nthLastChildMatches(RuleProcessorData& data, PRBool setNodeFlags, + nsPseudoClassList* pseudoClass) +{ + NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::nthLastChild, + "Unexpected atom"); + return nthChildGenericMatches(data, setNodeFlags, pseudoClass, + PR_FALSE, PR_TRUE); +} + +static PRBool NS_FASTCALL +nthOfTypeMatches(RuleProcessorData& data, PRBool setNodeFlags, + nsPseudoClassList* pseudoClass) +{ + NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::nthOfType, + "Unexpected atom"); + return nthChildGenericMatches(data, setNodeFlags, pseudoClass, + PR_TRUE, PR_FALSE); +} + +static PRBool NS_FASTCALL +nthLastOfTypeMatches(RuleProcessorData& data, PRBool setNodeFlags, + nsPseudoClassList* pseudoClass) +{ + NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::nthLastOfType, + "Unexpected atom"); + return nthChildGenericMatches(data, setNodeFlags, pseudoClass, + PR_TRUE, PR_TRUE); +} + +static inline PRBool +edgeOfTypeMatches(RuleProcessorData& data, PRBool setNodeFlags, + PRBool checkFirst, PRBool checkLast) +{ + nsIContent *parent = data.mParentContent; + if (!parent) { + return PR_FALSE; + } + + if (setNodeFlags) { + if (checkLast) + parent->SetFlags(NODE_HAS_SLOW_SELECTOR); + else + parent->SetFlags(NODE_HAS_SLOW_SELECTOR_NOAPPEND); + } + + return (!checkFirst || + data.GetNthIndex(PR_TRUE, PR_FALSE, PR_TRUE) == 1) && + (!checkLast || + data.GetNthIndex(PR_TRUE, PR_TRUE, PR_TRUE) == 1); +} + +static PRBool NS_FASTCALL +firstOfTypeMatches(RuleProcessorData& data, PRBool setNodeFlags, + nsPseudoClassList* pseudoClass) +{ + NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::firstOfType, + "Unexpected atom"); + return edgeOfTypeMatches(data, setNodeFlags, PR_TRUE, PR_FALSE); +} + +static PRBool NS_FASTCALL +lastOfTypeMatches(RuleProcessorData& data, PRBool setNodeFlags, + nsPseudoClassList* pseudoClass) +{ + NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::lastOfType, + "Unexpected atom"); + return edgeOfTypeMatches(data, setNodeFlags, PR_FALSE, PR_TRUE); +} + +static PRBool NS_FASTCALL +onlyOfTypeMatches(RuleProcessorData& data, PRBool setNodeFlags, + nsPseudoClassList* pseudoClass) +{ + NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::onlyOfType, + "Unexpected atom"); + return edgeOfTypeMatches(data, setNodeFlags, PR_TRUE, PR_TRUE); +} + +static inline PRBool +checkGenericEmptyMatches(RuleProcessorData& data, PRBool setNodeFlags, + PRBool isWhitespaceSignificant) +{ + nsIContent *child = nsnull; + nsIContent *element = data.mContent; + PRInt32 index = -1; + + if (setNodeFlags) + element->SetFlags(NODE_HAS_EMPTY_SELECTOR); + + do { + child = element->GetChildAt(++index); + // stop at first non-comment (and non-whitespace for + // :-moz-only-whitespace) node + } while (child && !IsSignificantChild(child, PR_TRUE, isWhitespaceSignificant)); + return (child == nsnull); +} + +static PRBool NS_FASTCALL +emptyMatches(RuleProcessorData& data, PRBool setNodeFlags, + nsPseudoClassList* pseudoClass) +{ + NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::empty, + "Unexpected atom"); + return checkGenericEmptyMatches(data, setNodeFlags, PR_TRUE); +} + +static PRBool NS_FASTCALL +mozOnlyWhitespaceMatches(RuleProcessorData& data, PRBool setNodeFlags, + nsPseudoClassList* pseudoClass) +{ + NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::mozOnlyWhitespace, + "Unexpected atom"); + return checkGenericEmptyMatches(data, setNodeFlags, PR_FALSE); +} + +static PRBool NS_FASTCALL +mozEmptyExceptChildrenWithLocalnameMatches(RuleProcessorData& data, + PRBool setNodeFlags, + nsPseudoClassList* pseudoClass) +{ + NS_PRECONDITION(pseudoClass->mAtom == + nsCSSPseudoClasses::mozEmptyExceptChildrenWithLocalname, + "Unexpected atom"); + NS_ASSERTION(pseudoClass->u.mString, "Must have string!"); + nsIContent *child = nsnull; + nsIContent *element = data.mContent; + PRInt32 index = -1; + + if (setNodeFlags) + element->SetFlags(NODE_HAS_SLOW_SELECTOR); + + do { + child = element->GetChildAt(++index); + } while (child && + (!IsSignificantChild(child, PR_TRUE, PR_FALSE) || + (child->GetNameSpaceID() == element->GetNameSpaceID() && + child->Tag()->Equals(nsDependentString(pseudoClass->u.mString))))); + return (child == nsnull); +} + +static PRBool NS_FASTCALL +mozSystemMetricMatches(RuleProcessorData& data, PRBool setNodeFlags, + nsPseudoClassList* pseudoClass) +{ + NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::mozSystemMetric, + "Unexpected atom"); + NS_ASSERTION(pseudoClass->u.mString, "Must have string!"); + nsCOMPtr metric = do_GetAtom(pseudoClass->u.mString); + return nsCSSRuleProcessor::HasSystemMetric(metric); +} + +static PRBool NS_FASTCALL +mozHasHandlerRefMatches(RuleProcessorData& data, PRBool setNodeFlags, + nsPseudoClassList* pseudoClass) +{ + NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::mozHasHandlerRef, + "Unexpected atom"); + nsIContent *child = nsnull; + nsIContent *element = data.mContent; + PRInt32 index = -1; + + do { + child = element->GetChildAt(++index); + if (child && child->IsHTML() && + child->Tag() == nsGkAtoms::param && + child->AttrValueIs(kNameSpaceID_None, nsGkAtoms::name, + NS_LITERAL_STRING("pluginurl"), eIgnoreCase)) { + return PR_TRUE; + } + } while (child); + return PR_FALSE; +} + +static PRBool NS_FASTCALL +rootMatches(RuleProcessorData& data, PRBool setNodeFlags, + nsPseudoClassList* pseudoClass) +{ + NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::root, + "Unexpected atom"); + return (data.mParentContent == nsnull && + data.mContent == data.mContent->GetOwnerDoc()->GetRootContent()); +} + +static PRBool NS_FASTCALL +mozBoundElementMatches(RuleProcessorData& data, PRBool setNodeFlags, + nsPseudoClassList* pseudoClass) +{ + NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::mozBoundElement, + "Unexpected atom"); + // XXXldb How do we know where the selector came from? And what + // if there are multiple bindings, and we should be matching the + // outer one? + return (data.mScopedRoot == data.mContent); +} + +static PRBool NS_FASTCALL +langMatches(RuleProcessorData& data, PRBool setNodeFlags, + nsPseudoClassList* pseudoClass) +{ + NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::lang, + "Unexpected atom"); + NS_ASSERTION(nsnull != pseudoClass->u.mString, "null lang parameter"); + if (!pseudoClass->u.mString || !*pseudoClass->u.mString) { + return PR_FALSE; + } + + // We have to determine the language of the current element. Since + // this is currently no property and since the language is inherited + // from the parent we have to be prepared to look at all parent + // nodes. The language itself is encoded in the LANG attribute. + const nsString* lang = data.GetLang(); + if (lang && !lang->IsEmpty()) { // null check for out-of-memory + return + nsStyleUtil::DashMatchCompare(*lang, + nsDependentString(pseudoClass->u.mString), + nsCaseInsensitiveStringComparator()); + } + + nsIDocument* doc = data.mContent->GetDocument(); + if (doc) { + // Try to get the language from the HTTP header or if this + // is missing as well from the preferences. + // The content language can be a comma-separated list of + // language codes. + nsAutoString language; + doc->GetContentLanguage(language); + + nsDependentString langString(pseudoClass->u.mString); + language.StripWhitespace(); + PRInt32 begin = 0; + PRInt32 len = language.Length(); + while (begin < len) { + PRInt32 end = language.FindChar(PRUnichar(','), begin); + if (end == kNotFound) { + end = len; + } + if (nsStyleUtil::DashMatchCompare(Substring(language, begin, end-begin), + langString, + nsCaseInsensitiveStringComparator())) { + return PR_TRUE; + } + begin = end + 1; + } + } + + return PR_FALSE; +} + +static PRBool NS_FASTCALL +mozAnyLinkMatches(RuleProcessorData& data, PRBool setNodeFlags, + nsPseudoClassList* pseudoClass) +{ + NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::mozAnyLink, + "Unexpected atom"); + return data.IsLink(); +} + +static PRBool NS_FASTCALL +linkMatches(RuleProcessorData& data, PRBool setNodeFlags, + nsPseudoClassList* pseudoClass) +{ + NS_NOTREACHED("Shouldn't be called"); + return PR_FALSE; +} + +static PRBool NS_FASTCALL +visitedMatches(RuleProcessorData& data, PRBool setNodeFlags, + nsPseudoClassList* pseudoClass) +{ + NS_NOTREACHED("Shouldn't be called"); + return PR_FALSE; +} + +static PRBool NS_FASTCALL +mozIsHTMLMatches(RuleProcessorData& data, PRBool setNodeFlags, + nsPseudoClassList* pseudoClass) +{ + NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::mozIsHTML, + "Unexpected atom"); + return data.mIsHTML; +} + +static PRBool NS_FASTCALL +mozLocaleDirMatches(RuleProcessorData& data, PRBool setNodeFlags, + nsPseudoClassList* pseudoClass) +{ + NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::mozLocaleDir, + "Unexpected atom"); + nsIDocument* doc = data.mContent->GetDocument(); + + if (!doc) { + return PR_FALSE; + } + + PRBool docIsRTL = doc && doc->IsDocumentRightToLeft(); + + nsDependentString dirString(pseudoClass->u.mString); + NS_ASSERTION(dirString.EqualsLiteral("ltr") || dirString.EqualsLiteral("rtl"), + "invalid value for -moz-locale-dir"); + + return dirString.EqualsLiteral("rtl") == docIsRTL; +} + +static PRBool NS_FASTCALL +mozLWThemeMatches(RuleProcessorData& data, PRBool setNodeFlags, + nsPseudoClassList* pseudoClass) +{ + NS_PRECONDITION(pseudoClass->mAtom == nsCSSPseudoClasses::mozLWTheme, + "Unexpected atom"); + nsIDocument* doc = data.mContent->GetOwnerDoc(); + return doc && doc->GetDocumentLWTheme() > nsIDocument::Doc_Theme_None; +} + +static PRBool NS_FASTCALL +mozLWThemeBrightTextMatches(RuleProcessorData& data, PRBool setNodeFlags, + nsPseudoClassList* pseudoClass) +{ + NS_PRECONDITION(pseudoClass->mAtom == + nsCSSPseudoClasses::mozLWThemeBrightText, + "Unexpected atom"); + nsIDocument* doc = data.mContent->GetOwnerDoc(); + return doc && doc->GetDocumentLWTheme() == nsIDocument::Doc_Theme_Bright; +} + +static PRBool NS_FASTCALL +mozLWThemeDarkTextMatches(RuleProcessorData& data, PRBool setNodeFlags, + nsPseudoClassList* pseudoClass) +{ + NS_PRECONDITION(pseudoClass->mAtom == + nsCSSPseudoClasses::mozLWThemeDarkText, + "Unexpected atom"); + nsIDocument* doc = data.mContent->GetOwnerDoc(); + return doc && doc->GetDocumentLWTheme() == nsIDocument::Doc_Theme_Dark; +} + +static PRBool NS_FASTCALL +notPseudoMatches(RuleProcessorData& data, PRBool setNodeFlags, + nsPseudoClassList* pseudoClass) +{ + NS_NOTREACHED("Why did this get called?"); + return PR_FALSE; +} + +typedef PRBool + (NS_FASTCALL * PseudoClassMatcher)(RuleProcessorData&, PRBool setNodeFlags, + nsPseudoClassList* pseudoClass); +// Only one of mFunc or mBit will be set; the other will be null or 0 +// respectively. We could use a union, but then we'd still need to +// differentiate somehow, eiher with another member in the struct or +// with a boolean coming from _sowewhere_. +struct PseudoClassInfo { + PseudoClassMatcher mFunc; + PRInt32 mBit; +}; + +static const PseudoClassInfo sPseudoClassInfo[] = { +#define CSS_PSEUDO_CLASS(_name, _value) \ + { &_name##Matches, 0 }, +#define CSS_STATE_PSEUDO_CLASS(_name, _value, _bit) \ + { nsnull, _bit }, +#include "nsCSSPseudoClassList.h" +#undef CSS_STATE_PSEUDO_CLASS +#undef CSS_PSEUDO_CLASS + // Add more entries for our fake values to make sure we can't + // index out of bounds into this array no matter what. + { nsnull, 0 }, + { nsnull, 0 } +}; +PR_STATIC_ASSERT(NS_ARRAY_LENGTH(sPseudoClassInfo) > + nsCSSPseudoClasses::ePseudoClass_NotPseudoClass); + +// NOTE: For |aStateMask| to work correctly, it's important that any change +// that changes multiple state bits include all those state bits in the +// notification. Otherwise, if multiple states change but we do separate +// notifications then we might determine the style is not state-dependent when +// it really is (e.g., determining that a :hover:active rule no longer matches +// when both states are unset). // If |aForStyling| is false, we shouldn't mark slow-selector bits on nodes. @@ -1245,448 +1773,124 @@ static PRBool AttrMatchesValue(const nsAttrSelector* aAttrSelector, // * when non-null, it indicates that we're processing a negation, // which is done only when SelectorMatches calls itself recursively // * what it points to should be set to true whenever a test is skipped -// because of aStateMask or aAttribute +// because of aStateMask static PRBool SelectorMatches(RuleProcessorData &data, nsCSSSelector* aSelector, PRInt32 aStateMask, // states NOT to test - nsIAtom* aAttribute, // attribute NOT to test PRBool aForStyling, PRBool* const aDependence = nsnull) { + NS_PRECONDITION(!aSelector->IsPseudoElement(), + "Pseudo-element snuck into SelectorMatches?"); // namespace/tag match // optimization : bail out early if we can if ((kNameSpaceID_Unknown != aSelector->mNameSpace && data.mNameSpaceID != aSelector->mNameSpace)) return PR_FALSE; - const PRBool isHTML = - data.mIsHTMLContent && data.mContent->GetOwnerDoc()->IsHTML(); - if (aSelector->mLowercaseTag && - (isHTML ? aSelector->mLowercaseTag : aSelector->mCasedTag) != + (data.mIsHTML ? aSelector->mLowercaseTag : aSelector->mCasedTag) != data.mContentTag) { return PR_FALSE; } - PRBool result = PR_TRUE; + nsAtomList* IDList = aSelector->mIDList; + if (IDList) { + if (data.mContentID) { + // case sensitivity: bug 93371 + const PRBool isCaseSensitive = + data.mCompatMode != eCompatibility_NavQuirks; + + if (isCaseSensitive) { + do { + if (IDList->mAtom != data.mContentID) { + return PR_FALSE; + } + IDList = IDList->mNext; + } while (IDList); + } else { + const char* id1Str; + data.mContentID->GetUTF8String(&id1Str); + nsDependentCString id1(id1Str); + do { + const char* id2Str; + IDList->mAtom->GetUTF8String(&id2Str); + if (!id1.Equals(id2Str, nsCaseInsensitiveCStringComparator())) { + return PR_FALSE; + } + IDList = IDList->mNext; + } while (IDList); + } + } else { + // Element has no id but we have an id selector + return PR_FALSE; + } + } + + nsAtomList* classList = aSelector->mClassList; + if (classList) { + // test for class match + const nsAttrValue *elementClasses = data.mClasses; + if (!elementClasses) { + // Element has no classes but we have a class selector + return PR_FALSE; + } + + // case sensitivity: bug 93371 + const PRBool isCaseSensitive = + data.mCompatMode != eCompatibility_NavQuirks; + + while (classList) { + if (!elementClasses->Contains(classList->mAtom, + isCaseSensitive ? + eCaseMatters : eIgnoreCase)) { + return PR_FALSE; + } + classList = classList->mNext; + } + } + const PRBool isNegated = (aDependence != nsnull); // The selectors for which we set node bits are, unfortunately, early // in this function (because they're pseudo-classes, which are // generally quick to test, and thus earlier). If they were later, // we'd probably avoid setting those bits in more cases where setting // them is unnecessary. - const PRBool setNodeFlags = aForStyling && aStateMask == 0 && !aAttribute; + NS_ASSERTION(aStateMask == 0 || !aForStyling, + "aForStyling must be false if we're just testing for " + "state-dependence"); + const PRBool setNodeFlags = aForStyling; // test for pseudo class match - // first-child, root, lang, active, focus, hover, link, visited... - // XXX disabled, enabled, selected, selection for (nsPseudoClassList* pseudoClass = aSelector->mPseudoClassList; - pseudoClass && result; pseudoClass = pseudoClass->mNext) { - PRInt32 stateToCheck = 0; - if (nsCSSPseudoClasses::firstNode == pseudoClass->mAtom) { - nsIContent *firstNode = nsnull; - nsIContent *parent = data.mParentContent; - if (parent) { - if (setNodeFlags) - parent->SetFlags(NODE_HAS_EDGE_CHILD_SELECTOR); - - PRInt32 index = -1; - do { - firstNode = parent->GetChildAt(++index); - // stop at first non-comment and non-whitespace node - } while (firstNode && - !IsSignificantChild(firstNode, PR_TRUE, PR_FALSE)); + pseudoClass; pseudoClass = pseudoClass->mNext) { + // XXXbz special-case for :link and :visited, which are neither + // fish nor fowl + if (pseudoClass->mAtom == nsCSSPseudoClasses::link || + pseudoClass->mAtom == nsCSSPseudoClasses::visited) { + if (!data.IsLink()) { + return PR_FALSE; } - result = (data.mContent == firstNode); - } - else if (nsCSSPseudoClasses::lastNode == pseudoClass->mAtom) { - nsIContent *lastNode = nsnull; - nsIContent *parent = data.mParentContent; - if (parent) { - if (setNodeFlags) - parent->SetFlags(NODE_HAS_EDGE_CHILD_SELECTOR); - PRUint32 index = parent->GetChildCount(); - do { - lastNode = parent->GetChildAt(--index); - // stop at first non-comment and non-whitespace node - } while (lastNode && - !IsSignificantChild(lastNode, PR_TRUE, PR_FALSE)); + if (aStateMask & NS_EVENT_STATE_VISITED) { + if (aDependence) + *aDependence = PR_TRUE; + } else if ((eLinkState_Visited == data.LinkState()) == + (nsCSSPseudoClasses::link == pseudoClass->mAtom)) { + // Visited but :link or unvisited but :visited + return PR_FALSE; } - result = (data.mContent == lastNode); + continue; } - else if (nsCSSPseudoClasses::firstChild == pseudoClass->mAtom || - nsCSSPseudoClasses::lastChild == pseudoClass->mAtom || - nsCSSPseudoClasses::onlyChild == pseudoClass->mAtom) { - nsIContent *parent = data.mParentContent; - if (parent) { - const PRBool checkFirst = - pseudoClass->mAtom != nsCSSPseudoClasses::lastChild; - const PRBool checkLast = - pseudoClass->mAtom != nsCSSPseudoClasses::firstChild; - if (setNodeFlags) - parent->SetFlags(NODE_HAS_EDGE_CHILD_SELECTOR); - - result = (!checkFirst || - data.GetNthIndex(PR_FALSE, PR_FALSE, PR_TRUE) == 1) && - (!checkLast || - data.GetNthIndex(PR_FALSE, PR_TRUE, PR_TRUE) == 1); - } else { - result = PR_FALSE; + const PseudoClassInfo& info = sPseudoClassInfo[pseudoClass->mType]; + if (info.mFunc) { + if (!(*info.mFunc)(data, setNodeFlags, pseudoClass)) { + return PR_FALSE; } - } - else if (nsCSSPseudoClasses::nthChild == pseudoClass->mAtom || - nsCSSPseudoClasses::nthLastChild == pseudoClass->mAtom || - nsCSSPseudoClasses::nthOfType == pseudoClass->mAtom || - nsCSSPseudoClasses::nthLastOfType == pseudoClass->mAtom) { - nsIContent *parent = data.mParentContent; - if (parent) { - PRBool isOfType = - nsCSSPseudoClasses::nthOfType == pseudoClass->mAtom || - nsCSSPseudoClasses::nthLastOfType == pseudoClass->mAtom; - PRBool isFromEnd = - nsCSSPseudoClasses::nthLastChild == pseudoClass->mAtom || - nsCSSPseudoClasses::nthLastOfType == pseudoClass->mAtom; - if (setNodeFlags) { - if (isFromEnd) - parent->SetFlags(NODE_HAS_SLOW_SELECTOR); - else - parent->SetFlags(NODE_HAS_SLOW_SELECTOR_NOAPPEND); - } - - const PRInt32 index = data.GetNthIndex(isOfType, isFromEnd, PR_FALSE); - if (index <= 0) { - // Node is anonymous content (not really a child of its parent). - result = PR_FALSE; - } else { - const PRInt32 a = pseudoClass->u.mNumbers[0]; - const PRInt32 b = pseudoClass->u.mNumbers[1]; - // result should be true if there exists n >= 0 such that - // a * n + b == index. - if (a == 0) { - result = b == index; - } else { - // Integer division in C does truncation (towards 0). So - // check that the result is nonnegative, and that there was no - // truncation. - const PRInt32 n = (index - b) / a; - result = n >= 0 && (a * n == index - b); - } - } - } else { - result = PR_FALSE; - } - } - else if (nsCSSPseudoClasses::firstOfType == pseudoClass->mAtom || - nsCSSPseudoClasses::lastOfType == pseudoClass->mAtom || - nsCSSPseudoClasses::onlyOfType == pseudoClass->mAtom) { - nsIContent *parent = data.mParentContent; - if (parent) { - const PRBool checkFirst = - pseudoClass->mAtom != nsCSSPseudoClasses::lastOfType; - const PRBool checkLast = - pseudoClass->mAtom != nsCSSPseudoClasses::firstOfType; - if (setNodeFlags) { - if (checkLast) - parent->SetFlags(NODE_HAS_SLOW_SELECTOR); - else - parent->SetFlags(NODE_HAS_SLOW_SELECTOR_NOAPPEND); - } - - result = (!checkFirst || - data.GetNthIndex(PR_TRUE, PR_FALSE, PR_TRUE) == 1) && - (!checkLast || - data.GetNthIndex(PR_TRUE, PR_TRUE, PR_TRUE) == 1); - } else { - result = PR_FALSE; - } - } - else if (nsCSSPseudoClasses::empty == pseudoClass->mAtom || - nsCSSPseudoClasses::mozOnlyWhitespace == pseudoClass->mAtom) { - nsIContent *child = nsnull; - nsIContent *element = data.mContent; - const PRBool isWhitespaceSignificant = - nsCSSPseudoClasses::empty == pseudoClass->mAtom; - PRInt32 index = -1; - - if (setNodeFlags) - element->SetFlags(NODE_HAS_EMPTY_SELECTOR); - - do { - child = element->GetChildAt(++index); - // stop at first non-comment (and non-whitespace for - // :-moz-only-whitespace) node - } while (child && !IsSignificantChild(child, PR_TRUE, isWhitespaceSignificant)); - result = (child == nsnull); - } - else if (nsCSSPseudoClasses::mozEmptyExceptChildrenWithLocalname == pseudoClass->mAtom) { - NS_ASSERTION(pseudoClass->u.mString, "Must have string!"); - nsIContent *child = nsnull; - nsIContent *element = data.mContent; - PRInt32 index = -1; - - if (setNodeFlags) - element->SetFlags(NODE_HAS_SLOW_SELECTOR); - - do { - child = element->GetChildAt(++index); - } while (child && - (!IsSignificantChild(child, PR_TRUE, PR_FALSE) || - (child->GetNameSpaceID() == element->GetNameSpaceID() && - child->Tag()->Equals(nsDependentString(pseudoClass->u.mString))))); - result = (child == nsnull); - } - else if (nsCSSPseudoClasses::mozSystemMetric == pseudoClass->mAtom) { - NS_ASSERTION(pseudoClass->u.mString, "Must have string!"); - nsCOMPtr metric = do_GetAtom(pseudoClass->u.mString); - result = nsCSSRuleProcessor::HasSystemMetric(metric); - } - else if (nsCSSPseudoClasses::mozHasHandlerRef == pseudoClass->mAtom) { - nsIContent *child = nsnull; - nsIContent *element = data.mContent; - PRInt32 index = -1; - - result = PR_FALSE; - if (element) { - do { - child = element->GetChildAt(++index); - if (child && child->IsHTML() && - child->Tag() == nsGkAtoms::param && - child->AttrValueIs(kNameSpaceID_None, nsGkAtoms::name, - NS_LITERAL_STRING("pluginurl"), eIgnoreCase)) { - result = PR_TRUE; - break; - } - } while (child); - } - } - else if (nsCSSPseudoClasses::root == pseudoClass->mAtom) { - result = (data.mParentContent == nsnull && - data.mContent && - data.mContent == - data.mContent->GetOwnerDoc()->GetRootContent()); - } - else if (nsCSSPseudoClasses::mozBoundElement == pseudoClass->mAtom) { - // XXXldb How do we know where the selector came from? And what - // if there are multiple bindings, and we should be matching the - // outer one? - result = (data.mScopedRoot && data.mScopedRoot == data.mContent); - } - else if (nsCSSPseudoClasses::lang == pseudoClass->mAtom) { - NS_ASSERTION(nsnull != pseudoClass->u.mString, "null lang parameter"); - result = PR_FALSE; - if (pseudoClass->u.mString && *pseudoClass->u.mString) { - // We have to determine the language of the current element. Since - // this is currently no property and since the language is inherited - // from the parent we have to be prepared to look at all parent - // nodes. The language itself is encoded in the LANG attribute. - const nsString* lang = data.GetLang(); - if (lang && !lang->IsEmpty()) { // null check for out-of-memory - result = nsStyleUtil::DashMatchCompare(*lang, - nsDependentString(pseudoClass->u.mString), - nsCaseInsensitiveStringComparator()); - } - else if (data.mContent) { - nsIDocument* doc = data.mContent->GetDocument(); - if (doc) { - // Try to get the language from the HTTP header or if this - // is missing as well from the preferences. - // The content language can be a comma-separated list of - // language codes. - nsAutoString language; - doc->GetContentLanguage(language); - - nsDependentString langString(pseudoClass->u.mString); - language.StripWhitespace(); - PRInt32 begin = 0; - PRInt32 len = language.Length(); - while (begin < len) { - PRInt32 end = language.FindChar(PRUnichar(','), begin); - if (end == kNotFound) { - end = len; - } - if (nsStyleUtil::DashMatchCompare(Substring(language, begin, end-begin), - langString, - nsCaseInsensitiveStringComparator())) { - result = PR_TRUE; - break; - } - begin = end + 1; - } - } - } - } - } else if (nsCSSPseudoClasses::active == pseudoClass->mAtom) { - stateToCheck = NS_EVENT_STATE_ACTIVE; - } - else if (nsCSSPseudoClasses::focus == pseudoClass->mAtom) { - stateToCheck = NS_EVENT_STATE_FOCUS; - } - else if (nsCSSPseudoClasses::hover == pseudoClass->mAtom) { - stateToCheck = NS_EVENT_STATE_HOVER; - } - else if (nsCSSPseudoClasses::mozDragOver == pseudoClass->mAtom) { - stateToCheck = NS_EVENT_STATE_DRAGOVER; - } - else if (nsCSSPseudoClasses::target == pseudoClass->mAtom) { - stateToCheck = NS_EVENT_STATE_URLTARGET; - } - else if (IsLinkPseudo(pseudoClass->mAtom)) { - if (data.mIsLink) { - if (nsCSSPseudoClasses::mozAnyLink == pseudoClass->mAtom) { - result = PR_TRUE; - } - else { - NS_ASSERTION(nsCSSPseudoClasses::link == pseudoClass->mAtom || - nsCSSPseudoClasses::visited == pseudoClass->mAtom, - "somebody changed IsLinkPseudo"); - NS_ASSERTION(data.mLinkState == eLinkState_Unvisited || - data.mLinkState == eLinkState_Visited, - "unexpected link state for mIsLink"); - if (aStateMask & NS_EVENT_STATE_VISITED) { - result = PR_TRUE; - if (aDependence) - *aDependence = PR_TRUE; - } else { - result = ((eLinkState_Unvisited == data.mLinkState) == - (nsCSSPseudoClasses::link == pseudoClass->mAtom)); - } - } - } - else { - result = PR_FALSE; // not a link - } - } - else if (nsCSSPseudoClasses::checked == pseudoClass->mAtom) { - // This pseudoclass matches the selected state on the following elements: - //
Mozilla Bug 525952 +

+ +
+
+
+ + diff --git a/layout/style/test/test_transitions_dynamic_changes.html b/layout/style/test/test_transitions_dynamic_changes.html new file mode 100644 index 000000000000..f5a5ad022db0 --- /dev/null +++ b/layout/style/test/test_transitions_dynamic_changes.html @@ -0,0 +1,46 @@ + + + + + Test for Bug 525530 + + + + + +Mozilla Bug 525530 +

+
+
+
+ + diff --git a/layout/style/test/test_transitions_per_property.html b/layout/style/test/test_transitions_per_property.html index 53fae9685f87..a54c71c820aa 100644 --- a/layout/style/test/test_transitions_per_property.html +++ b/layout/style/test/test_transitions_per_property.html @@ -51,14 +51,20 @@ var supported_properties = { "-moz-border-radius-bottomright": [ test_radius_transition ], "-moz-border-radius-topleft": [ test_radius_transition ], "-moz-border-radius-topright": [ test_radius_transition ], + "-moz-box-flex": [ test_float_zeroToOne_transition, + test_float_aboveOne_transition ], "-moz-box-shadow": [ test_shadow_transition ], + "-moz-column-count": [ test_pos_integer_or_auto_transition ], "-moz-column-gap": [ test_length_transition ], "-moz-column-rule-color": [ test_color_transition ], + "-moz-column-rule-width": [ test_length_transition ], "-moz-column-width": [ test_length_transition ], "-moz-outline-radius-bottomleft": [ test_radius_transition ], "-moz-outline-radius-bottomright": [ test_radius_transition ], "-moz-outline-radius-topleft": [ test_radius_transition ], "-moz-outline-radius-topright": [ test_radius_transition ], + "-moz-transform-origin": [ test_length_pair_transition, + test_length_percent_pair_transition ], "background-color": [ test_color_transition ], "border-bottom-color": [ test_color_transition ], "border-bottom-width": [ test_length_transition ], @@ -66,6 +72,7 @@ var supported_properties = { "border-left-width": [ test_length_transition ], "border-right-color": [ test_color_transition ], "border-right-width": [ test_length_transition ], + "border-spacing": [ test_length_pair_transition ], "border-top-color": [ test_color_transition ], "border-top-width": [ test_length_transition ], "bottom": [ test_length_transition, test_percent_transition ], @@ -116,7 +123,7 @@ var supported_properties = { "vertical-align": [ test_length_transition, test_percent_transition ], "width": [ test_length_transition, test_percent_transition ], "word-spacing": [ test_length_transition ], - "z-index": [ test_zindex_transition ], + "z-index": [ test_zindex_transition, test_pos_integer_or_auto_transition ], }; var div = document.getElementById("display"); @@ -477,6 +484,48 @@ function test_font_weight(prop) { "font-weight property " + prop + ": interpolation of font-weights"); } +function test_pos_integer_or_auto_transition(prop) { + div.style.setProperty("-moz-transition-property", "none", ""); + div.style.setProperty(prop, "4", ""); + is(cs.getPropertyValue(prop), "4", + "integer-valued property " + prop + ": computed value before transition"); + div.style.setProperty("-moz-transition-property", prop, ""); + div.style.setProperty(prop, "7", ""); + is(cs.getPropertyValue(prop), "5", + "integer-valued property " + prop + ": interpolation of lengths"); + div.style.setProperty(prop, "auto", ""); + is(cs.getPropertyValue(prop), "auto", + "integer-valued property " + prop + ": auto not interpolable"); + div.style.setProperty(prop, "8", ""); + is(cs.getPropertyValue(prop), "8", + "integer-valued property " + prop + ": computed value before transition"); + div.style.setProperty(prop, "4", ""); + is(cs.getPropertyValue(prop), "6", + "integer-valued property " + prop + ": interpolation of lengths"); +} + +function test_length_pair_transition(prop) { + div.style.setProperty("-moz-transition-property", "none", ""); + div.style.setProperty(prop, "4px 8px", ""); + is(cs.getPropertyValue(prop), "4px 8px", + "length-valued property " + prop + ": computed value before transition"); + div.style.setProperty("-moz-transition-property", prop, ""); + div.style.setProperty(prop, "12px 10px", ""); + is(cs.getPropertyValue(prop), "8px 9px", + "length-valued property " + prop + ": interpolation of lengths"); +} + +function test_length_percent_pair_transition(prop) { + div.style.setProperty("-moz-transition-property", "none", ""); + div.style.setProperty(prop, "4px 50%", ""); + is(cs.getPropertyValue(prop), "4px 50%", + "length-valued property " + prop + ": computed value before transition"); + div.style.setProperty("-moz-transition-property", prop, ""); + div.style.setProperty(prop, "12px 70%", ""); + is(cs.getPropertyValue(prop), "8px 60%", + "length-valued property " + prop + ": interpolation of lengths"); +} + diff --git a/layout/svg/base/src/nsSVGEffects.cpp b/layout/svg/base/src/nsSVGEffects.cpp index ec298c71312f..806cd4d0f736 100644 --- a/layout/svg/base/src/nsSVGEffects.cpp +++ b/layout/svg/base/src/nsSVGEffects.cpp @@ -149,8 +149,7 @@ nsSVGRenderingObserver::AttributeChanged(nsIDocument *aDocument, nsIContent *aContent, PRInt32 aNameSpaceID, nsIAtom *aAttribute, - PRInt32 aModType, - PRUint32 aStateMask) + PRInt32 aModType) { DoUpdate(); } diff --git a/layout/svg/base/src/nsSVGGlyphFrame.cpp b/layout/svg/base/src/nsSVGGlyphFrame.cpp index dd0cf85d0b42..8d1587e0df0d 100644 --- a/layout/svg/base/src/nsSVGGlyphFrame.cpp +++ b/layout/svg/base/src/nsSVGGlyphFrame.cpp @@ -54,7 +54,6 @@ #include "gfxMatrix.h" #include "gfxPlatform.h" #include "gfxTextRunWordCache.h" -#include "nsTextFrame.h" struct CharacterPosition { gfxPoint pos; @@ -295,10 +294,6 @@ nsSVGGlyphFrame::Init(nsIContent* aContent, "trying to construct an SVGGlyphFrame for wrong content element"); #endif /* DEBUG */ - if (!PresContext()->IsDynamic()) { - AddStateBits(NS_STATE_SVG_PRINTING); - } - return nsSVGGlyphFrameBase::Init(aContent, aParent, aPrevInFlow); } @@ -637,7 +632,7 @@ PRBool nsSVGGlyphFrame::GetCharacterData(nsAString & aCharacterData) { nsAutoString characterData; - GetFragment()->AppendTo(characterData); + mContent->AppendTextTo(characterData); if (mWhitespaceHandling & COMPRESS_WHITESPACE) { PRBool trimLeadingWhitespace, trimTrailingWhitespace; @@ -841,7 +836,7 @@ nsSVGGlyphFrame::GetHighlight(PRUint32 *charnum, PRUint32 *nchars, // The selection ranges are relative to the uncompressed text in // the content element. We'll need the text fragment: - const nsTextFragment* fragment = GetFragment(); + const nsTextFragment *fragment = mContent->GetText(); NS_ASSERTION(fragment, "no text"); // get the selection details @@ -1122,7 +1117,7 @@ PRUint32 nsSVGGlyphFrame::GetNumberOfChars() { if (mWhitespaceHandling == PRESERVE_WHITESPACE) - return GetFragment()->GetLength(); + return mContent->TextLength(); nsAutoString text; GetCharacterData(text); diff --git a/layout/svg/base/src/nsSVGGlyphFrame.h b/layout/svg/base/src/nsSVGGlyphFrame.h index 27d37e7874bb..357b87cb56b8 100644 --- a/layout/svg/base/src/nsSVGGlyphFrame.h +++ b/layout/svg/base/src/nsSVGGlyphFrame.h @@ -208,11 +208,6 @@ protected: nscolor *foreground, nscolor *background); float GetSubStringAdvance(PRUint32 charnum, PRUint32 fragmentChars); gfxFloat GetBaselineOffset(PRBool aForceGlobalTransform); - const nsTextFragment* GetFragment() const - { - return !(GetStateBits() & NS_STATE_SVG_PRINTING) ? - mContent->GetText() : nsLayoutUtils::GetTextFragmentForPrinting(this); - } // Used to support GetBBoxContribution by making GetConvasTM use this as the // parent transform instead of the real CanvasTM. diff --git a/layout/svg/base/src/nsSVGOuterSVGFrame.cpp b/layout/svg/base/src/nsSVGOuterSVGFrame.cpp index e2e84043e3c6..5f46f0c3c045 100644 --- a/layout/svg/base/src/nsSVGOuterSVGFrame.cpp +++ b/layout/svg/base/src/nsSVGOuterSVGFrame.cpp @@ -86,8 +86,7 @@ nsSVGMutationObserver::AttributeChanged(nsIDocument *aDocument, nsIContent *aContent, PRInt32 aNameSpaceID, nsIAtom *aAttribute, - PRInt32 aModType, - PRUint32 aStateMask) + PRInt32 aModType) { if (aNameSpaceID != kNameSpaceID_XML || aAttribute != nsGkAtoms::space) { return; diff --git a/layout/svg/base/src/nsSVGTextFrame.cpp b/layout/svg/base/src/nsSVGTextFrame.cpp index 03b838aefe59..64ae328fb435 100644 --- a/layout/svg/base/src/nsSVGTextFrame.cpp +++ b/layout/svg/base/src/nsSVGTextFrame.cpp @@ -189,6 +189,8 @@ nsSVGTextFrame::NotifySVGChanged(PRUint32 aFlags) mCanvasTM = nsnull; } + nsSVGTextFrameBase::NotifySVGChanged(aFlags); + if (aFlags & COORD_CONTEXT_CHANGED) { // If we are positioned using percentage values we need to update our // position whenever our viewport's dimensions change. @@ -198,8 +200,6 @@ nsSVGTextFrame::NotifySVGChanged(PRUint32 aFlags) // may not be worth it as we might need to check each glyph NotifyGlyphMetricsChange(); } - - nsSVGTextFrameBase::NotifySVGChanged(aFlags); } NS_IMETHODIMP diff --git a/layout/svg/base/src/nsSVGUtils.h b/layout/svg/base/src/nsSVGUtils.h index 83ba5f558ade..28840f08b1c6 100644 --- a/layout/svg/base/src/nsSVGUtils.h +++ b/layout/svg/base/src/nsSVGUtils.h @@ -95,9 +95,6 @@ class nsSVGDisplayContainerFrame; #define NS_STATE_SVG_PROPAGATE_TRANSFORM 0x00800000 -// nsSVGGlyphFrame uses this when the frame is within a non-dynamic PresContext. -#define NS_STATE_SVG_PRINTING 0x01000000 - /** * Byte offsets of channels in a native packed gfxColor or cairo image surface. */ diff --git a/layout/tables/crashtests/513732-1.html b/layout/tables/crashtests/513732-1.html new file mode 100644 index 000000000000..7ca35ddcebe0 --- /dev/null +++ b/layout/tables/crashtests/513732-1.html @@ -0,0 +1,7 @@ + + + + +
+ + diff --git a/layout/tables/crashtests/crashtests.list b/layout/tables/crashtests/crashtests.list index 5053b2791a98..641905fb905f 100644 --- a/layout/tables/crashtests/crashtests.list +++ b/layout/tables/crashtests/crashtests.list @@ -98,3 +98,4 @@ load 456041.html load 457115.html load 467141-1.html load 488388-1.html +load 513732-1.html diff --git a/layout/tables/nsTableFrame.cpp b/layout/tables/nsTableFrame.cpp index e23da75f27ed..e41e6b904dd5 100644 --- a/layout/tables/nsTableFrame.cpp +++ b/layout/tables/nsTableFrame.cpp @@ -668,9 +668,8 @@ nsTableFrame::CreateAnonymousColGroupFrame(nsTableColGroupType aColGroupType) nsIPresShell *shell = presContext->PresShell(); nsRefPtr colGroupStyle; - colGroupStyle = shell->StyleSet()->ResolvePseudoStyleFor(colGroupContent, - nsCSSAnonBoxes::tableColGroup, - mStyleContext); + colGroupStyle = shell->StyleSet()-> + ResolveAnonymousBoxStyle(nsCSSAnonBoxes::tableColGroup, mStyleContext); // Create a col group frame nsIFrame* newFrame = NS_NewTableColGroupFrame(shell, colGroupStyle); if (newFrame) { @@ -733,9 +732,8 @@ nsTableFrame::AppendAnonymousColFrames(nsTableColGroupFrame* aColGroupFrame, // col group iContent = aColGroupFrame->GetContent(); parentStyleContext = aColGroupFrame->GetStyleContext(); - styleContext = shell->StyleSet()->ResolvePseudoStyleFor(iContent, - nsCSSAnonBoxes::tableCol, - parentStyleContext); + styleContext = shell->StyleSet()-> + ResolveAnonymousBoxStyle(nsCSSAnonBoxes::tableCol, parentStyleContext); // ASSERTION to check for bug 54454 sneaking back in... NS_ASSERTION(iContent, "null content in CreateAnonymousColFrames"); diff --git a/layout/xul/base/src/crashtests/237787-1.xul b/layout/xul/base/src/crashtests/237787-1.xul new file mode 100644 index 000000000000..96cebca9ff5f --- /dev/null +++ b/layout/xul/base/src/crashtests/237787-1.xul @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/layout/xul/base/src/crashtests/508927-2.xul b/layout/xul/base/src/crashtests/508927-2.xul new file mode 100644 index 000000000000..5bf4f9a0c775 --- /dev/null +++ b/layout/xul/base/src/crashtests/508927-2.xul @@ -0,0 +1,6 @@ + + + + + + diff --git a/layout/xul/base/src/crashtests/crashtests.list b/layout/xul/base/src/crashtests/crashtests.list index 850eabf89144..6ecb45685695 100644 --- a/layout/xul/base/src/crashtests/crashtests.list +++ b/layout/xul/base/src/crashtests/crashtests.list @@ -3,6 +3,7 @@ load 137216-1.xul load 140218-1.xml load 151826-1.xul load 168724-1.xul +load 237787-1.xul load 289410-1.xul load 291702-1.xul load 291702-2.xul @@ -64,3 +65,4 @@ load 475133.html load 488210-1.xhtml load 495728-1.xul load 508927-1.xul +load 508927-2.xul diff --git a/layout/xul/base/src/nsImageBoxFrame.cpp b/layout/xul/base/src/nsImageBoxFrame.cpp index bdba84f8128f..ddcf243e0962 100644 --- a/layout/xul/base/src/nsImageBoxFrame.cpp +++ b/layout/xul/base/src/nsImageBoxFrame.cpp @@ -279,7 +279,7 @@ nsImageBoxFrame::UpdateImage() if (!(appearance && nsBox::gTheme && nsBox::gTheme->ThemeSupportsWidget(nsnull, this, appearance))) { // get the list-style-image - imgIRequest *styleRequest = GetStyleList()->mListStyleImage; + imgIRequest *styleRequest = GetStyleList()->GetListStyleImage(); if (styleRequest) { styleRequest->Clone(mListener, getter_AddRefs(mImageRequest)); } @@ -417,8 +417,8 @@ nsImageBoxFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext) nsCOMPtr oldURI, newURI; if (mImageRequest) mImageRequest->GetURI(getter_AddRefs(oldURI)); - if (myList->mListStyleImage) - myList->mListStyleImage->GetURI(getter_AddRefs(newURI)); + if (myList->GetListStyleImage()) + myList->GetListStyleImage()->GetURI(getter_AddRefs(newURI)); PRBool equal; if (newURI == oldURI || // handles null==null (newURI && oldURI && diff --git a/layout/xul/base/src/nsRepeatService.cpp b/layout/xul/base/src/nsRepeatService.cpp index 4f235cb036d3..1eaa00b09496 100644 --- a/layout/xul/base/src/nsRepeatService.cpp +++ b/layout/xul/base/src/nsRepeatService.cpp @@ -45,14 +45,6 @@ #include "nsRepeatService.h" #include "nsIServiceManager.h" -#ifdef XP_MACOSX -#define INITAL_REPEAT_DELAY 250 -#define REPEAT_DELAY 25 -#else -#define INITAL_REPEAT_DELAY 250 -#define REPEAT_DELAY 50 -#endif - nsRepeatService* nsRepeatService::gInstance = nsnull; nsRepeatService::nsRepeatService() @@ -81,7 +73,8 @@ nsRepeatService::Shutdown() NS_IF_RELEASE(gInstance); } -void nsRepeatService::Start(Callback aCallback, void* aCallbackData) +void nsRepeatService::Start(Callback aCallback, void* aCallbackData, + PRUint32 aInitialDelay) { NS_PRECONDITION(aCallback != nsnull, "null ptr"); @@ -91,7 +84,7 @@ void nsRepeatService::Start(Callback aCallback, void* aCallbackData) mRepeatTimer = do_CreateInstance("@mozilla.org/timer;1", &rv); if (NS_SUCCEEDED(rv)) { - mRepeatTimer->InitWithCallback(this, INITAL_REPEAT_DELAY, nsITimer::TYPE_ONE_SHOT); + mRepeatTimer->InitWithCallback(this, aInitialDelay, nsITimer::TYPE_ONE_SHOT); } } diff --git a/layout/xul/base/src/nsRepeatService.h b/layout/xul/base/src/nsRepeatService.h index 75f922f6cd74..3330587ead4c 100644 --- a/layout/xul/base/src/nsRepeatService.h +++ b/layout/xul/base/src/nsRepeatService.h @@ -44,6 +44,14 @@ #include "nsCOMPtr.h" #include "nsITimer.h" +#define INITAL_REPEAT_DELAY 250 + +#ifdef XP_MACOSX +#define REPEAT_DELAY 25 +#else +#define REPEAT_DELAY 50 +#endif + class nsITimer; class nsRepeatService : public nsITimerCallback @@ -57,7 +65,8 @@ public: // Start dispatching timer events to the callback. There is no memory // management of aData here; it is the caller's responsibility to call // Stop() before aData's memory is released. - void Start(Callback aCallback, void* aData); + void Start(Callback aCallback, void* aData, + PRUint32 aInitialDelay = INITAL_REPEAT_DELAY); // Stop dispatching timer events to the callback. If the repeat service // is not currently configured with the given callback and data, this // is just ignored. diff --git a/layout/xul/base/src/nsScrollBoxFrame.cpp b/layout/xul/base/src/nsScrollBoxFrame.cpp index 79c75756457a..690746bce626 100644 --- a/layout/xul/base/src/nsScrollBoxFrame.cpp +++ b/layout/xul/base/src/nsScrollBoxFrame.cpp @@ -77,7 +77,7 @@ protected: nsButtonBoxFrame(aPresShell, aContext) {} void StartRepeat() { - nsRepeatService::GetInstance()->Start(Notify, this); + nsRepeatService::GetInstance()->Start(Notify, this, 0); } void StopRepeat() { nsRepeatService::GetInstance()->Stop(Notify, this); diff --git a/layout/xul/base/src/tree/src/crashtests/509602-1-overlay.xul b/layout/xul/base/src/tree/src/crashtests/509602-1-overlay.xul new file mode 100644 index 000000000000..f5cecd40ed92 --- /dev/null +++ b/layout/xul/base/src/tree/src/crashtests/509602-1-overlay.xul @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/layout/xul/base/src/tree/src/crashtests/509602-1.xul b/layout/xul/base/src/tree/src/crashtests/509602-1.xul new file mode 100644 index 000000000000..a1cdcf1ccc1d --- /dev/null +++ b/layout/xul/base/src/tree/src/crashtests/509602-1.xul @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/layout/xul/base/src/tree/src/crashtests/crashtests.list b/layout/xul/base/src/tree/src/crashtests/crashtests.list index 326c5c17fc9f..58e1dc509a96 100644 --- a/layout/xul/base/src/tree/src/crashtests/crashtests.list +++ b/layout/xul/base/src/tree/src/crashtests/crashtests.list @@ -14,3 +14,4 @@ load 399715-1.xhtml load 409807-1.xul load 430394-1.xul load 454186-1.xul +load 509602-1.xul diff --git a/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp b/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp index 453a899fd9e0..84033a99bc62 100644 --- a/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp +++ b/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp @@ -2157,7 +2157,7 @@ nsTreeBodyFrame::GetImage(PRInt32 aRowIndex, nsTreeColumn* aCol, PRBool aUseCont else { // Obtain the URL from the style context. aAllowImageRegions = PR_TRUE; - styleRequest = aStyleContext->GetStyleList()->mListStyleImage; + styleRequest = aStyleContext->GetStyleList()->GetListStyleImage(); if (!styleRequest) return NS_OK; nsCOMPtr uri; diff --git a/layout/xul/base/src/tree/src/nsTreeColFrame.cpp b/layout/xul/base/src/tree/src/nsTreeColFrame.cpp index 4daab7079f5a..fa672bec5cd2 100644 --- a/layout/xul/base/src/tree/src/nsTreeColFrame.cpp +++ b/layout/xul/base/src/tree/src/nsTreeColFrame.cpp @@ -127,7 +127,6 @@ nsDisplayXULTreeColSplitterTarget::HitTest(nsDisplayListBuilder* aBuilder, if (left || right) { // We are a header. Look for the correct splitter. - const nsFrameList& frames(mFrame->GetParent()->GetChildList(nsnull)); nsIFrame* child; if (left) child = mFrame->GetPrevSibling(); diff --git a/layout/xul/base/src/tree/src/nsTreeContentView.cpp b/layout/xul/base/src/tree/src/nsTreeContentView.cpp index 0169d8372033..043a08b7b20a 100644 --- a/layout/xul/base/src/tree/src/nsTreeContentView.cpp +++ b/layout/xul/base/src/tree/src/nsTreeContentView.cpp @@ -811,8 +811,7 @@ nsTreeContentView::AttributeChanged(nsIDocument *aDocument, nsIContent* aContent, PRInt32 aNameSpaceID, nsIAtom* aAttribute, - PRInt32 aModType, - PRUint32 aStateMask) + PRInt32 aModType) { // Make sure this notification concerns us. // First check the tag to see if it's one that we care about. diff --git a/layout/xul/base/src/tree/src/nsTreeStyleCache.cpp b/layout/xul/base/src/tree/src/nsTreeStyleCache.cpp index 63e9c2605cb3..58cae4e761b1 100644 --- a/layout/xul/base/src/tree/src/nsTreeStyleCache.cpp +++ b/layout/xul/base/src/tree/src/nsTreeStyleCache.cpp @@ -101,8 +101,8 @@ nsTreeStyleCache::GetStyleContext(nsICSSPseudoComparator* aComparator, if (!result) { // We missed the cache. Resolve this pseudo-style. result = aPresContext->StyleSet()-> - ResolvePseudoStyleFor(aContent, aPseudoElement, - aContext, aComparator).get(); + ResolveXULTreePseudoStyle(aContent, aPseudoElement, + aContext, aComparator).get(); // Put the style context in our table, transferring the owning reference to the table. if (!mCache) { diff --git a/modules/libmar/src/mar.h b/modules/libmar/src/mar.h index 45f46e835a75..2ffd4ddbe97a 100644 --- a/modules/libmar/src/mar.h +++ b/modules/libmar/src/mar.h @@ -40,7 +40,13 @@ #define MAR_H__ /* We use NSPR here just to import the definition of PRUint32 */ +#ifndef WINCE #include "prtypes.h" +#else +typedef int PRInt32; +typedef unsigned int PRUint32; +typedef wchar_t PRUnichar; +#endif #ifdef __cplusplus extern "C" { diff --git a/modules/libpr0n/public/imgIRequest.idl b/modules/libpr0n/public/imgIRequest.idl index 0834035a71a2..0b8e741a5cfb 100644 --- a/modules/libpr0n/public/imgIRequest.idl +++ b/modules/libpr0n/public/imgIRequest.idl @@ -52,7 +52,7 @@ interface nsIPrincipal; * @version 0.1 * @see imagelib2 */ -[scriptable, uuid(c0c9f606-19d6-4ed1-8486-6cae2fe0a6a4)] +[scriptable, uuid(ebde51c9-cc11-4b6a-99c3-d7f568c7481b)] interface imgIRequest : nsIRequest { /** @@ -173,5 +173,11 @@ interface imgIRequest : nsIRequest */ void unlockImage(); + /** + * If this request is for an animated image, the method creates a new + * request which contains the current frame of the image. + * Otherwise returns the same request. + */ + imgIRequest getStaticRequest(); }; diff --git a/modules/libpr0n/src/Makefile.in b/modules/libpr0n/src/Makefile.in index d513e6fa4f7b..d51b7483211f 100644 --- a/modules/libpr0n/src/Makefile.in +++ b/modules/libpr0n/src/Makefile.in @@ -56,7 +56,9 @@ CPPSRCS = \ imgLoader.cpp \ imgRequest.cpp \ imgRequestProxy.cpp \ - imgTools.cpp + imgTools.cpp \ + imgContainerRequest.cpp \ + $(NULL) include $(topsrcdir)/config/rules.mk diff --git a/modules/libpr0n/src/imgContainerRequest.cpp b/modules/libpr0n/src/imgContainerRequest.cpp new file mode 100644 index 000000000000..eb94550124d0 --- /dev/null +++ b/modules/libpr0n/src/imgContainerRequest.cpp @@ -0,0 +1,280 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Olli Pettay (original author) + * + * 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 ***** */ + +#include "imgContainerRequest.h" +#include "ImageErrors.h" +#include "imgRequest.h" + +NS_IMPL_ISUPPORTS2(imgContainerRequest, imgIRequest, nsIRequest) + +imgContainerRequest::imgContainerRequest(imgIContainer* aImage, + nsIURI* aURI, + PRUint32 aImageStatus, + PRUint32 aState, + nsIPrincipal* aPrincipal) +: mImage(aImage), mURI(aURI), mPrincipal(aPrincipal), mImageStatus(aImageStatus), + mState(aState), mLocksHeld(0) +{ +#ifdef DEBUG + PRUint32 numFrames = 0; + if (aImage) { + aImage->GetNumFrames(&numFrames); + } + NS_ABORT_IF_FALSE(!aImage || numFrames == 1, + "Shouldn't have image with more than one frame!"); +#endif +} + +imgContainerRequest::~imgContainerRequest() +{ + if (mImage) { + while (mLocksHeld) { + UnlockImage(); + } + } +} + +NS_IMETHODIMP +imgContainerRequest::GetName(nsACString& aName) +{ + aName.Truncate(); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +imgContainerRequest::IsPending(PRBool* _retval) +{ + *_retval = PR_FALSE; + return NS_OK; +} + +NS_IMETHODIMP +imgContainerRequest::GetStatus(nsresult* aStatus) +{ + *aStatus = NS_OK; + return NS_OK; +} + +NS_IMETHODIMP +imgContainerRequest::Cancel(nsresult aStatus) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +imgContainerRequest::Suspend() +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +imgContainerRequest::Resume() +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +imgContainerRequest::GetLoadGroup(nsILoadGroup** aLoadGroup) +{ + *aLoadGroup = nsnull; + return NS_OK; +} + +NS_IMETHODIMP +imgContainerRequest::SetLoadGroup(nsILoadGroup* aLoadGroup) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +imgContainerRequest::GetLoadFlags(nsLoadFlags* aLoadFlags) +{ + *aLoadFlags = LOAD_NORMAL; + return NS_OK; +} + +NS_IMETHODIMP +imgContainerRequest::SetLoadFlags(nsLoadFlags aLoadFlags) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +imgContainerRequest::GetImage(imgIContainer** aImage) +{ + NS_IF_ADDREF(*aImage = mImage); + return NS_OK; +} + +NS_IMETHODIMP +imgContainerRequest::GetImageStatus(PRUint32* aImageStatus) +{ + *aImageStatus = mImageStatus; + return NS_OK; +} + +NS_IMETHODIMP +imgContainerRequest::GetURI(nsIURI** aURI) +{ + NS_IF_ADDREF(*aURI = mURI); + return NS_OK; +} + +NS_IMETHODIMP +imgContainerRequest::GetDecoderObserver(imgIDecoderObserver** aDecoderObserver) +{ + NS_IF_ADDREF(*aDecoderObserver = mObserver); + return NS_OK; +} + +NS_IMETHODIMP +imgContainerRequest::GetMimeType(char** aMimeType) +{ + *aMimeType = nsnull; + return NS_OK; +} + +NS_IMETHODIMP +imgContainerRequest::Clone(imgIDecoderObserver* aObserver, imgIRequest** _retval) +{ + imgContainerRequest* req = + new imgContainerRequest(mImage, mURI, mImageStatus, mState, mPrincipal); + if (!req) { + return NS_ERROR_OUT_OF_MEMORY; + } + + NS_ADDREF(*_retval = req); + req->mObserver = aObserver; + + nsCOMPtr kungFuDeathGrip(aObserver); + + // Keep these notifications in sync with imgRequest::NotifyProxyListener! + + // OnStartRequest + if (req->mState & stateRequestStarted) + aObserver->OnStartRequest(req); + + // OnStartContainer + if (req->mState & stateHasSize) + aObserver->OnStartContainer(req, req->mImage); + + // OnStartDecode + if (req->mState & stateDecodeStarted) + aObserver->OnStartDecode(req); + + // Send frame messages (OnStartFrame, OnDataAvailable, OnStopFrame) + PRUint32 nframes = 0; + if (req->mImage) + req->mImage->GetNumFrames(&nframes); + + if (nframes > 0) { + PRUint32 frame; + req->mImage->GetCurrentFrameIndex(&frame); + aObserver->OnStartFrame(req, frame); + + // OnDataAvailable + // XXX - Should only send partial rects here, but that needs to + // wait until we fix up the observer interface + nsIntRect r; + req->mImage->GetCurrentFrameRect(r); + aObserver->OnDataAvailable(req, frame, &r); + + if (req->mState & stateRequestStopped) + aObserver->OnStopFrame(req, frame); + } + + // Reseting image animation isn't needed here. + + if (req->mState & stateRequestStopped) { + aObserver->OnStopContainer(req, req->mImage); + aObserver->OnStopDecode(req, + imgRequest::GetResultFromImageStatus(req->mImageStatus), + nsnull); + aObserver->OnStopRequest(req, PR_TRUE); + } + + return NS_OK; +} + +NS_IMETHODIMP +imgContainerRequest::GetImagePrincipal(nsIPrincipal** aImagePrincipal) +{ + NS_IF_ADDREF(*aImagePrincipal = mPrincipal); + return NS_OK; +} + +NS_IMETHODIMP +imgContainerRequest::CancelAndForgetObserver(nsresult aStatus) +{ + return NS_OK; +} + +NS_IMETHODIMP +imgContainerRequest::RequestDecode() +{ + return mImage ? mImage->RequestDecode() : NS_OK; +} + +NS_IMETHODIMP +imgContainerRequest::LockImage() +{ + if (mImage) { + ++mLocksHeld; + return mImage->LockImage(); + } + return NS_OK; +} + +NS_IMETHODIMP +imgContainerRequest::UnlockImage() +{ + if (mImage) { + NS_ABORT_IF_FALSE(mLocksHeld > 0, "calling unlock but no locks!"); + --mLocksHeld; + return mImage->UnlockImage(); + } + return NS_OK; +} + +NS_IMETHODIMP +imgContainerRequest::GetStaticRequest(imgIRequest** aReturn) +{ + NS_ADDREF(*aReturn = this); + return NS_OK; +} + diff --git a/modules/libpr0n/src/imgContainerRequest.h b/modules/libpr0n/src/imgContainerRequest.h new file mode 100644 index 000000000000..b3e035c9413e --- /dev/null +++ b/modules/libpr0n/src/imgContainerRequest.h @@ -0,0 +1,71 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Olli Pettay (original author) + * + * 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 ***** */ + +#ifndef imgContainerRequest_h__ +#define imgContainerRequest_h__ + +#include "imgIRequest.h" +#include "imgIContainer.h" +#include "imgIDecoderObserver.h" +#include "nsIPrincipal.h" +#include "nsIURI.h" + +class imgContainerRequest : public imgIRequest +{ +public: + imgContainerRequest(imgIContainer* aImage, + nsIURI* aURI, + PRUint32 aImageStatus, + PRUint32 aState, + nsIPrincipal* aPrincipal); + virtual ~imgContainerRequest(); + + NS_DECL_ISUPPORTS + NS_DECL_IMGIREQUEST + NS_DECL_NSIREQUEST + +protected: + nsCOMPtr mImage; + nsCOMPtr mURI; + nsCOMPtr mPrincipal; + nsCOMPtr mObserver; + PRUint32 mImageStatus; + PRUint32 mState; + PRUint32 mLocksHeld; +}; +#endif diff --git a/modules/libpr0n/src/imgRequest.cpp b/modules/libpr0n/src/imgRequest.cpp index 643ff4d5e08a..5c19c23791a1 100644 --- a/modules/libpr0n/src/imgRequest.cpp +++ b/modules/libpr0n/src/imgRequest.cpp @@ -45,7 +45,6 @@ #include "imgContainer.h" #include "imgILoader.h" -#include "ImageErrors.h" #include "ImageLogging.h" #include "netCore.h" @@ -255,6 +254,8 @@ nsresult imgRequest::NotifyProxyListener(imgRequestProxy *proxy) { nsCOMPtr kungFuDeathGrip(proxy); + // Keep these notifications in sync with imgContainerRequest::Clone! + // OnStartRequest if (mState & stateRequestStarted) proxy->OnStartRequest(nsnull, nsnull); @@ -305,18 +306,6 @@ nsresult imgRequest::NotifyProxyListener(imgRequestProxy *proxy) return NS_OK; } -nsresult imgRequest::GetResultFromImageStatus(PRUint32 aStatus) const -{ - nsresult rv = NS_OK; - - if (aStatus & imgIRequest::STATUS_ERROR) - rv = NS_IMAGELIB_ERROR_FAILURE; - else if (aStatus & imgIRequest::STATUS_LOAD_COMPLETE) - rv = NS_IMAGELIB_SUCCESS_LOAD_FINISHED; - - return rv; -} - void imgRequest::Cancel(nsresult aStatus) { /* The Cancel() method here should only be called by this class. */ diff --git a/modules/libpr0n/src/imgRequest.h b/modules/libpr0n/src/imgRequest.h index 63cfc94c68c9..84a9ba8f008e 100644 --- a/modules/libpr0n/src/imgRequest.h +++ b/modules/libpr0n/src/imgRequest.h @@ -59,6 +59,8 @@ #include "nsString.h" #include "nsTObserverArray.h" #include "nsWeakReference.h" +#include "ImageErrors.h" +#include "imgIRequest.h" class imgCacheValidator; @@ -118,7 +120,14 @@ public: nsresult LockImage(); nsresult UnlockImage(); nsresult RequestDecode(); - + static nsresult GetResultFromImageStatus(PRUint32 aStatus) + { + if (aStatus & imgIRequest::STATUS_ERROR) + return NS_IMAGELIB_ERROR_FAILURE; + if (aStatus & imgIRequest::STATUS_LOAD_COMPLETE) + return NS_IMAGELIB_SUCCESS_LOAD_FINISHED; + return NS_OK; + } private: friend class imgCacheEntry; friend class imgRequestProxy; @@ -131,7 +140,7 @@ private: mLoadTime = PR_Now(); } inline PRUint32 GetImageStatus() const { return mImageStatus; } - inline nsresult GetResultFromImageStatus(PRUint32 aStatus) const; + inline PRUint32 GetState() const { return mState; } void Cancel(nsresult aStatus); nsresult GetURI(nsIURI **aURI); nsresult GetKeyURI(nsIURI **aURI); diff --git a/modules/libpr0n/src/imgRequestProxy.cpp b/modules/libpr0n/src/imgRequestProxy.cpp index 398e0781f07b..b8450d6ef4ad 100644 --- a/modules/libpr0n/src/imgRequestProxy.cpp +++ b/modules/libpr0n/src/imgRequestProxy.cpp @@ -53,7 +53,7 @@ #include "ImageLogging.h" #include "nspr.h" - +#include "imgContainerRequest.h" NS_IMPL_ISUPPORTS4(imgRequestProxy, imgIRequest, nsIRequest, nsISupportsPriority, nsISecurityInfoProvider) @@ -673,3 +673,47 @@ void imgRequestProxy::NullOutListener() mListener = nsnull; } } + +NS_IMETHODIMP +imgRequestProxy::GetStaticRequest(imgIRequest** aReturn) +{ + *aReturn = nsnull; + nsCOMPtr img, currentFrame; + GetImage(getter_AddRefs(img)); + if (img) { + PRBool animated = PR_FALSE; + nsresult rv = img->GetAnimated(&animated); + if (NS_SUCCEEDED(rv) && !animated) { + NS_ADDREF(*aReturn = this); + return NS_OK; + } + + PRInt32 w = 0; + PRInt32 h = 0; + img->GetWidth(&w); + img->GetHeight(&h); + nsIntRect rect(0, 0, w, h); + img->ExtractFrame(imgIContainer::FRAME_CURRENT, rect, + imgIContainer::FLAG_SYNC_DECODE, + getter_AddRefs(currentFrame)); + } + + nsCOMPtr uri; + GetURI(getter_AddRefs(uri)); + PRUint32 imageStatus = 0; + GetImageStatus(&imageStatus); + nsCOMPtr principal; + GetImagePrincipal(getter_AddRefs(principal)); + + imgContainerRequest* req = + new imgContainerRequest(currentFrame, uri, imageStatus, + mOwner ? mOwner->GetState() : 0, + principal); + if (!req) { + return NS_ERROR_OUT_OF_MEMORY; + } + + NS_ADDREF(*aReturn = req); + return NS_OK; +} + diff --git a/modules/libpref/src/init/all.js b/modules/libpref/src/init/all.js index dc7397ab3422..db58a86c31cc 100644 --- a/modules/libpref/src/init/all.js +++ b/modules/libpref/src/init/all.js @@ -2824,3 +2824,12 @@ pref("geo.enabled", true); pref("html5.enable", false); // Toggle which thread the HTML5 parser uses for streama parsing pref("html5.offmainthread", true); +// Time in milliseconds between the start of the network stream and the +// first time the flush timer fires in the off-the-main-thread HTML5 parser. +pref("html5.flushtimer.startdelay", 200); +// Time in milliseconds between the return to non-speculating more and the +// first time the flush timer fires thereafter. +pref("html5.flushtimer.continuedelay", 150); +// Time in milliseconds between timer firings once the timer has starting +// firing. +pref("html5.flushtimer.interval", 100); diff --git a/netwerk/base/public/nsIStreamLoader.idl b/netwerk/base/public/nsIStreamLoader.idl index 1a9995c8e65d..4e8fc9dc8047 100644 --- a/netwerk/base/public/nsIStreamLoader.idl +++ b/netwerk/base/public/nsIStreamLoader.idl @@ -59,8 +59,8 @@ interface nsIStreamLoaderObserver : nsISupports * If the observer wants to take over responsibility for the * data buffer (result), it returns NS_SUCCESS_ADOPTED_DATA * in place of NS_OK as its success code. The loader will then - * "forget" about the data, and not free() it in its own - * destructor; observer must call free() when the data is + * "forget" about the data, and not NS_Free() it in its own + * destructor; observer must call NS_Free() when the data is * no longer required. */ void onStreamComplete(in nsIStreamLoader loader, diff --git a/netwerk/base/src/nsStreamLoader.cpp b/netwerk/base/src/nsStreamLoader.cpp index 01bee7a69f9b..7878a07641fd 100644 --- a/netwerk/base/src/nsStreamLoader.cpp +++ b/netwerk/base/src/nsStreamLoader.cpp @@ -40,8 +40,6 @@ #include "nsIChannel.h" #include "nsNetError.h" -#include - nsStreamLoader::nsStreamLoader() : mData(nsnull), mAllocated(0), @@ -52,7 +50,7 @@ nsStreamLoader::nsStreamLoader() nsStreamLoader::~nsStreamLoader() { if (mData) { - ::free(mData); + NS_Free(mData); } } @@ -105,7 +103,7 @@ nsStreamLoader::OnStartRequest(nsIRequest* request, nsISupports *ctxt) chan->GetContentLength(&contentLength); if (contentLength >= 0) { // preallocate buffer - mData = static_cast(::malloc(contentLength)); + mData = static_cast(NS_Alloc(contentLength)); if (!mData) { return NS_ERROR_OUT_OF_MEMORY; } @@ -150,13 +148,13 @@ nsStreamLoader::WriteSegmentFun(nsIInputStream *inStr, { nsStreamLoader *self = (nsStreamLoader *) closure; - if (count > 0xffffffffU - self->mLength) { + if (count > PR_UINT32_MAX - self->mLength) { return NS_ERROR_ILLEGAL_VALUE; // is there a better error to use here? } if (self->mLength + count > self->mAllocated) { - self->mData = static_cast(::realloc(self->mData, - self->mLength + count)); + self->mData = static_cast(NS_Realloc(self->mData, + self->mLength + count)); if (!self->mData) { self->mLength = 0; self->mAllocated = 0; diff --git a/netwerk/base/src/nsStreamLoader.h b/netwerk/base/src/nsStreamLoader.h index 6b091eb79861..e9290a9f1a84 100644 --- a/netwerk/base/src/nsStreamLoader.h +++ b/netwerk/base/src/nsStreamLoader.h @@ -65,9 +65,11 @@ protected: nsCOMPtr mContext; // the observer's context nsCOMPtr mRequest; - PRUint8 *mData; - PRUint32 mAllocated; - PRUint32 mLength; + PRUint8 *mData; // buffer to accumulate incoming data + PRUint32 mAllocated; // allocated size of data buffer (we preallocate if + // contentSize is available) + PRUint32 mLength; // actual length of data in buffer + // (must be <= mAllocated) }; #endif // nsStreamLoader_h__ diff --git a/netwerk/dns/src/effective_tld_names.dat b/netwerk/dns/src/effective_tld_names.dat index 2a1ca7a1ace0..7b27f4984e91 100644 --- a/netwerk/dns/src/effective_tld_names.dat +++ b/netwerk/dns/src/effective_tld_names.dat @@ -678,6 +678,9 @@ us.com uy.com za.com +// Requested by Yngve Pettersen 2009-11-26 +operaunite.com + // coop : http://en.wikipedia.org/wiki/.coop coop @@ -807,6 +810,8 @@ fi // completely removed. // TODO: Check for updates (expected to be phased out around Q1/2009) aland.fi +// iki.fi : Submitted by Hannu Aronsson 2009-11-05 +iki.fi // fj : http://en.wikipedia.org/wiki/.fj *.fj @@ -2408,7 +2413,22 @@ zoology.museum иком.museum // mv : http://en.wikipedia.org/wiki/.mv -*.mv +// "mv" included because, contra Wikipedia, google.mv exists. +mv +aero.mv +biz.mv +com.mv +coop.mv +edu.mv +gov.mv +info.mv +int.mv +mil.mv +museum.mv +name.mv +net.mv +org.mv +pro.mv // mw : http://www.registrar.mw/ mw diff --git a/nsprpub/build/autoconf/config.sub b/nsprpub/build/autoconf/config.sub index 2d91b11c7f30..724382959124 100755 --- a/nsprpub/build/autoconf/config.sub +++ b/nsprpub/build/autoconf/config.sub @@ -1,9 +1,10 @@ #! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 +# Free Software Foundation, Inc. -timestamp='2005-10-13' +timestamp='2009-12-04' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software @@ -31,13 +32,16 @@ timestamp='2005-10-13' # Please send patches to . Submit a context -# diff and a properly formatted ChangeLog entry. +# diff and a properly formatted GNU ChangeLog entry. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD + # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. @@ -71,8 +75,8 @@ Report bugs and patches to ." version="\ GNU config.sub ($timestamp) -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 -Free Software Foundation, Inc. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -119,8 +123,10 @@ esac # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in - nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \ - kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*) + nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ + uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ + kopensolaris*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova* | wince-winmo*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; @@ -146,10 +152,13 @@ case $os in -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ - -apple | -axis | -knuth | -cray) + -apple | -axis | -knuth | -cray | -microblaze) os= basic_machine=$1 ;; + -bluegene*) + os=-cnk + ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 @@ -171,6 +180,10 @@ case $os in -hiux*) os=-hiuxwe2 ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` @@ -187,6 +200,10 @@ case $os in # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` @@ -226,28 +243,29 @@ esac case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. -#### MozillaHack -# mips*el -#### End MozillaHack 1750a | 580 \ | a29k \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ - | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ | bfin \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ - | fr30 | frv \ + | fido | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ - | m32r | m32rle | m68000 | m68k | m88k | maxq | mcore \ - | mips | mipsbe | mipseb | mips*el | mipsle \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ - | mips64vr | mips64vrel \ + | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ @@ -260,26 +278,26 @@ case $basic_machine in | mipsisa64sr71k | mipsisa64sr71kel \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ - | ms1 \ + | moxie \ + | mt \ | msp430 \ + | nios | nios2 \ | ns16k | ns32k \ | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ | pyramid \ - | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ - | sparc | sparc64 | sparc64b | sparc86x | sparclet | sparclite \ - | sparcv8 | sparcv9 | sparcv9b \ - | strongarm \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu | strongarm \ | tahoe | thumb | tic4x | tic80 | tron \ | v850 | v850e \ | we32k \ - | x86 | xscale | xscalee[bl] | xstormy16 | xtensa \ - | z8k) - basic_machine=$basic_machine-unknown - ;; - m32c) + | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ + | z8k | z80) basic_machine=$basic_machine-unknown ;; m6811 | m68hc11 | m6812 | m68hc12) @@ -289,6 +307,9 @@ case $basic_machine in ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; + ms1) + basic_machine=mt-unknown + ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and @@ -302,34 +323,34 @@ case $basic_machine in exit 1 ;; # Recognize the basic CPU types with company name. -#### MozillaHack -# mips*el -#### End MozillaHack 580-* \ | a29k-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ - | avr-* \ + | avr-* | avr32-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ - | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ - | m32r-* | m32rle-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | maxq-* | mcore-* \ - | mips-* | mipsbe-* | mipseb-* | mips*el-* | mipsle-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ - | mips64vr-* | mips64vrel-* \ + | mips64octeon-* | mips64octeonel-* \ | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ @@ -342,30 +363,33 @@ case $basic_machine in | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ - | ms1-* \ + | mt-* \ | msp430-* \ + | nios-* | nios2-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ | pyramid-* \ | romp-* | rs6000-* \ - | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | shbe-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ - | sparc-* | sparc64-* | sparc64b-* | sparc86x-* | sparclet-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ - | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ | tahoe-* | thumb-* \ - | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \ | tron-* \ | v850-* | v850e-* | vax-* \ | we32k-* \ - | x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \ - | xstormy16-* | xtensa-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ + | xstormy16-* | xtensa*-* \ | ymp-* \ - | z8k-*) + | z8k-* | z80-*) ;; - m32c-*) + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. @@ -429,6 +453,10 @@ case $basic_machine in basic_machine=m68k-apollo os=-bsd ;; + aros) + basic_machine=i386-pc + os=-aros + ;; aux) basic_machine=m68k-apple os=-aux @@ -437,10 +465,26 @@ case $basic_machine in basic_machine=ns32k-sequent os=-dynix ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; c90) basic_machine=c90-cray os=-unicos ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; convex-c1) basic_machine=c1-convex os=-bsd @@ -469,8 +513,8 @@ case $basic_machine in basic_machine=craynv-cray os=-unicosmp ;; - cr16c) - basic_machine=cr16c-unknown + cr16) + basic_machine=cr16-unknown os=-elf ;; crds | unos) @@ -508,6 +552,10 @@ case $basic_machine in basic_machine=m88k-motorola os=-sysv3 ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp @@ -662,6 +710,14 @@ case $basic_machine in basic_machine=m68k-isi os=-sysv ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; m88k-omron*) basic_machine=m88k-omron ;; @@ -673,16 +729,17 @@ case $basic_machine in basic_machine=ns32k-utek os=-sysv ;; + microblaze) + basic_machine=microblaze-xilinx + ;; mingw32) basic_machine=i386-pc os=-mingw32 ;; -#### MozillaHack - i386-msvc | msvc) - basic_machine=i386-pc - os=-msvc + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce ;; -#### End MozillaHack miniframe) basic_machine=m68000-convergent ;; @@ -708,6 +765,9 @@ case $basic_machine in basic_machine=i386-pc os=-msdos ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; mvs) basic_machine=i370-ibm os=-mvs @@ -806,6 +866,14 @@ case $basic_machine in basic_machine=i860-intel os=-osf ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; pbd) basic_machine=sparc-tti ;; @@ -815,6 +883,12 @@ case $basic_machine in pc532 | pc532-*) basic_machine=ns32k-pc532 ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; @@ -871,6 +945,10 @@ case $basic_machine in basic_machine=i586-unknown os=-pw32 ;; + rdos) + basic_machine=i386-pc + os=-rdos + ;; rom68k) basic_machine=m68k-rom68k os=-coff @@ -897,6 +975,10 @@ case $basic_machine in sb1el) basic_machine=mipsisa64sb1el-unknown ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; sei) basic_machine=mips-sei os=-seiux @@ -908,6 +990,9 @@ case $basic_machine in basic_machine=sh-hitachi os=-hms ;; + sh5el) + basic_machine=sh5le-unknown + ;; sh64) basic_machine=sh64-unknown ;; @@ -997,6 +1082,10 @@ case $basic_machine in basic_machine=tic6x-unknown os=-coff ;; + tile*) + basic_machine=tile-unknown + os=-linux-gnu + ;; tx39) basic_machine=mipstx39-unknown ;; @@ -1072,6 +1161,10 @@ case $basic_machine in basic_machine=z8k-unknown os=-sim ;; + z80-*-coff) + basic_machine=z80-unknown + os=-sim + ;; none) basic_machine=none-none os=-none @@ -1110,10 +1203,10 @@ case $basic_machine in we32k) basic_machine=we32k-att ;; - sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele) + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; - sparc | sparcv8 | sparcv9 | sparcv9b) + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) basic_machine=sparc-sun ;; cydra) @@ -1179,32 +1272,31 @@ case $os in # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -#### MozillaHack -# msvc -#### End MozillaHack -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ - | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -kopensolaris* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ - | -aos* \ + | -aos* | -aros* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -openbsd* | -solidbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ - | -chorusos* | -chorusrdb* \ + | -chorusos* | -chorusrdb* | -cegcc* \ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ - | -msvc* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ - | -skyos* | -haiku*) + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -winmo*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) @@ -1246,6 +1338,9 @@ case $os in -os400*) os=-os400 ;; + -wince-winmo*) + os=-wince-winmo + ;; -wince*) os=-wince ;; @@ -1334,6 +1429,9 @@ case $os in -zvmoe) os=-zvmoe ;; + -dicos*) + os=-dicos + ;; -none) ;; *) @@ -1356,6 +1454,12 @@ else # system, and we'll never get to this point. case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; *-acorn) os=-riscix1.2 ;; @@ -1365,9 +1469,9 @@ case $basic_machine in arm*-semi) os=-aout ;; - c4x-* | tic4x-*) - os=-coff - ;; + c4x-* | tic4x-*) + os=-coff + ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 @@ -1393,6 +1497,9 @@ case $basic_machine in m68*-cisco) os=-aout ;; + mep-*) + os=-elf + ;; mips*-cisco) os=-elf ;; @@ -1522,7 +1629,7 @@ case $basic_machine in -sunos*) vendor=sun ;; - -aix*) + -cnk*|-aix*) vendor=ibm ;; -beos*) diff --git a/nsprpub/config/prdepend.h b/nsprpub/config/prdepend.h index 55444c40b3aa..df72c56882d2 100644 --- a/nsprpub/config/prdepend.h +++ b/nsprpub/config/prdepend.h @@ -42,4 +42,3 @@ */ #error "Do not include this header file." - diff --git a/nsprpub/config/rules.mk b/nsprpub/config/rules.mk index 9840c6dc0a7f..eed1a19232d9 100644 --- a/nsprpub/config/rules.mk +++ b/nsprpub/config/rules.mk @@ -112,7 +112,7 @@ ifeq (,$(filter-out WINNT WINCE OS2,$(OS_ARCH))) # Win95 and OS/2 require library names conforming to the 8.3 rule. # other platforms do not. # -ifeq (,$(filter-out WIN95 WINCE OS2,$(OS_TARGET))) +ifeq (,$(filter-out WIN95 WINCE WINMO OS2,$(OS_TARGET))) LIBRARY = $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION)_s.$(LIB_SUFFIX) SHARED_LIBRARY = $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION).$(DLL_SUFFIX) IMPORT_LIBRARY = $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION).$(LIB_SUFFIX) @@ -305,7 +305,7 @@ $(IMPORT_LIBRARY): $(MAPFILE) rm -f $@ $(IMPLIB) $@ $(MAPFILE) else -ifeq (,$(filter-out WIN95 WINCE,$(OS_TARGET))) +ifeq (,$(filter-out WIN95 WINCE WINMO,$(OS_TARGET))) $(IMPORT_LIBRARY): $(SHARED_LIBRARY) endif endif diff --git a/nsprpub/configure b/nsprpub/configure index 24b937ed3549..eaf339efa588 100755 --- a/nsprpub/configure +++ b/nsprpub/configure @@ -1113,7 +1113,7 @@ EOF beos*) DEFINES="$DEFINES -DDEBUG_${USER}" ;; - msvc*|mks*|cygwin*|mingw*|wince*|os2*) + msvc*|mks*|cygwin*|mingw*|wince*|winmo*|os2*) DEFINES="$DEFINES -DDEBUG_`echo ${USERNAME} | sed -e 's| |_|g'`" ;; *) @@ -2787,6 +2787,7 @@ if test -n "$CROSS_COMPILE"; then solaris*) OS_ARCH=SunOS OS_RELEASE=5 ;; mingw*) OS_ARCH=WINNT ;; wince*) OS_ARCH=WINCE ;; + winmo*) OS_ARCH=WINCE ;; darwin*) OS_ARCH=Darwin ;; riscos*) OS_ARCH=RISCOS ;; esac @@ -2941,7 +2942,7 @@ case "$host" in *-mingw*) NSINSTALL=nsinstall ;; -*-cygwin*|*-msvc*|*-mks*|*-wince*) +*-cygwin*|*-msvc*|*-mks*|*-wince*|*-winmo*) NSINSTALL='$(CYGWIN_WRAPPER) nsinstall' if test `echo "${PATH}" | grep -c \;` = 0; then CYGWIN_WRAPPER='sh $(topsrcdir)/build/cygwin-wrapper' @@ -2975,17 +2976,17 @@ EOF DSO_LDOPTS='-brtl -bnortllib -bM:SRE -bnoentry -bexpall -blibpath:/usr/lib:/lib' ac_safe=`echo "sys/atomic_op.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for sys/atomic_op.h""... $ac_c" 1>&6 -echo "configure:2979: checking for sys/atomic_op.h" >&5 +echo "configure:2980: checking for sys/atomic_op.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2989: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2990: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -3142,7 +3143,7 @@ EOF _DEBUG_FLAGS='-gdwarf-2 -O0' MKSHLIB='$(CCC) $(DSO_LDOPTS) -o $@' echo $ac_n "checking for gethostbyaddr in -lbind""... $ac_c" 1>&6 -echo "configure:3146: checking for gethostbyaddr in -lbind" >&5 +echo "configure:3147: checking for gethostbyaddr in -lbind" >&5 ac_lib_var=`echo bind'_'gethostbyaddr | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -3150,7 +3151,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lbind $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:3166: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -4193,7 +4194,7 @@ EOF ;; -*-wince*) +*-wince*|*-winmo*) cat >> confdefs.h <<\EOF #define XP_PC 1 EOF @@ -4507,17 +4508,17 @@ EOF _OPTIMIZE_FLAGS="$_OPTIMIZE_FLAGS -Olimit 4000" ac_safe=`echo "machine/builtins.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for machine/builtins.h""... $ac_c" 1>&6 -echo "configure:4511: checking for machine/builtins.h" >&5 +echo "configure:4512: checking for machine/builtins.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:4521: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:4522: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -5166,7 +5167,7 @@ case $target in ;; *) echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6 -echo "configure:5170: checking for dlopen in -ldl" >&5 +echo "configure:5171: checking for dlopen in -ldl" >&5 ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -5174,7 +5175,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ldl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5190: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -5202,17 +5203,17 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_safe=`echo "dlfcn.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for dlfcn.h""... $ac_c" 1>&6 -echo "configure:5206: checking for dlfcn.h" >&5 +echo "configure:5207: checking for dlfcn.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:5216: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:5217: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -5245,13 +5246,13 @@ esac if test $ac_cv_prog_gcc = yes; then echo $ac_n "checking whether ${CC-cc} needs -traditional""... $ac_c" 1>&6 -echo "configure:5249: checking whether ${CC-cc} needs -traditional" >&5 +echo "configure:5250: checking whether ${CC-cc} needs -traditional" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc_traditional'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_pattern="Autoconf.*'x'" cat > conftest.$ac_ext < Autoconf TIOCGETP @@ -5269,7 +5270,7 @@ rm -f conftest* if test $ac_cv_prog_gcc_traditional = no; then cat > conftest.$ac_ext < Autoconf TCGETA @@ -5293,12 +5294,12 @@ fi for ac_func in lchown strerror do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5297: checking for $ac_func" >&5 +echo "configure:5298: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5326: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5362,7 +5363,7 @@ hpux*) if test -z "$GNU_CC"; then echo $ac_n "checking for +Olit support""... $ac_c" 1>&6 -echo "configure:5366: checking for +Olit support" >&5 +echo "configure:5367: checking for +Olit support" >&5 if eval "test \"`echo '$''{'ac_cv_hpux_usable_olit_option'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -5401,7 +5402,7 @@ darwin*) *) echo $ac_n "checking for pthread_create in -lpthreads""... $ac_c" 1>&6 -echo "configure:5405: checking for pthread_create in -lpthreads" >&5 +echo "configure:5406: checking for pthread_create in -lpthreads" >&5 echo " #include void *foo(void *v) { return v; } @@ -5423,7 +5424,7 @@ echo " echo "$ac_t""no" 1>&6 echo $ac_n "checking for pthread_create in -lpthread""... $ac_c" 1>&6 -echo "configure:5427: checking for pthread_create in -lpthread" >&5 +echo "configure:5428: checking for pthread_create in -lpthread" >&5 echo " #include void *foo(void *v) { return v; } @@ -5445,7 +5446,7 @@ echo " echo "$ac_t""no" 1>&6 echo $ac_n "checking for pthread_create in -lc_r""... $ac_c" 1>&6 -echo "configure:5449: checking for pthread_create in -lc_r" >&5 +echo "configure:5450: checking for pthread_create in -lc_r" >&5 echo " #include void *foo(void *v) { return v; } @@ -5467,7 +5468,7 @@ echo " echo "$ac_t""no" 1>&6 echo $ac_n "checking for pthread_create in -lc""... $ac_c" 1>&6 -echo "configure:5471: checking for pthread_create in -lc" >&5 +echo "configure:5472: checking for pthread_create in -lc" >&5 echo " #include void *foo(void *v) { return v; } @@ -5599,7 +5600,7 @@ if test -n "$USE_PTHREADS"; then rm -f conftest* ac_cv_have_dash_pthread=no echo $ac_n "checking whether ${CC-cc} accepts -pthread""... $ac_c" 1>&6 -echo "configure:5603: checking whether ${CC-cc} accepts -pthread" >&5 +echo "configure:5604: checking whether ${CC-cc} accepts -pthread" >&5 echo 'int main() { return 0; }' | cat > conftest.c ${CC-cc} -pthread -o conftest conftest.c > conftest.out 2>&1 if test $? -eq 0; then @@ -5622,7 +5623,7 @@ echo "configure:5603: checking whether ${CC-cc} accepts -pthread" >&5 ac_cv_have_dash_pthreads=no if test "$ac_cv_have_dash_pthread" = "no"; then echo $ac_n "checking whether ${CC-cc} accepts -pthreads""... $ac_c" 1>&6 -echo "configure:5626: checking whether ${CC-cc} accepts -pthreads" >&5 +echo "configure:5627: checking whether ${CC-cc} accepts -pthreads" >&5 echo 'int main() { return 0; }' | cat > conftest.c ${CC-cc} -pthreads -o conftest conftest.c > conftest.out 2>&1 if test $? -eq 0; then @@ -5821,7 +5822,7 @@ EOF fi ;; -*-mingw*|*-cygwin*|*-msvc*|*-mks*|*-wince*|*-os2*|*-beos*) +*-mingw*|*-cygwin*|*-msvc*|*-mks*|*-wince*|*-winmo*|*-os2*|*-beos*) USE_PTHREADS= _PTHREAD_LDFLAGS= USE_USER_PTHREADS= diff --git a/nsprpub/configure.in b/nsprpub/configure.in index 7c1f2b088eed..75039b9ecc83 100644 --- a/nsprpub/configure.in +++ b/nsprpub/configure.in @@ -380,7 +380,7 @@ if test -n "$MOZ_DEBUG"; then beos*) DEFINES="$DEFINES -DDEBUG_${USER}" ;; - msvc*|mks*|cygwin*|mingw*|wince*|os2*) + msvc*|mks*|cygwin*|mingw*|wince*|winmo*|os2*) DEFINES="$DEFINES -DDEBUG_`echo ${USERNAME} | sed -e 's| |_|g'`" ;; *) @@ -648,6 +648,7 @@ if test -n "$CROSS_COMPILE"; then solaris*) OS_ARCH=SunOS OS_RELEASE=5 ;; mingw*) OS_ARCH=WINNT ;; wince*) OS_ARCH=WINCE ;; + winmo*) OS_ARCH=WINCE ;; darwin*) OS_ARCH=Darwin ;; riscos*) OS_ARCH=RISCOS ;; esac @@ -805,7 +806,7 @@ case "$host" in *-mingw*) NSINSTALL=nsinstall ;; -*-cygwin*|*-msvc*|*-mks*|*-wince*) +*-cygwin*|*-msvc*|*-mks*|*-wince*|*-winmo*) NSINSTALL='$(CYGWIN_WRAPPER) nsinstall' if test `echo "${PATH}" | grep -c \;` = 0; then CYGWIN_WRAPPER='sh $(topsrcdir)/build/cygwin-wrapper' @@ -1657,7 +1658,7 @@ tools are selected during the Xcode/Developer Tools installation.]) ;; -*-wince*) +*-wince*|*-winmo*) AC_DEFINE(XP_PC) AC_DEFINE(WIN32) AC_DEFINE(WINCE) @@ -2668,7 +2669,7 @@ case "$target" in AC_DEFINE(_PR_LOCAL_THREADS_ONLY) fi ;; -*-mingw*|*-cygwin*|*-msvc*|*-mks*|*-wince*|*-os2*|*-beos*) +*-mingw*|*-cygwin*|*-msvc*|*-mks*|*-wince*|*-winmo*|*-os2*|*-beos*) dnl win32, wince, os2 & beos cannot use pthreads USE_PTHREADS= _PTHREAD_LDFLAGS= diff --git a/nsprpub/pr/src/Makefile.in b/nsprpub/pr/src/Makefile.in index a3bf4c3a72f3..99f67c67e810 100644 --- a/nsprpub/pr/src/Makefile.in +++ b/nsprpub/pr/src/Makefile.in @@ -201,7 +201,7 @@ OS_LIBS = advapi32.lib wsock32.lib winmm.lib endif endif -ifeq ($(OS_TARGET),WINCE) +ifeq ($(OS_ARCH),WINCE) OS_LIBS = ws2.lib endif diff --git a/nsprpub/pr/src/md/windows/Makefile.in b/nsprpub/pr/src/md/windows/Makefile.in index 6f16ecc92134..235b85aeda40 100644 --- a/nsprpub/pr/src/md/windows/Makefile.in +++ b/nsprpub/pr/src/md/windows/Makefile.in @@ -46,7 +46,7 @@ include $(MOD_DEPTH)/config/autoconf.mk include $(topsrcdir)/config/config.mk -ifeq (,$(filter-out WIN95 WINCE, $(OS_TARGET))) +ifeq (,$(filter-out WIN95 WINCE WINMO, $(OS_TARGET))) CSRCS = \ ntmisc.c \ ntsec.c \ diff --git a/nsprpub/pr/src/md/windows/objs.mk b/nsprpub/pr/src/md/windows/objs.mk index 5167246ed383..82ee36ecec95 100644 --- a/nsprpub/pr/src/md/windows/objs.mk +++ b/nsprpub/pr/src/md/windows/objs.mk @@ -51,7 +51,7 @@ CSRCS = ntmisc.c \ w32rng.c \ w32shm.c else -ifeq (,$(filter-out WIN95 WINCE, $(OS_TARGET))) +ifeq (,$(filter-out WIN95 WINCE WINMO, $(OS_TARGET))) CSRCS = ntmisc.c \ ntsec.c \ ntsem.c \ diff --git a/nsprpub/pr/tests/runtests.pl b/nsprpub/pr/tests/runtests.pl index 11438266b25e..d4e1588f8dfd 100755 --- a/nsprpub/pr/tests/runtests.pl +++ b/nsprpub/pr/tests/runtests.pl @@ -170,7 +170,7 @@ $ltimeout = shift; # timeout # No timeout: use blocking wait $ret = waitpid($lpid,0); # Exit and don't kill - $lstatus = $? % 256; + $lstatus = $?; $ltimeout = -1; } else { while ($ltimeout > 0) { diff --git a/parser/html/java/named-character-references.html b/parser/html/java/named-character-references.html index ea4ade1d9220..c8d1e08daf0b 100644 --- a/parser/html/java/named-character-references.html +++ b/parser/html/java/named-character-references.html @@ -1,168 +1,7 @@ - -HTML 5 - - -
-

W3C

-

HTML 5

-

A vocabulary and associated APIs for HTML and XHTML

-
- -

8.6 Named character references

This table lists the character reference names that are supported - by HTML, and the code points to which they refer. It is referenced - by the previous sections.

-
Name Character
AElig; U+000C6
AElig U+000C6
AMP; U+00026
AMP U+00026
Aacute; U+000C1
Aacute U+000C1
Abreve; U+00102
Acirc; U+000C2
Acirc U+000C2
Acy; U+00410
Afr; U+1D504
Agrave; U+000C0
Agrave U+000C0
Alpha; U+00391
Amacr; U+00100
And; U+02A53
Aogon; U+00104
Aopf; U+1D538
ApplyFunction; U+02061
Aring; U+000C5
Aring U+000C5
Ascr; U+1D49C
Assign; U+02254
Atilde; U+000C3
Atilde U+000C3
Auml; U+000C4
Auml U+000C4
Backslash; U+02216
Barv; U+02AE7
Barwed; U+02306
Bcy; U+00411
Because; U+02235
Bernoullis; U+0212C
Beta; U+00392
Bfr; U+1D505
Bopf; U+1D539
Breve; U+002D8
Bscr; U+0212C
Bumpeq; U+0224E
CHcy; U+00427
COPY; U+000A9
COPY U+000A9
Cacute; U+00106
Cap; U+022D2
CapitalDifferentialD; U+02145
Cayleys; U+0212D
Ccaron; U+0010C
Ccedil; U+000C7
Ccedil U+000C7
Ccirc; U+00108
Cconint; U+02230
Cdot; U+0010A
Cedilla; U+000B8
CenterDot; U+000B7
Cfr; U+0212D
Chi; U+003A7
CircleDot; U+02299
CircleMinus; U+02296
CirclePlus; U+02295
CircleTimes; U+02297
ClockwiseContourIntegral; U+02232
CloseCurlyDoubleQuote; U+0201D
CloseCurlyQuote; U+02019
Colon; U+02237
Colone; U+02A74
Congruent; U+02261
Conint; U+0222F
ContourIntegral; U+0222E
Copf; U+02102
Coproduct; U+02210
CounterClockwiseContourIntegral; U+02233
Cross; U+02A2F
Cscr; U+1D49E
Cup; U+022D3
CupCap; U+0224D
DD; U+02145
DDotrahd; U+02911
DJcy; U+00402
DScy; U+00405
DZcy; U+0040F
Dagger; U+02021
Darr; U+021A1
Dashv; U+02AE4
Dcaron; U+0010E
Dcy; U+00414
Del; U+02207
Delta; U+00394
Dfr; U+1D507
DiacriticalAcute; U+000B4
DiacriticalDot; U+002D9
DiacriticalDoubleAcute; U+002DD
DiacriticalGrave; U+00060
DiacriticalTilde; U+002DC
Diamond; U+022C4
DifferentialD; U+02146
Dopf; U+1D53B
Dot; U+000A8
DotDot; U+020DC
DotEqual; U+02250
DoubleContourIntegral; U+0222F
DoubleDot; U+000A8
DoubleDownArrow; U+021D3
DoubleLeftArrow; U+021D0
DoubleLeftRightArrow; U+021D4
DoubleLeftTee; U+02AE4
DoubleLongLeftArrow; U+027F8
DoubleLongLeftRightArrow; U+027FA
DoubleLongRightArrow; U+027F9
DoubleRightArrow; U+021D2
DoubleRightTee; U+022A8
DoubleUpArrow; U+021D1
DoubleUpDownArrow; U+021D5
DoubleVerticalBar; U+02225
DownArrow; U+02193
DownArrowBar; U+02913
DownArrowUpArrow; U+021F5
DownBreve; U+00311
DownLeftRightVector; U+02950
DownLeftTeeVector; U+0295E
DownLeftVector; U+021BD
DownLeftVectorBar; U+02956
DownRightTeeVector; U+0295F
DownRightVector; U+021C1
DownRightVectorBar; U+02957
DownTee; U+022A4
DownTeeArrow; U+021A7
Downarrow; U+021D3
Dscr; U+1D49F
Dstrok; U+00110
ENG; U+0014A
ETH; U+000D0
ETH U+000D0
Eacute; U+000C9
Eacute U+000C9
Ecaron; U+0011A
Ecirc; U+000CA
Ecirc U+000CA
Ecy; U+0042D
Edot; U+00116
Efr; U+1D508
Egrave; U+000C8
Egrave U+000C8
Element; U+02208
Emacr; U+00112
EmptySmallSquare; U+025FB
EmptyVerySmallSquare; U+025AB
Eogon; U+00118
Eopf; U+1D53C
Epsilon; U+00395
Equal; U+02A75
EqualTilde; U+02242
Equilibrium; U+021CC
Escr; U+02130
Esim; U+02A73
Eta; U+00397
Euml; U+000CB
Euml U+000CB
Exists; U+02203
ExponentialE; U+02147
Fcy; U+00424
Ffr; U+1D509
FilledSmallSquare; U+025FC
FilledVerySmallSquare; U+025AA
Fopf; U+1D53D
ForAll; U+02200
Fouriertrf; U+02131
Fscr; U+02131
GJcy; U+00403
GT; U+0003E
GT U+0003E
Gamma; U+00393
Gammad; U+003DC
Gbreve; U+0011E
Gcedil; U+00122
Gcirc; U+0011C
Gcy; U+00413
Gdot; U+00120
Gfr; U+1D50A
Gg; U+022D9
Gopf; U+1D53E
GreaterEqual; U+02265
GreaterEqualLess; U+022DB
GreaterFullEqual; U+02267
GreaterGreater; U+02AA2
GreaterLess; U+02277
GreaterSlantEqual; U+02A7E
GreaterTilde; U+02273
Gscr; U+1D4A2
Gt; U+0226B
HARDcy; U+0042A
Hacek; U+002C7
Hat; U+0005E
Hcirc; U+00124
Hfr; U+0210C
HilbertSpace; U+0210B
Hopf; U+0210D
HorizontalLine; U+02500
Hscr; U+0210B
Hstrok; U+00126
HumpDownHump; U+0224E
HumpEqual; U+0224F
IEcy; U+00415
IJlig; U+00132
IOcy; U+00401
Iacute; U+000CD
Iacute U+000CD
Icirc; U+000CE
Icirc U+000CE
Icy; U+00418
Idot; U+00130
Ifr; U+02111
Igrave; U+000CC
Igrave U+000CC
Im; U+02111
Imacr; U+0012A
ImaginaryI; U+02148
Implies; U+021D2
Int; U+0222C
Integral; U+0222B
Intersection; U+022C2
InvisibleComma; U+02063
InvisibleTimes; U+02062
Iogon; U+0012E
Iopf; U+1D540
Iota; U+00399
Iscr; U+02110
Itilde; U+00128
Iukcy; U+00406
Iuml; U+000CF
Iuml U+000CF
Jcirc; U+00134
Jcy; U+00419
Jfr; U+1D50D
Jopf; U+1D541
Jscr; U+1D4A5
Jsercy; U+00408
Jukcy; U+00404
KHcy; U+00425
KJcy; U+0040C
Kappa; U+0039A
Kcedil; U+00136
Kcy; U+0041A
Kfr; U+1D50E
Kopf; U+1D542
Kscr; U+1D4A6
LJcy; U+00409
LT; U+0003C
LT U+0003C
Lacute; U+00139
Lambda; U+0039B
Lang; U+027EA
Laplacetrf; U+02112
Larr; U+0219E
Lcaron; U+0013D
Lcedil; U+0013B
Lcy; U+0041B
LeftAngleBracket; U+027E8
LeftArrow; U+02190
LeftArrowBar; U+021E4
LeftArrowRightArrow; U+021C6
LeftCeiling; U+02308
LeftDoubleBracket; U+027E6
LeftDownTeeVector; U+02961
LeftDownVector; U+021C3
LeftDownVectorBar; U+02959
LeftFloor; U+0230A
LeftRightArrow; U+02194
LeftRightVector; U+0294E
LeftTee; U+022A3
LeftTeeArrow; U+021A4
LeftTeeVector; U+0295A
LeftTriangle; U+022B2
LeftTriangleBar; U+029CF
LeftTriangleEqual; U+022B4
LeftUpDownVector; U+02951
LeftUpTeeVector; U+02960
LeftUpVector; U+021BF
LeftUpVectorBar; U+02958
LeftVector; U+021BC
LeftVectorBar; U+02952
Leftarrow; U+021D0
Leftrightarrow; U+021D4
LessEqualGreater; U+022DA
LessFullEqual; U+02266
LessGreater; U+02276
LessLess; U+02AA1
LessSlantEqual; U+02A7D
LessTilde; U+02272
Lfr; U+1D50F
Ll; U+022D8
Lleftarrow; U+021DA
Lmidot; U+0013F
LongLeftArrow; U+027F5
LongLeftRightArrow; U+027F7
LongRightArrow; U+027F6
Longleftarrow; U+027F8
Longleftrightarrow; U+027FA
Longrightarrow; U+027F9
Lopf; U+1D543
LowerLeftArrow; U+02199
LowerRightArrow; U+02198
Lscr; U+02112
Lsh; U+021B0
Lstrok; U+00141
Lt; U+0226A
Map; U+02905
Mcy; U+0041C
MediumSpace; U+0205F
Mellintrf; U+02133
Mfr; U+1D510
MinusPlus; U+02213
Mopf; U+1D544
Mscr; U+02133
Mu; U+0039C
NJcy; U+0040A
Nacute; U+00143
Ncaron; U+00147
Ncedil; U+00145
Ncy; U+0041D
NegativeMediumSpace; U+0200B
NegativeThickSpace; U+0200B
NegativeThinSpace; U+0200B
NegativeVeryThinSpace; U+0200B
NestedGreaterGreater; U+0226B
NestedLessLess; U+0226A
NewLine; U+0000A
Nfr; U+1D511
NoBreak; U+02060
NonBreakingSpace; U+000A0
Nopf; U+02115
Not; U+02AEC
NotCongruent; U+02262
NotCupCap; U+0226D
NotDoubleVerticalBar; U+02226
NotElement; U+02209
NotEqual; U+02260
NotExists; U+02204
NotGreater; U+0226F
NotGreaterEqual; U+02271
NotGreaterLess; U+02279
NotGreaterTilde; U+02275
NotLeftTriangle; U+022EA
NotLeftTriangleEqual; U+022EC
NotLess; U+0226E
NotLessEqual; U+02270
NotLessGreater; U+02278
NotLessTilde; U+02274
NotPrecedes; U+02280
NotPrecedesSlantEqual; U+022E0
NotReverseElement; U+0220C
NotRightTriangle; U+022EB
NotRightTriangleEqual; U+022ED
NotSquareSubsetEqual; U+022E2
NotSquareSupersetEqual; U+022E3
NotSubsetEqual; U+02288
NotSucceeds; U+02281
NotSucceedsSlantEqual; U+022E1
NotSupersetEqual; U+02289
NotTilde; U+02241
NotTildeEqual; U+02244
NotTildeFullEqual; U+02247
NotTildeTilde; U+02249
NotVerticalBar; U+02224
Nscr; U+1D4A9
Ntilde; U+000D1
Ntilde U+000D1
Nu; U+0039D
OElig; U+00152
Oacute; U+000D3
Oacute U+000D3
Ocirc; U+000D4
Ocirc U+000D4
Ocy; U+0041E
Odblac; U+00150
Ofr; U+1D512
Ograve; U+000D2
Ograve U+000D2
Omacr; U+0014C
Omega; U+003A9
Omicron; U+0039F
Oopf; U+1D546
OpenCurlyDoubleQuote; U+0201C
OpenCurlyQuote; U+02018
Or; U+02A54
Oscr; U+1D4AA
Oslash; U+000D8
Oslash U+000D8
Otilde; U+000D5
Otilde U+000D5
Otimes; U+02A37
Ouml; U+000D6
Ouml U+000D6
OverBar; U+000AF
OverBrace; U+023DE
OverBracket; U+023B4
OverParenthesis; U+023DC
PartialD; U+02202
Pcy; U+0041F
Pfr; U+1D513
Phi; U+003A6
Pi; U+003A0
PlusMinus; U+000B1
Poincareplane; U+0210C
Popf; U+02119
Pr; U+02ABB
Precedes; U+0227A
PrecedesEqual; U+02AAF
PrecedesSlantEqual; U+0227C
PrecedesTilde; U+0227E
Prime; U+02033
Product; U+0220F
Proportion; U+02237
Proportional; U+0221D
Pscr; U+1D4AB
Psi; U+003A8
QUOT; U+00022
QUOT U+00022
Qfr; U+1D514
Qopf; U+0211A
Qscr; U+1D4AC
RBarr; U+02910
REG; U+000AE
REG U+000AE
Racute; U+00154
Rang; U+027EB
Rarr; U+021A0
Rarrtl; U+02916
Rcaron; U+00158
Rcedil; U+00156
Rcy; U+00420
Re; U+0211C
ReverseElement; U+0220B
ReverseEquilibrium; U+021CB
ReverseUpEquilibrium; U+0296F
Rfr; U+0211C
Rho; U+003A1
RightAngleBracket; U+027E9
RightArrow; U+02192
RightArrowBar; U+021E5
RightArrowLeftArrow; U+021C4
RightCeiling; U+02309
RightDoubleBracket; U+027E7
RightDownTeeVector; U+0295D
RightDownVector; U+021C2
RightDownVectorBar; U+02955
RightFloor; U+0230B
RightTee; U+022A2
RightTeeArrow; U+021A6
RightTeeVector; U+0295B
RightTriangle; U+022B3
RightTriangleBar; U+029D0
RightTriangleEqual; U+022B5
RightUpDownVector; U+0294F
RightUpTeeVector; U+0295C
RightUpVector; U+021BE
RightUpVectorBar; U+02954
RightVector; U+021C0
RightVectorBar; U+02953
Rightarrow; U+021D2
Ropf; U+0211D
RoundImplies; U+02970
Rrightarrow; U+021DB
Rscr; U+0211B
Rsh; U+021B1
RuleDelayed; U+029F4
SHCHcy; U+00429
SHcy; U+00428
SOFTcy; U+0042C
Sacute; U+0015A
Sc; U+02ABC
Scaron; U+00160
Scedil; U+0015E
Scirc; U+0015C
Scy; U+00421
Sfr; U+1D516
ShortDownArrow; U+02193
ShortLeftArrow; U+02190
ShortRightArrow; U+02192
ShortUpArrow; U+02191
Sigma; U+003A3
SmallCircle; U+02218
Sopf; U+1D54A
Sqrt; U+0221A
Square; U+025A1
SquareIntersection; U+02293
SquareSubset; U+0228F
SquareSubsetEqual; U+02291
SquareSuperset; U+02290
SquareSupersetEqual; U+02292
SquareUnion; U+02294
Sscr; U+1D4AE
Star; U+022C6
Sub; U+022D0
Subset; U+022D0
SubsetEqual; U+02286
Succeeds; U+0227B
SucceedsEqual; U+02AB0
SucceedsSlantEqual; U+0227D
SucceedsTilde; U+0227F
SuchThat; U+0220B
Sum; U+02211
Sup; U+022D1
Superset; U+02283
SupersetEqual; U+02287
Supset; U+022D1
THORN; U+000DE
THORN U+000DE
TRADE; U+02122
TSHcy; U+0040B
TScy; U+00426
Tab; U+00009
Tau; U+003A4
Tcaron; U+00164
Tcedil; U+00162
Tcy; U+00422
Tfr; U+1D517
Therefore; U+02234
Theta; U+00398
ThinSpace; U+02009
Tilde; U+0223C
TildeEqual; U+02243
TildeFullEqual; U+02245
TildeTilde; U+02248
Topf; U+1D54B
TripleDot; U+020DB
Tscr; U+1D4AF
Tstrok; U+00166
Uacute; U+000DA
Uacute U+000DA
Uarr; U+0219F
Uarrocir; U+02949
Ubrcy; U+0040E
Ubreve; U+0016C
Ucirc; U+000DB
Ucirc U+000DB
Ucy; U+00423
Udblac; U+00170
Ufr; U+1D518
Ugrave; U+000D9
Ugrave U+000D9
Umacr; U+0016A
UnderBar; U+00332
UnderBrace; U+023DF
UnderBracket; U+023B5
UnderParenthesis; U+023DD
Union; U+022C3
UnionPlus; U+0228E
Uogon; U+00172
Uopf; U+1D54C
UpArrow; U+02191
UpArrowBar; U+02912
UpArrowDownArrow; U+021C5
UpDownArrow; U+02195
UpEquilibrium; U+0296E
UpTee; U+022A5
UpTeeArrow; U+021A5
Uparrow; U+021D1
Updownarrow; U+021D5
UpperLeftArrow; U+02196
UpperRightArrow; U+02197
Upsi; U+003D2
Upsilon; U+003A5
Uring; U+0016E
Uscr; U+1D4B0
Utilde; U+00168
Uuml; U+000DC
Uuml U+000DC
VDash; U+022AB
Vbar; U+02AEB
Vcy; U+00412
Vdash; U+022A9
Vdashl; U+02AE6
Vee; U+022C1
Verbar; U+02016
Vert; U+02016
VerticalBar; U+02223
VerticalLine; U+0007C
VerticalSeparator; U+02758
VerticalTilde; U+02240
VeryThinSpace; U+0200A
Vfr; U+1D519
Vopf; U+1D54D
Vscr; U+1D4B1
Vvdash; U+022AA
Wcirc; U+00174
Wedge; U+022C0
Wfr; U+1D51A
Wopf; U+1D54E
Wscr; U+1D4B2
Xfr; U+1D51B
Xi; U+0039E
Xopf; U+1D54F
Xscr; U+1D4B3
YAcy; U+0042F
YIcy; U+00407
YUcy; U+0042E
Yacute; U+000DD
Yacute U+000DD
Ycirc; U+00176
Ycy; U+0042B
Yfr; U+1D51C
Yopf; U+1D550
Yscr; U+1D4B4
Yuml; U+00178
ZHcy; U+00416
Zacute; U+00179
Zcaron; U+0017D
Zcy; U+00417
Zdot; U+0017B
ZeroWidthSpace; U+0200B
Zeta; U+00396
Zfr; U+02128
Zopf; U+02124
Zscr; U+1D4B5
aacute; U+000E1
aacute U+000E1
abreve; U+00103
ac; U+0223E
acd; U+0223F
acirc; U+000E2
acirc U+000E2
acute; U+000B4
acute U+000B4
acy; U+00430
aelig; U+000E6
aelig U+000E6
af; U+02061
afr; U+1D51E
agrave; U+000E0
agrave U+000E0
alefsym; U+02135
aleph; U+02135
alpha; U+003B1
amacr; U+00101
amalg; U+02A3F
amp; U+00026
amp U+00026
and; U+02227
andand; U+02A55
andd; U+02A5C
andslope; U+02A58
andv; U+02A5A
ang; U+02220
ange; U+029A4
angle; U+02220
angmsd; U+02221
angmsdaa; U+029A8
angmsdab; U+029A9
angmsdac; U+029AA
angmsdad; U+029AB
angmsdae; U+029AC
angmsdaf; U+029AD
angmsdag; U+029AE
angmsdah; U+029AF
angrt; U+0221F
angrtvb; U+022BE
angrtvbd; U+0299D
angsph; U+02222
angst; U+0212B
angzarr; U+0237C
aogon; U+00105
aopf; U+1D552
ap; U+02248
apE; U+02A70
apacir; U+02A6F
ape; U+0224A
apid; U+0224B
apos; U+00027
approx; U+02248
approxeq; U+0224A
aring; U+000E5
aring U+000E5
ascr; U+1D4B6
ast; U+0002A
asymp; U+02248
asympeq; U+0224D
atilde; U+000E3
atilde U+000E3
auml; U+000E4
auml U+000E4
awconint; U+02233
awint; U+02A11
bNot; U+02AED
backcong; U+0224C
backepsilon; U+003F6
backprime; U+02035
backsim; U+0223D
backsimeq; U+022CD
barvee; U+022BD
barwed; U+02305
barwedge; U+02305
bbrk; U+023B5
bbrktbrk; U+023B6
bcong; U+0224C
bcy; U+00431
bdquo; U+0201E
becaus; U+02235
because; U+02235
bemptyv; U+029B0
bepsi; U+003F6
bernou; U+0212C
beta; U+003B2
beth; U+02136
between; U+0226C
bfr; U+1D51F
bigcap; U+022C2
bigcirc; U+025EF
bigcup; U+022C3
bigodot; U+02A00
bigoplus; U+02A01
bigotimes; U+02A02
bigsqcup; U+02A06
bigstar; U+02605
bigtriangledown; U+025BD
bigtriangleup; U+025B3
biguplus; U+02A04
bigvee; U+022C1
bigwedge; U+022C0
bkarow; U+0290D
blacklozenge; U+029EB
blacksquare; U+025AA
blacktriangle; U+025B4
blacktriangledown; U+025BE
blacktriangleleft; U+025C2
blacktriangleright; U+025B8
blank; U+02423
blk12; U+02592
blk14; U+02591
blk34; U+02593
block; U+02588
bnot; U+02310
bopf; U+1D553
bot; U+022A5
bottom; U+022A5
bowtie; U+022C8
boxDL; U+02557
boxDR; U+02554
boxDl; U+02556
boxDr; U+02553
boxH; U+02550
boxHD; U+02566
boxHU; U+02569
boxHd; U+02564
boxHu; U+02567
boxUL; U+0255D
boxUR; U+0255A
boxUl; U+0255C
boxUr; U+02559
boxV; U+02551
boxVH; U+0256C
boxVL; U+02563
boxVR; U+02560
boxVh; U+0256B
boxVl; U+02562
boxVr; U+0255F
boxbox; U+029C9
boxdL; U+02555
boxdR; U+02552
boxdl; U+02510
boxdr; U+0250C
boxh; U+02500
boxhD; U+02565
boxhU; U+02568
boxhd; U+0252C
boxhu; U+02534
boxminus; U+0229F
boxplus; U+0229E
boxtimes; U+022A0
boxuL; U+0255B
boxuR; U+02558
boxul; U+02518
boxur; U+02514
boxv; U+02502
boxvH; U+0256A
boxvL; U+02561
boxvR; U+0255E
boxvh; U+0253C
boxvl; U+02524
boxvr; U+0251C
bprime; U+02035
breve; U+002D8
brvbar; U+000A6
brvbar U+000A6
bscr; U+1D4B7
bsemi; U+0204F
bsim; U+0223D
bsime; U+022CD
bsol; U+0005C
bsolb; U+029C5
bull; U+02022
bullet; U+02022
bump; U+0224E
bumpE; U+02AAE
bumpe; U+0224F
bumpeq; U+0224F
cacute; U+00107
cap; U+02229
capand; U+02A44
capbrcup; U+02A49
capcap; U+02A4B
capcup; U+02A47
capdot; U+02A40
caret; U+02041
caron; U+002C7
ccaps; U+02A4D
ccaron; U+0010D
ccedil; U+000E7
ccedil U+000E7
ccirc; U+00109
ccups; U+02A4C
ccupssm; U+02A50
cdot; U+0010B
cedil; U+000B8
cedil U+000B8
cemptyv; U+029B2
cent; U+000A2
cent U+000A2
centerdot; U+000B7
cfr; U+1D520
chcy; U+00447
check; U+02713
checkmark; U+02713
chi; U+003C7
cir; U+025CB
cirE; U+029C3
circ; U+002C6
circeq; U+02257
circlearrowleft; U+021BA
circlearrowright; U+021BB
circledR; U+000AE
circledS; U+024C8
circledast; U+0229B
circledcirc; U+0229A
circleddash; U+0229D
cire; U+02257
cirfnint; U+02A10
cirmid; U+02AEF
cirscir; U+029C2
clubs; U+02663
clubsuit; U+02663
colon; U+0003A
colone; U+02254
coloneq; U+02254
comma; U+0002C
commat; U+00040
comp; U+02201
compfn; U+02218
complement; U+02201
complexes; U+02102
cong; U+02245
congdot; U+02A6D
conint; U+0222E
copf; U+1D554
coprod; U+02210
copy; U+000A9
copy U+000A9
copysr; U+02117
crarr; U+021B5
cross; U+02717
cscr; U+1D4B8
csub; U+02ACF
csube; U+02AD1
csup; U+02AD0
csupe; U+02AD2
ctdot; U+022EF
cudarrl; U+02938
cudarrr; U+02935
cuepr; U+022DE
cuesc; U+022DF
cularr; U+021B6
cularrp; U+0293D
cup; U+0222A
cupbrcap; U+02A48
cupcap; U+02A46
cupcup; U+02A4A
cupdot; U+0228D
cupor; U+02A45
curarr; U+021B7
curarrm; U+0293C
curlyeqprec; U+022DE
curlyeqsucc; U+022DF
curlyvee; U+022CE
curlywedge; U+022CF
curren; U+000A4
curren U+000A4
curvearrowleft; U+021B6
curvearrowright; U+021B7
cuvee; U+022CE
cuwed; U+022CF
cwconint; U+02232
cwint; U+02231
cylcty; U+0232D
dArr; U+021D3
dHar; U+02965
dagger; U+02020
daleth; U+02138
darr; U+02193
dash; U+02010
dashv; U+022A3
dbkarow; U+0290F
dblac; U+002DD
dcaron; U+0010F
dcy; U+00434
dd; U+02146
ddagger; U+02021
ddarr; U+021CA
ddotseq; U+02A77
deg; U+000B0
deg U+000B0
delta; U+003B4
demptyv; U+029B1
dfisht; U+0297F
dfr; U+1D521
dharl; U+021C3
dharr; U+021C2
diam; U+022C4
diamond; U+022C4
diamondsuit; U+02666
diams; U+02666
die; U+000A8
digamma; U+003DD
disin; U+022F2
div; U+000F7
divide; U+000F7
divide U+000F7
divideontimes; U+022C7
divonx; U+022C7
djcy; U+00452
dlcorn; U+0231E
dlcrop; U+0230D
dollar; U+00024
dopf; U+1D555
dot; U+002D9
doteq; U+02250
doteqdot; U+02251
dotminus; U+02238
dotplus; U+02214
dotsquare; U+022A1
doublebarwedge; U+02306
downarrow; U+02193
downdownarrows; U+021CA
downharpoonleft; U+021C3
downharpoonright; U+021C2
drbkarow; U+02910
drcorn; U+0231F
drcrop; U+0230C
dscr; U+1D4B9
dscy; U+00455
dsol; U+029F6
dstrok; U+00111
dtdot; U+022F1
dtri; U+025BF
dtrif; U+025BE
duarr; U+021F5
duhar; U+0296F
dwangle; U+029A6
dzcy; U+0045F
dzigrarr; U+027FF
eDDot; U+02A77
eDot; U+02251
eacute; U+000E9
eacute U+000E9
easter; U+02A6E
ecaron; U+0011B
ecir; U+02256
ecirc; U+000EA
ecirc U+000EA
ecolon; U+02255
ecy; U+0044D
edot; U+00117
ee; U+02147
efDot; U+02252
efr; U+1D522
eg; U+02A9A
egrave; U+000E8
egrave U+000E8
egs; U+02A96
egsdot; U+02A98
el; U+02A99
elinters; U+023E7
ell; U+02113
els; U+02A95
elsdot; U+02A97
emacr; U+00113
empty; U+02205
emptyset; U+02205
emptyv; U+02205
emsp13; U+02004
emsp14; U+02005
emsp; U+02003
eng; U+0014B
ensp; U+02002
eogon; U+00119
eopf; U+1D556
epar; U+022D5
eparsl; U+029E3
eplus; U+02A71
epsi; U+003F5
epsilon; U+003B5
epsiv; U+003B5
eqcirc; U+02256
eqcolon; U+02255
eqsim; U+02242
eqslantgtr; U+02A96
eqslantless; U+02A95
equals; U+0003D
equest; U+0225F
equiv; U+02261
equivDD; U+02A78
eqvparsl; U+029E5
erDot; U+02253
erarr; U+02971
escr; U+0212F
esdot; U+02250
esim; U+02242
eta; U+003B7
eth; U+000F0
eth U+000F0
euml; U+000EB
euml U+000EB
euro; U+020AC
excl; U+00021
exist; U+02203
expectation; U+02130
exponentiale; U+02147
fallingdotseq; U+02252
fcy; U+00444
female; U+02640
ffilig; U+0FB03
fflig; U+0FB00
ffllig; U+0FB04
ffr; U+1D523
filig; U+0FB01
flat; U+0266D
fllig; U+0FB02
fltns; U+025B1
fnof; U+00192
fopf; U+1D557
forall; U+02200
fork; U+022D4
forkv; U+02AD9
fpartint; U+02A0D
frac12; U+000BD
frac12 U+000BD
frac13; U+02153
frac14; U+000BC
frac14 U+000BC
frac15; U+02155
frac16; U+02159
frac18; U+0215B
frac23; U+02154
frac25; U+02156
frac34; U+000BE
frac34 U+000BE
frac35; U+02157
frac38; U+0215C
frac45; U+02158
frac56; U+0215A
frac58; U+0215D
frac78; U+0215E
frasl; U+02044
frown; U+02322
fscr; U+1D4BB
gE; U+02267
gEl; U+02A8C
gacute; U+001F5
gamma; U+003B3
gammad; U+003DD
gap; U+02A86
gbreve; U+0011F
gcirc; U+0011D
gcy; U+00433
gdot; U+00121
ge; U+02265
gel; U+022DB
geq; U+02265
geqq; U+02267
geqslant; U+02A7E
ges; U+02A7E
gescc; U+02AA9
gesdot; U+02A80
gesdoto; U+02A82
gesdotol; U+02A84
gesles; U+02A94
gfr; U+1D524
gg; U+0226B
ggg; U+022D9
gimel; U+02137
gjcy; U+00453
gl; U+02277
glE; U+02A92
gla; U+02AA5
glj; U+02AA4
gnE; U+02269
gnap; U+02A8A
gnapprox; U+02A8A
gne; U+02A88
gneq; U+02A88
gneqq; U+02269
gnsim; U+022E7
gopf; U+1D558
grave; U+00060
gscr; U+0210A
gsim; U+02273
gsime; U+02A8E
gsiml; U+02A90
gt; U+0003E
gt U+0003E
gtcc; U+02AA7
gtcir; U+02A7A
gtdot; U+022D7
gtlPar; U+02995
gtquest; U+02A7C
gtrapprox; U+02A86
gtrarr; U+02978
gtrdot; U+022D7
gtreqless; U+022DB
gtreqqless; U+02A8C
gtrless; U+02277
gtrsim; U+02273
hArr; U+021D4
hairsp; U+0200A
half; U+000BD
hamilt; U+0210B
hardcy; U+0044A
harr; U+02194
harrcir; U+02948
harrw; U+021AD
hbar; U+0210F
hcirc; U+00125
hearts; U+02665
heartsuit; U+02665
hellip; U+02026
hercon; U+022B9
hfr; U+1D525
hksearow; U+02925
hkswarow; U+02926
hoarr; U+021FF
homtht; U+0223B
hookleftarrow; U+021A9
hookrightarrow; U+021AA
hopf; U+1D559
horbar; U+02015
hscr; U+1D4BD
hslash; U+0210F
hstrok; U+00127
hybull; U+02043
hyphen; U+02010
iacute; U+000ED
iacute U+000ED
ic; U+02063
icirc; U+000EE
icirc U+000EE
icy; U+00438
iecy; U+00435
iexcl; U+000A1
iexcl U+000A1
iff; U+021D4
ifr; U+1D526
igrave; U+000EC
igrave U+000EC
ii; U+02148
iiiint; U+02A0C
iiint; U+0222D
iinfin; U+029DC
iiota; U+02129
ijlig; U+00133
imacr; U+0012B
image; U+02111
imagline; U+02110
imagpart; U+02111
imath; U+00131
imof; U+022B7
imped; U+001B5
in; U+02208
incare; U+02105
infin; U+0221E
infintie; U+029DD
inodot; U+00131
int; U+0222B
intcal; U+022BA
integers; U+02124
intercal; U+022BA
intlarhk; U+02A17
intprod; U+02A3C
iocy; U+00451
iogon; U+0012F
iopf; U+1D55A
iota; U+003B9
iprod; U+02A3C
iquest; U+000BF
iquest U+000BF
iscr; U+1D4BE
isin; U+02208
isinE; U+022F9
isindot; U+022F5
isins; U+022F4
isinsv; U+022F3
isinv; U+02208
it; U+02062
itilde; U+00129
iukcy; U+00456
iuml; U+000EF
iuml U+000EF
jcirc; U+00135
jcy; U+00439
jfr; U+1D527
jmath; U+00237
jopf; U+1D55B
jscr; U+1D4BF
jsercy; U+00458
jukcy; U+00454
kappa; U+003BA
kappav; U+003F0
kcedil; U+00137
kcy; U+0043A
kfr; U+1D528
kgreen; U+00138
khcy; U+00445
kjcy; U+0045C
kopf; U+1D55C
kscr; U+1D4C0
lAarr; U+021DA
lArr; U+021D0
lAtail; U+0291B
lBarr; U+0290E
lE; U+02266
lEg; U+02A8B
lHar; U+02962
lacute; U+0013A
laemptyv; U+029B4
lagran; U+02112
lambda; U+003BB
lang; U+027E8
langd; U+02991
langle; U+027E8
lap; U+02A85
laquo; U+000AB
laquo U+000AB
larr; U+02190
larrb; U+021E4
larrbfs; U+0291F
larrfs; U+0291D
larrhk; U+021A9
larrlp; U+021AB
larrpl; U+02939
larrsim; U+02973
larrtl; U+021A2
lat; U+02AAB
latail; U+02919
late; U+02AAD
lbarr; U+0290C
lbbrk; U+02772
lbrace; U+0007B
lbrack; U+0005B
lbrke; U+0298B
lbrksld; U+0298F
lbrkslu; U+0298D
lcaron; U+0013E
lcedil; U+0013C
lceil; U+02308
lcub; U+0007B
lcy; U+0043B
ldca; U+02936
ldquo; U+0201C
ldquor; U+0201E
ldrdhar; U+02967
ldrushar; U+0294B
ldsh; U+021B2
le; U+02264
leftarrow; U+02190
leftarrowtail; U+021A2
leftharpoondown; U+021BD
leftharpoonup; U+021BC
leftleftarrows; U+021C7
leftrightarrow; U+02194
leftrightarrows; U+021C6
leftrightharpoons; U+021CB
leftrightsquigarrow; U+021AD
leftthreetimes; U+022CB
leg; U+022DA
leq; U+02264
leqq; U+02266
leqslant; U+02A7D
les; U+02A7D
lescc; U+02AA8
lesdot; U+02A7F
lesdoto; U+02A81
lesdotor; U+02A83
lesges; U+02A93
lessapprox; U+02A85
lessdot; U+022D6
lesseqgtr; U+022DA
lesseqqgtr; U+02A8B
lessgtr; U+02276
lesssim; U+02272
lfisht; U+0297C
lfloor; U+0230A
lfr; U+1D529
lg; U+02276
lgE; U+02A91
lhard; U+021BD
lharu; U+021BC
lharul; U+0296A
lhblk; U+02584
ljcy; U+00459
ll; U+0226A
llarr; U+021C7
llcorner; U+0231E
llhard; U+0296B
lltri; U+025FA
lmidot; U+00140
lmoust; U+023B0
lmoustache; U+023B0
lnE; U+02268
lnap; U+02A89
lnapprox; U+02A89
lne; U+02A87
lneq; U+02A87
lneqq; U+02268
lnsim; U+022E6
loang; U+027EC
loarr; U+021FD
lobrk; U+027E6
longleftarrow; U+027F5
longleftrightarrow; U+027F7
longmapsto; U+027FC
longrightarrow; U+027F6
looparrowleft; U+021AB
looparrowright; U+021AC
lopar; U+02985
lopf; U+1D55D
loplus; U+02A2D
lotimes; U+02A34
lowast; U+02217
lowbar; U+0005F
loz; U+025CA
lozenge; U+025CA
lozf; U+029EB
lpar; U+00028
lparlt; U+02993
lrarr; U+021C6
lrcorner; U+0231F
lrhar; U+021CB
lrhard; U+0296D
lrm; U+0200E
lrtri; U+022BF
lsaquo; U+02039
lscr; U+1D4C1
lsh; U+021B0
lsim; U+02272
lsime; U+02A8D
lsimg; U+02A8F
lsqb; U+0005B
lsquo; U+02018
lsquor; U+0201A
lstrok; U+00142
lt; U+0003C
lt U+0003C
ltcc; U+02AA6
ltcir; U+02A79
ltdot; U+022D6
lthree; U+022CB
ltimes; U+022C9
ltlarr; U+02976
ltquest; U+02A7B
ltrPar; U+02996
ltri; U+025C3
ltrie; U+022B4
ltrif; U+025C2
lurdshar; U+0294A
luruhar; U+02966
mDDot; U+0223A
macr; U+000AF
macr U+000AF
male; U+02642
malt; U+02720
maltese; U+02720
map; U+021A6
mapsto; U+021A6
mapstodown; U+021A7
mapstoleft; U+021A4
mapstoup; U+021A5
marker; U+025AE
mcomma; U+02A29
mcy; U+0043C
mdash; U+02014
measuredangle; U+02221
mfr; U+1D52A
mho; U+02127
micro; U+000B5
micro U+000B5
mid; U+02223
midast; U+0002A
midcir; U+02AF0
middot; U+000B7
middot U+000B7
minus; U+02212
minusb; U+0229F
minusd; U+02238
minusdu; U+02A2A
mlcp; U+02ADB
mldr; U+02026
mnplus; U+02213
models; U+022A7
mopf; U+1D55E
mp; U+02213
mscr; U+1D4C2
mstpos; U+0223E
mu; U+003BC
multimap; U+022B8
mumap; U+022B8
nLeftarrow; U+021CD
nLeftrightarrow; U+021CE
nRightarrow; U+021CF
nVDash; U+022AF
nVdash; U+022AE
nabla; U+02207
nacute; U+00144
nap; U+02249
napos; U+00149
napprox; U+02249
natur; U+0266E
natural; U+0266E
naturals; U+02115
nbsp; U+000A0
nbsp U+000A0
ncap; U+02A43
ncaron; U+00148
ncedil; U+00146
ncong; U+02247
ncup; U+02A42
ncy; U+0043D
ndash; U+02013
ne; U+02260
neArr; U+021D7
nearhk; U+02924
nearr; U+02197
nearrow; U+02197
nequiv; U+02262
nesear; U+02928
nexist; U+02204
nexists; U+02204
nfr; U+1D52B
nge; U+02271
ngeq; U+02271
ngsim; U+02275
ngt; U+0226F
ngtr; U+0226F
nhArr; U+021CE
nharr; U+021AE
nhpar; U+02AF2
ni; U+0220B
nis; U+022FC
nisd; U+022FA
niv; U+0220B
njcy; U+0045A
nlArr; U+021CD
nlarr; U+0219A
nldr; U+02025
nle; U+02270
nleftarrow; U+0219A
nleftrightarrow; U+021AE
nleq; U+02270
nless; U+0226E
nlsim; U+02274
nlt; U+0226E
nltri; U+022EA
nltrie; U+022EC
nmid; U+02224
nopf; U+1D55F
not; U+000AC
not U+000AC
notin; U+02209
notinva; U+02209
notinvb; U+022F7
notinvc; U+022F6
notni; U+0220C
notniva; U+0220C
notnivb; U+022FE
notnivc; U+022FD
npar; U+02226
nparallel; U+02226
npolint; U+02A14
npr; U+02280
nprcue; U+022E0
nprec; U+02280
nrArr; U+021CF
nrarr; U+0219B
nrightarrow; U+0219B
nrtri; U+022EB
nrtrie; U+022ED
nsc; U+02281
nsccue; U+022E1
nscr; U+1D4C3
nshortmid; U+02224
nshortparallel; U+02226
nsim; U+02241
nsime; U+02244
nsimeq; U+02244
nsmid; U+02224
nspar; U+02226
nsqsube; U+022E2
nsqsupe; U+022E3
nsub; U+02284
nsube; U+02288
nsubseteq; U+02288
nsucc; U+02281
nsup; U+02285
nsupe; U+02289
nsupseteq; U+02289
ntgl; U+02279
ntilde; U+000F1
ntilde U+000F1
ntlg; U+02278
ntriangleleft; U+022EA
ntrianglelefteq; U+022EC
ntriangleright; U+022EB
ntrianglerighteq; U+022ED
nu; U+003BD
num; U+00023
numero; U+02116
numsp; U+02007
nvDash; U+022AD
nvHarr; U+02904
nvdash; U+022AC
nvinfin; U+029DE
nvlArr; U+02902
nvrArr; U+02903
nwArr; U+021D6
nwarhk; U+02923
nwarr; U+02196
nwarrow; U+02196
nwnear; U+02927
oS; U+024C8
oacute; U+000F3
oacute U+000F3
oast; U+0229B
ocir; U+0229A
ocirc; U+000F4
ocirc U+000F4
ocy; U+0043E
odash; U+0229D
odblac; U+00151
odiv; U+02A38
odot; U+02299
odsold; U+029BC
oelig; U+00153
ofcir; U+029BF
ofr; U+1D52C
ogon; U+002DB
ograve; U+000F2
ograve U+000F2
ogt; U+029C1
ohbar; U+029B5
ohm; U+02126
oint; U+0222E
olarr; U+021BA
olcir; U+029BE
olcross; U+029BB
oline; U+0203E
olt; U+029C0
omacr; U+0014D
omega; U+003C9
omicron; U+003BF
omid; U+029B6
ominus; U+02296
oopf; U+1D560
opar; U+029B7
operp; U+029B9
oplus; U+02295
or; U+02228
orarr; U+021BB
ord; U+02A5D
order; U+02134
orderof; U+02134
ordf; U+000AA
ordf U+000AA
ordm; U+000BA
ordm U+000BA
origof; U+022B6
oror; U+02A56
orslope; U+02A57
orv; U+02A5B
oscr; U+02134
oslash; U+000F8
oslash U+000F8
osol; U+02298
otilde; U+000F5
otilde U+000F5
otimes; U+02297
otimesas; U+02A36
ouml; U+000F6
ouml U+000F6
ovbar; U+0233D
par; U+02225
para; U+000B6
para U+000B6
parallel; U+02225
parsim; U+02AF3
parsl; U+02AFD
part; U+02202
pcy; U+0043F
percnt; U+00025
period; U+0002E
permil; U+02030
perp; U+022A5
pertenk; U+02031
pfr; U+1D52D
phi; U+003C6
phiv; U+003C6
phmmat; U+02133
phone; U+0260E
pi; U+003C0
pitchfork; U+022D4
piv; U+003D6
planck; U+0210F
planckh; U+0210E
plankv; U+0210F
plus; U+0002B
plusacir; U+02A23
plusb; U+0229E
pluscir; U+02A22
plusdo; U+02214
plusdu; U+02A25
pluse; U+02A72
plusmn; U+000B1
plusmn U+000B1
plussim; U+02A26
plustwo; U+02A27
pm; U+000B1
pointint; U+02A15
popf; U+1D561
pound; U+000A3
pound U+000A3
pr; U+0227A
prE; U+02AB3
prap; U+02AB7
prcue; U+0227C
pre; U+02AAF
prec; U+0227A
precapprox; U+02AB7
preccurlyeq; U+0227C
preceq; U+02AAF
precnapprox; U+02AB9
precneqq; U+02AB5
precnsim; U+022E8
precsim; U+0227E
prime; U+02032
primes; U+02119
prnE; U+02AB5
prnap; U+02AB9
prnsim; U+022E8
prod; U+0220F
profalar; U+0232E
profline; U+02312
profsurf; U+02313
prop; U+0221D
propto; U+0221D
prsim; U+0227E
prurel; U+022B0
pscr; U+1D4C5
psi; U+003C8
puncsp; U+02008
qfr; U+1D52E
qint; U+02A0C
qopf; U+1D562
qprime; U+02057
qscr; U+1D4C6
quaternions; U+0210D
quatint; U+02A16
quest; U+0003F
questeq; U+0225F
quot; U+00022
quot U+00022
rAarr; U+021DB
rArr; U+021D2
rAtail; U+0291C
rBarr; U+0290F
rHar; U+02964
race; U+029DA
racute; U+00155
radic; U+0221A
raemptyv; U+029B3
rang; U+027E9
rangd; U+02992
range; U+029A5
rangle; U+027E9
raquo; U+000BB
raquo U+000BB
rarr; U+02192
rarrap; U+02975
rarrb; U+021E5
rarrbfs; U+02920
rarrc; U+02933
rarrfs; U+0291E
rarrhk; U+021AA
rarrlp; U+021AC
rarrpl; U+02945
rarrsim; U+02974
rarrtl; U+021A3
rarrw; U+0219D
ratail; U+0291A
ratio; U+02236
rationals; U+0211A
rbarr; U+0290D
rbbrk; U+02773
rbrace; U+0007D
rbrack; U+0005D
rbrke; U+0298C
rbrksld; U+0298E
rbrkslu; U+02990
rcaron; U+00159
rcedil; U+00157
rceil; U+02309
rcub; U+0007D
rcy; U+00440
rdca; U+02937
rdldhar; U+02969
rdquo; U+0201D
rdquor; U+0201D
rdsh; U+021B3
real; U+0211C
realine; U+0211B
realpart; U+0211C
reals; U+0211D
rect; U+025AD
reg; U+000AE
reg U+000AE
rfisht; U+0297D
rfloor; U+0230B
rfr; U+1D52F
rhard; U+021C1
rharu; U+021C0
rharul; U+0296C
rho; U+003C1
rhov; U+003F1
rightarrow; U+02192
rightarrowtail; U+021A3
rightharpoondown; U+021C1
rightharpoonup; U+021C0
rightleftarrows; U+021C4
rightleftharpoons; U+021CC
rightrightarrows; U+021C9
rightsquigarrow; U+0219D
rightthreetimes; U+022CC
ring; U+002DA
risingdotseq; U+02253
rlarr; U+021C4
rlhar; U+021CC
rlm; U+0200F
rmoust; U+023B1
rmoustache; U+023B1
rnmid; U+02AEE
roang; U+027ED
roarr; U+021FE
robrk; U+027E7
ropar; U+02986
ropf; U+1D563
roplus; U+02A2E
rotimes; U+02A35
rpar; U+00029
rpargt; U+02994
rppolint; U+02A12
rrarr; U+021C9
rsaquo; U+0203A
rscr; U+1D4C7
rsh; U+021B1
rsqb; U+0005D
rsquo; U+02019
rsquor; U+02019
rthree; U+022CC
rtimes; U+022CA
rtri; U+025B9
rtrie; U+022B5
rtrif; U+025B8
rtriltri; U+029CE
ruluhar; U+02968
rx; U+0211E
sacute; U+0015B
sbquo; U+0201A
sc; U+0227B
scE; U+02AB4
scap; U+02AB8
scaron; U+00161
sccue; U+0227D
sce; U+02AB0
scedil; U+0015F
scirc; U+0015D
scnE; U+02AB6
scnap; U+02ABA
scnsim; U+022E9
scpolint; U+02A13
scsim; U+0227F
scy; U+00441
sdot; U+022C5
sdotb; U+022A1
sdote; U+02A66
seArr; U+021D8
searhk; U+02925
searr; U+02198
searrow; U+02198
sect; U+000A7
sect U+000A7
semi; U+0003B
seswar; U+02929
setminus; U+02216
setmn; U+02216
sext; U+02736
sfr; U+1D530
sfrown; U+02322
sharp; U+0266F
shchcy; U+00449
shcy; U+00448
shortmid; U+02223
shortparallel; U+02225
shy; U+000AD
shy U+000AD
sigma; U+003C3
sigmaf; U+003C2
sigmav; U+003C2
sim; U+0223C
simdot; U+02A6A
sime; U+02243
simeq; U+02243
simg; U+02A9E
simgE; U+02AA0
siml; U+02A9D
simlE; U+02A9F
simne; U+02246
simplus; U+02A24
simrarr; U+02972
slarr; U+02190
smallsetminus; U+02216
smashp; U+02A33
smeparsl; U+029E4
smid; U+02223
smile; U+02323
smt; U+02AAA
smte; U+02AAC
softcy; U+0044C
sol; U+0002F
solb; U+029C4
solbar; U+0233F
sopf; U+1D564
spades; U+02660
spadesuit; U+02660
spar; U+02225
sqcap; U+02293
sqcup; U+02294
sqsub; U+0228F
sqsube; U+02291
sqsubset; U+0228F
sqsubseteq; U+02291
sqsup; U+02290
sqsupe; U+02292
sqsupset; U+02290
sqsupseteq; U+02292
squ; U+025A1
square; U+025A1
squarf; U+025AA
squf; U+025AA
srarr; U+02192
sscr; U+1D4C8
ssetmn; U+02216
ssmile; U+02323
sstarf; U+022C6
star; U+02606
starf; U+02605
straightepsilon; U+003F5
straightphi; U+003D5
strns; U+000AF
sub; U+02282
subE; U+02AC5
subdot; U+02ABD
sube; U+02286
subedot; U+02AC3
submult; U+02AC1
subnE; U+02ACB
subne; U+0228A
subplus; U+02ABF
subrarr; U+02979
subset; U+02282
subseteq; U+02286
subseteqq; U+02AC5
subsetneq; U+0228A
subsetneqq; U+02ACB
subsim; U+02AC7
subsub; U+02AD5
subsup; U+02AD3
succ; U+0227B
succapprox; U+02AB8
succcurlyeq; U+0227D
succeq; U+02AB0
succnapprox; U+02ABA
succneqq; U+02AB6
succnsim; U+022E9
succsim; U+0227F
sum; U+02211
sung; U+0266A
sup1; U+000B9
sup1 U+000B9
sup2; U+000B2
sup2 U+000B2
sup3; U+000B3
sup3 U+000B3
sup; U+02283
supE; U+02AC6
supdot; U+02ABE
supdsub; U+02AD8
supe; U+02287
supedot; U+02AC4
suphsub; U+02AD7
suplarr; U+0297B
supmult; U+02AC2
supnE; U+02ACC
supne; U+0228B
supplus; U+02AC0
supset; U+02283
supseteq; U+02287
supseteqq; U+02AC6
supsetneq; U+0228B
supsetneqq; U+02ACC
supsim; U+02AC8
supsub; U+02AD4
supsup; U+02AD6
swArr; U+021D9
swarhk; U+02926
swarr; U+02199
swarrow; U+02199
swnwar; U+0292A
szlig; U+000DF
szlig U+000DF
target; U+02316
tau; U+003C4
tbrk; U+023B4
tcaron; U+00165
tcedil; U+00163
tcy; U+00442
tdot; U+020DB
telrec; U+02315
tfr; U+1D531
there4; U+02234
therefore; U+02234
theta; U+003B8
thetasym; U+003D1
thetav; U+003D1
thickapprox; U+02248
thicksim; U+0223C
thinsp; U+02009
thkap; U+02248
thksim; U+0223C
thorn; U+000FE
thorn U+000FE
tilde; U+002DC
times; U+000D7
times U+000D7
timesb; U+022A0
timesbar; U+02A31
timesd; U+02A30
tint; U+0222D
toea; U+02928
top; U+022A4
topbot; U+02336
topcir; U+02AF1
topf; U+1D565
topfork; U+02ADA
tosa; U+02929
tprime; U+02034
trade; U+02122
triangle; U+025B5
triangledown; U+025BF
triangleleft; U+025C3
trianglelefteq; U+022B4
triangleq; U+0225C
triangleright; U+025B9
trianglerighteq; U+022B5
tridot; U+025EC
trie; U+0225C
triminus; U+02A3A
triplus; U+02A39
trisb; U+029CD
tritime; U+02A3B
trpezium; U+023E2
tscr; U+1D4C9
tscy; U+00446
tshcy; U+0045B
tstrok; U+00167
twixt; U+0226C
twoheadleftarrow; U+0219E
twoheadrightarrow; U+021A0
uArr; U+021D1
uHar; U+02963
uacute; U+000FA
uacute U+000FA
uarr; U+02191
ubrcy; U+0045E
ubreve; U+0016D
ucirc; U+000FB
ucirc U+000FB
ucy; U+00443
udarr; U+021C5
udblac; U+00171
udhar; U+0296E
ufisht; U+0297E
ufr; U+1D532
ugrave; U+000F9
ugrave U+000F9
uharl; U+021BF
uharr; U+021BE
uhblk; U+02580
ulcorn; U+0231C
ulcorner; U+0231C
ulcrop; U+0230F
ultri; U+025F8
umacr; U+0016B
uml; U+000A8
uml U+000A8
uogon; U+00173
uopf; U+1D566
uparrow; U+02191
updownarrow; U+02195
upharpoonleft; U+021BF
upharpoonright; U+021BE
uplus; U+0228E
upsi; U+003C5
upsih; U+003D2
upsilon; U+003C5
upuparrows; U+021C8
urcorn; U+0231D
urcorner; U+0231D
urcrop; U+0230E
uring; U+0016F
urtri; U+025F9
uscr; U+1D4CA
utdot; U+022F0
utilde; U+00169
utri; U+025B5
utrif; U+025B4
uuarr; U+021C8
uuml; U+000FC
uuml U+000FC
uwangle; U+029A7
vArr; U+021D5
vBar; U+02AE8
vBarv; U+02AE9
vDash; U+022A8
vangrt; U+0299C
varepsilon; U+003B5
varkappa; U+003F0
varnothing; U+02205
varphi; U+003C6
varpi; U+003D6
varpropto; U+0221D
varr; U+02195
varrho; U+003F1
varsigma; U+003C2
vartheta; U+003D1
vartriangleleft; U+022B2
vartriangleright; U+022B3
vcy; U+00432
vdash; U+022A2
vee; U+02228
veebar; U+022BB
veeeq; U+0225A
vellip; U+022EE
verbar; U+0007C
vert; U+0007C
vfr; U+1D533
vltri; U+022B2
vopf; U+1D567
vprop; U+0221D
vrtri; U+022B3
vscr; U+1D4CB
vzigzag; U+0299A
wcirc; U+00175
wedbar; U+02A5F
wedge; U+02227
wedgeq; U+02259
weierp; U+02118
wfr; U+1D534
wopf; U+1D568
wp; U+02118
wr; U+02240
wreath; U+02240
wscr; U+1D4CC
xcap; U+022C2
xcirc; U+025EF
xcup; U+022C3
xdtri; U+025BD
xfr; U+1D535
xhArr; U+027FA
xharr; U+027F7
xi; U+003BE
xlArr; U+027F8
xlarr; U+027F5
xmap; U+027FC
xnis; U+022FB
xodot; U+02A00
xopf; U+1D569
xoplus; U+02A01
xotime; U+02A02
xrArr; U+027F9
xrarr; U+027F6
xscr; U+1D4CD
xsqcup; U+02A06
xuplus; U+02A04
xutri; U+025B3
xvee; U+022C1
xwedge; U+022C0
yacute; U+000FD
yacute U+000FD
yacy; U+0044F
ycirc; U+00177
ycy; U+0044B
yen; U+000A5
yen U+000A5
yfr; U+1D536
yicy; U+00457
yopf; U+1D56A
yscr; U+1D4CE
yucy; U+0044E
yuml; U+000FF
yuml U+000FF
zacute; U+0017A
zcaron; U+0017E
zcy; U+00437
zdot; U+0017C
zeetrf; U+02128
zeta; U+003B6
zfr; U+1D537
zhcy; U+00436
zigrarr; U+021DD
zopf; U+1D56B
zscr; U+1D4CF
zwj; U+0200D
zwnj; U+0200C
\ No newline at end of file + \ No newline at end of file diff --git a/parser/html/nsAHtml5TreeOpSink.h b/parser/html/nsAHtml5TreeOpSink.h index a4040f1cad6e..c8280e2f36e3 100644 --- a/parser/html/nsAHtml5TreeOpSink.h +++ b/parser/html/nsAHtml5TreeOpSink.h @@ -48,15 +48,9 @@ class nsAHtml5TreeOpSink { /** * Flush the operations from the tree operations from the argument - * queue if flushing is not expensive. + * queue into this sink unconditionally. */ - virtual void MaybeFlush(nsTArray& aOpQueue) = 0; - - /** - * Flush the operations from the tree operations from the argument - * queue unconditionally. - */ - virtual void ForcedFlush(nsTArray& aOpQueue) = 0; + virtual void MoveOpsFrom(nsTArray& aOpQueue) = 0; }; diff --git a/parser/html/nsHtml5AtomList.h b/parser/html/nsHtml5AtomList.h index b6b5a7042dbe..ca090f614dc0 100644 --- a/parser/html/nsHtml5AtomList.h +++ b/parser/html/nsHtml5AtomList.h @@ -2,13 +2,13 @@ HTML5_ATOM(emptystring, "") HTML5_ATOM(title, "title") HTML5_ATOM(textarea, "textarea") HTML5_ATOM(style, "style") -HTML5_ATOM(script, "script") HTML5_ATOM(xmp, "xmp") HTML5_ATOM(iframe, "iframe") HTML5_ATOM(noembed, "noembed") HTML5_ATOM(noframes, "noframes") HTML5_ATOM(noscript, "noscript") HTML5_ATOM(plaintext, "plaintext") +HTML5_ATOM(script, "script") HTML5_ATOM(table, "table") HTML5_ATOM(caption, "caption") HTML5_ATOM(p, "p") @@ -20,9 +20,11 @@ HTML5_ATOM(button, "button") HTML5_ATOM(input, "input") HTML5_ATOM(option, "option") HTML5_ATOM(ruby, "ruby") +HTML5_ATOM(select, "select") HTML5_ATOM(optgroup, "optgroup") HTML5_ATOM(frameset, "frameset") -HTML5_ATOM(select, "select") +HTML5_ATOM(ul, "ul") +HTML5_ATOM(ol, "ol") HTML5_ATOM(html, "html") HTML5_ATOM(td, "td") HTML5_ATOM(th, "th") @@ -711,12 +713,10 @@ HTML5_ATOM(mi, "mi") HTML5_ATOM(mn, "mn") HTML5_ATOM(mo, "mo") HTML5_ATOM(ms, "ms") -HTML5_ATOM(ol, "ol") HTML5_ATOM(or_, "or") HTML5_ATOM(pi, "pi") HTML5_ATOM(rp, "rp") HTML5_ATOM(tt, "tt") -HTML5_ATOM(ul, "ul") HTML5_ATOM(and_, "and") HTML5_ATOM(arg, "arg") HTML5_ATOM(abs, "abs") @@ -841,7 +841,6 @@ HTML5_ATOM(center, "center") HTML5_ATOM(canvas, "canvas") HTML5_ATOM(divide, "divide") HTML5_ATOM(degree, "degree") -HTML5_ATOM(dialog, "dialog") HTML5_ATOM(domain, "domain") HTML5_ATOM(exists, "exists") HTML5_ATOM(fetile, "fetile") @@ -849,6 +848,7 @@ HTML5_ATOM(feTile, "feTile") HTML5_ATOM(figure, "figure") HTML5_ATOM(forall, "forall") HTML5_ATOM(footer, "footer") +HTML5_ATOM(hgroup, "hgroup") HTML5_ATOM(header, "header") HTML5_ATOM(keygen, "keygen") HTML5_ATOM(lambda, "lambda") @@ -983,7 +983,6 @@ HTML5_ATOM(solidcolor, "solidcolor") HTML5_ATOM(altglyphdef, "altglyphdef") HTML5_ATOM(altGlyphDef, "altGlyphDef") HTML5_ATOM(determinant, "determinant") -HTML5_ATOM(eventsource, "eventsource") HTML5_ATOM(femergenode, "femergenode") HTML5_ATOM(feMergeNode, "feMergeNode") HTML5_ATOM(fecomposite, "fecomposite") diff --git a/parser/html/nsHtml5ElementName.cpp b/parser/html/nsHtml5ElementName.cpp index 04a20a34ade7..eed9a77e833b 100644 --- a/parser/html/nsHtml5ElementName.cpp +++ b/parser/html/nsHtml5ElementName.cpp @@ -131,7 +131,7 @@ nsHtml5ElementName::cloneElementName(nsHtml5AtomTable* interner) return this; } -static PRInt32 const ELEMENT_HASHES_DATA[] = { 1057, 1090, 1255, 1321, 1552, 1585, 1651, 1717, 68162, 68899, 69059, 69764, 70020, 70276, 71077, 71205, 72134, 72232, 72264, 72296, 72328, 72360, 72392, 73351, 74312, 75209, 78124, 78284, 78476, 79149, 79309, 79341, 79469, 81295, 81487, 82224, 84498, 84626, 86164, 86292, 86612, 86676, 87445, 3183041, 3186241, 3198017, 3218722, 3226754, 3247715, 3256803, 3263971, 3264995, 3289252, 3291332, 3295524, 3299620, 3326725, 3379303, 3392679, 3448233, 3460553, 3461577, 3510347, 3546604, 3552364, 3556524, 3576461, 3586349, 3588141, 3590797, 3596333, 3622062, 3625454, 3627054, 3675728, 3749042, 3771059, 3771571, 3776211, 3782323, 3782963, 3784883, 3785395, 3788979, 3815476, 3839605, 3885110, 3917911, 3948984, 3951096, 135304769, 135858241, 136498210, 136906434, 137138658, 137512995, 137531875, 137548067, 137629283, 137645539, 137646563, 137775779, 138529956, 138615076, 139040932, 140954086, 141179366, 141690439, 142738600, 143013512, 146979116, 147175724, 147475756, 147902637, 147936877, 148017645, 148131885, 148228141, 148229165, 148309165, 148395629, 148551853, 148618829, 149076462, 149490158, 149572782, 151277616, 151639440, 153268914, 153486514, 153563314, 153750706, 153763314, 153914034, 154406067, 154417459, 154600979, 154678323, 154680979, 154866835, 155366708, 155375188, 155391572, 155465780, 155869364, 158045494, 168988979, 169321621, 169652752, 173151309, 174240818, 174247297, 174669292, 175391532, 176638123, 177380397, 177879204, 177886734, 180753473, 181020073, 181503558, 181686320, 181999237, 181999311, 182048201, 182074866, 182078003, 182083764, 182920847, 184716457, 184976961, 185145071, 187281445, 187872052, 188100653, 188875944, 188919873, 188920457, 189203987, 189371817, 189414886, 189567458, 190266670, 191318187, 191337609, 202479203, 202493027, 202835587, 202843747, 203013219, 203036048, 203045987, 203177552, 203898516, 204648562, 205067918, 205078130, 205096654, 205689142, 205690439, 205766017, 205988909, 207213161, 207794484, 207800999, 208023602, 208213644, 208213647, 210310273, 210940978, 213325049, 213946445, 214055079, 215125040, 215134273, 215135028, 215237420, 215418148, 215553166, 215553394, 215563858, 215627949, 215754324, 217529652, 217713834, 217732628, 218731945, 221417045, 221424946, 221493746, 221515401, 221658189, 221844577, 221908140, 221910626, 221921586, 222659762, 225001091, 236105833, 236113965, 236194995, 236195427, 236206132, 236206387, 236211683, 236212707, 236381647, 236571826, 237124271, 238172205, 238210544, 238270764, 238435405, 238501172, 239224867, 239257644, 239710497, 240307721, 241208789, 241241557, 241318060, 241319404, 241343533, 241344069, 241405397, 241765845, 243864964, 244502085, 244946220, 245109902, 247647266, 247707956, 248648814, 248648836, 248682161, 248986932, 249058914, 249697357, 252132601, 252135604, 252317348, 255007012, 255278388, 256365156, 257566121, 269763372, 271202790, 271863856, 272049197, 272127474, 272770631, 274339449, 274939471, 275388004, 275388005, 275388006, 275977800, 278267602, 278513831, 278712622, 281613765, 281683369, 282120228, 282250732, 282508942, 283743649, 283787570, 284710386, 285391148, 285478533, 285854898, 285873762, 286931113, 288964227, 289445441, 289689648, 291671489, 303512884, 305319975, 305610036, 305764101, 308448294, 308675890, 312085683, 312264750, 315032867, 316391000, 317331042, 317902135, 318950711, 319447220, 321499182, 322538804, 323145200, 337067316, 337826293, 339905989, 340833697, 341457068, 345302593, 349554733, 349771471, 349786245, 350819405, 356072847, 370349192, 373962798, 374509141, 375558638, 375574835, 376053993, 383276530, 383373833, 383407586, 384439906, 386079012, 404133513, 404307343, 407031852, 408072233, 409112005, 409608425, 409771500, 419040932, 437730612, 439529766, 442616365, 442813037, 443157674, 443295316, 450118444, 450482697, 456789668, 459935396, 471217869, 474073645, 476230702, 476665218, 476717289, 483014825, 485083298, 489306281, 538364390, 540675748, 543819186, 543958612, 576960820, 577242548, 610515252, 642202932, 644420819 }; +static PRInt32 const ELEMENT_HASHES_DATA[] = { 1057, 1090, 1255, 1321, 1552, 1585, 1651, 1717, 68162, 68899, 69059, 69764, 70020, 70276, 71077, 71205, 72134, 72232, 72264, 72296, 72328, 72360, 72392, 73351, 74312, 75209, 78124, 78284, 78476, 79149, 79309, 79341, 79469, 81295, 81487, 82224, 84498, 84626, 86164, 86292, 86612, 86676, 87445, 3183041, 3186241, 3198017, 3218722, 3226754, 3247715, 3256803, 3263971, 3264995, 3289252, 3291332, 3295524, 3299620, 3326725, 3379303, 3392679, 3448233, 3460553, 3461577, 3510347, 3546604, 3552364, 3556524, 3576461, 3586349, 3588141, 3590797, 3596333, 3622062, 3625454, 3627054, 3675728, 3749042, 3771059, 3771571, 3776211, 3782323, 3782963, 3784883, 3785395, 3788979, 3815476, 3839605, 3885110, 3917911, 3948984, 3951096, 135304769, 135858241, 136498210, 136906434, 137138658, 137512995, 137531875, 137548067, 137629283, 137645539, 137646563, 137775779, 138529956, 138615076, 139040932, 140954086, 141179366, 141690439, 142738600, 143013512, 146979116, 147175724, 147475756, 147902637, 147936877, 148017645, 148131885, 148228141, 148229165, 148309165, 148395629, 148551853, 148618829, 149076462, 149490158, 149572782, 151277616, 151639440, 153268914, 153486514, 153563314, 153750706, 153763314, 153914034, 154406067, 154417459, 154600979, 154678323, 154680979, 154866835, 155366708, 155375188, 155391572, 155465780, 155869364, 158045494, 168988979, 169321621, 169652752, 173151309, 174240818, 174247297, 174669292, 175391532, 176638123, 177380397, 177879204, 177886734, 180753473, 181020073, 181503558, 181686320, 181999237, 181999311, 182048201, 182074866, 182078003, 182083764, 182920847, 184716457, 184976961, 185145071, 187281445, 187872052, 188100653, 188875944, 188919873, 188920457, 189203987, 189371817, 189414886, 189567458, 190266670, 191318187, 191337609, 202479203, 202493027, 202835587, 202843747, 203013219, 203036048, 203045987, 203177552, 203898516, 204648562, 205067918, 205078130, 205096654, 205689142, 205690439, 205988909, 207213161, 207794484, 207800999, 208023602, 208213644, 208213647, 210261490, 210310273, 210940978, 213325049, 213946445, 214055079, 215125040, 215134273, 215135028, 215237420, 215418148, 215553166, 215553394, 215563858, 215627949, 215754324, 217529652, 217713834, 217732628, 218731945, 221417045, 221424946, 221493746, 221515401, 221658189, 221844577, 221908140, 221910626, 221921586, 222659762, 225001091, 236105833, 236113965, 236194995, 236195427, 236206132, 236206387, 236211683, 236212707, 236381647, 236571826, 237124271, 238172205, 238210544, 238270764, 238435405, 238501172, 239224867, 239257644, 239710497, 240307721, 241208789, 241241557, 241318060, 241319404, 241343533, 241344069, 241405397, 241765845, 243864964, 244502085, 244946220, 245109902, 247647266, 247707956, 248648814, 248648836, 248682161, 248986932, 249058914, 249697357, 252132601, 252135604, 252317348, 255007012, 255278388, 256365156, 257566121, 269763372, 271202790, 271863856, 272049197, 272127474, 272770631, 274339449, 274939471, 275388004, 275388005, 275388006, 275977800, 278267602, 278513831, 278712622, 281613765, 281683369, 282120228, 282250732, 282508942, 283743649, 283787570, 284710386, 285391148, 285478533, 285854898, 285873762, 286931113, 288964227, 289445441, 289689648, 291671489, 303512884, 305319975, 305610036, 305764101, 308448294, 308675890, 312085683, 312264750, 315032867, 316391000, 317331042, 317902135, 318950711, 319447220, 321499182, 322538804, 323145200, 337067316, 337826293, 339905989, 340833697, 341457068, 345302593, 349554733, 349771471, 349786245, 350819405, 356072847, 370349192, 373962798, 375558638, 375574835, 376053993, 383276530, 383373833, 383407586, 384439906, 386079012, 404133513, 404307343, 407031852, 408072233, 409112005, 409608425, 409771500, 419040932, 437730612, 439529766, 442616365, 442813037, 443157674, 443295316, 450118444, 450482697, 456789668, 459935396, 471217869, 474073645, 476230702, 476665218, 476717289, 483014825, 485083298, 489306281, 538364390, 540675748, 543819186, 543958612, 576960820, 577242548, 610515252, 642202932, 644420819 }; void nsHtml5ElementName::initializeStatics() { @@ -190,7 +190,7 @@ nsHtml5ElementName::initializeStatics() ELT_COT = new nsHtml5ElementName(nsHtml5Atoms::cot, nsHtml5Atoms::cot, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); ELT_DEL = new nsHtml5ElementName(nsHtml5Atoms::del, nsHtml5Atoms::del, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); ELT_DFN = new nsHtml5ElementName(nsHtml5Atoms::dfn, nsHtml5Atoms::dfn, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); - ELT_DIR = new nsHtml5ElementName(nsHtml5Atoms::dir, nsHtml5Atoms::dir, NS_HTML5TREE_BUILDER_ADDRESS_OR_DIR_OR_ARTICLE_OR_ASIDE_OR_DATAGRID_OR_DETAILS_OR_DIALOG_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_NAV_OR_SECTION, PR_TRUE, PR_FALSE, PR_FALSE); + ELT_DIR = new nsHtml5ElementName(nsHtml5Atoms::dir, nsHtml5Atoms::dir, NS_HTML5TREE_BUILDER_ADDRESS_OR_DIR_OR_ARTICLE_OR_ASIDE_OR_DATAGRID_OR_DETAILS_OR_HGROUP_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_NAV_OR_SECTION, PR_TRUE, PR_FALSE, PR_FALSE); ELT_DIV = new nsHtml5ElementName(nsHtml5Atoms::div, nsHtml5Atoms::div, NS_HTML5TREE_BUILDER_DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU, PR_TRUE, PR_FALSE, PR_FALSE); ELT_EXP = new nsHtml5ElementName(nsHtml5Atoms::exp, nsHtml5Atoms::exp, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); ELT_GCD = new nsHtml5ElementName(nsHtml5Atoms::gcd, nsHtml5Atoms::gcd, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); @@ -209,7 +209,7 @@ nsHtml5ElementName::initializeStatics() ELT_MAX = new nsHtml5ElementName(nsHtml5Atoms::max, nsHtml5Atoms::max, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); ELT_NEQ = new nsHtml5ElementName(nsHtml5Atoms::neq, nsHtml5Atoms::neq, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); ELT_NOT = new nsHtml5ElementName(nsHtml5Atoms::not_, nsHtml5Atoms::not_, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); - ELT_NAV = new nsHtml5ElementName(nsHtml5Atoms::nav, nsHtml5Atoms::nav, NS_HTML5TREE_BUILDER_ADDRESS_OR_DIR_OR_ARTICLE_OR_ASIDE_OR_DATAGRID_OR_DETAILS_OR_DIALOG_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_NAV_OR_SECTION, PR_TRUE, PR_FALSE, PR_FALSE); + ELT_NAV = new nsHtml5ElementName(nsHtml5Atoms::nav, nsHtml5Atoms::nav, NS_HTML5TREE_BUILDER_ADDRESS_OR_DIR_OR_ARTICLE_OR_ASIDE_OR_DATAGRID_OR_DETAILS_OR_HGROUP_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_NAV_OR_SECTION, PR_TRUE, PR_FALSE, PR_FALSE); ELT_PRE = new nsHtml5ElementName(nsHtml5Atoms::pre, nsHtml5Atoms::pre, NS_HTML5TREE_BUILDER_PRE_OR_LISTING, PR_TRUE, PR_FALSE, PR_FALSE); ELT_REM = new nsHtml5ElementName(nsHtml5Atoms::rem, nsHtml5Atoms::rem, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); ELT_SUB = new nsHtml5ElementName(nsHtml5Atoms::sub, nsHtml5Atoms::sub, NS_HTML5TREE_BUILDER_RUBY_OR_SPAN_OR_SUB_OR_SUP_OR_VAR, PR_FALSE, PR_FALSE, PR_FALSE); @@ -282,7 +282,7 @@ nsHtml5ElementName::initializeStatics() ELT_TANH = new nsHtml5ElementName(nsHtml5Atoms::tanh, nsHtml5Atoms::tanh, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); ELT_TEXT = new nsHtml5ElementName(nsHtml5Atoms::text, nsHtml5Atoms::text, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); ELT_VIEW = new nsHtml5ElementName(nsHtml5Atoms::view, nsHtml5Atoms::view, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); - ELT_ASIDE = new nsHtml5ElementName(nsHtml5Atoms::aside, nsHtml5Atoms::aside, NS_HTML5TREE_BUILDER_ADDRESS_OR_DIR_OR_ARTICLE_OR_ASIDE_OR_DATAGRID_OR_DETAILS_OR_DIALOG_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_NAV_OR_SECTION, PR_TRUE, PR_FALSE, PR_FALSE); + ELT_ASIDE = new nsHtml5ElementName(nsHtml5Atoms::aside, nsHtml5Atoms::aside, NS_HTML5TREE_BUILDER_ADDRESS_OR_DIR_OR_ARTICLE_OR_ASIDE_OR_DATAGRID_OR_DETAILS_OR_HGROUP_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_NAV_OR_SECTION, PR_TRUE, PR_FALSE, PR_FALSE); ELT_AUDIO = new nsHtml5ElementName(nsHtml5Atoms::audio, nsHtml5Atoms::audio, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); ELT_APPLY = new nsHtml5ElementName(nsHtml5Atoms::apply, nsHtml5Atoms::apply, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); ELT_EMBED = new nsHtml5ElementName(nsHtml5Atoms::embed, nsHtml5Atoms::embed, NS_HTML5TREE_BUILDER_EMBED_OR_IMG, PR_TRUE, PR_FALSE, PR_FALSE); @@ -336,15 +336,15 @@ nsHtml5ElementName::initializeStatics() ELT_CANVAS = new nsHtml5ElementName(nsHtml5Atoms::canvas, nsHtml5Atoms::canvas, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); ELT_DIVIDE = new nsHtml5ElementName(nsHtml5Atoms::divide, nsHtml5Atoms::divide, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); ELT_DEGREE = new nsHtml5ElementName(nsHtml5Atoms::degree, nsHtml5Atoms::degree, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); - ELT_DIALOG = new nsHtml5ElementName(nsHtml5Atoms::dialog, nsHtml5Atoms::dialog, NS_HTML5TREE_BUILDER_ADDRESS_OR_DIR_OR_ARTICLE_OR_ASIDE_OR_DATAGRID_OR_DETAILS_OR_DIALOG_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_NAV_OR_SECTION, PR_TRUE, PR_FALSE, PR_FALSE); ELT_DOMAIN = new nsHtml5ElementName(nsHtml5Atoms::domain, nsHtml5Atoms::domain, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); ELT_EXISTS = new nsHtml5ElementName(nsHtml5Atoms::exists, nsHtml5Atoms::exists, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); ELT_FETILE = new nsHtml5ElementName(nsHtml5Atoms::fetile, nsHtml5Atoms::feTile, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); - ELT_FIGURE = new nsHtml5ElementName(nsHtml5Atoms::figure, nsHtml5Atoms::figure, NS_HTML5TREE_BUILDER_ADDRESS_OR_DIR_OR_ARTICLE_OR_ASIDE_OR_DATAGRID_OR_DETAILS_OR_DIALOG_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_NAV_OR_SECTION, PR_TRUE, PR_FALSE, PR_FALSE); + ELT_FIGURE = new nsHtml5ElementName(nsHtml5Atoms::figure, nsHtml5Atoms::figure, NS_HTML5TREE_BUILDER_ADDRESS_OR_DIR_OR_ARTICLE_OR_ASIDE_OR_DATAGRID_OR_DETAILS_OR_HGROUP_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_NAV_OR_SECTION, PR_TRUE, PR_FALSE, PR_FALSE); ELT_FORALL = new nsHtml5ElementName(nsHtml5Atoms::forall, nsHtml5Atoms::forall, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); ELT_FILTER = new nsHtml5ElementName(nsHtml5Atoms::filter, nsHtml5Atoms::filter, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); - ELT_FOOTER = new nsHtml5ElementName(nsHtml5Atoms::footer, nsHtml5Atoms::footer, NS_HTML5TREE_BUILDER_ADDRESS_OR_DIR_OR_ARTICLE_OR_ASIDE_OR_DATAGRID_OR_DETAILS_OR_DIALOG_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_NAV_OR_SECTION, PR_TRUE, PR_FALSE, PR_FALSE); - ELT_HEADER = new nsHtml5ElementName(nsHtml5Atoms::header, nsHtml5Atoms::header, NS_HTML5TREE_BUILDER_ADDRESS_OR_DIR_OR_ARTICLE_OR_ASIDE_OR_DATAGRID_OR_DETAILS_OR_DIALOG_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_NAV_OR_SECTION, PR_TRUE, PR_FALSE, PR_FALSE); + ELT_FOOTER = new nsHtml5ElementName(nsHtml5Atoms::footer, nsHtml5Atoms::footer, NS_HTML5TREE_BUILDER_ADDRESS_OR_DIR_OR_ARTICLE_OR_ASIDE_OR_DATAGRID_OR_DETAILS_OR_HGROUP_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_NAV_OR_SECTION, PR_TRUE, PR_FALSE, PR_FALSE); + ELT_HGROUP = new nsHtml5ElementName(nsHtml5Atoms::hgroup, nsHtml5Atoms::hgroup, NS_HTML5TREE_BUILDER_ADDRESS_OR_DIR_OR_ARTICLE_OR_ASIDE_OR_DATAGRID_OR_DETAILS_OR_HGROUP_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_NAV_OR_SECTION, PR_TRUE, PR_FALSE, PR_FALSE); + ELT_HEADER = new nsHtml5ElementName(nsHtml5Atoms::header, nsHtml5Atoms::header, NS_HTML5TREE_BUILDER_ADDRESS_OR_DIR_OR_ARTICLE_OR_ASIDE_OR_DATAGRID_OR_DETAILS_OR_HGROUP_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_NAV_OR_SECTION, PR_TRUE, PR_FALSE, PR_FALSE); ELT_IFRAME = new nsHtml5ElementName(nsHtml5Atoms::iframe, nsHtml5Atoms::iframe, NS_HTML5TREE_BUILDER_IFRAME, PR_TRUE, PR_FALSE, PR_FALSE); ELT_KEYGEN = new nsHtml5ElementName(nsHtml5Atoms::keygen, nsHtml5Atoms::keygen, NS_HTML5TREE_BUILDER_KEYGEN, PR_TRUE, PR_FALSE, PR_FALSE); ELT_LAMBDA = new nsHtml5ElementName(nsHtml5Atoms::lambda, nsHtml5Atoms::lambda, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); @@ -374,7 +374,7 @@ nsHtml5ElementName::initializeStatics() ELT_SCRIPT = new nsHtml5ElementName(nsHtml5Atoms::script, nsHtml5Atoms::script, NS_HTML5TREE_BUILDER_SCRIPT, PR_TRUE, PR_FALSE, PR_FALSE); ELT_TBREAK = new nsHtml5ElementName(nsHtml5Atoms::tbreak, nsHtml5Atoms::tbreak, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); ELT_VECTOR = new nsHtml5ElementName(nsHtml5Atoms::vector, nsHtml5Atoms::vector, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); - ELT_ARTICLE = new nsHtml5ElementName(nsHtml5Atoms::article, nsHtml5Atoms::article, NS_HTML5TREE_BUILDER_ADDRESS_OR_DIR_OR_ARTICLE_OR_ASIDE_OR_DATAGRID_OR_DETAILS_OR_DIALOG_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_NAV_OR_SECTION, PR_TRUE, PR_FALSE, PR_FALSE); + ELT_ARTICLE = new nsHtml5ElementName(nsHtml5Atoms::article, nsHtml5Atoms::article, NS_HTML5TREE_BUILDER_ADDRESS_OR_DIR_OR_ARTICLE_OR_ASIDE_OR_DATAGRID_OR_DETAILS_OR_HGROUP_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_NAV_OR_SECTION, PR_TRUE, PR_FALSE, PR_FALSE); ELT_ANIMATE = new nsHtml5ElementName(nsHtml5Atoms::animate, nsHtml5Atoms::animate, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); ELT_ARCSECH = new nsHtml5ElementName(nsHtml5Atoms::arcsech, nsHtml5Atoms::arcsech, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); ELT_ARCCSCH = new nsHtml5ElementName(nsHtml5Atoms::arccsch, nsHtml5Atoms::arccsch, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); @@ -383,16 +383,16 @@ nsHtml5ElementName::initializeStatics() ELT_ARCCOSH = new nsHtml5ElementName(nsHtml5Atoms::arccosh, nsHtml5Atoms::arccosh, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); ELT_ARCCOTH = new nsHtml5ElementName(nsHtml5Atoms::arccoth, nsHtml5Atoms::arccoth, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); ELT_ACRONYM = new nsHtml5ElementName(nsHtml5Atoms::acronym, nsHtml5Atoms::acronym, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); - ELT_ADDRESS = new nsHtml5ElementName(nsHtml5Atoms::address, nsHtml5Atoms::address, NS_HTML5TREE_BUILDER_ADDRESS_OR_DIR_OR_ARTICLE_OR_ASIDE_OR_DATAGRID_OR_DETAILS_OR_DIALOG_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_NAV_OR_SECTION, PR_TRUE, PR_FALSE, PR_FALSE); + ELT_ADDRESS = new nsHtml5ElementName(nsHtml5Atoms::address, nsHtml5Atoms::address, NS_HTML5TREE_BUILDER_ADDRESS_OR_DIR_OR_ARTICLE_OR_ASIDE_OR_DATAGRID_OR_DETAILS_OR_HGROUP_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_NAV_OR_SECTION, PR_TRUE, PR_FALSE, PR_FALSE); ELT_BGSOUND = new nsHtml5ElementName(nsHtml5Atoms::bgsound, nsHtml5Atoms::bgsound, NS_HTML5TREE_BUILDER_AREA_OR_BASEFONT_OR_BGSOUND_OR_SPACER_OR_WBR, PR_TRUE, PR_FALSE, PR_FALSE); - ELT_COMMAND = new nsHtml5ElementName(nsHtml5Atoms::command, nsHtml5Atoms::command, NS_HTML5TREE_BUILDER_COMMAND_OR_EVENT_SOURCE, PR_TRUE, PR_FALSE, PR_FALSE); + ELT_COMMAND = new nsHtml5ElementName(nsHtml5Atoms::command, nsHtml5Atoms::command, NS_HTML5TREE_BUILDER_COMMAND, PR_TRUE, PR_FALSE, PR_FALSE); ELT_COMPOSE = new nsHtml5ElementName(nsHtml5Atoms::compose, nsHtml5Atoms::compose, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); ELT_CEILING = new nsHtml5ElementName(nsHtml5Atoms::ceiling, nsHtml5Atoms::ceiling, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); ELT_CSYMBOL = new nsHtml5ElementName(nsHtml5Atoms::csymbol, nsHtml5Atoms::csymbol, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); ELT_CAPTION = new nsHtml5ElementName(nsHtml5Atoms::caption, nsHtml5Atoms::caption, NS_HTML5TREE_BUILDER_CAPTION, PR_FALSE, PR_TRUE, PR_FALSE); ELT_DISCARD = new nsHtml5ElementName(nsHtml5Atoms::discard, nsHtml5Atoms::discard, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); ELT_DECLARE = new nsHtml5ElementName(nsHtml5Atoms::declare, nsHtml5Atoms::declare, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); - ELT_DETAILS = new nsHtml5ElementName(nsHtml5Atoms::details, nsHtml5Atoms::details, NS_HTML5TREE_BUILDER_ADDRESS_OR_DIR_OR_ARTICLE_OR_ASIDE_OR_DATAGRID_OR_DETAILS_OR_DIALOG_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_NAV_OR_SECTION, PR_TRUE, PR_FALSE, PR_FALSE); + ELT_DETAILS = new nsHtml5ElementName(nsHtml5Atoms::details, nsHtml5Atoms::details, NS_HTML5TREE_BUILDER_ADDRESS_OR_DIR_OR_ARTICLE_OR_ASIDE_OR_DATAGRID_OR_DETAILS_OR_HGROUP_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_NAV_OR_SECTION, PR_TRUE, PR_FALSE, PR_FALSE); ELT_ELLIPSE = new nsHtml5ElementName(nsHtml5Atoms::ellipse, nsHtml5Atoms::ellipse, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); ELT_FEFUNCA = new nsHtml5ElementName(nsHtml5Atoms::fefunca, nsHtml5Atoms::feFuncA, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); ELT_FEFUNCB = new nsHtml5ElementName(nsHtml5Atoms::fefuncb, nsHtml5Atoms::feFuncB, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); @@ -418,7 +418,7 @@ nsHtml5ElementName::initializeStatics() ELT_PATTERN = new nsHtml5ElementName(nsHtml5Atoms::pattern, nsHtml5Atoms::pattern, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); ELT_PRODUCT = new nsHtml5ElementName(nsHtml5Atoms::product, nsHtml5Atoms::product, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); ELT_SETDIFF = new nsHtml5ElementName(nsHtml5Atoms::setdiff, nsHtml5Atoms::setdiff, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); - ELT_SECTION = new nsHtml5ElementName(nsHtml5Atoms::section, nsHtml5Atoms::section, NS_HTML5TREE_BUILDER_ADDRESS_OR_DIR_OR_ARTICLE_OR_ASIDE_OR_DATAGRID_OR_DETAILS_OR_DIALOG_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_NAV_OR_SECTION, PR_TRUE, PR_FALSE, PR_FALSE); + ELT_SECTION = new nsHtml5ElementName(nsHtml5Atoms::section, nsHtml5Atoms::section, NS_HTML5TREE_BUILDER_ADDRESS_OR_DIR_OR_ARTICLE_OR_ASIDE_OR_DATAGRID_OR_DETAILS_OR_HGROUP_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_NAV_OR_SECTION, PR_TRUE, PR_FALSE, PR_FALSE); ELT_TENDSTO = new nsHtml5ElementName(nsHtml5Atoms::tendsto, nsHtml5Atoms::tendsto, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); ELT_UPLIMIT = new nsHtml5ElementName(nsHtml5Atoms::uplimit, nsHtml5Atoms::uplimit, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); ELT_ALTGLYPH = new nsHtml5ElementName(nsHtml5Atoms::altglyph, nsHtml5Atoms::altGlyph, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); @@ -426,7 +426,7 @@ nsHtml5ElementName::initializeStatics() ELT_CLIPPATH = new nsHtml5ElementName(nsHtml5Atoms::clippath, nsHtml5Atoms::clipPath, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); ELT_CODOMAIN = new nsHtml5ElementName(nsHtml5Atoms::codomain, nsHtml5Atoms::codomain, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); ELT_COLGROUP = new nsHtml5ElementName(nsHtml5Atoms::colgroup, nsHtml5Atoms::colgroup, NS_HTML5TREE_BUILDER_COLGROUP, PR_TRUE, PR_FALSE, PR_FALSE); - ELT_DATAGRID = new nsHtml5ElementName(nsHtml5Atoms::datagrid, nsHtml5Atoms::datagrid, NS_HTML5TREE_BUILDER_ADDRESS_OR_DIR_OR_ARTICLE_OR_ASIDE_OR_DATAGRID_OR_DETAILS_OR_DIALOG_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_NAV_OR_SECTION, PR_TRUE, PR_FALSE, PR_FALSE); + ELT_DATAGRID = new nsHtml5ElementName(nsHtml5Atoms::datagrid, nsHtml5Atoms::datagrid, NS_HTML5TREE_BUILDER_ADDRESS_OR_DIR_OR_ARTICLE_OR_ASIDE_OR_DATAGRID_OR_DETAILS_OR_HGROUP_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_NAV_OR_SECTION, PR_TRUE, PR_FALSE, PR_FALSE); ELT_EMPTYSET = new nsHtml5ElementName(nsHtml5Atoms::emptyset, nsHtml5Atoms::emptyset, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); ELT_FACTOROF = new nsHtml5ElementName(nsHtml5Atoms::factorof, nsHtml5Atoms::factorof, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); ELT_FIELDSET = new nsHtml5ElementName(nsHtml5Atoms::fieldset, nsHtml5Atoms::fieldset, NS_HTML5TREE_BUILDER_FIELDSET, PR_TRUE, PR_FALSE, PR_FALSE); @@ -483,7 +483,6 @@ nsHtml5ElementName::initializeStatics() ELT_SOLIDCOLOR = new nsHtml5ElementName(nsHtml5Atoms::solidcolor, nsHtml5Atoms::solidcolor, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); ELT_ALTGLYPHDEF = new nsHtml5ElementName(nsHtml5Atoms::altglyphdef, nsHtml5Atoms::altGlyphDef, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); ELT_DETERMINANT = new nsHtml5ElementName(nsHtml5Atoms::determinant, nsHtml5Atoms::determinant, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); - ELT_EVENTSOURCE = new nsHtml5ElementName(nsHtml5Atoms::eventsource, nsHtml5Atoms::eventsource, NS_HTML5TREE_BUILDER_COMMAND_OR_EVENT_SOURCE, PR_TRUE, PR_FALSE, PR_FALSE); ELT_FEMERGENODE = new nsHtml5ElementName(nsHtml5Atoms::femergenode, nsHtml5Atoms::feMergeNode, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); ELT_FECOMPOSITE = new nsHtml5ElementName(nsHtml5Atoms::fecomposite, nsHtml5Atoms::feComposite, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); ELT_FESPOTLIGHT = new nsHtml5ElementName(nsHtml5Atoms::fespotlight, nsHtml5Atoms::feSpotLight, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); @@ -527,7 +526,7 @@ nsHtml5ElementName::initializeStatics() ELT_FESPECULARLIGHTING = new nsHtml5ElementName(nsHtml5Atoms::fespecularlighting, nsHtml5Atoms::feSpecularLighting, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); ELT_DOMAINOFAPPLICATION = new nsHtml5ElementName(nsHtml5Atoms::domainofapplication, nsHtml5Atoms::domainofapplication, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); ELT_FECOMPONENTTRANSFER = new nsHtml5ElementName(nsHtml5Atoms::fecomponenttransfer, nsHtml5Atoms::feComponentTransfer, NS_HTML5TREE_BUILDER_OTHER, PR_FALSE, PR_FALSE, PR_FALSE); - ELEMENT_NAMES = new nsHtml5ElementName*[391]; + ELEMENT_NAMES = new nsHtml5ElementName*[390]; ELEMENT_NAMES[0] = ELT_A; ELEMENT_NAMES[1] = ELT_B; ELEMENT_NAMES[2] = ELT_G; @@ -728,14 +727,14 @@ nsHtml5ElementName::initializeStatics() ELEMENT_NAMES[197] = ELT_CANVAS; ELEMENT_NAMES[198] = ELT_DIVIDE; ELEMENT_NAMES[199] = ELT_DEGREE; - ELEMENT_NAMES[200] = ELT_DIALOG; - ELEMENT_NAMES[201] = ELT_DOMAIN; - ELEMENT_NAMES[202] = ELT_EXISTS; - ELEMENT_NAMES[203] = ELT_FETILE; - ELEMENT_NAMES[204] = ELT_FIGURE; - ELEMENT_NAMES[205] = ELT_FORALL; - ELEMENT_NAMES[206] = ELT_FILTER; - ELEMENT_NAMES[207] = ELT_FOOTER; + ELEMENT_NAMES[200] = ELT_DOMAIN; + ELEMENT_NAMES[201] = ELT_EXISTS; + ELEMENT_NAMES[202] = ELT_FETILE; + ELEMENT_NAMES[203] = ELT_FIGURE; + ELEMENT_NAMES[204] = ELT_FORALL; + ELEMENT_NAMES[205] = ELT_FILTER; + ELEMENT_NAMES[206] = ELT_FOOTER; + ELEMENT_NAMES[207] = ELT_HGROUP; ELEMENT_NAMES[208] = ELT_HEADER; ELEMENT_NAMES[209] = ELT_IFRAME; ELEMENT_NAMES[210] = ELT_KEYGEN; @@ -875,51 +874,50 @@ nsHtml5ElementName::initializeStatics() ELEMENT_NAMES[344] = ELT_SOLIDCOLOR; ELEMENT_NAMES[345] = ELT_ALTGLYPHDEF; ELEMENT_NAMES[346] = ELT_DETERMINANT; - ELEMENT_NAMES[347] = ELT_EVENTSOURCE; - ELEMENT_NAMES[348] = ELT_FEMERGENODE; - ELEMENT_NAMES[349] = ELT_FECOMPOSITE; - ELEMENT_NAMES[350] = ELT_FESPOTLIGHT; - ELEMENT_NAMES[351] = ELT_MALIGNGROUP; - ELEMENT_NAMES[352] = ELT_MPRESCRIPTS; - ELEMENT_NAMES[353] = ELT_MOMENTABOUT; - ELEMENT_NAMES[354] = ELT_NOTPRSUBSET; - ELEMENT_NAMES[355] = ELT_PARTIALDIFF; - ELEMENT_NAMES[356] = ELT_ALTGLYPHITEM; - ELEMENT_NAMES[357] = ELT_ANIMATECOLOR; - ELEMENT_NAMES[358] = ELT_DATATEMPLATE; - ELEMENT_NAMES[359] = ELT_EXPONENTIALE; - ELEMENT_NAMES[360] = ELT_FETURBULENCE; - ELEMENT_NAMES[361] = ELT_FEPOINTLIGHT; - ELEMENT_NAMES[362] = ELT_FEMORPHOLOGY; - ELEMENT_NAMES[363] = ELT_OUTERPRODUCT; - ELEMENT_NAMES[364] = ELT_ANIMATEMOTION; - ELEMENT_NAMES[365] = ELT_COLOR_PROFILE; - ELEMENT_NAMES[366] = ELT_FONT_FACE_SRC; - ELEMENT_NAMES[367] = ELT_FONT_FACE_URI; - ELEMENT_NAMES[368] = ELT_FOREIGNOBJECT; - ELEMENT_NAMES[369] = ELT_FECOLORMATRIX; - ELEMENT_NAMES[370] = ELT_MISSING_GLYPH; - ELEMENT_NAMES[371] = ELT_MMULTISCRIPTS; - ELEMENT_NAMES[372] = ELT_SCALARPRODUCT; - ELEMENT_NAMES[373] = ELT_VECTORPRODUCT; - ELEMENT_NAMES[374] = ELT_ANNOTATION_XML; - ELEMENT_NAMES[375] = ELT_DEFINITION_SRC; - ELEMENT_NAMES[376] = ELT_FONT_FACE_NAME; - ELEMENT_NAMES[377] = ELT_FEGAUSSIANBLUR; - ELEMENT_NAMES[378] = ELT_FEDISTANTLIGHT; - ELEMENT_NAMES[379] = ELT_LINEARGRADIENT; - ELEMENT_NAMES[380] = ELT_NATURALNUMBERS; - ELEMENT_NAMES[381] = ELT_RADIALGRADIENT; - ELEMENT_NAMES[382] = ELT_ANIMATETRANSFORM; - ELEMENT_NAMES[383] = ELT_CARTESIANPRODUCT; - ELEMENT_NAMES[384] = ELT_FONT_FACE_FORMAT; - ELEMENT_NAMES[385] = ELT_FECONVOLVEMATRIX; - ELEMENT_NAMES[386] = ELT_FEDIFFUSELIGHTING; - ELEMENT_NAMES[387] = ELT_FEDISPLACEMENTMAP; - ELEMENT_NAMES[388] = ELT_FESPECULARLIGHTING; - ELEMENT_NAMES[389] = ELT_DOMAINOFAPPLICATION; - ELEMENT_NAMES[390] = ELT_FECOMPONENTTRANSFER; - ELEMENT_HASHES = jArray((PRInt32*)ELEMENT_HASHES_DATA, 391); + ELEMENT_NAMES[347] = ELT_FEMERGENODE; + ELEMENT_NAMES[348] = ELT_FECOMPOSITE; + ELEMENT_NAMES[349] = ELT_FESPOTLIGHT; + ELEMENT_NAMES[350] = ELT_MALIGNGROUP; + ELEMENT_NAMES[351] = ELT_MPRESCRIPTS; + ELEMENT_NAMES[352] = ELT_MOMENTABOUT; + ELEMENT_NAMES[353] = ELT_NOTPRSUBSET; + ELEMENT_NAMES[354] = ELT_PARTIALDIFF; + ELEMENT_NAMES[355] = ELT_ALTGLYPHITEM; + ELEMENT_NAMES[356] = ELT_ANIMATECOLOR; + ELEMENT_NAMES[357] = ELT_DATATEMPLATE; + ELEMENT_NAMES[358] = ELT_EXPONENTIALE; + ELEMENT_NAMES[359] = ELT_FETURBULENCE; + ELEMENT_NAMES[360] = ELT_FEPOINTLIGHT; + ELEMENT_NAMES[361] = ELT_FEMORPHOLOGY; + ELEMENT_NAMES[362] = ELT_OUTERPRODUCT; + ELEMENT_NAMES[363] = ELT_ANIMATEMOTION; + ELEMENT_NAMES[364] = ELT_COLOR_PROFILE; + ELEMENT_NAMES[365] = ELT_FONT_FACE_SRC; + ELEMENT_NAMES[366] = ELT_FONT_FACE_URI; + ELEMENT_NAMES[367] = ELT_FOREIGNOBJECT; + ELEMENT_NAMES[368] = ELT_FECOLORMATRIX; + ELEMENT_NAMES[369] = ELT_MISSING_GLYPH; + ELEMENT_NAMES[370] = ELT_MMULTISCRIPTS; + ELEMENT_NAMES[371] = ELT_SCALARPRODUCT; + ELEMENT_NAMES[372] = ELT_VECTORPRODUCT; + ELEMENT_NAMES[373] = ELT_ANNOTATION_XML; + ELEMENT_NAMES[374] = ELT_DEFINITION_SRC; + ELEMENT_NAMES[375] = ELT_FONT_FACE_NAME; + ELEMENT_NAMES[376] = ELT_FEGAUSSIANBLUR; + ELEMENT_NAMES[377] = ELT_FEDISTANTLIGHT; + ELEMENT_NAMES[378] = ELT_LINEARGRADIENT; + ELEMENT_NAMES[379] = ELT_NATURALNUMBERS; + ELEMENT_NAMES[380] = ELT_RADIALGRADIENT; + ELEMENT_NAMES[381] = ELT_ANIMATETRANSFORM; + ELEMENT_NAMES[382] = ELT_CARTESIANPRODUCT; + ELEMENT_NAMES[383] = ELT_FONT_FACE_FORMAT; + ELEMENT_NAMES[384] = ELT_FECONVOLVEMATRIX; + ELEMENT_NAMES[385] = ELT_FEDIFFUSELIGHTING; + ELEMENT_NAMES[386] = ELT_FEDISPLACEMENTMAP; + ELEMENT_NAMES[387] = ELT_FESPECULARLIGHTING; + ELEMENT_NAMES[388] = ELT_DOMAINOFAPPLICATION; + ELEMENT_NAMES[389] = ELT_FECOMPONENTTRANSFER; + ELEMENT_HASHES = jArray((PRInt32*)ELEMENT_HASHES_DATA, 390); } void @@ -1126,7 +1124,6 @@ nsHtml5ElementName::releaseStatics() delete ELT_CANVAS; delete ELT_DIVIDE; delete ELT_DEGREE; - delete ELT_DIALOG; delete ELT_DOMAIN; delete ELT_EXISTS; delete ELT_FETILE; @@ -1134,6 +1131,7 @@ nsHtml5ElementName::releaseStatics() delete ELT_FORALL; delete ELT_FILTER; delete ELT_FOOTER; + delete ELT_HGROUP; delete ELT_HEADER; delete ELT_IFRAME; delete ELT_KEYGEN; @@ -1273,7 +1271,6 @@ nsHtml5ElementName::releaseStatics() delete ELT_SOLIDCOLOR; delete ELT_ALTGLYPHDEF; delete ELT_DETERMINANT; - delete ELT_EVENTSOURCE; delete ELT_FEMERGENODE; delete ELT_FECOMPOSITE; delete ELT_FESPOTLIGHT; diff --git a/parser/html/nsHtml5ElementName.h b/parser/html/nsHtml5ElementName.h index 08865a877175..bff02370f585 100644 --- a/parser/html/nsHtml5ElementName.h +++ b/parser/html/nsHtml5ElementName.h @@ -278,7 +278,6 @@ class nsHtml5ElementName static nsHtml5ElementName* ELT_CANVAS; static nsHtml5ElementName* ELT_DIVIDE; static nsHtml5ElementName* ELT_DEGREE; - static nsHtml5ElementName* ELT_DIALOG; static nsHtml5ElementName* ELT_DOMAIN; static nsHtml5ElementName* ELT_EXISTS; static nsHtml5ElementName* ELT_FETILE; @@ -286,6 +285,7 @@ class nsHtml5ElementName static nsHtml5ElementName* ELT_FORALL; static nsHtml5ElementName* ELT_FILTER; static nsHtml5ElementName* ELT_FOOTER; + static nsHtml5ElementName* ELT_HGROUP; static nsHtml5ElementName* ELT_HEADER; static nsHtml5ElementName* ELT_IFRAME; static nsHtml5ElementName* ELT_KEYGEN; @@ -425,7 +425,6 @@ class nsHtml5ElementName static nsHtml5ElementName* ELT_SOLIDCOLOR; static nsHtml5ElementName* ELT_ALTGLYPHDEF; static nsHtml5ElementName* ELT_DETERMINANT; - static nsHtml5ElementName* ELT_EVENTSOURCE; static nsHtml5ElementName* ELT_FEMERGENODE; static nsHtml5ElementName* ELT_FECOMPOSITE; static nsHtml5ElementName* ELT_FESPOTLIGHT; @@ -679,7 +678,6 @@ nsHtml5ElementName* nsHtml5ElementName::ELT_CURSOR = nsnull; nsHtml5ElementName* nsHtml5ElementName::ELT_CANVAS = nsnull; nsHtml5ElementName* nsHtml5ElementName::ELT_DIVIDE = nsnull; nsHtml5ElementName* nsHtml5ElementName::ELT_DEGREE = nsnull; -nsHtml5ElementName* nsHtml5ElementName::ELT_DIALOG = nsnull; nsHtml5ElementName* nsHtml5ElementName::ELT_DOMAIN = nsnull; nsHtml5ElementName* nsHtml5ElementName::ELT_EXISTS = nsnull; nsHtml5ElementName* nsHtml5ElementName::ELT_FETILE = nsnull; @@ -687,6 +685,7 @@ nsHtml5ElementName* nsHtml5ElementName::ELT_FIGURE = nsnull; nsHtml5ElementName* nsHtml5ElementName::ELT_FORALL = nsnull; nsHtml5ElementName* nsHtml5ElementName::ELT_FILTER = nsnull; nsHtml5ElementName* nsHtml5ElementName::ELT_FOOTER = nsnull; +nsHtml5ElementName* nsHtml5ElementName::ELT_HGROUP = nsnull; nsHtml5ElementName* nsHtml5ElementName::ELT_HEADER = nsnull; nsHtml5ElementName* nsHtml5ElementName::ELT_IFRAME = nsnull; nsHtml5ElementName* nsHtml5ElementName::ELT_KEYGEN = nsnull; @@ -826,7 +825,6 @@ nsHtml5ElementName* nsHtml5ElementName::ELT_NOTANUMBER = nsnull; nsHtml5ElementName* nsHtml5ElementName::ELT_SOLIDCOLOR = nsnull; nsHtml5ElementName* nsHtml5ElementName::ELT_ALTGLYPHDEF = nsnull; nsHtml5ElementName* nsHtml5ElementName::ELT_DETERMINANT = nsnull; -nsHtml5ElementName* nsHtml5ElementName::ELT_EVENTSOURCE = nsnull; nsHtml5ElementName* nsHtml5ElementName::ELT_FEMERGENODE = nsnull; nsHtml5ElementName* nsHtml5ElementName::ELT_FECOMPOSITE = nsnull; nsHtml5ElementName* nsHtml5ElementName::ELT_FESPOTLIGHT = nsnull; diff --git a/parser/html/nsHtml5Module.cpp b/parser/html/nsHtml5Module.cpp index daad73913b9e..bdf462253c38 100644 --- a/parser/html/nsHtml5Module.cpp +++ b/parser/html/nsHtml5Module.cpp @@ -46,6 +46,8 @@ #include "nsHtml5TreeBuilder.h" #include "nsHtml5UTF16Buffer.h" #include "nsHtml5Module.h" +#include "nsIObserverService.h" +#include "nsIServiceManager.h" // static PRBool nsHtml5Module::sEnabled = PR_FALSE; @@ -69,6 +71,7 @@ nsHtml5Module::InitializeStatics() nsHtml5Tokenizer::initializeStatics(); nsHtml5TreeBuilder::initializeStatics(); nsHtml5UTF16Buffer::initializeStatics(); + nsHtml5StreamParser::InitializeStatics(); #ifdef DEBUG sNsHtml5ModuleInitialized = PR_TRUE; #endif @@ -90,9 +93,6 @@ nsHtml5Module::ReleaseStatics() nsHtml5Tokenizer::releaseStatics(); nsHtml5TreeBuilder::releaseStatics(); nsHtml5UTF16Buffer::releaseStatics(); - if (sStreamParserThread) { - sStreamParserThread->Shutdown(); - } NS_IF_RELEASE(sStreamParserThread); NS_IF_RELEASE(sMainThread); } @@ -116,6 +116,29 @@ nsHtml5Module::Initialize(nsIParser* aParser, nsIDocument* aDoc, nsIURI* aURI, n return parser->Initialize(aDoc, aURI, aContainer, aChannel); } +class nsHtml5ParserThreadTerminator : public nsIObserver +{ + public: + NS_DECL_ISUPPORTS + nsHtml5ParserThreadTerminator(nsIThread* aThread) + : mThread(aThread) + {} + NS_IMETHODIMP Observe(nsISupports *, const char *topic, const PRUnichar *) + { + NS_ASSERTION(!strcmp(topic, "xpcom-shutdown-threads"), + "Unexpected topic"); + if (mThread) { + mThread->Shutdown(); + mThread = nsnull; + } + return NS_OK; + } + private: + nsCOMPtr mThread; +}; + +NS_IMPL_ISUPPORTS1(nsHtml5ParserThreadTerminator, nsIObserver) + // static nsIThread* nsHtml5Module::GetStreamParserThread() @@ -124,6 +147,11 @@ nsHtml5Module::GetStreamParserThread() if (!sStreamParserThread) { NS_NewThread(&sStreamParserThread); NS_ASSERTION(sStreamParserThread, "Thread creation failed!"); + nsCOMPtr os = do_GetService("@mozilla.org/observer-service;1"); + NS_ASSERTION(os, "do_GetService failed"); + os->AddObserver(new nsHtml5ParserThreadTerminator(sStreamParserThread), + "xpcom-shutdown-threads", + PR_FALSE); } return sStreamParserThread; } diff --git a/parser/html/nsHtml5NamedCharacters.cpp b/parser/html/nsHtml5NamedCharacters.cpp index 8e1a009e02aa..3ac9ef693001 100644 --- a/parser/html/nsHtml5NamedCharacters.cpp +++ b/parser/html/nsHtml5NamedCharacters.cpp @@ -10,7 +10,7 @@ jArray* nsHtml5NamedCharacters::VALUES; PRUnichar** nsHtml5NamedCharacters::WINDOWS_1252; static PRUnichar const WINDOWS_1252_DATA[] = { 0x20AC, - 0xFFFD, + 0x0081, 0x201A, 0x0192, 0x201E, @@ -22,10 +22,10 @@ static PRUnichar const WINDOWS_1252_DATA[] = { 0x0160, 0x2039, 0x0152, - 0xFFFD, + 0x008D, 0x017D, - 0xFFFD, - 0xFFFD, + 0x008F, + 0x0090, 0x2018, 0x2019, 0x201C, @@ -38,7 +38,7 @@ static PRUnichar const WINDOWS_1252_DATA[] = { 0x0161, 0x203A, 0x0153, - 0xFFFD, + 0x009D, 0x017E, 0x0178 }; @@ -61,14 +61,14 @@ static PRUnichar const VALUE_##N[] = { VALUE }; void nsHtml5NamedCharacters::initializeStatics() { - NAMES = jArray,PRInt32>(2137); + NAMES = jArray,PRInt32>(2138); #define NAMED_CHARACTER_REFERENCE(N, CHARS, LEN, VALUE, SIZE) \ NAMES[N] = jArray((PRUnichar*)NAME_##N, LEN); #include "nsHtml5NamedCharactersInclude.h" #undef NAMED_CHARACTER_REFERENCE - VALUES = new jArray[2137]; + VALUES = new jArray[2138]; #define NAMED_CHARACTER_REFERENCE(N, CHARS, LEN, VALUE, SIZE) \ VALUES[N] = jArray((PRUnichar*)VALUE_##N, SIZE); diff --git a/parser/html/nsHtml5NamedCharactersInclude.h b/parser/html/nsHtml5NamedCharactersInclude.h index 2e8548aaa2a7..13155d15e569 100644 --- a/parser/html/nsHtml5NamedCharactersInclude.h +++ b/parser/html/nsHtml5NamedCharactersInclude.h @@ -413,7 +413,7 @@ NAMED_CHARACTER_REFERENCE(388, 'O' _ 't' _ 'i' _ 'l' _ 'd' _ 'e' _ ';', 7, 0x00d NAMED_CHARACTER_REFERENCE(389, 'O' _ 't' _ 'i' _ 'm' _ 'e' _ 's' _ ';', 7, 0x2a37, 1) NAMED_CHARACTER_REFERENCE(390, 'O' _ 'u' _ 'm' _ 'l', 4, 0x00d6, 1) NAMED_CHARACTER_REFERENCE(391, 'O' _ 'u' _ 'm' _ 'l' _ ';', 5, 0x00d6, 1) -NAMED_CHARACTER_REFERENCE(392, 'O' _ 'v' _ 'e' _ 'r' _ 'B' _ 'a' _ 'r' _ ';', 8, 0x00af, 1) +NAMED_CHARACTER_REFERENCE(392, 'O' _ 'v' _ 'e' _ 'r' _ 'B' _ 'a' _ 'r' _ ';', 8, 0x203e, 1) NAMED_CHARACTER_REFERENCE(393, 'O' _ 'v' _ 'e' _ 'r' _ 'B' _ 'r' _ 'a' _ 'c' _ 'e' _ ';', 10, 0x23de, 1) NAMED_CHARACTER_REFERENCE(394, 'O' _ 'v' _ 'e' _ 'r' _ 'B' _ 'r' _ 'a' _ 'c' _ 'k' _ 'e' _ 't' _ ';', 12, 0x23b4, 1) NAMED_CHARACTER_REFERENCE(395, 'O' _ 'v' _ 'e' _ 'r' _ 'P' _ 'a' _ 'r' _ 'e' _ 'n' _ 't' _ 'h' _ 'e' _ 's' _ 'i' _ 's' _ ';', 16, 0x23dc, 1) @@ -562,7 +562,7 @@ NAMED_CHARACTER_REFERENCE(537, 'U' _ 'f' _ 'r' _ ';', 4, 0xd835 _ 0xdd18, 2) NAMED_CHARACTER_REFERENCE(538, 'U' _ 'g' _ 'r' _ 'a' _ 'v' _ 'e', 6, 0x00d9, 1) NAMED_CHARACTER_REFERENCE(539, 'U' _ 'g' _ 'r' _ 'a' _ 'v' _ 'e' _ ';', 7, 0x00d9, 1) NAMED_CHARACTER_REFERENCE(540, 'U' _ 'm' _ 'a' _ 'c' _ 'r' _ ';', 6, 0x016a, 1) -NAMED_CHARACTER_REFERENCE(541, 'U' _ 'n' _ 'd' _ 'e' _ 'r' _ 'B' _ 'a' _ 'r' _ ';', 9, 0x0332, 1) +NAMED_CHARACTER_REFERENCE(541, 'U' _ 'n' _ 'd' _ 'e' _ 'r' _ 'B' _ 'a' _ 'r' _ ';', 9, 0x005f, 1) NAMED_CHARACTER_REFERENCE(542, 'U' _ 'n' _ 'd' _ 'e' _ 'r' _ 'B' _ 'r' _ 'a' _ 'c' _ 'e' _ ';', 11, 0x23df, 1) NAMED_CHARACTER_REFERENCE(543, 'U' _ 'n' _ 'd' _ 'e' _ 'r' _ 'B' _ 'r' _ 'a' _ 'c' _ 'k' _ 'e' _ 't' _ ';', 13, 0x23b5, 1) NAMED_CHARACTER_REFERENCE(544, 'U' _ 'n' _ 'd' _ 'e' _ 'r' _ 'P' _ 'a' _ 'r' _ 'e' _ 'n' _ 't' _ 'h' _ 'e' _ 's' _ 'i' _ 's' _ ';', 17, 0x23dd, 1) @@ -679,7 +679,7 @@ NAMED_CHARACTER_REFERENCE(654, 'a' _ 'n' _ 'g' _ 'r' _ 't' _ ';', 6, 0x221f, 1) NAMED_CHARACTER_REFERENCE(655, 'a' _ 'n' _ 'g' _ 'r' _ 't' _ 'v' _ 'b' _ ';', 8, 0x22be, 1) NAMED_CHARACTER_REFERENCE(656, 'a' _ 'n' _ 'g' _ 'r' _ 't' _ 'v' _ 'b' _ 'd' _ ';', 9, 0x299d, 1) NAMED_CHARACTER_REFERENCE(657, 'a' _ 'n' _ 'g' _ 's' _ 'p' _ 'h' _ ';', 7, 0x2222, 1) -NAMED_CHARACTER_REFERENCE(658, 'a' _ 'n' _ 'g' _ 's' _ 't' _ ';', 6, 0x212b, 1) +NAMED_CHARACTER_REFERENCE(658, 'a' _ 'n' _ 'g' _ 's' _ 't' _ ';', 6, 0x00c5, 1) NAMED_CHARACTER_REFERENCE(659, 'a' _ 'n' _ 'g' _ 'z' _ 'a' _ 'r' _ 'r' _ ';', 8, 0x237c, 1) NAMED_CHARACTER_REFERENCE(660, 'a' _ 'o' _ 'g' _ 'o' _ 'n' _ ';', 6, 0x0105, 1) NAMED_CHARACTER_REFERENCE(661, 'a' _ 'o' _ 'p' _ 'f' _ ';', 5, 0xd835 _ 0xdd52, 2) @@ -810,898 +810,898 @@ NAMED_CHARACTER_REFERENCE(785, 'b' _ 's' _ 'i' _ 'm' _ ';', 5, 0x223d, 1) NAMED_CHARACTER_REFERENCE(786, 'b' _ 's' _ 'i' _ 'm' _ 'e' _ ';', 6, 0x22cd, 1) NAMED_CHARACTER_REFERENCE(787, 'b' _ 's' _ 'o' _ 'l' _ ';', 5, 0x005c, 1) NAMED_CHARACTER_REFERENCE(788, 'b' _ 's' _ 'o' _ 'l' _ 'b' _ ';', 6, 0x29c5, 1) -NAMED_CHARACTER_REFERENCE(789, 'b' _ 'u' _ 'l' _ 'l' _ ';', 5, 0x2022, 1) -NAMED_CHARACTER_REFERENCE(790, 'b' _ 'u' _ 'l' _ 'l' _ 'e' _ 't' _ ';', 7, 0x2022, 1) -NAMED_CHARACTER_REFERENCE(791, 'b' _ 'u' _ 'm' _ 'p' _ ';', 5, 0x224e, 1) -NAMED_CHARACTER_REFERENCE(792, 'b' _ 'u' _ 'm' _ 'p' _ 'E' _ ';', 6, 0x2aae, 1) -NAMED_CHARACTER_REFERENCE(793, 'b' _ 'u' _ 'm' _ 'p' _ 'e' _ ';', 6, 0x224f, 1) -NAMED_CHARACTER_REFERENCE(794, 'b' _ 'u' _ 'm' _ 'p' _ 'e' _ 'q' _ ';', 7, 0x224f, 1) -NAMED_CHARACTER_REFERENCE(795, 'c' _ 'a' _ 'c' _ 'u' _ 't' _ 'e' _ ';', 7, 0x0107, 1) -NAMED_CHARACTER_REFERENCE(796, 'c' _ 'a' _ 'p' _ ';', 4, 0x2229, 1) -NAMED_CHARACTER_REFERENCE(797, 'c' _ 'a' _ 'p' _ 'a' _ 'n' _ 'd' _ ';', 7, 0x2a44, 1) -NAMED_CHARACTER_REFERENCE(798, 'c' _ 'a' _ 'p' _ 'b' _ 'r' _ 'c' _ 'u' _ 'p' _ ';', 9, 0x2a49, 1) -NAMED_CHARACTER_REFERENCE(799, 'c' _ 'a' _ 'p' _ 'c' _ 'a' _ 'p' _ ';', 7, 0x2a4b, 1) -NAMED_CHARACTER_REFERENCE(800, 'c' _ 'a' _ 'p' _ 'c' _ 'u' _ 'p' _ ';', 7, 0x2a47, 1) -NAMED_CHARACTER_REFERENCE(801, 'c' _ 'a' _ 'p' _ 'd' _ 'o' _ 't' _ ';', 7, 0x2a40, 1) -NAMED_CHARACTER_REFERENCE(802, 'c' _ 'a' _ 'r' _ 'e' _ 't' _ ';', 6, 0x2041, 1) -NAMED_CHARACTER_REFERENCE(803, 'c' _ 'a' _ 'r' _ 'o' _ 'n' _ ';', 6, 0x02c7, 1) -NAMED_CHARACTER_REFERENCE(804, 'c' _ 'c' _ 'a' _ 'p' _ 's' _ ';', 6, 0x2a4d, 1) -NAMED_CHARACTER_REFERENCE(805, 'c' _ 'c' _ 'a' _ 'r' _ 'o' _ 'n' _ ';', 7, 0x010d, 1) -NAMED_CHARACTER_REFERENCE(806, 'c' _ 'c' _ 'e' _ 'd' _ 'i' _ 'l', 6, 0x00e7, 1) -NAMED_CHARACTER_REFERENCE(807, 'c' _ 'c' _ 'e' _ 'd' _ 'i' _ 'l' _ ';', 7, 0x00e7, 1) -NAMED_CHARACTER_REFERENCE(808, 'c' _ 'c' _ 'i' _ 'r' _ 'c' _ ';', 6, 0x0109, 1) -NAMED_CHARACTER_REFERENCE(809, 'c' _ 'c' _ 'u' _ 'p' _ 's' _ ';', 6, 0x2a4c, 1) -NAMED_CHARACTER_REFERENCE(810, 'c' _ 'c' _ 'u' _ 'p' _ 's' _ 's' _ 'm' _ ';', 8, 0x2a50, 1) -NAMED_CHARACTER_REFERENCE(811, 'c' _ 'd' _ 'o' _ 't' _ ';', 5, 0x010b, 1) -NAMED_CHARACTER_REFERENCE(812, 'c' _ 'e' _ 'd' _ 'i' _ 'l', 5, 0x00b8, 1) -NAMED_CHARACTER_REFERENCE(813, 'c' _ 'e' _ 'd' _ 'i' _ 'l' _ ';', 6, 0x00b8, 1) -NAMED_CHARACTER_REFERENCE(814, 'c' _ 'e' _ 'm' _ 'p' _ 't' _ 'y' _ 'v' _ ';', 8, 0x29b2, 1) -NAMED_CHARACTER_REFERENCE(815, 'c' _ 'e' _ 'n' _ 't', 4, 0x00a2, 1) -NAMED_CHARACTER_REFERENCE(816, 'c' _ 'e' _ 'n' _ 't' _ ';', 5, 0x00a2, 1) -NAMED_CHARACTER_REFERENCE(817, 'c' _ 'e' _ 'n' _ 't' _ 'e' _ 'r' _ 'd' _ 'o' _ 't' _ ';', 10, 0x00b7, 1) -NAMED_CHARACTER_REFERENCE(818, 'c' _ 'f' _ 'r' _ ';', 4, 0xd835 _ 0xdd20, 2) -NAMED_CHARACTER_REFERENCE(819, 'c' _ 'h' _ 'c' _ 'y' _ ';', 5, 0x0447, 1) -NAMED_CHARACTER_REFERENCE(820, 'c' _ 'h' _ 'e' _ 'c' _ 'k' _ ';', 6, 0x2713, 1) -NAMED_CHARACTER_REFERENCE(821, 'c' _ 'h' _ 'e' _ 'c' _ 'k' _ 'm' _ 'a' _ 'r' _ 'k' _ ';', 10, 0x2713, 1) -NAMED_CHARACTER_REFERENCE(822, 'c' _ 'h' _ 'i' _ ';', 4, 0x03c7, 1) -NAMED_CHARACTER_REFERENCE(823, 'c' _ 'i' _ 'r' _ ';', 4, 0x25cb, 1) -NAMED_CHARACTER_REFERENCE(824, 'c' _ 'i' _ 'r' _ 'E' _ ';', 5, 0x29c3, 1) -NAMED_CHARACTER_REFERENCE(825, 'c' _ 'i' _ 'r' _ 'c' _ ';', 5, 0x02c6, 1) -NAMED_CHARACTER_REFERENCE(826, 'c' _ 'i' _ 'r' _ 'c' _ 'e' _ 'q' _ ';', 7, 0x2257, 1) -NAMED_CHARACTER_REFERENCE(827, 'c' _ 'i' _ 'r' _ 'c' _ 'l' _ 'e' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ 'l' _ 'e' _ 'f' _ 't' _ ';', 16, 0x21ba, 1) -NAMED_CHARACTER_REFERENCE(828, 'c' _ 'i' _ 'r' _ 'c' _ 'l' _ 'e' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ ';', 17, 0x21bb, 1) -NAMED_CHARACTER_REFERENCE(829, 'c' _ 'i' _ 'r' _ 'c' _ 'l' _ 'e' _ 'd' _ 'R' _ ';', 9, 0x00ae, 1) -NAMED_CHARACTER_REFERENCE(830, 'c' _ 'i' _ 'r' _ 'c' _ 'l' _ 'e' _ 'd' _ 'S' _ ';', 9, 0x24c8, 1) -NAMED_CHARACTER_REFERENCE(831, 'c' _ 'i' _ 'r' _ 'c' _ 'l' _ 'e' _ 'd' _ 'a' _ 's' _ 't' _ ';', 11, 0x229b, 1) -NAMED_CHARACTER_REFERENCE(832, 'c' _ 'i' _ 'r' _ 'c' _ 'l' _ 'e' _ 'd' _ 'c' _ 'i' _ 'r' _ 'c' _ ';', 12, 0x229a, 1) -NAMED_CHARACTER_REFERENCE(833, 'c' _ 'i' _ 'r' _ 'c' _ 'l' _ 'e' _ 'd' _ 'd' _ 'a' _ 's' _ 'h' _ ';', 12, 0x229d, 1) -NAMED_CHARACTER_REFERENCE(834, 'c' _ 'i' _ 'r' _ 'e' _ ';', 5, 0x2257, 1) -NAMED_CHARACTER_REFERENCE(835, 'c' _ 'i' _ 'r' _ 'f' _ 'n' _ 'i' _ 'n' _ 't' _ ';', 9, 0x2a10, 1) -NAMED_CHARACTER_REFERENCE(836, 'c' _ 'i' _ 'r' _ 'm' _ 'i' _ 'd' _ ';', 7, 0x2aef, 1) -NAMED_CHARACTER_REFERENCE(837, 'c' _ 'i' _ 'r' _ 's' _ 'c' _ 'i' _ 'r' _ ';', 8, 0x29c2, 1) -NAMED_CHARACTER_REFERENCE(838, 'c' _ 'l' _ 'u' _ 'b' _ 's' _ ';', 6, 0x2663, 1) -NAMED_CHARACTER_REFERENCE(839, 'c' _ 'l' _ 'u' _ 'b' _ 's' _ 'u' _ 'i' _ 't' _ ';', 9, 0x2663, 1) -NAMED_CHARACTER_REFERENCE(840, 'c' _ 'o' _ 'l' _ 'o' _ 'n' _ ';', 6, 0x003a, 1) -NAMED_CHARACTER_REFERENCE(841, 'c' _ 'o' _ 'l' _ 'o' _ 'n' _ 'e' _ ';', 7, 0x2254, 1) -NAMED_CHARACTER_REFERENCE(842, 'c' _ 'o' _ 'l' _ 'o' _ 'n' _ 'e' _ 'q' _ ';', 8, 0x2254, 1) -NAMED_CHARACTER_REFERENCE(843, 'c' _ 'o' _ 'm' _ 'm' _ 'a' _ ';', 6, 0x002c, 1) -NAMED_CHARACTER_REFERENCE(844, 'c' _ 'o' _ 'm' _ 'm' _ 'a' _ 't' _ ';', 7, 0x0040, 1) -NAMED_CHARACTER_REFERENCE(845, 'c' _ 'o' _ 'm' _ 'p' _ ';', 5, 0x2201, 1) -NAMED_CHARACTER_REFERENCE(846, 'c' _ 'o' _ 'm' _ 'p' _ 'f' _ 'n' _ ';', 7, 0x2218, 1) -NAMED_CHARACTER_REFERENCE(847, 'c' _ 'o' _ 'm' _ 'p' _ 'l' _ 'e' _ 'm' _ 'e' _ 'n' _ 't' _ ';', 11, 0x2201, 1) -NAMED_CHARACTER_REFERENCE(848, 'c' _ 'o' _ 'm' _ 'p' _ 'l' _ 'e' _ 'x' _ 'e' _ 's' _ ';', 10, 0x2102, 1) -NAMED_CHARACTER_REFERENCE(849, 'c' _ 'o' _ 'n' _ 'g' _ ';', 5, 0x2245, 1) -NAMED_CHARACTER_REFERENCE(850, 'c' _ 'o' _ 'n' _ 'g' _ 'd' _ 'o' _ 't' _ ';', 8, 0x2a6d, 1) -NAMED_CHARACTER_REFERENCE(851, 'c' _ 'o' _ 'n' _ 'i' _ 'n' _ 't' _ ';', 7, 0x222e, 1) -NAMED_CHARACTER_REFERENCE(852, 'c' _ 'o' _ 'p' _ 'f' _ ';', 5, 0xd835 _ 0xdd54, 2) -NAMED_CHARACTER_REFERENCE(853, 'c' _ 'o' _ 'p' _ 'r' _ 'o' _ 'd' _ ';', 7, 0x2210, 1) -NAMED_CHARACTER_REFERENCE(854, 'c' _ 'o' _ 'p' _ 'y', 4, 0x00a9, 1) -NAMED_CHARACTER_REFERENCE(855, 'c' _ 'o' _ 'p' _ 'y' _ ';', 5, 0x00a9, 1) -NAMED_CHARACTER_REFERENCE(856, 'c' _ 'o' _ 'p' _ 'y' _ 's' _ 'r' _ ';', 7, 0x2117, 1) -NAMED_CHARACTER_REFERENCE(857, 'c' _ 'r' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x21b5, 1) -NAMED_CHARACTER_REFERENCE(858, 'c' _ 'r' _ 'o' _ 's' _ 's' _ ';', 6, 0x2717, 1) -NAMED_CHARACTER_REFERENCE(859, 'c' _ 's' _ 'c' _ 'r' _ ';', 5, 0xd835 _ 0xdcb8, 2) -NAMED_CHARACTER_REFERENCE(860, 'c' _ 's' _ 'u' _ 'b' _ ';', 5, 0x2acf, 1) -NAMED_CHARACTER_REFERENCE(861, 'c' _ 's' _ 'u' _ 'b' _ 'e' _ ';', 6, 0x2ad1, 1) -NAMED_CHARACTER_REFERENCE(862, 'c' _ 's' _ 'u' _ 'p' _ ';', 5, 0x2ad0, 1) -NAMED_CHARACTER_REFERENCE(863, 'c' _ 's' _ 'u' _ 'p' _ 'e' _ ';', 6, 0x2ad2, 1) -NAMED_CHARACTER_REFERENCE(864, 'c' _ 't' _ 'd' _ 'o' _ 't' _ ';', 6, 0x22ef, 1) -NAMED_CHARACTER_REFERENCE(865, 'c' _ 'u' _ 'd' _ 'a' _ 'r' _ 'r' _ 'l' _ ';', 8, 0x2938, 1) -NAMED_CHARACTER_REFERENCE(866, 'c' _ 'u' _ 'd' _ 'a' _ 'r' _ 'r' _ 'r' _ ';', 8, 0x2935, 1) -NAMED_CHARACTER_REFERENCE(867, 'c' _ 'u' _ 'e' _ 'p' _ 'r' _ ';', 6, 0x22de, 1) -NAMED_CHARACTER_REFERENCE(868, 'c' _ 'u' _ 'e' _ 's' _ 'c' _ ';', 6, 0x22df, 1) -NAMED_CHARACTER_REFERENCE(869, 'c' _ 'u' _ 'l' _ 'a' _ 'r' _ 'r' _ ';', 7, 0x21b6, 1) -NAMED_CHARACTER_REFERENCE(870, 'c' _ 'u' _ 'l' _ 'a' _ 'r' _ 'r' _ 'p' _ ';', 8, 0x293d, 1) -NAMED_CHARACTER_REFERENCE(871, 'c' _ 'u' _ 'p' _ ';', 4, 0x222a, 1) -NAMED_CHARACTER_REFERENCE(872, 'c' _ 'u' _ 'p' _ 'b' _ 'r' _ 'c' _ 'a' _ 'p' _ ';', 9, 0x2a48, 1) -NAMED_CHARACTER_REFERENCE(873, 'c' _ 'u' _ 'p' _ 'c' _ 'a' _ 'p' _ ';', 7, 0x2a46, 1) -NAMED_CHARACTER_REFERENCE(874, 'c' _ 'u' _ 'p' _ 'c' _ 'u' _ 'p' _ ';', 7, 0x2a4a, 1) -NAMED_CHARACTER_REFERENCE(875, 'c' _ 'u' _ 'p' _ 'd' _ 'o' _ 't' _ ';', 7, 0x228d, 1) -NAMED_CHARACTER_REFERENCE(876, 'c' _ 'u' _ 'p' _ 'o' _ 'r' _ ';', 6, 0x2a45, 1) -NAMED_CHARACTER_REFERENCE(877, 'c' _ 'u' _ 'r' _ 'a' _ 'r' _ 'r' _ ';', 7, 0x21b7, 1) -NAMED_CHARACTER_REFERENCE(878, 'c' _ 'u' _ 'r' _ 'a' _ 'r' _ 'r' _ 'm' _ ';', 8, 0x293c, 1) -NAMED_CHARACTER_REFERENCE(879, 'c' _ 'u' _ 'r' _ 'l' _ 'y' _ 'e' _ 'q' _ 'p' _ 'r' _ 'e' _ 'c' _ ';', 12, 0x22de, 1) -NAMED_CHARACTER_REFERENCE(880, 'c' _ 'u' _ 'r' _ 'l' _ 'y' _ 'e' _ 'q' _ 's' _ 'u' _ 'c' _ 'c' _ ';', 12, 0x22df, 1) -NAMED_CHARACTER_REFERENCE(881, 'c' _ 'u' _ 'r' _ 'l' _ 'y' _ 'v' _ 'e' _ 'e' _ ';', 9, 0x22ce, 1) -NAMED_CHARACTER_REFERENCE(882, 'c' _ 'u' _ 'r' _ 'l' _ 'y' _ 'w' _ 'e' _ 'd' _ 'g' _ 'e' _ ';', 11, 0x22cf, 1) -NAMED_CHARACTER_REFERENCE(883, 'c' _ 'u' _ 'r' _ 'r' _ 'e' _ 'n', 6, 0x00a4, 1) -NAMED_CHARACTER_REFERENCE(884, 'c' _ 'u' _ 'r' _ 'r' _ 'e' _ 'n' _ ';', 7, 0x00a4, 1) -NAMED_CHARACTER_REFERENCE(885, 'c' _ 'u' _ 'r' _ 'v' _ 'e' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ 'l' _ 'e' _ 'f' _ 't' _ ';', 15, 0x21b6, 1) -NAMED_CHARACTER_REFERENCE(886, 'c' _ 'u' _ 'r' _ 'v' _ 'e' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ ';', 16, 0x21b7, 1) -NAMED_CHARACTER_REFERENCE(887, 'c' _ 'u' _ 'v' _ 'e' _ 'e' _ ';', 6, 0x22ce, 1) -NAMED_CHARACTER_REFERENCE(888, 'c' _ 'u' _ 'w' _ 'e' _ 'd' _ ';', 6, 0x22cf, 1) -NAMED_CHARACTER_REFERENCE(889, 'c' _ 'w' _ 'c' _ 'o' _ 'n' _ 'i' _ 'n' _ 't' _ ';', 9, 0x2232, 1) -NAMED_CHARACTER_REFERENCE(890, 'c' _ 'w' _ 'i' _ 'n' _ 't' _ ';', 6, 0x2231, 1) -NAMED_CHARACTER_REFERENCE(891, 'c' _ 'y' _ 'l' _ 'c' _ 't' _ 'y' _ ';', 7, 0x232d, 1) -NAMED_CHARACTER_REFERENCE(892, 'd' _ 'A' _ 'r' _ 'r' _ ';', 5, 0x21d3, 1) -NAMED_CHARACTER_REFERENCE(893, 'd' _ 'H' _ 'a' _ 'r' _ ';', 5, 0x2965, 1) -NAMED_CHARACTER_REFERENCE(894, 'd' _ 'a' _ 'g' _ 'g' _ 'e' _ 'r' _ ';', 7, 0x2020, 1) -NAMED_CHARACTER_REFERENCE(895, 'd' _ 'a' _ 'l' _ 'e' _ 't' _ 'h' _ ';', 7, 0x2138, 1) -NAMED_CHARACTER_REFERENCE(896, 'd' _ 'a' _ 'r' _ 'r' _ ';', 5, 0x2193, 1) -NAMED_CHARACTER_REFERENCE(897, 'd' _ 'a' _ 's' _ 'h' _ ';', 5, 0x2010, 1) -NAMED_CHARACTER_REFERENCE(898, 'd' _ 'a' _ 's' _ 'h' _ 'v' _ ';', 6, 0x22a3, 1) -NAMED_CHARACTER_REFERENCE(899, 'd' _ 'b' _ 'k' _ 'a' _ 'r' _ 'o' _ 'w' _ ';', 8, 0x290f, 1) -NAMED_CHARACTER_REFERENCE(900, 'd' _ 'b' _ 'l' _ 'a' _ 'c' _ ';', 6, 0x02dd, 1) -NAMED_CHARACTER_REFERENCE(901, 'd' _ 'c' _ 'a' _ 'r' _ 'o' _ 'n' _ ';', 7, 0x010f, 1) -NAMED_CHARACTER_REFERENCE(902, 'd' _ 'c' _ 'y' _ ';', 4, 0x0434, 1) -NAMED_CHARACTER_REFERENCE(903, 'd' _ 'd' _ ';', 3, 0x2146, 1) -NAMED_CHARACTER_REFERENCE(904, 'd' _ 'd' _ 'a' _ 'g' _ 'g' _ 'e' _ 'r' _ ';', 8, 0x2021, 1) -NAMED_CHARACTER_REFERENCE(905, 'd' _ 'd' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x21ca, 1) -NAMED_CHARACTER_REFERENCE(906, 'd' _ 'd' _ 'o' _ 't' _ 's' _ 'e' _ 'q' _ ';', 8, 0x2a77, 1) -NAMED_CHARACTER_REFERENCE(907, 'd' _ 'e' _ 'g', 3, 0x00b0, 1) -NAMED_CHARACTER_REFERENCE(908, 'd' _ 'e' _ 'g' _ ';', 4, 0x00b0, 1) -NAMED_CHARACTER_REFERENCE(909, 'd' _ 'e' _ 'l' _ 't' _ 'a' _ ';', 6, 0x03b4, 1) -NAMED_CHARACTER_REFERENCE(910, 'd' _ 'e' _ 'm' _ 'p' _ 't' _ 'y' _ 'v' _ ';', 8, 0x29b1, 1) -NAMED_CHARACTER_REFERENCE(911, 'd' _ 'f' _ 'i' _ 's' _ 'h' _ 't' _ ';', 7, 0x297f, 1) -NAMED_CHARACTER_REFERENCE(912, 'd' _ 'f' _ 'r' _ ';', 4, 0xd835 _ 0xdd21, 2) -NAMED_CHARACTER_REFERENCE(913, 'd' _ 'h' _ 'a' _ 'r' _ 'l' _ ';', 6, 0x21c3, 1) -NAMED_CHARACTER_REFERENCE(914, 'd' _ 'h' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x21c2, 1) -NAMED_CHARACTER_REFERENCE(915, 'd' _ 'i' _ 'a' _ 'm' _ ';', 5, 0x22c4, 1) -NAMED_CHARACTER_REFERENCE(916, 'd' _ 'i' _ 'a' _ 'm' _ 'o' _ 'n' _ 'd' _ ';', 8, 0x22c4, 1) -NAMED_CHARACTER_REFERENCE(917, 'd' _ 'i' _ 'a' _ 'm' _ 'o' _ 'n' _ 'd' _ 's' _ 'u' _ 'i' _ 't' _ ';', 12, 0x2666, 1) -NAMED_CHARACTER_REFERENCE(918, 'd' _ 'i' _ 'a' _ 'm' _ 's' _ ';', 6, 0x2666, 1) -NAMED_CHARACTER_REFERENCE(919, 'd' _ 'i' _ 'e' _ ';', 4, 0x00a8, 1) -NAMED_CHARACTER_REFERENCE(920, 'd' _ 'i' _ 'g' _ 'a' _ 'm' _ 'm' _ 'a' _ ';', 8, 0x03dd, 1) -NAMED_CHARACTER_REFERENCE(921, 'd' _ 'i' _ 's' _ 'i' _ 'n' _ ';', 6, 0x22f2, 1) -NAMED_CHARACTER_REFERENCE(922, 'd' _ 'i' _ 'v' _ ';', 4, 0x00f7, 1) -NAMED_CHARACTER_REFERENCE(923, 'd' _ 'i' _ 'v' _ 'i' _ 'd' _ 'e', 6, 0x00f7, 1) -NAMED_CHARACTER_REFERENCE(924, 'd' _ 'i' _ 'v' _ 'i' _ 'd' _ 'e' _ ';', 7, 0x00f7, 1) -NAMED_CHARACTER_REFERENCE(925, 'd' _ 'i' _ 'v' _ 'i' _ 'd' _ 'e' _ 'o' _ 'n' _ 't' _ 'i' _ 'm' _ 'e' _ 's' _ ';', 14, 0x22c7, 1) -NAMED_CHARACTER_REFERENCE(926, 'd' _ 'i' _ 'v' _ 'o' _ 'n' _ 'x' _ ';', 7, 0x22c7, 1) -NAMED_CHARACTER_REFERENCE(927, 'd' _ 'j' _ 'c' _ 'y' _ ';', 5, 0x0452, 1) -NAMED_CHARACTER_REFERENCE(928, 'd' _ 'l' _ 'c' _ 'o' _ 'r' _ 'n' _ ';', 7, 0x231e, 1) -NAMED_CHARACTER_REFERENCE(929, 'd' _ 'l' _ 'c' _ 'r' _ 'o' _ 'p' _ ';', 7, 0x230d, 1) -NAMED_CHARACTER_REFERENCE(930, 'd' _ 'o' _ 'l' _ 'l' _ 'a' _ 'r' _ ';', 7, 0x0024, 1) -NAMED_CHARACTER_REFERENCE(931, 'd' _ 'o' _ 'p' _ 'f' _ ';', 5, 0xd835 _ 0xdd55, 2) -NAMED_CHARACTER_REFERENCE(932, 'd' _ 'o' _ 't' _ ';', 4, 0x02d9, 1) -NAMED_CHARACTER_REFERENCE(933, 'd' _ 'o' _ 't' _ 'e' _ 'q' _ ';', 6, 0x2250, 1) -NAMED_CHARACTER_REFERENCE(934, 'd' _ 'o' _ 't' _ 'e' _ 'q' _ 'd' _ 'o' _ 't' _ ';', 9, 0x2251, 1) -NAMED_CHARACTER_REFERENCE(935, 'd' _ 'o' _ 't' _ 'm' _ 'i' _ 'n' _ 'u' _ 's' _ ';', 9, 0x2238, 1) -NAMED_CHARACTER_REFERENCE(936, 'd' _ 'o' _ 't' _ 'p' _ 'l' _ 'u' _ 's' _ ';', 8, 0x2214, 1) -NAMED_CHARACTER_REFERENCE(937, 'd' _ 'o' _ 't' _ 's' _ 'q' _ 'u' _ 'a' _ 'r' _ 'e' _ ';', 10, 0x22a1, 1) -NAMED_CHARACTER_REFERENCE(938, 'd' _ 'o' _ 'u' _ 'b' _ 'l' _ 'e' _ 'b' _ 'a' _ 'r' _ 'w' _ 'e' _ 'd' _ 'g' _ 'e' _ ';', 15, 0x2306, 1) -NAMED_CHARACTER_REFERENCE(939, 'd' _ 'o' _ 'w' _ 'n' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 10, 0x2193, 1) -NAMED_CHARACTER_REFERENCE(940, 'd' _ 'o' _ 'w' _ 'n' _ 'd' _ 'o' _ 'w' _ 'n' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ 's' _ ';', 15, 0x21ca, 1) -NAMED_CHARACTER_REFERENCE(941, 'd' _ 'o' _ 'w' _ 'n' _ 'h' _ 'a' _ 'r' _ 'p' _ 'o' _ 'o' _ 'n' _ 'l' _ 'e' _ 'f' _ 't' _ ';', 16, 0x21c3, 1) -NAMED_CHARACTER_REFERENCE(942, 'd' _ 'o' _ 'w' _ 'n' _ 'h' _ 'a' _ 'r' _ 'p' _ 'o' _ 'o' _ 'n' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ ';', 17, 0x21c2, 1) -NAMED_CHARACTER_REFERENCE(943, 'd' _ 'r' _ 'b' _ 'k' _ 'a' _ 'r' _ 'o' _ 'w' _ ';', 9, 0x2910, 1) -NAMED_CHARACTER_REFERENCE(944, 'd' _ 'r' _ 'c' _ 'o' _ 'r' _ 'n' _ ';', 7, 0x231f, 1) -NAMED_CHARACTER_REFERENCE(945, 'd' _ 'r' _ 'c' _ 'r' _ 'o' _ 'p' _ ';', 7, 0x230c, 1) -NAMED_CHARACTER_REFERENCE(946, 'd' _ 's' _ 'c' _ 'r' _ ';', 5, 0xd835 _ 0xdcb9, 2) -NAMED_CHARACTER_REFERENCE(947, 'd' _ 's' _ 'c' _ 'y' _ ';', 5, 0x0455, 1) -NAMED_CHARACTER_REFERENCE(948, 'd' _ 's' _ 'o' _ 'l' _ ';', 5, 0x29f6, 1) -NAMED_CHARACTER_REFERENCE(949, 'd' _ 's' _ 't' _ 'r' _ 'o' _ 'k' _ ';', 7, 0x0111, 1) -NAMED_CHARACTER_REFERENCE(950, 'd' _ 't' _ 'd' _ 'o' _ 't' _ ';', 6, 0x22f1, 1) -NAMED_CHARACTER_REFERENCE(951, 'd' _ 't' _ 'r' _ 'i' _ ';', 5, 0x25bf, 1) -NAMED_CHARACTER_REFERENCE(952, 'd' _ 't' _ 'r' _ 'i' _ 'f' _ ';', 6, 0x25be, 1) -NAMED_CHARACTER_REFERENCE(953, 'd' _ 'u' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x21f5, 1) -NAMED_CHARACTER_REFERENCE(954, 'd' _ 'u' _ 'h' _ 'a' _ 'r' _ ';', 6, 0x296f, 1) -NAMED_CHARACTER_REFERENCE(955, 'd' _ 'w' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ ';', 8, 0x29a6, 1) -NAMED_CHARACTER_REFERENCE(956, 'd' _ 'z' _ 'c' _ 'y' _ ';', 5, 0x045f, 1) -NAMED_CHARACTER_REFERENCE(957, 'd' _ 'z' _ 'i' _ 'g' _ 'r' _ 'a' _ 'r' _ 'r' _ ';', 9, 0x27ff, 1) -NAMED_CHARACTER_REFERENCE(958, 'e' _ 'D' _ 'D' _ 'o' _ 't' _ ';', 6, 0x2a77, 1) -NAMED_CHARACTER_REFERENCE(959, 'e' _ 'D' _ 'o' _ 't' _ ';', 5, 0x2251, 1) -NAMED_CHARACTER_REFERENCE(960, 'e' _ 'a' _ 'c' _ 'u' _ 't' _ 'e', 6, 0x00e9, 1) -NAMED_CHARACTER_REFERENCE(961, 'e' _ 'a' _ 'c' _ 'u' _ 't' _ 'e' _ ';', 7, 0x00e9, 1) -NAMED_CHARACTER_REFERENCE(962, 'e' _ 'a' _ 's' _ 't' _ 'e' _ 'r' _ ';', 7, 0x2a6e, 1) -NAMED_CHARACTER_REFERENCE(963, 'e' _ 'c' _ 'a' _ 'r' _ 'o' _ 'n' _ ';', 7, 0x011b, 1) -NAMED_CHARACTER_REFERENCE(964, 'e' _ 'c' _ 'i' _ 'r' _ ';', 5, 0x2256, 1) -NAMED_CHARACTER_REFERENCE(965, 'e' _ 'c' _ 'i' _ 'r' _ 'c', 5, 0x00ea, 1) -NAMED_CHARACTER_REFERENCE(966, 'e' _ 'c' _ 'i' _ 'r' _ 'c' _ ';', 6, 0x00ea, 1) -NAMED_CHARACTER_REFERENCE(967, 'e' _ 'c' _ 'o' _ 'l' _ 'o' _ 'n' _ ';', 7, 0x2255, 1) -NAMED_CHARACTER_REFERENCE(968, 'e' _ 'c' _ 'y' _ ';', 4, 0x044d, 1) -NAMED_CHARACTER_REFERENCE(969, 'e' _ 'd' _ 'o' _ 't' _ ';', 5, 0x0117, 1) -NAMED_CHARACTER_REFERENCE(970, 'e' _ 'e' _ ';', 3, 0x2147, 1) -NAMED_CHARACTER_REFERENCE(971, 'e' _ 'f' _ 'D' _ 'o' _ 't' _ ';', 6, 0x2252, 1) -NAMED_CHARACTER_REFERENCE(972, 'e' _ 'f' _ 'r' _ ';', 4, 0xd835 _ 0xdd22, 2) -NAMED_CHARACTER_REFERENCE(973, 'e' _ 'g' _ ';', 3, 0x2a9a, 1) -NAMED_CHARACTER_REFERENCE(974, 'e' _ 'g' _ 'r' _ 'a' _ 'v' _ 'e', 6, 0x00e8, 1) -NAMED_CHARACTER_REFERENCE(975, 'e' _ 'g' _ 'r' _ 'a' _ 'v' _ 'e' _ ';', 7, 0x00e8, 1) -NAMED_CHARACTER_REFERENCE(976, 'e' _ 'g' _ 's' _ ';', 4, 0x2a96, 1) -NAMED_CHARACTER_REFERENCE(977, 'e' _ 'g' _ 's' _ 'd' _ 'o' _ 't' _ ';', 7, 0x2a98, 1) -NAMED_CHARACTER_REFERENCE(978, 'e' _ 'l' _ ';', 3, 0x2a99, 1) -NAMED_CHARACTER_REFERENCE(979, 'e' _ 'l' _ 'i' _ 'n' _ 't' _ 'e' _ 'r' _ 's' _ ';', 9, 0x23e7, 1) -NAMED_CHARACTER_REFERENCE(980, 'e' _ 'l' _ 'l' _ ';', 4, 0x2113, 1) -NAMED_CHARACTER_REFERENCE(981, 'e' _ 'l' _ 's' _ ';', 4, 0x2a95, 1) -NAMED_CHARACTER_REFERENCE(982, 'e' _ 'l' _ 's' _ 'd' _ 'o' _ 't' _ ';', 7, 0x2a97, 1) -NAMED_CHARACTER_REFERENCE(983, 'e' _ 'm' _ 'a' _ 'c' _ 'r' _ ';', 6, 0x0113, 1) -NAMED_CHARACTER_REFERENCE(984, 'e' _ 'm' _ 'p' _ 't' _ 'y' _ ';', 6, 0x2205, 1) -NAMED_CHARACTER_REFERENCE(985, 'e' _ 'm' _ 'p' _ 't' _ 'y' _ 's' _ 'e' _ 't' _ ';', 9, 0x2205, 1) -NAMED_CHARACTER_REFERENCE(986, 'e' _ 'm' _ 'p' _ 't' _ 'y' _ 'v' _ ';', 7, 0x2205, 1) -NAMED_CHARACTER_REFERENCE(987, 'e' _ 'm' _ 's' _ 'p' _ '1' _ '3' _ ';', 7, 0x2004, 1) -NAMED_CHARACTER_REFERENCE(988, 'e' _ 'm' _ 's' _ 'p' _ '1' _ '4' _ ';', 7, 0x2005, 1) -NAMED_CHARACTER_REFERENCE(989, 'e' _ 'm' _ 's' _ 'p' _ ';', 5, 0x2003, 1) -NAMED_CHARACTER_REFERENCE(990, 'e' _ 'n' _ 'g' _ ';', 4, 0x014b, 1) -NAMED_CHARACTER_REFERENCE(991, 'e' _ 'n' _ 's' _ 'p' _ ';', 5, 0x2002, 1) -NAMED_CHARACTER_REFERENCE(992, 'e' _ 'o' _ 'g' _ 'o' _ 'n' _ ';', 6, 0x0119, 1) -NAMED_CHARACTER_REFERENCE(993, 'e' _ 'o' _ 'p' _ 'f' _ ';', 5, 0xd835 _ 0xdd56, 2) -NAMED_CHARACTER_REFERENCE(994, 'e' _ 'p' _ 'a' _ 'r' _ ';', 5, 0x22d5, 1) -NAMED_CHARACTER_REFERENCE(995, 'e' _ 'p' _ 'a' _ 'r' _ 's' _ 'l' _ ';', 7, 0x29e3, 1) -NAMED_CHARACTER_REFERENCE(996, 'e' _ 'p' _ 'l' _ 'u' _ 's' _ ';', 6, 0x2a71, 1) -NAMED_CHARACTER_REFERENCE(997, 'e' _ 'p' _ 's' _ 'i' _ ';', 5, 0x03f5, 1) -NAMED_CHARACTER_REFERENCE(998, 'e' _ 'p' _ 's' _ 'i' _ 'l' _ 'o' _ 'n' _ ';', 8, 0x03b5, 1) -NAMED_CHARACTER_REFERENCE(999, 'e' _ 'p' _ 's' _ 'i' _ 'v' _ ';', 6, 0x03b5, 1) -NAMED_CHARACTER_REFERENCE(1000, 'e' _ 'q' _ 'c' _ 'i' _ 'r' _ 'c' _ ';', 7, 0x2256, 1) -NAMED_CHARACTER_REFERENCE(1001, 'e' _ 'q' _ 'c' _ 'o' _ 'l' _ 'o' _ 'n' _ ';', 8, 0x2255, 1) -NAMED_CHARACTER_REFERENCE(1002, 'e' _ 'q' _ 's' _ 'i' _ 'm' _ ';', 6, 0x2242, 1) -NAMED_CHARACTER_REFERENCE(1003, 'e' _ 'q' _ 's' _ 'l' _ 'a' _ 'n' _ 't' _ 'g' _ 't' _ 'r' _ ';', 11, 0x2a96, 1) -NAMED_CHARACTER_REFERENCE(1004, 'e' _ 'q' _ 's' _ 'l' _ 'a' _ 'n' _ 't' _ 'l' _ 'e' _ 's' _ 's' _ ';', 12, 0x2a95, 1) -NAMED_CHARACTER_REFERENCE(1005, 'e' _ 'q' _ 'u' _ 'a' _ 'l' _ 's' _ ';', 7, 0x003d, 1) -NAMED_CHARACTER_REFERENCE(1006, 'e' _ 'q' _ 'u' _ 'e' _ 's' _ 't' _ ';', 7, 0x225f, 1) -NAMED_CHARACTER_REFERENCE(1007, 'e' _ 'q' _ 'u' _ 'i' _ 'v' _ ';', 6, 0x2261, 1) -NAMED_CHARACTER_REFERENCE(1008, 'e' _ 'q' _ 'u' _ 'i' _ 'v' _ 'D' _ 'D' _ ';', 8, 0x2a78, 1) -NAMED_CHARACTER_REFERENCE(1009, 'e' _ 'q' _ 'v' _ 'p' _ 'a' _ 'r' _ 's' _ 'l' _ ';', 9, 0x29e5, 1) -NAMED_CHARACTER_REFERENCE(1010, 'e' _ 'r' _ 'D' _ 'o' _ 't' _ ';', 6, 0x2253, 1) -NAMED_CHARACTER_REFERENCE(1011, 'e' _ 'r' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x2971, 1) -NAMED_CHARACTER_REFERENCE(1012, 'e' _ 's' _ 'c' _ 'r' _ ';', 5, 0x212f, 1) -NAMED_CHARACTER_REFERENCE(1013, 'e' _ 's' _ 'd' _ 'o' _ 't' _ ';', 6, 0x2250, 1) -NAMED_CHARACTER_REFERENCE(1014, 'e' _ 's' _ 'i' _ 'm' _ ';', 5, 0x2242, 1) -NAMED_CHARACTER_REFERENCE(1015, 'e' _ 't' _ 'a' _ ';', 4, 0x03b7, 1) -NAMED_CHARACTER_REFERENCE(1016, 'e' _ 't' _ 'h', 3, 0x00f0, 1) -NAMED_CHARACTER_REFERENCE(1017, 'e' _ 't' _ 'h' _ ';', 4, 0x00f0, 1) -NAMED_CHARACTER_REFERENCE(1018, 'e' _ 'u' _ 'm' _ 'l', 4, 0x00eb, 1) -NAMED_CHARACTER_REFERENCE(1019, 'e' _ 'u' _ 'm' _ 'l' _ ';', 5, 0x00eb, 1) -NAMED_CHARACTER_REFERENCE(1020, 'e' _ 'u' _ 'r' _ 'o' _ ';', 5, 0x20ac, 1) -NAMED_CHARACTER_REFERENCE(1021, 'e' _ 'x' _ 'c' _ 'l' _ ';', 5, 0x0021, 1) -NAMED_CHARACTER_REFERENCE(1022, 'e' _ 'x' _ 'i' _ 's' _ 't' _ ';', 6, 0x2203, 1) -NAMED_CHARACTER_REFERENCE(1023, 'e' _ 'x' _ 'p' _ 'e' _ 'c' _ 't' _ 'a' _ 't' _ 'i' _ 'o' _ 'n' _ ';', 12, 0x2130, 1) -NAMED_CHARACTER_REFERENCE(1024, 'e' _ 'x' _ 'p' _ 'o' _ 'n' _ 'e' _ 'n' _ 't' _ 'i' _ 'a' _ 'l' _ 'e' _ ';', 13, 0x2147, 1) -NAMED_CHARACTER_REFERENCE(1025, 'f' _ 'a' _ 'l' _ 'l' _ 'i' _ 'n' _ 'g' _ 'd' _ 'o' _ 't' _ 's' _ 'e' _ 'q' _ ';', 14, 0x2252, 1) -NAMED_CHARACTER_REFERENCE(1026, 'f' _ 'c' _ 'y' _ ';', 4, 0x0444, 1) -NAMED_CHARACTER_REFERENCE(1027, 'f' _ 'e' _ 'm' _ 'a' _ 'l' _ 'e' _ ';', 7, 0x2640, 1) -NAMED_CHARACTER_REFERENCE(1028, 'f' _ 'f' _ 'i' _ 'l' _ 'i' _ 'g' _ ';', 7, 0xfb03, 1) -NAMED_CHARACTER_REFERENCE(1029, 'f' _ 'f' _ 'l' _ 'i' _ 'g' _ ';', 6, 0xfb00, 1) -NAMED_CHARACTER_REFERENCE(1030, 'f' _ 'f' _ 'l' _ 'l' _ 'i' _ 'g' _ ';', 7, 0xfb04, 1) -NAMED_CHARACTER_REFERENCE(1031, 'f' _ 'f' _ 'r' _ ';', 4, 0xd835 _ 0xdd23, 2) -NAMED_CHARACTER_REFERENCE(1032, 'f' _ 'i' _ 'l' _ 'i' _ 'g' _ ';', 6, 0xfb01, 1) -NAMED_CHARACTER_REFERENCE(1033, 'f' _ 'l' _ 'a' _ 't' _ ';', 5, 0x266d, 1) -NAMED_CHARACTER_REFERENCE(1034, 'f' _ 'l' _ 'l' _ 'i' _ 'g' _ ';', 6, 0xfb02, 1) -NAMED_CHARACTER_REFERENCE(1035, 'f' _ 'l' _ 't' _ 'n' _ 's' _ ';', 6, 0x25b1, 1) -NAMED_CHARACTER_REFERENCE(1036, 'f' _ 'n' _ 'o' _ 'f' _ ';', 5, 0x0192, 1) -NAMED_CHARACTER_REFERENCE(1037, 'f' _ 'o' _ 'p' _ 'f' _ ';', 5, 0xd835 _ 0xdd57, 2) -NAMED_CHARACTER_REFERENCE(1038, 'f' _ 'o' _ 'r' _ 'a' _ 'l' _ 'l' _ ';', 7, 0x2200, 1) -NAMED_CHARACTER_REFERENCE(1039, 'f' _ 'o' _ 'r' _ 'k' _ ';', 5, 0x22d4, 1) -NAMED_CHARACTER_REFERENCE(1040, 'f' _ 'o' _ 'r' _ 'k' _ 'v' _ ';', 6, 0x2ad9, 1) -NAMED_CHARACTER_REFERENCE(1041, 'f' _ 'p' _ 'a' _ 'r' _ 't' _ 'i' _ 'n' _ 't' _ ';', 9, 0x2a0d, 1) -NAMED_CHARACTER_REFERENCE(1042, 'f' _ 'r' _ 'a' _ 'c' _ '1' _ '2', 6, 0x00bd, 1) -NAMED_CHARACTER_REFERENCE(1043, 'f' _ 'r' _ 'a' _ 'c' _ '1' _ '2' _ ';', 7, 0x00bd, 1) -NAMED_CHARACTER_REFERENCE(1044, 'f' _ 'r' _ 'a' _ 'c' _ '1' _ '3' _ ';', 7, 0x2153, 1) -NAMED_CHARACTER_REFERENCE(1045, 'f' _ 'r' _ 'a' _ 'c' _ '1' _ '4', 6, 0x00bc, 1) -NAMED_CHARACTER_REFERENCE(1046, 'f' _ 'r' _ 'a' _ 'c' _ '1' _ '4' _ ';', 7, 0x00bc, 1) -NAMED_CHARACTER_REFERENCE(1047, 'f' _ 'r' _ 'a' _ 'c' _ '1' _ '5' _ ';', 7, 0x2155, 1) -NAMED_CHARACTER_REFERENCE(1048, 'f' _ 'r' _ 'a' _ 'c' _ '1' _ '6' _ ';', 7, 0x2159, 1) -NAMED_CHARACTER_REFERENCE(1049, 'f' _ 'r' _ 'a' _ 'c' _ '1' _ '8' _ ';', 7, 0x215b, 1) -NAMED_CHARACTER_REFERENCE(1050, 'f' _ 'r' _ 'a' _ 'c' _ '2' _ '3' _ ';', 7, 0x2154, 1) -NAMED_CHARACTER_REFERENCE(1051, 'f' _ 'r' _ 'a' _ 'c' _ '2' _ '5' _ ';', 7, 0x2156, 1) -NAMED_CHARACTER_REFERENCE(1052, 'f' _ 'r' _ 'a' _ 'c' _ '3' _ '4', 6, 0x00be, 1) -NAMED_CHARACTER_REFERENCE(1053, 'f' _ 'r' _ 'a' _ 'c' _ '3' _ '4' _ ';', 7, 0x00be, 1) -NAMED_CHARACTER_REFERENCE(1054, 'f' _ 'r' _ 'a' _ 'c' _ '3' _ '5' _ ';', 7, 0x2157, 1) -NAMED_CHARACTER_REFERENCE(1055, 'f' _ 'r' _ 'a' _ 'c' _ '3' _ '8' _ ';', 7, 0x215c, 1) -NAMED_CHARACTER_REFERENCE(1056, 'f' _ 'r' _ 'a' _ 'c' _ '4' _ '5' _ ';', 7, 0x2158, 1) -NAMED_CHARACTER_REFERENCE(1057, 'f' _ 'r' _ 'a' _ 'c' _ '5' _ '6' _ ';', 7, 0x215a, 1) -NAMED_CHARACTER_REFERENCE(1058, 'f' _ 'r' _ 'a' _ 'c' _ '5' _ '8' _ ';', 7, 0x215d, 1) -NAMED_CHARACTER_REFERENCE(1059, 'f' _ 'r' _ 'a' _ 'c' _ '7' _ '8' _ ';', 7, 0x215e, 1) -NAMED_CHARACTER_REFERENCE(1060, 'f' _ 'r' _ 'a' _ 's' _ 'l' _ ';', 6, 0x2044, 1) -NAMED_CHARACTER_REFERENCE(1061, 'f' _ 'r' _ 'o' _ 'w' _ 'n' _ ';', 6, 0x2322, 1) -NAMED_CHARACTER_REFERENCE(1062, 'f' _ 's' _ 'c' _ 'r' _ ';', 5, 0xd835 _ 0xdcbb, 2) -NAMED_CHARACTER_REFERENCE(1063, 'g' _ 'E' _ ';', 3, 0x2267, 1) -NAMED_CHARACTER_REFERENCE(1064, 'g' _ 'E' _ 'l' _ ';', 4, 0x2a8c, 1) -NAMED_CHARACTER_REFERENCE(1065, 'g' _ 'a' _ 'c' _ 'u' _ 't' _ 'e' _ ';', 7, 0x01f5, 1) -NAMED_CHARACTER_REFERENCE(1066, 'g' _ 'a' _ 'm' _ 'm' _ 'a' _ ';', 6, 0x03b3, 1) -NAMED_CHARACTER_REFERENCE(1067, 'g' _ 'a' _ 'm' _ 'm' _ 'a' _ 'd' _ ';', 7, 0x03dd, 1) -NAMED_CHARACTER_REFERENCE(1068, 'g' _ 'a' _ 'p' _ ';', 4, 0x2a86, 1) -NAMED_CHARACTER_REFERENCE(1069, 'g' _ 'b' _ 'r' _ 'e' _ 'v' _ 'e' _ ';', 7, 0x011f, 1) -NAMED_CHARACTER_REFERENCE(1070, 'g' _ 'c' _ 'i' _ 'r' _ 'c' _ ';', 6, 0x011d, 1) -NAMED_CHARACTER_REFERENCE(1071, 'g' _ 'c' _ 'y' _ ';', 4, 0x0433, 1) -NAMED_CHARACTER_REFERENCE(1072, 'g' _ 'd' _ 'o' _ 't' _ ';', 5, 0x0121, 1) -NAMED_CHARACTER_REFERENCE(1073, 'g' _ 'e' _ ';', 3, 0x2265, 1) -NAMED_CHARACTER_REFERENCE(1074, 'g' _ 'e' _ 'l' _ ';', 4, 0x22db, 1) -NAMED_CHARACTER_REFERENCE(1075, 'g' _ 'e' _ 'q' _ ';', 4, 0x2265, 1) -NAMED_CHARACTER_REFERENCE(1076, 'g' _ 'e' _ 'q' _ 'q' _ ';', 5, 0x2267, 1) -NAMED_CHARACTER_REFERENCE(1077, 'g' _ 'e' _ 'q' _ 's' _ 'l' _ 'a' _ 'n' _ 't' _ ';', 9, 0x2a7e, 1) -NAMED_CHARACTER_REFERENCE(1078, 'g' _ 'e' _ 's' _ ';', 4, 0x2a7e, 1) -NAMED_CHARACTER_REFERENCE(1079, 'g' _ 'e' _ 's' _ 'c' _ 'c' _ ';', 6, 0x2aa9, 1) -NAMED_CHARACTER_REFERENCE(1080, 'g' _ 'e' _ 's' _ 'd' _ 'o' _ 't' _ ';', 7, 0x2a80, 1) -NAMED_CHARACTER_REFERENCE(1081, 'g' _ 'e' _ 's' _ 'd' _ 'o' _ 't' _ 'o' _ ';', 8, 0x2a82, 1) -NAMED_CHARACTER_REFERENCE(1082, 'g' _ 'e' _ 's' _ 'd' _ 'o' _ 't' _ 'o' _ 'l' _ ';', 9, 0x2a84, 1) -NAMED_CHARACTER_REFERENCE(1083, 'g' _ 'e' _ 's' _ 'l' _ 'e' _ 's' _ ';', 7, 0x2a94, 1) -NAMED_CHARACTER_REFERENCE(1084, 'g' _ 'f' _ 'r' _ ';', 4, 0xd835 _ 0xdd24, 2) -NAMED_CHARACTER_REFERENCE(1085, 'g' _ 'g' _ ';', 3, 0x226b, 1) -NAMED_CHARACTER_REFERENCE(1086, 'g' _ 'g' _ 'g' _ ';', 4, 0x22d9, 1) -NAMED_CHARACTER_REFERENCE(1087, 'g' _ 'i' _ 'm' _ 'e' _ 'l' _ ';', 6, 0x2137, 1) -NAMED_CHARACTER_REFERENCE(1088, 'g' _ 'j' _ 'c' _ 'y' _ ';', 5, 0x0453, 1) -NAMED_CHARACTER_REFERENCE(1089, 'g' _ 'l' _ ';', 3, 0x2277, 1) -NAMED_CHARACTER_REFERENCE(1090, 'g' _ 'l' _ 'E' _ ';', 4, 0x2a92, 1) -NAMED_CHARACTER_REFERENCE(1091, 'g' _ 'l' _ 'a' _ ';', 4, 0x2aa5, 1) -NAMED_CHARACTER_REFERENCE(1092, 'g' _ 'l' _ 'j' _ ';', 4, 0x2aa4, 1) -NAMED_CHARACTER_REFERENCE(1093, 'g' _ 'n' _ 'E' _ ';', 4, 0x2269, 1) -NAMED_CHARACTER_REFERENCE(1094, 'g' _ 'n' _ 'a' _ 'p' _ ';', 5, 0x2a8a, 1) -NAMED_CHARACTER_REFERENCE(1095, 'g' _ 'n' _ 'a' _ 'p' _ 'p' _ 'r' _ 'o' _ 'x' _ ';', 9, 0x2a8a, 1) -NAMED_CHARACTER_REFERENCE(1096, 'g' _ 'n' _ 'e' _ ';', 4, 0x2a88, 1) -NAMED_CHARACTER_REFERENCE(1097, 'g' _ 'n' _ 'e' _ 'q' _ ';', 5, 0x2a88, 1) -NAMED_CHARACTER_REFERENCE(1098, 'g' _ 'n' _ 'e' _ 'q' _ 'q' _ ';', 6, 0x2269, 1) -NAMED_CHARACTER_REFERENCE(1099, 'g' _ 'n' _ 's' _ 'i' _ 'm' _ ';', 6, 0x22e7, 1) -NAMED_CHARACTER_REFERENCE(1100, 'g' _ 'o' _ 'p' _ 'f' _ ';', 5, 0xd835 _ 0xdd58, 2) -NAMED_CHARACTER_REFERENCE(1101, 'g' _ 'r' _ 'a' _ 'v' _ 'e' _ ';', 6, 0x0060, 1) -NAMED_CHARACTER_REFERENCE(1102, 'g' _ 's' _ 'c' _ 'r' _ ';', 5, 0x210a, 1) -NAMED_CHARACTER_REFERENCE(1103, 'g' _ 's' _ 'i' _ 'm' _ ';', 5, 0x2273, 1) -NAMED_CHARACTER_REFERENCE(1104, 'g' _ 's' _ 'i' _ 'm' _ 'e' _ ';', 6, 0x2a8e, 1) -NAMED_CHARACTER_REFERENCE(1105, 'g' _ 's' _ 'i' _ 'm' _ 'l' _ ';', 6, 0x2a90, 1) -NAMED_CHARACTER_REFERENCE(1106, 'g' _ 't', 2, 0x003e, 1) -NAMED_CHARACTER_REFERENCE(1107, 'g' _ 't' _ ';', 3, 0x003e, 1) -NAMED_CHARACTER_REFERENCE(1108, 'g' _ 't' _ 'c' _ 'c' _ ';', 5, 0x2aa7, 1) -NAMED_CHARACTER_REFERENCE(1109, 'g' _ 't' _ 'c' _ 'i' _ 'r' _ ';', 6, 0x2a7a, 1) -NAMED_CHARACTER_REFERENCE(1110, 'g' _ 't' _ 'd' _ 'o' _ 't' _ ';', 6, 0x22d7, 1) -NAMED_CHARACTER_REFERENCE(1111, 'g' _ 't' _ 'l' _ 'P' _ 'a' _ 'r' _ ';', 7, 0x2995, 1) -NAMED_CHARACTER_REFERENCE(1112, 'g' _ 't' _ 'q' _ 'u' _ 'e' _ 's' _ 't' _ ';', 8, 0x2a7c, 1) -NAMED_CHARACTER_REFERENCE(1113, 'g' _ 't' _ 'r' _ 'a' _ 'p' _ 'p' _ 'r' _ 'o' _ 'x' _ ';', 10, 0x2a86, 1) -NAMED_CHARACTER_REFERENCE(1114, 'g' _ 't' _ 'r' _ 'a' _ 'r' _ 'r' _ ';', 7, 0x2978, 1) -NAMED_CHARACTER_REFERENCE(1115, 'g' _ 't' _ 'r' _ 'd' _ 'o' _ 't' _ ';', 7, 0x22d7, 1) -NAMED_CHARACTER_REFERENCE(1116, 'g' _ 't' _ 'r' _ 'e' _ 'q' _ 'l' _ 'e' _ 's' _ 's' _ ';', 10, 0x22db, 1) -NAMED_CHARACTER_REFERENCE(1117, 'g' _ 't' _ 'r' _ 'e' _ 'q' _ 'q' _ 'l' _ 'e' _ 's' _ 's' _ ';', 11, 0x2a8c, 1) -NAMED_CHARACTER_REFERENCE(1118, 'g' _ 't' _ 'r' _ 'l' _ 'e' _ 's' _ 's' _ ';', 8, 0x2277, 1) -NAMED_CHARACTER_REFERENCE(1119, 'g' _ 't' _ 'r' _ 's' _ 'i' _ 'm' _ ';', 7, 0x2273, 1) -NAMED_CHARACTER_REFERENCE(1120, 'h' _ 'A' _ 'r' _ 'r' _ ';', 5, 0x21d4, 1) -NAMED_CHARACTER_REFERENCE(1121, 'h' _ 'a' _ 'i' _ 'r' _ 's' _ 'p' _ ';', 7, 0x200a, 1) -NAMED_CHARACTER_REFERENCE(1122, 'h' _ 'a' _ 'l' _ 'f' _ ';', 5, 0x00bd, 1) -NAMED_CHARACTER_REFERENCE(1123, 'h' _ 'a' _ 'm' _ 'i' _ 'l' _ 't' _ ';', 7, 0x210b, 1) -NAMED_CHARACTER_REFERENCE(1124, 'h' _ 'a' _ 'r' _ 'd' _ 'c' _ 'y' _ ';', 7, 0x044a, 1) -NAMED_CHARACTER_REFERENCE(1125, 'h' _ 'a' _ 'r' _ 'r' _ ';', 5, 0x2194, 1) -NAMED_CHARACTER_REFERENCE(1126, 'h' _ 'a' _ 'r' _ 'r' _ 'c' _ 'i' _ 'r' _ ';', 8, 0x2948, 1) -NAMED_CHARACTER_REFERENCE(1127, 'h' _ 'a' _ 'r' _ 'r' _ 'w' _ ';', 6, 0x21ad, 1) -NAMED_CHARACTER_REFERENCE(1128, 'h' _ 'b' _ 'a' _ 'r' _ ';', 5, 0x210f, 1) -NAMED_CHARACTER_REFERENCE(1129, 'h' _ 'c' _ 'i' _ 'r' _ 'c' _ ';', 6, 0x0125, 1) -NAMED_CHARACTER_REFERENCE(1130, 'h' _ 'e' _ 'a' _ 'r' _ 't' _ 's' _ ';', 7, 0x2665, 1) -NAMED_CHARACTER_REFERENCE(1131, 'h' _ 'e' _ 'a' _ 'r' _ 't' _ 's' _ 'u' _ 'i' _ 't' _ ';', 10, 0x2665, 1) -NAMED_CHARACTER_REFERENCE(1132, 'h' _ 'e' _ 'l' _ 'l' _ 'i' _ 'p' _ ';', 7, 0x2026, 1) -NAMED_CHARACTER_REFERENCE(1133, 'h' _ 'e' _ 'r' _ 'c' _ 'o' _ 'n' _ ';', 7, 0x22b9, 1) -NAMED_CHARACTER_REFERENCE(1134, 'h' _ 'f' _ 'r' _ ';', 4, 0xd835 _ 0xdd25, 2) -NAMED_CHARACTER_REFERENCE(1135, 'h' _ 'k' _ 's' _ 'e' _ 'a' _ 'r' _ 'o' _ 'w' _ ';', 9, 0x2925, 1) -NAMED_CHARACTER_REFERENCE(1136, 'h' _ 'k' _ 's' _ 'w' _ 'a' _ 'r' _ 'o' _ 'w' _ ';', 9, 0x2926, 1) -NAMED_CHARACTER_REFERENCE(1137, 'h' _ 'o' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x21ff, 1) -NAMED_CHARACTER_REFERENCE(1138, 'h' _ 'o' _ 'm' _ 't' _ 'h' _ 't' _ ';', 7, 0x223b, 1) -NAMED_CHARACTER_REFERENCE(1139, 'h' _ 'o' _ 'o' _ 'k' _ 'l' _ 'e' _ 'f' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 14, 0x21a9, 1) -NAMED_CHARACTER_REFERENCE(1140, 'h' _ 'o' _ 'o' _ 'k' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 15, 0x21aa, 1) -NAMED_CHARACTER_REFERENCE(1141, 'h' _ 'o' _ 'p' _ 'f' _ ';', 5, 0xd835 _ 0xdd59, 2) -NAMED_CHARACTER_REFERENCE(1142, 'h' _ 'o' _ 'r' _ 'b' _ 'a' _ 'r' _ ';', 7, 0x2015, 1) -NAMED_CHARACTER_REFERENCE(1143, 'h' _ 's' _ 'c' _ 'r' _ ';', 5, 0xd835 _ 0xdcbd, 2) -NAMED_CHARACTER_REFERENCE(1144, 'h' _ 's' _ 'l' _ 'a' _ 's' _ 'h' _ ';', 7, 0x210f, 1) -NAMED_CHARACTER_REFERENCE(1145, 'h' _ 's' _ 't' _ 'r' _ 'o' _ 'k' _ ';', 7, 0x0127, 1) -NAMED_CHARACTER_REFERENCE(1146, 'h' _ 'y' _ 'b' _ 'u' _ 'l' _ 'l' _ ';', 7, 0x2043, 1) -NAMED_CHARACTER_REFERENCE(1147, 'h' _ 'y' _ 'p' _ 'h' _ 'e' _ 'n' _ ';', 7, 0x2010, 1) -NAMED_CHARACTER_REFERENCE(1148, 'i' _ 'a' _ 'c' _ 'u' _ 't' _ 'e', 6, 0x00ed, 1) -NAMED_CHARACTER_REFERENCE(1149, 'i' _ 'a' _ 'c' _ 'u' _ 't' _ 'e' _ ';', 7, 0x00ed, 1) -NAMED_CHARACTER_REFERENCE(1150, 'i' _ 'c' _ ';', 3, 0x2063, 1) -NAMED_CHARACTER_REFERENCE(1151, 'i' _ 'c' _ 'i' _ 'r' _ 'c', 5, 0x00ee, 1) -NAMED_CHARACTER_REFERENCE(1152, 'i' _ 'c' _ 'i' _ 'r' _ 'c' _ ';', 6, 0x00ee, 1) -NAMED_CHARACTER_REFERENCE(1153, 'i' _ 'c' _ 'y' _ ';', 4, 0x0438, 1) -NAMED_CHARACTER_REFERENCE(1154, 'i' _ 'e' _ 'c' _ 'y' _ ';', 5, 0x0435, 1) -NAMED_CHARACTER_REFERENCE(1155, 'i' _ 'e' _ 'x' _ 'c' _ 'l', 5, 0x00a1, 1) -NAMED_CHARACTER_REFERENCE(1156, 'i' _ 'e' _ 'x' _ 'c' _ 'l' _ ';', 6, 0x00a1, 1) -NAMED_CHARACTER_REFERENCE(1157, 'i' _ 'f' _ 'f' _ ';', 4, 0x21d4, 1) -NAMED_CHARACTER_REFERENCE(1158, 'i' _ 'f' _ 'r' _ ';', 4, 0xd835 _ 0xdd26, 2) -NAMED_CHARACTER_REFERENCE(1159, 'i' _ 'g' _ 'r' _ 'a' _ 'v' _ 'e', 6, 0x00ec, 1) -NAMED_CHARACTER_REFERENCE(1160, 'i' _ 'g' _ 'r' _ 'a' _ 'v' _ 'e' _ ';', 7, 0x00ec, 1) -NAMED_CHARACTER_REFERENCE(1161, 'i' _ 'i' _ ';', 3, 0x2148, 1) -NAMED_CHARACTER_REFERENCE(1162, 'i' _ 'i' _ 'i' _ 'i' _ 'n' _ 't' _ ';', 7, 0x2a0c, 1) -NAMED_CHARACTER_REFERENCE(1163, 'i' _ 'i' _ 'i' _ 'n' _ 't' _ ';', 6, 0x222d, 1) -NAMED_CHARACTER_REFERENCE(1164, 'i' _ 'i' _ 'n' _ 'f' _ 'i' _ 'n' _ ';', 7, 0x29dc, 1) -NAMED_CHARACTER_REFERENCE(1165, 'i' _ 'i' _ 'o' _ 't' _ 'a' _ ';', 6, 0x2129, 1) -NAMED_CHARACTER_REFERENCE(1166, 'i' _ 'j' _ 'l' _ 'i' _ 'g' _ ';', 6, 0x0133, 1) -NAMED_CHARACTER_REFERENCE(1167, 'i' _ 'm' _ 'a' _ 'c' _ 'r' _ ';', 6, 0x012b, 1) -NAMED_CHARACTER_REFERENCE(1168, 'i' _ 'm' _ 'a' _ 'g' _ 'e' _ ';', 6, 0x2111, 1) -NAMED_CHARACTER_REFERENCE(1169, 'i' _ 'm' _ 'a' _ 'g' _ 'l' _ 'i' _ 'n' _ 'e' _ ';', 9, 0x2110, 1) -NAMED_CHARACTER_REFERENCE(1170, 'i' _ 'm' _ 'a' _ 'g' _ 'p' _ 'a' _ 'r' _ 't' _ ';', 9, 0x2111, 1) -NAMED_CHARACTER_REFERENCE(1171, 'i' _ 'm' _ 'a' _ 't' _ 'h' _ ';', 6, 0x0131, 1) -NAMED_CHARACTER_REFERENCE(1172, 'i' _ 'm' _ 'o' _ 'f' _ ';', 5, 0x22b7, 1) -NAMED_CHARACTER_REFERENCE(1173, 'i' _ 'm' _ 'p' _ 'e' _ 'd' _ ';', 6, 0x01b5, 1) -NAMED_CHARACTER_REFERENCE(1174, 'i' _ 'n' _ ';', 3, 0x2208, 1) -NAMED_CHARACTER_REFERENCE(1175, 'i' _ 'n' _ 'c' _ 'a' _ 'r' _ 'e' _ ';', 7, 0x2105, 1) -NAMED_CHARACTER_REFERENCE(1176, 'i' _ 'n' _ 'f' _ 'i' _ 'n' _ ';', 6, 0x221e, 1) -NAMED_CHARACTER_REFERENCE(1177, 'i' _ 'n' _ 'f' _ 'i' _ 'n' _ 't' _ 'i' _ 'e' _ ';', 9, 0x29dd, 1) -NAMED_CHARACTER_REFERENCE(1178, 'i' _ 'n' _ 'o' _ 'd' _ 'o' _ 't' _ ';', 7, 0x0131, 1) -NAMED_CHARACTER_REFERENCE(1179, 'i' _ 'n' _ 't' _ ';', 4, 0x222b, 1) -NAMED_CHARACTER_REFERENCE(1180, 'i' _ 'n' _ 't' _ 'c' _ 'a' _ 'l' _ ';', 7, 0x22ba, 1) -NAMED_CHARACTER_REFERENCE(1181, 'i' _ 'n' _ 't' _ 'e' _ 'g' _ 'e' _ 'r' _ 's' _ ';', 9, 0x2124, 1) -NAMED_CHARACTER_REFERENCE(1182, 'i' _ 'n' _ 't' _ 'e' _ 'r' _ 'c' _ 'a' _ 'l' _ ';', 9, 0x22ba, 1) -NAMED_CHARACTER_REFERENCE(1183, 'i' _ 'n' _ 't' _ 'l' _ 'a' _ 'r' _ 'h' _ 'k' _ ';', 9, 0x2a17, 1) -NAMED_CHARACTER_REFERENCE(1184, 'i' _ 'n' _ 't' _ 'p' _ 'r' _ 'o' _ 'd' _ ';', 8, 0x2a3c, 1) -NAMED_CHARACTER_REFERENCE(1185, 'i' _ 'o' _ 'c' _ 'y' _ ';', 5, 0x0451, 1) -NAMED_CHARACTER_REFERENCE(1186, 'i' _ 'o' _ 'g' _ 'o' _ 'n' _ ';', 6, 0x012f, 1) -NAMED_CHARACTER_REFERENCE(1187, 'i' _ 'o' _ 'p' _ 'f' _ ';', 5, 0xd835 _ 0xdd5a, 2) -NAMED_CHARACTER_REFERENCE(1188, 'i' _ 'o' _ 't' _ 'a' _ ';', 5, 0x03b9, 1) -NAMED_CHARACTER_REFERENCE(1189, 'i' _ 'p' _ 'r' _ 'o' _ 'd' _ ';', 6, 0x2a3c, 1) -NAMED_CHARACTER_REFERENCE(1190, 'i' _ 'q' _ 'u' _ 'e' _ 's' _ 't', 6, 0x00bf, 1) -NAMED_CHARACTER_REFERENCE(1191, 'i' _ 'q' _ 'u' _ 'e' _ 's' _ 't' _ ';', 7, 0x00bf, 1) -NAMED_CHARACTER_REFERENCE(1192, 'i' _ 's' _ 'c' _ 'r' _ ';', 5, 0xd835 _ 0xdcbe, 2) -NAMED_CHARACTER_REFERENCE(1193, 'i' _ 's' _ 'i' _ 'n' _ ';', 5, 0x2208, 1) -NAMED_CHARACTER_REFERENCE(1194, 'i' _ 's' _ 'i' _ 'n' _ 'E' _ ';', 6, 0x22f9, 1) -NAMED_CHARACTER_REFERENCE(1195, 'i' _ 's' _ 'i' _ 'n' _ 'd' _ 'o' _ 't' _ ';', 8, 0x22f5, 1) -NAMED_CHARACTER_REFERENCE(1196, 'i' _ 's' _ 'i' _ 'n' _ 's' _ ';', 6, 0x22f4, 1) -NAMED_CHARACTER_REFERENCE(1197, 'i' _ 's' _ 'i' _ 'n' _ 's' _ 'v' _ ';', 7, 0x22f3, 1) -NAMED_CHARACTER_REFERENCE(1198, 'i' _ 's' _ 'i' _ 'n' _ 'v' _ ';', 6, 0x2208, 1) -NAMED_CHARACTER_REFERENCE(1199, 'i' _ 't' _ ';', 3, 0x2062, 1) -NAMED_CHARACTER_REFERENCE(1200, 'i' _ 't' _ 'i' _ 'l' _ 'd' _ 'e' _ ';', 7, 0x0129, 1) -NAMED_CHARACTER_REFERENCE(1201, 'i' _ 'u' _ 'k' _ 'c' _ 'y' _ ';', 6, 0x0456, 1) -NAMED_CHARACTER_REFERENCE(1202, 'i' _ 'u' _ 'm' _ 'l', 4, 0x00ef, 1) -NAMED_CHARACTER_REFERENCE(1203, 'i' _ 'u' _ 'm' _ 'l' _ ';', 5, 0x00ef, 1) -NAMED_CHARACTER_REFERENCE(1204, 'j' _ 'c' _ 'i' _ 'r' _ 'c' _ ';', 6, 0x0135, 1) -NAMED_CHARACTER_REFERENCE(1205, 'j' _ 'c' _ 'y' _ ';', 4, 0x0439, 1) -NAMED_CHARACTER_REFERENCE(1206, 'j' _ 'f' _ 'r' _ ';', 4, 0xd835 _ 0xdd27, 2) -NAMED_CHARACTER_REFERENCE(1207, 'j' _ 'm' _ 'a' _ 't' _ 'h' _ ';', 6, 0x0237, 1) -NAMED_CHARACTER_REFERENCE(1208, 'j' _ 'o' _ 'p' _ 'f' _ ';', 5, 0xd835 _ 0xdd5b, 2) -NAMED_CHARACTER_REFERENCE(1209, 'j' _ 's' _ 'c' _ 'r' _ ';', 5, 0xd835 _ 0xdcbf, 2) -NAMED_CHARACTER_REFERENCE(1210, 'j' _ 's' _ 'e' _ 'r' _ 'c' _ 'y' _ ';', 7, 0x0458, 1) -NAMED_CHARACTER_REFERENCE(1211, 'j' _ 'u' _ 'k' _ 'c' _ 'y' _ ';', 6, 0x0454, 1) -NAMED_CHARACTER_REFERENCE(1212, 'k' _ 'a' _ 'p' _ 'p' _ 'a' _ ';', 6, 0x03ba, 1) -NAMED_CHARACTER_REFERENCE(1213, 'k' _ 'a' _ 'p' _ 'p' _ 'a' _ 'v' _ ';', 7, 0x03f0, 1) -NAMED_CHARACTER_REFERENCE(1214, 'k' _ 'c' _ 'e' _ 'd' _ 'i' _ 'l' _ ';', 7, 0x0137, 1) -NAMED_CHARACTER_REFERENCE(1215, 'k' _ 'c' _ 'y' _ ';', 4, 0x043a, 1) -NAMED_CHARACTER_REFERENCE(1216, 'k' _ 'f' _ 'r' _ ';', 4, 0xd835 _ 0xdd28, 2) -NAMED_CHARACTER_REFERENCE(1217, 'k' _ 'g' _ 'r' _ 'e' _ 'e' _ 'n' _ ';', 7, 0x0138, 1) -NAMED_CHARACTER_REFERENCE(1218, 'k' _ 'h' _ 'c' _ 'y' _ ';', 5, 0x0445, 1) -NAMED_CHARACTER_REFERENCE(1219, 'k' _ 'j' _ 'c' _ 'y' _ ';', 5, 0x045c, 1) -NAMED_CHARACTER_REFERENCE(1220, 'k' _ 'o' _ 'p' _ 'f' _ ';', 5, 0xd835 _ 0xdd5c, 2) -NAMED_CHARACTER_REFERENCE(1221, 'k' _ 's' _ 'c' _ 'r' _ ';', 5, 0xd835 _ 0xdcc0, 2) -NAMED_CHARACTER_REFERENCE(1222, 'l' _ 'A' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x21da, 1) -NAMED_CHARACTER_REFERENCE(1223, 'l' _ 'A' _ 'r' _ 'r' _ ';', 5, 0x21d0, 1) -NAMED_CHARACTER_REFERENCE(1224, 'l' _ 'A' _ 't' _ 'a' _ 'i' _ 'l' _ ';', 7, 0x291b, 1) -NAMED_CHARACTER_REFERENCE(1225, 'l' _ 'B' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x290e, 1) -NAMED_CHARACTER_REFERENCE(1226, 'l' _ 'E' _ ';', 3, 0x2266, 1) -NAMED_CHARACTER_REFERENCE(1227, 'l' _ 'E' _ 'g' _ ';', 4, 0x2a8b, 1) -NAMED_CHARACTER_REFERENCE(1228, 'l' _ 'H' _ 'a' _ 'r' _ ';', 5, 0x2962, 1) -NAMED_CHARACTER_REFERENCE(1229, 'l' _ 'a' _ 'c' _ 'u' _ 't' _ 'e' _ ';', 7, 0x013a, 1) -NAMED_CHARACTER_REFERENCE(1230, 'l' _ 'a' _ 'e' _ 'm' _ 'p' _ 't' _ 'y' _ 'v' _ ';', 9, 0x29b4, 1) -NAMED_CHARACTER_REFERENCE(1231, 'l' _ 'a' _ 'g' _ 'r' _ 'a' _ 'n' _ ';', 7, 0x2112, 1) -NAMED_CHARACTER_REFERENCE(1232, 'l' _ 'a' _ 'm' _ 'b' _ 'd' _ 'a' _ ';', 7, 0x03bb, 1) -NAMED_CHARACTER_REFERENCE(1233, 'l' _ 'a' _ 'n' _ 'g' _ ';', 5, 0x27e8, 1) -NAMED_CHARACTER_REFERENCE(1234, 'l' _ 'a' _ 'n' _ 'g' _ 'd' _ ';', 6, 0x2991, 1) -NAMED_CHARACTER_REFERENCE(1235, 'l' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ ';', 7, 0x27e8, 1) -NAMED_CHARACTER_REFERENCE(1236, 'l' _ 'a' _ 'p' _ ';', 4, 0x2a85, 1) -NAMED_CHARACTER_REFERENCE(1237, 'l' _ 'a' _ 'q' _ 'u' _ 'o', 5, 0x00ab, 1) -NAMED_CHARACTER_REFERENCE(1238, 'l' _ 'a' _ 'q' _ 'u' _ 'o' _ ';', 6, 0x00ab, 1) -NAMED_CHARACTER_REFERENCE(1239, 'l' _ 'a' _ 'r' _ 'r' _ ';', 5, 0x2190, 1) -NAMED_CHARACTER_REFERENCE(1240, 'l' _ 'a' _ 'r' _ 'r' _ 'b' _ ';', 6, 0x21e4, 1) -NAMED_CHARACTER_REFERENCE(1241, 'l' _ 'a' _ 'r' _ 'r' _ 'b' _ 'f' _ 's' _ ';', 8, 0x291f, 1) -NAMED_CHARACTER_REFERENCE(1242, 'l' _ 'a' _ 'r' _ 'r' _ 'f' _ 's' _ ';', 7, 0x291d, 1) -NAMED_CHARACTER_REFERENCE(1243, 'l' _ 'a' _ 'r' _ 'r' _ 'h' _ 'k' _ ';', 7, 0x21a9, 1) -NAMED_CHARACTER_REFERENCE(1244, 'l' _ 'a' _ 'r' _ 'r' _ 'l' _ 'p' _ ';', 7, 0x21ab, 1) -NAMED_CHARACTER_REFERENCE(1245, 'l' _ 'a' _ 'r' _ 'r' _ 'p' _ 'l' _ ';', 7, 0x2939, 1) -NAMED_CHARACTER_REFERENCE(1246, 'l' _ 'a' _ 'r' _ 'r' _ 's' _ 'i' _ 'm' _ ';', 8, 0x2973, 1) -NAMED_CHARACTER_REFERENCE(1247, 'l' _ 'a' _ 'r' _ 'r' _ 't' _ 'l' _ ';', 7, 0x21a2, 1) -NAMED_CHARACTER_REFERENCE(1248, 'l' _ 'a' _ 't' _ ';', 4, 0x2aab, 1) -NAMED_CHARACTER_REFERENCE(1249, 'l' _ 'a' _ 't' _ 'a' _ 'i' _ 'l' _ ';', 7, 0x2919, 1) -NAMED_CHARACTER_REFERENCE(1250, 'l' _ 'a' _ 't' _ 'e' _ ';', 5, 0x2aad, 1) -NAMED_CHARACTER_REFERENCE(1251, 'l' _ 'b' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x290c, 1) -NAMED_CHARACTER_REFERENCE(1252, 'l' _ 'b' _ 'b' _ 'r' _ 'k' _ ';', 6, 0x2772, 1) -NAMED_CHARACTER_REFERENCE(1253, 'l' _ 'b' _ 'r' _ 'a' _ 'c' _ 'e' _ ';', 7, 0x007b, 1) -NAMED_CHARACTER_REFERENCE(1254, 'l' _ 'b' _ 'r' _ 'a' _ 'c' _ 'k' _ ';', 7, 0x005b, 1) -NAMED_CHARACTER_REFERENCE(1255, 'l' _ 'b' _ 'r' _ 'k' _ 'e' _ ';', 6, 0x298b, 1) -NAMED_CHARACTER_REFERENCE(1256, 'l' _ 'b' _ 'r' _ 'k' _ 's' _ 'l' _ 'd' _ ';', 8, 0x298f, 1) -NAMED_CHARACTER_REFERENCE(1257, 'l' _ 'b' _ 'r' _ 'k' _ 's' _ 'l' _ 'u' _ ';', 8, 0x298d, 1) -NAMED_CHARACTER_REFERENCE(1258, 'l' _ 'c' _ 'a' _ 'r' _ 'o' _ 'n' _ ';', 7, 0x013e, 1) -NAMED_CHARACTER_REFERENCE(1259, 'l' _ 'c' _ 'e' _ 'd' _ 'i' _ 'l' _ ';', 7, 0x013c, 1) -NAMED_CHARACTER_REFERENCE(1260, 'l' _ 'c' _ 'e' _ 'i' _ 'l' _ ';', 6, 0x2308, 1) -NAMED_CHARACTER_REFERENCE(1261, 'l' _ 'c' _ 'u' _ 'b' _ ';', 5, 0x007b, 1) -NAMED_CHARACTER_REFERENCE(1262, 'l' _ 'c' _ 'y' _ ';', 4, 0x043b, 1) -NAMED_CHARACTER_REFERENCE(1263, 'l' _ 'd' _ 'c' _ 'a' _ ';', 5, 0x2936, 1) -NAMED_CHARACTER_REFERENCE(1264, 'l' _ 'd' _ 'q' _ 'u' _ 'o' _ ';', 6, 0x201c, 1) -NAMED_CHARACTER_REFERENCE(1265, 'l' _ 'd' _ 'q' _ 'u' _ 'o' _ 'r' _ ';', 7, 0x201e, 1) -NAMED_CHARACTER_REFERENCE(1266, 'l' _ 'd' _ 'r' _ 'd' _ 'h' _ 'a' _ 'r' _ ';', 8, 0x2967, 1) -NAMED_CHARACTER_REFERENCE(1267, 'l' _ 'd' _ 'r' _ 'u' _ 's' _ 'h' _ 'a' _ 'r' _ ';', 9, 0x294b, 1) -NAMED_CHARACTER_REFERENCE(1268, 'l' _ 'd' _ 's' _ 'h' _ ';', 5, 0x21b2, 1) -NAMED_CHARACTER_REFERENCE(1269, 'l' _ 'e' _ ';', 3, 0x2264, 1) -NAMED_CHARACTER_REFERENCE(1270, 'l' _ 'e' _ 'f' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 10, 0x2190, 1) -NAMED_CHARACTER_REFERENCE(1271, 'l' _ 'e' _ 'f' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ 't' _ 'a' _ 'i' _ 'l' _ ';', 14, 0x21a2, 1) -NAMED_CHARACTER_REFERENCE(1272, 'l' _ 'e' _ 'f' _ 't' _ 'h' _ 'a' _ 'r' _ 'p' _ 'o' _ 'o' _ 'n' _ 'd' _ 'o' _ 'w' _ 'n' _ ';', 16, 0x21bd, 1) -NAMED_CHARACTER_REFERENCE(1273, 'l' _ 'e' _ 'f' _ 't' _ 'h' _ 'a' _ 'r' _ 'p' _ 'o' _ 'o' _ 'n' _ 'u' _ 'p' _ ';', 14, 0x21bc, 1) -NAMED_CHARACTER_REFERENCE(1274, 'l' _ 'e' _ 'f' _ 't' _ 'l' _ 'e' _ 'f' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ 's' _ ';', 15, 0x21c7, 1) -NAMED_CHARACTER_REFERENCE(1275, 'l' _ 'e' _ 'f' _ 't' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 15, 0x2194, 1) -NAMED_CHARACTER_REFERENCE(1276, 'l' _ 'e' _ 'f' _ 't' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ 's' _ ';', 16, 0x21c6, 1) -NAMED_CHARACTER_REFERENCE(1277, 'l' _ 'e' _ 'f' _ 't' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ 'h' _ 'a' _ 'r' _ 'p' _ 'o' _ 'o' _ 'n' _ 's' _ ';', 18, 0x21cb, 1) -NAMED_CHARACTER_REFERENCE(1278, 'l' _ 'e' _ 'f' _ 't' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ 's' _ 'q' _ 'u' _ 'i' _ 'g' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 20, 0x21ad, 1) -NAMED_CHARACTER_REFERENCE(1279, 'l' _ 'e' _ 'f' _ 't' _ 't' _ 'h' _ 'r' _ 'e' _ 'e' _ 't' _ 'i' _ 'm' _ 'e' _ 's' _ ';', 15, 0x22cb, 1) -NAMED_CHARACTER_REFERENCE(1280, 'l' _ 'e' _ 'g' _ ';', 4, 0x22da, 1) -NAMED_CHARACTER_REFERENCE(1281, 'l' _ 'e' _ 'q' _ ';', 4, 0x2264, 1) -NAMED_CHARACTER_REFERENCE(1282, 'l' _ 'e' _ 'q' _ 'q' _ ';', 5, 0x2266, 1) -NAMED_CHARACTER_REFERENCE(1283, 'l' _ 'e' _ 'q' _ 's' _ 'l' _ 'a' _ 'n' _ 't' _ ';', 9, 0x2a7d, 1) -NAMED_CHARACTER_REFERENCE(1284, 'l' _ 'e' _ 's' _ ';', 4, 0x2a7d, 1) -NAMED_CHARACTER_REFERENCE(1285, 'l' _ 'e' _ 's' _ 'c' _ 'c' _ ';', 6, 0x2aa8, 1) -NAMED_CHARACTER_REFERENCE(1286, 'l' _ 'e' _ 's' _ 'd' _ 'o' _ 't' _ ';', 7, 0x2a7f, 1) -NAMED_CHARACTER_REFERENCE(1287, 'l' _ 'e' _ 's' _ 'd' _ 'o' _ 't' _ 'o' _ ';', 8, 0x2a81, 1) -NAMED_CHARACTER_REFERENCE(1288, 'l' _ 'e' _ 's' _ 'd' _ 'o' _ 't' _ 'o' _ 'r' _ ';', 9, 0x2a83, 1) -NAMED_CHARACTER_REFERENCE(1289, 'l' _ 'e' _ 's' _ 'g' _ 'e' _ 's' _ ';', 7, 0x2a93, 1) -NAMED_CHARACTER_REFERENCE(1290, 'l' _ 'e' _ 's' _ 's' _ 'a' _ 'p' _ 'p' _ 'r' _ 'o' _ 'x' _ ';', 11, 0x2a85, 1) -NAMED_CHARACTER_REFERENCE(1291, 'l' _ 'e' _ 's' _ 's' _ 'd' _ 'o' _ 't' _ ';', 8, 0x22d6, 1) -NAMED_CHARACTER_REFERENCE(1292, 'l' _ 'e' _ 's' _ 's' _ 'e' _ 'q' _ 'g' _ 't' _ 'r' _ ';', 10, 0x22da, 1) -NAMED_CHARACTER_REFERENCE(1293, 'l' _ 'e' _ 's' _ 's' _ 'e' _ 'q' _ 'q' _ 'g' _ 't' _ 'r' _ ';', 11, 0x2a8b, 1) -NAMED_CHARACTER_REFERENCE(1294, 'l' _ 'e' _ 's' _ 's' _ 'g' _ 't' _ 'r' _ ';', 8, 0x2276, 1) -NAMED_CHARACTER_REFERENCE(1295, 'l' _ 'e' _ 's' _ 's' _ 's' _ 'i' _ 'm' _ ';', 8, 0x2272, 1) -NAMED_CHARACTER_REFERENCE(1296, 'l' _ 'f' _ 'i' _ 's' _ 'h' _ 't' _ ';', 7, 0x297c, 1) -NAMED_CHARACTER_REFERENCE(1297, 'l' _ 'f' _ 'l' _ 'o' _ 'o' _ 'r' _ ';', 7, 0x230a, 1) -NAMED_CHARACTER_REFERENCE(1298, 'l' _ 'f' _ 'r' _ ';', 4, 0xd835 _ 0xdd29, 2) -NAMED_CHARACTER_REFERENCE(1299, 'l' _ 'g' _ ';', 3, 0x2276, 1) -NAMED_CHARACTER_REFERENCE(1300, 'l' _ 'g' _ 'E' _ ';', 4, 0x2a91, 1) -NAMED_CHARACTER_REFERENCE(1301, 'l' _ 'h' _ 'a' _ 'r' _ 'd' _ ';', 6, 0x21bd, 1) -NAMED_CHARACTER_REFERENCE(1302, 'l' _ 'h' _ 'a' _ 'r' _ 'u' _ ';', 6, 0x21bc, 1) -NAMED_CHARACTER_REFERENCE(1303, 'l' _ 'h' _ 'a' _ 'r' _ 'u' _ 'l' _ ';', 7, 0x296a, 1) -NAMED_CHARACTER_REFERENCE(1304, 'l' _ 'h' _ 'b' _ 'l' _ 'k' _ ';', 6, 0x2584, 1) -NAMED_CHARACTER_REFERENCE(1305, 'l' _ 'j' _ 'c' _ 'y' _ ';', 5, 0x0459, 1) -NAMED_CHARACTER_REFERENCE(1306, 'l' _ 'l' _ ';', 3, 0x226a, 1) -NAMED_CHARACTER_REFERENCE(1307, 'l' _ 'l' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x21c7, 1) -NAMED_CHARACTER_REFERENCE(1308, 'l' _ 'l' _ 'c' _ 'o' _ 'r' _ 'n' _ 'e' _ 'r' _ ';', 9, 0x231e, 1) -NAMED_CHARACTER_REFERENCE(1309, 'l' _ 'l' _ 'h' _ 'a' _ 'r' _ 'd' _ ';', 7, 0x296b, 1) -NAMED_CHARACTER_REFERENCE(1310, 'l' _ 'l' _ 't' _ 'r' _ 'i' _ ';', 6, 0x25fa, 1) -NAMED_CHARACTER_REFERENCE(1311, 'l' _ 'm' _ 'i' _ 'd' _ 'o' _ 't' _ ';', 7, 0x0140, 1) -NAMED_CHARACTER_REFERENCE(1312, 'l' _ 'm' _ 'o' _ 'u' _ 's' _ 't' _ ';', 7, 0x23b0, 1) -NAMED_CHARACTER_REFERENCE(1313, 'l' _ 'm' _ 'o' _ 'u' _ 's' _ 't' _ 'a' _ 'c' _ 'h' _ 'e' _ ';', 11, 0x23b0, 1) -NAMED_CHARACTER_REFERENCE(1314, 'l' _ 'n' _ 'E' _ ';', 4, 0x2268, 1) -NAMED_CHARACTER_REFERENCE(1315, 'l' _ 'n' _ 'a' _ 'p' _ ';', 5, 0x2a89, 1) -NAMED_CHARACTER_REFERENCE(1316, 'l' _ 'n' _ 'a' _ 'p' _ 'p' _ 'r' _ 'o' _ 'x' _ ';', 9, 0x2a89, 1) -NAMED_CHARACTER_REFERENCE(1317, 'l' _ 'n' _ 'e' _ ';', 4, 0x2a87, 1) -NAMED_CHARACTER_REFERENCE(1318, 'l' _ 'n' _ 'e' _ 'q' _ ';', 5, 0x2a87, 1) -NAMED_CHARACTER_REFERENCE(1319, 'l' _ 'n' _ 'e' _ 'q' _ 'q' _ ';', 6, 0x2268, 1) -NAMED_CHARACTER_REFERENCE(1320, 'l' _ 'n' _ 's' _ 'i' _ 'm' _ ';', 6, 0x22e6, 1) -NAMED_CHARACTER_REFERENCE(1321, 'l' _ 'o' _ 'a' _ 'n' _ 'g' _ ';', 6, 0x27ec, 1) -NAMED_CHARACTER_REFERENCE(1322, 'l' _ 'o' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x21fd, 1) -NAMED_CHARACTER_REFERENCE(1323, 'l' _ 'o' _ 'b' _ 'r' _ 'k' _ ';', 6, 0x27e6, 1) -NAMED_CHARACTER_REFERENCE(1324, 'l' _ 'o' _ 'n' _ 'g' _ 'l' _ 'e' _ 'f' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 14, 0x27f5, 1) -NAMED_CHARACTER_REFERENCE(1325, 'l' _ 'o' _ 'n' _ 'g' _ 'l' _ 'e' _ 'f' _ 't' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 19, 0x27f7, 1) -NAMED_CHARACTER_REFERENCE(1326, 'l' _ 'o' _ 'n' _ 'g' _ 'm' _ 'a' _ 'p' _ 's' _ 't' _ 'o' _ ';', 11, 0x27fc, 1) -NAMED_CHARACTER_REFERENCE(1327, 'l' _ 'o' _ 'n' _ 'g' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 15, 0x27f6, 1) -NAMED_CHARACTER_REFERENCE(1328, 'l' _ 'o' _ 'o' _ 'p' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ 'l' _ 'e' _ 'f' _ 't' _ ';', 14, 0x21ab, 1) -NAMED_CHARACTER_REFERENCE(1329, 'l' _ 'o' _ 'o' _ 'p' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ ';', 15, 0x21ac, 1) -NAMED_CHARACTER_REFERENCE(1330, 'l' _ 'o' _ 'p' _ 'a' _ 'r' _ ';', 6, 0x2985, 1) -NAMED_CHARACTER_REFERENCE(1331, 'l' _ 'o' _ 'p' _ 'f' _ ';', 5, 0xd835 _ 0xdd5d, 2) -NAMED_CHARACTER_REFERENCE(1332, 'l' _ 'o' _ 'p' _ 'l' _ 'u' _ 's' _ ';', 7, 0x2a2d, 1) -NAMED_CHARACTER_REFERENCE(1333, 'l' _ 'o' _ 't' _ 'i' _ 'm' _ 'e' _ 's' _ ';', 8, 0x2a34, 1) -NAMED_CHARACTER_REFERENCE(1334, 'l' _ 'o' _ 'w' _ 'a' _ 's' _ 't' _ ';', 7, 0x2217, 1) -NAMED_CHARACTER_REFERENCE(1335, 'l' _ 'o' _ 'w' _ 'b' _ 'a' _ 'r' _ ';', 7, 0x005f, 1) -NAMED_CHARACTER_REFERENCE(1336, 'l' _ 'o' _ 'z' _ ';', 4, 0x25ca, 1) -NAMED_CHARACTER_REFERENCE(1337, 'l' _ 'o' _ 'z' _ 'e' _ 'n' _ 'g' _ 'e' _ ';', 8, 0x25ca, 1) -NAMED_CHARACTER_REFERENCE(1338, 'l' _ 'o' _ 'z' _ 'f' _ ';', 5, 0x29eb, 1) -NAMED_CHARACTER_REFERENCE(1339, 'l' _ 'p' _ 'a' _ 'r' _ ';', 5, 0x0028, 1) -NAMED_CHARACTER_REFERENCE(1340, 'l' _ 'p' _ 'a' _ 'r' _ 'l' _ 't' _ ';', 7, 0x2993, 1) -NAMED_CHARACTER_REFERENCE(1341, 'l' _ 'r' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x21c6, 1) -NAMED_CHARACTER_REFERENCE(1342, 'l' _ 'r' _ 'c' _ 'o' _ 'r' _ 'n' _ 'e' _ 'r' _ ';', 9, 0x231f, 1) -NAMED_CHARACTER_REFERENCE(1343, 'l' _ 'r' _ 'h' _ 'a' _ 'r' _ ';', 6, 0x21cb, 1) -NAMED_CHARACTER_REFERENCE(1344, 'l' _ 'r' _ 'h' _ 'a' _ 'r' _ 'd' _ ';', 7, 0x296d, 1) -NAMED_CHARACTER_REFERENCE(1345, 'l' _ 'r' _ 'm' _ ';', 4, 0x200e, 1) -NAMED_CHARACTER_REFERENCE(1346, 'l' _ 'r' _ 't' _ 'r' _ 'i' _ ';', 6, 0x22bf, 1) -NAMED_CHARACTER_REFERENCE(1347, 'l' _ 's' _ 'a' _ 'q' _ 'u' _ 'o' _ ';', 7, 0x2039, 1) -NAMED_CHARACTER_REFERENCE(1348, 'l' _ 's' _ 'c' _ 'r' _ ';', 5, 0xd835 _ 0xdcc1, 2) -NAMED_CHARACTER_REFERENCE(1349, 'l' _ 's' _ 'h' _ ';', 4, 0x21b0, 1) -NAMED_CHARACTER_REFERENCE(1350, 'l' _ 's' _ 'i' _ 'm' _ ';', 5, 0x2272, 1) -NAMED_CHARACTER_REFERENCE(1351, 'l' _ 's' _ 'i' _ 'm' _ 'e' _ ';', 6, 0x2a8d, 1) -NAMED_CHARACTER_REFERENCE(1352, 'l' _ 's' _ 'i' _ 'm' _ 'g' _ ';', 6, 0x2a8f, 1) -NAMED_CHARACTER_REFERENCE(1353, 'l' _ 's' _ 'q' _ 'b' _ ';', 5, 0x005b, 1) -NAMED_CHARACTER_REFERENCE(1354, 'l' _ 's' _ 'q' _ 'u' _ 'o' _ ';', 6, 0x2018, 1) -NAMED_CHARACTER_REFERENCE(1355, 'l' _ 's' _ 'q' _ 'u' _ 'o' _ 'r' _ ';', 7, 0x201a, 1) -NAMED_CHARACTER_REFERENCE(1356, 'l' _ 's' _ 't' _ 'r' _ 'o' _ 'k' _ ';', 7, 0x0142, 1) -NAMED_CHARACTER_REFERENCE(1357, 'l' _ 't', 2, 0x003c, 1) -NAMED_CHARACTER_REFERENCE(1358, 'l' _ 't' _ ';', 3, 0x003c, 1) -NAMED_CHARACTER_REFERENCE(1359, 'l' _ 't' _ 'c' _ 'c' _ ';', 5, 0x2aa6, 1) -NAMED_CHARACTER_REFERENCE(1360, 'l' _ 't' _ 'c' _ 'i' _ 'r' _ ';', 6, 0x2a79, 1) -NAMED_CHARACTER_REFERENCE(1361, 'l' _ 't' _ 'd' _ 'o' _ 't' _ ';', 6, 0x22d6, 1) -NAMED_CHARACTER_REFERENCE(1362, 'l' _ 't' _ 'h' _ 'r' _ 'e' _ 'e' _ ';', 7, 0x22cb, 1) -NAMED_CHARACTER_REFERENCE(1363, 'l' _ 't' _ 'i' _ 'm' _ 'e' _ 's' _ ';', 7, 0x22c9, 1) -NAMED_CHARACTER_REFERENCE(1364, 'l' _ 't' _ 'l' _ 'a' _ 'r' _ 'r' _ ';', 7, 0x2976, 1) -NAMED_CHARACTER_REFERENCE(1365, 'l' _ 't' _ 'q' _ 'u' _ 'e' _ 's' _ 't' _ ';', 8, 0x2a7b, 1) -NAMED_CHARACTER_REFERENCE(1366, 'l' _ 't' _ 'r' _ 'P' _ 'a' _ 'r' _ ';', 7, 0x2996, 1) -NAMED_CHARACTER_REFERENCE(1367, 'l' _ 't' _ 'r' _ 'i' _ ';', 5, 0x25c3, 1) -NAMED_CHARACTER_REFERENCE(1368, 'l' _ 't' _ 'r' _ 'i' _ 'e' _ ';', 6, 0x22b4, 1) -NAMED_CHARACTER_REFERENCE(1369, 'l' _ 't' _ 'r' _ 'i' _ 'f' _ ';', 6, 0x25c2, 1) -NAMED_CHARACTER_REFERENCE(1370, 'l' _ 'u' _ 'r' _ 'd' _ 's' _ 'h' _ 'a' _ 'r' _ ';', 9, 0x294a, 1) -NAMED_CHARACTER_REFERENCE(1371, 'l' _ 'u' _ 'r' _ 'u' _ 'h' _ 'a' _ 'r' _ ';', 8, 0x2966, 1) -NAMED_CHARACTER_REFERENCE(1372, 'm' _ 'D' _ 'D' _ 'o' _ 't' _ ';', 6, 0x223a, 1) -NAMED_CHARACTER_REFERENCE(1373, 'm' _ 'a' _ 'c' _ 'r', 4, 0x00af, 1) -NAMED_CHARACTER_REFERENCE(1374, 'm' _ 'a' _ 'c' _ 'r' _ ';', 5, 0x00af, 1) -NAMED_CHARACTER_REFERENCE(1375, 'm' _ 'a' _ 'l' _ 'e' _ ';', 5, 0x2642, 1) -NAMED_CHARACTER_REFERENCE(1376, 'm' _ 'a' _ 'l' _ 't' _ ';', 5, 0x2720, 1) -NAMED_CHARACTER_REFERENCE(1377, 'm' _ 'a' _ 'l' _ 't' _ 'e' _ 's' _ 'e' _ ';', 8, 0x2720, 1) -NAMED_CHARACTER_REFERENCE(1378, 'm' _ 'a' _ 'p' _ ';', 4, 0x21a6, 1) -NAMED_CHARACTER_REFERENCE(1379, 'm' _ 'a' _ 'p' _ 's' _ 't' _ 'o' _ ';', 7, 0x21a6, 1) -NAMED_CHARACTER_REFERENCE(1380, 'm' _ 'a' _ 'p' _ 's' _ 't' _ 'o' _ 'd' _ 'o' _ 'w' _ 'n' _ ';', 11, 0x21a7, 1) -NAMED_CHARACTER_REFERENCE(1381, 'm' _ 'a' _ 'p' _ 's' _ 't' _ 'o' _ 'l' _ 'e' _ 'f' _ 't' _ ';', 11, 0x21a4, 1) -NAMED_CHARACTER_REFERENCE(1382, 'm' _ 'a' _ 'p' _ 's' _ 't' _ 'o' _ 'u' _ 'p' _ ';', 9, 0x21a5, 1) -NAMED_CHARACTER_REFERENCE(1383, 'm' _ 'a' _ 'r' _ 'k' _ 'e' _ 'r' _ ';', 7, 0x25ae, 1) -NAMED_CHARACTER_REFERENCE(1384, 'm' _ 'c' _ 'o' _ 'm' _ 'm' _ 'a' _ ';', 7, 0x2a29, 1) -NAMED_CHARACTER_REFERENCE(1385, 'm' _ 'c' _ 'y' _ ';', 4, 0x043c, 1) -NAMED_CHARACTER_REFERENCE(1386, 'm' _ 'd' _ 'a' _ 's' _ 'h' _ ';', 6, 0x2014, 1) -NAMED_CHARACTER_REFERENCE(1387, 'm' _ 'e' _ 'a' _ 's' _ 'u' _ 'r' _ 'e' _ 'd' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ ';', 14, 0x2221, 1) -NAMED_CHARACTER_REFERENCE(1388, 'm' _ 'f' _ 'r' _ ';', 4, 0xd835 _ 0xdd2a, 2) -NAMED_CHARACTER_REFERENCE(1389, 'm' _ 'h' _ 'o' _ ';', 4, 0x2127, 1) -NAMED_CHARACTER_REFERENCE(1390, 'm' _ 'i' _ 'c' _ 'r' _ 'o', 5, 0x00b5, 1) -NAMED_CHARACTER_REFERENCE(1391, 'm' _ 'i' _ 'c' _ 'r' _ 'o' _ ';', 6, 0x00b5, 1) -NAMED_CHARACTER_REFERENCE(1392, 'm' _ 'i' _ 'd' _ ';', 4, 0x2223, 1) -NAMED_CHARACTER_REFERENCE(1393, 'm' _ 'i' _ 'd' _ 'a' _ 's' _ 't' _ ';', 7, 0x002a, 1) -NAMED_CHARACTER_REFERENCE(1394, 'm' _ 'i' _ 'd' _ 'c' _ 'i' _ 'r' _ ';', 7, 0x2af0, 1) -NAMED_CHARACTER_REFERENCE(1395, 'm' _ 'i' _ 'd' _ 'd' _ 'o' _ 't', 6, 0x00b7, 1) -NAMED_CHARACTER_REFERENCE(1396, 'm' _ 'i' _ 'd' _ 'd' _ 'o' _ 't' _ ';', 7, 0x00b7, 1) -NAMED_CHARACTER_REFERENCE(1397, 'm' _ 'i' _ 'n' _ 'u' _ 's' _ ';', 6, 0x2212, 1) -NAMED_CHARACTER_REFERENCE(1398, 'm' _ 'i' _ 'n' _ 'u' _ 's' _ 'b' _ ';', 7, 0x229f, 1) -NAMED_CHARACTER_REFERENCE(1399, 'm' _ 'i' _ 'n' _ 'u' _ 's' _ 'd' _ ';', 7, 0x2238, 1) -NAMED_CHARACTER_REFERENCE(1400, 'm' _ 'i' _ 'n' _ 'u' _ 's' _ 'd' _ 'u' _ ';', 8, 0x2a2a, 1) -NAMED_CHARACTER_REFERENCE(1401, 'm' _ 'l' _ 'c' _ 'p' _ ';', 5, 0x2adb, 1) -NAMED_CHARACTER_REFERENCE(1402, 'm' _ 'l' _ 'd' _ 'r' _ ';', 5, 0x2026, 1) -NAMED_CHARACTER_REFERENCE(1403, 'm' _ 'n' _ 'p' _ 'l' _ 'u' _ 's' _ ';', 7, 0x2213, 1) -NAMED_CHARACTER_REFERENCE(1404, 'm' _ 'o' _ 'd' _ 'e' _ 'l' _ 's' _ ';', 7, 0x22a7, 1) -NAMED_CHARACTER_REFERENCE(1405, 'm' _ 'o' _ 'p' _ 'f' _ ';', 5, 0xd835 _ 0xdd5e, 2) -NAMED_CHARACTER_REFERENCE(1406, 'm' _ 'p' _ ';', 3, 0x2213, 1) -NAMED_CHARACTER_REFERENCE(1407, 'm' _ 's' _ 'c' _ 'r' _ ';', 5, 0xd835 _ 0xdcc2, 2) -NAMED_CHARACTER_REFERENCE(1408, 'm' _ 's' _ 't' _ 'p' _ 'o' _ 's' _ ';', 7, 0x223e, 1) -NAMED_CHARACTER_REFERENCE(1409, 'm' _ 'u' _ ';', 3, 0x03bc, 1) -NAMED_CHARACTER_REFERENCE(1410, 'm' _ 'u' _ 'l' _ 't' _ 'i' _ 'm' _ 'a' _ 'p' _ ';', 9, 0x22b8, 1) -NAMED_CHARACTER_REFERENCE(1411, 'm' _ 'u' _ 'm' _ 'a' _ 'p' _ ';', 6, 0x22b8, 1) -NAMED_CHARACTER_REFERENCE(1412, 'n' _ 'L' _ 'e' _ 'f' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 11, 0x21cd, 1) -NAMED_CHARACTER_REFERENCE(1413, 'n' _ 'L' _ 'e' _ 'f' _ 't' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 16, 0x21ce, 1) -NAMED_CHARACTER_REFERENCE(1414, 'n' _ 'R' _ 'i' _ 'g' _ 'h' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 12, 0x21cf, 1) -NAMED_CHARACTER_REFERENCE(1415, 'n' _ 'V' _ 'D' _ 'a' _ 's' _ 'h' _ ';', 7, 0x22af, 1) -NAMED_CHARACTER_REFERENCE(1416, 'n' _ 'V' _ 'd' _ 'a' _ 's' _ 'h' _ ';', 7, 0x22ae, 1) -NAMED_CHARACTER_REFERENCE(1417, 'n' _ 'a' _ 'b' _ 'l' _ 'a' _ ';', 6, 0x2207, 1) -NAMED_CHARACTER_REFERENCE(1418, 'n' _ 'a' _ 'c' _ 'u' _ 't' _ 'e' _ ';', 7, 0x0144, 1) -NAMED_CHARACTER_REFERENCE(1419, 'n' _ 'a' _ 'p' _ ';', 4, 0x2249, 1) -NAMED_CHARACTER_REFERENCE(1420, 'n' _ 'a' _ 'p' _ 'o' _ 's' _ ';', 6, 0x0149, 1) -NAMED_CHARACTER_REFERENCE(1421, 'n' _ 'a' _ 'p' _ 'p' _ 'r' _ 'o' _ 'x' _ ';', 8, 0x2249, 1) -NAMED_CHARACTER_REFERENCE(1422, 'n' _ 'a' _ 't' _ 'u' _ 'r' _ ';', 6, 0x266e, 1) -NAMED_CHARACTER_REFERENCE(1423, 'n' _ 'a' _ 't' _ 'u' _ 'r' _ 'a' _ 'l' _ ';', 8, 0x266e, 1) -NAMED_CHARACTER_REFERENCE(1424, 'n' _ 'a' _ 't' _ 'u' _ 'r' _ 'a' _ 'l' _ 's' _ ';', 9, 0x2115, 1) -NAMED_CHARACTER_REFERENCE(1425, 'n' _ 'b' _ 's' _ 'p', 4, 0x00a0, 1) -NAMED_CHARACTER_REFERENCE(1426, 'n' _ 'b' _ 's' _ 'p' _ ';', 5, 0x00a0, 1) -NAMED_CHARACTER_REFERENCE(1427, 'n' _ 'c' _ 'a' _ 'p' _ ';', 5, 0x2a43, 1) -NAMED_CHARACTER_REFERENCE(1428, 'n' _ 'c' _ 'a' _ 'r' _ 'o' _ 'n' _ ';', 7, 0x0148, 1) -NAMED_CHARACTER_REFERENCE(1429, 'n' _ 'c' _ 'e' _ 'd' _ 'i' _ 'l' _ ';', 7, 0x0146, 1) -NAMED_CHARACTER_REFERENCE(1430, 'n' _ 'c' _ 'o' _ 'n' _ 'g' _ ';', 6, 0x2247, 1) -NAMED_CHARACTER_REFERENCE(1431, 'n' _ 'c' _ 'u' _ 'p' _ ';', 5, 0x2a42, 1) -NAMED_CHARACTER_REFERENCE(1432, 'n' _ 'c' _ 'y' _ ';', 4, 0x043d, 1) -NAMED_CHARACTER_REFERENCE(1433, 'n' _ 'd' _ 'a' _ 's' _ 'h' _ ';', 6, 0x2013, 1) -NAMED_CHARACTER_REFERENCE(1434, 'n' _ 'e' _ ';', 3, 0x2260, 1) -NAMED_CHARACTER_REFERENCE(1435, 'n' _ 'e' _ 'A' _ 'r' _ 'r' _ ';', 6, 0x21d7, 1) -NAMED_CHARACTER_REFERENCE(1436, 'n' _ 'e' _ 'a' _ 'r' _ 'h' _ 'k' _ ';', 7, 0x2924, 1) -NAMED_CHARACTER_REFERENCE(1437, 'n' _ 'e' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x2197, 1) -NAMED_CHARACTER_REFERENCE(1438, 'n' _ 'e' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 8, 0x2197, 1) -NAMED_CHARACTER_REFERENCE(1439, 'n' _ 'e' _ 'q' _ 'u' _ 'i' _ 'v' _ ';', 7, 0x2262, 1) -NAMED_CHARACTER_REFERENCE(1440, 'n' _ 'e' _ 's' _ 'e' _ 'a' _ 'r' _ ';', 7, 0x2928, 1) -NAMED_CHARACTER_REFERENCE(1441, 'n' _ 'e' _ 'x' _ 'i' _ 's' _ 't' _ ';', 7, 0x2204, 1) -NAMED_CHARACTER_REFERENCE(1442, 'n' _ 'e' _ 'x' _ 'i' _ 's' _ 't' _ 's' _ ';', 8, 0x2204, 1) -NAMED_CHARACTER_REFERENCE(1443, 'n' _ 'f' _ 'r' _ ';', 4, 0xd835 _ 0xdd2b, 2) -NAMED_CHARACTER_REFERENCE(1444, 'n' _ 'g' _ 'e' _ ';', 4, 0x2271, 1) -NAMED_CHARACTER_REFERENCE(1445, 'n' _ 'g' _ 'e' _ 'q' _ ';', 5, 0x2271, 1) -NAMED_CHARACTER_REFERENCE(1446, 'n' _ 'g' _ 's' _ 'i' _ 'm' _ ';', 6, 0x2275, 1) -NAMED_CHARACTER_REFERENCE(1447, 'n' _ 'g' _ 't' _ ';', 4, 0x226f, 1) -NAMED_CHARACTER_REFERENCE(1448, 'n' _ 'g' _ 't' _ 'r' _ ';', 5, 0x226f, 1) -NAMED_CHARACTER_REFERENCE(1449, 'n' _ 'h' _ 'A' _ 'r' _ 'r' _ ';', 6, 0x21ce, 1) -NAMED_CHARACTER_REFERENCE(1450, 'n' _ 'h' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x21ae, 1) -NAMED_CHARACTER_REFERENCE(1451, 'n' _ 'h' _ 'p' _ 'a' _ 'r' _ ';', 6, 0x2af2, 1) -NAMED_CHARACTER_REFERENCE(1452, 'n' _ 'i' _ ';', 3, 0x220b, 1) -NAMED_CHARACTER_REFERENCE(1453, 'n' _ 'i' _ 's' _ ';', 4, 0x22fc, 1) -NAMED_CHARACTER_REFERENCE(1454, 'n' _ 'i' _ 's' _ 'd' _ ';', 5, 0x22fa, 1) -NAMED_CHARACTER_REFERENCE(1455, 'n' _ 'i' _ 'v' _ ';', 4, 0x220b, 1) -NAMED_CHARACTER_REFERENCE(1456, 'n' _ 'j' _ 'c' _ 'y' _ ';', 5, 0x045a, 1) -NAMED_CHARACTER_REFERENCE(1457, 'n' _ 'l' _ 'A' _ 'r' _ 'r' _ ';', 6, 0x21cd, 1) -NAMED_CHARACTER_REFERENCE(1458, 'n' _ 'l' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x219a, 1) -NAMED_CHARACTER_REFERENCE(1459, 'n' _ 'l' _ 'd' _ 'r' _ ';', 5, 0x2025, 1) -NAMED_CHARACTER_REFERENCE(1460, 'n' _ 'l' _ 'e' _ ';', 4, 0x2270, 1) -NAMED_CHARACTER_REFERENCE(1461, 'n' _ 'l' _ 'e' _ 'f' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 11, 0x219a, 1) -NAMED_CHARACTER_REFERENCE(1462, 'n' _ 'l' _ 'e' _ 'f' _ 't' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 16, 0x21ae, 1) -NAMED_CHARACTER_REFERENCE(1463, 'n' _ 'l' _ 'e' _ 'q' _ ';', 5, 0x2270, 1) -NAMED_CHARACTER_REFERENCE(1464, 'n' _ 'l' _ 'e' _ 's' _ 's' _ ';', 6, 0x226e, 1) -NAMED_CHARACTER_REFERENCE(1465, 'n' _ 'l' _ 's' _ 'i' _ 'm' _ ';', 6, 0x2274, 1) -NAMED_CHARACTER_REFERENCE(1466, 'n' _ 'l' _ 't' _ ';', 4, 0x226e, 1) -NAMED_CHARACTER_REFERENCE(1467, 'n' _ 'l' _ 't' _ 'r' _ 'i' _ ';', 6, 0x22ea, 1) -NAMED_CHARACTER_REFERENCE(1468, 'n' _ 'l' _ 't' _ 'r' _ 'i' _ 'e' _ ';', 7, 0x22ec, 1) -NAMED_CHARACTER_REFERENCE(1469, 'n' _ 'm' _ 'i' _ 'd' _ ';', 5, 0x2224, 1) -NAMED_CHARACTER_REFERENCE(1470, 'n' _ 'o' _ 'p' _ 'f' _ ';', 5, 0xd835 _ 0xdd5f, 2) -NAMED_CHARACTER_REFERENCE(1471, 'n' _ 'o' _ 't', 3, 0x00ac, 1) -NAMED_CHARACTER_REFERENCE(1472, 'n' _ 'o' _ 't' _ ';', 4, 0x00ac, 1) -NAMED_CHARACTER_REFERENCE(1473, 'n' _ 'o' _ 't' _ 'i' _ 'n' _ ';', 6, 0x2209, 1) -NAMED_CHARACTER_REFERENCE(1474, 'n' _ 'o' _ 't' _ 'i' _ 'n' _ 'v' _ 'a' _ ';', 8, 0x2209, 1) -NAMED_CHARACTER_REFERENCE(1475, 'n' _ 'o' _ 't' _ 'i' _ 'n' _ 'v' _ 'b' _ ';', 8, 0x22f7, 1) -NAMED_CHARACTER_REFERENCE(1476, 'n' _ 'o' _ 't' _ 'i' _ 'n' _ 'v' _ 'c' _ ';', 8, 0x22f6, 1) -NAMED_CHARACTER_REFERENCE(1477, 'n' _ 'o' _ 't' _ 'n' _ 'i' _ ';', 6, 0x220c, 1) -NAMED_CHARACTER_REFERENCE(1478, 'n' _ 'o' _ 't' _ 'n' _ 'i' _ 'v' _ 'a' _ ';', 8, 0x220c, 1) -NAMED_CHARACTER_REFERENCE(1479, 'n' _ 'o' _ 't' _ 'n' _ 'i' _ 'v' _ 'b' _ ';', 8, 0x22fe, 1) -NAMED_CHARACTER_REFERENCE(1480, 'n' _ 'o' _ 't' _ 'n' _ 'i' _ 'v' _ 'c' _ ';', 8, 0x22fd, 1) -NAMED_CHARACTER_REFERENCE(1481, 'n' _ 'p' _ 'a' _ 'r' _ ';', 5, 0x2226, 1) -NAMED_CHARACTER_REFERENCE(1482, 'n' _ 'p' _ 'a' _ 'r' _ 'a' _ 'l' _ 'l' _ 'e' _ 'l' _ ';', 10, 0x2226, 1) -NAMED_CHARACTER_REFERENCE(1483, 'n' _ 'p' _ 'o' _ 'l' _ 'i' _ 'n' _ 't' _ ';', 8, 0x2a14, 1) -NAMED_CHARACTER_REFERENCE(1484, 'n' _ 'p' _ 'r' _ ';', 4, 0x2280, 1) -NAMED_CHARACTER_REFERENCE(1485, 'n' _ 'p' _ 'r' _ 'c' _ 'u' _ 'e' _ ';', 7, 0x22e0, 1) -NAMED_CHARACTER_REFERENCE(1486, 'n' _ 'p' _ 'r' _ 'e' _ 'c' _ ';', 6, 0x2280, 1) -NAMED_CHARACTER_REFERENCE(1487, 'n' _ 'r' _ 'A' _ 'r' _ 'r' _ ';', 6, 0x21cf, 1) -NAMED_CHARACTER_REFERENCE(1488, 'n' _ 'r' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x219b, 1) -NAMED_CHARACTER_REFERENCE(1489, 'n' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 12, 0x219b, 1) -NAMED_CHARACTER_REFERENCE(1490, 'n' _ 'r' _ 't' _ 'r' _ 'i' _ ';', 6, 0x22eb, 1) -NAMED_CHARACTER_REFERENCE(1491, 'n' _ 'r' _ 't' _ 'r' _ 'i' _ 'e' _ ';', 7, 0x22ed, 1) -NAMED_CHARACTER_REFERENCE(1492, 'n' _ 's' _ 'c' _ ';', 4, 0x2281, 1) -NAMED_CHARACTER_REFERENCE(1493, 'n' _ 's' _ 'c' _ 'c' _ 'u' _ 'e' _ ';', 7, 0x22e1, 1) -NAMED_CHARACTER_REFERENCE(1494, 'n' _ 's' _ 'c' _ 'r' _ ';', 5, 0xd835 _ 0xdcc3, 2) -NAMED_CHARACTER_REFERENCE(1495, 'n' _ 's' _ 'h' _ 'o' _ 'r' _ 't' _ 'm' _ 'i' _ 'd' _ ';', 10, 0x2224, 1) -NAMED_CHARACTER_REFERENCE(1496, 'n' _ 's' _ 'h' _ 'o' _ 'r' _ 't' _ 'p' _ 'a' _ 'r' _ 'a' _ 'l' _ 'l' _ 'e' _ 'l' _ ';', 15, 0x2226, 1) -NAMED_CHARACTER_REFERENCE(1497, 'n' _ 's' _ 'i' _ 'm' _ ';', 5, 0x2241, 1) -NAMED_CHARACTER_REFERENCE(1498, 'n' _ 's' _ 'i' _ 'm' _ 'e' _ ';', 6, 0x2244, 1) -NAMED_CHARACTER_REFERENCE(1499, 'n' _ 's' _ 'i' _ 'm' _ 'e' _ 'q' _ ';', 7, 0x2244, 1) -NAMED_CHARACTER_REFERENCE(1500, 'n' _ 's' _ 'm' _ 'i' _ 'd' _ ';', 6, 0x2224, 1) -NAMED_CHARACTER_REFERENCE(1501, 'n' _ 's' _ 'p' _ 'a' _ 'r' _ ';', 6, 0x2226, 1) -NAMED_CHARACTER_REFERENCE(1502, 'n' _ 's' _ 'q' _ 's' _ 'u' _ 'b' _ 'e' _ ';', 8, 0x22e2, 1) -NAMED_CHARACTER_REFERENCE(1503, 'n' _ 's' _ 'q' _ 's' _ 'u' _ 'p' _ 'e' _ ';', 8, 0x22e3, 1) -NAMED_CHARACTER_REFERENCE(1504, 'n' _ 's' _ 'u' _ 'b' _ ';', 5, 0x2284, 1) -NAMED_CHARACTER_REFERENCE(1505, 'n' _ 's' _ 'u' _ 'b' _ 'e' _ ';', 6, 0x2288, 1) -NAMED_CHARACTER_REFERENCE(1506, 'n' _ 's' _ 'u' _ 'b' _ 's' _ 'e' _ 't' _ 'e' _ 'q' _ ';', 10, 0x2288, 1) -NAMED_CHARACTER_REFERENCE(1507, 'n' _ 's' _ 'u' _ 'c' _ 'c' _ ';', 6, 0x2281, 1) -NAMED_CHARACTER_REFERENCE(1508, 'n' _ 's' _ 'u' _ 'p' _ ';', 5, 0x2285, 1) -NAMED_CHARACTER_REFERENCE(1509, 'n' _ 's' _ 'u' _ 'p' _ 'e' _ ';', 6, 0x2289, 1) -NAMED_CHARACTER_REFERENCE(1510, 'n' _ 's' _ 'u' _ 'p' _ 's' _ 'e' _ 't' _ 'e' _ 'q' _ ';', 10, 0x2289, 1) -NAMED_CHARACTER_REFERENCE(1511, 'n' _ 't' _ 'g' _ 'l' _ ';', 5, 0x2279, 1) -NAMED_CHARACTER_REFERENCE(1512, 'n' _ 't' _ 'i' _ 'l' _ 'd' _ 'e', 6, 0x00f1, 1) -NAMED_CHARACTER_REFERENCE(1513, 'n' _ 't' _ 'i' _ 'l' _ 'd' _ 'e' _ ';', 7, 0x00f1, 1) -NAMED_CHARACTER_REFERENCE(1514, 'n' _ 't' _ 'l' _ 'g' _ ';', 5, 0x2278, 1) -NAMED_CHARACTER_REFERENCE(1515, 'n' _ 't' _ 'r' _ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ 'l' _ 'e' _ 'f' _ 't' _ ';', 14, 0x22ea, 1) -NAMED_CHARACTER_REFERENCE(1516, 'n' _ 't' _ 'r' _ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ 'l' _ 'e' _ 'f' _ 't' _ 'e' _ 'q' _ ';', 16, 0x22ec, 1) -NAMED_CHARACTER_REFERENCE(1517, 'n' _ 't' _ 'r' _ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ ';', 15, 0x22eb, 1) -NAMED_CHARACTER_REFERENCE(1518, 'n' _ 't' _ 'r' _ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ 'e' _ 'q' _ ';', 17, 0x22ed, 1) -NAMED_CHARACTER_REFERENCE(1519, 'n' _ 'u' _ ';', 3, 0x03bd, 1) -NAMED_CHARACTER_REFERENCE(1520, 'n' _ 'u' _ 'm' _ ';', 4, 0x0023, 1) -NAMED_CHARACTER_REFERENCE(1521, 'n' _ 'u' _ 'm' _ 'e' _ 'r' _ 'o' _ ';', 7, 0x2116, 1) -NAMED_CHARACTER_REFERENCE(1522, 'n' _ 'u' _ 'm' _ 's' _ 'p' _ ';', 6, 0x2007, 1) -NAMED_CHARACTER_REFERENCE(1523, 'n' _ 'v' _ 'D' _ 'a' _ 's' _ 'h' _ ';', 7, 0x22ad, 1) -NAMED_CHARACTER_REFERENCE(1524, 'n' _ 'v' _ 'H' _ 'a' _ 'r' _ 'r' _ ';', 7, 0x2904, 1) -NAMED_CHARACTER_REFERENCE(1525, 'n' _ 'v' _ 'd' _ 'a' _ 's' _ 'h' _ ';', 7, 0x22ac, 1) -NAMED_CHARACTER_REFERENCE(1526, 'n' _ 'v' _ 'i' _ 'n' _ 'f' _ 'i' _ 'n' _ ';', 8, 0x29de, 1) -NAMED_CHARACTER_REFERENCE(1527, 'n' _ 'v' _ 'l' _ 'A' _ 'r' _ 'r' _ ';', 7, 0x2902, 1) -NAMED_CHARACTER_REFERENCE(1528, 'n' _ 'v' _ 'r' _ 'A' _ 'r' _ 'r' _ ';', 7, 0x2903, 1) -NAMED_CHARACTER_REFERENCE(1529, 'n' _ 'w' _ 'A' _ 'r' _ 'r' _ ';', 6, 0x21d6, 1) -NAMED_CHARACTER_REFERENCE(1530, 'n' _ 'w' _ 'a' _ 'r' _ 'h' _ 'k' _ ';', 7, 0x2923, 1) -NAMED_CHARACTER_REFERENCE(1531, 'n' _ 'w' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x2196, 1) -NAMED_CHARACTER_REFERENCE(1532, 'n' _ 'w' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 8, 0x2196, 1) -NAMED_CHARACTER_REFERENCE(1533, 'n' _ 'w' _ 'n' _ 'e' _ 'a' _ 'r' _ ';', 7, 0x2927, 1) -NAMED_CHARACTER_REFERENCE(1534, 'o' _ 'S' _ ';', 3, 0x24c8, 1) -NAMED_CHARACTER_REFERENCE(1535, 'o' _ 'a' _ 'c' _ 'u' _ 't' _ 'e', 6, 0x00f3, 1) -NAMED_CHARACTER_REFERENCE(1536, 'o' _ 'a' _ 'c' _ 'u' _ 't' _ 'e' _ ';', 7, 0x00f3, 1) -NAMED_CHARACTER_REFERENCE(1537, 'o' _ 'a' _ 's' _ 't' _ ';', 5, 0x229b, 1) -NAMED_CHARACTER_REFERENCE(1538, 'o' _ 'c' _ 'i' _ 'r' _ ';', 5, 0x229a, 1) -NAMED_CHARACTER_REFERENCE(1539, 'o' _ 'c' _ 'i' _ 'r' _ 'c', 5, 0x00f4, 1) -NAMED_CHARACTER_REFERENCE(1540, 'o' _ 'c' _ 'i' _ 'r' _ 'c' _ ';', 6, 0x00f4, 1) -NAMED_CHARACTER_REFERENCE(1541, 'o' _ 'c' _ 'y' _ ';', 4, 0x043e, 1) -NAMED_CHARACTER_REFERENCE(1542, 'o' _ 'd' _ 'a' _ 's' _ 'h' _ ';', 6, 0x229d, 1) -NAMED_CHARACTER_REFERENCE(1543, 'o' _ 'd' _ 'b' _ 'l' _ 'a' _ 'c' _ ';', 7, 0x0151, 1) -NAMED_CHARACTER_REFERENCE(1544, 'o' _ 'd' _ 'i' _ 'v' _ ';', 5, 0x2a38, 1) -NAMED_CHARACTER_REFERENCE(1545, 'o' _ 'd' _ 'o' _ 't' _ ';', 5, 0x2299, 1) -NAMED_CHARACTER_REFERENCE(1546, 'o' _ 'd' _ 's' _ 'o' _ 'l' _ 'd' _ ';', 7, 0x29bc, 1) -NAMED_CHARACTER_REFERENCE(1547, 'o' _ 'e' _ 'l' _ 'i' _ 'g' _ ';', 6, 0x0153, 1) -NAMED_CHARACTER_REFERENCE(1548, 'o' _ 'f' _ 'c' _ 'i' _ 'r' _ ';', 6, 0x29bf, 1) -NAMED_CHARACTER_REFERENCE(1549, 'o' _ 'f' _ 'r' _ ';', 4, 0xd835 _ 0xdd2c, 2) -NAMED_CHARACTER_REFERENCE(1550, 'o' _ 'g' _ 'o' _ 'n' _ ';', 5, 0x02db, 1) -NAMED_CHARACTER_REFERENCE(1551, 'o' _ 'g' _ 'r' _ 'a' _ 'v' _ 'e', 6, 0x00f2, 1) -NAMED_CHARACTER_REFERENCE(1552, 'o' _ 'g' _ 'r' _ 'a' _ 'v' _ 'e' _ ';', 7, 0x00f2, 1) -NAMED_CHARACTER_REFERENCE(1553, 'o' _ 'g' _ 't' _ ';', 4, 0x29c1, 1) -NAMED_CHARACTER_REFERENCE(1554, 'o' _ 'h' _ 'b' _ 'a' _ 'r' _ ';', 6, 0x29b5, 1) -NAMED_CHARACTER_REFERENCE(1555, 'o' _ 'h' _ 'm' _ ';', 4, 0x2126, 1) -NAMED_CHARACTER_REFERENCE(1556, 'o' _ 'i' _ 'n' _ 't' _ ';', 5, 0x222e, 1) -NAMED_CHARACTER_REFERENCE(1557, 'o' _ 'l' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x21ba, 1) -NAMED_CHARACTER_REFERENCE(1558, 'o' _ 'l' _ 'c' _ 'i' _ 'r' _ ';', 6, 0x29be, 1) -NAMED_CHARACTER_REFERENCE(1559, 'o' _ 'l' _ 'c' _ 'r' _ 'o' _ 's' _ 's' _ ';', 8, 0x29bb, 1) -NAMED_CHARACTER_REFERENCE(1560, 'o' _ 'l' _ 'i' _ 'n' _ 'e' _ ';', 6, 0x203e, 1) -NAMED_CHARACTER_REFERENCE(1561, 'o' _ 'l' _ 't' _ ';', 4, 0x29c0, 1) -NAMED_CHARACTER_REFERENCE(1562, 'o' _ 'm' _ 'a' _ 'c' _ 'r' _ ';', 6, 0x014d, 1) -NAMED_CHARACTER_REFERENCE(1563, 'o' _ 'm' _ 'e' _ 'g' _ 'a' _ ';', 6, 0x03c9, 1) -NAMED_CHARACTER_REFERENCE(1564, 'o' _ 'm' _ 'i' _ 'c' _ 'r' _ 'o' _ 'n' _ ';', 8, 0x03bf, 1) -NAMED_CHARACTER_REFERENCE(1565, 'o' _ 'm' _ 'i' _ 'd' _ ';', 5, 0x29b6, 1) -NAMED_CHARACTER_REFERENCE(1566, 'o' _ 'm' _ 'i' _ 'n' _ 'u' _ 's' _ ';', 7, 0x2296, 1) -NAMED_CHARACTER_REFERENCE(1567, 'o' _ 'o' _ 'p' _ 'f' _ ';', 5, 0xd835 _ 0xdd60, 2) -NAMED_CHARACTER_REFERENCE(1568, 'o' _ 'p' _ 'a' _ 'r' _ ';', 5, 0x29b7, 1) -NAMED_CHARACTER_REFERENCE(1569, 'o' _ 'p' _ 'e' _ 'r' _ 'p' _ ';', 6, 0x29b9, 1) -NAMED_CHARACTER_REFERENCE(1570, 'o' _ 'p' _ 'l' _ 'u' _ 's' _ ';', 6, 0x2295, 1) -NAMED_CHARACTER_REFERENCE(1571, 'o' _ 'r' _ ';', 3, 0x2228, 1) -NAMED_CHARACTER_REFERENCE(1572, 'o' _ 'r' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x21bb, 1) -NAMED_CHARACTER_REFERENCE(1573, 'o' _ 'r' _ 'd' _ ';', 4, 0x2a5d, 1) -NAMED_CHARACTER_REFERENCE(1574, 'o' _ 'r' _ 'd' _ 'e' _ 'r' _ ';', 6, 0x2134, 1) -NAMED_CHARACTER_REFERENCE(1575, 'o' _ 'r' _ 'd' _ 'e' _ 'r' _ 'o' _ 'f' _ ';', 8, 0x2134, 1) -NAMED_CHARACTER_REFERENCE(1576, 'o' _ 'r' _ 'd' _ 'f', 4, 0x00aa, 1) -NAMED_CHARACTER_REFERENCE(1577, 'o' _ 'r' _ 'd' _ 'f' _ ';', 5, 0x00aa, 1) -NAMED_CHARACTER_REFERENCE(1578, 'o' _ 'r' _ 'd' _ 'm', 4, 0x00ba, 1) -NAMED_CHARACTER_REFERENCE(1579, 'o' _ 'r' _ 'd' _ 'm' _ ';', 5, 0x00ba, 1) -NAMED_CHARACTER_REFERENCE(1580, 'o' _ 'r' _ 'i' _ 'g' _ 'o' _ 'f' _ ';', 7, 0x22b6, 1) -NAMED_CHARACTER_REFERENCE(1581, 'o' _ 'r' _ 'o' _ 'r' _ ';', 5, 0x2a56, 1) -NAMED_CHARACTER_REFERENCE(1582, 'o' _ 'r' _ 's' _ 'l' _ 'o' _ 'p' _ 'e' _ ';', 8, 0x2a57, 1) -NAMED_CHARACTER_REFERENCE(1583, 'o' _ 'r' _ 'v' _ ';', 4, 0x2a5b, 1) -NAMED_CHARACTER_REFERENCE(1584, 'o' _ 's' _ 'c' _ 'r' _ ';', 5, 0x2134, 1) -NAMED_CHARACTER_REFERENCE(1585, 'o' _ 's' _ 'l' _ 'a' _ 's' _ 'h', 6, 0x00f8, 1) -NAMED_CHARACTER_REFERENCE(1586, 'o' _ 's' _ 'l' _ 'a' _ 's' _ 'h' _ ';', 7, 0x00f8, 1) -NAMED_CHARACTER_REFERENCE(1587, 'o' _ 's' _ 'o' _ 'l' _ ';', 5, 0x2298, 1) -NAMED_CHARACTER_REFERENCE(1588, 'o' _ 't' _ 'i' _ 'l' _ 'd' _ 'e', 6, 0x00f5, 1) -NAMED_CHARACTER_REFERENCE(1589, 'o' _ 't' _ 'i' _ 'l' _ 'd' _ 'e' _ ';', 7, 0x00f5, 1) -NAMED_CHARACTER_REFERENCE(1590, 'o' _ 't' _ 'i' _ 'm' _ 'e' _ 's' _ ';', 7, 0x2297, 1) -NAMED_CHARACTER_REFERENCE(1591, 'o' _ 't' _ 'i' _ 'm' _ 'e' _ 's' _ 'a' _ 's' _ ';', 9, 0x2a36, 1) -NAMED_CHARACTER_REFERENCE(1592, 'o' _ 'u' _ 'm' _ 'l', 4, 0x00f6, 1) -NAMED_CHARACTER_REFERENCE(1593, 'o' _ 'u' _ 'm' _ 'l' _ ';', 5, 0x00f6, 1) -NAMED_CHARACTER_REFERENCE(1594, 'o' _ 'v' _ 'b' _ 'a' _ 'r' _ ';', 6, 0x233d, 1) -NAMED_CHARACTER_REFERENCE(1595, 'p' _ 'a' _ 'r' _ ';', 4, 0x2225, 1) -NAMED_CHARACTER_REFERENCE(1596, 'p' _ 'a' _ 'r' _ 'a', 4, 0x00b6, 1) -NAMED_CHARACTER_REFERENCE(1597, 'p' _ 'a' _ 'r' _ 'a' _ ';', 5, 0x00b6, 1) -NAMED_CHARACTER_REFERENCE(1598, 'p' _ 'a' _ 'r' _ 'a' _ 'l' _ 'l' _ 'e' _ 'l' _ ';', 9, 0x2225, 1) -NAMED_CHARACTER_REFERENCE(1599, 'p' _ 'a' _ 'r' _ 's' _ 'i' _ 'm' _ ';', 7, 0x2af3, 1) -NAMED_CHARACTER_REFERENCE(1600, 'p' _ 'a' _ 'r' _ 's' _ 'l' _ ';', 6, 0x2afd, 1) -NAMED_CHARACTER_REFERENCE(1601, 'p' _ 'a' _ 'r' _ 't' _ ';', 5, 0x2202, 1) -NAMED_CHARACTER_REFERENCE(1602, 'p' _ 'c' _ 'y' _ ';', 4, 0x043f, 1) -NAMED_CHARACTER_REFERENCE(1603, 'p' _ 'e' _ 'r' _ 'c' _ 'n' _ 't' _ ';', 7, 0x0025, 1) -NAMED_CHARACTER_REFERENCE(1604, 'p' _ 'e' _ 'r' _ 'i' _ 'o' _ 'd' _ ';', 7, 0x002e, 1) -NAMED_CHARACTER_REFERENCE(1605, 'p' _ 'e' _ 'r' _ 'm' _ 'i' _ 'l' _ ';', 7, 0x2030, 1) -NAMED_CHARACTER_REFERENCE(1606, 'p' _ 'e' _ 'r' _ 'p' _ ';', 5, 0x22a5, 1) -NAMED_CHARACTER_REFERENCE(1607, 'p' _ 'e' _ 'r' _ 't' _ 'e' _ 'n' _ 'k' _ ';', 8, 0x2031, 1) -NAMED_CHARACTER_REFERENCE(1608, 'p' _ 'f' _ 'r' _ ';', 4, 0xd835 _ 0xdd2d, 2) -NAMED_CHARACTER_REFERENCE(1609, 'p' _ 'h' _ 'i' _ ';', 4, 0x03c6, 1) -NAMED_CHARACTER_REFERENCE(1610, 'p' _ 'h' _ 'i' _ 'v' _ ';', 5, 0x03c6, 1) -NAMED_CHARACTER_REFERENCE(1611, 'p' _ 'h' _ 'm' _ 'm' _ 'a' _ 't' _ ';', 7, 0x2133, 1) -NAMED_CHARACTER_REFERENCE(1612, 'p' _ 'h' _ 'o' _ 'n' _ 'e' _ ';', 6, 0x260e, 1) -NAMED_CHARACTER_REFERENCE(1613, 'p' _ 'i' _ ';', 3, 0x03c0, 1) -NAMED_CHARACTER_REFERENCE(1614, 'p' _ 'i' _ 't' _ 'c' _ 'h' _ 'f' _ 'o' _ 'r' _ 'k' _ ';', 10, 0x22d4, 1) -NAMED_CHARACTER_REFERENCE(1615, 'p' _ 'i' _ 'v' _ ';', 4, 0x03d6, 1) -NAMED_CHARACTER_REFERENCE(1616, 'p' _ 'l' _ 'a' _ 'n' _ 'c' _ 'k' _ ';', 7, 0x210f, 1) -NAMED_CHARACTER_REFERENCE(1617, 'p' _ 'l' _ 'a' _ 'n' _ 'c' _ 'k' _ 'h' _ ';', 8, 0x210e, 1) -NAMED_CHARACTER_REFERENCE(1618, 'p' _ 'l' _ 'a' _ 'n' _ 'k' _ 'v' _ ';', 7, 0x210f, 1) -NAMED_CHARACTER_REFERENCE(1619, 'p' _ 'l' _ 'u' _ 's' _ ';', 5, 0x002b, 1) -NAMED_CHARACTER_REFERENCE(1620, 'p' _ 'l' _ 'u' _ 's' _ 'a' _ 'c' _ 'i' _ 'r' _ ';', 9, 0x2a23, 1) -NAMED_CHARACTER_REFERENCE(1621, 'p' _ 'l' _ 'u' _ 's' _ 'b' _ ';', 6, 0x229e, 1) -NAMED_CHARACTER_REFERENCE(1622, 'p' _ 'l' _ 'u' _ 's' _ 'c' _ 'i' _ 'r' _ ';', 8, 0x2a22, 1) -NAMED_CHARACTER_REFERENCE(1623, 'p' _ 'l' _ 'u' _ 's' _ 'd' _ 'o' _ ';', 7, 0x2214, 1) -NAMED_CHARACTER_REFERENCE(1624, 'p' _ 'l' _ 'u' _ 's' _ 'd' _ 'u' _ ';', 7, 0x2a25, 1) -NAMED_CHARACTER_REFERENCE(1625, 'p' _ 'l' _ 'u' _ 's' _ 'e' _ ';', 6, 0x2a72, 1) -NAMED_CHARACTER_REFERENCE(1626, 'p' _ 'l' _ 'u' _ 's' _ 'm' _ 'n', 6, 0x00b1, 1) -NAMED_CHARACTER_REFERENCE(1627, 'p' _ 'l' _ 'u' _ 's' _ 'm' _ 'n' _ ';', 7, 0x00b1, 1) -NAMED_CHARACTER_REFERENCE(1628, 'p' _ 'l' _ 'u' _ 's' _ 's' _ 'i' _ 'm' _ ';', 8, 0x2a26, 1) -NAMED_CHARACTER_REFERENCE(1629, 'p' _ 'l' _ 'u' _ 's' _ 't' _ 'w' _ 'o' _ ';', 8, 0x2a27, 1) -NAMED_CHARACTER_REFERENCE(1630, 'p' _ 'm' _ ';', 3, 0x00b1, 1) -NAMED_CHARACTER_REFERENCE(1631, 'p' _ 'o' _ 'i' _ 'n' _ 't' _ 'i' _ 'n' _ 't' _ ';', 9, 0x2a15, 1) -NAMED_CHARACTER_REFERENCE(1632, 'p' _ 'o' _ 'p' _ 'f' _ ';', 5, 0xd835 _ 0xdd61, 2) -NAMED_CHARACTER_REFERENCE(1633, 'p' _ 'o' _ 'u' _ 'n' _ 'd', 5, 0x00a3, 1) -NAMED_CHARACTER_REFERENCE(1634, 'p' _ 'o' _ 'u' _ 'n' _ 'd' _ ';', 6, 0x00a3, 1) -NAMED_CHARACTER_REFERENCE(1635, 'p' _ 'r' _ ';', 3, 0x227a, 1) -NAMED_CHARACTER_REFERENCE(1636, 'p' _ 'r' _ 'E' _ ';', 4, 0x2ab3, 1) -NAMED_CHARACTER_REFERENCE(1637, 'p' _ 'r' _ 'a' _ 'p' _ ';', 5, 0x2ab7, 1) -NAMED_CHARACTER_REFERENCE(1638, 'p' _ 'r' _ 'c' _ 'u' _ 'e' _ ';', 6, 0x227c, 1) -NAMED_CHARACTER_REFERENCE(1639, 'p' _ 'r' _ 'e' _ ';', 4, 0x2aaf, 1) -NAMED_CHARACTER_REFERENCE(1640, 'p' _ 'r' _ 'e' _ 'c' _ ';', 5, 0x227a, 1) -NAMED_CHARACTER_REFERENCE(1641, 'p' _ 'r' _ 'e' _ 'c' _ 'a' _ 'p' _ 'p' _ 'r' _ 'o' _ 'x' _ ';', 11, 0x2ab7, 1) -NAMED_CHARACTER_REFERENCE(1642, 'p' _ 'r' _ 'e' _ 'c' _ 'c' _ 'u' _ 'r' _ 'l' _ 'y' _ 'e' _ 'q' _ ';', 12, 0x227c, 1) -NAMED_CHARACTER_REFERENCE(1643, 'p' _ 'r' _ 'e' _ 'c' _ 'e' _ 'q' _ ';', 7, 0x2aaf, 1) -NAMED_CHARACTER_REFERENCE(1644, 'p' _ 'r' _ 'e' _ 'c' _ 'n' _ 'a' _ 'p' _ 'p' _ 'r' _ 'o' _ 'x' _ ';', 12, 0x2ab9, 1) -NAMED_CHARACTER_REFERENCE(1645, 'p' _ 'r' _ 'e' _ 'c' _ 'n' _ 'e' _ 'q' _ 'q' _ ';', 9, 0x2ab5, 1) -NAMED_CHARACTER_REFERENCE(1646, 'p' _ 'r' _ 'e' _ 'c' _ 'n' _ 's' _ 'i' _ 'm' _ ';', 9, 0x22e8, 1) -NAMED_CHARACTER_REFERENCE(1647, 'p' _ 'r' _ 'e' _ 'c' _ 's' _ 'i' _ 'm' _ ';', 8, 0x227e, 1) -NAMED_CHARACTER_REFERENCE(1648, 'p' _ 'r' _ 'i' _ 'm' _ 'e' _ ';', 6, 0x2032, 1) -NAMED_CHARACTER_REFERENCE(1649, 'p' _ 'r' _ 'i' _ 'm' _ 'e' _ 's' _ ';', 7, 0x2119, 1) -NAMED_CHARACTER_REFERENCE(1650, 'p' _ 'r' _ 'n' _ 'E' _ ';', 5, 0x2ab5, 1) -NAMED_CHARACTER_REFERENCE(1651, 'p' _ 'r' _ 'n' _ 'a' _ 'p' _ ';', 6, 0x2ab9, 1) -NAMED_CHARACTER_REFERENCE(1652, 'p' _ 'r' _ 'n' _ 's' _ 'i' _ 'm' _ ';', 7, 0x22e8, 1) -NAMED_CHARACTER_REFERENCE(1653, 'p' _ 'r' _ 'o' _ 'd' _ ';', 5, 0x220f, 1) -NAMED_CHARACTER_REFERENCE(1654, 'p' _ 'r' _ 'o' _ 'f' _ 'a' _ 'l' _ 'a' _ 'r' _ ';', 9, 0x232e, 1) -NAMED_CHARACTER_REFERENCE(1655, 'p' _ 'r' _ 'o' _ 'f' _ 'l' _ 'i' _ 'n' _ 'e' _ ';', 9, 0x2312, 1) -NAMED_CHARACTER_REFERENCE(1656, 'p' _ 'r' _ 'o' _ 'f' _ 's' _ 'u' _ 'r' _ 'f' _ ';', 9, 0x2313, 1) -NAMED_CHARACTER_REFERENCE(1657, 'p' _ 'r' _ 'o' _ 'p' _ ';', 5, 0x221d, 1) -NAMED_CHARACTER_REFERENCE(1658, 'p' _ 'r' _ 'o' _ 'p' _ 't' _ 'o' _ ';', 7, 0x221d, 1) -NAMED_CHARACTER_REFERENCE(1659, 'p' _ 'r' _ 's' _ 'i' _ 'm' _ ';', 6, 0x227e, 1) -NAMED_CHARACTER_REFERENCE(1660, 'p' _ 'r' _ 'u' _ 'r' _ 'e' _ 'l' _ ';', 7, 0x22b0, 1) -NAMED_CHARACTER_REFERENCE(1661, 'p' _ 's' _ 'c' _ 'r' _ ';', 5, 0xd835 _ 0xdcc5, 2) -NAMED_CHARACTER_REFERENCE(1662, 'p' _ 's' _ 'i' _ ';', 4, 0x03c8, 1) -NAMED_CHARACTER_REFERENCE(1663, 'p' _ 'u' _ 'n' _ 'c' _ 's' _ 'p' _ ';', 7, 0x2008, 1) -NAMED_CHARACTER_REFERENCE(1664, 'q' _ 'f' _ 'r' _ ';', 4, 0xd835 _ 0xdd2e, 2) -NAMED_CHARACTER_REFERENCE(1665, 'q' _ 'i' _ 'n' _ 't' _ ';', 5, 0x2a0c, 1) -NAMED_CHARACTER_REFERENCE(1666, 'q' _ 'o' _ 'p' _ 'f' _ ';', 5, 0xd835 _ 0xdd62, 2) -NAMED_CHARACTER_REFERENCE(1667, 'q' _ 'p' _ 'r' _ 'i' _ 'm' _ 'e' _ ';', 7, 0x2057, 1) -NAMED_CHARACTER_REFERENCE(1668, 'q' _ 's' _ 'c' _ 'r' _ ';', 5, 0xd835 _ 0xdcc6, 2) -NAMED_CHARACTER_REFERENCE(1669, 'q' _ 'u' _ 'a' _ 't' _ 'e' _ 'r' _ 'n' _ 'i' _ 'o' _ 'n' _ 's' _ ';', 12, 0x210d, 1) -NAMED_CHARACTER_REFERENCE(1670, 'q' _ 'u' _ 'a' _ 't' _ 'i' _ 'n' _ 't' _ ';', 8, 0x2a16, 1) -NAMED_CHARACTER_REFERENCE(1671, 'q' _ 'u' _ 'e' _ 's' _ 't' _ ';', 6, 0x003f, 1) -NAMED_CHARACTER_REFERENCE(1672, 'q' _ 'u' _ 'e' _ 's' _ 't' _ 'e' _ 'q' _ ';', 8, 0x225f, 1) -NAMED_CHARACTER_REFERENCE(1673, 'q' _ 'u' _ 'o' _ 't', 4, 0x0022, 1) -NAMED_CHARACTER_REFERENCE(1674, 'q' _ 'u' _ 'o' _ 't' _ ';', 5, 0x0022, 1) -NAMED_CHARACTER_REFERENCE(1675, 'r' _ 'A' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x21db, 1) -NAMED_CHARACTER_REFERENCE(1676, 'r' _ 'A' _ 'r' _ 'r' _ ';', 5, 0x21d2, 1) -NAMED_CHARACTER_REFERENCE(1677, 'r' _ 'A' _ 't' _ 'a' _ 'i' _ 'l' _ ';', 7, 0x291c, 1) -NAMED_CHARACTER_REFERENCE(1678, 'r' _ 'B' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x290f, 1) -NAMED_CHARACTER_REFERENCE(1679, 'r' _ 'H' _ 'a' _ 'r' _ ';', 5, 0x2964, 1) -NAMED_CHARACTER_REFERENCE(1680, 'r' _ 'a' _ 'c' _ 'e' _ ';', 5, 0x29da, 1) +NAMED_CHARACTER_REFERENCE(789, 'b' _ 's' _ 'o' _ 'l' _ 'h' _ 's' _ 'u' _ 'b' _ ';', 9, 0x27c8, 1) +NAMED_CHARACTER_REFERENCE(790, 'b' _ 'u' _ 'l' _ 'l' _ ';', 5, 0x2022, 1) +NAMED_CHARACTER_REFERENCE(791, 'b' _ 'u' _ 'l' _ 'l' _ 'e' _ 't' _ ';', 7, 0x2022, 1) +NAMED_CHARACTER_REFERENCE(792, 'b' _ 'u' _ 'm' _ 'p' _ ';', 5, 0x224e, 1) +NAMED_CHARACTER_REFERENCE(793, 'b' _ 'u' _ 'm' _ 'p' _ 'E' _ ';', 6, 0x2aae, 1) +NAMED_CHARACTER_REFERENCE(794, 'b' _ 'u' _ 'm' _ 'p' _ 'e' _ ';', 6, 0x224f, 1) +NAMED_CHARACTER_REFERENCE(795, 'b' _ 'u' _ 'm' _ 'p' _ 'e' _ 'q' _ ';', 7, 0x224f, 1) +NAMED_CHARACTER_REFERENCE(796, 'c' _ 'a' _ 'c' _ 'u' _ 't' _ 'e' _ ';', 7, 0x0107, 1) +NAMED_CHARACTER_REFERENCE(797, 'c' _ 'a' _ 'p' _ ';', 4, 0x2229, 1) +NAMED_CHARACTER_REFERENCE(798, 'c' _ 'a' _ 'p' _ 'a' _ 'n' _ 'd' _ ';', 7, 0x2a44, 1) +NAMED_CHARACTER_REFERENCE(799, 'c' _ 'a' _ 'p' _ 'b' _ 'r' _ 'c' _ 'u' _ 'p' _ ';', 9, 0x2a49, 1) +NAMED_CHARACTER_REFERENCE(800, 'c' _ 'a' _ 'p' _ 'c' _ 'a' _ 'p' _ ';', 7, 0x2a4b, 1) +NAMED_CHARACTER_REFERENCE(801, 'c' _ 'a' _ 'p' _ 'c' _ 'u' _ 'p' _ ';', 7, 0x2a47, 1) +NAMED_CHARACTER_REFERENCE(802, 'c' _ 'a' _ 'p' _ 'd' _ 'o' _ 't' _ ';', 7, 0x2a40, 1) +NAMED_CHARACTER_REFERENCE(803, 'c' _ 'a' _ 'r' _ 'e' _ 't' _ ';', 6, 0x2041, 1) +NAMED_CHARACTER_REFERENCE(804, 'c' _ 'a' _ 'r' _ 'o' _ 'n' _ ';', 6, 0x02c7, 1) +NAMED_CHARACTER_REFERENCE(805, 'c' _ 'c' _ 'a' _ 'p' _ 's' _ ';', 6, 0x2a4d, 1) +NAMED_CHARACTER_REFERENCE(806, 'c' _ 'c' _ 'a' _ 'r' _ 'o' _ 'n' _ ';', 7, 0x010d, 1) +NAMED_CHARACTER_REFERENCE(807, 'c' _ 'c' _ 'e' _ 'd' _ 'i' _ 'l', 6, 0x00e7, 1) +NAMED_CHARACTER_REFERENCE(808, 'c' _ 'c' _ 'e' _ 'd' _ 'i' _ 'l' _ ';', 7, 0x00e7, 1) +NAMED_CHARACTER_REFERENCE(809, 'c' _ 'c' _ 'i' _ 'r' _ 'c' _ ';', 6, 0x0109, 1) +NAMED_CHARACTER_REFERENCE(810, 'c' _ 'c' _ 'u' _ 'p' _ 's' _ ';', 6, 0x2a4c, 1) +NAMED_CHARACTER_REFERENCE(811, 'c' _ 'c' _ 'u' _ 'p' _ 's' _ 's' _ 'm' _ ';', 8, 0x2a50, 1) +NAMED_CHARACTER_REFERENCE(812, 'c' _ 'd' _ 'o' _ 't' _ ';', 5, 0x010b, 1) +NAMED_CHARACTER_REFERENCE(813, 'c' _ 'e' _ 'd' _ 'i' _ 'l', 5, 0x00b8, 1) +NAMED_CHARACTER_REFERENCE(814, 'c' _ 'e' _ 'd' _ 'i' _ 'l' _ ';', 6, 0x00b8, 1) +NAMED_CHARACTER_REFERENCE(815, 'c' _ 'e' _ 'm' _ 'p' _ 't' _ 'y' _ 'v' _ ';', 8, 0x29b2, 1) +NAMED_CHARACTER_REFERENCE(816, 'c' _ 'e' _ 'n' _ 't', 4, 0x00a2, 1) +NAMED_CHARACTER_REFERENCE(817, 'c' _ 'e' _ 'n' _ 't' _ ';', 5, 0x00a2, 1) +NAMED_CHARACTER_REFERENCE(818, 'c' _ 'e' _ 'n' _ 't' _ 'e' _ 'r' _ 'd' _ 'o' _ 't' _ ';', 10, 0x00b7, 1) +NAMED_CHARACTER_REFERENCE(819, 'c' _ 'f' _ 'r' _ ';', 4, 0xd835 _ 0xdd20, 2) +NAMED_CHARACTER_REFERENCE(820, 'c' _ 'h' _ 'c' _ 'y' _ ';', 5, 0x0447, 1) +NAMED_CHARACTER_REFERENCE(821, 'c' _ 'h' _ 'e' _ 'c' _ 'k' _ ';', 6, 0x2713, 1) +NAMED_CHARACTER_REFERENCE(822, 'c' _ 'h' _ 'e' _ 'c' _ 'k' _ 'm' _ 'a' _ 'r' _ 'k' _ ';', 10, 0x2713, 1) +NAMED_CHARACTER_REFERENCE(823, 'c' _ 'h' _ 'i' _ ';', 4, 0x03c7, 1) +NAMED_CHARACTER_REFERENCE(824, 'c' _ 'i' _ 'r' _ ';', 4, 0x25cb, 1) +NAMED_CHARACTER_REFERENCE(825, 'c' _ 'i' _ 'r' _ 'E' _ ';', 5, 0x29c3, 1) +NAMED_CHARACTER_REFERENCE(826, 'c' _ 'i' _ 'r' _ 'c' _ ';', 5, 0x02c6, 1) +NAMED_CHARACTER_REFERENCE(827, 'c' _ 'i' _ 'r' _ 'c' _ 'e' _ 'q' _ ';', 7, 0x2257, 1) +NAMED_CHARACTER_REFERENCE(828, 'c' _ 'i' _ 'r' _ 'c' _ 'l' _ 'e' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ 'l' _ 'e' _ 'f' _ 't' _ ';', 16, 0x21ba, 1) +NAMED_CHARACTER_REFERENCE(829, 'c' _ 'i' _ 'r' _ 'c' _ 'l' _ 'e' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ ';', 17, 0x21bb, 1) +NAMED_CHARACTER_REFERENCE(830, 'c' _ 'i' _ 'r' _ 'c' _ 'l' _ 'e' _ 'd' _ 'R' _ ';', 9, 0x00ae, 1) +NAMED_CHARACTER_REFERENCE(831, 'c' _ 'i' _ 'r' _ 'c' _ 'l' _ 'e' _ 'd' _ 'S' _ ';', 9, 0x24c8, 1) +NAMED_CHARACTER_REFERENCE(832, 'c' _ 'i' _ 'r' _ 'c' _ 'l' _ 'e' _ 'd' _ 'a' _ 's' _ 't' _ ';', 11, 0x229b, 1) +NAMED_CHARACTER_REFERENCE(833, 'c' _ 'i' _ 'r' _ 'c' _ 'l' _ 'e' _ 'd' _ 'c' _ 'i' _ 'r' _ 'c' _ ';', 12, 0x229a, 1) +NAMED_CHARACTER_REFERENCE(834, 'c' _ 'i' _ 'r' _ 'c' _ 'l' _ 'e' _ 'd' _ 'd' _ 'a' _ 's' _ 'h' _ ';', 12, 0x229d, 1) +NAMED_CHARACTER_REFERENCE(835, 'c' _ 'i' _ 'r' _ 'e' _ ';', 5, 0x2257, 1) +NAMED_CHARACTER_REFERENCE(836, 'c' _ 'i' _ 'r' _ 'f' _ 'n' _ 'i' _ 'n' _ 't' _ ';', 9, 0x2a10, 1) +NAMED_CHARACTER_REFERENCE(837, 'c' _ 'i' _ 'r' _ 'm' _ 'i' _ 'd' _ ';', 7, 0x2aef, 1) +NAMED_CHARACTER_REFERENCE(838, 'c' _ 'i' _ 'r' _ 's' _ 'c' _ 'i' _ 'r' _ ';', 8, 0x29c2, 1) +NAMED_CHARACTER_REFERENCE(839, 'c' _ 'l' _ 'u' _ 'b' _ 's' _ ';', 6, 0x2663, 1) +NAMED_CHARACTER_REFERENCE(840, 'c' _ 'l' _ 'u' _ 'b' _ 's' _ 'u' _ 'i' _ 't' _ ';', 9, 0x2663, 1) +NAMED_CHARACTER_REFERENCE(841, 'c' _ 'o' _ 'l' _ 'o' _ 'n' _ ';', 6, 0x003a, 1) +NAMED_CHARACTER_REFERENCE(842, 'c' _ 'o' _ 'l' _ 'o' _ 'n' _ 'e' _ ';', 7, 0x2254, 1) +NAMED_CHARACTER_REFERENCE(843, 'c' _ 'o' _ 'l' _ 'o' _ 'n' _ 'e' _ 'q' _ ';', 8, 0x2254, 1) +NAMED_CHARACTER_REFERENCE(844, 'c' _ 'o' _ 'm' _ 'm' _ 'a' _ ';', 6, 0x002c, 1) +NAMED_CHARACTER_REFERENCE(845, 'c' _ 'o' _ 'm' _ 'm' _ 'a' _ 't' _ ';', 7, 0x0040, 1) +NAMED_CHARACTER_REFERENCE(846, 'c' _ 'o' _ 'm' _ 'p' _ ';', 5, 0x2201, 1) +NAMED_CHARACTER_REFERENCE(847, 'c' _ 'o' _ 'm' _ 'p' _ 'f' _ 'n' _ ';', 7, 0x2218, 1) +NAMED_CHARACTER_REFERENCE(848, 'c' _ 'o' _ 'm' _ 'p' _ 'l' _ 'e' _ 'm' _ 'e' _ 'n' _ 't' _ ';', 11, 0x2201, 1) +NAMED_CHARACTER_REFERENCE(849, 'c' _ 'o' _ 'm' _ 'p' _ 'l' _ 'e' _ 'x' _ 'e' _ 's' _ ';', 10, 0x2102, 1) +NAMED_CHARACTER_REFERENCE(850, 'c' _ 'o' _ 'n' _ 'g' _ ';', 5, 0x2245, 1) +NAMED_CHARACTER_REFERENCE(851, 'c' _ 'o' _ 'n' _ 'g' _ 'd' _ 'o' _ 't' _ ';', 8, 0x2a6d, 1) +NAMED_CHARACTER_REFERENCE(852, 'c' _ 'o' _ 'n' _ 'i' _ 'n' _ 't' _ ';', 7, 0x222e, 1) +NAMED_CHARACTER_REFERENCE(853, 'c' _ 'o' _ 'p' _ 'f' _ ';', 5, 0xd835 _ 0xdd54, 2) +NAMED_CHARACTER_REFERENCE(854, 'c' _ 'o' _ 'p' _ 'r' _ 'o' _ 'd' _ ';', 7, 0x2210, 1) +NAMED_CHARACTER_REFERENCE(855, 'c' _ 'o' _ 'p' _ 'y', 4, 0x00a9, 1) +NAMED_CHARACTER_REFERENCE(856, 'c' _ 'o' _ 'p' _ 'y' _ ';', 5, 0x00a9, 1) +NAMED_CHARACTER_REFERENCE(857, 'c' _ 'o' _ 'p' _ 'y' _ 's' _ 'r' _ ';', 7, 0x2117, 1) +NAMED_CHARACTER_REFERENCE(858, 'c' _ 'r' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x21b5, 1) +NAMED_CHARACTER_REFERENCE(859, 'c' _ 'r' _ 'o' _ 's' _ 's' _ ';', 6, 0x2717, 1) +NAMED_CHARACTER_REFERENCE(860, 'c' _ 's' _ 'c' _ 'r' _ ';', 5, 0xd835 _ 0xdcb8, 2) +NAMED_CHARACTER_REFERENCE(861, 'c' _ 's' _ 'u' _ 'b' _ ';', 5, 0x2acf, 1) +NAMED_CHARACTER_REFERENCE(862, 'c' _ 's' _ 'u' _ 'b' _ 'e' _ ';', 6, 0x2ad1, 1) +NAMED_CHARACTER_REFERENCE(863, 'c' _ 's' _ 'u' _ 'p' _ ';', 5, 0x2ad0, 1) +NAMED_CHARACTER_REFERENCE(864, 'c' _ 's' _ 'u' _ 'p' _ 'e' _ ';', 6, 0x2ad2, 1) +NAMED_CHARACTER_REFERENCE(865, 'c' _ 't' _ 'd' _ 'o' _ 't' _ ';', 6, 0x22ef, 1) +NAMED_CHARACTER_REFERENCE(866, 'c' _ 'u' _ 'd' _ 'a' _ 'r' _ 'r' _ 'l' _ ';', 8, 0x2938, 1) +NAMED_CHARACTER_REFERENCE(867, 'c' _ 'u' _ 'd' _ 'a' _ 'r' _ 'r' _ 'r' _ ';', 8, 0x2935, 1) +NAMED_CHARACTER_REFERENCE(868, 'c' _ 'u' _ 'e' _ 'p' _ 'r' _ ';', 6, 0x22de, 1) +NAMED_CHARACTER_REFERENCE(869, 'c' _ 'u' _ 'e' _ 's' _ 'c' _ ';', 6, 0x22df, 1) +NAMED_CHARACTER_REFERENCE(870, 'c' _ 'u' _ 'l' _ 'a' _ 'r' _ 'r' _ ';', 7, 0x21b6, 1) +NAMED_CHARACTER_REFERENCE(871, 'c' _ 'u' _ 'l' _ 'a' _ 'r' _ 'r' _ 'p' _ ';', 8, 0x293d, 1) +NAMED_CHARACTER_REFERENCE(872, 'c' _ 'u' _ 'p' _ ';', 4, 0x222a, 1) +NAMED_CHARACTER_REFERENCE(873, 'c' _ 'u' _ 'p' _ 'b' _ 'r' _ 'c' _ 'a' _ 'p' _ ';', 9, 0x2a48, 1) +NAMED_CHARACTER_REFERENCE(874, 'c' _ 'u' _ 'p' _ 'c' _ 'a' _ 'p' _ ';', 7, 0x2a46, 1) +NAMED_CHARACTER_REFERENCE(875, 'c' _ 'u' _ 'p' _ 'c' _ 'u' _ 'p' _ ';', 7, 0x2a4a, 1) +NAMED_CHARACTER_REFERENCE(876, 'c' _ 'u' _ 'p' _ 'd' _ 'o' _ 't' _ ';', 7, 0x228d, 1) +NAMED_CHARACTER_REFERENCE(877, 'c' _ 'u' _ 'p' _ 'o' _ 'r' _ ';', 6, 0x2a45, 1) +NAMED_CHARACTER_REFERENCE(878, 'c' _ 'u' _ 'r' _ 'a' _ 'r' _ 'r' _ ';', 7, 0x21b7, 1) +NAMED_CHARACTER_REFERENCE(879, 'c' _ 'u' _ 'r' _ 'a' _ 'r' _ 'r' _ 'm' _ ';', 8, 0x293c, 1) +NAMED_CHARACTER_REFERENCE(880, 'c' _ 'u' _ 'r' _ 'l' _ 'y' _ 'e' _ 'q' _ 'p' _ 'r' _ 'e' _ 'c' _ ';', 12, 0x22de, 1) +NAMED_CHARACTER_REFERENCE(881, 'c' _ 'u' _ 'r' _ 'l' _ 'y' _ 'e' _ 'q' _ 's' _ 'u' _ 'c' _ 'c' _ ';', 12, 0x22df, 1) +NAMED_CHARACTER_REFERENCE(882, 'c' _ 'u' _ 'r' _ 'l' _ 'y' _ 'v' _ 'e' _ 'e' _ ';', 9, 0x22ce, 1) +NAMED_CHARACTER_REFERENCE(883, 'c' _ 'u' _ 'r' _ 'l' _ 'y' _ 'w' _ 'e' _ 'd' _ 'g' _ 'e' _ ';', 11, 0x22cf, 1) +NAMED_CHARACTER_REFERENCE(884, 'c' _ 'u' _ 'r' _ 'r' _ 'e' _ 'n', 6, 0x00a4, 1) +NAMED_CHARACTER_REFERENCE(885, 'c' _ 'u' _ 'r' _ 'r' _ 'e' _ 'n' _ ';', 7, 0x00a4, 1) +NAMED_CHARACTER_REFERENCE(886, 'c' _ 'u' _ 'r' _ 'v' _ 'e' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ 'l' _ 'e' _ 'f' _ 't' _ ';', 15, 0x21b6, 1) +NAMED_CHARACTER_REFERENCE(887, 'c' _ 'u' _ 'r' _ 'v' _ 'e' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ ';', 16, 0x21b7, 1) +NAMED_CHARACTER_REFERENCE(888, 'c' _ 'u' _ 'v' _ 'e' _ 'e' _ ';', 6, 0x22ce, 1) +NAMED_CHARACTER_REFERENCE(889, 'c' _ 'u' _ 'w' _ 'e' _ 'd' _ ';', 6, 0x22cf, 1) +NAMED_CHARACTER_REFERENCE(890, 'c' _ 'w' _ 'c' _ 'o' _ 'n' _ 'i' _ 'n' _ 't' _ ';', 9, 0x2232, 1) +NAMED_CHARACTER_REFERENCE(891, 'c' _ 'w' _ 'i' _ 'n' _ 't' _ ';', 6, 0x2231, 1) +NAMED_CHARACTER_REFERENCE(892, 'c' _ 'y' _ 'l' _ 'c' _ 't' _ 'y' _ ';', 7, 0x232d, 1) +NAMED_CHARACTER_REFERENCE(893, 'd' _ 'A' _ 'r' _ 'r' _ ';', 5, 0x21d3, 1) +NAMED_CHARACTER_REFERENCE(894, 'd' _ 'H' _ 'a' _ 'r' _ ';', 5, 0x2965, 1) +NAMED_CHARACTER_REFERENCE(895, 'd' _ 'a' _ 'g' _ 'g' _ 'e' _ 'r' _ ';', 7, 0x2020, 1) +NAMED_CHARACTER_REFERENCE(896, 'd' _ 'a' _ 'l' _ 'e' _ 't' _ 'h' _ ';', 7, 0x2138, 1) +NAMED_CHARACTER_REFERENCE(897, 'd' _ 'a' _ 'r' _ 'r' _ ';', 5, 0x2193, 1) +NAMED_CHARACTER_REFERENCE(898, 'd' _ 'a' _ 's' _ 'h' _ ';', 5, 0x2010, 1) +NAMED_CHARACTER_REFERENCE(899, 'd' _ 'a' _ 's' _ 'h' _ 'v' _ ';', 6, 0x22a3, 1) +NAMED_CHARACTER_REFERENCE(900, 'd' _ 'b' _ 'k' _ 'a' _ 'r' _ 'o' _ 'w' _ ';', 8, 0x290f, 1) +NAMED_CHARACTER_REFERENCE(901, 'd' _ 'b' _ 'l' _ 'a' _ 'c' _ ';', 6, 0x02dd, 1) +NAMED_CHARACTER_REFERENCE(902, 'd' _ 'c' _ 'a' _ 'r' _ 'o' _ 'n' _ ';', 7, 0x010f, 1) +NAMED_CHARACTER_REFERENCE(903, 'd' _ 'c' _ 'y' _ ';', 4, 0x0434, 1) +NAMED_CHARACTER_REFERENCE(904, 'd' _ 'd' _ ';', 3, 0x2146, 1) +NAMED_CHARACTER_REFERENCE(905, 'd' _ 'd' _ 'a' _ 'g' _ 'g' _ 'e' _ 'r' _ ';', 8, 0x2021, 1) +NAMED_CHARACTER_REFERENCE(906, 'd' _ 'd' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x21ca, 1) +NAMED_CHARACTER_REFERENCE(907, 'd' _ 'd' _ 'o' _ 't' _ 's' _ 'e' _ 'q' _ ';', 8, 0x2a77, 1) +NAMED_CHARACTER_REFERENCE(908, 'd' _ 'e' _ 'g', 3, 0x00b0, 1) +NAMED_CHARACTER_REFERENCE(909, 'd' _ 'e' _ 'g' _ ';', 4, 0x00b0, 1) +NAMED_CHARACTER_REFERENCE(910, 'd' _ 'e' _ 'l' _ 't' _ 'a' _ ';', 6, 0x03b4, 1) +NAMED_CHARACTER_REFERENCE(911, 'd' _ 'e' _ 'm' _ 'p' _ 't' _ 'y' _ 'v' _ ';', 8, 0x29b1, 1) +NAMED_CHARACTER_REFERENCE(912, 'd' _ 'f' _ 'i' _ 's' _ 'h' _ 't' _ ';', 7, 0x297f, 1) +NAMED_CHARACTER_REFERENCE(913, 'd' _ 'f' _ 'r' _ ';', 4, 0xd835 _ 0xdd21, 2) +NAMED_CHARACTER_REFERENCE(914, 'd' _ 'h' _ 'a' _ 'r' _ 'l' _ ';', 6, 0x21c3, 1) +NAMED_CHARACTER_REFERENCE(915, 'd' _ 'h' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x21c2, 1) +NAMED_CHARACTER_REFERENCE(916, 'd' _ 'i' _ 'a' _ 'm' _ ';', 5, 0x22c4, 1) +NAMED_CHARACTER_REFERENCE(917, 'd' _ 'i' _ 'a' _ 'm' _ 'o' _ 'n' _ 'd' _ ';', 8, 0x22c4, 1) +NAMED_CHARACTER_REFERENCE(918, 'd' _ 'i' _ 'a' _ 'm' _ 'o' _ 'n' _ 'd' _ 's' _ 'u' _ 'i' _ 't' _ ';', 12, 0x2666, 1) +NAMED_CHARACTER_REFERENCE(919, 'd' _ 'i' _ 'a' _ 'm' _ 's' _ ';', 6, 0x2666, 1) +NAMED_CHARACTER_REFERENCE(920, 'd' _ 'i' _ 'e' _ ';', 4, 0x00a8, 1) +NAMED_CHARACTER_REFERENCE(921, 'd' _ 'i' _ 'g' _ 'a' _ 'm' _ 'm' _ 'a' _ ';', 8, 0x03dd, 1) +NAMED_CHARACTER_REFERENCE(922, 'd' _ 'i' _ 's' _ 'i' _ 'n' _ ';', 6, 0x22f2, 1) +NAMED_CHARACTER_REFERENCE(923, 'd' _ 'i' _ 'v' _ ';', 4, 0x00f7, 1) +NAMED_CHARACTER_REFERENCE(924, 'd' _ 'i' _ 'v' _ 'i' _ 'd' _ 'e', 6, 0x00f7, 1) +NAMED_CHARACTER_REFERENCE(925, 'd' _ 'i' _ 'v' _ 'i' _ 'd' _ 'e' _ ';', 7, 0x00f7, 1) +NAMED_CHARACTER_REFERENCE(926, 'd' _ 'i' _ 'v' _ 'i' _ 'd' _ 'e' _ 'o' _ 'n' _ 't' _ 'i' _ 'm' _ 'e' _ 's' _ ';', 14, 0x22c7, 1) +NAMED_CHARACTER_REFERENCE(927, 'd' _ 'i' _ 'v' _ 'o' _ 'n' _ 'x' _ ';', 7, 0x22c7, 1) +NAMED_CHARACTER_REFERENCE(928, 'd' _ 'j' _ 'c' _ 'y' _ ';', 5, 0x0452, 1) +NAMED_CHARACTER_REFERENCE(929, 'd' _ 'l' _ 'c' _ 'o' _ 'r' _ 'n' _ ';', 7, 0x231e, 1) +NAMED_CHARACTER_REFERENCE(930, 'd' _ 'l' _ 'c' _ 'r' _ 'o' _ 'p' _ ';', 7, 0x230d, 1) +NAMED_CHARACTER_REFERENCE(931, 'd' _ 'o' _ 'l' _ 'l' _ 'a' _ 'r' _ ';', 7, 0x0024, 1) +NAMED_CHARACTER_REFERENCE(932, 'd' _ 'o' _ 'p' _ 'f' _ ';', 5, 0xd835 _ 0xdd55, 2) +NAMED_CHARACTER_REFERENCE(933, 'd' _ 'o' _ 't' _ ';', 4, 0x02d9, 1) +NAMED_CHARACTER_REFERENCE(934, 'd' _ 'o' _ 't' _ 'e' _ 'q' _ ';', 6, 0x2250, 1) +NAMED_CHARACTER_REFERENCE(935, 'd' _ 'o' _ 't' _ 'e' _ 'q' _ 'd' _ 'o' _ 't' _ ';', 9, 0x2251, 1) +NAMED_CHARACTER_REFERENCE(936, 'd' _ 'o' _ 't' _ 'm' _ 'i' _ 'n' _ 'u' _ 's' _ ';', 9, 0x2238, 1) +NAMED_CHARACTER_REFERENCE(937, 'd' _ 'o' _ 't' _ 'p' _ 'l' _ 'u' _ 's' _ ';', 8, 0x2214, 1) +NAMED_CHARACTER_REFERENCE(938, 'd' _ 'o' _ 't' _ 's' _ 'q' _ 'u' _ 'a' _ 'r' _ 'e' _ ';', 10, 0x22a1, 1) +NAMED_CHARACTER_REFERENCE(939, 'd' _ 'o' _ 'u' _ 'b' _ 'l' _ 'e' _ 'b' _ 'a' _ 'r' _ 'w' _ 'e' _ 'd' _ 'g' _ 'e' _ ';', 15, 0x2306, 1) +NAMED_CHARACTER_REFERENCE(940, 'd' _ 'o' _ 'w' _ 'n' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 10, 0x2193, 1) +NAMED_CHARACTER_REFERENCE(941, 'd' _ 'o' _ 'w' _ 'n' _ 'd' _ 'o' _ 'w' _ 'n' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ 's' _ ';', 15, 0x21ca, 1) +NAMED_CHARACTER_REFERENCE(942, 'd' _ 'o' _ 'w' _ 'n' _ 'h' _ 'a' _ 'r' _ 'p' _ 'o' _ 'o' _ 'n' _ 'l' _ 'e' _ 'f' _ 't' _ ';', 16, 0x21c3, 1) +NAMED_CHARACTER_REFERENCE(943, 'd' _ 'o' _ 'w' _ 'n' _ 'h' _ 'a' _ 'r' _ 'p' _ 'o' _ 'o' _ 'n' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ ';', 17, 0x21c2, 1) +NAMED_CHARACTER_REFERENCE(944, 'd' _ 'r' _ 'b' _ 'k' _ 'a' _ 'r' _ 'o' _ 'w' _ ';', 9, 0x2910, 1) +NAMED_CHARACTER_REFERENCE(945, 'd' _ 'r' _ 'c' _ 'o' _ 'r' _ 'n' _ ';', 7, 0x231f, 1) +NAMED_CHARACTER_REFERENCE(946, 'd' _ 'r' _ 'c' _ 'r' _ 'o' _ 'p' _ ';', 7, 0x230c, 1) +NAMED_CHARACTER_REFERENCE(947, 'd' _ 's' _ 'c' _ 'r' _ ';', 5, 0xd835 _ 0xdcb9, 2) +NAMED_CHARACTER_REFERENCE(948, 'd' _ 's' _ 'c' _ 'y' _ ';', 5, 0x0455, 1) +NAMED_CHARACTER_REFERENCE(949, 'd' _ 's' _ 'o' _ 'l' _ ';', 5, 0x29f6, 1) +NAMED_CHARACTER_REFERENCE(950, 'd' _ 's' _ 't' _ 'r' _ 'o' _ 'k' _ ';', 7, 0x0111, 1) +NAMED_CHARACTER_REFERENCE(951, 'd' _ 't' _ 'd' _ 'o' _ 't' _ ';', 6, 0x22f1, 1) +NAMED_CHARACTER_REFERENCE(952, 'd' _ 't' _ 'r' _ 'i' _ ';', 5, 0x25bf, 1) +NAMED_CHARACTER_REFERENCE(953, 'd' _ 't' _ 'r' _ 'i' _ 'f' _ ';', 6, 0x25be, 1) +NAMED_CHARACTER_REFERENCE(954, 'd' _ 'u' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x21f5, 1) +NAMED_CHARACTER_REFERENCE(955, 'd' _ 'u' _ 'h' _ 'a' _ 'r' _ ';', 6, 0x296f, 1) +NAMED_CHARACTER_REFERENCE(956, 'd' _ 'w' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ ';', 8, 0x29a6, 1) +NAMED_CHARACTER_REFERENCE(957, 'd' _ 'z' _ 'c' _ 'y' _ ';', 5, 0x045f, 1) +NAMED_CHARACTER_REFERENCE(958, 'd' _ 'z' _ 'i' _ 'g' _ 'r' _ 'a' _ 'r' _ 'r' _ ';', 9, 0x27ff, 1) +NAMED_CHARACTER_REFERENCE(959, 'e' _ 'D' _ 'D' _ 'o' _ 't' _ ';', 6, 0x2a77, 1) +NAMED_CHARACTER_REFERENCE(960, 'e' _ 'D' _ 'o' _ 't' _ ';', 5, 0x2251, 1) +NAMED_CHARACTER_REFERENCE(961, 'e' _ 'a' _ 'c' _ 'u' _ 't' _ 'e', 6, 0x00e9, 1) +NAMED_CHARACTER_REFERENCE(962, 'e' _ 'a' _ 'c' _ 'u' _ 't' _ 'e' _ ';', 7, 0x00e9, 1) +NAMED_CHARACTER_REFERENCE(963, 'e' _ 'a' _ 's' _ 't' _ 'e' _ 'r' _ ';', 7, 0x2a6e, 1) +NAMED_CHARACTER_REFERENCE(964, 'e' _ 'c' _ 'a' _ 'r' _ 'o' _ 'n' _ ';', 7, 0x011b, 1) +NAMED_CHARACTER_REFERENCE(965, 'e' _ 'c' _ 'i' _ 'r' _ ';', 5, 0x2256, 1) +NAMED_CHARACTER_REFERENCE(966, 'e' _ 'c' _ 'i' _ 'r' _ 'c', 5, 0x00ea, 1) +NAMED_CHARACTER_REFERENCE(967, 'e' _ 'c' _ 'i' _ 'r' _ 'c' _ ';', 6, 0x00ea, 1) +NAMED_CHARACTER_REFERENCE(968, 'e' _ 'c' _ 'o' _ 'l' _ 'o' _ 'n' _ ';', 7, 0x2255, 1) +NAMED_CHARACTER_REFERENCE(969, 'e' _ 'c' _ 'y' _ ';', 4, 0x044d, 1) +NAMED_CHARACTER_REFERENCE(970, 'e' _ 'd' _ 'o' _ 't' _ ';', 5, 0x0117, 1) +NAMED_CHARACTER_REFERENCE(971, 'e' _ 'e' _ ';', 3, 0x2147, 1) +NAMED_CHARACTER_REFERENCE(972, 'e' _ 'f' _ 'D' _ 'o' _ 't' _ ';', 6, 0x2252, 1) +NAMED_CHARACTER_REFERENCE(973, 'e' _ 'f' _ 'r' _ ';', 4, 0xd835 _ 0xdd22, 2) +NAMED_CHARACTER_REFERENCE(974, 'e' _ 'g' _ ';', 3, 0x2a9a, 1) +NAMED_CHARACTER_REFERENCE(975, 'e' _ 'g' _ 'r' _ 'a' _ 'v' _ 'e', 6, 0x00e8, 1) +NAMED_CHARACTER_REFERENCE(976, 'e' _ 'g' _ 'r' _ 'a' _ 'v' _ 'e' _ ';', 7, 0x00e8, 1) +NAMED_CHARACTER_REFERENCE(977, 'e' _ 'g' _ 's' _ ';', 4, 0x2a96, 1) +NAMED_CHARACTER_REFERENCE(978, 'e' _ 'g' _ 's' _ 'd' _ 'o' _ 't' _ ';', 7, 0x2a98, 1) +NAMED_CHARACTER_REFERENCE(979, 'e' _ 'l' _ ';', 3, 0x2a99, 1) +NAMED_CHARACTER_REFERENCE(980, 'e' _ 'l' _ 'i' _ 'n' _ 't' _ 'e' _ 'r' _ 's' _ ';', 9, 0x23e7, 1) +NAMED_CHARACTER_REFERENCE(981, 'e' _ 'l' _ 'l' _ ';', 4, 0x2113, 1) +NAMED_CHARACTER_REFERENCE(982, 'e' _ 'l' _ 's' _ ';', 4, 0x2a95, 1) +NAMED_CHARACTER_REFERENCE(983, 'e' _ 'l' _ 's' _ 'd' _ 'o' _ 't' _ ';', 7, 0x2a97, 1) +NAMED_CHARACTER_REFERENCE(984, 'e' _ 'm' _ 'a' _ 'c' _ 'r' _ ';', 6, 0x0113, 1) +NAMED_CHARACTER_REFERENCE(985, 'e' _ 'm' _ 'p' _ 't' _ 'y' _ ';', 6, 0x2205, 1) +NAMED_CHARACTER_REFERENCE(986, 'e' _ 'm' _ 'p' _ 't' _ 'y' _ 's' _ 'e' _ 't' _ ';', 9, 0x2205, 1) +NAMED_CHARACTER_REFERENCE(987, 'e' _ 'm' _ 'p' _ 't' _ 'y' _ 'v' _ ';', 7, 0x2205, 1) +NAMED_CHARACTER_REFERENCE(988, 'e' _ 'm' _ 's' _ 'p' _ '1' _ '3' _ ';', 7, 0x2004, 1) +NAMED_CHARACTER_REFERENCE(989, 'e' _ 'm' _ 's' _ 'p' _ '1' _ '4' _ ';', 7, 0x2005, 1) +NAMED_CHARACTER_REFERENCE(990, 'e' _ 'm' _ 's' _ 'p' _ ';', 5, 0x2003, 1) +NAMED_CHARACTER_REFERENCE(991, 'e' _ 'n' _ 'g' _ ';', 4, 0x014b, 1) +NAMED_CHARACTER_REFERENCE(992, 'e' _ 'n' _ 's' _ 'p' _ ';', 5, 0x2002, 1) +NAMED_CHARACTER_REFERENCE(993, 'e' _ 'o' _ 'g' _ 'o' _ 'n' _ ';', 6, 0x0119, 1) +NAMED_CHARACTER_REFERENCE(994, 'e' _ 'o' _ 'p' _ 'f' _ ';', 5, 0xd835 _ 0xdd56, 2) +NAMED_CHARACTER_REFERENCE(995, 'e' _ 'p' _ 'a' _ 'r' _ ';', 5, 0x22d5, 1) +NAMED_CHARACTER_REFERENCE(996, 'e' _ 'p' _ 'a' _ 'r' _ 's' _ 'l' _ ';', 7, 0x29e3, 1) +NAMED_CHARACTER_REFERENCE(997, 'e' _ 'p' _ 'l' _ 'u' _ 's' _ ';', 6, 0x2a71, 1) +NAMED_CHARACTER_REFERENCE(998, 'e' _ 'p' _ 's' _ 'i' _ ';', 5, 0x03b5, 1) +NAMED_CHARACTER_REFERENCE(999, 'e' _ 'p' _ 's' _ 'i' _ 'l' _ 'o' _ 'n' _ ';', 8, 0x03b5, 1) +NAMED_CHARACTER_REFERENCE(1000, 'e' _ 'p' _ 's' _ 'i' _ 'v' _ ';', 6, 0x03f5, 1) +NAMED_CHARACTER_REFERENCE(1001, 'e' _ 'q' _ 'c' _ 'i' _ 'r' _ 'c' _ ';', 7, 0x2256, 1) +NAMED_CHARACTER_REFERENCE(1002, 'e' _ 'q' _ 'c' _ 'o' _ 'l' _ 'o' _ 'n' _ ';', 8, 0x2255, 1) +NAMED_CHARACTER_REFERENCE(1003, 'e' _ 'q' _ 's' _ 'i' _ 'm' _ ';', 6, 0x2242, 1) +NAMED_CHARACTER_REFERENCE(1004, 'e' _ 'q' _ 's' _ 'l' _ 'a' _ 'n' _ 't' _ 'g' _ 't' _ 'r' _ ';', 11, 0x2a96, 1) +NAMED_CHARACTER_REFERENCE(1005, 'e' _ 'q' _ 's' _ 'l' _ 'a' _ 'n' _ 't' _ 'l' _ 'e' _ 's' _ 's' _ ';', 12, 0x2a95, 1) +NAMED_CHARACTER_REFERENCE(1006, 'e' _ 'q' _ 'u' _ 'a' _ 'l' _ 's' _ ';', 7, 0x003d, 1) +NAMED_CHARACTER_REFERENCE(1007, 'e' _ 'q' _ 'u' _ 'e' _ 's' _ 't' _ ';', 7, 0x225f, 1) +NAMED_CHARACTER_REFERENCE(1008, 'e' _ 'q' _ 'u' _ 'i' _ 'v' _ ';', 6, 0x2261, 1) +NAMED_CHARACTER_REFERENCE(1009, 'e' _ 'q' _ 'u' _ 'i' _ 'v' _ 'D' _ 'D' _ ';', 8, 0x2a78, 1) +NAMED_CHARACTER_REFERENCE(1010, 'e' _ 'q' _ 'v' _ 'p' _ 'a' _ 'r' _ 's' _ 'l' _ ';', 9, 0x29e5, 1) +NAMED_CHARACTER_REFERENCE(1011, 'e' _ 'r' _ 'D' _ 'o' _ 't' _ ';', 6, 0x2253, 1) +NAMED_CHARACTER_REFERENCE(1012, 'e' _ 'r' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x2971, 1) +NAMED_CHARACTER_REFERENCE(1013, 'e' _ 's' _ 'c' _ 'r' _ ';', 5, 0x212f, 1) +NAMED_CHARACTER_REFERENCE(1014, 'e' _ 's' _ 'd' _ 'o' _ 't' _ ';', 6, 0x2250, 1) +NAMED_CHARACTER_REFERENCE(1015, 'e' _ 's' _ 'i' _ 'm' _ ';', 5, 0x2242, 1) +NAMED_CHARACTER_REFERENCE(1016, 'e' _ 't' _ 'a' _ ';', 4, 0x03b7, 1) +NAMED_CHARACTER_REFERENCE(1017, 'e' _ 't' _ 'h', 3, 0x00f0, 1) +NAMED_CHARACTER_REFERENCE(1018, 'e' _ 't' _ 'h' _ ';', 4, 0x00f0, 1) +NAMED_CHARACTER_REFERENCE(1019, 'e' _ 'u' _ 'm' _ 'l', 4, 0x00eb, 1) +NAMED_CHARACTER_REFERENCE(1020, 'e' _ 'u' _ 'm' _ 'l' _ ';', 5, 0x00eb, 1) +NAMED_CHARACTER_REFERENCE(1021, 'e' _ 'u' _ 'r' _ 'o' _ ';', 5, 0x20ac, 1) +NAMED_CHARACTER_REFERENCE(1022, 'e' _ 'x' _ 'c' _ 'l' _ ';', 5, 0x0021, 1) +NAMED_CHARACTER_REFERENCE(1023, 'e' _ 'x' _ 'i' _ 's' _ 't' _ ';', 6, 0x2203, 1) +NAMED_CHARACTER_REFERENCE(1024, 'e' _ 'x' _ 'p' _ 'e' _ 'c' _ 't' _ 'a' _ 't' _ 'i' _ 'o' _ 'n' _ ';', 12, 0x2130, 1) +NAMED_CHARACTER_REFERENCE(1025, 'e' _ 'x' _ 'p' _ 'o' _ 'n' _ 'e' _ 'n' _ 't' _ 'i' _ 'a' _ 'l' _ 'e' _ ';', 13, 0x2147, 1) +NAMED_CHARACTER_REFERENCE(1026, 'f' _ 'a' _ 'l' _ 'l' _ 'i' _ 'n' _ 'g' _ 'd' _ 'o' _ 't' _ 's' _ 'e' _ 'q' _ ';', 14, 0x2252, 1) +NAMED_CHARACTER_REFERENCE(1027, 'f' _ 'c' _ 'y' _ ';', 4, 0x0444, 1) +NAMED_CHARACTER_REFERENCE(1028, 'f' _ 'e' _ 'm' _ 'a' _ 'l' _ 'e' _ ';', 7, 0x2640, 1) +NAMED_CHARACTER_REFERENCE(1029, 'f' _ 'f' _ 'i' _ 'l' _ 'i' _ 'g' _ ';', 7, 0xfb03, 1) +NAMED_CHARACTER_REFERENCE(1030, 'f' _ 'f' _ 'l' _ 'i' _ 'g' _ ';', 6, 0xfb00, 1) +NAMED_CHARACTER_REFERENCE(1031, 'f' _ 'f' _ 'l' _ 'l' _ 'i' _ 'g' _ ';', 7, 0xfb04, 1) +NAMED_CHARACTER_REFERENCE(1032, 'f' _ 'f' _ 'r' _ ';', 4, 0xd835 _ 0xdd23, 2) +NAMED_CHARACTER_REFERENCE(1033, 'f' _ 'i' _ 'l' _ 'i' _ 'g' _ ';', 6, 0xfb01, 1) +NAMED_CHARACTER_REFERENCE(1034, 'f' _ 'l' _ 'a' _ 't' _ ';', 5, 0x266d, 1) +NAMED_CHARACTER_REFERENCE(1035, 'f' _ 'l' _ 'l' _ 'i' _ 'g' _ ';', 6, 0xfb02, 1) +NAMED_CHARACTER_REFERENCE(1036, 'f' _ 'l' _ 't' _ 'n' _ 's' _ ';', 6, 0x25b1, 1) +NAMED_CHARACTER_REFERENCE(1037, 'f' _ 'n' _ 'o' _ 'f' _ ';', 5, 0x0192, 1) +NAMED_CHARACTER_REFERENCE(1038, 'f' _ 'o' _ 'p' _ 'f' _ ';', 5, 0xd835 _ 0xdd57, 2) +NAMED_CHARACTER_REFERENCE(1039, 'f' _ 'o' _ 'r' _ 'a' _ 'l' _ 'l' _ ';', 7, 0x2200, 1) +NAMED_CHARACTER_REFERENCE(1040, 'f' _ 'o' _ 'r' _ 'k' _ ';', 5, 0x22d4, 1) +NAMED_CHARACTER_REFERENCE(1041, 'f' _ 'o' _ 'r' _ 'k' _ 'v' _ ';', 6, 0x2ad9, 1) +NAMED_CHARACTER_REFERENCE(1042, 'f' _ 'p' _ 'a' _ 'r' _ 't' _ 'i' _ 'n' _ 't' _ ';', 9, 0x2a0d, 1) +NAMED_CHARACTER_REFERENCE(1043, 'f' _ 'r' _ 'a' _ 'c' _ '1' _ '2', 6, 0x00bd, 1) +NAMED_CHARACTER_REFERENCE(1044, 'f' _ 'r' _ 'a' _ 'c' _ '1' _ '2' _ ';', 7, 0x00bd, 1) +NAMED_CHARACTER_REFERENCE(1045, 'f' _ 'r' _ 'a' _ 'c' _ '1' _ '3' _ ';', 7, 0x2153, 1) +NAMED_CHARACTER_REFERENCE(1046, 'f' _ 'r' _ 'a' _ 'c' _ '1' _ '4', 6, 0x00bc, 1) +NAMED_CHARACTER_REFERENCE(1047, 'f' _ 'r' _ 'a' _ 'c' _ '1' _ '4' _ ';', 7, 0x00bc, 1) +NAMED_CHARACTER_REFERENCE(1048, 'f' _ 'r' _ 'a' _ 'c' _ '1' _ '5' _ ';', 7, 0x2155, 1) +NAMED_CHARACTER_REFERENCE(1049, 'f' _ 'r' _ 'a' _ 'c' _ '1' _ '6' _ ';', 7, 0x2159, 1) +NAMED_CHARACTER_REFERENCE(1050, 'f' _ 'r' _ 'a' _ 'c' _ '1' _ '8' _ ';', 7, 0x215b, 1) +NAMED_CHARACTER_REFERENCE(1051, 'f' _ 'r' _ 'a' _ 'c' _ '2' _ '3' _ ';', 7, 0x2154, 1) +NAMED_CHARACTER_REFERENCE(1052, 'f' _ 'r' _ 'a' _ 'c' _ '2' _ '5' _ ';', 7, 0x2156, 1) +NAMED_CHARACTER_REFERENCE(1053, 'f' _ 'r' _ 'a' _ 'c' _ '3' _ '4', 6, 0x00be, 1) +NAMED_CHARACTER_REFERENCE(1054, 'f' _ 'r' _ 'a' _ 'c' _ '3' _ '4' _ ';', 7, 0x00be, 1) +NAMED_CHARACTER_REFERENCE(1055, 'f' _ 'r' _ 'a' _ 'c' _ '3' _ '5' _ ';', 7, 0x2157, 1) +NAMED_CHARACTER_REFERENCE(1056, 'f' _ 'r' _ 'a' _ 'c' _ '3' _ '8' _ ';', 7, 0x215c, 1) +NAMED_CHARACTER_REFERENCE(1057, 'f' _ 'r' _ 'a' _ 'c' _ '4' _ '5' _ ';', 7, 0x2158, 1) +NAMED_CHARACTER_REFERENCE(1058, 'f' _ 'r' _ 'a' _ 'c' _ '5' _ '6' _ ';', 7, 0x215a, 1) +NAMED_CHARACTER_REFERENCE(1059, 'f' _ 'r' _ 'a' _ 'c' _ '5' _ '8' _ ';', 7, 0x215d, 1) +NAMED_CHARACTER_REFERENCE(1060, 'f' _ 'r' _ 'a' _ 'c' _ '7' _ '8' _ ';', 7, 0x215e, 1) +NAMED_CHARACTER_REFERENCE(1061, 'f' _ 'r' _ 'a' _ 's' _ 'l' _ ';', 6, 0x2044, 1) +NAMED_CHARACTER_REFERENCE(1062, 'f' _ 'r' _ 'o' _ 'w' _ 'n' _ ';', 6, 0x2322, 1) +NAMED_CHARACTER_REFERENCE(1063, 'f' _ 's' _ 'c' _ 'r' _ ';', 5, 0xd835 _ 0xdcbb, 2) +NAMED_CHARACTER_REFERENCE(1064, 'g' _ 'E' _ ';', 3, 0x2267, 1) +NAMED_CHARACTER_REFERENCE(1065, 'g' _ 'E' _ 'l' _ ';', 4, 0x2a8c, 1) +NAMED_CHARACTER_REFERENCE(1066, 'g' _ 'a' _ 'c' _ 'u' _ 't' _ 'e' _ ';', 7, 0x01f5, 1) +NAMED_CHARACTER_REFERENCE(1067, 'g' _ 'a' _ 'm' _ 'm' _ 'a' _ ';', 6, 0x03b3, 1) +NAMED_CHARACTER_REFERENCE(1068, 'g' _ 'a' _ 'm' _ 'm' _ 'a' _ 'd' _ ';', 7, 0x03dd, 1) +NAMED_CHARACTER_REFERENCE(1069, 'g' _ 'a' _ 'p' _ ';', 4, 0x2a86, 1) +NAMED_CHARACTER_REFERENCE(1070, 'g' _ 'b' _ 'r' _ 'e' _ 'v' _ 'e' _ ';', 7, 0x011f, 1) +NAMED_CHARACTER_REFERENCE(1071, 'g' _ 'c' _ 'i' _ 'r' _ 'c' _ ';', 6, 0x011d, 1) +NAMED_CHARACTER_REFERENCE(1072, 'g' _ 'c' _ 'y' _ ';', 4, 0x0433, 1) +NAMED_CHARACTER_REFERENCE(1073, 'g' _ 'd' _ 'o' _ 't' _ ';', 5, 0x0121, 1) +NAMED_CHARACTER_REFERENCE(1074, 'g' _ 'e' _ ';', 3, 0x2265, 1) +NAMED_CHARACTER_REFERENCE(1075, 'g' _ 'e' _ 'l' _ ';', 4, 0x22db, 1) +NAMED_CHARACTER_REFERENCE(1076, 'g' _ 'e' _ 'q' _ ';', 4, 0x2265, 1) +NAMED_CHARACTER_REFERENCE(1077, 'g' _ 'e' _ 'q' _ 'q' _ ';', 5, 0x2267, 1) +NAMED_CHARACTER_REFERENCE(1078, 'g' _ 'e' _ 'q' _ 's' _ 'l' _ 'a' _ 'n' _ 't' _ ';', 9, 0x2a7e, 1) +NAMED_CHARACTER_REFERENCE(1079, 'g' _ 'e' _ 's' _ ';', 4, 0x2a7e, 1) +NAMED_CHARACTER_REFERENCE(1080, 'g' _ 'e' _ 's' _ 'c' _ 'c' _ ';', 6, 0x2aa9, 1) +NAMED_CHARACTER_REFERENCE(1081, 'g' _ 'e' _ 's' _ 'd' _ 'o' _ 't' _ ';', 7, 0x2a80, 1) +NAMED_CHARACTER_REFERENCE(1082, 'g' _ 'e' _ 's' _ 'd' _ 'o' _ 't' _ 'o' _ ';', 8, 0x2a82, 1) +NAMED_CHARACTER_REFERENCE(1083, 'g' _ 'e' _ 's' _ 'd' _ 'o' _ 't' _ 'o' _ 'l' _ ';', 9, 0x2a84, 1) +NAMED_CHARACTER_REFERENCE(1084, 'g' _ 'e' _ 's' _ 'l' _ 'e' _ 's' _ ';', 7, 0x2a94, 1) +NAMED_CHARACTER_REFERENCE(1085, 'g' _ 'f' _ 'r' _ ';', 4, 0xd835 _ 0xdd24, 2) +NAMED_CHARACTER_REFERENCE(1086, 'g' _ 'g' _ ';', 3, 0x226b, 1) +NAMED_CHARACTER_REFERENCE(1087, 'g' _ 'g' _ 'g' _ ';', 4, 0x22d9, 1) +NAMED_CHARACTER_REFERENCE(1088, 'g' _ 'i' _ 'm' _ 'e' _ 'l' _ ';', 6, 0x2137, 1) +NAMED_CHARACTER_REFERENCE(1089, 'g' _ 'j' _ 'c' _ 'y' _ ';', 5, 0x0453, 1) +NAMED_CHARACTER_REFERENCE(1090, 'g' _ 'l' _ ';', 3, 0x2277, 1) +NAMED_CHARACTER_REFERENCE(1091, 'g' _ 'l' _ 'E' _ ';', 4, 0x2a92, 1) +NAMED_CHARACTER_REFERENCE(1092, 'g' _ 'l' _ 'a' _ ';', 4, 0x2aa5, 1) +NAMED_CHARACTER_REFERENCE(1093, 'g' _ 'l' _ 'j' _ ';', 4, 0x2aa4, 1) +NAMED_CHARACTER_REFERENCE(1094, 'g' _ 'n' _ 'E' _ ';', 4, 0x2269, 1) +NAMED_CHARACTER_REFERENCE(1095, 'g' _ 'n' _ 'a' _ 'p' _ ';', 5, 0x2a8a, 1) +NAMED_CHARACTER_REFERENCE(1096, 'g' _ 'n' _ 'a' _ 'p' _ 'p' _ 'r' _ 'o' _ 'x' _ ';', 9, 0x2a8a, 1) +NAMED_CHARACTER_REFERENCE(1097, 'g' _ 'n' _ 'e' _ ';', 4, 0x2a88, 1) +NAMED_CHARACTER_REFERENCE(1098, 'g' _ 'n' _ 'e' _ 'q' _ ';', 5, 0x2a88, 1) +NAMED_CHARACTER_REFERENCE(1099, 'g' _ 'n' _ 'e' _ 'q' _ 'q' _ ';', 6, 0x2269, 1) +NAMED_CHARACTER_REFERENCE(1100, 'g' _ 'n' _ 's' _ 'i' _ 'm' _ ';', 6, 0x22e7, 1) +NAMED_CHARACTER_REFERENCE(1101, 'g' _ 'o' _ 'p' _ 'f' _ ';', 5, 0xd835 _ 0xdd58, 2) +NAMED_CHARACTER_REFERENCE(1102, 'g' _ 'r' _ 'a' _ 'v' _ 'e' _ ';', 6, 0x0060, 1) +NAMED_CHARACTER_REFERENCE(1103, 'g' _ 's' _ 'c' _ 'r' _ ';', 5, 0x210a, 1) +NAMED_CHARACTER_REFERENCE(1104, 'g' _ 's' _ 'i' _ 'm' _ ';', 5, 0x2273, 1) +NAMED_CHARACTER_REFERENCE(1105, 'g' _ 's' _ 'i' _ 'm' _ 'e' _ ';', 6, 0x2a8e, 1) +NAMED_CHARACTER_REFERENCE(1106, 'g' _ 's' _ 'i' _ 'm' _ 'l' _ ';', 6, 0x2a90, 1) +NAMED_CHARACTER_REFERENCE(1107, 'g' _ 't', 2, 0x003e, 1) +NAMED_CHARACTER_REFERENCE(1108, 'g' _ 't' _ ';', 3, 0x003e, 1) +NAMED_CHARACTER_REFERENCE(1109, 'g' _ 't' _ 'c' _ 'c' _ ';', 5, 0x2aa7, 1) +NAMED_CHARACTER_REFERENCE(1110, 'g' _ 't' _ 'c' _ 'i' _ 'r' _ ';', 6, 0x2a7a, 1) +NAMED_CHARACTER_REFERENCE(1111, 'g' _ 't' _ 'd' _ 'o' _ 't' _ ';', 6, 0x22d7, 1) +NAMED_CHARACTER_REFERENCE(1112, 'g' _ 't' _ 'l' _ 'P' _ 'a' _ 'r' _ ';', 7, 0x2995, 1) +NAMED_CHARACTER_REFERENCE(1113, 'g' _ 't' _ 'q' _ 'u' _ 'e' _ 's' _ 't' _ ';', 8, 0x2a7c, 1) +NAMED_CHARACTER_REFERENCE(1114, 'g' _ 't' _ 'r' _ 'a' _ 'p' _ 'p' _ 'r' _ 'o' _ 'x' _ ';', 10, 0x2a86, 1) +NAMED_CHARACTER_REFERENCE(1115, 'g' _ 't' _ 'r' _ 'a' _ 'r' _ 'r' _ ';', 7, 0x2978, 1) +NAMED_CHARACTER_REFERENCE(1116, 'g' _ 't' _ 'r' _ 'd' _ 'o' _ 't' _ ';', 7, 0x22d7, 1) +NAMED_CHARACTER_REFERENCE(1117, 'g' _ 't' _ 'r' _ 'e' _ 'q' _ 'l' _ 'e' _ 's' _ 's' _ ';', 10, 0x22db, 1) +NAMED_CHARACTER_REFERENCE(1118, 'g' _ 't' _ 'r' _ 'e' _ 'q' _ 'q' _ 'l' _ 'e' _ 's' _ 's' _ ';', 11, 0x2a8c, 1) +NAMED_CHARACTER_REFERENCE(1119, 'g' _ 't' _ 'r' _ 'l' _ 'e' _ 's' _ 's' _ ';', 8, 0x2277, 1) +NAMED_CHARACTER_REFERENCE(1120, 'g' _ 't' _ 'r' _ 's' _ 'i' _ 'm' _ ';', 7, 0x2273, 1) +NAMED_CHARACTER_REFERENCE(1121, 'h' _ 'A' _ 'r' _ 'r' _ ';', 5, 0x21d4, 1) +NAMED_CHARACTER_REFERENCE(1122, 'h' _ 'a' _ 'i' _ 'r' _ 's' _ 'p' _ ';', 7, 0x200a, 1) +NAMED_CHARACTER_REFERENCE(1123, 'h' _ 'a' _ 'l' _ 'f' _ ';', 5, 0x00bd, 1) +NAMED_CHARACTER_REFERENCE(1124, 'h' _ 'a' _ 'm' _ 'i' _ 'l' _ 't' _ ';', 7, 0x210b, 1) +NAMED_CHARACTER_REFERENCE(1125, 'h' _ 'a' _ 'r' _ 'd' _ 'c' _ 'y' _ ';', 7, 0x044a, 1) +NAMED_CHARACTER_REFERENCE(1126, 'h' _ 'a' _ 'r' _ 'r' _ ';', 5, 0x2194, 1) +NAMED_CHARACTER_REFERENCE(1127, 'h' _ 'a' _ 'r' _ 'r' _ 'c' _ 'i' _ 'r' _ ';', 8, 0x2948, 1) +NAMED_CHARACTER_REFERENCE(1128, 'h' _ 'a' _ 'r' _ 'r' _ 'w' _ ';', 6, 0x21ad, 1) +NAMED_CHARACTER_REFERENCE(1129, 'h' _ 'b' _ 'a' _ 'r' _ ';', 5, 0x210f, 1) +NAMED_CHARACTER_REFERENCE(1130, 'h' _ 'c' _ 'i' _ 'r' _ 'c' _ ';', 6, 0x0125, 1) +NAMED_CHARACTER_REFERENCE(1131, 'h' _ 'e' _ 'a' _ 'r' _ 't' _ 's' _ ';', 7, 0x2665, 1) +NAMED_CHARACTER_REFERENCE(1132, 'h' _ 'e' _ 'a' _ 'r' _ 't' _ 's' _ 'u' _ 'i' _ 't' _ ';', 10, 0x2665, 1) +NAMED_CHARACTER_REFERENCE(1133, 'h' _ 'e' _ 'l' _ 'l' _ 'i' _ 'p' _ ';', 7, 0x2026, 1) +NAMED_CHARACTER_REFERENCE(1134, 'h' _ 'e' _ 'r' _ 'c' _ 'o' _ 'n' _ ';', 7, 0x22b9, 1) +NAMED_CHARACTER_REFERENCE(1135, 'h' _ 'f' _ 'r' _ ';', 4, 0xd835 _ 0xdd25, 2) +NAMED_CHARACTER_REFERENCE(1136, 'h' _ 'k' _ 's' _ 'e' _ 'a' _ 'r' _ 'o' _ 'w' _ ';', 9, 0x2925, 1) +NAMED_CHARACTER_REFERENCE(1137, 'h' _ 'k' _ 's' _ 'w' _ 'a' _ 'r' _ 'o' _ 'w' _ ';', 9, 0x2926, 1) +NAMED_CHARACTER_REFERENCE(1138, 'h' _ 'o' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x21ff, 1) +NAMED_CHARACTER_REFERENCE(1139, 'h' _ 'o' _ 'm' _ 't' _ 'h' _ 't' _ ';', 7, 0x223b, 1) +NAMED_CHARACTER_REFERENCE(1140, 'h' _ 'o' _ 'o' _ 'k' _ 'l' _ 'e' _ 'f' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 14, 0x21a9, 1) +NAMED_CHARACTER_REFERENCE(1141, 'h' _ 'o' _ 'o' _ 'k' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 15, 0x21aa, 1) +NAMED_CHARACTER_REFERENCE(1142, 'h' _ 'o' _ 'p' _ 'f' _ ';', 5, 0xd835 _ 0xdd59, 2) +NAMED_CHARACTER_REFERENCE(1143, 'h' _ 'o' _ 'r' _ 'b' _ 'a' _ 'r' _ ';', 7, 0x2015, 1) +NAMED_CHARACTER_REFERENCE(1144, 'h' _ 's' _ 'c' _ 'r' _ ';', 5, 0xd835 _ 0xdcbd, 2) +NAMED_CHARACTER_REFERENCE(1145, 'h' _ 's' _ 'l' _ 'a' _ 's' _ 'h' _ ';', 7, 0x210f, 1) +NAMED_CHARACTER_REFERENCE(1146, 'h' _ 's' _ 't' _ 'r' _ 'o' _ 'k' _ ';', 7, 0x0127, 1) +NAMED_CHARACTER_REFERENCE(1147, 'h' _ 'y' _ 'b' _ 'u' _ 'l' _ 'l' _ ';', 7, 0x2043, 1) +NAMED_CHARACTER_REFERENCE(1148, 'h' _ 'y' _ 'p' _ 'h' _ 'e' _ 'n' _ ';', 7, 0x2010, 1) +NAMED_CHARACTER_REFERENCE(1149, 'i' _ 'a' _ 'c' _ 'u' _ 't' _ 'e', 6, 0x00ed, 1) +NAMED_CHARACTER_REFERENCE(1150, 'i' _ 'a' _ 'c' _ 'u' _ 't' _ 'e' _ ';', 7, 0x00ed, 1) +NAMED_CHARACTER_REFERENCE(1151, 'i' _ 'c' _ ';', 3, 0x2063, 1) +NAMED_CHARACTER_REFERENCE(1152, 'i' _ 'c' _ 'i' _ 'r' _ 'c', 5, 0x00ee, 1) +NAMED_CHARACTER_REFERENCE(1153, 'i' _ 'c' _ 'i' _ 'r' _ 'c' _ ';', 6, 0x00ee, 1) +NAMED_CHARACTER_REFERENCE(1154, 'i' _ 'c' _ 'y' _ ';', 4, 0x0438, 1) +NAMED_CHARACTER_REFERENCE(1155, 'i' _ 'e' _ 'c' _ 'y' _ ';', 5, 0x0435, 1) +NAMED_CHARACTER_REFERENCE(1156, 'i' _ 'e' _ 'x' _ 'c' _ 'l', 5, 0x00a1, 1) +NAMED_CHARACTER_REFERENCE(1157, 'i' _ 'e' _ 'x' _ 'c' _ 'l' _ ';', 6, 0x00a1, 1) +NAMED_CHARACTER_REFERENCE(1158, 'i' _ 'f' _ 'f' _ ';', 4, 0x21d4, 1) +NAMED_CHARACTER_REFERENCE(1159, 'i' _ 'f' _ 'r' _ ';', 4, 0xd835 _ 0xdd26, 2) +NAMED_CHARACTER_REFERENCE(1160, 'i' _ 'g' _ 'r' _ 'a' _ 'v' _ 'e', 6, 0x00ec, 1) +NAMED_CHARACTER_REFERENCE(1161, 'i' _ 'g' _ 'r' _ 'a' _ 'v' _ 'e' _ ';', 7, 0x00ec, 1) +NAMED_CHARACTER_REFERENCE(1162, 'i' _ 'i' _ ';', 3, 0x2148, 1) +NAMED_CHARACTER_REFERENCE(1163, 'i' _ 'i' _ 'i' _ 'i' _ 'n' _ 't' _ ';', 7, 0x2a0c, 1) +NAMED_CHARACTER_REFERENCE(1164, 'i' _ 'i' _ 'i' _ 'n' _ 't' _ ';', 6, 0x222d, 1) +NAMED_CHARACTER_REFERENCE(1165, 'i' _ 'i' _ 'n' _ 'f' _ 'i' _ 'n' _ ';', 7, 0x29dc, 1) +NAMED_CHARACTER_REFERENCE(1166, 'i' _ 'i' _ 'o' _ 't' _ 'a' _ ';', 6, 0x2129, 1) +NAMED_CHARACTER_REFERENCE(1167, 'i' _ 'j' _ 'l' _ 'i' _ 'g' _ ';', 6, 0x0133, 1) +NAMED_CHARACTER_REFERENCE(1168, 'i' _ 'm' _ 'a' _ 'c' _ 'r' _ ';', 6, 0x012b, 1) +NAMED_CHARACTER_REFERENCE(1169, 'i' _ 'm' _ 'a' _ 'g' _ 'e' _ ';', 6, 0x2111, 1) +NAMED_CHARACTER_REFERENCE(1170, 'i' _ 'm' _ 'a' _ 'g' _ 'l' _ 'i' _ 'n' _ 'e' _ ';', 9, 0x2110, 1) +NAMED_CHARACTER_REFERENCE(1171, 'i' _ 'm' _ 'a' _ 'g' _ 'p' _ 'a' _ 'r' _ 't' _ ';', 9, 0x2111, 1) +NAMED_CHARACTER_REFERENCE(1172, 'i' _ 'm' _ 'a' _ 't' _ 'h' _ ';', 6, 0x0131, 1) +NAMED_CHARACTER_REFERENCE(1173, 'i' _ 'm' _ 'o' _ 'f' _ ';', 5, 0x22b7, 1) +NAMED_CHARACTER_REFERENCE(1174, 'i' _ 'm' _ 'p' _ 'e' _ 'd' _ ';', 6, 0x01b5, 1) +NAMED_CHARACTER_REFERENCE(1175, 'i' _ 'n' _ ';', 3, 0x2208, 1) +NAMED_CHARACTER_REFERENCE(1176, 'i' _ 'n' _ 'c' _ 'a' _ 'r' _ 'e' _ ';', 7, 0x2105, 1) +NAMED_CHARACTER_REFERENCE(1177, 'i' _ 'n' _ 'f' _ 'i' _ 'n' _ ';', 6, 0x221e, 1) +NAMED_CHARACTER_REFERENCE(1178, 'i' _ 'n' _ 'f' _ 'i' _ 'n' _ 't' _ 'i' _ 'e' _ ';', 9, 0x29dd, 1) +NAMED_CHARACTER_REFERENCE(1179, 'i' _ 'n' _ 'o' _ 'd' _ 'o' _ 't' _ ';', 7, 0x0131, 1) +NAMED_CHARACTER_REFERENCE(1180, 'i' _ 'n' _ 't' _ ';', 4, 0x222b, 1) +NAMED_CHARACTER_REFERENCE(1181, 'i' _ 'n' _ 't' _ 'c' _ 'a' _ 'l' _ ';', 7, 0x22ba, 1) +NAMED_CHARACTER_REFERENCE(1182, 'i' _ 'n' _ 't' _ 'e' _ 'g' _ 'e' _ 'r' _ 's' _ ';', 9, 0x2124, 1) +NAMED_CHARACTER_REFERENCE(1183, 'i' _ 'n' _ 't' _ 'e' _ 'r' _ 'c' _ 'a' _ 'l' _ ';', 9, 0x22ba, 1) +NAMED_CHARACTER_REFERENCE(1184, 'i' _ 'n' _ 't' _ 'l' _ 'a' _ 'r' _ 'h' _ 'k' _ ';', 9, 0x2a17, 1) +NAMED_CHARACTER_REFERENCE(1185, 'i' _ 'n' _ 't' _ 'p' _ 'r' _ 'o' _ 'd' _ ';', 8, 0x2a3c, 1) +NAMED_CHARACTER_REFERENCE(1186, 'i' _ 'o' _ 'c' _ 'y' _ ';', 5, 0x0451, 1) +NAMED_CHARACTER_REFERENCE(1187, 'i' _ 'o' _ 'g' _ 'o' _ 'n' _ ';', 6, 0x012f, 1) +NAMED_CHARACTER_REFERENCE(1188, 'i' _ 'o' _ 'p' _ 'f' _ ';', 5, 0xd835 _ 0xdd5a, 2) +NAMED_CHARACTER_REFERENCE(1189, 'i' _ 'o' _ 't' _ 'a' _ ';', 5, 0x03b9, 1) +NAMED_CHARACTER_REFERENCE(1190, 'i' _ 'p' _ 'r' _ 'o' _ 'd' _ ';', 6, 0x2a3c, 1) +NAMED_CHARACTER_REFERENCE(1191, 'i' _ 'q' _ 'u' _ 'e' _ 's' _ 't', 6, 0x00bf, 1) +NAMED_CHARACTER_REFERENCE(1192, 'i' _ 'q' _ 'u' _ 'e' _ 's' _ 't' _ ';', 7, 0x00bf, 1) +NAMED_CHARACTER_REFERENCE(1193, 'i' _ 's' _ 'c' _ 'r' _ ';', 5, 0xd835 _ 0xdcbe, 2) +NAMED_CHARACTER_REFERENCE(1194, 'i' _ 's' _ 'i' _ 'n' _ ';', 5, 0x2208, 1) +NAMED_CHARACTER_REFERENCE(1195, 'i' _ 's' _ 'i' _ 'n' _ 'E' _ ';', 6, 0x22f9, 1) +NAMED_CHARACTER_REFERENCE(1196, 'i' _ 's' _ 'i' _ 'n' _ 'd' _ 'o' _ 't' _ ';', 8, 0x22f5, 1) +NAMED_CHARACTER_REFERENCE(1197, 'i' _ 's' _ 'i' _ 'n' _ 's' _ ';', 6, 0x22f4, 1) +NAMED_CHARACTER_REFERENCE(1198, 'i' _ 's' _ 'i' _ 'n' _ 's' _ 'v' _ ';', 7, 0x22f3, 1) +NAMED_CHARACTER_REFERENCE(1199, 'i' _ 's' _ 'i' _ 'n' _ 'v' _ ';', 6, 0x2208, 1) +NAMED_CHARACTER_REFERENCE(1200, 'i' _ 't' _ ';', 3, 0x2062, 1) +NAMED_CHARACTER_REFERENCE(1201, 'i' _ 't' _ 'i' _ 'l' _ 'd' _ 'e' _ ';', 7, 0x0129, 1) +NAMED_CHARACTER_REFERENCE(1202, 'i' _ 'u' _ 'k' _ 'c' _ 'y' _ ';', 6, 0x0456, 1) +NAMED_CHARACTER_REFERENCE(1203, 'i' _ 'u' _ 'm' _ 'l', 4, 0x00ef, 1) +NAMED_CHARACTER_REFERENCE(1204, 'i' _ 'u' _ 'm' _ 'l' _ ';', 5, 0x00ef, 1) +NAMED_CHARACTER_REFERENCE(1205, 'j' _ 'c' _ 'i' _ 'r' _ 'c' _ ';', 6, 0x0135, 1) +NAMED_CHARACTER_REFERENCE(1206, 'j' _ 'c' _ 'y' _ ';', 4, 0x0439, 1) +NAMED_CHARACTER_REFERENCE(1207, 'j' _ 'f' _ 'r' _ ';', 4, 0xd835 _ 0xdd27, 2) +NAMED_CHARACTER_REFERENCE(1208, 'j' _ 'm' _ 'a' _ 't' _ 'h' _ ';', 6, 0x0237, 1) +NAMED_CHARACTER_REFERENCE(1209, 'j' _ 'o' _ 'p' _ 'f' _ ';', 5, 0xd835 _ 0xdd5b, 2) +NAMED_CHARACTER_REFERENCE(1210, 'j' _ 's' _ 'c' _ 'r' _ ';', 5, 0xd835 _ 0xdcbf, 2) +NAMED_CHARACTER_REFERENCE(1211, 'j' _ 's' _ 'e' _ 'r' _ 'c' _ 'y' _ ';', 7, 0x0458, 1) +NAMED_CHARACTER_REFERENCE(1212, 'j' _ 'u' _ 'k' _ 'c' _ 'y' _ ';', 6, 0x0454, 1) +NAMED_CHARACTER_REFERENCE(1213, 'k' _ 'a' _ 'p' _ 'p' _ 'a' _ ';', 6, 0x03ba, 1) +NAMED_CHARACTER_REFERENCE(1214, 'k' _ 'a' _ 'p' _ 'p' _ 'a' _ 'v' _ ';', 7, 0x03f0, 1) +NAMED_CHARACTER_REFERENCE(1215, 'k' _ 'c' _ 'e' _ 'd' _ 'i' _ 'l' _ ';', 7, 0x0137, 1) +NAMED_CHARACTER_REFERENCE(1216, 'k' _ 'c' _ 'y' _ ';', 4, 0x043a, 1) +NAMED_CHARACTER_REFERENCE(1217, 'k' _ 'f' _ 'r' _ ';', 4, 0xd835 _ 0xdd28, 2) +NAMED_CHARACTER_REFERENCE(1218, 'k' _ 'g' _ 'r' _ 'e' _ 'e' _ 'n' _ ';', 7, 0x0138, 1) +NAMED_CHARACTER_REFERENCE(1219, 'k' _ 'h' _ 'c' _ 'y' _ ';', 5, 0x0445, 1) +NAMED_CHARACTER_REFERENCE(1220, 'k' _ 'j' _ 'c' _ 'y' _ ';', 5, 0x045c, 1) +NAMED_CHARACTER_REFERENCE(1221, 'k' _ 'o' _ 'p' _ 'f' _ ';', 5, 0xd835 _ 0xdd5c, 2) +NAMED_CHARACTER_REFERENCE(1222, 'k' _ 's' _ 'c' _ 'r' _ ';', 5, 0xd835 _ 0xdcc0, 2) +NAMED_CHARACTER_REFERENCE(1223, 'l' _ 'A' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x21da, 1) +NAMED_CHARACTER_REFERENCE(1224, 'l' _ 'A' _ 'r' _ 'r' _ ';', 5, 0x21d0, 1) +NAMED_CHARACTER_REFERENCE(1225, 'l' _ 'A' _ 't' _ 'a' _ 'i' _ 'l' _ ';', 7, 0x291b, 1) +NAMED_CHARACTER_REFERENCE(1226, 'l' _ 'B' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x290e, 1) +NAMED_CHARACTER_REFERENCE(1227, 'l' _ 'E' _ ';', 3, 0x2266, 1) +NAMED_CHARACTER_REFERENCE(1228, 'l' _ 'E' _ 'g' _ ';', 4, 0x2a8b, 1) +NAMED_CHARACTER_REFERENCE(1229, 'l' _ 'H' _ 'a' _ 'r' _ ';', 5, 0x2962, 1) +NAMED_CHARACTER_REFERENCE(1230, 'l' _ 'a' _ 'c' _ 'u' _ 't' _ 'e' _ ';', 7, 0x013a, 1) +NAMED_CHARACTER_REFERENCE(1231, 'l' _ 'a' _ 'e' _ 'm' _ 'p' _ 't' _ 'y' _ 'v' _ ';', 9, 0x29b4, 1) +NAMED_CHARACTER_REFERENCE(1232, 'l' _ 'a' _ 'g' _ 'r' _ 'a' _ 'n' _ ';', 7, 0x2112, 1) +NAMED_CHARACTER_REFERENCE(1233, 'l' _ 'a' _ 'm' _ 'b' _ 'd' _ 'a' _ ';', 7, 0x03bb, 1) +NAMED_CHARACTER_REFERENCE(1234, 'l' _ 'a' _ 'n' _ 'g' _ ';', 5, 0x27e8, 1) +NAMED_CHARACTER_REFERENCE(1235, 'l' _ 'a' _ 'n' _ 'g' _ 'd' _ ';', 6, 0x2991, 1) +NAMED_CHARACTER_REFERENCE(1236, 'l' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ ';', 7, 0x27e8, 1) +NAMED_CHARACTER_REFERENCE(1237, 'l' _ 'a' _ 'p' _ ';', 4, 0x2a85, 1) +NAMED_CHARACTER_REFERENCE(1238, 'l' _ 'a' _ 'q' _ 'u' _ 'o', 5, 0x00ab, 1) +NAMED_CHARACTER_REFERENCE(1239, 'l' _ 'a' _ 'q' _ 'u' _ 'o' _ ';', 6, 0x00ab, 1) +NAMED_CHARACTER_REFERENCE(1240, 'l' _ 'a' _ 'r' _ 'r' _ ';', 5, 0x2190, 1) +NAMED_CHARACTER_REFERENCE(1241, 'l' _ 'a' _ 'r' _ 'r' _ 'b' _ ';', 6, 0x21e4, 1) +NAMED_CHARACTER_REFERENCE(1242, 'l' _ 'a' _ 'r' _ 'r' _ 'b' _ 'f' _ 's' _ ';', 8, 0x291f, 1) +NAMED_CHARACTER_REFERENCE(1243, 'l' _ 'a' _ 'r' _ 'r' _ 'f' _ 's' _ ';', 7, 0x291d, 1) +NAMED_CHARACTER_REFERENCE(1244, 'l' _ 'a' _ 'r' _ 'r' _ 'h' _ 'k' _ ';', 7, 0x21a9, 1) +NAMED_CHARACTER_REFERENCE(1245, 'l' _ 'a' _ 'r' _ 'r' _ 'l' _ 'p' _ ';', 7, 0x21ab, 1) +NAMED_CHARACTER_REFERENCE(1246, 'l' _ 'a' _ 'r' _ 'r' _ 'p' _ 'l' _ ';', 7, 0x2939, 1) +NAMED_CHARACTER_REFERENCE(1247, 'l' _ 'a' _ 'r' _ 'r' _ 's' _ 'i' _ 'm' _ ';', 8, 0x2973, 1) +NAMED_CHARACTER_REFERENCE(1248, 'l' _ 'a' _ 'r' _ 'r' _ 't' _ 'l' _ ';', 7, 0x21a2, 1) +NAMED_CHARACTER_REFERENCE(1249, 'l' _ 'a' _ 't' _ ';', 4, 0x2aab, 1) +NAMED_CHARACTER_REFERENCE(1250, 'l' _ 'a' _ 't' _ 'a' _ 'i' _ 'l' _ ';', 7, 0x2919, 1) +NAMED_CHARACTER_REFERENCE(1251, 'l' _ 'a' _ 't' _ 'e' _ ';', 5, 0x2aad, 1) +NAMED_CHARACTER_REFERENCE(1252, 'l' _ 'b' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x290c, 1) +NAMED_CHARACTER_REFERENCE(1253, 'l' _ 'b' _ 'b' _ 'r' _ 'k' _ ';', 6, 0x2772, 1) +NAMED_CHARACTER_REFERENCE(1254, 'l' _ 'b' _ 'r' _ 'a' _ 'c' _ 'e' _ ';', 7, 0x007b, 1) +NAMED_CHARACTER_REFERENCE(1255, 'l' _ 'b' _ 'r' _ 'a' _ 'c' _ 'k' _ ';', 7, 0x005b, 1) +NAMED_CHARACTER_REFERENCE(1256, 'l' _ 'b' _ 'r' _ 'k' _ 'e' _ ';', 6, 0x298b, 1) +NAMED_CHARACTER_REFERENCE(1257, 'l' _ 'b' _ 'r' _ 'k' _ 's' _ 'l' _ 'd' _ ';', 8, 0x298f, 1) +NAMED_CHARACTER_REFERENCE(1258, 'l' _ 'b' _ 'r' _ 'k' _ 's' _ 'l' _ 'u' _ ';', 8, 0x298d, 1) +NAMED_CHARACTER_REFERENCE(1259, 'l' _ 'c' _ 'a' _ 'r' _ 'o' _ 'n' _ ';', 7, 0x013e, 1) +NAMED_CHARACTER_REFERENCE(1260, 'l' _ 'c' _ 'e' _ 'd' _ 'i' _ 'l' _ ';', 7, 0x013c, 1) +NAMED_CHARACTER_REFERENCE(1261, 'l' _ 'c' _ 'e' _ 'i' _ 'l' _ ';', 6, 0x2308, 1) +NAMED_CHARACTER_REFERENCE(1262, 'l' _ 'c' _ 'u' _ 'b' _ ';', 5, 0x007b, 1) +NAMED_CHARACTER_REFERENCE(1263, 'l' _ 'c' _ 'y' _ ';', 4, 0x043b, 1) +NAMED_CHARACTER_REFERENCE(1264, 'l' _ 'd' _ 'c' _ 'a' _ ';', 5, 0x2936, 1) +NAMED_CHARACTER_REFERENCE(1265, 'l' _ 'd' _ 'q' _ 'u' _ 'o' _ ';', 6, 0x201c, 1) +NAMED_CHARACTER_REFERENCE(1266, 'l' _ 'd' _ 'q' _ 'u' _ 'o' _ 'r' _ ';', 7, 0x201e, 1) +NAMED_CHARACTER_REFERENCE(1267, 'l' _ 'd' _ 'r' _ 'd' _ 'h' _ 'a' _ 'r' _ ';', 8, 0x2967, 1) +NAMED_CHARACTER_REFERENCE(1268, 'l' _ 'd' _ 'r' _ 'u' _ 's' _ 'h' _ 'a' _ 'r' _ ';', 9, 0x294b, 1) +NAMED_CHARACTER_REFERENCE(1269, 'l' _ 'd' _ 's' _ 'h' _ ';', 5, 0x21b2, 1) +NAMED_CHARACTER_REFERENCE(1270, 'l' _ 'e' _ ';', 3, 0x2264, 1) +NAMED_CHARACTER_REFERENCE(1271, 'l' _ 'e' _ 'f' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 10, 0x2190, 1) +NAMED_CHARACTER_REFERENCE(1272, 'l' _ 'e' _ 'f' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ 't' _ 'a' _ 'i' _ 'l' _ ';', 14, 0x21a2, 1) +NAMED_CHARACTER_REFERENCE(1273, 'l' _ 'e' _ 'f' _ 't' _ 'h' _ 'a' _ 'r' _ 'p' _ 'o' _ 'o' _ 'n' _ 'd' _ 'o' _ 'w' _ 'n' _ ';', 16, 0x21bd, 1) +NAMED_CHARACTER_REFERENCE(1274, 'l' _ 'e' _ 'f' _ 't' _ 'h' _ 'a' _ 'r' _ 'p' _ 'o' _ 'o' _ 'n' _ 'u' _ 'p' _ ';', 14, 0x21bc, 1) +NAMED_CHARACTER_REFERENCE(1275, 'l' _ 'e' _ 'f' _ 't' _ 'l' _ 'e' _ 'f' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ 's' _ ';', 15, 0x21c7, 1) +NAMED_CHARACTER_REFERENCE(1276, 'l' _ 'e' _ 'f' _ 't' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 15, 0x2194, 1) +NAMED_CHARACTER_REFERENCE(1277, 'l' _ 'e' _ 'f' _ 't' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ 's' _ ';', 16, 0x21c6, 1) +NAMED_CHARACTER_REFERENCE(1278, 'l' _ 'e' _ 'f' _ 't' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ 'h' _ 'a' _ 'r' _ 'p' _ 'o' _ 'o' _ 'n' _ 's' _ ';', 18, 0x21cb, 1) +NAMED_CHARACTER_REFERENCE(1279, 'l' _ 'e' _ 'f' _ 't' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ 's' _ 'q' _ 'u' _ 'i' _ 'g' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 20, 0x21ad, 1) +NAMED_CHARACTER_REFERENCE(1280, 'l' _ 'e' _ 'f' _ 't' _ 't' _ 'h' _ 'r' _ 'e' _ 'e' _ 't' _ 'i' _ 'm' _ 'e' _ 's' _ ';', 15, 0x22cb, 1) +NAMED_CHARACTER_REFERENCE(1281, 'l' _ 'e' _ 'g' _ ';', 4, 0x22da, 1) +NAMED_CHARACTER_REFERENCE(1282, 'l' _ 'e' _ 'q' _ ';', 4, 0x2264, 1) +NAMED_CHARACTER_REFERENCE(1283, 'l' _ 'e' _ 'q' _ 'q' _ ';', 5, 0x2266, 1) +NAMED_CHARACTER_REFERENCE(1284, 'l' _ 'e' _ 'q' _ 's' _ 'l' _ 'a' _ 'n' _ 't' _ ';', 9, 0x2a7d, 1) +NAMED_CHARACTER_REFERENCE(1285, 'l' _ 'e' _ 's' _ ';', 4, 0x2a7d, 1) +NAMED_CHARACTER_REFERENCE(1286, 'l' _ 'e' _ 's' _ 'c' _ 'c' _ ';', 6, 0x2aa8, 1) +NAMED_CHARACTER_REFERENCE(1287, 'l' _ 'e' _ 's' _ 'd' _ 'o' _ 't' _ ';', 7, 0x2a7f, 1) +NAMED_CHARACTER_REFERENCE(1288, 'l' _ 'e' _ 's' _ 'd' _ 'o' _ 't' _ 'o' _ ';', 8, 0x2a81, 1) +NAMED_CHARACTER_REFERENCE(1289, 'l' _ 'e' _ 's' _ 'd' _ 'o' _ 't' _ 'o' _ 'r' _ ';', 9, 0x2a83, 1) +NAMED_CHARACTER_REFERENCE(1290, 'l' _ 'e' _ 's' _ 'g' _ 'e' _ 's' _ ';', 7, 0x2a93, 1) +NAMED_CHARACTER_REFERENCE(1291, 'l' _ 'e' _ 's' _ 's' _ 'a' _ 'p' _ 'p' _ 'r' _ 'o' _ 'x' _ ';', 11, 0x2a85, 1) +NAMED_CHARACTER_REFERENCE(1292, 'l' _ 'e' _ 's' _ 's' _ 'd' _ 'o' _ 't' _ ';', 8, 0x22d6, 1) +NAMED_CHARACTER_REFERENCE(1293, 'l' _ 'e' _ 's' _ 's' _ 'e' _ 'q' _ 'g' _ 't' _ 'r' _ ';', 10, 0x22da, 1) +NAMED_CHARACTER_REFERENCE(1294, 'l' _ 'e' _ 's' _ 's' _ 'e' _ 'q' _ 'q' _ 'g' _ 't' _ 'r' _ ';', 11, 0x2a8b, 1) +NAMED_CHARACTER_REFERENCE(1295, 'l' _ 'e' _ 's' _ 's' _ 'g' _ 't' _ 'r' _ ';', 8, 0x2276, 1) +NAMED_CHARACTER_REFERENCE(1296, 'l' _ 'e' _ 's' _ 's' _ 's' _ 'i' _ 'm' _ ';', 8, 0x2272, 1) +NAMED_CHARACTER_REFERENCE(1297, 'l' _ 'f' _ 'i' _ 's' _ 'h' _ 't' _ ';', 7, 0x297c, 1) +NAMED_CHARACTER_REFERENCE(1298, 'l' _ 'f' _ 'l' _ 'o' _ 'o' _ 'r' _ ';', 7, 0x230a, 1) +NAMED_CHARACTER_REFERENCE(1299, 'l' _ 'f' _ 'r' _ ';', 4, 0xd835 _ 0xdd29, 2) +NAMED_CHARACTER_REFERENCE(1300, 'l' _ 'g' _ ';', 3, 0x2276, 1) +NAMED_CHARACTER_REFERENCE(1301, 'l' _ 'g' _ 'E' _ ';', 4, 0x2a91, 1) +NAMED_CHARACTER_REFERENCE(1302, 'l' _ 'h' _ 'a' _ 'r' _ 'd' _ ';', 6, 0x21bd, 1) +NAMED_CHARACTER_REFERENCE(1303, 'l' _ 'h' _ 'a' _ 'r' _ 'u' _ ';', 6, 0x21bc, 1) +NAMED_CHARACTER_REFERENCE(1304, 'l' _ 'h' _ 'a' _ 'r' _ 'u' _ 'l' _ ';', 7, 0x296a, 1) +NAMED_CHARACTER_REFERENCE(1305, 'l' _ 'h' _ 'b' _ 'l' _ 'k' _ ';', 6, 0x2584, 1) +NAMED_CHARACTER_REFERENCE(1306, 'l' _ 'j' _ 'c' _ 'y' _ ';', 5, 0x0459, 1) +NAMED_CHARACTER_REFERENCE(1307, 'l' _ 'l' _ ';', 3, 0x226a, 1) +NAMED_CHARACTER_REFERENCE(1308, 'l' _ 'l' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x21c7, 1) +NAMED_CHARACTER_REFERENCE(1309, 'l' _ 'l' _ 'c' _ 'o' _ 'r' _ 'n' _ 'e' _ 'r' _ ';', 9, 0x231e, 1) +NAMED_CHARACTER_REFERENCE(1310, 'l' _ 'l' _ 'h' _ 'a' _ 'r' _ 'd' _ ';', 7, 0x296b, 1) +NAMED_CHARACTER_REFERENCE(1311, 'l' _ 'l' _ 't' _ 'r' _ 'i' _ ';', 6, 0x25fa, 1) +NAMED_CHARACTER_REFERENCE(1312, 'l' _ 'm' _ 'i' _ 'd' _ 'o' _ 't' _ ';', 7, 0x0140, 1) +NAMED_CHARACTER_REFERENCE(1313, 'l' _ 'm' _ 'o' _ 'u' _ 's' _ 't' _ ';', 7, 0x23b0, 1) +NAMED_CHARACTER_REFERENCE(1314, 'l' _ 'm' _ 'o' _ 'u' _ 's' _ 't' _ 'a' _ 'c' _ 'h' _ 'e' _ ';', 11, 0x23b0, 1) +NAMED_CHARACTER_REFERENCE(1315, 'l' _ 'n' _ 'E' _ ';', 4, 0x2268, 1) +NAMED_CHARACTER_REFERENCE(1316, 'l' _ 'n' _ 'a' _ 'p' _ ';', 5, 0x2a89, 1) +NAMED_CHARACTER_REFERENCE(1317, 'l' _ 'n' _ 'a' _ 'p' _ 'p' _ 'r' _ 'o' _ 'x' _ ';', 9, 0x2a89, 1) +NAMED_CHARACTER_REFERENCE(1318, 'l' _ 'n' _ 'e' _ ';', 4, 0x2a87, 1) +NAMED_CHARACTER_REFERENCE(1319, 'l' _ 'n' _ 'e' _ 'q' _ ';', 5, 0x2a87, 1) +NAMED_CHARACTER_REFERENCE(1320, 'l' _ 'n' _ 'e' _ 'q' _ 'q' _ ';', 6, 0x2268, 1) +NAMED_CHARACTER_REFERENCE(1321, 'l' _ 'n' _ 's' _ 'i' _ 'm' _ ';', 6, 0x22e6, 1) +NAMED_CHARACTER_REFERENCE(1322, 'l' _ 'o' _ 'a' _ 'n' _ 'g' _ ';', 6, 0x27ec, 1) +NAMED_CHARACTER_REFERENCE(1323, 'l' _ 'o' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x21fd, 1) +NAMED_CHARACTER_REFERENCE(1324, 'l' _ 'o' _ 'b' _ 'r' _ 'k' _ ';', 6, 0x27e6, 1) +NAMED_CHARACTER_REFERENCE(1325, 'l' _ 'o' _ 'n' _ 'g' _ 'l' _ 'e' _ 'f' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 14, 0x27f5, 1) +NAMED_CHARACTER_REFERENCE(1326, 'l' _ 'o' _ 'n' _ 'g' _ 'l' _ 'e' _ 'f' _ 't' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 19, 0x27f7, 1) +NAMED_CHARACTER_REFERENCE(1327, 'l' _ 'o' _ 'n' _ 'g' _ 'm' _ 'a' _ 'p' _ 's' _ 't' _ 'o' _ ';', 11, 0x27fc, 1) +NAMED_CHARACTER_REFERENCE(1328, 'l' _ 'o' _ 'n' _ 'g' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 15, 0x27f6, 1) +NAMED_CHARACTER_REFERENCE(1329, 'l' _ 'o' _ 'o' _ 'p' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ 'l' _ 'e' _ 'f' _ 't' _ ';', 14, 0x21ab, 1) +NAMED_CHARACTER_REFERENCE(1330, 'l' _ 'o' _ 'o' _ 'p' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ ';', 15, 0x21ac, 1) +NAMED_CHARACTER_REFERENCE(1331, 'l' _ 'o' _ 'p' _ 'a' _ 'r' _ ';', 6, 0x2985, 1) +NAMED_CHARACTER_REFERENCE(1332, 'l' _ 'o' _ 'p' _ 'f' _ ';', 5, 0xd835 _ 0xdd5d, 2) +NAMED_CHARACTER_REFERENCE(1333, 'l' _ 'o' _ 'p' _ 'l' _ 'u' _ 's' _ ';', 7, 0x2a2d, 1) +NAMED_CHARACTER_REFERENCE(1334, 'l' _ 'o' _ 't' _ 'i' _ 'm' _ 'e' _ 's' _ ';', 8, 0x2a34, 1) +NAMED_CHARACTER_REFERENCE(1335, 'l' _ 'o' _ 'w' _ 'a' _ 's' _ 't' _ ';', 7, 0x2217, 1) +NAMED_CHARACTER_REFERENCE(1336, 'l' _ 'o' _ 'w' _ 'b' _ 'a' _ 'r' _ ';', 7, 0x005f, 1) +NAMED_CHARACTER_REFERENCE(1337, 'l' _ 'o' _ 'z' _ ';', 4, 0x25ca, 1) +NAMED_CHARACTER_REFERENCE(1338, 'l' _ 'o' _ 'z' _ 'e' _ 'n' _ 'g' _ 'e' _ ';', 8, 0x25ca, 1) +NAMED_CHARACTER_REFERENCE(1339, 'l' _ 'o' _ 'z' _ 'f' _ ';', 5, 0x29eb, 1) +NAMED_CHARACTER_REFERENCE(1340, 'l' _ 'p' _ 'a' _ 'r' _ ';', 5, 0x0028, 1) +NAMED_CHARACTER_REFERENCE(1341, 'l' _ 'p' _ 'a' _ 'r' _ 'l' _ 't' _ ';', 7, 0x2993, 1) +NAMED_CHARACTER_REFERENCE(1342, 'l' _ 'r' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x21c6, 1) +NAMED_CHARACTER_REFERENCE(1343, 'l' _ 'r' _ 'c' _ 'o' _ 'r' _ 'n' _ 'e' _ 'r' _ ';', 9, 0x231f, 1) +NAMED_CHARACTER_REFERENCE(1344, 'l' _ 'r' _ 'h' _ 'a' _ 'r' _ ';', 6, 0x21cb, 1) +NAMED_CHARACTER_REFERENCE(1345, 'l' _ 'r' _ 'h' _ 'a' _ 'r' _ 'd' _ ';', 7, 0x296d, 1) +NAMED_CHARACTER_REFERENCE(1346, 'l' _ 'r' _ 'm' _ ';', 4, 0x200e, 1) +NAMED_CHARACTER_REFERENCE(1347, 'l' _ 'r' _ 't' _ 'r' _ 'i' _ ';', 6, 0x22bf, 1) +NAMED_CHARACTER_REFERENCE(1348, 'l' _ 's' _ 'a' _ 'q' _ 'u' _ 'o' _ ';', 7, 0x2039, 1) +NAMED_CHARACTER_REFERENCE(1349, 'l' _ 's' _ 'c' _ 'r' _ ';', 5, 0xd835 _ 0xdcc1, 2) +NAMED_CHARACTER_REFERENCE(1350, 'l' _ 's' _ 'h' _ ';', 4, 0x21b0, 1) +NAMED_CHARACTER_REFERENCE(1351, 'l' _ 's' _ 'i' _ 'm' _ ';', 5, 0x2272, 1) +NAMED_CHARACTER_REFERENCE(1352, 'l' _ 's' _ 'i' _ 'm' _ 'e' _ ';', 6, 0x2a8d, 1) +NAMED_CHARACTER_REFERENCE(1353, 'l' _ 's' _ 'i' _ 'm' _ 'g' _ ';', 6, 0x2a8f, 1) +NAMED_CHARACTER_REFERENCE(1354, 'l' _ 's' _ 'q' _ 'b' _ ';', 5, 0x005b, 1) +NAMED_CHARACTER_REFERENCE(1355, 'l' _ 's' _ 'q' _ 'u' _ 'o' _ ';', 6, 0x2018, 1) +NAMED_CHARACTER_REFERENCE(1356, 'l' _ 's' _ 'q' _ 'u' _ 'o' _ 'r' _ ';', 7, 0x201a, 1) +NAMED_CHARACTER_REFERENCE(1357, 'l' _ 's' _ 't' _ 'r' _ 'o' _ 'k' _ ';', 7, 0x0142, 1) +NAMED_CHARACTER_REFERENCE(1358, 'l' _ 't', 2, 0x003c, 1) +NAMED_CHARACTER_REFERENCE(1359, 'l' _ 't' _ ';', 3, 0x003c, 1) +NAMED_CHARACTER_REFERENCE(1360, 'l' _ 't' _ 'c' _ 'c' _ ';', 5, 0x2aa6, 1) +NAMED_CHARACTER_REFERENCE(1361, 'l' _ 't' _ 'c' _ 'i' _ 'r' _ ';', 6, 0x2a79, 1) +NAMED_CHARACTER_REFERENCE(1362, 'l' _ 't' _ 'd' _ 'o' _ 't' _ ';', 6, 0x22d6, 1) +NAMED_CHARACTER_REFERENCE(1363, 'l' _ 't' _ 'h' _ 'r' _ 'e' _ 'e' _ ';', 7, 0x22cb, 1) +NAMED_CHARACTER_REFERENCE(1364, 'l' _ 't' _ 'i' _ 'm' _ 'e' _ 's' _ ';', 7, 0x22c9, 1) +NAMED_CHARACTER_REFERENCE(1365, 'l' _ 't' _ 'l' _ 'a' _ 'r' _ 'r' _ ';', 7, 0x2976, 1) +NAMED_CHARACTER_REFERENCE(1366, 'l' _ 't' _ 'q' _ 'u' _ 'e' _ 's' _ 't' _ ';', 8, 0x2a7b, 1) +NAMED_CHARACTER_REFERENCE(1367, 'l' _ 't' _ 'r' _ 'P' _ 'a' _ 'r' _ ';', 7, 0x2996, 1) +NAMED_CHARACTER_REFERENCE(1368, 'l' _ 't' _ 'r' _ 'i' _ ';', 5, 0x25c3, 1) +NAMED_CHARACTER_REFERENCE(1369, 'l' _ 't' _ 'r' _ 'i' _ 'e' _ ';', 6, 0x22b4, 1) +NAMED_CHARACTER_REFERENCE(1370, 'l' _ 't' _ 'r' _ 'i' _ 'f' _ ';', 6, 0x25c2, 1) +NAMED_CHARACTER_REFERENCE(1371, 'l' _ 'u' _ 'r' _ 'd' _ 's' _ 'h' _ 'a' _ 'r' _ ';', 9, 0x294a, 1) +NAMED_CHARACTER_REFERENCE(1372, 'l' _ 'u' _ 'r' _ 'u' _ 'h' _ 'a' _ 'r' _ ';', 8, 0x2966, 1) +NAMED_CHARACTER_REFERENCE(1373, 'm' _ 'D' _ 'D' _ 'o' _ 't' _ ';', 6, 0x223a, 1) +NAMED_CHARACTER_REFERENCE(1374, 'm' _ 'a' _ 'c' _ 'r', 4, 0x00af, 1) +NAMED_CHARACTER_REFERENCE(1375, 'm' _ 'a' _ 'c' _ 'r' _ ';', 5, 0x00af, 1) +NAMED_CHARACTER_REFERENCE(1376, 'm' _ 'a' _ 'l' _ 'e' _ ';', 5, 0x2642, 1) +NAMED_CHARACTER_REFERENCE(1377, 'm' _ 'a' _ 'l' _ 't' _ ';', 5, 0x2720, 1) +NAMED_CHARACTER_REFERENCE(1378, 'm' _ 'a' _ 'l' _ 't' _ 'e' _ 's' _ 'e' _ ';', 8, 0x2720, 1) +NAMED_CHARACTER_REFERENCE(1379, 'm' _ 'a' _ 'p' _ ';', 4, 0x21a6, 1) +NAMED_CHARACTER_REFERENCE(1380, 'm' _ 'a' _ 'p' _ 's' _ 't' _ 'o' _ ';', 7, 0x21a6, 1) +NAMED_CHARACTER_REFERENCE(1381, 'm' _ 'a' _ 'p' _ 's' _ 't' _ 'o' _ 'd' _ 'o' _ 'w' _ 'n' _ ';', 11, 0x21a7, 1) +NAMED_CHARACTER_REFERENCE(1382, 'm' _ 'a' _ 'p' _ 's' _ 't' _ 'o' _ 'l' _ 'e' _ 'f' _ 't' _ ';', 11, 0x21a4, 1) +NAMED_CHARACTER_REFERENCE(1383, 'm' _ 'a' _ 'p' _ 's' _ 't' _ 'o' _ 'u' _ 'p' _ ';', 9, 0x21a5, 1) +NAMED_CHARACTER_REFERENCE(1384, 'm' _ 'a' _ 'r' _ 'k' _ 'e' _ 'r' _ ';', 7, 0x25ae, 1) +NAMED_CHARACTER_REFERENCE(1385, 'm' _ 'c' _ 'o' _ 'm' _ 'm' _ 'a' _ ';', 7, 0x2a29, 1) +NAMED_CHARACTER_REFERENCE(1386, 'm' _ 'c' _ 'y' _ ';', 4, 0x043c, 1) +NAMED_CHARACTER_REFERENCE(1387, 'm' _ 'd' _ 'a' _ 's' _ 'h' _ ';', 6, 0x2014, 1) +NAMED_CHARACTER_REFERENCE(1388, 'm' _ 'e' _ 'a' _ 's' _ 'u' _ 'r' _ 'e' _ 'd' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ ';', 14, 0x2221, 1) +NAMED_CHARACTER_REFERENCE(1389, 'm' _ 'f' _ 'r' _ ';', 4, 0xd835 _ 0xdd2a, 2) +NAMED_CHARACTER_REFERENCE(1390, 'm' _ 'h' _ 'o' _ ';', 4, 0x2127, 1) +NAMED_CHARACTER_REFERENCE(1391, 'm' _ 'i' _ 'c' _ 'r' _ 'o', 5, 0x00b5, 1) +NAMED_CHARACTER_REFERENCE(1392, 'm' _ 'i' _ 'c' _ 'r' _ 'o' _ ';', 6, 0x00b5, 1) +NAMED_CHARACTER_REFERENCE(1393, 'm' _ 'i' _ 'd' _ ';', 4, 0x2223, 1) +NAMED_CHARACTER_REFERENCE(1394, 'm' _ 'i' _ 'd' _ 'a' _ 's' _ 't' _ ';', 7, 0x002a, 1) +NAMED_CHARACTER_REFERENCE(1395, 'm' _ 'i' _ 'd' _ 'c' _ 'i' _ 'r' _ ';', 7, 0x2af0, 1) +NAMED_CHARACTER_REFERENCE(1396, 'm' _ 'i' _ 'd' _ 'd' _ 'o' _ 't', 6, 0x00b7, 1) +NAMED_CHARACTER_REFERENCE(1397, 'm' _ 'i' _ 'd' _ 'd' _ 'o' _ 't' _ ';', 7, 0x00b7, 1) +NAMED_CHARACTER_REFERENCE(1398, 'm' _ 'i' _ 'n' _ 'u' _ 's' _ ';', 6, 0x2212, 1) +NAMED_CHARACTER_REFERENCE(1399, 'm' _ 'i' _ 'n' _ 'u' _ 's' _ 'b' _ ';', 7, 0x229f, 1) +NAMED_CHARACTER_REFERENCE(1400, 'm' _ 'i' _ 'n' _ 'u' _ 's' _ 'd' _ ';', 7, 0x2238, 1) +NAMED_CHARACTER_REFERENCE(1401, 'm' _ 'i' _ 'n' _ 'u' _ 's' _ 'd' _ 'u' _ ';', 8, 0x2a2a, 1) +NAMED_CHARACTER_REFERENCE(1402, 'm' _ 'l' _ 'c' _ 'p' _ ';', 5, 0x2adb, 1) +NAMED_CHARACTER_REFERENCE(1403, 'm' _ 'l' _ 'd' _ 'r' _ ';', 5, 0x2026, 1) +NAMED_CHARACTER_REFERENCE(1404, 'm' _ 'n' _ 'p' _ 'l' _ 'u' _ 's' _ ';', 7, 0x2213, 1) +NAMED_CHARACTER_REFERENCE(1405, 'm' _ 'o' _ 'd' _ 'e' _ 'l' _ 's' _ ';', 7, 0x22a7, 1) +NAMED_CHARACTER_REFERENCE(1406, 'm' _ 'o' _ 'p' _ 'f' _ ';', 5, 0xd835 _ 0xdd5e, 2) +NAMED_CHARACTER_REFERENCE(1407, 'm' _ 'p' _ ';', 3, 0x2213, 1) +NAMED_CHARACTER_REFERENCE(1408, 'm' _ 's' _ 'c' _ 'r' _ ';', 5, 0xd835 _ 0xdcc2, 2) +NAMED_CHARACTER_REFERENCE(1409, 'm' _ 's' _ 't' _ 'p' _ 'o' _ 's' _ ';', 7, 0x223e, 1) +NAMED_CHARACTER_REFERENCE(1410, 'm' _ 'u' _ ';', 3, 0x03bc, 1) +NAMED_CHARACTER_REFERENCE(1411, 'm' _ 'u' _ 'l' _ 't' _ 'i' _ 'm' _ 'a' _ 'p' _ ';', 9, 0x22b8, 1) +NAMED_CHARACTER_REFERENCE(1412, 'm' _ 'u' _ 'm' _ 'a' _ 'p' _ ';', 6, 0x22b8, 1) +NAMED_CHARACTER_REFERENCE(1413, 'n' _ 'L' _ 'e' _ 'f' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 11, 0x21cd, 1) +NAMED_CHARACTER_REFERENCE(1414, 'n' _ 'L' _ 'e' _ 'f' _ 't' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 16, 0x21ce, 1) +NAMED_CHARACTER_REFERENCE(1415, 'n' _ 'R' _ 'i' _ 'g' _ 'h' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 12, 0x21cf, 1) +NAMED_CHARACTER_REFERENCE(1416, 'n' _ 'V' _ 'D' _ 'a' _ 's' _ 'h' _ ';', 7, 0x22af, 1) +NAMED_CHARACTER_REFERENCE(1417, 'n' _ 'V' _ 'd' _ 'a' _ 's' _ 'h' _ ';', 7, 0x22ae, 1) +NAMED_CHARACTER_REFERENCE(1418, 'n' _ 'a' _ 'b' _ 'l' _ 'a' _ ';', 6, 0x2207, 1) +NAMED_CHARACTER_REFERENCE(1419, 'n' _ 'a' _ 'c' _ 'u' _ 't' _ 'e' _ ';', 7, 0x0144, 1) +NAMED_CHARACTER_REFERENCE(1420, 'n' _ 'a' _ 'p' _ ';', 4, 0x2249, 1) +NAMED_CHARACTER_REFERENCE(1421, 'n' _ 'a' _ 'p' _ 'o' _ 's' _ ';', 6, 0x0149, 1) +NAMED_CHARACTER_REFERENCE(1422, 'n' _ 'a' _ 'p' _ 'p' _ 'r' _ 'o' _ 'x' _ ';', 8, 0x2249, 1) +NAMED_CHARACTER_REFERENCE(1423, 'n' _ 'a' _ 't' _ 'u' _ 'r' _ ';', 6, 0x266e, 1) +NAMED_CHARACTER_REFERENCE(1424, 'n' _ 'a' _ 't' _ 'u' _ 'r' _ 'a' _ 'l' _ ';', 8, 0x266e, 1) +NAMED_CHARACTER_REFERENCE(1425, 'n' _ 'a' _ 't' _ 'u' _ 'r' _ 'a' _ 'l' _ 's' _ ';', 9, 0x2115, 1) +NAMED_CHARACTER_REFERENCE(1426, 'n' _ 'b' _ 's' _ 'p', 4, 0x00a0, 1) +NAMED_CHARACTER_REFERENCE(1427, 'n' _ 'b' _ 's' _ 'p' _ ';', 5, 0x00a0, 1) +NAMED_CHARACTER_REFERENCE(1428, 'n' _ 'c' _ 'a' _ 'p' _ ';', 5, 0x2a43, 1) +NAMED_CHARACTER_REFERENCE(1429, 'n' _ 'c' _ 'a' _ 'r' _ 'o' _ 'n' _ ';', 7, 0x0148, 1) +NAMED_CHARACTER_REFERENCE(1430, 'n' _ 'c' _ 'e' _ 'd' _ 'i' _ 'l' _ ';', 7, 0x0146, 1) +NAMED_CHARACTER_REFERENCE(1431, 'n' _ 'c' _ 'o' _ 'n' _ 'g' _ ';', 6, 0x2247, 1) +NAMED_CHARACTER_REFERENCE(1432, 'n' _ 'c' _ 'u' _ 'p' _ ';', 5, 0x2a42, 1) +NAMED_CHARACTER_REFERENCE(1433, 'n' _ 'c' _ 'y' _ ';', 4, 0x043d, 1) +NAMED_CHARACTER_REFERENCE(1434, 'n' _ 'd' _ 'a' _ 's' _ 'h' _ ';', 6, 0x2013, 1) +NAMED_CHARACTER_REFERENCE(1435, 'n' _ 'e' _ ';', 3, 0x2260, 1) +NAMED_CHARACTER_REFERENCE(1436, 'n' _ 'e' _ 'A' _ 'r' _ 'r' _ ';', 6, 0x21d7, 1) +NAMED_CHARACTER_REFERENCE(1437, 'n' _ 'e' _ 'a' _ 'r' _ 'h' _ 'k' _ ';', 7, 0x2924, 1) +NAMED_CHARACTER_REFERENCE(1438, 'n' _ 'e' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x2197, 1) +NAMED_CHARACTER_REFERENCE(1439, 'n' _ 'e' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 8, 0x2197, 1) +NAMED_CHARACTER_REFERENCE(1440, 'n' _ 'e' _ 'q' _ 'u' _ 'i' _ 'v' _ ';', 7, 0x2262, 1) +NAMED_CHARACTER_REFERENCE(1441, 'n' _ 'e' _ 's' _ 'e' _ 'a' _ 'r' _ ';', 7, 0x2928, 1) +NAMED_CHARACTER_REFERENCE(1442, 'n' _ 'e' _ 'x' _ 'i' _ 's' _ 't' _ ';', 7, 0x2204, 1) +NAMED_CHARACTER_REFERENCE(1443, 'n' _ 'e' _ 'x' _ 'i' _ 's' _ 't' _ 's' _ ';', 8, 0x2204, 1) +NAMED_CHARACTER_REFERENCE(1444, 'n' _ 'f' _ 'r' _ ';', 4, 0xd835 _ 0xdd2b, 2) +NAMED_CHARACTER_REFERENCE(1445, 'n' _ 'g' _ 'e' _ ';', 4, 0x2271, 1) +NAMED_CHARACTER_REFERENCE(1446, 'n' _ 'g' _ 'e' _ 'q' _ ';', 5, 0x2271, 1) +NAMED_CHARACTER_REFERENCE(1447, 'n' _ 'g' _ 's' _ 'i' _ 'm' _ ';', 6, 0x2275, 1) +NAMED_CHARACTER_REFERENCE(1448, 'n' _ 'g' _ 't' _ ';', 4, 0x226f, 1) +NAMED_CHARACTER_REFERENCE(1449, 'n' _ 'g' _ 't' _ 'r' _ ';', 5, 0x226f, 1) +NAMED_CHARACTER_REFERENCE(1450, 'n' _ 'h' _ 'A' _ 'r' _ 'r' _ ';', 6, 0x21ce, 1) +NAMED_CHARACTER_REFERENCE(1451, 'n' _ 'h' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x21ae, 1) +NAMED_CHARACTER_REFERENCE(1452, 'n' _ 'h' _ 'p' _ 'a' _ 'r' _ ';', 6, 0x2af2, 1) +NAMED_CHARACTER_REFERENCE(1453, 'n' _ 'i' _ ';', 3, 0x220b, 1) +NAMED_CHARACTER_REFERENCE(1454, 'n' _ 'i' _ 's' _ ';', 4, 0x22fc, 1) +NAMED_CHARACTER_REFERENCE(1455, 'n' _ 'i' _ 's' _ 'd' _ ';', 5, 0x22fa, 1) +NAMED_CHARACTER_REFERENCE(1456, 'n' _ 'i' _ 'v' _ ';', 4, 0x220b, 1) +NAMED_CHARACTER_REFERENCE(1457, 'n' _ 'j' _ 'c' _ 'y' _ ';', 5, 0x045a, 1) +NAMED_CHARACTER_REFERENCE(1458, 'n' _ 'l' _ 'A' _ 'r' _ 'r' _ ';', 6, 0x21cd, 1) +NAMED_CHARACTER_REFERENCE(1459, 'n' _ 'l' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x219a, 1) +NAMED_CHARACTER_REFERENCE(1460, 'n' _ 'l' _ 'd' _ 'r' _ ';', 5, 0x2025, 1) +NAMED_CHARACTER_REFERENCE(1461, 'n' _ 'l' _ 'e' _ ';', 4, 0x2270, 1) +NAMED_CHARACTER_REFERENCE(1462, 'n' _ 'l' _ 'e' _ 'f' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 11, 0x219a, 1) +NAMED_CHARACTER_REFERENCE(1463, 'n' _ 'l' _ 'e' _ 'f' _ 't' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 16, 0x21ae, 1) +NAMED_CHARACTER_REFERENCE(1464, 'n' _ 'l' _ 'e' _ 'q' _ ';', 5, 0x2270, 1) +NAMED_CHARACTER_REFERENCE(1465, 'n' _ 'l' _ 'e' _ 's' _ 's' _ ';', 6, 0x226e, 1) +NAMED_CHARACTER_REFERENCE(1466, 'n' _ 'l' _ 's' _ 'i' _ 'm' _ ';', 6, 0x2274, 1) +NAMED_CHARACTER_REFERENCE(1467, 'n' _ 'l' _ 't' _ ';', 4, 0x226e, 1) +NAMED_CHARACTER_REFERENCE(1468, 'n' _ 'l' _ 't' _ 'r' _ 'i' _ ';', 6, 0x22ea, 1) +NAMED_CHARACTER_REFERENCE(1469, 'n' _ 'l' _ 't' _ 'r' _ 'i' _ 'e' _ ';', 7, 0x22ec, 1) +NAMED_CHARACTER_REFERENCE(1470, 'n' _ 'm' _ 'i' _ 'd' _ ';', 5, 0x2224, 1) +NAMED_CHARACTER_REFERENCE(1471, 'n' _ 'o' _ 'p' _ 'f' _ ';', 5, 0xd835 _ 0xdd5f, 2) +NAMED_CHARACTER_REFERENCE(1472, 'n' _ 'o' _ 't', 3, 0x00ac, 1) +NAMED_CHARACTER_REFERENCE(1473, 'n' _ 'o' _ 't' _ ';', 4, 0x00ac, 1) +NAMED_CHARACTER_REFERENCE(1474, 'n' _ 'o' _ 't' _ 'i' _ 'n' _ ';', 6, 0x2209, 1) +NAMED_CHARACTER_REFERENCE(1475, 'n' _ 'o' _ 't' _ 'i' _ 'n' _ 'v' _ 'a' _ ';', 8, 0x2209, 1) +NAMED_CHARACTER_REFERENCE(1476, 'n' _ 'o' _ 't' _ 'i' _ 'n' _ 'v' _ 'b' _ ';', 8, 0x22f7, 1) +NAMED_CHARACTER_REFERENCE(1477, 'n' _ 'o' _ 't' _ 'i' _ 'n' _ 'v' _ 'c' _ ';', 8, 0x22f6, 1) +NAMED_CHARACTER_REFERENCE(1478, 'n' _ 'o' _ 't' _ 'n' _ 'i' _ ';', 6, 0x220c, 1) +NAMED_CHARACTER_REFERENCE(1479, 'n' _ 'o' _ 't' _ 'n' _ 'i' _ 'v' _ 'a' _ ';', 8, 0x220c, 1) +NAMED_CHARACTER_REFERENCE(1480, 'n' _ 'o' _ 't' _ 'n' _ 'i' _ 'v' _ 'b' _ ';', 8, 0x22fe, 1) +NAMED_CHARACTER_REFERENCE(1481, 'n' _ 'o' _ 't' _ 'n' _ 'i' _ 'v' _ 'c' _ ';', 8, 0x22fd, 1) +NAMED_CHARACTER_REFERENCE(1482, 'n' _ 'p' _ 'a' _ 'r' _ ';', 5, 0x2226, 1) +NAMED_CHARACTER_REFERENCE(1483, 'n' _ 'p' _ 'a' _ 'r' _ 'a' _ 'l' _ 'l' _ 'e' _ 'l' _ ';', 10, 0x2226, 1) +NAMED_CHARACTER_REFERENCE(1484, 'n' _ 'p' _ 'o' _ 'l' _ 'i' _ 'n' _ 't' _ ';', 8, 0x2a14, 1) +NAMED_CHARACTER_REFERENCE(1485, 'n' _ 'p' _ 'r' _ ';', 4, 0x2280, 1) +NAMED_CHARACTER_REFERENCE(1486, 'n' _ 'p' _ 'r' _ 'c' _ 'u' _ 'e' _ ';', 7, 0x22e0, 1) +NAMED_CHARACTER_REFERENCE(1487, 'n' _ 'p' _ 'r' _ 'e' _ 'c' _ ';', 6, 0x2280, 1) +NAMED_CHARACTER_REFERENCE(1488, 'n' _ 'r' _ 'A' _ 'r' _ 'r' _ ';', 6, 0x21cf, 1) +NAMED_CHARACTER_REFERENCE(1489, 'n' _ 'r' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x219b, 1) +NAMED_CHARACTER_REFERENCE(1490, 'n' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 12, 0x219b, 1) +NAMED_CHARACTER_REFERENCE(1491, 'n' _ 'r' _ 't' _ 'r' _ 'i' _ ';', 6, 0x22eb, 1) +NAMED_CHARACTER_REFERENCE(1492, 'n' _ 'r' _ 't' _ 'r' _ 'i' _ 'e' _ ';', 7, 0x22ed, 1) +NAMED_CHARACTER_REFERENCE(1493, 'n' _ 's' _ 'c' _ ';', 4, 0x2281, 1) +NAMED_CHARACTER_REFERENCE(1494, 'n' _ 's' _ 'c' _ 'c' _ 'u' _ 'e' _ ';', 7, 0x22e1, 1) +NAMED_CHARACTER_REFERENCE(1495, 'n' _ 's' _ 'c' _ 'r' _ ';', 5, 0xd835 _ 0xdcc3, 2) +NAMED_CHARACTER_REFERENCE(1496, 'n' _ 's' _ 'h' _ 'o' _ 'r' _ 't' _ 'm' _ 'i' _ 'd' _ ';', 10, 0x2224, 1) +NAMED_CHARACTER_REFERENCE(1497, 'n' _ 's' _ 'h' _ 'o' _ 'r' _ 't' _ 'p' _ 'a' _ 'r' _ 'a' _ 'l' _ 'l' _ 'e' _ 'l' _ ';', 15, 0x2226, 1) +NAMED_CHARACTER_REFERENCE(1498, 'n' _ 's' _ 'i' _ 'm' _ ';', 5, 0x2241, 1) +NAMED_CHARACTER_REFERENCE(1499, 'n' _ 's' _ 'i' _ 'm' _ 'e' _ ';', 6, 0x2244, 1) +NAMED_CHARACTER_REFERENCE(1500, 'n' _ 's' _ 'i' _ 'm' _ 'e' _ 'q' _ ';', 7, 0x2244, 1) +NAMED_CHARACTER_REFERENCE(1501, 'n' _ 's' _ 'm' _ 'i' _ 'd' _ ';', 6, 0x2224, 1) +NAMED_CHARACTER_REFERENCE(1502, 'n' _ 's' _ 'p' _ 'a' _ 'r' _ ';', 6, 0x2226, 1) +NAMED_CHARACTER_REFERENCE(1503, 'n' _ 's' _ 'q' _ 's' _ 'u' _ 'b' _ 'e' _ ';', 8, 0x22e2, 1) +NAMED_CHARACTER_REFERENCE(1504, 'n' _ 's' _ 'q' _ 's' _ 'u' _ 'p' _ 'e' _ ';', 8, 0x22e3, 1) +NAMED_CHARACTER_REFERENCE(1505, 'n' _ 's' _ 'u' _ 'b' _ ';', 5, 0x2284, 1) +NAMED_CHARACTER_REFERENCE(1506, 'n' _ 's' _ 'u' _ 'b' _ 'e' _ ';', 6, 0x2288, 1) +NAMED_CHARACTER_REFERENCE(1507, 'n' _ 's' _ 'u' _ 'b' _ 's' _ 'e' _ 't' _ 'e' _ 'q' _ ';', 10, 0x2288, 1) +NAMED_CHARACTER_REFERENCE(1508, 'n' _ 's' _ 'u' _ 'c' _ 'c' _ ';', 6, 0x2281, 1) +NAMED_CHARACTER_REFERENCE(1509, 'n' _ 's' _ 'u' _ 'p' _ ';', 5, 0x2285, 1) +NAMED_CHARACTER_REFERENCE(1510, 'n' _ 's' _ 'u' _ 'p' _ 'e' _ ';', 6, 0x2289, 1) +NAMED_CHARACTER_REFERENCE(1511, 'n' _ 's' _ 'u' _ 'p' _ 's' _ 'e' _ 't' _ 'e' _ 'q' _ ';', 10, 0x2289, 1) +NAMED_CHARACTER_REFERENCE(1512, 'n' _ 't' _ 'g' _ 'l' _ ';', 5, 0x2279, 1) +NAMED_CHARACTER_REFERENCE(1513, 'n' _ 't' _ 'i' _ 'l' _ 'd' _ 'e', 6, 0x00f1, 1) +NAMED_CHARACTER_REFERENCE(1514, 'n' _ 't' _ 'i' _ 'l' _ 'd' _ 'e' _ ';', 7, 0x00f1, 1) +NAMED_CHARACTER_REFERENCE(1515, 'n' _ 't' _ 'l' _ 'g' _ ';', 5, 0x2278, 1) +NAMED_CHARACTER_REFERENCE(1516, 'n' _ 't' _ 'r' _ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ 'l' _ 'e' _ 'f' _ 't' _ ';', 14, 0x22ea, 1) +NAMED_CHARACTER_REFERENCE(1517, 'n' _ 't' _ 'r' _ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ 'l' _ 'e' _ 'f' _ 't' _ 'e' _ 'q' _ ';', 16, 0x22ec, 1) +NAMED_CHARACTER_REFERENCE(1518, 'n' _ 't' _ 'r' _ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ ';', 15, 0x22eb, 1) +NAMED_CHARACTER_REFERENCE(1519, 'n' _ 't' _ 'r' _ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ 'e' _ 'q' _ ';', 17, 0x22ed, 1) +NAMED_CHARACTER_REFERENCE(1520, 'n' _ 'u' _ ';', 3, 0x03bd, 1) +NAMED_CHARACTER_REFERENCE(1521, 'n' _ 'u' _ 'm' _ ';', 4, 0x0023, 1) +NAMED_CHARACTER_REFERENCE(1522, 'n' _ 'u' _ 'm' _ 'e' _ 'r' _ 'o' _ ';', 7, 0x2116, 1) +NAMED_CHARACTER_REFERENCE(1523, 'n' _ 'u' _ 'm' _ 's' _ 'p' _ ';', 6, 0x2007, 1) +NAMED_CHARACTER_REFERENCE(1524, 'n' _ 'v' _ 'D' _ 'a' _ 's' _ 'h' _ ';', 7, 0x22ad, 1) +NAMED_CHARACTER_REFERENCE(1525, 'n' _ 'v' _ 'H' _ 'a' _ 'r' _ 'r' _ ';', 7, 0x2904, 1) +NAMED_CHARACTER_REFERENCE(1526, 'n' _ 'v' _ 'd' _ 'a' _ 's' _ 'h' _ ';', 7, 0x22ac, 1) +NAMED_CHARACTER_REFERENCE(1527, 'n' _ 'v' _ 'i' _ 'n' _ 'f' _ 'i' _ 'n' _ ';', 8, 0x29de, 1) +NAMED_CHARACTER_REFERENCE(1528, 'n' _ 'v' _ 'l' _ 'A' _ 'r' _ 'r' _ ';', 7, 0x2902, 1) +NAMED_CHARACTER_REFERENCE(1529, 'n' _ 'v' _ 'r' _ 'A' _ 'r' _ 'r' _ ';', 7, 0x2903, 1) +NAMED_CHARACTER_REFERENCE(1530, 'n' _ 'w' _ 'A' _ 'r' _ 'r' _ ';', 6, 0x21d6, 1) +NAMED_CHARACTER_REFERENCE(1531, 'n' _ 'w' _ 'a' _ 'r' _ 'h' _ 'k' _ ';', 7, 0x2923, 1) +NAMED_CHARACTER_REFERENCE(1532, 'n' _ 'w' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x2196, 1) +NAMED_CHARACTER_REFERENCE(1533, 'n' _ 'w' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 8, 0x2196, 1) +NAMED_CHARACTER_REFERENCE(1534, 'n' _ 'w' _ 'n' _ 'e' _ 'a' _ 'r' _ ';', 7, 0x2927, 1) +NAMED_CHARACTER_REFERENCE(1535, 'o' _ 'S' _ ';', 3, 0x24c8, 1) +NAMED_CHARACTER_REFERENCE(1536, 'o' _ 'a' _ 'c' _ 'u' _ 't' _ 'e', 6, 0x00f3, 1) +NAMED_CHARACTER_REFERENCE(1537, 'o' _ 'a' _ 'c' _ 'u' _ 't' _ 'e' _ ';', 7, 0x00f3, 1) +NAMED_CHARACTER_REFERENCE(1538, 'o' _ 'a' _ 's' _ 't' _ ';', 5, 0x229b, 1) +NAMED_CHARACTER_REFERENCE(1539, 'o' _ 'c' _ 'i' _ 'r' _ ';', 5, 0x229a, 1) +NAMED_CHARACTER_REFERENCE(1540, 'o' _ 'c' _ 'i' _ 'r' _ 'c', 5, 0x00f4, 1) +NAMED_CHARACTER_REFERENCE(1541, 'o' _ 'c' _ 'i' _ 'r' _ 'c' _ ';', 6, 0x00f4, 1) +NAMED_CHARACTER_REFERENCE(1542, 'o' _ 'c' _ 'y' _ ';', 4, 0x043e, 1) +NAMED_CHARACTER_REFERENCE(1543, 'o' _ 'd' _ 'a' _ 's' _ 'h' _ ';', 6, 0x229d, 1) +NAMED_CHARACTER_REFERENCE(1544, 'o' _ 'd' _ 'b' _ 'l' _ 'a' _ 'c' _ ';', 7, 0x0151, 1) +NAMED_CHARACTER_REFERENCE(1545, 'o' _ 'd' _ 'i' _ 'v' _ ';', 5, 0x2a38, 1) +NAMED_CHARACTER_REFERENCE(1546, 'o' _ 'd' _ 'o' _ 't' _ ';', 5, 0x2299, 1) +NAMED_CHARACTER_REFERENCE(1547, 'o' _ 'd' _ 's' _ 'o' _ 'l' _ 'd' _ ';', 7, 0x29bc, 1) +NAMED_CHARACTER_REFERENCE(1548, 'o' _ 'e' _ 'l' _ 'i' _ 'g' _ ';', 6, 0x0153, 1) +NAMED_CHARACTER_REFERENCE(1549, 'o' _ 'f' _ 'c' _ 'i' _ 'r' _ ';', 6, 0x29bf, 1) +NAMED_CHARACTER_REFERENCE(1550, 'o' _ 'f' _ 'r' _ ';', 4, 0xd835 _ 0xdd2c, 2) +NAMED_CHARACTER_REFERENCE(1551, 'o' _ 'g' _ 'o' _ 'n' _ ';', 5, 0x02db, 1) +NAMED_CHARACTER_REFERENCE(1552, 'o' _ 'g' _ 'r' _ 'a' _ 'v' _ 'e', 6, 0x00f2, 1) +NAMED_CHARACTER_REFERENCE(1553, 'o' _ 'g' _ 'r' _ 'a' _ 'v' _ 'e' _ ';', 7, 0x00f2, 1) +NAMED_CHARACTER_REFERENCE(1554, 'o' _ 'g' _ 't' _ ';', 4, 0x29c1, 1) +NAMED_CHARACTER_REFERENCE(1555, 'o' _ 'h' _ 'b' _ 'a' _ 'r' _ ';', 6, 0x29b5, 1) +NAMED_CHARACTER_REFERENCE(1556, 'o' _ 'h' _ 'm' _ ';', 4, 0x03a9, 1) +NAMED_CHARACTER_REFERENCE(1557, 'o' _ 'i' _ 'n' _ 't' _ ';', 5, 0x222e, 1) +NAMED_CHARACTER_REFERENCE(1558, 'o' _ 'l' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x21ba, 1) +NAMED_CHARACTER_REFERENCE(1559, 'o' _ 'l' _ 'c' _ 'i' _ 'r' _ ';', 6, 0x29be, 1) +NAMED_CHARACTER_REFERENCE(1560, 'o' _ 'l' _ 'c' _ 'r' _ 'o' _ 's' _ 's' _ ';', 8, 0x29bb, 1) +NAMED_CHARACTER_REFERENCE(1561, 'o' _ 'l' _ 'i' _ 'n' _ 'e' _ ';', 6, 0x203e, 1) +NAMED_CHARACTER_REFERENCE(1562, 'o' _ 'l' _ 't' _ ';', 4, 0x29c0, 1) +NAMED_CHARACTER_REFERENCE(1563, 'o' _ 'm' _ 'a' _ 'c' _ 'r' _ ';', 6, 0x014d, 1) +NAMED_CHARACTER_REFERENCE(1564, 'o' _ 'm' _ 'e' _ 'g' _ 'a' _ ';', 6, 0x03c9, 1) +NAMED_CHARACTER_REFERENCE(1565, 'o' _ 'm' _ 'i' _ 'c' _ 'r' _ 'o' _ 'n' _ ';', 8, 0x03bf, 1) +NAMED_CHARACTER_REFERENCE(1566, 'o' _ 'm' _ 'i' _ 'd' _ ';', 5, 0x29b6, 1) +NAMED_CHARACTER_REFERENCE(1567, 'o' _ 'm' _ 'i' _ 'n' _ 'u' _ 's' _ ';', 7, 0x2296, 1) +NAMED_CHARACTER_REFERENCE(1568, 'o' _ 'o' _ 'p' _ 'f' _ ';', 5, 0xd835 _ 0xdd60, 2) +NAMED_CHARACTER_REFERENCE(1569, 'o' _ 'p' _ 'a' _ 'r' _ ';', 5, 0x29b7, 1) +NAMED_CHARACTER_REFERENCE(1570, 'o' _ 'p' _ 'e' _ 'r' _ 'p' _ ';', 6, 0x29b9, 1) +NAMED_CHARACTER_REFERENCE(1571, 'o' _ 'p' _ 'l' _ 'u' _ 's' _ ';', 6, 0x2295, 1) +NAMED_CHARACTER_REFERENCE(1572, 'o' _ 'r' _ ';', 3, 0x2228, 1) +NAMED_CHARACTER_REFERENCE(1573, 'o' _ 'r' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x21bb, 1) +NAMED_CHARACTER_REFERENCE(1574, 'o' _ 'r' _ 'd' _ ';', 4, 0x2a5d, 1) +NAMED_CHARACTER_REFERENCE(1575, 'o' _ 'r' _ 'd' _ 'e' _ 'r' _ ';', 6, 0x2134, 1) +NAMED_CHARACTER_REFERENCE(1576, 'o' _ 'r' _ 'd' _ 'e' _ 'r' _ 'o' _ 'f' _ ';', 8, 0x2134, 1) +NAMED_CHARACTER_REFERENCE(1577, 'o' _ 'r' _ 'd' _ 'f', 4, 0x00aa, 1) +NAMED_CHARACTER_REFERENCE(1578, 'o' _ 'r' _ 'd' _ 'f' _ ';', 5, 0x00aa, 1) +NAMED_CHARACTER_REFERENCE(1579, 'o' _ 'r' _ 'd' _ 'm', 4, 0x00ba, 1) +NAMED_CHARACTER_REFERENCE(1580, 'o' _ 'r' _ 'd' _ 'm' _ ';', 5, 0x00ba, 1) +NAMED_CHARACTER_REFERENCE(1581, 'o' _ 'r' _ 'i' _ 'g' _ 'o' _ 'f' _ ';', 7, 0x22b6, 1) +NAMED_CHARACTER_REFERENCE(1582, 'o' _ 'r' _ 'o' _ 'r' _ ';', 5, 0x2a56, 1) +NAMED_CHARACTER_REFERENCE(1583, 'o' _ 'r' _ 's' _ 'l' _ 'o' _ 'p' _ 'e' _ ';', 8, 0x2a57, 1) +NAMED_CHARACTER_REFERENCE(1584, 'o' _ 'r' _ 'v' _ ';', 4, 0x2a5b, 1) +NAMED_CHARACTER_REFERENCE(1585, 'o' _ 's' _ 'c' _ 'r' _ ';', 5, 0x2134, 1) +NAMED_CHARACTER_REFERENCE(1586, 'o' _ 's' _ 'l' _ 'a' _ 's' _ 'h', 6, 0x00f8, 1) +NAMED_CHARACTER_REFERENCE(1587, 'o' _ 's' _ 'l' _ 'a' _ 's' _ 'h' _ ';', 7, 0x00f8, 1) +NAMED_CHARACTER_REFERENCE(1588, 'o' _ 's' _ 'o' _ 'l' _ ';', 5, 0x2298, 1) +NAMED_CHARACTER_REFERENCE(1589, 'o' _ 't' _ 'i' _ 'l' _ 'd' _ 'e', 6, 0x00f5, 1) +NAMED_CHARACTER_REFERENCE(1590, 'o' _ 't' _ 'i' _ 'l' _ 'd' _ 'e' _ ';', 7, 0x00f5, 1) +NAMED_CHARACTER_REFERENCE(1591, 'o' _ 't' _ 'i' _ 'm' _ 'e' _ 's' _ ';', 7, 0x2297, 1) +NAMED_CHARACTER_REFERENCE(1592, 'o' _ 't' _ 'i' _ 'm' _ 'e' _ 's' _ 'a' _ 's' _ ';', 9, 0x2a36, 1) +NAMED_CHARACTER_REFERENCE(1593, 'o' _ 'u' _ 'm' _ 'l', 4, 0x00f6, 1) +NAMED_CHARACTER_REFERENCE(1594, 'o' _ 'u' _ 'm' _ 'l' _ ';', 5, 0x00f6, 1) +NAMED_CHARACTER_REFERENCE(1595, 'o' _ 'v' _ 'b' _ 'a' _ 'r' _ ';', 6, 0x233d, 1) +NAMED_CHARACTER_REFERENCE(1596, 'p' _ 'a' _ 'r' _ ';', 4, 0x2225, 1) +NAMED_CHARACTER_REFERENCE(1597, 'p' _ 'a' _ 'r' _ 'a', 4, 0x00b6, 1) +NAMED_CHARACTER_REFERENCE(1598, 'p' _ 'a' _ 'r' _ 'a' _ ';', 5, 0x00b6, 1) +NAMED_CHARACTER_REFERENCE(1599, 'p' _ 'a' _ 'r' _ 'a' _ 'l' _ 'l' _ 'e' _ 'l' _ ';', 9, 0x2225, 1) +NAMED_CHARACTER_REFERENCE(1600, 'p' _ 'a' _ 'r' _ 's' _ 'i' _ 'm' _ ';', 7, 0x2af3, 1) +NAMED_CHARACTER_REFERENCE(1601, 'p' _ 'a' _ 'r' _ 's' _ 'l' _ ';', 6, 0x2afd, 1) +NAMED_CHARACTER_REFERENCE(1602, 'p' _ 'a' _ 'r' _ 't' _ ';', 5, 0x2202, 1) +NAMED_CHARACTER_REFERENCE(1603, 'p' _ 'c' _ 'y' _ ';', 4, 0x043f, 1) +NAMED_CHARACTER_REFERENCE(1604, 'p' _ 'e' _ 'r' _ 'c' _ 'n' _ 't' _ ';', 7, 0x0025, 1) +NAMED_CHARACTER_REFERENCE(1605, 'p' _ 'e' _ 'r' _ 'i' _ 'o' _ 'd' _ ';', 7, 0x002e, 1) +NAMED_CHARACTER_REFERENCE(1606, 'p' _ 'e' _ 'r' _ 'm' _ 'i' _ 'l' _ ';', 7, 0x2030, 1) +NAMED_CHARACTER_REFERENCE(1607, 'p' _ 'e' _ 'r' _ 'p' _ ';', 5, 0x22a5, 1) +NAMED_CHARACTER_REFERENCE(1608, 'p' _ 'e' _ 'r' _ 't' _ 'e' _ 'n' _ 'k' _ ';', 8, 0x2031, 1) +NAMED_CHARACTER_REFERENCE(1609, 'p' _ 'f' _ 'r' _ ';', 4, 0xd835 _ 0xdd2d, 2) +NAMED_CHARACTER_REFERENCE(1610, 'p' _ 'h' _ 'i' _ ';', 4, 0x03c6, 1) +NAMED_CHARACTER_REFERENCE(1611, 'p' _ 'h' _ 'i' _ 'v' _ ';', 5, 0x03d5, 1) +NAMED_CHARACTER_REFERENCE(1612, 'p' _ 'h' _ 'm' _ 'm' _ 'a' _ 't' _ ';', 7, 0x2133, 1) +NAMED_CHARACTER_REFERENCE(1613, 'p' _ 'h' _ 'o' _ 'n' _ 'e' _ ';', 6, 0x260e, 1) +NAMED_CHARACTER_REFERENCE(1614, 'p' _ 'i' _ ';', 3, 0x03c0, 1) +NAMED_CHARACTER_REFERENCE(1615, 'p' _ 'i' _ 't' _ 'c' _ 'h' _ 'f' _ 'o' _ 'r' _ 'k' _ ';', 10, 0x22d4, 1) +NAMED_CHARACTER_REFERENCE(1616, 'p' _ 'i' _ 'v' _ ';', 4, 0x03d6, 1) +NAMED_CHARACTER_REFERENCE(1617, 'p' _ 'l' _ 'a' _ 'n' _ 'c' _ 'k' _ ';', 7, 0x210f, 1) +NAMED_CHARACTER_REFERENCE(1618, 'p' _ 'l' _ 'a' _ 'n' _ 'c' _ 'k' _ 'h' _ ';', 8, 0x210e, 1) +NAMED_CHARACTER_REFERENCE(1619, 'p' _ 'l' _ 'a' _ 'n' _ 'k' _ 'v' _ ';', 7, 0x210f, 1) +NAMED_CHARACTER_REFERENCE(1620, 'p' _ 'l' _ 'u' _ 's' _ ';', 5, 0x002b, 1) +NAMED_CHARACTER_REFERENCE(1621, 'p' _ 'l' _ 'u' _ 's' _ 'a' _ 'c' _ 'i' _ 'r' _ ';', 9, 0x2a23, 1) +NAMED_CHARACTER_REFERENCE(1622, 'p' _ 'l' _ 'u' _ 's' _ 'b' _ ';', 6, 0x229e, 1) +NAMED_CHARACTER_REFERENCE(1623, 'p' _ 'l' _ 'u' _ 's' _ 'c' _ 'i' _ 'r' _ ';', 8, 0x2a22, 1) +NAMED_CHARACTER_REFERENCE(1624, 'p' _ 'l' _ 'u' _ 's' _ 'd' _ 'o' _ ';', 7, 0x2214, 1) +NAMED_CHARACTER_REFERENCE(1625, 'p' _ 'l' _ 'u' _ 's' _ 'd' _ 'u' _ ';', 7, 0x2a25, 1) +NAMED_CHARACTER_REFERENCE(1626, 'p' _ 'l' _ 'u' _ 's' _ 'e' _ ';', 6, 0x2a72, 1) +NAMED_CHARACTER_REFERENCE(1627, 'p' _ 'l' _ 'u' _ 's' _ 'm' _ 'n', 6, 0x00b1, 1) +NAMED_CHARACTER_REFERENCE(1628, 'p' _ 'l' _ 'u' _ 's' _ 'm' _ 'n' _ ';', 7, 0x00b1, 1) +NAMED_CHARACTER_REFERENCE(1629, 'p' _ 'l' _ 'u' _ 's' _ 's' _ 'i' _ 'm' _ ';', 8, 0x2a26, 1) +NAMED_CHARACTER_REFERENCE(1630, 'p' _ 'l' _ 'u' _ 's' _ 't' _ 'w' _ 'o' _ ';', 8, 0x2a27, 1) +NAMED_CHARACTER_REFERENCE(1631, 'p' _ 'm' _ ';', 3, 0x00b1, 1) +NAMED_CHARACTER_REFERENCE(1632, 'p' _ 'o' _ 'i' _ 'n' _ 't' _ 'i' _ 'n' _ 't' _ ';', 9, 0x2a15, 1) +NAMED_CHARACTER_REFERENCE(1633, 'p' _ 'o' _ 'p' _ 'f' _ ';', 5, 0xd835 _ 0xdd61, 2) +NAMED_CHARACTER_REFERENCE(1634, 'p' _ 'o' _ 'u' _ 'n' _ 'd', 5, 0x00a3, 1) +NAMED_CHARACTER_REFERENCE(1635, 'p' _ 'o' _ 'u' _ 'n' _ 'd' _ ';', 6, 0x00a3, 1) +NAMED_CHARACTER_REFERENCE(1636, 'p' _ 'r' _ ';', 3, 0x227a, 1) +NAMED_CHARACTER_REFERENCE(1637, 'p' _ 'r' _ 'E' _ ';', 4, 0x2ab3, 1) +NAMED_CHARACTER_REFERENCE(1638, 'p' _ 'r' _ 'a' _ 'p' _ ';', 5, 0x2ab7, 1) +NAMED_CHARACTER_REFERENCE(1639, 'p' _ 'r' _ 'c' _ 'u' _ 'e' _ ';', 6, 0x227c, 1) +NAMED_CHARACTER_REFERENCE(1640, 'p' _ 'r' _ 'e' _ ';', 4, 0x2aaf, 1) +NAMED_CHARACTER_REFERENCE(1641, 'p' _ 'r' _ 'e' _ 'c' _ ';', 5, 0x227a, 1) +NAMED_CHARACTER_REFERENCE(1642, 'p' _ 'r' _ 'e' _ 'c' _ 'a' _ 'p' _ 'p' _ 'r' _ 'o' _ 'x' _ ';', 11, 0x2ab7, 1) +NAMED_CHARACTER_REFERENCE(1643, 'p' _ 'r' _ 'e' _ 'c' _ 'c' _ 'u' _ 'r' _ 'l' _ 'y' _ 'e' _ 'q' _ ';', 12, 0x227c, 1) +NAMED_CHARACTER_REFERENCE(1644, 'p' _ 'r' _ 'e' _ 'c' _ 'e' _ 'q' _ ';', 7, 0x2aaf, 1) +NAMED_CHARACTER_REFERENCE(1645, 'p' _ 'r' _ 'e' _ 'c' _ 'n' _ 'a' _ 'p' _ 'p' _ 'r' _ 'o' _ 'x' _ ';', 12, 0x2ab9, 1) +NAMED_CHARACTER_REFERENCE(1646, 'p' _ 'r' _ 'e' _ 'c' _ 'n' _ 'e' _ 'q' _ 'q' _ ';', 9, 0x2ab5, 1) +NAMED_CHARACTER_REFERENCE(1647, 'p' _ 'r' _ 'e' _ 'c' _ 'n' _ 's' _ 'i' _ 'm' _ ';', 9, 0x22e8, 1) +NAMED_CHARACTER_REFERENCE(1648, 'p' _ 'r' _ 'e' _ 'c' _ 's' _ 'i' _ 'm' _ ';', 8, 0x227e, 1) +NAMED_CHARACTER_REFERENCE(1649, 'p' _ 'r' _ 'i' _ 'm' _ 'e' _ ';', 6, 0x2032, 1) +NAMED_CHARACTER_REFERENCE(1650, 'p' _ 'r' _ 'i' _ 'm' _ 'e' _ 's' _ ';', 7, 0x2119, 1) +NAMED_CHARACTER_REFERENCE(1651, 'p' _ 'r' _ 'n' _ 'E' _ ';', 5, 0x2ab5, 1) +NAMED_CHARACTER_REFERENCE(1652, 'p' _ 'r' _ 'n' _ 'a' _ 'p' _ ';', 6, 0x2ab9, 1) +NAMED_CHARACTER_REFERENCE(1653, 'p' _ 'r' _ 'n' _ 's' _ 'i' _ 'm' _ ';', 7, 0x22e8, 1) +NAMED_CHARACTER_REFERENCE(1654, 'p' _ 'r' _ 'o' _ 'd' _ ';', 5, 0x220f, 1) +NAMED_CHARACTER_REFERENCE(1655, 'p' _ 'r' _ 'o' _ 'f' _ 'a' _ 'l' _ 'a' _ 'r' _ ';', 9, 0x232e, 1) +NAMED_CHARACTER_REFERENCE(1656, 'p' _ 'r' _ 'o' _ 'f' _ 'l' _ 'i' _ 'n' _ 'e' _ ';', 9, 0x2312, 1) +NAMED_CHARACTER_REFERENCE(1657, 'p' _ 'r' _ 'o' _ 'f' _ 's' _ 'u' _ 'r' _ 'f' _ ';', 9, 0x2313, 1) +NAMED_CHARACTER_REFERENCE(1658, 'p' _ 'r' _ 'o' _ 'p' _ ';', 5, 0x221d, 1) +NAMED_CHARACTER_REFERENCE(1659, 'p' _ 'r' _ 'o' _ 'p' _ 't' _ 'o' _ ';', 7, 0x221d, 1) +NAMED_CHARACTER_REFERENCE(1660, 'p' _ 'r' _ 's' _ 'i' _ 'm' _ ';', 6, 0x227e, 1) +NAMED_CHARACTER_REFERENCE(1661, 'p' _ 'r' _ 'u' _ 'r' _ 'e' _ 'l' _ ';', 7, 0x22b0, 1) +NAMED_CHARACTER_REFERENCE(1662, 'p' _ 's' _ 'c' _ 'r' _ ';', 5, 0xd835 _ 0xdcc5, 2) +NAMED_CHARACTER_REFERENCE(1663, 'p' _ 's' _ 'i' _ ';', 4, 0x03c8, 1) +NAMED_CHARACTER_REFERENCE(1664, 'p' _ 'u' _ 'n' _ 'c' _ 's' _ 'p' _ ';', 7, 0x2008, 1) +NAMED_CHARACTER_REFERENCE(1665, 'q' _ 'f' _ 'r' _ ';', 4, 0xd835 _ 0xdd2e, 2) +NAMED_CHARACTER_REFERENCE(1666, 'q' _ 'i' _ 'n' _ 't' _ ';', 5, 0x2a0c, 1) +NAMED_CHARACTER_REFERENCE(1667, 'q' _ 'o' _ 'p' _ 'f' _ ';', 5, 0xd835 _ 0xdd62, 2) +NAMED_CHARACTER_REFERENCE(1668, 'q' _ 'p' _ 'r' _ 'i' _ 'm' _ 'e' _ ';', 7, 0x2057, 1) +NAMED_CHARACTER_REFERENCE(1669, 'q' _ 's' _ 'c' _ 'r' _ ';', 5, 0xd835 _ 0xdcc6, 2) +NAMED_CHARACTER_REFERENCE(1670, 'q' _ 'u' _ 'a' _ 't' _ 'e' _ 'r' _ 'n' _ 'i' _ 'o' _ 'n' _ 's' _ ';', 12, 0x210d, 1) +NAMED_CHARACTER_REFERENCE(1671, 'q' _ 'u' _ 'a' _ 't' _ 'i' _ 'n' _ 't' _ ';', 8, 0x2a16, 1) +NAMED_CHARACTER_REFERENCE(1672, 'q' _ 'u' _ 'e' _ 's' _ 't' _ ';', 6, 0x003f, 1) +NAMED_CHARACTER_REFERENCE(1673, 'q' _ 'u' _ 'e' _ 's' _ 't' _ 'e' _ 'q' _ ';', 8, 0x225f, 1) +NAMED_CHARACTER_REFERENCE(1674, 'q' _ 'u' _ 'o' _ 't', 4, 0x0022, 1) +NAMED_CHARACTER_REFERENCE(1675, 'q' _ 'u' _ 'o' _ 't' _ ';', 5, 0x0022, 1) +NAMED_CHARACTER_REFERENCE(1676, 'r' _ 'A' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x21db, 1) +NAMED_CHARACTER_REFERENCE(1677, 'r' _ 'A' _ 'r' _ 'r' _ ';', 5, 0x21d2, 1) +NAMED_CHARACTER_REFERENCE(1678, 'r' _ 'A' _ 't' _ 'a' _ 'i' _ 'l' _ ';', 7, 0x291c, 1) +NAMED_CHARACTER_REFERENCE(1679, 'r' _ 'B' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x290f, 1) +NAMED_CHARACTER_REFERENCE(1680, 'r' _ 'H' _ 'a' _ 'r' _ ';', 5, 0x2964, 1) NAMED_CHARACTER_REFERENCE(1681, 'r' _ 'a' _ 'c' _ 'u' _ 't' _ 'e' _ ';', 7, 0x0155, 1) NAMED_CHARACTER_REFERENCE(1682, 'r' _ 'a' _ 'd' _ 'i' _ 'c' _ ';', 6, 0x221a, 1) NAMED_CHARACTER_REFERENCE(1683, 'r' _ 'a' _ 'e' _ 'm' _ 'p' _ 't' _ 'y' _ 'v' _ ';', 9, 0x29b3, 1) @@ -1933,230 +1933,231 @@ NAMED_CHARACTER_REFERENCE(1908, 's' _ 'u' _ 'p' _ 'd' _ 'o' _ 't' _ ';', 7, 0x2a NAMED_CHARACTER_REFERENCE(1909, 's' _ 'u' _ 'p' _ 'd' _ 's' _ 'u' _ 'b' _ ';', 8, 0x2ad8, 1) NAMED_CHARACTER_REFERENCE(1910, 's' _ 'u' _ 'p' _ 'e' _ ';', 5, 0x2287, 1) NAMED_CHARACTER_REFERENCE(1911, 's' _ 'u' _ 'p' _ 'e' _ 'd' _ 'o' _ 't' _ ';', 8, 0x2ac4, 1) -NAMED_CHARACTER_REFERENCE(1912, 's' _ 'u' _ 'p' _ 'h' _ 's' _ 'u' _ 'b' _ ';', 8, 0x2ad7, 1) -NAMED_CHARACTER_REFERENCE(1913, 's' _ 'u' _ 'p' _ 'l' _ 'a' _ 'r' _ 'r' _ ';', 8, 0x297b, 1) -NAMED_CHARACTER_REFERENCE(1914, 's' _ 'u' _ 'p' _ 'm' _ 'u' _ 'l' _ 't' _ ';', 8, 0x2ac2, 1) -NAMED_CHARACTER_REFERENCE(1915, 's' _ 'u' _ 'p' _ 'n' _ 'E' _ ';', 6, 0x2acc, 1) -NAMED_CHARACTER_REFERENCE(1916, 's' _ 'u' _ 'p' _ 'n' _ 'e' _ ';', 6, 0x228b, 1) -NAMED_CHARACTER_REFERENCE(1917, 's' _ 'u' _ 'p' _ 'p' _ 'l' _ 'u' _ 's' _ ';', 8, 0x2ac0, 1) -NAMED_CHARACTER_REFERENCE(1918, 's' _ 'u' _ 'p' _ 's' _ 'e' _ 't' _ ';', 7, 0x2283, 1) -NAMED_CHARACTER_REFERENCE(1919, 's' _ 'u' _ 'p' _ 's' _ 'e' _ 't' _ 'e' _ 'q' _ ';', 9, 0x2287, 1) -NAMED_CHARACTER_REFERENCE(1920, 's' _ 'u' _ 'p' _ 's' _ 'e' _ 't' _ 'e' _ 'q' _ 'q' _ ';', 10, 0x2ac6, 1) -NAMED_CHARACTER_REFERENCE(1921, 's' _ 'u' _ 'p' _ 's' _ 'e' _ 't' _ 'n' _ 'e' _ 'q' _ ';', 10, 0x228b, 1) -NAMED_CHARACTER_REFERENCE(1922, 's' _ 'u' _ 'p' _ 's' _ 'e' _ 't' _ 'n' _ 'e' _ 'q' _ 'q' _ ';', 11, 0x2acc, 1) -NAMED_CHARACTER_REFERENCE(1923, 's' _ 'u' _ 'p' _ 's' _ 'i' _ 'm' _ ';', 7, 0x2ac8, 1) -NAMED_CHARACTER_REFERENCE(1924, 's' _ 'u' _ 'p' _ 's' _ 'u' _ 'b' _ ';', 7, 0x2ad4, 1) -NAMED_CHARACTER_REFERENCE(1925, 's' _ 'u' _ 'p' _ 's' _ 'u' _ 'p' _ ';', 7, 0x2ad6, 1) -NAMED_CHARACTER_REFERENCE(1926, 's' _ 'w' _ 'A' _ 'r' _ 'r' _ ';', 6, 0x21d9, 1) -NAMED_CHARACTER_REFERENCE(1927, 's' _ 'w' _ 'a' _ 'r' _ 'h' _ 'k' _ ';', 7, 0x2926, 1) -NAMED_CHARACTER_REFERENCE(1928, 's' _ 'w' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x2199, 1) -NAMED_CHARACTER_REFERENCE(1929, 's' _ 'w' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 8, 0x2199, 1) -NAMED_CHARACTER_REFERENCE(1930, 's' _ 'w' _ 'n' _ 'w' _ 'a' _ 'r' _ ';', 7, 0x292a, 1) -NAMED_CHARACTER_REFERENCE(1931, 's' _ 'z' _ 'l' _ 'i' _ 'g', 5, 0x00df, 1) -NAMED_CHARACTER_REFERENCE(1932, 's' _ 'z' _ 'l' _ 'i' _ 'g' _ ';', 6, 0x00df, 1) -NAMED_CHARACTER_REFERENCE(1933, 't' _ 'a' _ 'r' _ 'g' _ 'e' _ 't' _ ';', 7, 0x2316, 1) -NAMED_CHARACTER_REFERENCE(1934, 't' _ 'a' _ 'u' _ ';', 4, 0x03c4, 1) -NAMED_CHARACTER_REFERENCE(1935, 't' _ 'b' _ 'r' _ 'k' _ ';', 5, 0x23b4, 1) -NAMED_CHARACTER_REFERENCE(1936, 't' _ 'c' _ 'a' _ 'r' _ 'o' _ 'n' _ ';', 7, 0x0165, 1) -NAMED_CHARACTER_REFERENCE(1937, 't' _ 'c' _ 'e' _ 'd' _ 'i' _ 'l' _ ';', 7, 0x0163, 1) -NAMED_CHARACTER_REFERENCE(1938, 't' _ 'c' _ 'y' _ ';', 4, 0x0442, 1) -NAMED_CHARACTER_REFERENCE(1939, 't' _ 'd' _ 'o' _ 't' _ ';', 5, 0x20db, 1) -NAMED_CHARACTER_REFERENCE(1940, 't' _ 'e' _ 'l' _ 'r' _ 'e' _ 'c' _ ';', 7, 0x2315, 1) -NAMED_CHARACTER_REFERENCE(1941, 't' _ 'f' _ 'r' _ ';', 4, 0xd835 _ 0xdd31, 2) -NAMED_CHARACTER_REFERENCE(1942, 't' _ 'h' _ 'e' _ 'r' _ 'e' _ '4' _ ';', 7, 0x2234, 1) -NAMED_CHARACTER_REFERENCE(1943, 't' _ 'h' _ 'e' _ 'r' _ 'e' _ 'f' _ 'o' _ 'r' _ 'e' _ ';', 10, 0x2234, 1) -NAMED_CHARACTER_REFERENCE(1944, 't' _ 'h' _ 'e' _ 't' _ 'a' _ ';', 6, 0x03b8, 1) -NAMED_CHARACTER_REFERENCE(1945, 't' _ 'h' _ 'e' _ 't' _ 'a' _ 's' _ 'y' _ 'm' _ ';', 9, 0x03d1, 1) -NAMED_CHARACTER_REFERENCE(1946, 't' _ 'h' _ 'e' _ 't' _ 'a' _ 'v' _ ';', 7, 0x03d1, 1) -NAMED_CHARACTER_REFERENCE(1947, 't' _ 'h' _ 'i' _ 'c' _ 'k' _ 'a' _ 'p' _ 'p' _ 'r' _ 'o' _ 'x' _ ';', 12, 0x2248, 1) -NAMED_CHARACTER_REFERENCE(1948, 't' _ 'h' _ 'i' _ 'c' _ 'k' _ 's' _ 'i' _ 'm' _ ';', 9, 0x223c, 1) -NAMED_CHARACTER_REFERENCE(1949, 't' _ 'h' _ 'i' _ 'n' _ 's' _ 'p' _ ';', 7, 0x2009, 1) -NAMED_CHARACTER_REFERENCE(1950, 't' _ 'h' _ 'k' _ 'a' _ 'p' _ ';', 6, 0x2248, 1) -NAMED_CHARACTER_REFERENCE(1951, 't' _ 'h' _ 'k' _ 's' _ 'i' _ 'm' _ ';', 7, 0x223c, 1) -NAMED_CHARACTER_REFERENCE(1952, 't' _ 'h' _ 'o' _ 'r' _ 'n', 5, 0x00fe, 1) -NAMED_CHARACTER_REFERENCE(1953, 't' _ 'h' _ 'o' _ 'r' _ 'n' _ ';', 6, 0x00fe, 1) -NAMED_CHARACTER_REFERENCE(1954, 't' _ 'i' _ 'l' _ 'd' _ 'e' _ ';', 6, 0x02dc, 1) -NAMED_CHARACTER_REFERENCE(1955, 't' _ 'i' _ 'm' _ 'e' _ 's', 5, 0x00d7, 1) -NAMED_CHARACTER_REFERENCE(1956, 't' _ 'i' _ 'm' _ 'e' _ 's' _ ';', 6, 0x00d7, 1) -NAMED_CHARACTER_REFERENCE(1957, 't' _ 'i' _ 'm' _ 'e' _ 's' _ 'b' _ ';', 7, 0x22a0, 1) -NAMED_CHARACTER_REFERENCE(1958, 't' _ 'i' _ 'm' _ 'e' _ 's' _ 'b' _ 'a' _ 'r' _ ';', 9, 0x2a31, 1) -NAMED_CHARACTER_REFERENCE(1959, 't' _ 'i' _ 'm' _ 'e' _ 's' _ 'd' _ ';', 7, 0x2a30, 1) -NAMED_CHARACTER_REFERENCE(1960, 't' _ 'i' _ 'n' _ 't' _ ';', 5, 0x222d, 1) -NAMED_CHARACTER_REFERENCE(1961, 't' _ 'o' _ 'e' _ 'a' _ ';', 5, 0x2928, 1) -NAMED_CHARACTER_REFERENCE(1962, 't' _ 'o' _ 'p' _ ';', 4, 0x22a4, 1) -NAMED_CHARACTER_REFERENCE(1963, 't' _ 'o' _ 'p' _ 'b' _ 'o' _ 't' _ ';', 7, 0x2336, 1) -NAMED_CHARACTER_REFERENCE(1964, 't' _ 'o' _ 'p' _ 'c' _ 'i' _ 'r' _ ';', 7, 0x2af1, 1) -NAMED_CHARACTER_REFERENCE(1965, 't' _ 'o' _ 'p' _ 'f' _ ';', 5, 0xd835 _ 0xdd65, 2) -NAMED_CHARACTER_REFERENCE(1966, 't' _ 'o' _ 'p' _ 'f' _ 'o' _ 'r' _ 'k' _ ';', 8, 0x2ada, 1) -NAMED_CHARACTER_REFERENCE(1967, 't' _ 'o' _ 's' _ 'a' _ ';', 5, 0x2929, 1) -NAMED_CHARACTER_REFERENCE(1968, 't' _ 'p' _ 'r' _ 'i' _ 'm' _ 'e' _ ';', 7, 0x2034, 1) -NAMED_CHARACTER_REFERENCE(1969, 't' _ 'r' _ 'a' _ 'd' _ 'e' _ ';', 6, 0x2122, 1) -NAMED_CHARACTER_REFERENCE(1970, 't' _ 'r' _ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ ';', 9, 0x25b5, 1) -NAMED_CHARACTER_REFERENCE(1971, 't' _ 'r' _ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ 'd' _ 'o' _ 'w' _ 'n' _ ';', 13, 0x25bf, 1) -NAMED_CHARACTER_REFERENCE(1972, 't' _ 'r' _ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ 'l' _ 'e' _ 'f' _ 't' _ ';', 13, 0x25c3, 1) -NAMED_CHARACTER_REFERENCE(1973, 't' _ 'r' _ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ 'l' _ 'e' _ 'f' _ 't' _ 'e' _ 'q' _ ';', 15, 0x22b4, 1) -NAMED_CHARACTER_REFERENCE(1974, 't' _ 'r' _ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ 'q' _ ';', 10, 0x225c, 1) -NAMED_CHARACTER_REFERENCE(1975, 't' _ 'r' _ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ ';', 14, 0x25b9, 1) -NAMED_CHARACTER_REFERENCE(1976, 't' _ 'r' _ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ 'e' _ 'q' _ ';', 16, 0x22b5, 1) -NAMED_CHARACTER_REFERENCE(1977, 't' _ 'r' _ 'i' _ 'd' _ 'o' _ 't' _ ';', 7, 0x25ec, 1) -NAMED_CHARACTER_REFERENCE(1978, 't' _ 'r' _ 'i' _ 'e' _ ';', 5, 0x225c, 1) -NAMED_CHARACTER_REFERENCE(1979, 't' _ 'r' _ 'i' _ 'm' _ 'i' _ 'n' _ 'u' _ 's' _ ';', 9, 0x2a3a, 1) -NAMED_CHARACTER_REFERENCE(1980, 't' _ 'r' _ 'i' _ 'p' _ 'l' _ 'u' _ 's' _ ';', 8, 0x2a39, 1) -NAMED_CHARACTER_REFERENCE(1981, 't' _ 'r' _ 'i' _ 's' _ 'b' _ ';', 6, 0x29cd, 1) -NAMED_CHARACTER_REFERENCE(1982, 't' _ 'r' _ 'i' _ 't' _ 'i' _ 'm' _ 'e' _ ';', 8, 0x2a3b, 1) -NAMED_CHARACTER_REFERENCE(1983, 't' _ 'r' _ 'p' _ 'e' _ 'z' _ 'i' _ 'u' _ 'm' _ ';', 9, 0x23e2, 1) -NAMED_CHARACTER_REFERENCE(1984, 't' _ 's' _ 'c' _ 'r' _ ';', 5, 0xd835 _ 0xdcc9, 2) -NAMED_CHARACTER_REFERENCE(1985, 't' _ 's' _ 'c' _ 'y' _ ';', 5, 0x0446, 1) -NAMED_CHARACTER_REFERENCE(1986, 't' _ 's' _ 'h' _ 'c' _ 'y' _ ';', 6, 0x045b, 1) -NAMED_CHARACTER_REFERENCE(1987, 't' _ 's' _ 't' _ 'r' _ 'o' _ 'k' _ ';', 7, 0x0167, 1) -NAMED_CHARACTER_REFERENCE(1988, 't' _ 'w' _ 'i' _ 'x' _ 't' _ ';', 6, 0x226c, 1) -NAMED_CHARACTER_REFERENCE(1989, 't' _ 'w' _ 'o' _ 'h' _ 'e' _ 'a' _ 'd' _ 'l' _ 'e' _ 'f' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 17, 0x219e, 1) -NAMED_CHARACTER_REFERENCE(1990, 't' _ 'w' _ 'o' _ 'h' _ 'e' _ 'a' _ 'd' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 18, 0x21a0, 1) -NAMED_CHARACTER_REFERENCE(1991, 'u' _ 'A' _ 'r' _ 'r' _ ';', 5, 0x21d1, 1) -NAMED_CHARACTER_REFERENCE(1992, 'u' _ 'H' _ 'a' _ 'r' _ ';', 5, 0x2963, 1) -NAMED_CHARACTER_REFERENCE(1993, 'u' _ 'a' _ 'c' _ 'u' _ 't' _ 'e', 6, 0x00fa, 1) -NAMED_CHARACTER_REFERENCE(1994, 'u' _ 'a' _ 'c' _ 'u' _ 't' _ 'e' _ ';', 7, 0x00fa, 1) -NAMED_CHARACTER_REFERENCE(1995, 'u' _ 'a' _ 'r' _ 'r' _ ';', 5, 0x2191, 1) -NAMED_CHARACTER_REFERENCE(1996, 'u' _ 'b' _ 'r' _ 'c' _ 'y' _ ';', 6, 0x045e, 1) -NAMED_CHARACTER_REFERENCE(1997, 'u' _ 'b' _ 'r' _ 'e' _ 'v' _ 'e' _ ';', 7, 0x016d, 1) -NAMED_CHARACTER_REFERENCE(1998, 'u' _ 'c' _ 'i' _ 'r' _ 'c', 5, 0x00fb, 1) -NAMED_CHARACTER_REFERENCE(1999, 'u' _ 'c' _ 'i' _ 'r' _ 'c' _ ';', 6, 0x00fb, 1) -NAMED_CHARACTER_REFERENCE(2000, 'u' _ 'c' _ 'y' _ ';', 4, 0x0443, 1) -NAMED_CHARACTER_REFERENCE(2001, 'u' _ 'd' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x21c5, 1) -NAMED_CHARACTER_REFERENCE(2002, 'u' _ 'd' _ 'b' _ 'l' _ 'a' _ 'c' _ ';', 7, 0x0171, 1) -NAMED_CHARACTER_REFERENCE(2003, 'u' _ 'd' _ 'h' _ 'a' _ 'r' _ ';', 6, 0x296e, 1) -NAMED_CHARACTER_REFERENCE(2004, 'u' _ 'f' _ 'i' _ 's' _ 'h' _ 't' _ ';', 7, 0x297e, 1) -NAMED_CHARACTER_REFERENCE(2005, 'u' _ 'f' _ 'r' _ ';', 4, 0xd835 _ 0xdd32, 2) -NAMED_CHARACTER_REFERENCE(2006, 'u' _ 'g' _ 'r' _ 'a' _ 'v' _ 'e', 6, 0x00f9, 1) -NAMED_CHARACTER_REFERENCE(2007, 'u' _ 'g' _ 'r' _ 'a' _ 'v' _ 'e' _ ';', 7, 0x00f9, 1) -NAMED_CHARACTER_REFERENCE(2008, 'u' _ 'h' _ 'a' _ 'r' _ 'l' _ ';', 6, 0x21bf, 1) -NAMED_CHARACTER_REFERENCE(2009, 'u' _ 'h' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x21be, 1) -NAMED_CHARACTER_REFERENCE(2010, 'u' _ 'h' _ 'b' _ 'l' _ 'k' _ ';', 6, 0x2580, 1) -NAMED_CHARACTER_REFERENCE(2011, 'u' _ 'l' _ 'c' _ 'o' _ 'r' _ 'n' _ ';', 7, 0x231c, 1) -NAMED_CHARACTER_REFERENCE(2012, 'u' _ 'l' _ 'c' _ 'o' _ 'r' _ 'n' _ 'e' _ 'r' _ ';', 9, 0x231c, 1) -NAMED_CHARACTER_REFERENCE(2013, 'u' _ 'l' _ 'c' _ 'r' _ 'o' _ 'p' _ ';', 7, 0x230f, 1) -NAMED_CHARACTER_REFERENCE(2014, 'u' _ 'l' _ 't' _ 'r' _ 'i' _ ';', 6, 0x25f8, 1) -NAMED_CHARACTER_REFERENCE(2015, 'u' _ 'm' _ 'a' _ 'c' _ 'r' _ ';', 6, 0x016b, 1) -NAMED_CHARACTER_REFERENCE(2016, 'u' _ 'm' _ 'l', 3, 0x00a8, 1) -NAMED_CHARACTER_REFERENCE(2017, 'u' _ 'm' _ 'l' _ ';', 4, 0x00a8, 1) -NAMED_CHARACTER_REFERENCE(2018, 'u' _ 'o' _ 'g' _ 'o' _ 'n' _ ';', 6, 0x0173, 1) -NAMED_CHARACTER_REFERENCE(2019, 'u' _ 'o' _ 'p' _ 'f' _ ';', 5, 0xd835 _ 0xdd66, 2) -NAMED_CHARACTER_REFERENCE(2020, 'u' _ 'p' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 8, 0x2191, 1) -NAMED_CHARACTER_REFERENCE(2021, 'u' _ 'p' _ 'd' _ 'o' _ 'w' _ 'n' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 12, 0x2195, 1) -NAMED_CHARACTER_REFERENCE(2022, 'u' _ 'p' _ 'h' _ 'a' _ 'r' _ 'p' _ 'o' _ 'o' _ 'n' _ 'l' _ 'e' _ 'f' _ 't' _ ';', 14, 0x21bf, 1) -NAMED_CHARACTER_REFERENCE(2023, 'u' _ 'p' _ 'h' _ 'a' _ 'r' _ 'p' _ 'o' _ 'o' _ 'n' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ ';', 15, 0x21be, 1) -NAMED_CHARACTER_REFERENCE(2024, 'u' _ 'p' _ 'l' _ 'u' _ 's' _ ';', 6, 0x228e, 1) -NAMED_CHARACTER_REFERENCE(2025, 'u' _ 'p' _ 's' _ 'i' _ ';', 5, 0x03c5, 1) -NAMED_CHARACTER_REFERENCE(2026, 'u' _ 'p' _ 's' _ 'i' _ 'h' _ ';', 6, 0x03d2, 1) -NAMED_CHARACTER_REFERENCE(2027, 'u' _ 'p' _ 's' _ 'i' _ 'l' _ 'o' _ 'n' _ ';', 8, 0x03c5, 1) -NAMED_CHARACTER_REFERENCE(2028, 'u' _ 'p' _ 'u' _ 'p' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ 's' _ ';', 11, 0x21c8, 1) -NAMED_CHARACTER_REFERENCE(2029, 'u' _ 'r' _ 'c' _ 'o' _ 'r' _ 'n' _ ';', 7, 0x231d, 1) -NAMED_CHARACTER_REFERENCE(2030, 'u' _ 'r' _ 'c' _ 'o' _ 'r' _ 'n' _ 'e' _ 'r' _ ';', 9, 0x231d, 1) -NAMED_CHARACTER_REFERENCE(2031, 'u' _ 'r' _ 'c' _ 'r' _ 'o' _ 'p' _ ';', 7, 0x230e, 1) -NAMED_CHARACTER_REFERENCE(2032, 'u' _ 'r' _ 'i' _ 'n' _ 'g' _ ';', 6, 0x016f, 1) -NAMED_CHARACTER_REFERENCE(2033, 'u' _ 'r' _ 't' _ 'r' _ 'i' _ ';', 6, 0x25f9, 1) -NAMED_CHARACTER_REFERENCE(2034, 'u' _ 's' _ 'c' _ 'r' _ ';', 5, 0xd835 _ 0xdcca, 2) -NAMED_CHARACTER_REFERENCE(2035, 'u' _ 't' _ 'd' _ 'o' _ 't' _ ';', 6, 0x22f0, 1) -NAMED_CHARACTER_REFERENCE(2036, 'u' _ 't' _ 'i' _ 'l' _ 'd' _ 'e' _ ';', 7, 0x0169, 1) -NAMED_CHARACTER_REFERENCE(2037, 'u' _ 't' _ 'r' _ 'i' _ ';', 5, 0x25b5, 1) -NAMED_CHARACTER_REFERENCE(2038, 'u' _ 't' _ 'r' _ 'i' _ 'f' _ ';', 6, 0x25b4, 1) -NAMED_CHARACTER_REFERENCE(2039, 'u' _ 'u' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x21c8, 1) -NAMED_CHARACTER_REFERENCE(2040, 'u' _ 'u' _ 'm' _ 'l', 4, 0x00fc, 1) -NAMED_CHARACTER_REFERENCE(2041, 'u' _ 'u' _ 'm' _ 'l' _ ';', 5, 0x00fc, 1) -NAMED_CHARACTER_REFERENCE(2042, 'u' _ 'w' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ ';', 8, 0x29a7, 1) -NAMED_CHARACTER_REFERENCE(2043, 'v' _ 'A' _ 'r' _ 'r' _ ';', 5, 0x21d5, 1) -NAMED_CHARACTER_REFERENCE(2044, 'v' _ 'B' _ 'a' _ 'r' _ ';', 5, 0x2ae8, 1) -NAMED_CHARACTER_REFERENCE(2045, 'v' _ 'B' _ 'a' _ 'r' _ 'v' _ ';', 6, 0x2ae9, 1) -NAMED_CHARACTER_REFERENCE(2046, 'v' _ 'D' _ 'a' _ 's' _ 'h' _ ';', 6, 0x22a8, 1) -NAMED_CHARACTER_REFERENCE(2047, 'v' _ 'a' _ 'n' _ 'g' _ 'r' _ 't' _ ';', 7, 0x299c, 1) -NAMED_CHARACTER_REFERENCE(2048, 'v' _ 'a' _ 'r' _ 'e' _ 'p' _ 's' _ 'i' _ 'l' _ 'o' _ 'n' _ ';', 11, 0x03b5, 1) -NAMED_CHARACTER_REFERENCE(2049, 'v' _ 'a' _ 'r' _ 'k' _ 'a' _ 'p' _ 'p' _ 'a' _ ';', 9, 0x03f0, 1) -NAMED_CHARACTER_REFERENCE(2050, 'v' _ 'a' _ 'r' _ 'n' _ 'o' _ 't' _ 'h' _ 'i' _ 'n' _ 'g' _ ';', 11, 0x2205, 1) -NAMED_CHARACTER_REFERENCE(2051, 'v' _ 'a' _ 'r' _ 'p' _ 'h' _ 'i' _ ';', 7, 0x03c6, 1) -NAMED_CHARACTER_REFERENCE(2052, 'v' _ 'a' _ 'r' _ 'p' _ 'i' _ ';', 6, 0x03d6, 1) -NAMED_CHARACTER_REFERENCE(2053, 'v' _ 'a' _ 'r' _ 'p' _ 'r' _ 'o' _ 'p' _ 't' _ 'o' _ ';', 10, 0x221d, 1) -NAMED_CHARACTER_REFERENCE(2054, 'v' _ 'a' _ 'r' _ 'r' _ ';', 5, 0x2195, 1) -NAMED_CHARACTER_REFERENCE(2055, 'v' _ 'a' _ 'r' _ 'r' _ 'h' _ 'o' _ ';', 7, 0x03f1, 1) -NAMED_CHARACTER_REFERENCE(2056, 'v' _ 'a' _ 'r' _ 's' _ 'i' _ 'g' _ 'm' _ 'a' _ ';', 9, 0x03c2, 1) -NAMED_CHARACTER_REFERENCE(2057, 'v' _ 'a' _ 'r' _ 't' _ 'h' _ 'e' _ 't' _ 'a' _ ';', 9, 0x03d1, 1) -NAMED_CHARACTER_REFERENCE(2058, 'v' _ 'a' _ 'r' _ 't' _ 'r' _ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ 'l' _ 'e' _ 'f' _ 't' _ ';', 16, 0x22b2, 1) -NAMED_CHARACTER_REFERENCE(2059, 'v' _ 'a' _ 'r' _ 't' _ 'r' _ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ ';', 17, 0x22b3, 1) -NAMED_CHARACTER_REFERENCE(2060, 'v' _ 'c' _ 'y' _ ';', 4, 0x0432, 1) -NAMED_CHARACTER_REFERENCE(2061, 'v' _ 'd' _ 'a' _ 's' _ 'h' _ ';', 6, 0x22a2, 1) -NAMED_CHARACTER_REFERENCE(2062, 'v' _ 'e' _ 'e' _ ';', 4, 0x2228, 1) -NAMED_CHARACTER_REFERENCE(2063, 'v' _ 'e' _ 'e' _ 'b' _ 'a' _ 'r' _ ';', 7, 0x22bb, 1) -NAMED_CHARACTER_REFERENCE(2064, 'v' _ 'e' _ 'e' _ 'e' _ 'q' _ ';', 6, 0x225a, 1) -NAMED_CHARACTER_REFERENCE(2065, 'v' _ 'e' _ 'l' _ 'l' _ 'i' _ 'p' _ ';', 7, 0x22ee, 1) -NAMED_CHARACTER_REFERENCE(2066, 'v' _ 'e' _ 'r' _ 'b' _ 'a' _ 'r' _ ';', 7, 0x007c, 1) -NAMED_CHARACTER_REFERENCE(2067, 'v' _ 'e' _ 'r' _ 't' _ ';', 5, 0x007c, 1) -NAMED_CHARACTER_REFERENCE(2068, 'v' _ 'f' _ 'r' _ ';', 4, 0xd835 _ 0xdd33, 2) -NAMED_CHARACTER_REFERENCE(2069, 'v' _ 'l' _ 't' _ 'r' _ 'i' _ ';', 6, 0x22b2, 1) -NAMED_CHARACTER_REFERENCE(2070, 'v' _ 'o' _ 'p' _ 'f' _ ';', 5, 0xd835 _ 0xdd67, 2) -NAMED_CHARACTER_REFERENCE(2071, 'v' _ 'p' _ 'r' _ 'o' _ 'p' _ ';', 6, 0x221d, 1) -NAMED_CHARACTER_REFERENCE(2072, 'v' _ 'r' _ 't' _ 'r' _ 'i' _ ';', 6, 0x22b3, 1) -NAMED_CHARACTER_REFERENCE(2073, 'v' _ 's' _ 'c' _ 'r' _ ';', 5, 0xd835 _ 0xdccb, 2) -NAMED_CHARACTER_REFERENCE(2074, 'v' _ 'z' _ 'i' _ 'g' _ 'z' _ 'a' _ 'g' _ ';', 8, 0x299a, 1) -NAMED_CHARACTER_REFERENCE(2075, 'w' _ 'c' _ 'i' _ 'r' _ 'c' _ ';', 6, 0x0175, 1) -NAMED_CHARACTER_REFERENCE(2076, 'w' _ 'e' _ 'd' _ 'b' _ 'a' _ 'r' _ ';', 7, 0x2a5f, 1) -NAMED_CHARACTER_REFERENCE(2077, 'w' _ 'e' _ 'd' _ 'g' _ 'e' _ ';', 6, 0x2227, 1) -NAMED_CHARACTER_REFERENCE(2078, 'w' _ 'e' _ 'd' _ 'g' _ 'e' _ 'q' _ ';', 7, 0x2259, 1) -NAMED_CHARACTER_REFERENCE(2079, 'w' _ 'e' _ 'i' _ 'e' _ 'r' _ 'p' _ ';', 7, 0x2118, 1) -NAMED_CHARACTER_REFERENCE(2080, 'w' _ 'f' _ 'r' _ ';', 4, 0xd835 _ 0xdd34, 2) -NAMED_CHARACTER_REFERENCE(2081, 'w' _ 'o' _ 'p' _ 'f' _ ';', 5, 0xd835 _ 0xdd68, 2) -NAMED_CHARACTER_REFERENCE(2082, 'w' _ 'p' _ ';', 3, 0x2118, 1) -NAMED_CHARACTER_REFERENCE(2083, 'w' _ 'r' _ ';', 3, 0x2240, 1) -NAMED_CHARACTER_REFERENCE(2084, 'w' _ 'r' _ 'e' _ 'a' _ 't' _ 'h' _ ';', 7, 0x2240, 1) -NAMED_CHARACTER_REFERENCE(2085, 'w' _ 's' _ 'c' _ 'r' _ ';', 5, 0xd835 _ 0xdccc, 2) -NAMED_CHARACTER_REFERENCE(2086, 'x' _ 'c' _ 'a' _ 'p' _ ';', 5, 0x22c2, 1) -NAMED_CHARACTER_REFERENCE(2087, 'x' _ 'c' _ 'i' _ 'r' _ 'c' _ ';', 6, 0x25ef, 1) -NAMED_CHARACTER_REFERENCE(2088, 'x' _ 'c' _ 'u' _ 'p' _ ';', 5, 0x22c3, 1) -NAMED_CHARACTER_REFERENCE(2089, 'x' _ 'd' _ 't' _ 'r' _ 'i' _ ';', 6, 0x25bd, 1) -NAMED_CHARACTER_REFERENCE(2090, 'x' _ 'f' _ 'r' _ ';', 4, 0xd835 _ 0xdd35, 2) -NAMED_CHARACTER_REFERENCE(2091, 'x' _ 'h' _ 'A' _ 'r' _ 'r' _ ';', 6, 0x27fa, 1) -NAMED_CHARACTER_REFERENCE(2092, 'x' _ 'h' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x27f7, 1) -NAMED_CHARACTER_REFERENCE(2093, 'x' _ 'i' _ ';', 3, 0x03be, 1) -NAMED_CHARACTER_REFERENCE(2094, 'x' _ 'l' _ 'A' _ 'r' _ 'r' _ ';', 6, 0x27f8, 1) -NAMED_CHARACTER_REFERENCE(2095, 'x' _ 'l' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x27f5, 1) -NAMED_CHARACTER_REFERENCE(2096, 'x' _ 'm' _ 'a' _ 'p' _ ';', 5, 0x27fc, 1) -NAMED_CHARACTER_REFERENCE(2097, 'x' _ 'n' _ 'i' _ 's' _ ';', 5, 0x22fb, 1) -NAMED_CHARACTER_REFERENCE(2098, 'x' _ 'o' _ 'd' _ 'o' _ 't' _ ';', 6, 0x2a00, 1) -NAMED_CHARACTER_REFERENCE(2099, 'x' _ 'o' _ 'p' _ 'f' _ ';', 5, 0xd835 _ 0xdd69, 2) -NAMED_CHARACTER_REFERENCE(2100, 'x' _ 'o' _ 'p' _ 'l' _ 'u' _ 's' _ ';', 7, 0x2a01, 1) -NAMED_CHARACTER_REFERENCE(2101, 'x' _ 'o' _ 't' _ 'i' _ 'm' _ 'e' _ ';', 7, 0x2a02, 1) -NAMED_CHARACTER_REFERENCE(2102, 'x' _ 'r' _ 'A' _ 'r' _ 'r' _ ';', 6, 0x27f9, 1) -NAMED_CHARACTER_REFERENCE(2103, 'x' _ 'r' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x27f6, 1) -NAMED_CHARACTER_REFERENCE(2104, 'x' _ 's' _ 'c' _ 'r' _ ';', 5, 0xd835 _ 0xdccd, 2) -NAMED_CHARACTER_REFERENCE(2105, 'x' _ 's' _ 'q' _ 'c' _ 'u' _ 'p' _ ';', 7, 0x2a06, 1) -NAMED_CHARACTER_REFERENCE(2106, 'x' _ 'u' _ 'p' _ 'l' _ 'u' _ 's' _ ';', 7, 0x2a04, 1) -NAMED_CHARACTER_REFERENCE(2107, 'x' _ 'u' _ 't' _ 'r' _ 'i' _ ';', 6, 0x25b3, 1) -NAMED_CHARACTER_REFERENCE(2108, 'x' _ 'v' _ 'e' _ 'e' _ ';', 5, 0x22c1, 1) -NAMED_CHARACTER_REFERENCE(2109, 'x' _ 'w' _ 'e' _ 'd' _ 'g' _ 'e' _ ';', 7, 0x22c0, 1) -NAMED_CHARACTER_REFERENCE(2110, 'y' _ 'a' _ 'c' _ 'u' _ 't' _ 'e', 6, 0x00fd, 1) -NAMED_CHARACTER_REFERENCE(2111, 'y' _ 'a' _ 'c' _ 'u' _ 't' _ 'e' _ ';', 7, 0x00fd, 1) -NAMED_CHARACTER_REFERENCE(2112, 'y' _ 'a' _ 'c' _ 'y' _ ';', 5, 0x044f, 1) -NAMED_CHARACTER_REFERENCE(2113, 'y' _ 'c' _ 'i' _ 'r' _ 'c' _ ';', 6, 0x0177, 1) -NAMED_CHARACTER_REFERENCE(2114, 'y' _ 'c' _ 'y' _ ';', 4, 0x044b, 1) -NAMED_CHARACTER_REFERENCE(2115, 'y' _ 'e' _ 'n', 3, 0x00a5, 1) -NAMED_CHARACTER_REFERENCE(2116, 'y' _ 'e' _ 'n' _ ';', 4, 0x00a5, 1) -NAMED_CHARACTER_REFERENCE(2117, 'y' _ 'f' _ 'r' _ ';', 4, 0xd835 _ 0xdd36, 2) -NAMED_CHARACTER_REFERENCE(2118, 'y' _ 'i' _ 'c' _ 'y' _ ';', 5, 0x0457, 1) -NAMED_CHARACTER_REFERENCE(2119, 'y' _ 'o' _ 'p' _ 'f' _ ';', 5, 0xd835 _ 0xdd6a, 2) -NAMED_CHARACTER_REFERENCE(2120, 'y' _ 's' _ 'c' _ 'r' _ ';', 5, 0xd835 _ 0xdcce, 2) -NAMED_CHARACTER_REFERENCE(2121, 'y' _ 'u' _ 'c' _ 'y' _ ';', 5, 0x044e, 1) -NAMED_CHARACTER_REFERENCE(2122, 'y' _ 'u' _ 'm' _ 'l', 4, 0x00ff, 1) -NAMED_CHARACTER_REFERENCE(2123, 'y' _ 'u' _ 'm' _ 'l' _ ';', 5, 0x00ff, 1) -NAMED_CHARACTER_REFERENCE(2124, 'z' _ 'a' _ 'c' _ 'u' _ 't' _ 'e' _ ';', 7, 0x017a, 1) -NAMED_CHARACTER_REFERENCE(2125, 'z' _ 'c' _ 'a' _ 'r' _ 'o' _ 'n' _ ';', 7, 0x017e, 1) -NAMED_CHARACTER_REFERENCE(2126, 'z' _ 'c' _ 'y' _ ';', 4, 0x0437, 1) -NAMED_CHARACTER_REFERENCE(2127, 'z' _ 'd' _ 'o' _ 't' _ ';', 5, 0x017c, 1) -NAMED_CHARACTER_REFERENCE(2128, 'z' _ 'e' _ 'e' _ 't' _ 'r' _ 'f' _ ';', 7, 0x2128, 1) -NAMED_CHARACTER_REFERENCE(2129, 'z' _ 'e' _ 't' _ 'a' _ ';', 5, 0x03b6, 1) -NAMED_CHARACTER_REFERENCE(2130, 'z' _ 'f' _ 'r' _ ';', 4, 0xd835 _ 0xdd37, 2) -NAMED_CHARACTER_REFERENCE(2131, 'z' _ 'h' _ 'c' _ 'y' _ ';', 5, 0x0436, 1) -NAMED_CHARACTER_REFERENCE(2132, 'z' _ 'i' _ 'g' _ 'r' _ 'a' _ 'r' _ 'r' _ ';', 8, 0x21dd, 1) -NAMED_CHARACTER_REFERENCE(2133, 'z' _ 'o' _ 'p' _ 'f' _ ';', 5, 0xd835 _ 0xdd6b, 2) -NAMED_CHARACTER_REFERENCE(2134, 'z' _ 's' _ 'c' _ 'r' _ ';', 5, 0xd835 _ 0xdccf, 2) -NAMED_CHARACTER_REFERENCE(2135, 'z' _ 'w' _ 'j' _ ';', 4, 0x200d, 1) -NAMED_CHARACTER_REFERENCE(2136, 'z' _ 'w' _ 'n' _ 'j' _ ';', 5, 0x200c, 1) +NAMED_CHARACTER_REFERENCE(1912, 's' _ 'u' _ 'p' _ 'h' _ 's' _ 'o' _ 'l' _ ';', 8, 0x27c9, 1) +NAMED_CHARACTER_REFERENCE(1913, 's' _ 'u' _ 'p' _ 'h' _ 's' _ 'u' _ 'b' _ ';', 8, 0x2ad7, 1) +NAMED_CHARACTER_REFERENCE(1914, 's' _ 'u' _ 'p' _ 'l' _ 'a' _ 'r' _ 'r' _ ';', 8, 0x297b, 1) +NAMED_CHARACTER_REFERENCE(1915, 's' _ 'u' _ 'p' _ 'm' _ 'u' _ 'l' _ 't' _ ';', 8, 0x2ac2, 1) +NAMED_CHARACTER_REFERENCE(1916, 's' _ 'u' _ 'p' _ 'n' _ 'E' _ ';', 6, 0x2acc, 1) +NAMED_CHARACTER_REFERENCE(1917, 's' _ 'u' _ 'p' _ 'n' _ 'e' _ ';', 6, 0x228b, 1) +NAMED_CHARACTER_REFERENCE(1918, 's' _ 'u' _ 'p' _ 'p' _ 'l' _ 'u' _ 's' _ ';', 8, 0x2ac0, 1) +NAMED_CHARACTER_REFERENCE(1919, 's' _ 'u' _ 'p' _ 's' _ 'e' _ 't' _ ';', 7, 0x2283, 1) +NAMED_CHARACTER_REFERENCE(1920, 's' _ 'u' _ 'p' _ 's' _ 'e' _ 't' _ 'e' _ 'q' _ ';', 9, 0x2287, 1) +NAMED_CHARACTER_REFERENCE(1921, 's' _ 'u' _ 'p' _ 's' _ 'e' _ 't' _ 'e' _ 'q' _ 'q' _ ';', 10, 0x2ac6, 1) +NAMED_CHARACTER_REFERENCE(1922, 's' _ 'u' _ 'p' _ 's' _ 'e' _ 't' _ 'n' _ 'e' _ 'q' _ ';', 10, 0x228b, 1) +NAMED_CHARACTER_REFERENCE(1923, 's' _ 'u' _ 'p' _ 's' _ 'e' _ 't' _ 'n' _ 'e' _ 'q' _ 'q' _ ';', 11, 0x2acc, 1) +NAMED_CHARACTER_REFERENCE(1924, 's' _ 'u' _ 'p' _ 's' _ 'i' _ 'm' _ ';', 7, 0x2ac8, 1) +NAMED_CHARACTER_REFERENCE(1925, 's' _ 'u' _ 'p' _ 's' _ 'u' _ 'b' _ ';', 7, 0x2ad4, 1) +NAMED_CHARACTER_REFERENCE(1926, 's' _ 'u' _ 'p' _ 's' _ 'u' _ 'p' _ ';', 7, 0x2ad6, 1) +NAMED_CHARACTER_REFERENCE(1927, 's' _ 'w' _ 'A' _ 'r' _ 'r' _ ';', 6, 0x21d9, 1) +NAMED_CHARACTER_REFERENCE(1928, 's' _ 'w' _ 'a' _ 'r' _ 'h' _ 'k' _ ';', 7, 0x2926, 1) +NAMED_CHARACTER_REFERENCE(1929, 's' _ 'w' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x2199, 1) +NAMED_CHARACTER_REFERENCE(1930, 's' _ 'w' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 8, 0x2199, 1) +NAMED_CHARACTER_REFERENCE(1931, 's' _ 'w' _ 'n' _ 'w' _ 'a' _ 'r' _ ';', 7, 0x292a, 1) +NAMED_CHARACTER_REFERENCE(1932, 's' _ 'z' _ 'l' _ 'i' _ 'g', 5, 0x00df, 1) +NAMED_CHARACTER_REFERENCE(1933, 's' _ 'z' _ 'l' _ 'i' _ 'g' _ ';', 6, 0x00df, 1) +NAMED_CHARACTER_REFERENCE(1934, 't' _ 'a' _ 'r' _ 'g' _ 'e' _ 't' _ ';', 7, 0x2316, 1) +NAMED_CHARACTER_REFERENCE(1935, 't' _ 'a' _ 'u' _ ';', 4, 0x03c4, 1) +NAMED_CHARACTER_REFERENCE(1936, 't' _ 'b' _ 'r' _ 'k' _ ';', 5, 0x23b4, 1) +NAMED_CHARACTER_REFERENCE(1937, 't' _ 'c' _ 'a' _ 'r' _ 'o' _ 'n' _ ';', 7, 0x0165, 1) +NAMED_CHARACTER_REFERENCE(1938, 't' _ 'c' _ 'e' _ 'd' _ 'i' _ 'l' _ ';', 7, 0x0163, 1) +NAMED_CHARACTER_REFERENCE(1939, 't' _ 'c' _ 'y' _ ';', 4, 0x0442, 1) +NAMED_CHARACTER_REFERENCE(1940, 't' _ 'd' _ 'o' _ 't' _ ';', 5, 0x20db, 1) +NAMED_CHARACTER_REFERENCE(1941, 't' _ 'e' _ 'l' _ 'r' _ 'e' _ 'c' _ ';', 7, 0x2315, 1) +NAMED_CHARACTER_REFERENCE(1942, 't' _ 'f' _ 'r' _ ';', 4, 0xd835 _ 0xdd31, 2) +NAMED_CHARACTER_REFERENCE(1943, 't' _ 'h' _ 'e' _ 'r' _ 'e' _ '4' _ ';', 7, 0x2234, 1) +NAMED_CHARACTER_REFERENCE(1944, 't' _ 'h' _ 'e' _ 'r' _ 'e' _ 'f' _ 'o' _ 'r' _ 'e' _ ';', 10, 0x2234, 1) +NAMED_CHARACTER_REFERENCE(1945, 't' _ 'h' _ 'e' _ 't' _ 'a' _ ';', 6, 0x03b8, 1) +NAMED_CHARACTER_REFERENCE(1946, 't' _ 'h' _ 'e' _ 't' _ 'a' _ 's' _ 'y' _ 'm' _ ';', 9, 0x03d1, 1) +NAMED_CHARACTER_REFERENCE(1947, 't' _ 'h' _ 'e' _ 't' _ 'a' _ 'v' _ ';', 7, 0x03d1, 1) +NAMED_CHARACTER_REFERENCE(1948, 't' _ 'h' _ 'i' _ 'c' _ 'k' _ 'a' _ 'p' _ 'p' _ 'r' _ 'o' _ 'x' _ ';', 12, 0x2248, 1) +NAMED_CHARACTER_REFERENCE(1949, 't' _ 'h' _ 'i' _ 'c' _ 'k' _ 's' _ 'i' _ 'm' _ ';', 9, 0x223c, 1) +NAMED_CHARACTER_REFERENCE(1950, 't' _ 'h' _ 'i' _ 'n' _ 's' _ 'p' _ ';', 7, 0x2009, 1) +NAMED_CHARACTER_REFERENCE(1951, 't' _ 'h' _ 'k' _ 'a' _ 'p' _ ';', 6, 0x2248, 1) +NAMED_CHARACTER_REFERENCE(1952, 't' _ 'h' _ 'k' _ 's' _ 'i' _ 'm' _ ';', 7, 0x223c, 1) +NAMED_CHARACTER_REFERENCE(1953, 't' _ 'h' _ 'o' _ 'r' _ 'n', 5, 0x00fe, 1) +NAMED_CHARACTER_REFERENCE(1954, 't' _ 'h' _ 'o' _ 'r' _ 'n' _ ';', 6, 0x00fe, 1) +NAMED_CHARACTER_REFERENCE(1955, 't' _ 'i' _ 'l' _ 'd' _ 'e' _ ';', 6, 0x02dc, 1) +NAMED_CHARACTER_REFERENCE(1956, 't' _ 'i' _ 'm' _ 'e' _ 's', 5, 0x00d7, 1) +NAMED_CHARACTER_REFERENCE(1957, 't' _ 'i' _ 'm' _ 'e' _ 's' _ ';', 6, 0x00d7, 1) +NAMED_CHARACTER_REFERENCE(1958, 't' _ 'i' _ 'm' _ 'e' _ 's' _ 'b' _ ';', 7, 0x22a0, 1) +NAMED_CHARACTER_REFERENCE(1959, 't' _ 'i' _ 'm' _ 'e' _ 's' _ 'b' _ 'a' _ 'r' _ ';', 9, 0x2a31, 1) +NAMED_CHARACTER_REFERENCE(1960, 't' _ 'i' _ 'm' _ 'e' _ 's' _ 'd' _ ';', 7, 0x2a30, 1) +NAMED_CHARACTER_REFERENCE(1961, 't' _ 'i' _ 'n' _ 't' _ ';', 5, 0x222d, 1) +NAMED_CHARACTER_REFERENCE(1962, 't' _ 'o' _ 'e' _ 'a' _ ';', 5, 0x2928, 1) +NAMED_CHARACTER_REFERENCE(1963, 't' _ 'o' _ 'p' _ ';', 4, 0x22a4, 1) +NAMED_CHARACTER_REFERENCE(1964, 't' _ 'o' _ 'p' _ 'b' _ 'o' _ 't' _ ';', 7, 0x2336, 1) +NAMED_CHARACTER_REFERENCE(1965, 't' _ 'o' _ 'p' _ 'c' _ 'i' _ 'r' _ ';', 7, 0x2af1, 1) +NAMED_CHARACTER_REFERENCE(1966, 't' _ 'o' _ 'p' _ 'f' _ ';', 5, 0xd835 _ 0xdd65, 2) +NAMED_CHARACTER_REFERENCE(1967, 't' _ 'o' _ 'p' _ 'f' _ 'o' _ 'r' _ 'k' _ ';', 8, 0x2ada, 1) +NAMED_CHARACTER_REFERENCE(1968, 't' _ 'o' _ 's' _ 'a' _ ';', 5, 0x2929, 1) +NAMED_CHARACTER_REFERENCE(1969, 't' _ 'p' _ 'r' _ 'i' _ 'm' _ 'e' _ ';', 7, 0x2034, 1) +NAMED_CHARACTER_REFERENCE(1970, 't' _ 'r' _ 'a' _ 'd' _ 'e' _ ';', 6, 0x2122, 1) +NAMED_CHARACTER_REFERENCE(1971, 't' _ 'r' _ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ ';', 9, 0x25b5, 1) +NAMED_CHARACTER_REFERENCE(1972, 't' _ 'r' _ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ 'd' _ 'o' _ 'w' _ 'n' _ ';', 13, 0x25bf, 1) +NAMED_CHARACTER_REFERENCE(1973, 't' _ 'r' _ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ 'l' _ 'e' _ 'f' _ 't' _ ';', 13, 0x25c3, 1) +NAMED_CHARACTER_REFERENCE(1974, 't' _ 'r' _ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ 'l' _ 'e' _ 'f' _ 't' _ 'e' _ 'q' _ ';', 15, 0x22b4, 1) +NAMED_CHARACTER_REFERENCE(1975, 't' _ 'r' _ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ 'q' _ ';', 10, 0x225c, 1) +NAMED_CHARACTER_REFERENCE(1976, 't' _ 'r' _ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ ';', 14, 0x25b9, 1) +NAMED_CHARACTER_REFERENCE(1977, 't' _ 'r' _ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ 'e' _ 'q' _ ';', 16, 0x22b5, 1) +NAMED_CHARACTER_REFERENCE(1978, 't' _ 'r' _ 'i' _ 'd' _ 'o' _ 't' _ ';', 7, 0x25ec, 1) +NAMED_CHARACTER_REFERENCE(1979, 't' _ 'r' _ 'i' _ 'e' _ ';', 5, 0x225c, 1) +NAMED_CHARACTER_REFERENCE(1980, 't' _ 'r' _ 'i' _ 'm' _ 'i' _ 'n' _ 'u' _ 's' _ ';', 9, 0x2a3a, 1) +NAMED_CHARACTER_REFERENCE(1981, 't' _ 'r' _ 'i' _ 'p' _ 'l' _ 'u' _ 's' _ ';', 8, 0x2a39, 1) +NAMED_CHARACTER_REFERENCE(1982, 't' _ 'r' _ 'i' _ 's' _ 'b' _ ';', 6, 0x29cd, 1) +NAMED_CHARACTER_REFERENCE(1983, 't' _ 'r' _ 'i' _ 't' _ 'i' _ 'm' _ 'e' _ ';', 8, 0x2a3b, 1) +NAMED_CHARACTER_REFERENCE(1984, 't' _ 'r' _ 'p' _ 'e' _ 'z' _ 'i' _ 'u' _ 'm' _ ';', 9, 0x23e2, 1) +NAMED_CHARACTER_REFERENCE(1985, 't' _ 's' _ 'c' _ 'r' _ ';', 5, 0xd835 _ 0xdcc9, 2) +NAMED_CHARACTER_REFERENCE(1986, 't' _ 's' _ 'c' _ 'y' _ ';', 5, 0x0446, 1) +NAMED_CHARACTER_REFERENCE(1987, 't' _ 's' _ 'h' _ 'c' _ 'y' _ ';', 6, 0x045b, 1) +NAMED_CHARACTER_REFERENCE(1988, 't' _ 's' _ 't' _ 'r' _ 'o' _ 'k' _ ';', 7, 0x0167, 1) +NAMED_CHARACTER_REFERENCE(1989, 't' _ 'w' _ 'i' _ 'x' _ 't' _ ';', 6, 0x226c, 1) +NAMED_CHARACTER_REFERENCE(1990, 't' _ 'w' _ 'o' _ 'h' _ 'e' _ 'a' _ 'd' _ 'l' _ 'e' _ 'f' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 17, 0x219e, 1) +NAMED_CHARACTER_REFERENCE(1991, 't' _ 'w' _ 'o' _ 'h' _ 'e' _ 'a' _ 'd' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 18, 0x21a0, 1) +NAMED_CHARACTER_REFERENCE(1992, 'u' _ 'A' _ 'r' _ 'r' _ ';', 5, 0x21d1, 1) +NAMED_CHARACTER_REFERENCE(1993, 'u' _ 'H' _ 'a' _ 'r' _ ';', 5, 0x2963, 1) +NAMED_CHARACTER_REFERENCE(1994, 'u' _ 'a' _ 'c' _ 'u' _ 't' _ 'e', 6, 0x00fa, 1) +NAMED_CHARACTER_REFERENCE(1995, 'u' _ 'a' _ 'c' _ 'u' _ 't' _ 'e' _ ';', 7, 0x00fa, 1) +NAMED_CHARACTER_REFERENCE(1996, 'u' _ 'a' _ 'r' _ 'r' _ ';', 5, 0x2191, 1) +NAMED_CHARACTER_REFERENCE(1997, 'u' _ 'b' _ 'r' _ 'c' _ 'y' _ ';', 6, 0x045e, 1) +NAMED_CHARACTER_REFERENCE(1998, 'u' _ 'b' _ 'r' _ 'e' _ 'v' _ 'e' _ ';', 7, 0x016d, 1) +NAMED_CHARACTER_REFERENCE(1999, 'u' _ 'c' _ 'i' _ 'r' _ 'c', 5, 0x00fb, 1) +NAMED_CHARACTER_REFERENCE(2000, 'u' _ 'c' _ 'i' _ 'r' _ 'c' _ ';', 6, 0x00fb, 1) +NAMED_CHARACTER_REFERENCE(2001, 'u' _ 'c' _ 'y' _ ';', 4, 0x0443, 1) +NAMED_CHARACTER_REFERENCE(2002, 'u' _ 'd' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x21c5, 1) +NAMED_CHARACTER_REFERENCE(2003, 'u' _ 'd' _ 'b' _ 'l' _ 'a' _ 'c' _ ';', 7, 0x0171, 1) +NAMED_CHARACTER_REFERENCE(2004, 'u' _ 'd' _ 'h' _ 'a' _ 'r' _ ';', 6, 0x296e, 1) +NAMED_CHARACTER_REFERENCE(2005, 'u' _ 'f' _ 'i' _ 's' _ 'h' _ 't' _ ';', 7, 0x297e, 1) +NAMED_CHARACTER_REFERENCE(2006, 'u' _ 'f' _ 'r' _ ';', 4, 0xd835 _ 0xdd32, 2) +NAMED_CHARACTER_REFERENCE(2007, 'u' _ 'g' _ 'r' _ 'a' _ 'v' _ 'e', 6, 0x00f9, 1) +NAMED_CHARACTER_REFERENCE(2008, 'u' _ 'g' _ 'r' _ 'a' _ 'v' _ 'e' _ ';', 7, 0x00f9, 1) +NAMED_CHARACTER_REFERENCE(2009, 'u' _ 'h' _ 'a' _ 'r' _ 'l' _ ';', 6, 0x21bf, 1) +NAMED_CHARACTER_REFERENCE(2010, 'u' _ 'h' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x21be, 1) +NAMED_CHARACTER_REFERENCE(2011, 'u' _ 'h' _ 'b' _ 'l' _ 'k' _ ';', 6, 0x2580, 1) +NAMED_CHARACTER_REFERENCE(2012, 'u' _ 'l' _ 'c' _ 'o' _ 'r' _ 'n' _ ';', 7, 0x231c, 1) +NAMED_CHARACTER_REFERENCE(2013, 'u' _ 'l' _ 'c' _ 'o' _ 'r' _ 'n' _ 'e' _ 'r' _ ';', 9, 0x231c, 1) +NAMED_CHARACTER_REFERENCE(2014, 'u' _ 'l' _ 'c' _ 'r' _ 'o' _ 'p' _ ';', 7, 0x230f, 1) +NAMED_CHARACTER_REFERENCE(2015, 'u' _ 'l' _ 't' _ 'r' _ 'i' _ ';', 6, 0x25f8, 1) +NAMED_CHARACTER_REFERENCE(2016, 'u' _ 'm' _ 'a' _ 'c' _ 'r' _ ';', 6, 0x016b, 1) +NAMED_CHARACTER_REFERENCE(2017, 'u' _ 'm' _ 'l', 3, 0x00a8, 1) +NAMED_CHARACTER_REFERENCE(2018, 'u' _ 'm' _ 'l' _ ';', 4, 0x00a8, 1) +NAMED_CHARACTER_REFERENCE(2019, 'u' _ 'o' _ 'g' _ 'o' _ 'n' _ ';', 6, 0x0173, 1) +NAMED_CHARACTER_REFERENCE(2020, 'u' _ 'o' _ 'p' _ 'f' _ ';', 5, 0xd835 _ 0xdd66, 2) +NAMED_CHARACTER_REFERENCE(2021, 'u' _ 'p' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 8, 0x2191, 1) +NAMED_CHARACTER_REFERENCE(2022, 'u' _ 'p' _ 'd' _ 'o' _ 'w' _ 'n' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ ';', 12, 0x2195, 1) +NAMED_CHARACTER_REFERENCE(2023, 'u' _ 'p' _ 'h' _ 'a' _ 'r' _ 'p' _ 'o' _ 'o' _ 'n' _ 'l' _ 'e' _ 'f' _ 't' _ ';', 14, 0x21bf, 1) +NAMED_CHARACTER_REFERENCE(2024, 'u' _ 'p' _ 'h' _ 'a' _ 'r' _ 'p' _ 'o' _ 'o' _ 'n' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ ';', 15, 0x21be, 1) +NAMED_CHARACTER_REFERENCE(2025, 'u' _ 'p' _ 'l' _ 'u' _ 's' _ ';', 6, 0x228e, 1) +NAMED_CHARACTER_REFERENCE(2026, 'u' _ 'p' _ 's' _ 'i' _ ';', 5, 0x03c5, 1) +NAMED_CHARACTER_REFERENCE(2027, 'u' _ 'p' _ 's' _ 'i' _ 'h' _ ';', 6, 0x03d2, 1) +NAMED_CHARACTER_REFERENCE(2028, 'u' _ 'p' _ 's' _ 'i' _ 'l' _ 'o' _ 'n' _ ';', 8, 0x03c5, 1) +NAMED_CHARACTER_REFERENCE(2029, 'u' _ 'p' _ 'u' _ 'p' _ 'a' _ 'r' _ 'r' _ 'o' _ 'w' _ 's' _ ';', 11, 0x21c8, 1) +NAMED_CHARACTER_REFERENCE(2030, 'u' _ 'r' _ 'c' _ 'o' _ 'r' _ 'n' _ ';', 7, 0x231d, 1) +NAMED_CHARACTER_REFERENCE(2031, 'u' _ 'r' _ 'c' _ 'o' _ 'r' _ 'n' _ 'e' _ 'r' _ ';', 9, 0x231d, 1) +NAMED_CHARACTER_REFERENCE(2032, 'u' _ 'r' _ 'c' _ 'r' _ 'o' _ 'p' _ ';', 7, 0x230e, 1) +NAMED_CHARACTER_REFERENCE(2033, 'u' _ 'r' _ 'i' _ 'n' _ 'g' _ ';', 6, 0x016f, 1) +NAMED_CHARACTER_REFERENCE(2034, 'u' _ 'r' _ 't' _ 'r' _ 'i' _ ';', 6, 0x25f9, 1) +NAMED_CHARACTER_REFERENCE(2035, 'u' _ 's' _ 'c' _ 'r' _ ';', 5, 0xd835 _ 0xdcca, 2) +NAMED_CHARACTER_REFERENCE(2036, 'u' _ 't' _ 'd' _ 'o' _ 't' _ ';', 6, 0x22f0, 1) +NAMED_CHARACTER_REFERENCE(2037, 'u' _ 't' _ 'i' _ 'l' _ 'd' _ 'e' _ ';', 7, 0x0169, 1) +NAMED_CHARACTER_REFERENCE(2038, 'u' _ 't' _ 'r' _ 'i' _ ';', 5, 0x25b5, 1) +NAMED_CHARACTER_REFERENCE(2039, 'u' _ 't' _ 'r' _ 'i' _ 'f' _ ';', 6, 0x25b4, 1) +NAMED_CHARACTER_REFERENCE(2040, 'u' _ 'u' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x21c8, 1) +NAMED_CHARACTER_REFERENCE(2041, 'u' _ 'u' _ 'm' _ 'l', 4, 0x00fc, 1) +NAMED_CHARACTER_REFERENCE(2042, 'u' _ 'u' _ 'm' _ 'l' _ ';', 5, 0x00fc, 1) +NAMED_CHARACTER_REFERENCE(2043, 'u' _ 'w' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ ';', 8, 0x29a7, 1) +NAMED_CHARACTER_REFERENCE(2044, 'v' _ 'A' _ 'r' _ 'r' _ ';', 5, 0x21d5, 1) +NAMED_CHARACTER_REFERENCE(2045, 'v' _ 'B' _ 'a' _ 'r' _ ';', 5, 0x2ae8, 1) +NAMED_CHARACTER_REFERENCE(2046, 'v' _ 'B' _ 'a' _ 'r' _ 'v' _ ';', 6, 0x2ae9, 1) +NAMED_CHARACTER_REFERENCE(2047, 'v' _ 'D' _ 'a' _ 's' _ 'h' _ ';', 6, 0x22a8, 1) +NAMED_CHARACTER_REFERENCE(2048, 'v' _ 'a' _ 'n' _ 'g' _ 'r' _ 't' _ ';', 7, 0x299c, 1) +NAMED_CHARACTER_REFERENCE(2049, 'v' _ 'a' _ 'r' _ 'e' _ 'p' _ 's' _ 'i' _ 'l' _ 'o' _ 'n' _ ';', 11, 0x03f5, 1) +NAMED_CHARACTER_REFERENCE(2050, 'v' _ 'a' _ 'r' _ 'k' _ 'a' _ 'p' _ 'p' _ 'a' _ ';', 9, 0x03f0, 1) +NAMED_CHARACTER_REFERENCE(2051, 'v' _ 'a' _ 'r' _ 'n' _ 'o' _ 't' _ 'h' _ 'i' _ 'n' _ 'g' _ ';', 11, 0x2205, 1) +NAMED_CHARACTER_REFERENCE(2052, 'v' _ 'a' _ 'r' _ 'p' _ 'h' _ 'i' _ ';', 7, 0x03d5, 1) +NAMED_CHARACTER_REFERENCE(2053, 'v' _ 'a' _ 'r' _ 'p' _ 'i' _ ';', 6, 0x03d6, 1) +NAMED_CHARACTER_REFERENCE(2054, 'v' _ 'a' _ 'r' _ 'p' _ 'r' _ 'o' _ 'p' _ 't' _ 'o' _ ';', 10, 0x221d, 1) +NAMED_CHARACTER_REFERENCE(2055, 'v' _ 'a' _ 'r' _ 'r' _ ';', 5, 0x2195, 1) +NAMED_CHARACTER_REFERENCE(2056, 'v' _ 'a' _ 'r' _ 'r' _ 'h' _ 'o' _ ';', 7, 0x03f1, 1) +NAMED_CHARACTER_REFERENCE(2057, 'v' _ 'a' _ 'r' _ 's' _ 'i' _ 'g' _ 'm' _ 'a' _ ';', 9, 0x03c2, 1) +NAMED_CHARACTER_REFERENCE(2058, 'v' _ 'a' _ 'r' _ 't' _ 'h' _ 'e' _ 't' _ 'a' _ ';', 9, 0x03d1, 1) +NAMED_CHARACTER_REFERENCE(2059, 'v' _ 'a' _ 'r' _ 't' _ 'r' _ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ 'l' _ 'e' _ 'f' _ 't' _ ';', 16, 0x22b2, 1) +NAMED_CHARACTER_REFERENCE(2060, 'v' _ 'a' _ 'r' _ 't' _ 'r' _ 'i' _ 'a' _ 'n' _ 'g' _ 'l' _ 'e' _ 'r' _ 'i' _ 'g' _ 'h' _ 't' _ ';', 17, 0x22b3, 1) +NAMED_CHARACTER_REFERENCE(2061, 'v' _ 'c' _ 'y' _ ';', 4, 0x0432, 1) +NAMED_CHARACTER_REFERENCE(2062, 'v' _ 'd' _ 'a' _ 's' _ 'h' _ ';', 6, 0x22a2, 1) +NAMED_CHARACTER_REFERENCE(2063, 'v' _ 'e' _ 'e' _ ';', 4, 0x2228, 1) +NAMED_CHARACTER_REFERENCE(2064, 'v' _ 'e' _ 'e' _ 'b' _ 'a' _ 'r' _ ';', 7, 0x22bb, 1) +NAMED_CHARACTER_REFERENCE(2065, 'v' _ 'e' _ 'e' _ 'e' _ 'q' _ ';', 6, 0x225a, 1) +NAMED_CHARACTER_REFERENCE(2066, 'v' _ 'e' _ 'l' _ 'l' _ 'i' _ 'p' _ ';', 7, 0x22ee, 1) +NAMED_CHARACTER_REFERENCE(2067, 'v' _ 'e' _ 'r' _ 'b' _ 'a' _ 'r' _ ';', 7, 0x007c, 1) +NAMED_CHARACTER_REFERENCE(2068, 'v' _ 'e' _ 'r' _ 't' _ ';', 5, 0x007c, 1) +NAMED_CHARACTER_REFERENCE(2069, 'v' _ 'f' _ 'r' _ ';', 4, 0xd835 _ 0xdd33, 2) +NAMED_CHARACTER_REFERENCE(2070, 'v' _ 'l' _ 't' _ 'r' _ 'i' _ ';', 6, 0x22b2, 1) +NAMED_CHARACTER_REFERENCE(2071, 'v' _ 'o' _ 'p' _ 'f' _ ';', 5, 0xd835 _ 0xdd67, 2) +NAMED_CHARACTER_REFERENCE(2072, 'v' _ 'p' _ 'r' _ 'o' _ 'p' _ ';', 6, 0x221d, 1) +NAMED_CHARACTER_REFERENCE(2073, 'v' _ 'r' _ 't' _ 'r' _ 'i' _ ';', 6, 0x22b3, 1) +NAMED_CHARACTER_REFERENCE(2074, 'v' _ 's' _ 'c' _ 'r' _ ';', 5, 0xd835 _ 0xdccb, 2) +NAMED_CHARACTER_REFERENCE(2075, 'v' _ 'z' _ 'i' _ 'g' _ 'z' _ 'a' _ 'g' _ ';', 8, 0x299a, 1) +NAMED_CHARACTER_REFERENCE(2076, 'w' _ 'c' _ 'i' _ 'r' _ 'c' _ ';', 6, 0x0175, 1) +NAMED_CHARACTER_REFERENCE(2077, 'w' _ 'e' _ 'd' _ 'b' _ 'a' _ 'r' _ ';', 7, 0x2a5f, 1) +NAMED_CHARACTER_REFERENCE(2078, 'w' _ 'e' _ 'd' _ 'g' _ 'e' _ ';', 6, 0x2227, 1) +NAMED_CHARACTER_REFERENCE(2079, 'w' _ 'e' _ 'd' _ 'g' _ 'e' _ 'q' _ ';', 7, 0x2259, 1) +NAMED_CHARACTER_REFERENCE(2080, 'w' _ 'e' _ 'i' _ 'e' _ 'r' _ 'p' _ ';', 7, 0x2118, 1) +NAMED_CHARACTER_REFERENCE(2081, 'w' _ 'f' _ 'r' _ ';', 4, 0xd835 _ 0xdd34, 2) +NAMED_CHARACTER_REFERENCE(2082, 'w' _ 'o' _ 'p' _ 'f' _ ';', 5, 0xd835 _ 0xdd68, 2) +NAMED_CHARACTER_REFERENCE(2083, 'w' _ 'p' _ ';', 3, 0x2118, 1) +NAMED_CHARACTER_REFERENCE(2084, 'w' _ 'r' _ ';', 3, 0x2240, 1) +NAMED_CHARACTER_REFERENCE(2085, 'w' _ 'r' _ 'e' _ 'a' _ 't' _ 'h' _ ';', 7, 0x2240, 1) +NAMED_CHARACTER_REFERENCE(2086, 'w' _ 's' _ 'c' _ 'r' _ ';', 5, 0xd835 _ 0xdccc, 2) +NAMED_CHARACTER_REFERENCE(2087, 'x' _ 'c' _ 'a' _ 'p' _ ';', 5, 0x22c2, 1) +NAMED_CHARACTER_REFERENCE(2088, 'x' _ 'c' _ 'i' _ 'r' _ 'c' _ ';', 6, 0x25ef, 1) +NAMED_CHARACTER_REFERENCE(2089, 'x' _ 'c' _ 'u' _ 'p' _ ';', 5, 0x22c3, 1) +NAMED_CHARACTER_REFERENCE(2090, 'x' _ 'd' _ 't' _ 'r' _ 'i' _ ';', 6, 0x25bd, 1) +NAMED_CHARACTER_REFERENCE(2091, 'x' _ 'f' _ 'r' _ ';', 4, 0xd835 _ 0xdd35, 2) +NAMED_CHARACTER_REFERENCE(2092, 'x' _ 'h' _ 'A' _ 'r' _ 'r' _ ';', 6, 0x27fa, 1) +NAMED_CHARACTER_REFERENCE(2093, 'x' _ 'h' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x27f7, 1) +NAMED_CHARACTER_REFERENCE(2094, 'x' _ 'i' _ ';', 3, 0x03be, 1) +NAMED_CHARACTER_REFERENCE(2095, 'x' _ 'l' _ 'A' _ 'r' _ 'r' _ ';', 6, 0x27f8, 1) +NAMED_CHARACTER_REFERENCE(2096, 'x' _ 'l' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x27f5, 1) +NAMED_CHARACTER_REFERENCE(2097, 'x' _ 'm' _ 'a' _ 'p' _ ';', 5, 0x27fc, 1) +NAMED_CHARACTER_REFERENCE(2098, 'x' _ 'n' _ 'i' _ 's' _ ';', 5, 0x22fb, 1) +NAMED_CHARACTER_REFERENCE(2099, 'x' _ 'o' _ 'd' _ 'o' _ 't' _ ';', 6, 0x2a00, 1) +NAMED_CHARACTER_REFERENCE(2100, 'x' _ 'o' _ 'p' _ 'f' _ ';', 5, 0xd835 _ 0xdd69, 2) +NAMED_CHARACTER_REFERENCE(2101, 'x' _ 'o' _ 'p' _ 'l' _ 'u' _ 's' _ ';', 7, 0x2a01, 1) +NAMED_CHARACTER_REFERENCE(2102, 'x' _ 'o' _ 't' _ 'i' _ 'm' _ 'e' _ ';', 7, 0x2a02, 1) +NAMED_CHARACTER_REFERENCE(2103, 'x' _ 'r' _ 'A' _ 'r' _ 'r' _ ';', 6, 0x27f9, 1) +NAMED_CHARACTER_REFERENCE(2104, 'x' _ 'r' _ 'a' _ 'r' _ 'r' _ ';', 6, 0x27f6, 1) +NAMED_CHARACTER_REFERENCE(2105, 'x' _ 's' _ 'c' _ 'r' _ ';', 5, 0xd835 _ 0xdccd, 2) +NAMED_CHARACTER_REFERENCE(2106, 'x' _ 's' _ 'q' _ 'c' _ 'u' _ 'p' _ ';', 7, 0x2a06, 1) +NAMED_CHARACTER_REFERENCE(2107, 'x' _ 'u' _ 'p' _ 'l' _ 'u' _ 's' _ ';', 7, 0x2a04, 1) +NAMED_CHARACTER_REFERENCE(2108, 'x' _ 'u' _ 't' _ 'r' _ 'i' _ ';', 6, 0x25b3, 1) +NAMED_CHARACTER_REFERENCE(2109, 'x' _ 'v' _ 'e' _ 'e' _ ';', 5, 0x22c1, 1) +NAMED_CHARACTER_REFERENCE(2110, 'x' _ 'w' _ 'e' _ 'd' _ 'g' _ 'e' _ ';', 7, 0x22c0, 1) +NAMED_CHARACTER_REFERENCE(2111, 'y' _ 'a' _ 'c' _ 'u' _ 't' _ 'e', 6, 0x00fd, 1) +NAMED_CHARACTER_REFERENCE(2112, 'y' _ 'a' _ 'c' _ 'u' _ 't' _ 'e' _ ';', 7, 0x00fd, 1) +NAMED_CHARACTER_REFERENCE(2113, 'y' _ 'a' _ 'c' _ 'y' _ ';', 5, 0x044f, 1) +NAMED_CHARACTER_REFERENCE(2114, 'y' _ 'c' _ 'i' _ 'r' _ 'c' _ ';', 6, 0x0177, 1) +NAMED_CHARACTER_REFERENCE(2115, 'y' _ 'c' _ 'y' _ ';', 4, 0x044b, 1) +NAMED_CHARACTER_REFERENCE(2116, 'y' _ 'e' _ 'n', 3, 0x00a5, 1) +NAMED_CHARACTER_REFERENCE(2117, 'y' _ 'e' _ 'n' _ ';', 4, 0x00a5, 1) +NAMED_CHARACTER_REFERENCE(2118, 'y' _ 'f' _ 'r' _ ';', 4, 0xd835 _ 0xdd36, 2) +NAMED_CHARACTER_REFERENCE(2119, 'y' _ 'i' _ 'c' _ 'y' _ ';', 5, 0x0457, 1) +NAMED_CHARACTER_REFERENCE(2120, 'y' _ 'o' _ 'p' _ 'f' _ ';', 5, 0xd835 _ 0xdd6a, 2) +NAMED_CHARACTER_REFERENCE(2121, 'y' _ 's' _ 'c' _ 'r' _ ';', 5, 0xd835 _ 0xdcce, 2) +NAMED_CHARACTER_REFERENCE(2122, 'y' _ 'u' _ 'c' _ 'y' _ ';', 5, 0x044e, 1) +NAMED_CHARACTER_REFERENCE(2123, 'y' _ 'u' _ 'm' _ 'l', 4, 0x00ff, 1) +NAMED_CHARACTER_REFERENCE(2124, 'y' _ 'u' _ 'm' _ 'l' _ ';', 5, 0x00ff, 1) +NAMED_CHARACTER_REFERENCE(2125, 'z' _ 'a' _ 'c' _ 'u' _ 't' _ 'e' _ ';', 7, 0x017a, 1) +NAMED_CHARACTER_REFERENCE(2126, 'z' _ 'c' _ 'a' _ 'r' _ 'o' _ 'n' _ ';', 7, 0x017e, 1) +NAMED_CHARACTER_REFERENCE(2127, 'z' _ 'c' _ 'y' _ ';', 4, 0x0437, 1) +NAMED_CHARACTER_REFERENCE(2128, 'z' _ 'd' _ 'o' _ 't' _ ';', 5, 0x017c, 1) +NAMED_CHARACTER_REFERENCE(2129, 'z' _ 'e' _ 'e' _ 't' _ 'r' _ 'f' _ ';', 7, 0x2128, 1) +NAMED_CHARACTER_REFERENCE(2130, 'z' _ 'e' _ 't' _ 'a' _ ';', 5, 0x03b6, 1) +NAMED_CHARACTER_REFERENCE(2131, 'z' _ 'f' _ 'r' _ ';', 4, 0xd835 _ 0xdd37, 2) +NAMED_CHARACTER_REFERENCE(2132, 'z' _ 'h' _ 'c' _ 'y' _ ';', 5, 0x0436, 1) +NAMED_CHARACTER_REFERENCE(2133, 'z' _ 'i' _ 'g' _ 'r' _ 'a' _ 'r' _ 'r' _ ';', 8, 0x21dd, 1) +NAMED_CHARACTER_REFERENCE(2134, 'z' _ 'o' _ 'p' _ 'f' _ ';', 5, 0xd835 _ 0xdd6b, 2) +NAMED_CHARACTER_REFERENCE(2135, 'z' _ 's' _ 'c' _ 'r' _ ';', 5, 0xd835 _ 0xdccf, 2) +NAMED_CHARACTER_REFERENCE(2136, 'z' _ 'w' _ 'j' _ ';', 4, 0x200d, 1) +NAMED_CHARACTER_REFERENCE(2137, 'z' _ 'w' _ 'n' _ 'j' _ ';', 5, 0x200c, 1) #undef _ diff --git a/parser/html/nsHtml5Parser.cpp b/parser/html/nsHtml5Parser.cpp index 2257c77332d3..77547d2ad0f0 100644 --- a/parser/html/nsHtml5Parser.cpp +++ b/parser/html/nsHtml5Parser.cpp @@ -251,7 +251,7 @@ nsHtml5Parser::Parse(const nsAString& aSourceBuffer, PRBool aLastCall, nsDTDMode aMode) // ignored { - NS_PRECONDITION(!mFragmentMode, "Document.write called in fragment mode!"); + NS_PRECONDITION(!mExecutor->IsFragmentMode(), "Document.write called in fragment mode!"); // Maintain a reference to ourselves so we don't go away // till we're completely done. The old parser grips itself in this method. @@ -458,7 +458,7 @@ nsHtml5Parser::ParseFragment(const nsAString& aSourceBuffer, nsIContent* weakTarget = target; mTreeBuilder->setFragmentContext(aContextLocalName, aContextNamespace, &weakTarget, aQuirks); - mFragmentMode = PR_TRUE; + mExecutor->EnableFragmentMode(); NS_PRECONDITION(!mExecutor->HasStarted(), "Tried to start parse without initializing the parser properly."); mTreeBuilder->setScriptingEnabled(mExecutor->IsScriptEnabled()); @@ -474,7 +474,6 @@ nsHtml5Parser::ParseFragment(const nsAString& aSourceBuffer, lastWasCR = PR_FALSE; if (buffer.hasMore()) { lastWasCR = mTokenizer->tokenizeBuffer(&buffer); - mExecutor->MaybePreventExecution(); } } } @@ -507,7 +506,6 @@ nsHtml5Parser::Reset() { mExecutor->Reset(); mLastWasCR = PR_FALSE; - mFragmentMode = PR_FALSE; UnblockParser(); mDocumentClosed = PR_FALSE; mStreamParser = nsnull; @@ -524,7 +522,7 @@ nsHtml5Parser::Reset() PRBool nsHtml5Parser::CanInterrupt() { - return !mFragmentMode; + return !mExecutor->IsFragmentMode(); } PRBool @@ -565,7 +563,7 @@ nsHtml5Parser::IsScriptCreated() void nsHtml5Parser::ParseUntilBlocked() { - NS_PRECONDITION(!mFragmentMode, "ParseUntilBlocked called in fragment mode."); + NS_PRECONDITION(!mExecutor->IsFragmentMode(), "ParseUntilBlocked called in fragment mode."); if (mBlocked) { return; diff --git a/parser/html/nsHtml5Speculation.cpp b/parser/html/nsHtml5Speculation.cpp index 14afa1b8a0e0..c81bd3d9a7e8 100644 --- a/parser/html/nsHtml5Speculation.cpp +++ b/parser/html/nsHtml5Speculation.cpp @@ -55,13 +55,7 @@ nsHtml5Speculation::~nsHtml5Speculation() } void -nsHtml5Speculation::MaybeFlush(nsTArray& aOpQueue) -{ - // No-op -} - -void -nsHtml5Speculation::ForcedFlush(nsTArray& aOpQueue) +nsHtml5Speculation::MoveOpsFrom(nsTArray& aOpQueue) { if (mOpQueue.IsEmpty()) { mOpQueue.SwapElements(aOpQueue); @@ -73,5 +67,5 @@ nsHtml5Speculation::ForcedFlush(nsTArray& aOpQueue) void nsHtml5Speculation::FlushToSink(nsAHtml5TreeOpSink* aSink) { - aSink->ForcedFlush(mOpQueue); + aSink->MoveOpsFrom(mOpQueue); } diff --git a/parser/html/nsHtml5Speculation.h b/parser/html/nsHtml5Speculation.h index 07b3b7d867f6..ae9974a270a2 100644 --- a/parser/html/nsHtml5Speculation.h +++ b/parser/html/nsHtml5Speculation.h @@ -71,16 +71,11 @@ class nsHtml5Speculation : public nsAHtml5TreeOpSink return mSnapshot; } - /** - * No-op. - */ - virtual void MaybeFlush(nsTArray& aOpQueue); - /** * Flush the operations from the tree operations from the argument * queue unconditionally. */ - virtual void ForcedFlush(nsTArray& aOpQueue); + virtual void MoveOpsFrom(nsTArray& aOpQueue); void FlushToSink(nsAHtml5TreeOpSink* aSink); diff --git a/parser/html/nsHtml5StreamParser.cpp b/parser/html/nsHtml5StreamParser.cpp index 228d8936ebf9..cbb1457f3da3 100644 --- a/parser/html/nsHtml5StreamParser.cpp +++ b/parser/html/nsHtml5StreamParser.cpp @@ -54,6 +54,22 @@ static NS_DEFINE_CID(kCharsetAliasCID, NS_CHARSETALIAS_CID); +PRInt32 nsHtml5StreamParser::sTimerStartDelay = 200; +PRInt32 nsHtml5StreamParser::sTimerContinueDelay = 150; +PRInt32 nsHtml5StreamParser::sTimerInterval = 100; + +// static +void +nsHtml5StreamParser::InitializeStatics() +{ + nsContentUtils::AddIntPrefVarCache("html5.flushtimer.startdelay", + &sTimerStartDelay); + nsContentUtils::AddIntPrefVarCache("html5.flushtimer.continuedelay", + &sTimerContinueDelay); + nsContentUtils::AddIntPrefVarCache("html5.flushtimer.interval", + &sTimerInterval); +} + NS_IMPL_CYCLE_COLLECTING_ADDREF(nsHtml5StreamParser) NS_IMPL_CYCLE_COLLECTING_RELEASE(nsHtml5StreamParser) @@ -67,6 +83,10 @@ NS_INTERFACE_MAP_END NS_IMPL_CYCLE_COLLECTION_CLASS(nsHtml5StreamParser) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsHtml5StreamParser) + if (tmp->mFlushTimer) { + tmp->mFlushTimer->Cancel(); + tmp->mFlushTimer = nsnull; + } NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mObserver) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mRequest) tmp->mOwner = nsnull; @@ -125,6 +145,7 @@ nsHtml5StreamParser::nsHtml5StreamParser(nsHtml5TreeOpExecutor* aExecutor, , mTerminatedMutex("nsHtml5StreamParser mTerminatedMutex") , mThread(nsHtml5Module::GetStreamParserThread()) , mExecutorFlusher(new nsHtml5ExecutorFlusher(aExecutor)) + , mFlushTimer(do_CreateInstance("@mozilla.org/timer;1")) { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); mAtomTable.Init(); // we aren't checking for OOM anyway... @@ -150,6 +171,10 @@ nsHtml5StreamParser::~nsHtml5StreamParser() mTreeBuilder = nsnull; mTokenizer = nsnull; mOwner = nsnull; + if (mFlushTimer) { + mFlushTimer->Cancel(); + mFlushTimer = nsnull; + } } void @@ -483,6 +508,11 @@ nsHtml5StreamParser::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext) */ mExecutor->WillBuildModel(eDTDMode_unknown); + mFlushTimer->InitWithFuncCallback(nsHtml5StreamParser::TimerCallback, + static_cast (this), + sTimerStartDelay, + nsITimer::TYPE_ONE_SHOT); + nsresult rv = NS_OK; mReparseForbidden = PR_FALSE; @@ -719,7 +749,6 @@ nsHtml5StreamParser::ParseAvailableData() mFirstBuffer->setStart(0); mFirstBuffer->setEnd(0); } - mTreeBuilder->Flush(); return; // no more data for now but expecting more case STREAM_ENDED: if (mAtEOF) { @@ -772,7 +801,6 @@ nsHtml5StreamParser::ParseAvailableData() if (IsTerminatedOrInterrupted()) { return; } - mTreeBuilder->MaybeFlush(); } continue; } @@ -873,6 +901,11 @@ nsHtml5StreamParser::ContinueAfterScripts(nsHtml5Tokenizer* aTokenizer, mTreeBuilder->SetOpSink(mExecutor->GetStage()); mExecutor->StartReadingFromStage(); mSpeculating = PR_FALSE; + mFlushTimer->Cancel(); // just in case + mFlushTimer->InitWithFuncCallback(nsHtml5StreamParser::TimerCallback, + static_cast (this), + sTimerContinueDelay, + nsITimer::TYPE_ONE_SHOT); // Copy state over mLastWasCR = aLastWasCR; mTokenizer->loadState(aTokenizer); @@ -890,6 +923,11 @@ nsHtml5StreamParser::ContinueAfterScripts(nsHtml5Tokenizer* aTokenizer, mTreeBuilder->SetOpSink(mExecutor->GetStage()); mExecutor->StartReadingFromStage(); mSpeculating = PR_FALSE; + mFlushTimer->Cancel(); // just in case + mFlushTimer->InitWithFuncCallback(nsHtml5StreamParser::TimerCallback, + static_cast (this), + sTimerContinueDelay, + nsITimer::TYPE_ONE_SHOT); } } Uninterrupt(); @@ -912,6 +950,89 @@ nsHtml5StreamParser::ContinueAfterFailedCharsetSwitch() Uninterrupt(); nsCOMPtr event = new nsHtml5StreamParserContinuation(this); if (NS_FAILED(mThread->Dispatch(event, nsIThread::DISPATCH_NORMAL))) { - NS_WARNING("Failed to dispatch ParseAvailableData event"); - } + NS_WARNING("Failed to dispatch nsHtml5StreamParserContinuation"); + } } + +// Using a static, because the method name Notify is taken by the chardet +// callback. +void +nsHtml5StreamParser::TimerCallback(nsITimer* aTimer, void* aClosure) +{ + (static_cast (aClosure))->PostTimerFlush(); +} + +void +nsHtml5StreamParser::TimerFlush() +{ + NS_ASSERTION(IsParserThread(), "Wrong thread!"); + mTokenizerMutex.AssertCurrentThreadOwns(); + + if (mSpeculating) { + return; + } + + // we aren't speculating and we don't know when new data is + // going to arrive. Send data to the main thread. + // However, don't do if the current element on the stack is a + // foster-parenting element and there's pending text, because flushing in + // that case would make the tree shape dependent on where the flush points + // fall. + if (mTreeBuilder->IsDiscretionaryFlushSafe()) { + mTreeBuilder->flushCharacters(); + if (mTreeBuilder->Flush()) { + if (NS_FAILED(NS_DispatchToMainThread(mExecutorFlusher))) { + NS_WARNING("failed to dispatch executor flush event"); + } + } + } +} + +class nsHtml5StreamParserTimerFlusher : public nsRunnable +{ +private: + nsHtml5RefPtr mStreamParser; +public: + nsHtml5StreamParserTimerFlusher(nsHtml5StreamParser* aStreamParser) + : mStreamParser(aStreamParser) + {} + NS_IMETHODIMP Run() + { + mozilla::MutexAutoLock autoLock(mStreamParser->mTokenizerMutex); + mStreamParser->TimerFlush(); + return NS_OK; + } +}; + +void +nsHtml5StreamParser::PostTimerFlush() +{ + NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); + + mFlushTimer->Cancel(); // just in case + + // The following line reads a mutex-protected variable without acquiring + // the mutex. This is OK, because failure to exit early here is harmless. + // The early exit here is merely an optimization. Note that parser thread + // may have set mSpeculating to true where it previously was false--not + // the other way round. mSpeculating is set to false only on the main thread. + if (mSpeculating) { + // No need for timer flushes when speculating + return; + } + + // Schedule the next timer shot + mFlushTimer->InitWithFuncCallback(nsHtml5StreamParser::TimerCallback, + static_cast (this), + sTimerInterval, + nsITimer::TYPE_ONE_SHOT); + + // TODO: (If mDocument isn't in the frontmost tab or If the user isn't + // interacting with the browser) and this isn't every nth timer flush, return + + nsCOMPtr event = new nsHtml5StreamParserTimerFlusher(this); + if (NS_FAILED(mThread->Dispatch(event, nsIThread::DISPATCH_NORMAL))) { + NS_WARNING("Failed to dispatch nsHtml5StreamParserTimerFlusher"); + } +} + diff --git a/parser/html/nsHtml5StreamParser.h b/parser/html/nsHtml5StreamParser.h index e362a425fc35..cfcea78372cb 100644 --- a/parser/html/nsHtml5StreamParser.h +++ b/parser/html/nsHtml5StreamParser.h @@ -52,6 +52,7 @@ #include "mozilla/Mutex.h" #include "nsHtml5AtomTable.h" #include "nsHtml5Speculation.h" +#include "nsITimer.h" class nsHtml5Parser; @@ -106,12 +107,15 @@ class nsHtml5StreamParser : public nsIStreamListener, friend class nsHtml5RequestStopper; friend class nsHtml5DataAvailable; friend class nsHtml5StreamParserContinuation; + friend class nsHtml5StreamParserTimerFlusher; public: NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsHtml5StreamParser, nsIStreamListener) + static void InitializeStatics(); + nsHtml5StreamParser(nsHtml5TreeOpExecutor* aExecutor, nsHtml5Parser* aOwner); @@ -301,6 +305,23 @@ class nsHtml5StreamParser : public nsIStreamListener, nsresult SetupDecodingFromBom(const char* aCharsetName, const char* aDecoderCharsetName); + /** + * Callback for mFlushTimer. + */ + static void TimerCallback(nsITimer* aTimer, void* aClosure); + + /** + * Main thread entry point for (maybe) flushing the ops and posting + * a flush runnable back on the main thread. + */ + void PostTimerFlush(); + + /** + * Parser thread entry point for (maybe) flushing the ops and posting + * a flush runnable back on the main thread. + */ + void TimerFlush(); + nsCOMPtr mRequest; nsCOMPtr mObserver; @@ -435,6 +456,31 @@ class nsHtml5StreamParser : public nsIStreamListener, * The document wrapped by the speculative loader. */ nsCOMPtr mDocument; + + /** + * Timer for flushing tree ops once in a while when not speculating. + */ + nsCOMPtr mFlushTimer; + + /** + * The pref html5.flushtimer.startdelay: Time in milliseconds between + * the start of the network stream and the first time the flush timer + * fires. + */ + static PRInt32 sTimerStartDelay; + + /** + * The pref html5.flushtimer.continuedelay: Time in milliseconds between + * the return to non-speculating more and the first time the flush timer + * fires thereafter. + */ + static PRInt32 sTimerContinueDelay; + + /** + * The pref html5.flushtimer.interval: Time in milliseconds between + * timer firings once the timer has starting firing. + */ + static PRInt32 sTimerInterval; }; #endif // nsHtml5StreamParser_h__ diff --git a/parser/html/nsHtml5Tokenizer.cpp b/parser/html/nsHtml5Tokenizer.cpp index 29ecfde859bf..e0fa149718f5 100644 --- a/parser/html/nsHtml5Tokenizer.cpp +++ b/parser/html/nsHtml5Tokenizer.cpp @@ -375,6 +375,7 @@ nsHtml5Tokenizer::emitCurrentTagToken(PRBool selfClosing, PRInt32 pos) if (endTag) { tokenHandler->endTag(tagName); + delete attributes; } else { tokenHandler->startTag(tagName, attrs, selfClosing); } @@ -443,14 +444,22 @@ nsHtml5Tokenizer::tokenizeBuffer(nsHtml5UTF16Buffer* buffer) switch(state) { case NS_HTML5TOKENIZER_DATA: case NS_HTML5TOKENIZER_RCDATA: - case NS_HTML5TOKENIZER_CDATA: + case NS_HTML5TOKENIZER_SCRIPT_DATA: case NS_HTML5TOKENIZER_PLAINTEXT: + case NS_HTML5TOKENIZER_RAWTEXT: case NS_HTML5TOKENIZER_CDATA_SECTION: - case NS_HTML5TOKENIZER_ESCAPE: - case NS_HTML5TOKENIZER_ESCAPE_EXCLAMATION: - case NS_HTML5TOKENIZER_ESCAPE_EXCLAMATION_HYPHEN: - case NS_HTML5TOKENIZER_ESCAPE_HYPHEN: - case NS_HTML5TOKENIZER_ESCAPE_HYPHEN_HYPHEN: { + case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED: + case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPE_START: + case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPE_START_DASH: + case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_DASH: + case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_DASH_DASH: + case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_LESS_THAN: + case NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPE_START: + case NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED: + case NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN: + case NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED_DASH: + case NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH: + case NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPE_END: { cstart = start; break; } @@ -538,7 +547,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar* goto stateloop; } case '/': { - state = NS_HTML5TOKENIZER_CLOSE_TAG_OPEN_PCDATA; + state = NS_HTML5TOKENIZER_CLOSE_TAG_OPEN; goto stateloop; } case '\?': { @@ -779,6 +788,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar* } case '<': case '=': + case '`': default: { clearLongStrBufAndAppendCurrentC(c); state = NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_UNQUOTED; @@ -943,6 +953,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar* case '\"': case '\'': case '=': + case '`': default: { appendLongStrBuf(c); @@ -1636,14 +1647,14 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar* index++; continue; } else { - state = NS_HTML5TOKENIZER_BEFORE_DOCTYPE_PUBLIC_IDENTIFIER; + state = NS_HTML5TOKENIZER_AFTER_DOCTYPE_PUBLIC_KEYWORD; reconsume = PR_TRUE; goto doctypeublicloop_end; } } doctypeublicloop_end: ; } - case NS_HTML5TOKENIZER_BEFORE_DOCTYPE_PUBLIC_IDENTIFIER: { + case NS_HTML5TOKENIZER_AFTER_DOCTYPE_PUBLIC_KEYWORD: { for (; ; ) { if (reconsume) { reconsume = PR_FALSE; @@ -1653,6 +1664,55 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar* } c = checkChar(buf, pos); } + switch(c) { + case '\r': { + silentCarriageReturn(); + state = NS_HTML5TOKENIZER_BEFORE_DOCTYPE_PUBLIC_IDENTIFIER; + goto stateloop_end; + } + case '\n': { + silentLineFeed(); + } + case ' ': + case '\t': + case '\f': { + state = NS_HTML5TOKENIZER_BEFORE_DOCTYPE_PUBLIC_IDENTIFIER; + goto afterdoctypepublickeywordloop_end; + } + case '\"': { + + clearLongStrBufForNextState(); + state = NS_HTML5TOKENIZER_DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED; + goto stateloop; + } + case '\'': { + + clearLongStrBufForNextState(); + state = NS_HTML5TOKENIZER_DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED; + goto stateloop; + } + case '>': { + + forceQuirks = PR_TRUE; + emitDoctypeToken(pos); + state = NS_HTML5TOKENIZER_DATA; + goto stateloop; + } + default: { + bogusDoctype(); + state = NS_HTML5TOKENIZER_BOGUS_DOCTYPE; + goto stateloop; + } + } + } + afterdoctypepublickeywordloop_end: ; + } + case NS_HTML5TOKENIZER_BEFORE_DOCTYPE_PUBLIC_IDENTIFIER: { + for (; ; ) { + if (++pos == endPos) { + goto stateloop_end; + } + c = checkChar(buf, pos); switch(c) { case '\r': { silentCarriageReturn(); @@ -1740,6 +1800,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar* switch(c) { case '\r': { silentCarriageReturn(); + state = NS_HTML5TOKENIZER_BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS; goto stateloop_end; } case '\n': { @@ -1748,23 +1809,26 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar* case ' ': case '\t': case '\f': { - continue; - } - case '\"': { - clearLongStrBufForNextState(); - state = NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED; + state = NS_HTML5TOKENIZER_BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS; goto afterdoctypepublicidentifierloop_end; } - case '\'': { - clearLongStrBufForNextState(); - state = NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED; - goto stateloop; - } case '>': { emitDoctypeToken(pos); state = NS_HTML5TOKENIZER_DATA; goto stateloop; } + case '\"': { + + clearLongStrBufForNextState(); + state = NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED; + goto stateloop; + } + case '\'': { + + clearLongStrBufForNextState(); + state = NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED; + goto stateloop; + } default: { bogusDoctype(); state = NS_HTML5TOKENIZER_BOGUS_DOCTYPE; @@ -1774,6 +1838,49 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar* } afterdoctypepublicidentifierloop_end: ; } + case NS_HTML5TOKENIZER_BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS: { + for (; ; ) { + if (++pos == endPos) { + goto stateloop_end; + } + c = checkChar(buf, pos); + switch(c) { + case '\r': { + silentCarriageReturn(); + goto stateloop_end; + } + case '\n': { + silentLineFeed(); + } + case ' ': + case '\t': + case '\f': { + continue; + } + case '>': { + emitDoctypeToken(pos); + state = NS_HTML5TOKENIZER_DATA; + goto stateloop; + } + case '\"': { + clearLongStrBufForNextState(); + state = NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED; + goto betweendoctypepublicandsystemidentifiersloop_end; + } + case '\'': { + clearLongStrBufForNextState(); + state = NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED; + goto stateloop; + } + default: { + bogusDoctype(); + state = NS_HTML5TOKENIZER_BOGUS_DOCTYPE; + goto stateloop; + } + } + } + betweendoctypepublicandsystemidentifiersloop_end: ; + } case NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED: { for (; ; ) { if (++pos == endPos) { @@ -1895,14 +2002,14 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar* index++; goto stateloop; } else { - state = NS_HTML5TOKENIZER_BEFORE_DOCTYPE_SYSTEM_IDENTIFIER; + state = NS_HTML5TOKENIZER_AFTER_DOCTYPE_SYSTEM_KEYWORD; reconsume = PR_TRUE; goto doctypeystemloop_end; } } doctypeystemloop_end: ; } - case NS_HTML5TOKENIZER_BEFORE_DOCTYPE_SYSTEM_IDENTIFIER: { + case NS_HTML5TOKENIZER_AFTER_DOCTYPE_SYSTEM_KEYWORD: { for (; ; ) { if (reconsume) { reconsume = PR_FALSE; @@ -1912,6 +2019,55 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar* } c = checkChar(buf, pos); } + switch(c) { + case '\r': { + silentCarriageReturn(); + state = NS_HTML5TOKENIZER_BEFORE_DOCTYPE_SYSTEM_IDENTIFIER; + goto stateloop_end; + } + case '\n': { + silentLineFeed(); + } + case ' ': + case '\t': + case '\f': { + state = NS_HTML5TOKENIZER_BEFORE_DOCTYPE_SYSTEM_IDENTIFIER; + goto afterdoctypesystemkeywordloop_end; + } + case '\"': { + + clearLongStrBufForNextState(); + state = NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED; + goto stateloop; + } + case '\'': { + + clearLongStrBufForNextState(); + state = NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED; + goto stateloop; + } + case '>': { + + forceQuirks = PR_TRUE; + emitDoctypeToken(pos); + state = NS_HTML5TOKENIZER_DATA; + goto stateloop; + } + default: { + bogusDoctype(); + state = NS_HTML5TOKENIZER_BOGUS_DOCTYPE; + goto stateloop; + } + } + } + afterdoctypesystemkeywordloop_end: ; + } + case NS_HTML5TOKENIZER_BEFORE_DOCTYPE_SYSTEM_IDENTIFIER: { + for (; ; ) { + if (++pos == endPos) { + goto stateloop_end; + } + c = checkChar(buf, pos); switch(c) { case '\r': { silentCarriageReturn(); @@ -2500,7 +2656,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar* } } - case NS_HTML5TOKENIZER_CDATA: { + case NS_HTML5TOKENIZER_SCRIPT_DATA: { for (; ; ) { if (reconsume) { reconsume = PR_FALSE; @@ -2514,8 +2670,8 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar* case '<': { flushChars(buf, pos); returnState = state; - state = NS_HTML5TOKENIZER_TAG_OPEN_NON_PCDATA; - goto cdataloop_end; + state = NS_HTML5TOKENIZER_SCRIPT_DATA_LESS_THAN_SIGN_STATE; + goto scriptdataloop_end; } case '\0': { emitReplacementCharacter(buf, pos); @@ -2533,41 +2689,39 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar* } } } - cdataloop_end: ; + scriptdataloop_end: ; } - case NS_HTML5TOKENIZER_TAG_OPEN_NON_PCDATA: { + case NS_HTML5TOKENIZER_SCRIPT_DATA_LESS_THAN_SIGN_STATE: { for (; ; ) { if (++pos == endPos) { goto stateloop_end; } c = checkChar(buf, pos); switch(c) { + case '/': { + index = 0; + clearStrBufForNextState(); + state = NS_HTML5TOKENIZER_NON_DATA_END_TAG_NAME; + goto stateloop; + } case '!': { tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1); cstart = pos; - state = NS_HTML5TOKENIZER_ESCAPE_EXCLAMATION; - goto tagopennonpcdataloop_end; - } - case '/': { - if (!!contentModelElement) { - index = 0; - clearStrBufForNextState(); - state = NS_HTML5TOKENIZER_CLOSE_TAG_OPEN_NOT_PCDATA; - goto stateloop; - } + state = NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPE_START; + goto scriptdatalessthansignloop_end; } default: { tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1); cstart = pos; - state = returnState; + state = NS_HTML5TOKENIZER_SCRIPT_DATA; reconsume = PR_TRUE; goto stateloop; } } } - tagopennonpcdataloop_end: ; + scriptdatalessthansignloop_end: ; } - case NS_HTML5TOKENIZER_ESCAPE_EXCLAMATION: { + case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPE_START: { for (; ; ) { if (++pos == endPos) { goto stateloop_end; @@ -2575,19 +2729,19 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar* c = checkChar(buf, pos); switch(c) { case '-': { - state = NS_HTML5TOKENIZER_ESCAPE_EXCLAMATION_HYPHEN; - goto escapeexclamationloop_end; + state = NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPE_START_DASH; + goto scriptdataescapestartloop_end; } default: { - state = returnState; + state = NS_HTML5TOKENIZER_SCRIPT_DATA; reconsume = PR_TRUE; goto stateloop; } } } - escapeexclamationloop_end: ; + scriptdataescapestartloop_end: ; } - case NS_HTML5TOKENIZER_ESCAPE_EXCLAMATION_HYPHEN: { + case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPE_START_DASH: { for (; ; ) { if (++pos == endPos) { goto stateloop_end; @@ -2595,19 +2749,19 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar* c = checkChar(buf, pos); switch(c) { case '-': { - state = NS_HTML5TOKENIZER_ESCAPE_HYPHEN_HYPHEN; - goto escapeexclamationhyphenloop_end; + state = NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_DASH_DASH; + goto scriptdataescapestartdashloop_end; } default: { - state = returnState; + state = NS_HTML5TOKENIZER_SCRIPT_DATA; reconsume = PR_TRUE; goto stateloop; } } } - escapeexclamationhyphenloop_end: ; + scriptdataescapestartdashloop_end: ; } - case NS_HTML5TOKENIZER_ESCAPE_HYPHEN_HYPHEN: { + case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_DASH_DASH: { for (; ; ) { if (++pos == endPos) { goto stateloop_end; @@ -2617,41 +2771,55 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar* case '-': { continue; } + case '<': { + flushChars(buf, pos); + state = NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_LESS_THAN; + goto stateloop; + } case '>': { - state = returnState; + state = NS_HTML5TOKENIZER_SCRIPT_DATA; goto stateloop; } case '\0': { emitReplacementCharacter(buf, pos); - state = NS_HTML5TOKENIZER_ESCAPE; - goto escapehyphenhyphenloop_end; + state = NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED; + goto scriptdataescapeddashdashloop_end; } case '\r': { emitCarriageReturn(buf, pos); - state = NS_HTML5TOKENIZER_ESCAPE; + state = NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED; goto stateloop_end; } case '\n': { silentLineFeed(); } default: { - state = NS_HTML5TOKENIZER_ESCAPE; - goto escapehyphenhyphenloop_end; + state = NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED; + goto scriptdataescapeddashdashloop_end; } } } - escapehyphenhyphenloop_end: ; + scriptdataescapeddashdashloop_end: ; } - case NS_HTML5TOKENIZER_ESCAPE: { + case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED: { for (; ; ) { - if (++pos == endPos) { - goto stateloop_end; + if (reconsume) { + reconsume = PR_FALSE; + } else { + if (++pos == endPos) { + goto stateloop_end; + } + c = checkChar(buf, pos); } - c = checkChar(buf, pos); switch(c) { case '-': { - state = NS_HTML5TOKENIZER_ESCAPE_HYPHEN; - goto escapeloop_end; + state = NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_DASH; + goto scriptdataescapedloop_end; + } + case '<': { + flushChars(buf, pos); + state = NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_LESS_THAN; + goto stateloop; } case '\0': { emitReplacementCharacter(buf, pos); @@ -2669,9 +2837,9 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar* } } } - escapeloop_end: ; + scriptdataescapedloop_end: ; } - case NS_HTML5TOKENIZER_ESCAPE_HYPHEN: { + case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_DASH: { for (; ; ) { if (++pos == endPos) { goto stateloop_end; @@ -2679,98 +2847,295 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar* c = checkChar(buf, pos); switch(c) { case '-': { - state = NS_HTML5TOKENIZER_ESCAPE_HYPHEN_HYPHEN; + state = NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_DASH_DASH; goto stateloop; } + case '<': { + flushChars(buf, pos); + state = NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_LESS_THAN; + goto scriptdataescapeddashloop_end; + } case '\0': { emitReplacementCharacter(buf, pos); - state = NS_HTML5TOKENIZER_ESCAPE; + state = NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED; goto stateloop; } case '\r': { emitCarriageReturn(buf, pos); - state = NS_HTML5TOKENIZER_ESCAPE; - goto stateloop; + state = NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED; + goto stateloop_end; } case '\n': { silentLineFeed(); } default: { - state = NS_HTML5TOKENIZER_ESCAPE; + state = NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED; + goto stateloop; + } + } + } + scriptdataescapeddashloop_end: ; + } + case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_LESS_THAN: { + for (; ; ) { + if (++pos == endPos) { + goto stateloop_end; + } + c = checkChar(buf, pos); + switch(c) { + case '/': { + index = 0; + clearStrBufForNextState(); + returnState = NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED; + state = NS_HTML5TOKENIZER_NON_DATA_END_TAG_NAME; + goto stateloop; + } + case 'S': + case 's': { + tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1); + cstart = pos; + index = 1; + state = NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPE_START; + goto scriptdataescapedlessthanloop_end; + } + default: { + tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1); + cstart = pos; + reconsume = PR_TRUE; + state = NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED; + goto stateloop; + } + } + } + scriptdataescapedlessthanloop_end: ; + } + case NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPE_START: { + for (; ; ) { + if (++pos == endPos) { + goto stateloop_end; + } + c = checkChar(buf, pos); + + if (index < 6) { + PRUnichar folded = c; + if (c >= 'A' && c <= 'Z') { + folded += 0x20; + } + if (folded != nsHtml5Tokenizer::SCRIPT_ARR[index]) { + reconsume = PR_TRUE; + state = NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED; + goto stateloop; + } + index++; + continue; + } + switch(c) { + case '\r': { + emitCarriageReturn(buf, pos); + state = NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED; + goto stateloop_end; + } + case '\n': { + silentLineFeed(); + } + case ' ': + case '\t': + case '\f': + case '/': + case '>': { + state = NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED; + goto scriptdatadoubleescapestartloop_end; + } + default: { + reconsume = PR_TRUE; + state = NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED; + goto stateloop; + } + } + } + scriptdatadoubleescapestartloop_end: ; + } + case NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED: { + for (; ; ) { + if (reconsume) { + reconsume = PR_FALSE; + } else { + if (++pos == endPos) { + goto stateloop_end; + } + c = checkChar(buf, pos); + } + switch(c) { + case '-': { + state = NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED_DASH; + goto scriptdatadoubleescapedloop_end; + } + case '<': { + flushChars(buf, pos); + state = NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN; + goto stateloop; + } + case '\0': { + emitReplacementCharacter(buf, pos); + continue; + } + case '\r': { + emitCarriageReturn(buf, pos); + goto stateloop_end; + } + case '\n': { + silentLineFeed(); + } + default: { + continue; + } + } + } + scriptdatadoubleescapedloop_end: ; + } + case NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED_DASH: { + for (; ; ) { + if (++pos == endPos) { + goto stateloop_end; + } + c = checkChar(buf, pos); + switch(c) { + case '-': { + state = NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH; + goto scriptdatadoubleescapeddashloop_end; + } + case '<': { + flushChars(buf, pos); + state = NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN; + goto stateloop; + } + case '\0': { + emitReplacementCharacter(buf, pos); + state = NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED; + goto stateloop; + } + case '\r': { + emitCarriageReturn(buf, pos); + state = NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED; + goto stateloop_end; + } + case '\n': { + silentLineFeed(); + } + default: { + state = NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED; + goto stateloop; + } + } + } + scriptdatadoubleescapeddashloop_end: ; + } + case NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH: { + for (; ; ) { + if (++pos == endPos) { + goto stateloop_end; + } + c = checkChar(buf, pos); + switch(c) { + case '-': { + continue; + } + case '<': { + state = NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN; + goto scriptdatadoubleescapeddashdashloop_end; + } + case '>': { + state = NS_HTML5TOKENIZER_SCRIPT_DATA; + goto stateloop; + } + case '\0': { + emitReplacementCharacter(buf, pos); + state = NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED; + goto stateloop; + } + case '\r': { + emitCarriageReturn(buf, pos); + state = NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED; + goto stateloop_end; + } + case '\n': { + silentLineFeed(); + } + default: { + state = NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED; + goto stateloop; + } + } + } + scriptdatadoubleescapeddashdashloop_end: ; + } + case NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN: { + for (; ; ) { + if (++pos == endPos) { + goto stateloop_end; + } + c = checkChar(buf, pos); + switch(c) { + case '/': { + index = 0; + state = NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPE_END; + goto scriptdatadoubleescapedlessthanloop_end; + } + default: { + reconsume = PR_TRUE; + state = NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED; + goto stateloop; + } + } + } + scriptdatadoubleescapedlessthanloop_end: ; + } + case NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPE_END: { + for (; ; ) { + if (++pos == endPos) { + goto stateloop_end; + } + c = checkChar(buf, pos); + if (index < 6) { + PRUnichar folded = c; + if (c >= 'A' && c <= 'Z') { + folded += 0x20; + } + if (folded != nsHtml5Tokenizer::SCRIPT_ARR[index]) { + reconsume = PR_TRUE; + state = NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED; + goto stateloop; + } + index++; + continue; + } + switch(c) { + case '\r': { + emitCarriageReturn(buf, pos); + state = NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED; + goto stateloop_end; + } + case '\n': { + silentLineFeed(); + } + case ' ': + case '\t': + case '\f': + case '/': + case '>': { + state = NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED; + goto stateloop; + } + default: { + reconsume = PR_TRUE; + state = NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED; goto stateloop; } } } } - case NS_HTML5TOKENIZER_CLOSE_TAG_OPEN_NOT_PCDATA: { - for (; ; ) { - if (++pos == endPos) { - goto stateloop_end; - } - c = checkChar(buf, pos); - if (index < contentModelElementNameAsArray.length) { - PRUnichar e = contentModelElementNameAsArray[index]; - PRUnichar folded = c; - if (c >= 'A' && c <= 'Z') { - folded += 0x20; - } - if (folded != e) { - tokenHandler->characters(nsHtml5Tokenizer::LT_SOLIDUS, 0, 2); - emitStrBuf(); - cstart = pos; - state = returnState; - reconsume = PR_TRUE; - goto stateloop; - } - appendStrBuf(c); - index++; - continue; - } else { - endTag = PR_TRUE; - tagName = contentModelElement; - switch(c) { - case '\r': { - silentCarriageReturn(); - state = NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME; - goto stateloop_end; - } - case '\n': { - silentLineFeed(); - } - case ' ': - case '\t': - case '\f': { - state = NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME; - goto stateloop; - } - case '>': { - state = emitCurrentTagToken(PR_FALSE, pos); - if (shouldSuspend) { - goto stateloop_end; - } - goto stateloop; - } - case '/': { - state = NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG; - goto stateloop; - } - default: { - tokenHandler->characters(nsHtml5Tokenizer::LT_SOLIDUS, 0, 2); - emitStrBuf(); - if (c == '\0') { - emitReplacementCharacter(buf, pos); - } else { - cstart = pos; - } - state = returnState; - goto stateloop; - } - } - } - } - } - case NS_HTML5TOKENIZER_CLOSE_TAG_OPEN_PCDATA: { + case NS_HTML5TOKENIZER_CLOSE_TAG_OPEN: { if (++pos == endPos) { goto stateloop_end; } @@ -2839,7 +3204,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar* case '<': { flushChars(buf, pos); returnState = state; - state = NS_HTML5TOKENIZER_TAG_OPEN_NON_PCDATA; + state = NS_HTML5TOKENIZER_RAWTEXT_RCDATA_LESS_THAN_SIGN_STATE; goto stateloop; } case '\0': { @@ -2860,6 +3225,132 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar* } } + case NS_HTML5TOKENIZER_RAWTEXT: { + for (; ; ) { + if (reconsume) { + reconsume = PR_FALSE; + } else { + if (++pos == endPos) { + goto stateloop_end; + } + c = checkChar(buf, pos); + } + switch(c) { + case '<': { + flushChars(buf, pos); + returnState = state; + state = NS_HTML5TOKENIZER_RAWTEXT_RCDATA_LESS_THAN_SIGN_STATE; + goto rawtextloop_end; + } + case '\0': { + emitReplacementCharacter(buf, pos); + continue; + } + case '\r': { + emitCarriageReturn(buf, pos); + goto stateloop_end; + } + case '\n': { + silentLineFeed(); + } + default: { + continue; + } + } + } + rawtextloop_end: ; + } + case NS_HTML5TOKENIZER_RAWTEXT_RCDATA_LESS_THAN_SIGN_STATE: { + for (; ; ) { + if (++pos == endPos) { + goto stateloop_end; + } + c = checkChar(buf, pos); + switch(c) { + case '/': { + index = 0; + clearStrBufForNextState(); + state = NS_HTML5TOKENIZER_NON_DATA_END_TAG_NAME; + goto rawtextrcdatalessthansignloop_end; + } + default: { + tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1); + cstart = pos; + state = returnState; + reconsume = PR_TRUE; + goto stateloop; + } + } + } + rawtextrcdatalessthansignloop_end: ; + } + case NS_HTML5TOKENIZER_NON_DATA_END_TAG_NAME: { + for (; ; ) { + if (++pos == endPos) { + goto stateloop_end; + } + c = checkChar(buf, pos); + if (index < contentModelElementNameAsArray.length) { + PRUnichar e = contentModelElementNameAsArray[index]; + PRUnichar folded = c; + if (c >= 'A' && c <= 'Z') { + folded += 0x20; + } + if (folded != e) { + tokenHandler->characters(nsHtml5Tokenizer::LT_SOLIDUS, 0, 2); + emitStrBuf(); + cstart = pos; + state = returnState; + reconsume = PR_TRUE; + goto stateloop; + } + appendStrBuf(c); + index++; + continue; + } else { + endTag = PR_TRUE; + tagName = contentModelElement; + switch(c) { + case '\r': { + silentCarriageReturn(); + state = NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME; + goto stateloop_end; + } + case '\n': { + silentLineFeed(); + } + case ' ': + case '\t': + case '\f': { + state = NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME; + goto stateloop; + } + case '/': { + state = NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG; + goto stateloop; + } + case '>': { + state = emitCurrentTagToken(PR_FALSE, pos); + if (shouldSuspend) { + goto stateloop_end; + } + goto stateloop; + } + default: { + tokenHandler->characters(nsHtml5Tokenizer::LT_SOLIDUS, 0, 2); + emitStrBuf(); + if (c == '\0') { + emitReplacementCharacter(buf, pos); + } else { + cstart = pos; + } + state = returnState; + goto stateloop; + } + } + } + } + } } } stateloop_end: ; @@ -2936,29 +3427,25 @@ nsHtml5Tokenizer::emitOrAppendStrBuf(PRInt32 returnState) void nsHtml5Tokenizer::handleNcrValue(PRInt32 returnState) { - if (value >= 0x80 && value <= 0x9f) { + if (value <= 0xFFFF) { + if (value >= 0x80 && value <= 0x9f) { - PRUnichar* val = nsHtml5NamedCharacters::WINDOWS_1252[value - 0x80]; - emitOrAppendOne(val, returnState); - } else if (value == 0x0D) { + PRUnichar* val = nsHtml5NamedCharacters::WINDOWS_1252[value - 0x80]; + emitOrAppendOne(val, returnState); + } else if (value == 0x0D) { - emitOrAppendOne(nsHtml5Tokenizer::LF, returnState); - } else if ((value >= 0x0000 && value <= 0x0008) || (value == 0x000B) || (value >= 0x000E && value <= 0x001F) || value == 0x007F) { + emitOrAppendOne(nsHtml5Tokenizer::LF, returnState); + } else if (value == 0x0) { - emitOrAppendOne(nsHtml5Tokenizer::REPLACEMENT_CHARACTER, returnState); - } else if ((value & 0xF800) == 0xD800) { + emitOrAppendOne(nsHtml5Tokenizer::REPLACEMENT_CHARACTER, returnState); + } else if ((value & 0xF800) == 0xD800) { - emitOrAppendOne(nsHtml5Tokenizer::REPLACEMENT_CHARACTER, returnState); - } else if ((value & 0xFFFE) == 0xFFFE) { - - emitOrAppendOne(nsHtml5Tokenizer::REPLACEMENT_CHARACTER, returnState); - } else if (value >= 0xFDD0 && value <= 0xFDEF) { - - emitOrAppendOne(nsHtml5Tokenizer::REPLACEMENT_CHARACTER, returnState); - } else if (value <= 0xFFFF) { - PRUnichar ch = (PRUnichar) value; - bmpChar[0] = ch; - emitOrAppendOne(bmpChar, returnState); + emitOrAppendOne(nsHtml5Tokenizer::REPLACEMENT_CHARACTER, returnState); + } else { + PRUnichar ch = (PRUnichar) value; + bmpChar[0] = ch; + emitOrAppendOne(bmpChar, returnState); + } } else if (value <= 0x10FFFF) { astralChar[0] = (PRUnichar) (NS_HTML5TOKENIZER_LEAD_OFFSET + (value >> 10)); astralChar[1] = (PRUnichar) (0xDC00 + (value & 0x3FF)); @@ -2976,7 +3463,7 @@ nsHtml5Tokenizer::eof() PRInt32 returnState = returnStateSave; eofloop: for (; ; ) { switch(state) { - case NS_HTML5TOKENIZER_TAG_OPEN_NON_PCDATA: { + case NS_HTML5TOKENIZER_SCRIPT_DATA_LESS_THAN_SIGN_STATE: { tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1); goto eofloop_end; } @@ -2985,7 +3472,7 @@ nsHtml5Tokenizer::eof() tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1); goto eofloop_end; } - case NS_HTML5TOKENIZER_CLOSE_TAG_OPEN_NOT_PCDATA: { + case NS_HTML5TOKENIZER_NON_DATA_END_TAG_NAME: { if (index < contentModelElementNameAsArray.length) { goto eofloop_end; } else { @@ -2993,7 +3480,7 @@ nsHtml5Tokenizer::eof() goto eofloop_end; } } - case NS_HTML5TOKENIZER_CLOSE_TAG_OPEN_PCDATA: { + case NS_HTML5TOKENIZER_CLOSE_TAG_OPEN: { tokenHandler->characters(nsHtml5Tokenizer::LT_SOLIDUS, 0, 2); goto eofloop_end; @@ -3104,6 +3591,8 @@ nsHtml5Tokenizer::eof() case NS_HTML5TOKENIZER_DOCTYPE_UBLIC: case NS_HTML5TOKENIZER_DOCTYPE_YSTEM: case NS_HTML5TOKENIZER_AFTER_DOCTYPE_NAME: + case NS_HTML5TOKENIZER_AFTER_DOCTYPE_PUBLIC_KEYWORD: + case NS_HTML5TOKENIZER_AFTER_DOCTYPE_SYSTEM_KEYWORD: case NS_HTML5TOKENIZER_BEFORE_DOCTYPE_PUBLIC_IDENTIFIER: { forceQuirks = PR_TRUE; @@ -3119,7 +3608,8 @@ nsHtml5Tokenizer::eof() goto eofloop_end; } case NS_HTML5TOKENIZER_AFTER_DOCTYPE_PUBLIC_IDENTIFIER: - case NS_HTML5TOKENIZER_BEFORE_DOCTYPE_SYSTEM_IDENTIFIER: { + case NS_HTML5TOKENIZER_BEFORE_DOCTYPE_SYSTEM_IDENTIFIER: + case NS_HTML5TOKENIZER_BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS: { forceQuirks = PR_TRUE; emitDoctypeToken(0); diff --git a/parser/html/nsHtml5Tokenizer.h b/parser/html/nsHtml5Tokenizer.h index d046a1908a2e..85995a6498d0 100644 --- a/parser/html/nsHtml5Tokenizer.h +++ b/parser/html/nsHtml5Tokenizer.h @@ -295,10 +295,10 @@ jArray nsHtml5Tokenizer::NOFRAMES_ARR = 0; #define NS_HTML5TOKENIZER_DATA 0 #define NS_HTML5TOKENIZER_RCDATA 1 -#define NS_HTML5TOKENIZER_CDATA 2 +#define NS_HTML5TOKENIZER_SCRIPT_DATA 2 #define NS_HTML5TOKENIZER_PLAINTEXT 3 #define NS_HTML5TOKENIZER_TAG_OPEN 4 -#define NS_HTML5TOKENIZER_CLOSE_TAG_OPEN_PCDATA 5 +#define NS_HTML5TOKENIZER_CLOSE_TAG_OPEN 5 #define NS_HTML5TOKENIZER_TAG_NAME 6 #define NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME 7 #define NS_HTML5TOKENIZER_ATTRIBUTE_NAME 8 @@ -330,7 +330,7 @@ jArray nsHtml5Tokenizer::NOFRAMES_ARR = 0; #define NS_HTML5TOKENIZER_COMMENT_END 34 #define NS_HTML5TOKENIZER_COMMENT_END_SPACE 35 #define NS_HTML5TOKENIZER_COMMENT_END_BANG 36 -#define NS_HTML5TOKENIZER_CLOSE_TAG_OPEN_NOT_PCDATA 37 +#define NS_HTML5TOKENIZER_NON_DATA_END_TAG_NAME 37 #define NS_HTML5TOKENIZER_MARKUP_DECLARATION_HYPHEN 38 #define NS_HTML5TOKENIZER_MARKUP_DECLARATION_OCTYPE 39 #define NS_HTML5TOKENIZER_DOCTYPE_UBLIC 40 @@ -346,13 +346,25 @@ jArray nsHtml5Tokenizer::NOFRAMES_ARR = 0; #define NS_HTML5TOKENIZER_CDATA_SECTION 50 #define NS_HTML5TOKENIZER_CDATA_RSQB 51 #define NS_HTML5TOKENIZER_CDATA_RSQB_RSQB 52 -#define NS_HTML5TOKENIZER_TAG_OPEN_NON_PCDATA 53 -#define NS_HTML5TOKENIZER_ESCAPE_EXCLAMATION 54 -#define NS_HTML5TOKENIZER_ESCAPE_EXCLAMATION_HYPHEN 55 -#define NS_HTML5TOKENIZER_ESCAPE 56 -#define NS_HTML5TOKENIZER_ESCAPE_HYPHEN 57 -#define NS_HTML5TOKENIZER_ESCAPE_HYPHEN_HYPHEN 58 +#define NS_HTML5TOKENIZER_SCRIPT_DATA_LESS_THAN_SIGN_STATE 53 +#define NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPE_START 54 +#define NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPE_START_DASH 55 +#define NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED 56 +#define NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_DASH 57 +#define NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_DASH_DASH 58 #define NS_HTML5TOKENIZER_BOGUS_COMMENT_HYPHEN 59 +#define NS_HTML5TOKENIZER_RAWTEXT 60 +#define NS_HTML5TOKENIZER_RAWTEXT_RCDATA_LESS_THAN_SIGN_STATE 61 +#define NS_HTML5TOKENIZER_AFTER_DOCTYPE_PUBLIC_KEYWORD 62 +#define NS_HTML5TOKENIZER_BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS 63 +#define NS_HTML5TOKENIZER_AFTER_DOCTYPE_SYSTEM_KEYWORD 64 +#define NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_LESS_THAN 65 +#define NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPE_START 66 +#define NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED 67 +#define NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN 68 +#define NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED_DASH 69 +#define NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH 70 +#define NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPE_END 71 #define NS_HTML5TOKENIZER_LEAD_OFFSET (0xD800 - (0x10000 >> 10)) #define NS_HTML5TOKENIZER_BUFFER_GROW_BY 1024 diff --git a/parser/html/nsHtml5TreeBuilder.cpp b/parser/html/nsHtml5TreeBuilder.cpp index d681da78588a..c10e91770540 100644 --- a/parser/html/nsHtml5TreeBuilder.cpp +++ b/parser/html/nsHtml5TreeBuilder.cpp @@ -97,10 +97,12 @@ nsHtml5TreeBuilder::startTokenization(nsHtml5Tokenizer* self) resetTheInsertionMode(); if (nsHtml5Atoms::title == contextName || nsHtml5Atoms::textarea == contextName) { tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_RCDATA, contextName); - } else if (nsHtml5Atoms::style == contextName || nsHtml5Atoms::script == contextName || nsHtml5Atoms::xmp == contextName || nsHtml5Atoms::iframe == contextName || nsHtml5Atoms::noembed == contextName || nsHtml5Atoms::noframes == contextName || (scriptingEnabled && nsHtml5Atoms::noscript == contextName)) { - tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_CDATA, contextName); + } else if (nsHtml5Atoms::style == contextName || nsHtml5Atoms::xmp == contextName || nsHtml5Atoms::iframe == contextName || nsHtml5Atoms::noembed == contextName || nsHtml5Atoms::noframes == contextName || (scriptingEnabled && nsHtml5Atoms::noscript == contextName)) { + tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_RAWTEXT, contextName); } else if (nsHtml5Atoms::plaintext == contextName) { tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_PLAINTEXT, contextName); + } else if (nsHtml5Atoms::script == contextName) { + tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_SCRIPT_DATA, contextName); } else { tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_DATA, contextName); } @@ -209,7 +211,7 @@ nsHtml5TreeBuilder::characters(PRUnichar* buf, PRInt32 start, PRInt32 length) case NS_HTML5TREE_BUILDER_IN_CAPTION: { reconstructTheActiveFormattingElements(); } - case NS_HTML5TREE_BUILDER_IN_CDATA_RCDATA: { + case NS_HTML5TREE_BUILDER_TEXT: { accumulateCharacters(buf, start, length); return; } @@ -495,7 +497,7 @@ nsHtml5TreeBuilder::eof() case NS_HTML5TREE_BUILDER_IN_BODY: { goto eofloop_end; } - case NS_HTML5TREE_BUILDER_IN_CDATA_RCDATA: { + case NS_HTML5TREE_BUILDER_TEXT: { if (originalMode == NS_HTML5TREE_BUILDER_AFTER_HEAD) { popOnEof(); @@ -765,12 +767,19 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu resetTheInsertionMode(); goto starttagloop; } - case NS_HTML5TREE_BUILDER_SCRIPT: + case NS_HTML5TREE_BUILDER_SCRIPT: { + appendToCurrentNodeAndPushElement(kNameSpaceID_XHTML, elementName, attributes); + originalMode = mode; + mode = NS_HTML5TREE_BUILDER_TEXT; + tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_SCRIPT_DATA, elementName); + attributes = nsnull; + goto starttagloop_end; + } case NS_HTML5TREE_BUILDER_STYLE: { appendToCurrentNodeAndPushElement(kNameSpaceID_XHTML, elementName, attributes); originalMode = mode; - mode = NS_HTML5TREE_BUILDER_IN_CDATA_RCDATA; - tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_CDATA, elementName); + mode = NS_HTML5TREE_BUILDER_TEXT; + tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_RAWTEXT, elementName); attributes = nsnull; goto starttagloop_end; } @@ -783,6 +792,12 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu attributes = nsnull; goto starttagloop_end; } + case NS_HTML5TREE_BUILDER_FORM: { + + appendVoidElementToCurrent(kNameSpaceID_XHTML, name, attributes); + attributes = nsnull; + goto starttagloop_end; + } default: { goto intableloop_end; @@ -904,7 +919,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu case NS_HTML5TREE_BUILDER_STYLE: case NS_HTML5TREE_BUILDER_SCRIPT: case NS_HTML5TREE_BUILDER_TITLE: - case NS_HTML5TREE_BUILDER_COMMAND_OR_EVENT_SOURCE: { + case NS_HTML5TREE_BUILDER_COMMAND: { goto inbodyloop_end; } case NS_HTML5TREE_BUILDER_BODY: { @@ -916,7 +931,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu case NS_HTML5TREE_BUILDER_P: case NS_HTML5TREE_BUILDER_DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU: case NS_HTML5TREE_BUILDER_UL_OR_OL_OR_DL: - case NS_HTML5TREE_BUILDER_ADDRESS_OR_DIR_OR_ARTICLE_OR_ASIDE_OR_DATAGRID_OR_DETAILS_OR_DIALOG_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_NAV_OR_SECTION: { + case NS_HTML5TREE_BUILDER_ADDRESS_OR_DIR_OR_ARTICLE_OR_ASIDE_OR_DATAGRID_OR_DETAILS_OR_HGROUP_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_NAV_OR_SECTION: { implicitlyCloseP(); appendToCurrentNodeAndPushElementMayFoster(kNameSpaceID_XHTML, elementName, attributes); attributes = nsnull; @@ -1058,15 +1073,6 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu attributes = nsnull; goto starttagloop_end; } - case NS_HTML5TREE_BUILDER_XMP: { - reconstructTheActiveFormattingElements(); - appendToCurrentNodeAndPushElementMayFoster(kNameSpaceID_XHTML, elementName, attributes); - originalMode = mode; - mode = NS_HTML5TREE_BUILDER_IN_CDATA_RCDATA; - tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_CDATA, elementName); - attributes = nsnull; - goto starttagloop_end; - } case NS_HTML5TREE_BUILDER_TABLE: { if (!quirks) { implicitlyCloseP(); @@ -1120,7 +1126,6 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu } appendToCurrentNodeAndPushFormElementMayFoster(formAttrs); appendVoidElementToCurrentMayFoster(kNameSpaceID_XHTML, nsHtml5ElementName::ELT_HR, nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES); - appendToCurrentNodeAndPushElementMayFoster(kNameSpaceID_XHTML, nsHtml5ElementName::ELT_P, nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES); appendToCurrentNodeAndPushElementMayFoster(kNameSpaceID_XHTML, nsHtml5ElementName::ELT_LABEL, nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES); PRInt32 promptIndex = attributes->getIndex(nsHtml5AttributeName::ATTR_PROMPT); if (promptIndex > -1) { @@ -1143,12 +1148,10 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu attributes->clearWithoutReleasingContents(); appendVoidElementToCurrentMayFoster(kNameSpaceID_XHTML, nsHtml5Atoms::input, inputAttributes, formPointer); pop(); - pop(); appendVoidElementToCurrentMayFoster(kNameSpaceID_XHTML, nsHtml5ElementName::ELT_HR, nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES); pop(); selfClosing = PR_FALSE; - delete formAttrs; - delete inputAttributes; + delete attributes; attributes = nsnull; goto starttagloop_end; } @@ -1156,11 +1159,21 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu appendToCurrentNodeAndPushElementMayFoster(kNameSpaceID_XHTML, elementName, attributes, formPointer); tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_RCDATA, elementName); originalMode = mode; - mode = NS_HTML5TREE_BUILDER_IN_CDATA_RCDATA; + mode = NS_HTML5TREE_BUILDER_TEXT; needToDropLF = PR_TRUE; attributes = nsnull; goto starttagloop_end; } + case NS_HTML5TREE_BUILDER_XMP: { + implicitlyCloseP(); + reconstructTheActiveFormattingElements(); + appendToCurrentNodeAndPushElementMayFoster(kNameSpaceID_XHTML, elementName, attributes); + originalMode = mode; + mode = NS_HTML5TREE_BUILDER_TEXT; + tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_RAWTEXT, elementName); + attributes = nsnull; + goto starttagloop_end; + } case NS_HTML5TREE_BUILDER_NOSCRIPT: { if (!scriptingEnabled) { reconstructTheActiveFormattingElements(); @@ -1175,8 +1188,8 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu case NS_HTML5TREE_BUILDER_NOEMBED: { appendToCurrentNodeAndPushElementMayFoster(kNameSpaceID_XHTML, elementName, attributes); originalMode = mode; - mode = NS_HTML5TREE_BUILDER_IN_CDATA_RCDATA; - tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_CDATA, elementName); + mode = NS_HTML5TREE_BUILDER_TEXT; + tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_RAWTEXT, elementName); attributes = nsnull; goto starttagloop_end; } @@ -1310,7 +1323,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu goto starttagloop_end; } case NS_HTML5TREE_BUILDER_BASE: - case NS_HTML5TREE_BUILDER_COMMAND_OR_EVENT_SOURCE: { + case NS_HTML5TREE_BUILDER_COMMAND: { appendVoidElementToCurrentMayFoster(kNameSpaceID_XHTML, elementName, attributes); selfClosing = PR_FALSE; attributes = nsnull; @@ -1323,7 +1336,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu case NS_HTML5TREE_BUILDER_TITLE: { appendToCurrentNodeAndPushElementMayFoster(kNameSpaceID_XHTML, elementName, attributes); originalMode = mode; - mode = NS_HTML5TREE_BUILDER_IN_CDATA_RCDATA; + mode = NS_HTML5TREE_BUILDER_TEXT; tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_RCDATA, elementName); attributes = nsnull; goto starttagloop_end; @@ -1332,8 +1345,8 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu if (scriptingEnabled) { appendToCurrentNodeAndPushElement(kNameSpaceID_XHTML, elementName, attributes); originalMode = mode; - mode = NS_HTML5TREE_BUILDER_IN_CDATA_RCDATA; - tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_CDATA, elementName); + mode = NS_HTML5TREE_BUILDER_TEXT; + tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_RAWTEXT, elementName); } else { appendToCurrentNodeAndPushElementMayFoster(kNameSpaceID_XHTML, elementName, attributes); mode = NS_HTML5TREE_BUILDER_IN_HEAD_NOSCRIPT; @@ -1341,13 +1354,20 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu attributes = nsnull; goto starttagloop_end; } - case NS_HTML5TREE_BUILDER_SCRIPT: + case NS_HTML5TREE_BUILDER_SCRIPT: { + appendToCurrentNodeAndPushElementMayFoster(kNameSpaceID_XHTML, elementName, attributes); + originalMode = mode; + mode = NS_HTML5TREE_BUILDER_TEXT; + tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_SCRIPT_DATA, elementName); + attributes = nsnull; + goto starttagloop_end; + } case NS_HTML5TREE_BUILDER_STYLE: case NS_HTML5TREE_BUILDER_NOFRAMES: { appendToCurrentNodeAndPushElementMayFoster(kNameSpaceID_XHTML, elementName, attributes); originalMode = mode; - mode = NS_HTML5TREE_BUILDER_IN_CDATA_RCDATA; - tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_CDATA, elementName); + mode = NS_HTML5TREE_BUILDER_TEXT; + tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_RAWTEXT, elementName); attributes = nsnull; goto starttagloop_end; } @@ -1389,8 +1409,8 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu case NS_HTML5TREE_BUILDER_NOFRAMES: { appendToCurrentNodeAndPushElement(kNameSpaceID_XHTML, elementName, attributes); originalMode = mode; - mode = NS_HTML5TREE_BUILDER_IN_CDATA_RCDATA; - tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_CDATA, elementName); + mode = NS_HTML5TREE_BUILDER_TEXT; + tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_RAWTEXT, elementName); attributes = nsnull; goto starttagloop_end; } @@ -1444,7 +1464,15 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu case NS_HTML5TREE_BUILDER_TD_OR_TH: case NS_HTML5TREE_BUILDER_TABLE: { - endSelect(); + eltPos = findLastInTableScope(nsHtml5Atoms::select); + if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) { + + goto starttagloop_end; + } + while (currentPtr >= eltPos) { + pop(); + } + resetTheInsertionMode(); continue; } default: @@ -1494,16 +1522,25 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu } } case NS_HTML5TREE_BUILDER_INPUT: - case NS_HTML5TREE_BUILDER_TEXTAREA: { + case NS_HTML5TREE_BUILDER_TEXTAREA: + case NS_HTML5TREE_BUILDER_KEYGEN: { - endSelect(); + eltPos = findLastInTableScope(nsHtml5Atoms::select); + if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) { + + goto starttagloop_end; + } + while (currentPtr >= eltPos) { + pop(); + } + resetTheInsertionMode(); continue; } case NS_HTML5TREE_BUILDER_SCRIPT: { appendToCurrentNodeAndPushElementMayFoster(kNameSpaceID_XHTML, elementName, attributes); originalMode = mode; - mode = NS_HTML5TREE_BUILDER_IN_CDATA_RCDATA; - tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_CDATA, elementName); + mode = NS_HTML5TREE_BUILDER_TEXT; + tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_SCRIPT_DATA, elementName); attributes = nsnull; goto starttagloop_end; } @@ -1556,8 +1593,8 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu case NS_HTML5TREE_BUILDER_NOFRAMES: { appendToCurrentNodeAndPushElement(kNameSpaceID_XHTML, elementName, attributes); originalMode = mode; - mode = NS_HTML5TREE_BUILDER_IN_CDATA_RCDATA; - tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_CDATA, elementName); + mode = NS_HTML5TREE_BUILDER_TEXT; + tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_RAWTEXT, elementName); attributes = nsnull; goto starttagloop_end; } @@ -1626,7 +1663,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu } else { appendToCurrentNodeAndPushBodyElement(attributes); } - mode = NS_HTML5TREE_BUILDER_FRAMESET_OK; + mode = NS_HTML5TREE_BUILDER_IN_BODY; attributes = nsnull; goto starttagloop_end; } @@ -1669,8 +1706,8 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu pushHeadPointerOntoStack(); appendToCurrentNodeAndPushElement(kNameSpaceID_XHTML, elementName, attributes); originalMode = mode; - mode = NS_HTML5TREE_BUILDER_IN_CDATA_RCDATA; - tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_CDATA, elementName); + mode = NS_HTML5TREE_BUILDER_TEXT; + tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_SCRIPT_DATA, elementName); attributes = nsnull; goto starttagloop_end; } @@ -1680,8 +1717,8 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu pushHeadPointerOntoStack(); appendToCurrentNodeAndPushElement(kNameSpaceID_XHTML, elementName, attributes); originalMode = mode; - mode = NS_HTML5TREE_BUILDER_IN_CDATA_RCDATA; - tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_CDATA, elementName); + mode = NS_HTML5TREE_BUILDER_TEXT; + tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_RAWTEXT, elementName); attributes = nsnull; goto starttagloop_end; } @@ -1690,7 +1727,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu pushHeadPointerOntoStack(); appendToCurrentNodeAndPushElement(kNameSpaceID_XHTML, elementName, attributes); originalMode = mode; - mode = NS_HTML5TREE_BUILDER_IN_CDATA_RCDATA; + mode = NS_HTML5TREE_BUILDER_TEXT; tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_RCDATA, elementName); attributes = nsnull; goto starttagloop_end; @@ -1727,8 +1764,8 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu case NS_HTML5TREE_BUILDER_NOFRAMES: { appendToCurrentNodeAndPushElementMayFoster(kNameSpaceID_XHTML, elementName, attributes); originalMode = mode; - mode = NS_HTML5TREE_BUILDER_IN_CDATA_RCDATA; - tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_CDATA, elementName); + mode = NS_HTML5TREE_BUILDER_TEXT; + tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_SCRIPT_DATA, elementName); attributes = nsnull; goto starttagloop_end; } @@ -2222,7 +2259,7 @@ nsHtml5TreeBuilder::endTag(nsHtml5ElementName* elementName) case NS_HTML5TREE_BUILDER_UL_OR_OL_OR_DL: case NS_HTML5TREE_BUILDER_PRE_OR_LISTING: case NS_HTML5TREE_BUILDER_FIELDSET: - case NS_HTML5TREE_BUILDER_ADDRESS_OR_DIR_OR_ARTICLE_OR_ASIDE_OR_DATAGRID_OR_DETAILS_OR_DIALOG_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_NAV_OR_SECTION: { + case NS_HTML5TREE_BUILDER_ADDRESS_OR_DIR_OR_ARTICLE_OR_ASIDE_OR_DATAGRID_OR_DETAILS_OR_HGROUP_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_NAV_OR_SECTION: { eltPos = findLastInScope(name); if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) { @@ -2280,8 +2317,22 @@ nsHtml5TreeBuilder::endTag(nsHtml5ElementName* elementName) } goto endtagloop_end; } - case NS_HTML5TREE_BUILDER_DD_OR_DT: case NS_HTML5TREE_BUILDER_LI: { + eltPos = findLastInListScope(name); + if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) { + + } else { + generateImpliedEndTagsExceptFor(name); + if (eltPos != currentPtr) { + + } + while (currentPtr >= eltPos) { + pop(); + } + } + goto endtagloop_end; + } + case NS_HTML5TREE_BUILDER_DD_OR_DT: { eltPos = findLastInScope(name); if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) { @@ -2436,7 +2487,15 @@ nsHtml5TreeBuilder::endTag(nsHtml5ElementName* elementName) case NS_HTML5TREE_BUILDER_TD_OR_TH: { if (findLastInTableScope(name) != NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) { - endSelect(); + eltPos = findLastInTableScope(nsHtml5Atoms::select); + if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) { + + goto endtagloop_end; + } + while (currentPtr >= eltPos) { + pop(); + } + resetTheInsertionMode(); continue; } else { goto endtagloop_end; @@ -2469,7 +2528,16 @@ nsHtml5TreeBuilder::endTag(nsHtml5ElementName* elementName) goto endtagloop_end; } case NS_HTML5TREE_BUILDER_SELECT: { - endSelect(); + eltPos = findLastInTableScope(nsHtml5Atoms::select); + if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) { + + + goto endtagloop_end; + } + while (currentPtr >= eltPos) { + pop(); + } + resetTheInsertionMode(); goto endtagloop_end; } default: { @@ -2534,9 +2602,20 @@ nsHtml5TreeBuilder::endTag(nsHtml5ElementName* elementName) continue; } case NS_HTML5TREE_BUILDER_BEFORE_HTML: { - appendHtmlElementToDocumentAndPush(); - mode = NS_HTML5TREE_BUILDER_BEFORE_HEAD; - continue; + switch(group) { + case NS_HTML5TREE_BUILDER_HEAD: + case NS_HTML5TREE_BUILDER_BR: + case NS_HTML5TREE_BUILDER_HTML: + case NS_HTML5TREE_BUILDER_BODY: { + appendHtmlElementToDocumentAndPush(); + mode = NS_HTML5TREE_BUILDER_BEFORE_HEAD; + continue; + } + default: { + + goto endtagloop_end; + } + } } case NS_HTML5TREE_BUILDER_BEFORE_HEAD: { switch(group) { @@ -2618,11 +2697,11 @@ nsHtml5TreeBuilder::endTag(nsHtml5ElementName* elementName) mode = NS_HTML5TREE_BUILDER_IN_FRAMESET; continue; } - case NS_HTML5TREE_BUILDER_IN_CDATA_RCDATA: { - if (originalMode == NS_HTML5TREE_BUILDER_AFTER_HEAD) { - pop(); - } + case NS_HTML5TREE_BUILDER_TEXT: { pop(); + if (originalMode == NS_HTML5TREE_BUILDER_AFTER_HEAD) { + silentPop(); + } mode = originalMode; goto endtagloop_end; } @@ -2634,21 +2713,6 @@ nsHtml5TreeBuilder::endTag(nsHtml5ElementName* elementName) } } -void -nsHtml5TreeBuilder::endSelect() -{ - PRInt32 eltPos = findLastInTableScope(nsHtml5Atoms::select); - if (eltPos == NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK) { - - - return; - } - while (currentPtr >= eltPos) { - pop(); - } - resetTheInsertionMode(); -} - PRInt32 nsHtml5TreeBuilder::findLastInTableScopeOrRootTbodyTheadTfoot() { @@ -2697,6 +2761,19 @@ nsHtml5TreeBuilder::findLastInScope(nsIAtom* name) return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK; } +PRInt32 +nsHtml5TreeBuilder::findLastInListScope(nsIAtom* name) +{ + for (PRInt32 i = currentPtr; i > 0; i--) { + if (stack[i]->name == name) { + return i; + } else if (stack[i]->scoping || stack[i]->name == nsHtml5Atoms::ul || stack[i]->name == nsHtml5Atoms::ol) { + return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK; + } + } + return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK; +} + PRInt32 nsHtml5TreeBuilder::findLastInScopeHn() { @@ -2984,6 +3061,19 @@ nsHtml5TreeBuilder::push(nsHtml5StackNode* node) elementPushed(node->ns, node->popName, node->node); } +void +nsHtml5TreeBuilder::silentPush(nsHtml5StackNode* node) +{ + currentPtr++; + if (currentPtr == stack.length) { + jArray newStack = jArray(stack.length + 64); + nsHtml5ArrayCopy::arraycopy(stack, newStack, stack.length); + stack.release(); + stack = newStack; + } + stack[currentPtr] = node; +} + void nsHtml5TreeBuilder::append(nsHtml5StackNode* node) { @@ -3274,14 +3364,12 @@ nsHtml5TreeBuilder::addAttributesToHtml(nsHtml5HtmlAttributes* attributes) void nsHtml5TreeBuilder::pushHeadPointerOntoStack() { + + + flushCharacters(); - if (!headPointer) { - - push(stack[currentPtr]); - } else { - push(new nsHtml5StackNode(kNameSpaceID_XHTML, nsHtml5ElementName::ELT_HEAD, headPointer)); - } + silentPush(new nsHtml5StackNode(kNameSpaceID_XHTML, nsHtml5ElementName::ELT_HEAD, headPointer)); } void @@ -3364,6 +3452,16 @@ nsHtml5TreeBuilder::pop() node->release(); } +void +nsHtml5TreeBuilder::silentPop() +{ + flushCharacters(); + nsHtml5StackNode* node = stack[currentPtr]; + + currentPtr--; + node->release(); +} + void nsHtml5TreeBuilder::popOnEof() { @@ -3601,6 +3699,18 @@ nsHtml5TreeBuilder::appendVoidElementToCurrent(PRInt32 ns, nsIAtom* name, nsHtml ; } +void +nsHtml5TreeBuilder::appendVoidElementToCurrent(PRInt32 ns, nsIAtom* name, nsHtml5HtmlAttributes* attributes) +{ + flushCharacters(); + nsIContent** elt = createElement(ns, name, attributes); + nsHtml5StackNode* current = stack[currentPtr]; + appendElement(elt, current->node); + elementPushed(ns, name, elt); + elementPopped(ns, name, elt); + ; +} + void nsHtml5TreeBuilder::accumulateCharacter(PRUnichar c) { diff --git a/parser/html/nsHtml5TreeBuilder.h b/parser/html/nsHtml5TreeBuilder.h index 4799d346b20a..fc8089ba4bed 100644 --- a/parser/html/nsHtml5TreeBuilder.h +++ b/parser/html/nsHtml5TreeBuilder.h @@ -110,11 +110,11 @@ class nsHtml5TreeBuilder : public nsAHtml5TreeBuilderState public: void endTag(nsHtml5ElementName* elementName); private: - void endSelect(); PRInt32 findLastInTableScopeOrRootTbodyTheadTfoot(); PRInt32 findLast(nsIAtom* name); PRInt32 findLastInTableScope(nsIAtom* name); PRInt32 findLastInScope(nsIAtom* name); + PRInt32 findLastInListScope(nsIAtom* name); PRInt32 findLastInScopeHn(); PRBool hasForeignInScope(); void generateImpliedEndTagsExceptFor(nsIAtom* name); @@ -131,6 +131,7 @@ class nsHtml5TreeBuilder : public nsAHtml5TreeBuilderState PRBool clearLastStackSlot(); PRBool clearLastListSlot(); void push(nsHtml5StackNode* node); + void silentPush(nsHtml5StackNode* node); void append(nsHtml5StackNode* node); inline void insertMarker() { @@ -160,6 +161,7 @@ class nsHtml5TreeBuilder : public nsAHtml5TreeBuilderState void insertIntoFosterParent(nsIContent** child); PRBool isInStack(nsHtml5StackNode* node); void pop(); + void silentPop(); void popOnEof(); void appendHtmlElementToDocumentAndPush(nsHtml5HtmlAttributes* attributes); void appendHtmlElementToDocumentAndPush(); @@ -177,6 +179,7 @@ class nsHtml5TreeBuilder : public nsAHtml5TreeBuilderState void appendVoidElementToCurrentMayFoster(PRInt32 ns, nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes); void appendVoidElementToCurrentMayFosterCamelCase(PRInt32 ns, nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes); void appendVoidElementToCurrent(PRInt32 ns, nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContent** form); + void appendVoidElementToCurrent(PRInt32 ns, nsIAtom* name, nsHtml5HtmlAttributes* attributes); protected: void accumulateCharacters(PRUnichar* buf, PRInt32 start, PRInt32 length); void accumulateCharacter(PRUnichar c); @@ -289,10 +292,10 @@ jArray nsHtml5TreeBuilder::QUIRKY_PUBLIC_IDS = nsnull; #define NS_HTML5TREE_BUILDER_EMBED_OR_IMG 48 #define NS_HTML5TREE_BUILDER_AREA_OR_BASEFONT_OR_BGSOUND_OR_SPACER_OR_WBR 49 #define NS_HTML5TREE_BUILDER_DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU 50 -#define NS_HTML5TREE_BUILDER_ADDRESS_OR_DIR_OR_ARTICLE_OR_ASIDE_OR_DATAGRID_OR_DETAILS_OR_DIALOG_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_NAV_OR_SECTION 51 +#define NS_HTML5TREE_BUILDER_ADDRESS_OR_DIR_OR_ARTICLE_OR_ASIDE_OR_DATAGRID_OR_DETAILS_OR_HGROUP_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_NAV_OR_SECTION 51 #define NS_HTML5TREE_BUILDER_RUBY_OR_SPAN_OR_SUB_OR_SUP_OR_VAR 52 #define NS_HTML5TREE_BUILDER_RT_OR_RP 53 -#define NS_HTML5TREE_BUILDER_COMMAND_OR_EVENT_SOURCE 54 +#define NS_HTML5TREE_BUILDER_COMMAND 54 #define NS_HTML5TREE_BUILDER_PARAM_OR_SOURCE 55 #define NS_HTML5TREE_BUILDER_MGLYPH_OR_MALIGNMARK 56 #define NS_HTML5TREE_BUILDER_MI_MO_MN_MS_MTEXT 57 @@ -324,7 +327,7 @@ jArray nsHtml5TreeBuilder::QUIRKY_PUBLIC_IDS = nsnull; #define NS_HTML5TREE_BUILDER_AFTER_FRAMESET 17 #define NS_HTML5TREE_BUILDER_AFTER_AFTER_BODY 18 #define NS_HTML5TREE_BUILDER_AFTER_AFTER_FRAMESET 19 -#define NS_HTML5TREE_BUILDER_IN_CDATA_RCDATA 20 +#define NS_HTML5TREE_BUILDER_TEXT 20 #define NS_HTML5TREE_BUILDER_FRAMESET_OK 21 #define NS_HTML5TREE_BUILDER_CHARSET_INITIAL 0 #define NS_HTML5TREE_BUILDER_CHARSET_C 1 diff --git a/parser/html/nsHtml5TreeBuilderCppSupplement.h b/parser/html/nsHtml5TreeBuilderCppSupplement.h index 43cadf8bb371..4e43e6ad8f73 100644 --- a/parser/html/nsHtml5TreeBuilderCppSupplement.h +++ b/parser/html/nsHtml5TreeBuilderCppSupplement.h @@ -59,6 +59,7 @@ nsHtml5TreeBuilder::nsHtml5TreeBuilder(nsAHtml5TreeOpSink* aOpSink) , mOpSink(aOpSink) , mHandles(new nsIContent*[NS_HTML5_TREE_BUILDER_HANDLE_ARRAY_LENGTH]) , mHandlesUsed(0) + , mCurrentHtmlScriptIsAsyncOrDefer(PR_FALSE) #ifdef DEBUG , mActive(PR_FALSE) #endif @@ -164,7 +165,7 @@ nsHtml5TreeBuilder::createElement(PRInt32 aNamespace, nsIAtom* aName, nsHtml5Htm } else if (nsHtml5Atoms::script == aName) { nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(); NS_ASSERTION(treeOp, "Tree op allocation failed."); - treeOp->Init(eTreeOpSetScriptLineNumber, content, tokenizer->getLineNumber()); + treeOp->Init(eTreeOpSetScriptLineNumberAndFreeze, content, tokenizer->getLineNumber()); nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_SRC); if (url) { @@ -174,6 +175,9 @@ nsHtml5TreeBuilder::createElement(PRInt32 aNamespace, nsIAtom* aName, nsHtml5Htm *url, (charset) ? *charset : EmptyString(), (type) ? *type : EmptyString())); + mCurrentHtmlScriptIsAsyncOrDefer = + aAttributes->contains(nsHtml5AttributeName::ATTR_ASYNC) || + aAttributes->contains(nsHtml5AttributeName::ATTR_DEFER); } } else if (nsHtml5Atoms::link == aName) { nsString* rel = aAttributes->getValue(nsHtml5AttributeName::ATTR_REL); @@ -208,7 +212,7 @@ nsHtml5TreeBuilder::createElement(PRInt32 aNamespace, nsIAtom* aName, nsHtml5Htm } else if (nsHtml5Atoms::script == aName) { nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(); NS_ASSERTION(treeOp, "Tree op allocation failed."); - treeOp->Init(eTreeOpSetScriptLineNumber, content, tokenizer->getLineNumber()); + treeOp->Init(eTreeOpSetScriptLineNumberAndFreeze, content, tokenizer->getLineNumber()); nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_XLINK_HREF); if (url) { @@ -233,7 +237,7 @@ nsHtml5TreeBuilder::createElement(PRInt32 aNamespace, nsIAtom* aName, nsHtml5Htm break; } } else if (aNamespace != kNameSpaceID_MathML) { - // No speculative loader--just line numbers + // No speculative loader--just line numbers and defer/async check if (nsHtml5Atoms::style == aName) { nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(); NS_ASSERTION(treeOp, "Tree op allocation failed."); @@ -241,7 +245,13 @@ nsHtml5TreeBuilder::createElement(PRInt32 aNamespace, nsIAtom* aName, nsHtml5Htm } else if (nsHtml5Atoms::script == aName) { nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(); NS_ASSERTION(treeOp, "Tree op allocation failed."); - treeOp->Init(eTreeOpSetScriptLineNumber, content, tokenizer->getLineNumber()); + treeOp->Init(eTreeOpSetScriptLineNumberAndFreeze, content, tokenizer->getLineNumber()); + if (aNamespace == kNameSpaceID_XHTML) { + mCurrentHtmlScriptIsAsyncOrDefer = + aAttributes->contains(nsHtml5AttributeName::ATTR_SRC) && + (aAttributes->contains(nsHtml5AttributeName::ATTR_ASYNC) || + aAttributes->contains(nsHtml5AttributeName::ATTR_DEFER)); + } } } @@ -314,15 +324,9 @@ nsHtml5TreeBuilder::insertFosterParentedCharacters(PRUnichar* aBuffer, PRInt32 a PRUnichar* bufferCopy = new PRUnichar[aLength]; memcpy(bufferCopy, aBuffer, aLength * sizeof(PRUnichar)); - nsIContent** text = AllocateContentHandle(); - nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(); NS_ASSERTION(treeOp, "Tree op allocation failed."); - treeOp->Init(eTreeOpCreateTextNode, bufferCopy, aLength, text); - - treeOp = mOpQueue.AppendElement(); - NS_ASSERTION(treeOp, "Tree op allocation failed."); - treeOp->Init(eTreeOpFosterParent, text, aStackParent, aTable); + treeOp->Init(eTreeOpFosterParentText, bufferCopy, aLength, aStackParent, aTable); } void @@ -346,15 +350,9 @@ nsHtml5TreeBuilder::appendCharacters(nsIContent** aParent, PRUnichar* aBuffer, P PRUnichar* bufferCopy = new PRUnichar[aLength]; memcpy(bufferCopy, aBuffer, aLength * sizeof(PRUnichar)); - nsIContent** text = AllocateContentHandle(); - nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(); NS_ASSERTION(treeOp, "Tree op allocation failed."); - treeOp->Init(eTreeOpCreateTextNode, bufferCopy, aLength, text); - - treeOp = mOpQueue.AppendElement(); - NS_ASSERTION(treeOp, "Tree op allocation failed."); - treeOp->Init(eTreeOpAppend, text, aParent); + treeOp->Init(eTreeOpAppendText, bufferCopy, aLength, aParent); } void @@ -366,15 +364,9 @@ nsHtml5TreeBuilder::appendComment(nsIContent** aParent, PRUnichar* aBuffer, PRIn PRUnichar* bufferCopy = new PRUnichar[aLength]; memcpy(bufferCopy, aBuffer, aLength * sizeof(PRUnichar)); - nsIContent** comment = AllocateContentHandle(); - nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(); NS_ASSERTION(treeOp, "Tree op allocation failed."); - treeOp->Init(eTreeOpCreateComment, bufferCopy, aLength, comment); - - treeOp = mOpQueue.AppendElement(); - NS_ASSERTION(treeOp, "Tree op allocation failed."); - treeOp->Init(eTreeOpAppend, comment, aParent); + treeOp->Init(eTreeOpAppendComment, bufferCopy, aLength, aParent); } void @@ -385,15 +377,9 @@ nsHtml5TreeBuilder::appendCommentToDocument(PRUnichar* aBuffer, PRInt32 aStart, PRUnichar* bufferCopy = new PRUnichar[aLength]; memcpy(bufferCopy, aBuffer, aLength * sizeof(PRUnichar)); - nsIContent** comment = AllocateContentHandle(); - nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(); NS_ASSERTION(treeOp, "Tree op allocation failed."); - treeOp->Init(eTreeOpCreateComment, bufferCopy, aLength, comment); - - treeOp = mOpQueue.AppendElement(); - NS_ASSERTION(treeOp, "Tree op allocation failed."); - treeOp->Init(eTreeOpAppendToDocument, comment); + treeOp->Init(eTreeOpAppendCommentToDocument, bufferCopy, aLength); } void @@ -423,6 +409,7 @@ nsHtml5TreeBuilder::markMalformedIfScript(nsIContent** aElement) void nsHtml5TreeBuilder::start(PRBool fragment) { + mCurrentHtmlScriptIsAsyncOrDefer = PR_FALSE; #ifdef DEBUG mActive = PR_TRUE; #endif @@ -442,15 +429,9 @@ nsHtml5TreeBuilder::appendDoctypeToDocument(nsIAtom* aName, nsString* aPublicId, { NS_PRECONDITION(aName, "Null name"); - nsIContent** content = AllocateContentHandle(); - nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(); NS_ASSERTION(treeOp, "Tree op allocation failed."); - treeOp->Init(aName, *aPublicId, *aSystemId, content); - - treeOp = mOpQueue.AppendElement(); - NS_ASSERTION(treeOp, "Tree op allocation failed."); - treeOp->Init(eTreeOpAppendToDocument, content); + treeOp->Init(aName, *aPublicId, *aSystemId); // nsXMLContentSink can flush here, but what's the point? // It can also interrupt here, but we can't. } @@ -483,6 +464,15 @@ nsHtml5TreeBuilder::elementPopped(PRInt32 aNamespace, nsIAtom* aName, nsIContent } // we now have only SVG and HTML if (aName == nsHtml5Atoms::script) { + if (mCurrentHtmlScriptIsAsyncOrDefer) { + NS_ASSERTION(aNamespace == kNameSpaceID_XHTML, + "Only HTML scripts may be async/defer."); + nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(); + NS_ASSERTION(treeOp, "Tree op allocation failed."); + treeOp->Init(eTreeOpRunScriptAsyncDefer, aElement); + mCurrentHtmlScriptIsAsyncOrDefer = PR_FALSE; + return; + } requestSuspension(); nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(); NS_ASSERTION(treeOp, "Tree op allocation failed."); @@ -541,6 +531,14 @@ nsHtml5TreeBuilder::elementPopped(PRInt32 aNamespace, nsIAtom* aName, nsIContent } if (aName == nsHtml5Atoms::input || aName == nsHtml5Atoms::button) { + if (!formPointer) { + // If form inputs don't belong to a form, their state preservation + // won't work right without an append notification flush at this + // point. See bug 497861. + nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(); + NS_ASSERTION(treeOp, "Tree op allocation failed."); + treeOp->Init(eTreeOpFlushPendingAppendNotifications); + } nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(); NS_ASSERTION(treeOp, "Tree op allocation failed."); treeOp->Init(eTreeOpDoneCreatingElement, aElement); @@ -606,16 +604,14 @@ nsHtml5TreeBuilder::HasScript() return mOpQueue.ElementAt(len - 1).IsRunScript(); } -void +PRBool nsHtml5TreeBuilder::Flush() { - mOpSink->ForcedFlush(mOpQueue); -} - -void -nsHtml5TreeBuilder::MaybeFlush() -{ - mOpSink->MaybeFlush(mOpQueue); + PRBool hasOps = !mOpQueue.IsEmpty(); + if (hasOps) { + mOpSink->MoveOpsFrom(mOpQueue); + } + return hasOps; } void @@ -668,6 +664,14 @@ nsHtml5TreeBuilder::DropSpeculativeLoader() { mSpeculativeLoader = nsnull; } +PRBool +nsHtml5TreeBuilder::IsDiscretionaryFlushSafe() +{ + return !(charBufferLen && + currentPtr >= 0 && + stack[currentPtr]->fosterParenting); +} + // DocumentModeHandler void nsHtml5TreeBuilder::documentMode(nsHtml5DocumentMode m) diff --git a/parser/html/nsHtml5TreeBuilderHSupplement.h b/parser/html/nsHtml5TreeBuilderHSupplement.h index 02059423fd8d..bff38d1354db 100644 --- a/parser/html/nsHtml5TreeBuilderHSupplement.h +++ b/parser/html/nsHtml5TreeBuilderHSupplement.h @@ -45,6 +45,7 @@ PRInt32 mHandlesUsed; nsTArray > mOldHandles; nsRefPtr mSpeculativeLoader; + PRBool mCurrentHtmlScriptIsAsyncOrDefer; #ifdef DEBUG PRBool mActive; #endif @@ -63,6 +64,8 @@ ~nsHtml5TreeBuilder(); + PRBool IsDiscretionaryFlushSafe(); + PRBool HasScript(); void SetOpSink(nsAHtml5TreeOpSink* aOpSink) { @@ -77,9 +80,7 @@ void DropSpeculativeLoader(); - void Flush(); - - void MaybeFlush(); + PRBool Flush(); void SetDocumentCharset(nsACString& aCharset); diff --git a/parser/html/nsHtml5TreeOpExecutor.cpp b/parser/html/nsHtml5TreeOpExecutor.cpp index dbc9ce245d97..594c9d6bf4c8 100644 --- a/parser/html/nsHtml5TreeOpExecutor.cpp +++ b/parser/html/nsHtml5TreeOpExecutor.cpp @@ -60,7 +60,6 @@ #define NS_HTML5_TREE_OP_EXECUTOR_MAX_QUEUE_TIME 3000UL // milliseconds #define NS_HTML5_TREE_OP_EXECUTOR_DEFAULT_QUEUE_LENGTH 200 #define NS_HTML5_TREE_OP_EXECUTOR_MIN_QUEUE_LENGTH 100 -#define NS_HTML5_TREE_OP_EXECUTOR_MAX_TIME_WITHOUT_FLUSH 5000 // milliseconds NS_IMPL_CYCLE_COLLECTION_CLASS(nsHtml5TreeOpExecutor) @@ -74,41 +73,21 @@ NS_IMPL_ADDREF_INHERITED(nsHtml5TreeOpExecutor, nsContentSink) NS_IMPL_RELEASE_INHERITED(nsHtml5TreeOpExecutor, nsContentSink) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsHtml5TreeOpExecutor, nsContentSink) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mFlushTimer) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mScriptElement) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mOwnedElements) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mOwnedNonElements) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsHtml5TreeOpExecutor, nsContentSink) - if (tmp->mFlushTimer) { - tmp->mFlushTimer->Cancel(); - } - NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mFlushTimer) - NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mScriptElement) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mOwnedElements) - NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mOwnedNonElements) NS_IMPL_CYCLE_COLLECTION_UNLINK_END nsHtml5TreeOpExecutor::nsHtml5TreeOpExecutor() - : mFlushTimer(do_CreateInstance("@mozilla.org/timer;1")) { - // zeroing operator new for everything else + // zeroing operator new for everything } nsHtml5TreeOpExecutor::~nsHtml5TreeOpExecutor() { NS_ASSERTION(mOpQueue.IsEmpty(), "Somehow there's stuff in the op queue."); - if (mFlushTimer) { - mFlushTimer->Cancel(); // XXX why is this even necessary? it is, though. - } - mFlushTimer = nsnull; -} - -static void -TimerCallbackFunc(nsITimer* aTimer, void* aClosure) -{ - (static_cast (aClosure))->Flush(); } // nsIContentSink @@ -123,8 +102,17 @@ nsHtml5TreeOpExecutor::WillParse() NS_IMETHODIMP nsHtml5TreeOpExecutor::DidBuildModel(PRBool aTerminated) { - NS_PRECONDITION(mStarted && mParser, - "Bad life cycle."); + NS_PRECONDITION(mStarted, "Bad life cycle."); + + // Break out of update batch if we are in one + EndDocUpdate(); + + // If the above caused a call to nsIParser::Terminate(), let that call + // win. + if (!mParser) { + return NS_OK; + } + // This is comes from nsXMLContentSink DidBuildModelImpl(aTerminated); mDocument->ScriptLoader()->RemoveObserver(this); @@ -276,22 +264,23 @@ void nsHtml5TreeOpExecutor::Flush() { if (!mParser) { - mFlushTimer->Cancel(); return; } - if (mFlushing) { + if (mFlushState != eNotFlushing) { return; } - mFlushing = PR_TRUE; + mFlushState = eInFlush; nsRefPtr kungFuDeathGrip(this); // avoid crashing near EOF nsCOMPtr parserKungFuDeathGrip(mParser); if (mReadingFromStage) { - mStage.RetrieveOperations(mOpQueue); + mStage.MoveOpsTo(mOpQueue); } + nsIContent* scriptElement = nsnull; + BeginDocUpdate(); PRIntervalTime flushStart = 0; @@ -308,13 +297,8 @@ nsHtml5TreeOpExecutor::Flush() // The previous tree op caused a call to nsIParser::Terminate(); break; } - iter->Perform(this); - } - - if (NS_LIKELY(mParser)) { - FlushPendingAppendNotifications(); - } else { - mPendingNotifications.Clear(); + NS_ASSERTION(mFlushState == eInDocUpdate, "Tried to perform tree op outside update batch."); + iter->Perform(this, &scriptElement); } #ifdef DEBUG_hsivonen @@ -338,49 +322,17 @@ nsHtml5TreeOpExecutor::Flush() EndDocUpdate(); - mFlushing = PR_FALSE; + mFlushState = eNotFlushing; if (!mParser) { return; } - ScheduleTimer(); - - if (!mCharsetSwitch.IsEmpty()) { - NS_ASSERTION(!mScriptElement, "Had a charset switch and a script"); - NS_ASSERTION(!mCallDidBuildModel, "Had a charset switch and DidBuildModel call"); - PerformCharsetSwitch(); - mCharsetSwitch.Truncate(); - if (mParser) { - // The charset switch was unsuccessful. - return (static_cast (mParser.get()))->ContinueAfterFailedCharsetSwitch(); - } - } else if (mCallDidBuildModel) { - mCallDidBuildModel = PR_FALSE; - // If we have a script element here, it must be malformed - #ifdef DEBUG - nsCOMPtr sele = do_QueryInterface(mScriptElement); - if (sele) { - NS_ASSERTION(sele->IsMalformed(), "Script wasn't marked as malformed."); - } - #endif - mScriptElement = nsnull; - DidBuildModel(PR_FALSE); - } else if (mScriptElement) { - RunScript(); + if (scriptElement) { + RunScript(scriptElement); // must be tail call when mFlushState is eNotFlushing } } -void -nsHtml5TreeOpExecutor::ScheduleTimer() -{ - mFlushTimer->Cancel(); - mFlushTimer->InitWithFuncCallback(TimerCallbackFunc, - static_cast (this), - NS_HTML5_TREE_OP_EXECUTOR_MAX_TIME_WITHOUT_FLUSH, - nsITimer::TYPE_ONE_SHOT); -} - nsresult nsHtml5TreeOpExecutor::ProcessBASETag(nsIContent* aContent) { @@ -458,32 +410,60 @@ nsHtml5TreeOpExecutor::DocumentMode(nsHtml5DocumentMode m) * main-thread case is to allow the control to return from the tokenizer * before scripts run. This way, the tokenizer is not invoked re-entrantly * although the parser is. + * + * The reason why this is called as a tail call when mFlushState is set to + * eNotFlushing is to allow re-entry to Flush() but only after the current + * Flush() has cleared the op queue and is otherwise done cleaning up after + * itself. */ void -nsHtml5TreeOpExecutor::RunScript() +nsHtml5TreeOpExecutor::RunScript(nsIContent* aScriptElement) { - mReadingFromStage = PR_FALSE; - NS_ASSERTION(mScriptElement, "No script to run"); - - nsCOMPtr sele = do_QueryInterface(mScriptElement); + NS_ASSERTION(aScriptElement, "No script to run"); + nsCOMPtr sele = do_QueryInterface(aScriptElement); + if (!mParser) { NS_ASSERTION(sele->IsMalformed(), "Script wasn't marked as malformed."); // We got here not because of an end tag but because the tree builder // popped an incomplete script element on EOF. Returning here to avoid - // calling back into mParser anymore. mParser has been nulled out by now. + // calling back into mParser anymore. return; } + + if (mFragmentMode) { + // ending the doc update called nsIParser::Terminate or we are in the + // fragment mode + sele->PreventExecution(); + return; + } + + if (sele->GetScriptDeferred() || sele->GetScriptAsync()) { + #ifdef DEBUG + nsresult rv = + #endif + aScriptElement->DoneAddingChildren(PR_TRUE); // scripts ignore the argument + NS_ASSERTION(rv != NS_ERROR_HTMLPARSER_BLOCK, + "Defer or async script tried to block."); + return; + } + + NS_ASSERTION(mFlushState == eNotFlushing, "Tried to run script when flushing."); + + mReadingFromStage = PR_FALSE; + sele->SetCreatorParser(mParser); + // Notify our document that we're loading this script. nsCOMPtr htmlDocument = do_QueryInterface(mDocument); NS_ASSERTION(htmlDocument, "Document didn't QI into HTML document."); htmlDocument->ScriptLoading(sele); - // Copied from nsXMLContentSink + + // Copied from nsXMLContentSink // Now tell the script that it's ready to go. This may execute the script // or return NS_ERROR_HTMLPARSER_BLOCK. Or neither if the script doesn't // need executing. - nsresult rv = mScriptElement->DoneAddingChildren(PR_TRUE); - mScriptElement = nsnull; + nsresult rv = aScriptElement->DoneAddingChildren(PR_TRUE); + // If the act of insertion evaluated the script, we're fine. // Else, block the parser till the script has loaded. if (rv == NS_ERROR_HTMLPARSER_BLOCK) { @@ -516,19 +496,18 @@ nsHtml5TreeOpExecutor::Start() { NS_PRECONDITION(!mStarted, "Tried to start when already started."); mStarted = PR_TRUE; - mScriptElement = nsnull; - ScheduleTimer(); } void nsHtml5TreeOpExecutor::NeedsCharsetSwitchTo(const char* aEncoding) { - mCharsetSwitch.Assign(aEncoding); -} + EndDocUpdate(); -void -nsHtml5TreeOpExecutor::PerformCharsetSwitch() -{ + if(NS_UNLIKELY(!mParser)) { + // got terminate + return; + } + nsresult rv = NS_OK; nsCOMPtr wss = do_QueryInterface(mDocShell); if (!wss) { @@ -540,12 +519,21 @@ nsHtml5TreeOpExecutor::PerformCharsetSwitch() // do nothing and fall thru } else if (NS_FAILED(rv = wss->StopDocumentLoad())) { rv = wss->SetRendering(PR_TRUE); // turn on the rendering so at least we will see something. - } else if (NS_FAILED(rv = wss->ReloadDocument(mCharsetSwitch.get(), kCharsetFromMetaTag))) { + } else if (NS_FAILED(rv = wss->ReloadDocument(aEncoding, kCharsetFromMetaTag))) { rv = wss->SetRendering(PR_TRUE); // turn on the rendering so at least we will see something. } // if the charset switch was accepted, wss has called Terminate() on the // parser by now #endif + + if (!mParser) { + // success + return; + } + + (static_cast (mParser.get()))->ContinueAfterFailedCharsetSwitch(); + + BeginDocUpdate(); } nsHtml5Tokenizer* @@ -560,23 +548,14 @@ nsHtml5TreeOpExecutor::Reset() { mReadingFromStage = PR_FALSE; mOpQueue.Clear(); mStarted = PR_FALSE; - mScriptElement = nsnull; - mCallDidBuildModel = PR_FALSE; - mCharsetSwitch.Truncate(); - mInDocumentUpdate = PR_FALSE; - mFlushing = PR_FALSE; + mFlushState = eNotFlushing; + mFragmentMode = PR_FALSE; } void -nsHtml5TreeOpExecutor::MaybeFlush(nsTArray& aOpQueue) +nsHtml5TreeOpExecutor::MoveOpsFrom(nsTArray& aOpQueue) { - // no-op -} - -void -nsHtml5TreeOpExecutor::ForcedFlush(nsTArray& aOpQueue) -{ - NS_PRECONDITION(!mFlushing, "mOpQueue modified during tree op execution."); + NS_PRECONDITION(mFlushState == eNotFlushing, "mOpQueue modified during tree op execution."); if (mOpQueue.IsEmpty()) { mOpQueue.SwapElements(aOpQueue); return; @@ -590,12 +569,6 @@ nsHtml5TreeOpExecutor::InitializeDocWriteParserState(nsAHtml5TreeBuilderState* a static_cast (mParser.get())->InitializeDocWriteParserState(aState, aLine); } -void -nsHtml5TreeOpExecutor::StreamEnded() -{ - mCallDidBuildModel = PR_TRUE; -} - PRUint32 nsHtml5TreeOpExecutor::sTreeOpQueueMaxLength = NS_HTML5_TREE_OP_EXECUTOR_DEFAULT_QUEUE_LENGTH; #ifdef DEBUG_hsivonen PRUint32 nsHtml5TreeOpExecutor::sInsertionBatchMaxLength = 0; diff --git a/parser/html/nsHtml5TreeOpExecutor.h b/parser/html/nsHtml5TreeOpExecutor.h index 26749e9797c4..d0987c66c08d 100644 --- a/parser/html/nsHtml5TreeOpExecutor.h +++ b/parser/html/nsHtml5TreeOpExecutor.h @@ -50,7 +50,6 @@ #include "nsContentSink.h" #include "nsNodeInfoManager.h" #include "nsHtml5DocumentMode.h" -#include "nsITimer.h" #include "nsIScriptElement.h" #include "nsIParser.h" #include "nsCOMArray.h" @@ -63,6 +62,13 @@ class nsHtml5StreamParser; typedef nsIContent* nsIContentPtr; +enum eHtml5FlushState { + eNotFlushing = 0, // not flushing + eInFlush = 1, // the Flush() method is on the call stack + eInDocUpdate = 2, // inside an update batch on the document + eNotifying = 3 // flushing pending append notifications +}; + class nsHtml5TreeOpExecutor : public nsContentSink, public nsIContentSink, public nsAHtml5TreeOpSink @@ -88,40 +94,22 @@ class nsHtml5TreeOpExecutor : public nsContentSink, PRBool mHasProcessedBase; PRBool mReadingFromStage; - nsCOMPtr mFlushTimer; nsTArray mOpQueue; nsTArray mElementsSeenInThisAppendBatch; nsTArray mPendingNotifications; nsHtml5StreamParser* mStreamParser; nsCOMArray mOwnedElements; - // This could be optimized away by introducing more tree ops so that - // non-elements wouldn't use the handle setup but the text node / comment - // / doctype operand would be remembered by the tree op executor. - nsCOMArray mOwnedNonElements; - /** * Whether the parser has started */ PRBool mStarted; - /** - * Script to run ASAP - */ - nsCOMPtr mScriptElement; - nsHtml5TreeOpStage mStage; - PRBool mFlushing; - - PRBool mInDocumentUpdate; + eHtml5FlushState mFlushState; - /** - * Used for deferring DidBuildModel call out of notification batch - */ - PRBool mCallDidBuildModel; - - nsCString mCharsetSwitch; + PRBool mFragmentMode; public: @@ -220,25 +208,33 @@ class nsHtml5TreeOpExecutor : public nsContentSink, mStreamParser = aStreamParser; } - inline void SetScriptElement(nsIContent* aScript) { - mScriptElement = aScript; - } - void InitializeDocWriteParserState(nsAHtml5TreeBuilderState* aState, PRInt32 aLine); PRBool IsScriptEnabled(); + void EnableFragmentMode() { + mFragmentMode = PR_TRUE; + } + + PRBool IsFragmentMode() { + return mFragmentMode; + } + inline void BeginDocUpdate() { - NS_PRECONDITION(!mInDocumentUpdate, "Tried to double-open update."); + NS_PRECONDITION(mFlushState == eInFlush, "Tried to double-open update."); NS_PRECONDITION(mParser, "Started update without parser."); - mInDocumentUpdate = PR_TRUE; + mFlushState = eInDocUpdate; mDocument->BeginUpdate(UPDATE_CONTENT_MODEL); } inline void EndDocUpdate() { - if (mInDocumentUpdate) { - mInDocumentUpdate = PR_FALSE; + if (mFlushState >= eInDocUpdate) { + FlushPendingAppendNotifications(); + if (NS_UNLIKELY(!mParser)) { + return; + } mDocument->EndUpdate(UPDATE_CONTENT_MODEL); + mFlushState = eInFlush; } } @@ -268,9 +264,23 @@ class nsHtml5TreeOpExecutor : public nsContentSink, } void FlushPendingAppendNotifications() { + if (NS_UNLIKELY(mFlushState == eNotifying)) { + // nsIParser::Terminate() was called in response to iter->Fire below + // earlier in the call stack. + return; + } + NS_PRECONDITION(mFlushState == eInDocUpdate, "Notifications flushed outside update"); + mFlushState = eNotifying; const nsHtml5PendingNotification* start = mPendingNotifications.Elements(); const nsHtml5PendingNotification* end = start + mPendingNotifications.Length(); for (nsHtml5PendingNotification* iter = (nsHtml5PendingNotification*)start; iter < end; ++iter) { + if (NS_UNLIKELY(!mParser)) { + // nsIParser::Terminate() was called in response to a notification + // this most likely means that the page is being navigated away from + // so just dropping the rest of the notifications on the floor + // instead of doing something fancy. + break; + } iter->Fire(); } mPendingNotifications.Clear(); @@ -280,23 +290,24 @@ class nsHtml5TreeOpExecutor : public nsContentSink, } #endif mElementsSeenInThisAppendBatch.Clear(); + mFlushState = eInDocUpdate; } - inline PRBool HaveNotified(nsIContent* aElement) { - NS_PRECONDITION(aElement, "HaveNotified called with null argument."); + inline PRBool HaveNotified(nsIContent* aNode) { + NS_PRECONDITION(aNode, "HaveNotified called with null argument."); const nsHtml5PendingNotification* start = mPendingNotifications.Elements(); const nsHtml5PendingNotification* end = start + mPendingNotifications.Length(); for (;;) { - nsIContent* parent = aElement->GetParent(); + nsIContent* parent = aNode->GetParent(); if (!parent) { return PR_TRUE; } for (nsHtml5PendingNotification* iter = (nsHtml5PendingNotification*)start; iter < end; ++iter) { if (iter->Contains(parent)) { - return iter->HaveNotifiedIndex(parent->IndexOf(aElement)); + return iter->HaveNotifiedIndex(parent->IndexOf(aNode)); } } - aElement = parent; + aNode = parent; } } @@ -321,14 +332,6 @@ class nsHtml5TreeOpExecutor : public nsContentSink, void NeedsCharsetSwitchTo(const char* aEncoding); - void PerformCharsetSwitch(); - -#ifdef DEBUG - PRBool HasScriptElement() { - return !!mScriptElement; - } -#endif - PRBool IsComplete() { return !mParser; } @@ -338,19 +341,10 @@ class nsHtml5TreeOpExecutor : public nsContentSink, } PRBool IsFlushing() { - return mFlushing; + return mFlushState >= eInFlush; } - void RunScript(); - - void MaybePreventExecution() { - if (mScriptElement) { - nsCOMPtr script = do_QueryInterface(mScriptElement); - NS_ASSERTION(script, "mScriptElement didn't QI to nsIScriptElement!"); - script->PreventExecution(); - mScriptElement = nsnull; - } - } + void RunScript(nsIContent* aScriptElement); void Reset(); @@ -358,22 +352,13 @@ class nsHtml5TreeOpExecutor : public nsContentSink, mOwnedElements.AppendObject(aContent); } - inline void HoldNonElement(nsIContent* aContent) { - mOwnedNonElements.AppendObject(aContent); - } - // The following two methods are for the main-thread case - /** - * No-op - */ - virtual void MaybeFlush(nsTArray& aOpQueue); - /** * Flush the operations from the tree operations from the argument * queue unconditionally. */ - virtual void ForcedFlush(nsTArray& aOpQueue); + virtual void MoveOpsFrom(nsTArray& aOpQueue); nsAHtml5TreeOpSink* GetStage() { return &mStage; @@ -385,8 +370,6 @@ class nsHtml5TreeOpExecutor : public nsContentSink, void StreamEnded(); - void ScheduleTimer(); - #ifdef DEBUG void AssertStageEmpty() { mStage.AssertEmpty(); diff --git a/parser/html/nsHtml5TreeOpStage.cpp b/parser/html/nsHtml5TreeOpStage.cpp index d211d9eee3f8..a44eb54d076b 100644 --- a/parser/html/nsHtml5TreeOpStage.cpp +++ b/parser/html/nsHtml5TreeOpStage.cpp @@ -47,16 +47,7 @@ nsHtml5TreeOpStage::~nsHtml5TreeOpStage() } void -nsHtml5TreeOpStage::MaybeFlush(nsTArray& aOpQueue) -{ - mozilla::MutexAutoLock autoLock(mMutex); - if (mOpQueue.IsEmpty()) { - mOpQueue.SwapElements(aOpQueue); - } -} - -void -nsHtml5TreeOpStage::ForcedFlush(nsTArray& aOpQueue) +nsHtml5TreeOpStage::MoveOpsFrom(nsTArray& aOpQueue) { mozilla::MutexAutoLock autoLock(mMutex); if (mOpQueue.IsEmpty()) { @@ -67,7 +58,7 @@ nsHtml5TreeOpStage::ForcedFlush(nsTArray& aOpQueue) } void -nsHtml5TreeOpStage::RetrieveOperations(nsTArray& aOpQueue) +nsHtml5TreeOpStage::MoveOpsTo(nsTArray& aOpQueue) { mozilla::MutexAutoLock autoLock(mMutex); if (aOpQueue.IsEmpty()) { diff --git a/parser/html/nsHtml5TreeOpStage.h b/parser/html/nsHtml5TreeOpStage.h index 271f6ef847c9..6cd1ecd004d0 100644 --- a/parser/html/nsHtml5TreeOpStage.h +++ b/parser/html/nsHtml5TreeOpStage.h @@ -50,22 +50,16 @@ class nsHtml5TreeOpStage : public nsAHtml5TreeOpSink { ~nsHtml5TreeOpStage(); - /** - * Flush the operations from the tree operations from the argument - * queue if flushing is not expensive. - */ - virtual void MaybeFlush(nsTArray& aOpQueue); - /** * Flush the operations from the tree operations from the argument * queue unconditionally. */ - virtual void ForcedFlush(nsTArray& aOpQueue); + virtual void MoveOpsFrom(nsTArray& aOpQueue); /** * Retrieve the staged operations into the argument. */ - void RetrieveOperations(nsTArray& aOpQueue); + void MoveOpsTo(nsTArray& aOpQueue); #ifdef DEBUG void AssertEmpty(); diff --git a/parser/html/nsHtml5TreeOperation.cpp b/parser/html/nsHtml5TreeOperation.cpp index b471c07ef69c..5352f913ee0d 100644 --- a/parser/html/nsHtml5TreeOperation.cpp +++ b/parser/html/nsHtml5TreeOperation.cpp @@ -57,6 +57,35 @@ #include "nsIFormControl.h" #include "nsIStyleSheetLinkingElement.h" #include "nsIDOMDocumentType.h" +#include "nsIMutationObserver.h" + +/** + * Helper class that opens a notification batch if the current doc + * is different from the executor doc. + */ +class NS_STACK_CLASS nsHtml5OtherDocUpdate { + public: + nsHtml5OtherDocUpdate(nsIDocument* aCurrentDoc, nsIDocument* aExecutorDoc) + { + NS_PRECONDITION(aCurrentDoc, "Node has no doc?"); + NS_PRECONDITION(aExecutorDoc, "Executor has no doc?"); + if (NS_LIKELY(aCurrentDoc == aExecutorDoc)) { + mDocument = nsnull; + } else { + mDocument = aCurrentDoc; + aCurrentDoc->BeginUpdate(UPDATE_CONTENT_MODEL); + } + } + + ~nsHtml5OtherDocUpdate() + { + if (NS_UNLIKELY(mDocument)) { + mDocument->EndUpdate(UPDATE_CONTENT_MODEL); + } + } + private: + nsIDocument* mDocument; +}; nsHtml5TreeOperation::nsHtml5TreeOperation() #ifdef DEBUG @@ -77,11 +106,13 @@ nsHtml5TreeOperation::~nsHtml5TreeOperation() case eTreeOpCreateElement: delete mThree.attributes; break; - case eTreeOpCreateDoctype: + case eTreeOpAppendDoctypeToDocument: delete mTwo.stringPair; break; - case eTreeOpCreateTextNode: - case eTreeOpCreateComment: + case eTreeOpFosterParentText: + case eTreeOpAppendText: + case eTreeOpAppendComment: + case eTreeOpAppendCommentToDocument: delete[] mTwo.unicharPtr; break; case eTreeOpSetDocumentCharset: @@ -94,22 +125,124 @@ nsHtml5TreeOperation::~nsHtml5TreeOperation() } nsresult -nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder) +nsHtml5TreeOperation::AppendTextToTextNode(PRUnichar* aBuffer, + PRInt32 aLength, + nsIContent* aTextNode, + nsHtml5TreeOpExecutor* aBuilder) +{ + NS_PRECONDITION(aTextNode, "Got null text node."); + + if (aBuilder->HaveNotified(aTextNode)) { + // This text node has already been notified on, so it's necessary to + // notify on the append + nsresult rv = NS_OK; + PRUint32 oldLength = aTextNode->TextLength(); + CharacterDataChangeInfo info = { + PR_TRUE, + oldLength, + oldLength, + aLength + }; + nsNodeUtils::CharacterDataWillChange(aTextNode, &info); + + rv = aTextNode->AppendText(aBuffer, aLength, PR_FALSE); + NS_ENSURE_SUCCESS(rv, rv); + + nsNodeUtils::CharacterDataChanged(aTextNode, &info); + return rv; + } + + return aTextNode->AppendText(aBuffer, aLength, PR_FALSE); +} + + +nsresult +nsHtml5TreeOperation::AppendText(PRUnichar* aBuffer, + PRInt32 aLength, + nsIContent* aParent, + nsHtml5TreeOpExecutor* aBuilder) +{ + nsresult rv = NS_OK; + nsIContent* lastChild = aParent->GetLastChild(); + if (lastChild && lastChild->IsNodeOfType(nsINode::eTEXT)) { + nsHtml5OtherDocUpdate update(aParent->GetOwnerDoc(), + aBuilder->GetDocument()); + return AppendTextToTextNode(aBuffer, + aLength, + lastChild, + aBuilder); + } + + nsCOMPtr text; + NS_NewTextNode(getter_AddRefs(text), aBuilder->GetNodeInfoManager()); + NS_ASSERTION(text, "Infallible malloc failed?"); + rv = text->SetText(aBuffer, aLength, PR_FALSE); + NS_ENSURE_SUCCESS(rv, rv); + + return Append(text, aParent, aBuilder); +} + +nsresult +nsHtml5TreeOperation::Append(nsIContent* aNode, + nsIContent* aParent, + nsHtml5TreeOpExecutor* aBuilder) +{ + nsresult rv = NS_OK; + nsIDocument* executorDoc = aBuilder->GetDocument(); + NS_ASSERTION(executorDoc, "Null doc on executor"); + nsIDocument* parentDoc = aParent->GetOwnerDoc(); + NS_ASSERTION(parentDoc, "Null owner doc on old node."); + + if (NS_LIKELY(executorDoc == parentDoc)) { + // the usual case. the parent is in the parser's doc + aBuilder->PostPendingAppendNotification(aParent, aNode); + rv = aParent->AppendChildTo(aNode, PR_FALSE); + return rv; + } + + // The parent has been moved to another doc + parentDoc->BeginUpdate(UPDATE_CONTENT_MODEL); + + PRUint32 childCount = aParent->GetChildCount(); + rv = aParent->AppendChildTo(aNode, PR_FALSE); + nsNodeUtils::ContentAppended(aParent, childCount); + + parentDoc->EndUpdate(UPDATE_CONTENT_MODEL); + return rv; +} + +nsresult +nsHtml5TreeOperation::AppendToDocument(nsIContent* aNode, + nsHtml5TreeOpExecutor* aBuilder) +{ + nsresult rv = NS_OK; + aBuilder->FlushPendingAppendNotifications(); + nsIDocument* doc = aBuilder->GetDocument(); + PRUint32 childCount = doc->GetChildCount(); + rv = doc->AppendChildTo(aNode, PR_FALSE); + NS_ENSURE_SUCCESS(rv, rv); + nsNodeUtils::ContentInserted(doc, aNode, childCount); + return rv; +} + +nsresult +nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder, + nsIContent** aScriptElement) { nsresult rv = NS_OK; switch(mOpCode) { case eTreeOpAppend: { nsIContent* node = *(mOne.node); nsIContent* parent = *(mTwo.node); - aBuilder->PostPendingAppendNotification(parent, node); - rv = parent->AppendChildTo(node, PR_FALSE); - return rv; + return Append(node, parent, aBuilder); } case eTreeOpDetach: { nsIContent* node = *(mOne.node); aBuilder->FlushPendingAppendNotifications(); nsIContent* parent = node->GetParent(); if (parent) { + nsHtml5OtherDocUpdate update(parent->GetOwnerDoc(), + aBuilder->GetDocument()); PRUint32 pos = parent->IndexOf(node); NS_ASSERTION((pos >= 0), "Element not found as child of its parent"); rv = parent->RemoveChildAt(pos, PR_TRUE, PR_FALSE); @@ -121,6 +254,10 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder) nsIContent* node = *(mOne.node); nsIContent* parent = *(mTwo.node); aBuilder->FlushPendingAppendNotifications(); + + nsHtml5OtherDocUpdate update(parent->GetOwnerDoc(), + aBuilder->GetDocument()); + PRUint32 childCount = parent->GetChildCount(); PRBool didAppend = PR_FALSE; while (node->GetChildCount()) { @@ -141,32 +278,33 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder) nsIContent* parent = *(mTwo.node); nsIContent* table = *(mThree.node); nsIContent* foster = table->GetParent(); + if (foster && foster->IsNodeOfType(nsINode::eELEMENT)) { aBuilder->FlushPendingAppendNotifications(); + + nsHtml5OtherDocUpdate update(foster->GetOwnerDoc(), + aBuilder->GetDocument()); + PRUint32 pos = foster->IndexOf(table); rv = foster->InsertChildAt(node, pos, PR_FALSE); NS_ENSURE_SUCCESS(rv, rv); nsNodeUtils::ContentInserted(foster, node, pos); - } else { - aBuilder->PostPendingAppendNotification(parent, node); - rv = parent->AppendChildTo(node, PR_FALSE); + return rv; } - return rv; + + return Append(node, parent, aBuilder); } case eTreeOpAppendToDocument: { nsIContent* node = *(mOne.node); - aBuilder->FlushPendingAppendNotifications(); - nsIDocument* doc = aBuilder->GetDocument(); - PRUint32 childCount = doc->GetChildCount(); - rv = doc->AppendChildTo(node, PR_FALSE); - NS_ENSURE_SUCCESS(rv, rv); - nsNodeUtils::ContentInserted(doc, node, childCount); - return rv; + return AppendToDocument(node, aBuilder); } case eTreeOpAddAttributes: { nsIContent* node = *(mOne.node); nsHtml5HtmlAttributes* attributes = mTwo.attributes; + nsHtml5OtherDocUpdate update(node->GetOwnerDoc(), + aBuilder->GetDocument()); + nsIDocument* document = node->GetCurrentDoc(); PRInt32 len = attributes->getLength(); @@ -209,8 +347,7 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder) nsNodeUtils::AttributeChanged(node, nsuri, localName, - static_cast(nsIDOMMutationEvent::ADDITION), - stateMask); + static_cast(nsIDOMMutationEvent::ADDITION)); } } @@ -236,6 +373,9 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder) ssle->InitStyleLinkElement(PR_FALSE); ssle->SetEnableUpdates(PR_FALSE); } + } else if (NS_UNLIKELY(name == nsHtml5Atoms::script && ns == kNameSpaceID_SVG)) { + nsCOMPtr sele = do_QueryInterface(newContent); + sele->WillCallDoneAddingChildren(); } if (!attributes) { @@ -265,41 +405,81 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder) } return rv; } - case eTreeOpCreateTextNode: { - nsIContent** target = mOne.node; + case eTreeOpAppendText: { + nsIContent* parent = *mOne.node; PRUnichar* buffer = mTwo.unicharPtr; PRInt32 length = mInt; - - nsCOMPtr text; - NS_NewTextNode(getter_AddRefs(text), aBuilder->GetNodeInfoManager()); - // XXX nsresult and comment null check? - text->SetText(buffer, length, PR_FALSE); - // XXX nsresult - - aBuilder->HoldNonElement(*target = text); - return rv; + return AppendText(buffer, length, parent, aBuilder); } - case eTreeOpCreateComment: { - nsIContent** target = mOne.node; + case eTreeOpFosterParentText: { + nsIContent* stackParent = *mOne.node; + PRUnichar* buffer = mTwo.unicharPtr; + PRInt32 length = mInt; + nsIContent* table = *mThree.node; + + nsIContent* foster = table->GetParent(); + + if (foster && foster->IsNodeOfType(nsINode::eELEMENT)) { + aBuilder->FlushPendingAppendNotifications(); + + nsHtml5OtherDocUpdate update(foster->GetOwnerDoc(), + aBuilder->GetDocument()); + + PRUint32 pos = foster->IndexOf(table); + + nsIContent* previousSibling = foster->GetChildAt(pos - 1); + if (previousSibling && previousSibling->IsNodeOfType(nsINode::eTEXT)) { + return AppendTextToTextNode(buffer, + length, + previousSibling, + aBuilder); + } + + nsCOMPtr text; + NS_NewTextNode(getter_AddRefs(text), aBuilder->GetNodeInfoManager()); + NS_ASSERTION(text, "Infallible malloc failed?"); + rv = text->SetText(buffer, length, PR_FALSE); + NS_ENSURE_SUCCESS(rv, rv); + + rv = foster->InsertChildAt(text, pos, PR_FALSE); + NS_ENSURE_SUCCESS(rv, rv); + nsNodeUtils::ContentInserted(foster, text, pos); + return rv; + } + + return AppendText(buffer, length, stackParent, aBuilder); + } + case eTreeOpAppendComment: { + nsIContent* parent = *mOne.node; PRUnichar* buffer = mTwo.unicharPtr; PRInt32 length = mInt; nsCOMPtr comment; NS_NewCommentNode(getter_AddRefs(comment), aBuilder->GetNodeInfoManager()); - // XXX nsresult and comment null check? - comment->SetText(buffer, length, PR_FALSE); - // XXX nsresult + NS_ASSERTION(comment, "Infallible malloc failed?"); + rv = comment->SetText(buffer, length, PR_FALSE); + NS_ENSURE_SUCCESS(rv, rv); - aBuilder->HoldNonElement(*target = comment); - return rv; + return Append(comment, parent, aBuilder); } - case eTreeOpCreateDoctype: { + case eTreeOpAppendCommentToDocument: { + PRUnichar* buffer = mTwo.unicharPtr; + PRInt32 length = mInt; + + nsCOMPtr comment; + NS_NewCommentNode(getter_AddRefs(comment), aBuilder->GetNodeInfoManager()); + NS_ASSERTION(comment, "Infallible malloc failed?"); + rv = comment->SetText(buffer, length, PR_FALSE); + NS_ENSURE_SUCCESS(rv, rv); + + return AppendToDocument(comment, aBuilder); + } + case eTreeOpAppendDoctypeToDocument: { nsCOMPtr name = Reget(mOne.atom); nsHtml5TreeOperationStringPair* pair = mTwo.stringPair; nsString publicId; nsString systemId; pair->Get(publicId, systemId); - nsIContent** target = mThree.node; // Adapted from nsXMLContentSink // Create a new doctype node @@ -317,8 +497,7 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder) voidString); NS_ASSERTION(docType, "Doctype creation failed."); nsCOMPtr asContent = do_QueryInterface(docType); - aBuilder->HoldNonElement(*target = asContent); - return rv; + return AppendToDocument(asContent, aBuilder); } case eTreeOpRunScript: { nsIContent* node = *(mOne.node); @@ -326,7 +505,7 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder) if (snapshot) { aBuilder->InitializeDocWriteParserState(snapshot, mInt); } - aBuilder->SetScriptElement(node); + *aScriptElement = node; return rv; } case eTreeOpDoneAddingChildren: { @@ -339,6 +518,10 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder) node->DoneCreatingElement(); return rv; } + case eTreeOpFlushPendingAppendNotifications: { + aBuilder->FlushPendingAppendNotifications(); + return rv; + } case eTreeOpSetDocumentCharset: { char* str = mOne.charPtr; nsDependentCString dependentString(str); @@ -381,11 +564,11 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder) return rv; } case eTreeOpStreamEnded: { - aBuilder->StreamEnded(); + aBuilder->DidBuildModel(PR_FALSE); // this causes a notifications flush anyway return rv; } case eTreeOpStartLayout: { - aBuilder->StartLayout(); // this causes a flush anyway + aBuilder->StartLayout(); // this causes a notification flush anyway return rv; } case eTreeOpDocumentMode: { @@ -399,11 +582,12 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder) ssle->SetLineNumber(mInt); return rv; } - case eTreeOpSetScriptLineNumber: { + case eTreeOpSetScriptLineNumberAndFreeze: { nsIContent* node = *(mOne.node); nsCOMPtr sele = do_QueryInterface(node); NS_ASSERTION(sele, "Node didn't QI to script."); sele->SetScriptLineNumber(mInt); + sele->FreezeUriAsyncDefer(); return rv; } default: { diff --git a/parser/html/nsHtml5TreeOperation.h b/parser/html/nsHtml5TreeOperation.h index 75be187debe2..51c31fbfc463 100644 --- a/parser/html/nsHtml5TreeOperation.h +++ b/parser/html/nsHtml5TreeOperation.h @@ -59,13 +59,17 @@ enum eHtml5TreeOperation { eTreeOpDocumentMode, eTreeOpCreateElement, eTreeOpSetFormElement, - eTreeOpCreateTextNode, - eTreeOpCreateComment, - eTreeOpCreateDoctype, + eTreeOpAppendText, + eTreeOpFosterParentText, + eTreeOpAppendComment, + eTreeOpAppendCommentToDocument, + eTreeOpAppendDoctypeToDocument, // Gecko-specific on-pop ops eTreeOpRunScript, + eTreeOpRunScriptAsyncDefer, eTreeOpDoneAddingChildren, eTreeOpDoneCreatingElement, + eTreeOpFlushPendingAppendNotifications, eTreeOpSetDocumentCharset, eTreeOpNeedsCharsetSwitchTo, eTreeOpUpdateStyleSheet, @@ -75,7 +79,7 @@ enum eHtml5TreeOperation { eTreeOpMarkMalformedIfScript, eTreeOpStreamEnded, eTreeOpSetStyleLineNumber, - eTreeOpSetScriptLineNumber, + eTreeOpSetScriptLineNumberAndFreeze, eTreeOpStartLayout }; @@ -187,12 +191,38 @@ class nsHtml5TreeOperation { inline void Init(eHtml5TreeOperation aOpCode, PRUnichar* aBuffer, PRInt32 aLength, - nsIContent** aTarget) { + nsIContent** aStackParent, + nsIContent** aTable) { + NS_PRECONDITION(mOpCode == eTreeOpUninitialized, + "Op code must be uninitialized when initializing."); + NS_PRECONDITION(aBuffer, "Initialized tree op with null buffer."); + mOpCode = aOpCode; + mOne.node = aStackParent; + mTwo.unicharPtr = aBuffer; + mThree.node = aTable; + mInt = aLength; + } + + inline void Init(eHtml5TreeOperation aOpCode, + PRUnichar* aBuffer, + PRInt32 aLength, + nsIContent** aParent) { + NS_PRECONDITION(mOpCode == eTreeOpUninitialized, + "Op code must be uninitialized when initializing."); + NS_PRECONDITION(aBuffer, "Initialized tree op with null buffer."); + mOpCode = aOpCode; + mOne.node = aParent; + mTwo.unicharPtr = aBuffer; + mInt = aLength; + } + + inline void Init(eHtml5TreeOperation aOpCode, + PRUnichar* aBuffer, + PRInt32 aLength) { NS_PRECONDITION(mOpCode == eTreeOpUninitialized, "Op code must be uninitialized when initializing."); NS_PRECONDITION(aBuffer, "Initialized tree op with null buffer."); mOpCode = aOpCode; - mOne.node = aTarget; mTwo.unicharPtr = aBuffer; mInt = aLength; } @@ -209,13 +239,12 @@ class nsHtml5TreeOperation { inline void Init(nsIAtom* aName, const nsAString& aPublicId, - const nsAString& aSystemId, nsIContent** aTarget) { + const nsAString& aSystemId) { NS_PRECONDITION(mOpCode == eTreeOpUninitialized, "Op code must be uninitialized when initializing."); - mOpCode = eTreeOpCreateDoctype; + mOpCode = eTreeOpAppendDoctypeToDocument; mOne.atom = aName; mTwo.stringPair = new nsHtml5TreeOperationStringPair(aPublicId, aSystemId); - mThree.node = aTarget; } inline void Init(eHtml5TreeOperation aOpCode, const nsACString& aString) { @@ -257,7 +286,7 @@ class nsHtml5TreeOperation { mInt = aLine; } - nsresult Perform(nsHtml5TreeOpExecutor* aBuilder); + nsresult Perform(nsHtml5TreeOpExecutor* aBuilder, nsIContent** aScriptElement); inline already_AddRefed Reget(nsIAtom* aAtom) { if (!aAtom || aAtom->IsStaticAtom()) { @@ -269,6 +298,23 @@ class nsHtml5TreeOperation { } private: + + nsresult AppendTextToTextNode(PRUnichar* aBuffer, + PRInt32 aLength, + nsIContent* aTextNode, + nsHtml5TreeOpExecutor* aBuilder); + + nsresult AppendText(PRUnichar* aBuffer, + PRInt32 aLength, + nsIContent* aParent, + nsHtml5TreeOpExecutor* aBuilder); + + nsresult Append(nsIContent* aNode, + nsIContent* aParent, + nsHtml5TreeOpExecutor* aBuilder); + + nsresult AppendToDocument(nsIContent* aNode, + nsHtml5TreeOpExecutor* aBuilder); // possible optimization: // Make the queue take items the size of pointer and make the op code diff --git a/parser/htmlparser/src/nsViewSourceHTML.cpp b/parser/htmlparser/src/nsViewSourceHTML.cpp index b9a4be2b3663..5f905994c511 100644 --- a/parser/htmlparser/src/nsViewSourceHTML.cpp +++ b/parser/htmlparser/src/nsViewSourceHTML.cpp @@ -948,6 +948,8 @@ PRBool CViewSourceHTML::IsUrlAttribute(const nsAString& tagName, PRBool isHref = trimmedAttrName.LowerCaseEqualsLiteral("href"); PRBool isSrc = !isHref && trimmedAttrName.LowerCaseEqualsLiteral("src"); + PRBool isXLink = !isHref && !isSrc && + mDocType == eXML && trimmedAttrName.EqualsLiteral("xlink:href"); // If this is the HREF attribute of a BASE element, then update the base URI. // This doesn't feel like the ideal place for this, but the alternatives don't @@ -959,7 +961,7 @@ PRBool CViewSourceHTML::IsUrlAttribute(const nsAString& tagName, SetBaseURI(expandedBaseSpec); } - return isHref || isSrc; + return isHref || isSrc || isXLink; } void CViewSourceHTML::WriteHrefAttribute(nsTokenAllocator* allocator, diff --git a/parser/htmlparser/tests/crashtests/515278-1.html b/parser/htmlparser/tests/crashtests/515278-1.html new file mode 100644 index 000000000000..33e01f2224a0 --- /dev/null +++ b/parser/htmlparser/tests/crashtests/515278-1.html @@ -0,0 +1,3 @@ + + + diff --git a/parser/htmlparser/tests/crashtests/515533-1-inner.html b/parser/htmlparser/tests/crashtests/515533-1-inner.html new file mode 100644 index 000000000000..6bd0684e2103 --- /dev/null +++ b/parser/htmlparser/tests/crashtests/515533-1-inner.html @@ -0,0 +1,12 @@ + + + + + + + + + + diff --git a/parser/htmlparser/tests/crashtests/515533-1.html b/parser/htmlparser/tests/crashtests/515533-1.html new file mode 100644 index 000000000000..b0d5b570b878 --- /dev/null +++ b/parser/htmlparser/tests/crashtests/515533-1.html @@ -0,0 +1 @@ + diff --git a/parser/htmlparser/tests/crashtests/522326-1.html b/parser/htmlparser/tests/crashtests/522326-1.html new file mode 100644 index 000000000000..d06ab6cf7def --- /dev/null +++ b/parser/htmlparser/tests/crashtests/522326-1.html @@ -0,0 +1 @@ +abcd diff --git a/parser/htmlparser/tests/crashtests/525229-1.html b/parser/htmlparser/tests/crashtests/525229-1.html new file mode 100644 index 000000000000..8bffa7d6012b --- /dev/null +++ b/parser/htmlparser/tests/crashtests/525229-1.html @@ -0,0 +1,7 @@ + +Test for bug 525229 + + +text diff --git a/parser/htmlparser/tests/crashtests/crashtests.list b/parser/htmlparser/tests/crashtests/crashtests.list index e0bc87254d74..066536bae1fc 100644 --- a/parser/htmlparser/tests/crashtests/crashtests.list +++ b/parser/htmlparser/tests/crashtests/crashtests.list @@ -35,4 +35,8 @@ load 408939-1.html load 423373-1.html skip load 460706-1.xhtml # Bug 479499 load 468538-1.xhtml +load 515278-1.html +load 515533-1.html load 515816-1.html +load 525229-1.html +load 522326-1.html diff --git a/parser/htmlparser/tests/mochitest/Makefile.in b/parser/htmlparser/tests/mochitest/Makefile.in index ac787859ed5e..dcddf627295e 100644 --- a/parser/htmlparser/tests/mochitest/Makefile.in +++ b/parser/htmlparser/tests/mochitest/Makefile.in @@ -57,6 +57,7 @@ _TEST_FILES = parser_datreader.js \ test_bug396568.html \ test_bug418464.html \ test_bug460437.xhtml \ + test_bug502091.html \ bug_502091_iframe.html \ test_compatmode.html \ regressions.txt \ @@ -65,6 +66,3 @@ _TEST_FILES = parser_datreader.js \ libs:: $(_TEST_FILES) $(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir) - -# Disabled due to bug 529544 -# test_bug502091.html \ diff --git a/parser/htmlparser/tests/mochitest/test_compatmode.html b/parser/htmlparser/tests/mochitest/test_compatmode.html index 17090f87ea16..2c7b618aeacf 100644 --- a/parser/htmlparser/tests/mochitest/test_compatmode.html +++ b/parser/htmlparser/tests/mochitest/test_compatmode.html @@ -77,12 +77,12 @@ function finishTest() { function test(mode,i){ is(mode,doctypes[i],doctypes[i+1]); if (i == doctypes.length - 2) { -// if (typeof(gOriginalHtml5Pref) == "undefined") { -// doTestHtml5(); Disabled due to bug 529544 -// } -// else { + if (typeof(gOriginalHtml5Pref) == "undefined") { + doTestHtml5(); + } + else { finishTest(); -// } + } } } diff --git a/testing/testsuite-targets.mk b/testing/testsuite-targets.mk index 6be4d75d23bb..d6f709c235fe 100644 --- a/testing/testsuite-targets.mk +++ b/testing/testsuite-targets.mk @@ -99,9 +99,9 @@ crashtest: $(call RUN_REFTEST,$(topsrcdir)/$(TEST_PATH)) $(CHECK_TEST_ERROR) -jstestbrowser: EXTRA_TEST_ARGS += --extra-profile-file=$(topsrcdir)/js/src/tests/user.js +jstestbrowser: TEST_PATH=js/src/tests/jstests.list jstestbrowser: - $(call RUN_REFTEST,$(topsrcdir)/js/src/tests/jstests.list) + $(call RUN_REFTEST,$(topsrcdir)/$(TEST_PATH) --extra-profile-file=$(topsrcdir)/js/src/tests/user.js) $(CHECK_TEST_ERROR) # Execute all xpcshell tests in the directories listed in the manifest. diff --git a/toolkit/components/places/src/nsPlacesAutoComplete.js b/toolkit/components/places/src/nsPlacesAutoComplete.js index 3b4fac52eab9..bb8ee23e6b9e 100644 --- a/toolkit/components/places/src/nsPlacesAutoComplete.js +++ b/toolkit/components/places/src/nsPlacesAutoComplete.js @@ -306,10 +306,12 @@ function nsPlacesAutoComplete() // title). return this._db.createStatement( "/* do not warn (bug 487789) */ " + - "SELECT IFNULL(h_t.url, h.url), IFNULL(h_t.title, h.title), f.url, " + - kBookTagSQLFragment + ", IFNULL(h_t.visit_count, h.visit_count), " + - "IFNULL(h_t.typed, h.typed), IFNULL(h_t.id, h.id), " + - ":query_type, rank " + + "SELECT IFNULL(h_t.url, h.url) AS c_url, " + + "IFNULL(h_t.title, h.title) AS c_title, f.url, " + + kBookTagSQLFragment + ", " + + "IFNULL(h_t.visit_count, h.visit_count) AS c_visit_count, " + + "IFNULL(h_t.typed, h.typed) AS c_typed, " + + "IFNULL(h_t.id, h.id), :query_type, rank " + "FROM ( " + "SELECT ROUND(MAX(((i.input = :search_string) + " + "(SUBSTR(i.input, 1, LENGTH(:search_string)) = :search_string)) * " + @@ -320,11 +322,11 @@ function nsPlacesAutoComplete() ") AS i " + "LEFT JOIN moz_places h ON h.id = i.place_id " + "LEFT JOIN moz_places_temp h_t ON h_t.id = i.place_id " + - "LEFT JOIN moz_favicons f ON f.id = IFNULL(h_t.favicon_id, h.favicon_id) "+ - "WHERE IFNULL(h_t.url, h.url) NOTNULL " + - "AND AUTOCOMPLETE_MATCH(:searchString, 0 /* url */, " + - "IFNULL(bookmark, 1 /* title */), tags, " + - "6 /* visit_count */, 7 /* typed */, parent, " + + "LEFT JOIN moz_favicons f ON f.id = IFNULL(h_t.favicon_id, h.favicon_id) " + + "WHERE c_url NOTNULL " + + "AND AUTOCOMPLETE_MATCH(:searchString, c_url, " + + "IFNULL(bookmark, c_title), tags, " + + "c_visit_count, c_typed, parent, " + ":matchBehavior, :searchBehavior) " + "ORDER BY rank DESC, IFNULL(h_t.frecency, h.frecency) DESC" ); diff --git a/toolkit/components/places/tests/unit/test_adaptive_bug527311.js b/toolkit/components/places/tests/unit/test_adaptive_bug527311.js new file mode 100644 index 000000000000..d91422331c53 --- /dev/null +++ b/toolkit/components/places/tests/unit/test_adaptive_bug527311.js @@ -0,0 +1,161 @@ +/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et: */ +/* ***** 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 Places Unit Test Code. + * + * The Initial Developer of the Original Code is Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Marco Bonardo + * + * 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 ***** */ + +const TEST_URL = "http://adapt.mozilla.org/"; +const SEARCH_STRING = "adapt"; + +Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); + +let hs = Cc["@mozilla.org/browser/nav-history-service;1"]. + getService(Ci.nsINavHistoryService); +let bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"]. + getService(Ci.nsINavBookmarksService); +let os = Cc["@mozilla.org/observer-service;1"]. + getService(Ci.nsIObserverService); +let ps = Cc["@mozilla.org/preferences-service;1"]. + getService(Ci.nsIPrefBranch); + +const PLACES_AUTOCOMPLETE_FEEDBACK_UPDATED_TOPIC = + "places-autocomplete-feedback-updated"; + +function AutoCompleteInput(aSearches) { + this.searches = aSearches; +} +AutoCompleteInput.prototype = { + constructor: AutoCompleteInput, + searches: null, + minResultsForPopup: 0, + timeout: 10, + searchParam: "", + textValue: "", + disableAutoComplete: false, + completeDefaultIndex: false, + + get searchCount() { + return this.searches.length; + }, + + getSearchAt: function ACI_getSearchAt(aIndex) { + return this.searches[aIndex]; + }, + + onSearchComplete: function ACI_onSearchComplete() {}, + + popupOpen: false, + + popup: { + setSelectedIndex: function() {}, + invalidate: function() {}, + + QueryInterface: function(iid) { + if (iid.equals(Ci.nsISupports) || + iid.equals(Ci.nsIAutoCompletePopup)) + return this; + + throw Components.results.NS_ERROR_NO_INTERFACE; + } + }, + + onSearchBegin: function() {}, + + QueryInterface: function(iid) { + if (iid.equals(Ci.nsISupports) || + iid.equals(Ci.nsIAutoCompleteInput)) + return this; + + throw Components.results.NS_ERROR_NO_INTERFACE; + } +} + + +function check_results() { + let controller = Cc["@mozilla.org/autocomplete/controller;1"]. + getService(Ci.nsIAutoCompleteController); + let input = new AutoCompleteInput(["history"]); + controller.input = input; + + input.onSearchComplete = function() { + do_check_eq(controller.searchStatus, + Ci.nsIAutoCompleteController.STATUS_COMPLETE_NO_MATCH); + do_check_eq(controller.matchCount, 0); + + remove_all_bookmarks(); + do_test_finished(); + }; + + controller.startSearch(SEARCH_STRING); +} + + +function addAdaptiveFeedback(aUrl, aSearch, aCallback) { + let observer = { + observe: function(aSubject, aTopic, aData) { + os.removeObserver(observer, PLACES_AUTOCOMPLETE_FEEDBACK_UPDATED_TOPIC); + do_timeout(0, aCallback); + } + }; + os.addObserver(observer, PLACES_AUTOCOMPLETE_FEEDBACK_UPDATED_TOPIC, false); + + let thing = { + QueryInterface: XPCOMUtils.generateQI([Ci.nsIAutoCompleteInput, + Ci.nsIAutoCompletePopup, + Ci.nsIAutoCompleteController]), + get popup() { return thing; }, + get controller() { return thing; }, + popupOpen: true, + selectedIndex: 0, + getValueAt: function() aUrl, + searchString: aSearch + }; + + os.notifyObservers(thing, "autocomplete-will-enter-text", null); +} + + +function run_test() { + do_test_pending(); + + // Add a bookmark to our url. + bs.insertBookmark(bs.unfiledBookmarksFolder, uri(TEST_URL), + bs.DEFAULT_INDEX, "test_book"); + // We want to search only history. + ps.setIntPref("browser.urlbar.default.behavior", + Ci.mozIPlacesAutoComplete.BEHAVIOR_HISTORY); + // Add an adaptive entry. + addAdaptiveFeedback(TEST_URL, SEARCH_STRING, check_results); +} diff --git a/toolkit/components/printing/content/printPreviewBindings.xml b/toolkit/components/printing/content/printPreviewBindings.xml index 641e51d437af..12a930ad508a 100644 --- a/toolkit/components/printing/content/printPreviewBindings.xml +++ b/toolkit/components/printing/content/printPreviewBindings.xml @@ -161,7 +161,7 @@ - + diff --git a/toolkit/xre/nsNativeAppSupportUnix.cpp b/toolkit/xre/nsNativeAppSupportUnix.cpp index a4f8bd0aa854..06861feb6691 100644 --- a/toolkit/xre/nsNativeAppSupportUnix.cpp +++ b/toolkit/xre/nsNativeAppSupportUnix.cpp @@ -48,6 +48,12 @@ #include "nsXREDirProvider.h" #include "nsReadableUtils.h" +#include "nsIFile.h" +#include "nsDirectoryServiceDefs.h" +#include "nsICommandLineRunner.h" +#include "nsIWindowMediator.h" +#include "nsIDOMWindowInternal.h" + #include #include #include @@ -59,7 +65,6 @@ struct DBusMessage; /* libosso.h references internals of dbus */ #include #include #include - #endif #define MIN_GTK_MAJOR_VERSION 2 @@ -205,7 +210,7 @@ class nsNativeAppSupportUnix : public nsNativeAppSupportBase { public: NS_IMETHOD Start(PRBool* aRetVal); - NS_IMETHOD Stop( PRBool *aResult); + NS_IMETHOD Stop(PRBool *aResult); private: #ifdef NS_OSSO @@ -241,7 +246,7 @@ static void OssoHardwareCallback(osso_hw_state_t *state, gpointer data) osso_hw_state_t* ourState = (osso_hw_state_t*) data; if (state->shutdown_ind) { - nsCOMPtr appService = do_GetService("@mozilla.org/toolkit/app-startup;1"); + nsCOMPtr appService = do_GetService("@mozilla.org/toolkit/app-startup;1"); if (appService) appService->Quit(nsIAppStartup::eForceQuit); return; @@ -269,6 +274,73 @@ static void OssoHardwareCallback(osso_hw_state_t *state, gpointer data) memcpy(ourState, state, sizeof(osso_hw_state_t)); } +static gint +OssoDbusCallback(const gchar *interface, const gchar *method, + GArray *arguments, gpointer data, osso_rpc_t *retval) +{ + retval->type = DBUS_TYPE_INVALID; + + // The "top_application" method just wants us to focus the top-most window. + if (!strcmp("top_application", method)) { + nsCOMPtr wm = do_GetService("@mozilla.org/appshell/window-mediator;1"); + + nsCOMPtr window; + wm->GetMostRecentWindow(NS_LITERAL_STRING("").get(), getter_AddRefs(window)); + if (window) { + window->Focus(); + } + return OSSO_OK; + } + + if (!strcmp("quit", method)) { + nsCOMPtr appService = do_GetService("@mozilla.org/toolkit/app-startup;1"); + if (appService) + appService->Quit(nsIAppStartup::eForceQuit); + + return OSSO_OK; + } + + // Other methods can have arguments, which we convert and send to commandline + // handlers. + nsCOMPtr cmdLine + (do_CreateInstance("@mozilla.org/toolkit/command-line;1")); + + nsCOMPtr workingDir; + NS_GetSpecialDirectory(NS_XPCOM_CURRENT_PROCESS_DIR, + getter_AddRefs(workingDir)); + + char** argv = 0; + int argc = 0; + + // Not all DBus methods pass arguments + if (arguments && arguments->len > 0) { + // Create argument list with a dummy argv[0] + argc = arguments->len + 1; + argv = (char**)calloc(1, argc * sizeof(*argv)); + + // Start at 1 to skip the dummy argv[0] + for (int i = 1; i < argc; i++) { + osso_rpc_t* entry = (osso_rpc_t*)&g_array_index(arguments, osso_rpc_t, i - 1); + if (entry->type != DBUS_TYPE_STRING) + continue; + + argv[i] = strdup(entry->value.s); + } + } + + cmdLine->Init(argc, argv, workingDir, nsICommandLine::STATE_REMOTE_AUTO); + + // Cleanup argument list + while (argc) { + free(argv[--argc]); + } + free(argv); + + cmdLine->Run(); + + return OSSO_OK; +} + #endif NS_IMETHODIMP @@ -324,19 +396,9 @@ nsNativeAppSupportUnix::Start(PRBool *aRetVal) return NS_ERROR_FAILURE; } - osso_hw_set_event_cb(m_osso_context, - nsnull, - OssoHardwareCallback, - &m_hw_state); - - - osso_hw_set_display_event_cb(m_osso_context, - OssoDisplayCallback, - nsnull); - - - - + osso_hw_set_event_cb(m_osso_context, nsnull, OssoHardwareCallback, &m_hw_state); + osso_hw_set_display_event_cb(m_osso_context, OssoDisplayCallback, nsnull); + osso_rpc_set_default_cb_f(m_osso_context, OssoDbusCallback, nsnull); #endif *aRetVal = PR_TRUE; @@ -413,15 +475,15 @@ nsNativeAppSupportUnix::Start(PRBool *aRetVal) } NS_IMETHODIMP -nsNativeAppSupportUnix::Stop( PRBool *aResult ) +nsNativeAppSupportUnix::Stop(PRBool *aResult) { - NS_ENSURE_ARG( aResult ); + NS_ENSURE_ARG(aResult); *aResult = PR_TRUE; #ifdef NS_OSSO - if (m_osso_context) - { + if (m_osso_context) { osso_hw_unset_event_cb(m_osso_context, nsnull); + osso_rpc_unset_default_cb_f(m_osso_context, OssoDbusCallback, nsnull); osso_deinitialize(m_osso_context); m_osso_context = nsnull; } diff --git a/widget/src/cocoa/nsChildView.h b/widget/src/cocoa/nsChildView.h index d9f9a932678a..efb7029b9448 100644 --- a/widget/src/cocoa/nsChildView.h +++ b/widget/src/cocoa/nsChildView.h @@ -155,9 +155,6 @@ enum { NSMutableArray* mPendingDirtyRects; BOOL mPendingFullDisplay; - PRIntervalTime mLastShadowInvalidation; - BOOL mNeedsShadowInvalidation; - // Holds our drag service across multiple drag calls. The reference to the // service is obtained when the mouse enters the view and is released when // the mouse exits or there is a drop. This prevents us from having to @@ -287,6 +284,7 @@ public: static void MouseMoved(NSEvent* aEvent); static void OnDestroyView(ChildView* aView); static BOOL WindowAcceptsEvent(NSWindow* aWindow, NSEvent* aEvent); + static void ReEvaluateMouseEnterState(NSEvent* aEvent = nil); static ChildView* sLastMouseEventView; diff --git a/widget/src/cocoa/nsChildView.mm b/widget/src/cocoa/nsChildView.mm index 62723d3e7982..d2b8eba6a2fd 100644 --- a/widget/src/cocoa/nsChildView.mm +++ b/widget/src/cocoa/nsChildView.mm @@ -195,9 +195,6 @@ PRUint32 nsChildView::sLastInputEventCount = 0; + (NSEvent*)makeNewCocoaEventWithType:(NSEventType)type fromEvent:(NSEvent*)theEvent; -- (void)maybeInvalidateShadow; -- (void)invalidateShadow; - #if USE_CLICK_HOLD_CONTEXTMENU // called on a timer two seconds after a mouse down to see if we should display // a context menu (click-hold) @@ -2497,37 +2494,6 @@ NSEvent* gLastDragMouseDownEvent = nil; NS_OBJC_END_TRY_ABORT_BLOCK; } -// Limit shadow invalidation to 10 times per second. -static const PRInt32 sShadowInvalidationInterval = 100; -- (void)maybeInvalidateShadow -{ - NSWindow* window = [self window]; - if (!window || [window isOpaque] || ![window hasShadow]) - return; - - PRIntervalTime now = PR_IntervalNow(); - PRInt32 elapsed = PR_IntervalToMilliseconds(now - mLastShadowInvalidation); - if (!mLastShadowInvalidation || - elapsed >= sShadowInvalidationInterval) { - [window invalidateShadow]; - mLastShadowInvalidation = now; - mNeedsShadowInvalidation = NO; - } else if (!mNeedsShadowInvalidation) { - mNeedsShadowInvalidation = YES; - [self performSelector:@selector(invalidateShadow) - withObject:nil - afterDelay:(sShadowInvalidationInterval - elapsed) / 1000.0]; - } -} - -- (void)invalidateShadow -{ - if (![self window] || !mNeedsShadowInvalidation) - return; - [[self window] invalidateShadow]; - mNeedsShadowInvalidation = NO; -} - // The display system has told us that a portion of our view is dirty. Tell // gecko to paint it - (void)drawRect:(NSRect)aRect @@ -2535,9 +2501,11 @@ static const PRInt32 sShadowInvalidationInterval = 100; CGContextRef cgContext = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort]; [self drawRect:aRect inContext:cgContext]; - // If we're a transparent window, and our contents have changed, we need + // If we're a transparent window and our contents have changed, we need // to make sure the shadow is updated to the new contents. - [self maybeInvalidateShadow]; + if ([[self window] isKindOfClass:[BaseWindow class]]) { + [(BaseWindow*)[self window] deferredInvalidateShadow]; + } } - (void)drawRect:(NSRect)aRect inContext:(CGContextRef)aContext @@ -2665,11 +2633,11 @@ static const PRInt32 sShadowInvalidationInterval = 100; - (void)viewWillDraw { - if (!mGeckoChild) - return; - - nsPaintEvent paintEvent(PR_TRUE, NS_WILL_PAINT, mGeckoChild); - mGeckoChild->DispatchWindowEvent(paintEvent); + if (mGeckoChild) { + nsPaintEvent paintEvent(PR_TRUE, NS_WILL_PAINT, mGeckoChild); + mGeckoChild->DispatchWindowEvent(paintEvent); + } + [super viewWillDraw]; } // Allows us to turn off setting up the clip region @@ -3012,10 +2980,28 @@ static const PRInt32 sShadowInvalidationInterval = 100; NS_OBJC_END_TRY_ABORT_BLOCK; } +// Returning NO from this method only disallows ordering on mousedown - in order +// to prevent it for mouseup too, we need to call [NSApp preventWindowOrdering] +// when handling the mousedown event. +- (BOOL)shouldDelayWindowOrderingForEvent:(NSEvent*)aEvent +{ + // Always using system-provided window ordering for normal windows. + if (![[self window] isKindOfClass:[PopupWindow class]]) + return NO; + + // Don't reorder when we're already accepting mouse events, for example + // because we're a context menu. + return ChildViewMouseTracker::WindowAcceptsEvent([self window], aEvent); +} + - (void)mouseDown:(NSEvent*)theEvent { NS_OBJC_BEGIN_TRY_ABORT_BLOCK; + if ([self shouldDelayWindowOrderingForEvent:theEvent]) { + [NSApp preventWindowOrdering]; + } + // If we've already seen this event due to direct dispatch from menuForEvent: // just bail; if not, remember it. if (mLastMouseDownEvent == theEvent) { @@ -6536,26 +6522,28 @@ ChildViewMouseTracker::OnDestroyView(ChildView* aView) } void -ChildViewMouseTracker::MouseMoved(NSEvent* aEvent) +ChildViewMouseTracker::ReEvaluateMouseEnterState(NSEvent* aEvent) { ChildView* oldView = sLastMouseEventView; - ChildView* newView = ViewForEvent(aEvent); - sLastMouseEventView = newView; - if (newView != oldView) { + sLastMouseEventView = ViewForEvent(aEvent); + if (sLastMouseEventView != oldView) { // Send enter and / or exit events. - nsMouseEvent::exitType type = [newView window] == [oldView window] ? + nsMouseEvent::exitType type = [sLastMouseEventView window] == [oldView window] ? nsMouseEvent::eChild : nsMouseEvent::eTopLevel; [oldView sendMouseEnterOrExitEvent:aEvent enter:NO type:type]; // After the cursor exits the window set it to a visible regular arrow cursor. if (type == nsMouseEvent::eTopLevel) { [[nsCursorManager sharedInstance] setCursor:eCursor_standard]; } - // Sending the exit event to the old view might have destroyed our new view; - // if that has happened, sLastMouseEventView has been set to nil. - newView = sLastMouseEventView; - [newView sendMouseEnterOrExitEvent:aEvent enter:YES type:type]; + [sLastMouseEventView sendMouseEnterOrExitEvent:aEvent enter:YES type:type]; } - [newView handleMouseMoved:aEvent]; +} + +void +ChildViewMouseTracker::MouseMoved(NSEvent* aEvent) +{ + ReEvaluateMouseEnterState(aEvent); + [sLastMouseEventView handleMouseMoved:aEvent]; } ChildView* diff --git a/widget/src/cocoa/nsCocoaUtils.h b/widget/src/cocoa/nsCocoaUtils.h index b1591f1dd36c..e21afa29006e 100644 --- a/widget/src/cocoa/nsCocoaUtils.h +++ b/widget/src/cocoa/nsCocoaUtils.h @@ -138,6 +138,7 @@ class nsCocoaUtils // Gives the location for the event in screen coordinates. Do not call this // unless the window the event was originally targeted at is still alive! + // anEvent may be nil -- in that case the current mouse location is returned. static NSPoint ScreenLocationForEvent(NSEvent* anEvent); // Determines if an event happened over a window, whether or not the event diff --git a/widget/src/cocoa/nsCocoaUtils.mm b/widget/src/cocoa/nsCocoaUtils.mm index ecfcbebd7d72..3e931deafef0 100644 --- a/widget/src/cocoa/nsCocoaUtils.mm +++ b/widget/src/cocoa/nsCocoaUtils.mm @@ -100,7 +100,7 @@ NSPoint nsCocoaUtils::ScreenLocationForEvent(NSEvent* anEvent) NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN; // Don't trust mouse locations of mouse move events, see bug 443178. - if ([anEvent type] == NSMouseMoved) + if (!anEvent || [anEvent type] == NSMouseMoved) return [NSEvent mouseLocation]; return [[anEvent window] convertBaseToScreen:[anEvent locationInWindow]]; diff --git a/widget/src/cocoa/nsCocoaWindow.h b/widget/src/cocoa/nsCocoaWindow.h index b10f4e1a41db..559bfe62c864 100644 --- a/widget/src/cocoa/nsCocoaWindow.h +++ b/widget/src/cocoa/nsCocoaWindow.h @@ -60,18 +60,22 @@ typedef struct _nsCocoaWindowList { } nsCocoaWindowList; // NSWindow subclass that is the base class for all of our own window classes. -// This class handles the storage of those settings that need to be persisted -// across window destruction and reconstruction, i.e. when switching to and from -// fullscreen mode. +// Among other things, this class handles the storage of those settings that +// need to be persisted across window destruction and reconstruction, i.e. when +// switching to and from fullscreen mode. // We don't save shadow, transparency mode or background color because it's not // worth the hassle - Gecko will reset them anyway as soon as the window is // resized. @interface BaseWindow : NSWindow { + // Data Storage NSMutableDictionary* mState; BOOL mDrawsIntoWindowFrame; NSColor* mActiveTitlebarColor; NSColor* mInactiveTitlebarColor; + + // Shadow + BOOL mScheduledShadowInvalidation; } - (void)importState:(NSDictionary*)aState; @@ -81,6 +85,9 @@ typedef struct _nsCocoaWindowList { - (void)setTitlebarColor:(NSColor*)aColor forActiveWindow:(BOOL)aActive; - (NSColor*)titlebarColorForActiveWindow:(BOOL)aActive; +- (void)deferredInvalidateShadow; +- (void)invalidateShadow; + @end @interface NSWindow (Undocumented) diff --git a/widget/src/cocoa/nsCocoaWindow.mm b/widget/src/cocoa/nsCocoaWindow.mm index c0a134a699c1..185019ee660f 100644 --- a/widget/src/cocoa/nsCocoaWindow.mm +++ b/widget/src/cocoa/nsCocoaWindow.mm @@ -1563,6 +1563,7 @@ nsCocoaWindow::UnifiedShading(void* aInfo, const CGFloat* aIn, CGFloat* aOut) NS_OBJC_BEGIN_TRY_ABORT_BLOCK; RollUpPopups(); + ChildViewMouseTracker::ReEvaluateMouseEnterState(); // [NSApp _isRunningAppModal] will return true if we're running an OS dialog // app modally. If one of those is up then we want it to retain its menu bar. @@ -1578,6 +1579,7 @@ nsCocoaWindow::UnifiedShading(void* aInfo, const CGFloat* aIn, CGFloat* aOut) - (void)windowDidResignMain:(NSNotification *)aNotification { RollUpPopups(); + ChildViewMouseTracker::ReEvaluateMouseEnterState(); // [NSApp _isRunningAppModal] will return true if we're running an OS dialog // app modally. If one of those is up then we want it to retain its menu bar. @@ -1595,6 +1597,7 @@ nsCocoaWindow::UnifiedShading(void* aInfo, const CGFloat* aIn, CGFloat* aOut) NS_OBJC_BEGIN_TRY_ABORT_BLOCK; RollUpPopups(); + ChildViewMouseTracker::ReEvaluateMouseEnterState(); NSWindow* window = [aNotification object]; if ([window isSheet]) @@ -1608,6 +1611,7 @@ nsCocoaWindow::UnifiedShading(void* aInfo, const CGFloat* aIn, CGFloat* aOut) NS_OBJC_BEGIN_TRY_ABORT_BLOCK; RollUpPopups(); + ChildViewMouseTracker::ReEvaluateMouseEnterState(); // If a sheet just resigned key then we should paint the menu bar // for whatever window is now main. @@ -1744,6 +1748,7 @@ nsCocoaWindow::UnifiedShading(void* aInfo, const CGFloat* aIn, CGFloat* aOut) mDrawsIntoWindowFrame = NO; mActiveTitlebarColor = nil; mInactiveTitlebarColor = nil; + mScheduledShadowInvalidation = NO; return self; } @@ -1812,6 +1817,21 @@ static const NSString* kStateInactiveTitlebarColorKey = @"inactiveTitlebarColor" return aActive ? mActiveTitlebarColor : mInactiveTitlebarColor; } +- (void)deferredInvalidateShadow +{ + if (mScheduledShadowInvalidation || [self isOpaque] || ![self hasShadow]) + return; + + [self performSelector:@selector(invalidateShadow) withObject:nil afterDelay:0]; + mScheduledShadowInvalidation = YES; +} + +- (void)invalidateShadow +{ + [super invalidateShadow]; + mScheduledShadowInvalidation = NO; +} + @end // This class allows us to have a "unified toolbar" style window. It works like this: @@ -2227,53 +2247,6 @@ ContentPatternDrawCallback(void* aInfo, CGContextRef aContext) case NSScrollWheel: [target scrollWheel:anEvent]; break; - case NSLeftMouseDown: - if ([NSApp isActive]) { - [target mouseDown:anEvent]; - } else if (mIsContextMenu) { - [target mouseDown:anEvent]; - // If we're in a context menu and our NSApp isn't active (i.e. if - // we're in a context menu raised by a right mouse-down event), we - // don't want the OS to send the coming NSLeftMouseUp event to NSApp - // via the window server, but we do want our ChildView to receive an - // NSLeftMouseUp event (and to send a Gecko NS_MOUSE_BUTTON_UP event - // to the corresponding nsChildView object). If our NSApp isn't - // active when it receives the coming NSLeftMouseUp via the window - // server, our app will (in effect) become partially activated, - // which has strange side effects: For example, if another app's - // window had the focus, that window will lose the focus and the - // other app's main menu will be completely disabled (though it will - // continue to be displayed). - // A side effect of not allowing the coming NSLeftMouseUp event to be - // sent to NSApp via the window server is that our custom context - // menus will roll up whenever the user left-clicks on them, whether - // or not the left-click hit an active menu item. This is how native - // context menus behave, but wasn't how our custom context menus - // behaved previously (on the trunk or e.g. in Firefox 2.0.0.4). - // If our ChildView's corresponding nsChildView object doesn't - // dispatch an NS_MOUSE_BUTTON_UP event, none of our active menu items - // will "work" on an NSLeftMouseUp. - NSEvent *newEvent = [NSEvent mouseEventWithType:NSLeftMouseUp - location:windowLocation - modifierFlags:nsCocoaUtils::GetCocoaEventModifierFlags(anEvent) - timestamp:GetCurrentEventTime() - windowNumber:[self windowNumber] - context:nil - eventNumber:0 - clickCount:1 - pressure:0.0]; - [target mouseUp:newEvent]; - RollUpPopups(); - } else { - // If our NSApp isn't active and we're not a context menu (i.e. if - // we're an ordinary popup window), activate us before sending the - // event to its target. This prevents us from being used in the - // background, and resolves bmo bug 434097 (another app focus - // wierdness bug). - [NSApp activateIgnoringOtherApps:YES]; - [target mouseDown:anEvent]; - } - break; case NSLeftMouseUp: [target mouseUp:anEvent]; break; diff --git a/widget/src/cocoa/nsCursorManager.mm b/widget/src/cocoa/nsCursorManager.mm index b2d016689c31..db4707471bb3 100644 --- a/widget/src/cocoa/nsCursorManager.mm +++ b/widget/src/cocoa/nsCursorManager.mm @@ -107,6 +107,7 @@ static NSArray* sSpinCursorFrames = nil; switch(aCursor) { + SEL cursorSelector; case eCursor_standard: return [nsMacCursor cursorWithCursor: [NSCursor arrowCursor]]; case eCursor_wait: @@ -123,12 +124,20 @@ static NSArray* sSpinCursorFrames = nil; case eCursor_help: return [nsMacCursor cursorWithImageNamed: @"help" hotSpot: NSMakePoint(1,1)]; case eCursor_copy: - return [nsMacCursor cursorWithCursor: [NSCursor arrowCursor]]; //XXX needs real implementation + cursorSelector = @selector(dragCopyCursor); + return [nsMacCursor cursorWithCursor: [NSCursor respondsToSelector: cursorSelector] ? + [NSCursor performSelector: cursorSelector] : + [NSCursor arrowCursor]]; case eCursor_alias: - return [nsMacCursor cursorWithCursor: [NSCursor arrowCursor]]; //XXX needs real implementation + cursorSelector = @selector(dragLinkCursor); + return [nsMacCursor cursorWithCursor: [NSCursor respondsToSelector: cursorSelector] ? + [NSCursor performSelector: cursorSelector] : + [NSCursor arrowCursor]]; case eCursor_context_menu: - return [nsMacCursor cursorWithCursor: [NSCursor arrowCursor]]; //XXX needs real implementation - + cursorSelector = @selector(contextualMenuCursor); + return [nsMacCursor cursorWithCursor: [NSCursor respondsToSelector: cursorSelector] ? + [NSCursor performSelector: cursorSelector] : + [NSCursor arrowCursor]]; case eCursor_cell: return [nsMacCursor cursorWithCursor: [NSCursor crosshairCursor]]; case eCursor_grab: @@ -145,8 +154,10 @@ static NSArray* sSpinCursorFrames = nil; return [nsMacCursor cursorWithCursor: [NSCursor openHandCursor]];; case eCursor_not_allowed: case eCursor_no_drop: - return [nsMacCursor cursorWithCursor: [NSCursor arrowCursor]]; //XXX needs real implementation - + cursorSelector = @selector(operationNotAllowedCursor); + return [nsMacCursor cursorWithCursor: [NSCursor respondsToSelector: cursorSelector] ? + [NSCursor performSelector: cursorSelector] : + [NSCursor arrowCursor]]; // Resize Cursors: //North case eCursor_n_resize: @@ -223,16 +234,18 @@ static NSArray* sSpinCursorFrames = nil; if (aCursor != mCurrentCursor || ![currentCursor isSet]) { [currentCursor unset]; [[self getCursor: aCursor] set]; - - mCurrentCursor = aCursor; } - if (mCurrentCursor == eCursor_none) { - [NSCursor hide]; - } else { - [NSCursor unhide]; + if (mCurrentCursor != aCursor) { + if (aCursor == eCursor_none) { + [NSCursor hide]; + } else if (mCurrentCursor == eCursor_none) { + [NSCursor unhide]; + } } + mCurrentCursor = aCursor; + NS_OBJC_END_TRY_ABORT_BLOCK; } diff --git a/widget/src/cocoa/nsMenuBarX.mm b/widget/src/cocoa/nsMenuBarX.mm index 99ebdc6debc9..a9de0fddd34f 100644 --- a/widget/src/cocoa/nsMenuBarX.mm +++ b/widget/src/cocoa/nsMenuBarX.mm @@ -714,7 +714,7 @@ void nsMenuBarX::AttributeWillChange(nsIDocument* aDocument, void nsMenuBarX::AttributeChanged(nsIDocument * aDocument, nsIContent * aContent, PRInt32 aNameSpaceID, nsIAtom * aAttribute, - PRInt32 aModType, PRUint32 aStateMask) + PRInt32 aModType) { nsChangeObserver* obs = LookupContentChangeObserver(aContent); if (obs) diff --git a/widget/src/cocoa/nsMenuItemIconX.h b/widget/src/cocoa/nsMenuItemIconX.h index ee203ab5b353..2b42438367ba 100644 --- a/widget/src/cocoa/nsMenuItemIconX.h +++ b/widget/src/cocoa/nsMenuItemIconX.h @@ -89,6 +89,7 @@ protected: nsCOMPtr mContent; nsCOMPtr mIconRequest; nsMenuObjectX* mMenuObject; // [weak] + nsIntRect mImageRegionRect; PRPackedBool mLoadedIcon; PRPackedBool mSetIcon; NSMenuItem* mNativeMenuItem; // [weak] diff --git a/widget/src/cocoa/nsMenuItemIconX.mm b/widget/src/cocoa/nsMenuItemIconX.mm index 353eb85cc8e8..d67dc6799b76 100644 --- a/widget/src/cocoa/nsMenuItemIconX.mm +++ b/widget/src/cocoa/nsMenuItemIconX.mm @@ -21,6 +21,7 @@ * Contributor(s): * Mark Mentovai (Original Author) * Josh Aas + * Benjamin Frisch * * 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 @@ -54,6 +55,7 @@ #include "nsIDOMCSSStyleDeclaration.h" #include "nsIDOMCSSValue.h" #include "nsIDOMCSSPrimitiveValue.h" +#include "nsIDOMRect.h" #include "nsThreadUtils.h" #include "nsToolkit.h" #include "nsNetUtil.h" @@ -77,6 +79,8 @@ PRAllocCGFree(void* aInfo, const void* aData, size_t aSize) { free((void*)aData); } +typedef nsresult (nsIDOMRect::*GetRectSideMethod)(nsIDOMCSSPrimitiveValue**); + NS_IMPL_ISUPPORTS2(nsMenuItemIconX, imgIContainerObserver, imgIDecoderObserver) nsMenuItemIconX::nsMenuItemIconX(nsMenuObjectX* aMenuItem, @@ -131,11 +135,40 @@ nsMenuItemIconX::SetupIcon() return NS_OK; } - return LoadIcon(iconURI); + rv = LoadIcon(iconURI); + if (NS_FAILED(rv)) { + // There is no icon for this menu item, as an error occured while loading it. + // An icon might have been set earlier or the place holder icon may have + // been set. Clear it. + [mNativeMenuItem setImage:nil]; + } + return rv; NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT; } +static PRInt32 +GetDOMRectSide(nsIDOMRect* aRect, GetRectSideMethod aMethod) +{ + nsCOMPtr dimensionValue; + (aRect->*aMethod)(getter_AddRefs(dimensionValue)); + if (!dimensionValue) + return -1; + + PRUint16 primitiveType; + nsresult rv = dimensionValue->GetPrimitiveType(&primitiveType); + if (NS_FAILED(rv) || primitiveType != nsIDOMCSSPrimitiveValue::CSS_PX) + return -1; + + float dimension = 0; + rv = dimensionValue->GetFloatValue(nsIDOMCSSPrimitiveValue::CSS_PX, + &dimension); + if (NS_FAILED(rv)) + return -1; + + return NSToIntRound(dimension); +} + nsresult nsMenuItemIconX::GetIconURI(nsIURI** aIconURI) { @@ -164,6 +197,10 @@ nsMenuItemIconX::GetIconURI(nsIURI** aIconURI) imageURIString); nsresult rv; + nsCOMPtr cssValue; + nsCOMPtr cssStyleDecl; + nsCOMPtr primitiveValue; + PRUint16 primitiveType; if (!hasImageAttr) { // If the content node has no "image" attribute, get the // "list-style-image" property from CSS. @@ -181,23 +218,19 @@ nsMenuItemIconX::GetIconURI(nsIURI** aIconURI) nsCOMPtr domElement = do_QueryInterface(mContent); if (!domElement) return NS_ERROR_FAILURE; - nsCOMPtr cssStyleDecl; nsAutoString empty; rv = domViewCSS->GetComputedStyle(domElement, empty, getter_AddRefs(cssStyleDecl)); if (NS_FAILED(rv)) return rv; NS_NAMED_LITERAL_STRING(listStyleImage, "list-style-image"); - nsCOMPtr cssValue; rv = cssStyleDecl->GetPropertyCSSValue(listStyleImage, getter_AddRefs(cssValue)); if (NS_FAILED(rv)) return rv; - nsCOMPtr primitiveValue = - do_QueryInterface(cssValue); + primitiveValue = do_QueryInterface(cssValue); if (!primitiveValue) return NS_ERROR_FAILURE; - PRUint16 primitiveType; rv = primitiveValue->GetPrimitiveType(&primitiveType); if (NS_FAILED(rv)) return rv; if (primitiveType != nsIDOMCSSPrimitiveValue::CSS_URI) @@ -207,6 +240,11 @@ nsMenuItemIconX::GetIconURI(nsIURI** aIconURI) if (NS_FAILED(rv)) return rv; } + // Empty the mImageRegionRect initially as the image region CSS could + // have been changed and now have an error or have been removed since the + // last GetIconURI call. + mImageRegionRect.Empty(); + // If this menu item shouldn't have an icon, the string will be empty, // and NS_NewURI will fail. nsCOMPtr iconURI; @@ -215,6 +253,44 @@ nsMenuItemIconX::GetIconURI(nsIURI** aIconURI) *aIconURI = iconURI; NS_ADDREF(*aIconURI); + + if (!hasImageAttr) { + // Check if the icon has a specified image region so that it can be + // cropped appropriately before being displayed. + NS_NAMED_LITERAL_STRING(imageRegion, "-moz-image-region"); + rv = cssStyleDecl->GetPropertyCSSValue(imageRegion, + getter_AddRefs(cssValue)); + // Just return NS_OK if there if there is a failure due to no + // moz-image region specified so the whole icon will be drawn anyway. + if (NS_FAILED(rv)) return NS_OK; + + primitiveValue = do_QueryInterface(cssValue); + if (!primitiveValue) return NS_OK; + + rv = primitiveValue->GetPrimitiveType(&primitiveType); + if (NS_FAILED(rv)) return NS_OK; + if (primitiveType != nsIDOMCSSPrimitiveValue::CSS_RECT) + return NS_OK; + + nsCOMPtr imageRegionRect; + rv = primitiveValue->GetRectValue(getter_AddRefs(imageRegionRect)); + if (NS_FAILED(rv)) return NS_OK; + + if (imageRegionRect) { + // Return NS_ERROR_FAILURE if the image region is invalid so the image + // is not drawn, and behavior is similar to XUL menus. + PRInt32 bottom = GetDOMRectSide(imageRegionRect, &nsIDOMRect::GetBottom); + PRInt32 right = GetDOMRectSide(imageRegionRect, &nsIDOMRect::GetRight); + PRInt32 top = GetDOMRectSide(imageRegionRect, &nsIDOMRect::GetTop); + PRInt32 left = GetDOMRectSide(imageRegionRect, &nsIDOMRect::GetLeft); + + if (top < 0 || left < 0 || bottom <= top || right <= left) + return NS_ERROR_FAILURE; + + mImageRegionRect.SetRect(left, top, right - left, bottom - top); + } + } + return NS_OK; } @@ -344,46 +420,77 @@ nsMenuItemIconX::OnStopFrame(imgIRequest* aRequest, nsCOMPtr imageContainer; aRequest->GetImage(getter_AddRefs(imageContainer)); - if (!imageContainer) + if (!imageContainer) { + [mNativeMenuItem setImage:nil]; return NS_ERROR_FAILURE; + } nsRefPtr image; nsresult rv = imageContainer->CopyFrame(imgIContainer::FRAME_CURRENT, imgIContainer::FLAG_NONE, getter_AddRefs(image)); - if (NS_FAILED(rv) || !image) + if (NS_FAILED(rv) || !image) { + [mNativeMenuItem setImage:nil]; return NS_ERROR_FAILURE; + } - PRInt32 height = image->Height(); - PRInt32 stride = image->Stride(); - PRInt32 width = image->Width(); - PRUint32 imageLength = ((stride * height) / 4); - if ((stride % 4 != 0) || (height < 1) || (width < 1)) + PRInt32 origHeight = image->Height(); + PRInt32 origStride = image->Stride(); + PRInt32 origWidth = image->Width(); + if ((origStride % 4 != 0) || (origHeight < 1) || (origWidth < 1)) { + [mNativeMenuItem setImage:nil]; return NS_ERROR_FAILURE; + } PRUint32* imageData = (PRUint32*)image->Data(); - PRUint32* reorderedData = (PRUint32*)malloc(height * stride); - if (!reorderedData) - return NS_ERROR_OUT_OF_MEMORY; + // If the image region is invalid, don't draw the image to almost match + // the behavior of other platforms. + if (!mImageRegionRect.IsEmpty() && + (mImageRegionRect.XMost() > origWidth || + mImageRegionRect.YMost() > origHeight)) { + [mNativeMenuItem setImage:nil]; + return NS_ERROR_FAILURE; + } - // We have to reorder data to have alpha last because only Tiger can handle - // alpha being first. Also the data must always be big endian (silly). - - for (PRUint32 i = 0; i < imageLength; i++) { - PRUint32 pixel = imageData[i]; - reorderedData[i] = CFSwapInt32HostToBig((pixel << 8) | (pixel >> 24)); + if (mImageRegionRect.IsEmpty()) { + mImageRegionRect.SetRect(0, 0, origWidth, origHeight); + } + + PRInt32 newStride = mImageRegionRect.width * sizeof(PRUint32); + PRInt32 imageLength = mImageRegionRect.height * mImageRegionRect.width; + + PRUint32* reorderedData = (PRUint32*)malloc(imageLength * sizeof(PRUint32)); + if (!reorderedData) { + [mNativeMenuItem setImage:nil]; + return NS_ERROR_OUT_OF_MEMORY; + } + + // We have to clip the data to the image region and reorder the data to have + // alpha last because only Tiger can handle alpha being first. Also the data + // must always be big endian (silly). + for (PRInt32 y = 0; y < mImageRegionRect.height; y++) { + PRInt32 srcLine = (mImageRegionRect.y + y) * (origStride/4); + PRInt32 dstLine = y * mImageRegionRect.width; + for (PRInt32 x = 0; x < mImageRegionRect.width; x++) { + PRUint32 pixel = imageData[srcLine + x + mImageRegionRect.x]; + reorderedData[dstLine + x] = + CFSwapInt32HostToBig((pixel << 8) | (pixel >> 24)); + } } CGDataProviderRef provider = ::CGDataProviderCreateWithData(NULL, reorderedData, imageLength, PRAllocCGFree); if (!provider) { free(reorderedData); + [mNativeMenuItem setImage:nil]; return NS_ERROR_FAILURE; } CGColorSpaceRef colorSpace = ::CGColorSpaceCreateDeviceRGB(); - CGImageRef cgImage = ::CGImageCreate(width, height, 8, 32, stride, colorSpace, - kCGImageAlphaPremultipliedLast, provider, - NULL, true, kCGRenderingIntentDefault); + CGImageRef cgImage = ::CGImageCreate(mImageRegionRect.width, + mImageRegionRect.height, 8, 32, newStride, + colorSpace, kCGImageAlphaPremultipliedLast, + provider, NULL, true, + kCGRenderingIntentDefault); ::CGDataProviderRelease(provider); // The image may not be the right size for a menu icon (16x16). diff --git a/widget/src/cocoa/nsNativeThemeCocoa.mm b/widget/src/cocoa/nsNativeThemeCocoa.mm index d6428d54fed6..ee8401aa63f5 100644 --- a/widget/src/cocoa/nsNativeThemeCocoa.mm +++ b/widget/src/cocoa/nsNativeThemeCocoa.mm @@ -972,7 +972,7 @@ nsNativeThemeCocoa::DrawDropdown(CGContextRef cgContext, const HIRect& inBoxRect [cell setEnabled:!IsDisabled(aFrame)]; [cell setShowsFirstResponder:(IsFocused(aFrame) || (inState & NS_EVENT_STATE_FOCUS))]; - [cell setHighlighted:((inState & NS_EVENT_STATE_ACTIVE) && (inState & NS_EVENT_STATE_HOVER))]; + [cell setHighlighted:IsOpenButton(aFrame)]; [cell setControlTint:(FrameIsInActiveWindow(aFrame) ? [NSColor currentControlTint] : NSClearControlTint)]; const CellRenderSettings& settings = isEditable ? editableMenulistSettings : dropdownSettings; @@ -2365,7 +2365,8 @@ nsNativeThemeCocoa::WidgetStateChanged(nsIFrame* aFrame, PRUint8 aWidgetType, aAttribute == nsWidgetAtoms::sortdirection || aAttribute == nsWidgetAtoms::focused || aAttribute == nsWidgetAtoms::_default || - aAttribute == nsWidgetAtoms::step) + aAttribute == nsWidgetAtoms::step || + aAttribute == nsWidgetAtoms::open) *aShouldRepaint = PR_TRUE; } diff --git a/widget/src/cocoa/nsToolkit.mm b/widget/src/cocoa/nsToolkit.mm index 64dcd2f25734..b9b9b68b17a3 100644 --- a/widget/src/cocoa/nsToolkit.mm +++ b/widget/src/cocoa/nsToolkit.mm @@ -192,10 +192,17 @@ nsToolkit::RemoveSleepWakeNotifcations() NS_OBJC_END_TRY_ABORT_BLOCK; } -// We shouldn't do anything here. See RegisterForAllProcessMouseEvents() for -// the reason why. +// This is the callback used in RegisterForAllProcessMouseEvents. static OSStatus EventMonitorHandler(EventHandlerCallRef aCaller, EventRef aEvent, void* aRefcon) { + // Up to Mac OS 10.4 (or when building with the 10.4 SDK), installing a Carbon + // event handler like this one caused the OS to post the equivalent Cocoa + // events to [NSApp sendEvent:]. When using the 10.5 SDK, this doesn't happen + // any more, so we need to do it manually. +#ifdef NS_LEOPARD_AND_LATER + [NSApp sendEvent:[NSEvent eventWithEventRef:aEvent]]; +#endif // NS_LEOPARD_AND_LATER + return eventNotHandledErr; } @@ -265,16 +272,6 @@ nsToolkit::RegisterForAllProcessMouseEvents() return; } if (!mEventMonitorHandler) { - // Installing a handler for particular Carbon events causes the OS to post - // equivalent Cocoa events to the browser's event stream (the one that - // passes through [NSApp sendEvent:]). For this reason installing a - // handler for kEventMouseMoved fixes bmo bug 368077, even though our - // handler does nothing on mouse-moved events. (Actually it's more - // accurate to say that the OS (working in a different process) sends - // events to the window server, from which the OS (acting in the browser's - // process on its behalf) grabs them and turns them into both Carbon - // events (which get fed to our handler) and Cocoa events (which get fed - // to [NSApp sendEvent:]).) EventTypeSpec kEvents[] = {{kEventClassMouse, kEventMouseMoved}}; InstallEventHandler(GetEventMonitorTarget(), EventMonitorHandler, GetEventTypeCount(kEvents), kEvents, 0, diff --git a/widget/src/windows/nsDeviceContextSpecWin.cpp b/widget/src/windows/nsDeviceContextSpecWin.cpp index 2e1b78a3ed8f..4b788a75b14e 100644 --- a/widget/src/windows/nsDeviceContextSpecWin.cpp +++ b/widget/src/windows/nsDeviceContextSpecWin.cpp @@ -464,8 +464,10 @@ NS_IMETHODIMP nsDeviceContextSpecWin::Init(nsIWidget* aWidget, HGLOBAL hDevNames = NULL; // Get the Print Name to be used - PRUnichar * printerName; - mPrintSettings->GetPrinterName(&printerName); + PRUnichar * printerName = nsnull; + if (mPrintSettings) { + mPrintSettings->GetPrinterName(&printerName); + } // If there is no name then use the default printer if (!printerName || (printerName && !*printerName)) { @@ -508,8 +510,10 @@ NS_IMETHODIMP nsDeviceContextSpecWin::GetSurfaceForPrinter(gfxASurface **surface nsRefPtr newSurface; - PRInt16 outputFormat; - mPrintSettings->GetOutputFormat(&outputFormat); + PRInt16 outputFormat = 0; + if (mPrintSettings) { + mPrintSettings->GetOutputFormat(&outputFormat); + } if (outputFormat == nsIPrintSettings::kOutputFormatPDF) { nsXPIDLString filename; @@ -534,6 +538,7 @@ NS_IMETHODIMP nsDeviceContextSpecWin::GetSurfaceForPrinter(gfxASurface **surface newSurface = new gfxPDFSurface(stream, gfxSize(width, height)); } else { if (mDevMode) { + NS_WARN_IF_FALSE(mDriverName, "No driver!"); HDC dc = ::CreateDCW(mDriverName, mDeviceName, NULL, mDevMode); // have this surface take over ownership of this DC diff --git a/widget/src/windows/nsWindow.cpp b/widget/src/windows/nsWindow.cpp index f0ddfd6677e9..369f9404178f 100644 --- a/widget/src/windows/nsWindow.cpp +++ b/widget/src/windows/nsWindow.cpp @@ -3426,10 +3426,23 @@ PRBool nsWindow::DispatchFocusToTopLevelWindow(PRUint32 aEventType) sJustGotActivate = PR_FALSE; sJustGotDeactivate = PR_FALSE; - // clear the flags, and retrieve the toplevel window. This way, it doesn't - // mattter what child widget received the focus event and it will always be - // fired at the toplevel window. - HWND toplevelWnd = GetTopLevelHWND(mWnd); + // retrive the toplevel window or dialog + HWND curWnd = mWnd; + HWND toplevelWnd = NULL; + while (curWnd) { + toplevelWnd = curWnd; + + nsWindow *win = GetNSWindowPtr(curWnd); + if (win) { + nsWindowType wintype; + win->GetWindowType(wintype); + if (wintype == eWindowType_toplevel || wintype == eWindowType_dialog) + break; + } + + curWnd = ::GetParent(curWnd); // Parent or owner (if has no parent) + } + if (toplevelWnd) { nsWindow *win = GetNSWindowPtr(toplevelWnd); if (win) diff --git a/widget/tests/native_mouse_mac_window.xul b/widget/tests/native_mouse_mac_window.xul index 9d598df8b5b5..e8d3ae012240 100644 --- a/widget/tests/native_mouse_mac_window.xul +++ b/widget/tests/native_mouse_mac_window.xul @@ -110,6 +110,10 @@ NSEventTypeBeginGesture = 19, NSEventTypeEndGesture = 20; + const gDebug = false; + + function printDebug(msg) { if (gDebug) dump(msg); } + var gExpectedEvents = []; var gRightWindow = null, gPopup = null; @@ -120,6 +124,7 @@ expEv.screenY = y; gExpectedEvents.push(expEv); }); + printDebug("sending event: " + x + ", " + y + " (" + msg + ")\n"); netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect'); var utils = win.QueryInterface(Components.interfaces.nsIInterfaceRequestor). getInterface(Components.interfaces.nsIDOMWindowUtils); @@ -139,6 +144,7 @@ function focusAndThen(win, callback) { eventListenOnce(win, "focus", callback); + printDebug("focusing a window\n"); win.focus(); } @@ -159,6 +165,7 @@ var gEventNum = 0; function eventMonitor(e) { + printDebug("got event: " + eventToString(e) + "\n"); var expectedEvent = gExpectedEvents.shift(); while (expectedEvent && expectedEvent.todoShouldHaveFired) { todo(false, "Should have got event: " + eventToString(expectedEvent)); @@ -238,22 +245,21 @@ [400, 150, NSMouseMoved, null, right, [ { type: "mouseout", target: leftElem }, ]], - // Clicking an inactive window shouldn't have any effect, other - // than focusing it. + // Clicking an inactive window should make it active and fire a mouseover + // event. [400, 150, NSLeftMouseDown, null, right, [ + { type: "mouseover", target: rightElem }, ]], [400, 150, NSLeftMouseUp, null, right, [ ]], // Now it's focused, so we should get a mousedown event when clicking. [400, 150, NSLeftMouseDown, null, right, [ { type: "mousedown", target: rightElem }, - { type: "mouseover", target: rightElem, todoShouldHaveFired: true }, ]], // Let's drag to the right without letting the button go. It would be better // if the mouseover event had fired as soon as the mouse entered the window, // and not only when dragging, but that's ok. [410, 150, NSLeftMouseDragged, null, right, [ - { type: "mouseover", target: rightElem, todoShouldNotHaveFired: true }, { type: "mousemove", target: rightElem }, ]], // Let go of the mouse. @@ -279,12 +285,15 @@ ]], // Right clicking hasn't focused it, so the window is still inactive. // Let's focus it; this time without the mouse, for variaton's sake. + // Still, mouseout and mouseover events should fire. function raiseLeftWindow(callback) { - focusAndThen(left, callback); + clearExpectedEvents(); + gExpectedEvents.push({ screenX: 150, screenY: 170, type: "mouseout", target: rightElem }); + gExpectedEvents.push({ screenX: 150, screenY: 170, type: "mouseover", target: leftElem }); + focusAndThen(left, function () { SimpleTest.executeSoon(callback); }); }, // It's active, so it should respond to mousemove events now. [150, 170, NSMouseMoved, null, left, [ - { type: "mouseover", target: leftElem }, { type: "mousemove", target: leftElem }, ]], @@ -328,8 +337,9 @@ [400, 180, NSMouseMoved, null, right, [ ]], // Activate the right window with a click. - // This will close the popup. + // This will close the popup and make the mouse enter the right window. [400, 180, NSLeftMouseDown, null, right, [ + { type: "mouseover", target: rightElem }, ]], [400, 180, NSLeftMouseUp, null, right, [ ]], @@ -338,9 +348,7 @@ callback(); }, // Now the right window is active; click it again, just for fun. - // (Would be good to have a mouseover event here.) [400, 180, NSLeftMouseDown, null, right, [ - { type: "mouseover", target: rightElem, todoShouldHaveFired: true }, { type: "mousedown", target: rightElem }, ]], [400, 180, NSLeftMouseUp, null, right, [ diff --git a/xpcom/glue/AutoRestore.h b/xpcom/glue/AutoRestore.h new file mode 100644 index 000000000000..5810a85f6d5e --- /dev/null +++ b/xpcom/glue/AutoRestore.h @@ -0,0 +1,70 @@ +/* vim: set shiftwidth=2 tabstop=8 autoindent cindent expandtab: */ +/* ***** 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 nsAutoRestore.h. + * + * The Initial Developer of the Original Code is the Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * L. David Baron , Mozilla Corporation (original author) + * + * 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 ***** */ + +/* functions for restoring saved values at the end of a C++ scope */ + +#ifndef mozilla_AutoRestore_h_ +#define mozilla_AutoRestore_h_ + +namespace mozilla { + + /** + * Save the current value of a variable and restore it when the object + * goes out of scope. For example: + * { + * AutoRestore savePainting(mIsPainting); + * mIsPainting = PR_TRUE; + * + * // ... your code here ... + * + * // mIsPainting is reset to its old value at the end of this block + * } + */ + template + class AutoRestore + { + private: + T& mLocation; + T mValue; + public: + AutoRestore(T& aValue) : mLocation(aValue), mValue(aValue) {} + ~AutoRestore() { mLocation = mValue; } + }; + +} + +#endif /* !defined(mozilla_AutoRestore_h_) */ diff --git a/xpcom/glue/Makefile.in b/xpcom/glue/Makefile.in index aba0211be525..726e68fae8ce 100644 --- a/xpcom/glue/Makefile.in +++ b/xpcom/glue/Makefile.in @@ -124,11 +124,13 @@ EXPORTS = \ $(NULL) EXPORTS_mozilla = \ + AutoRestore.h \ BlockingResourceBase.h \ CondVar.h \ DeadlockDetector.h \ Monitor.h \ Mutex.h \ + SSE.h \ $(NULL) SDK_LIBRARY = \ diff --git a/xpcom/glue/SSE.cpp b/xpcom/glue/SSE.cpp new file mode 100644 index 000000000000..5c8651831dc2 --- /dev/null +++ b/xpcom/glue/SSE.cpp @@ -0,0 +1,93 @@ +/* vim: set shiftwidth=4 tabstop=8 autoindent cindent expandtab: */ +/* ***** 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 SSE.cpp + * + * The Initial Developer of the Original Code is the Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * L. David Baron , Mozilla Corporation (original author) + * + * 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 ***** */ + +/* compile-time and runtime tests for whether to use SSE instructions */ + +#include "SSE.h" + +namespace mozilla { + +namespace sse_private { + +#if defined(MOZILLA_SSE_HAVE_CPUID_DETECTION) + +#if !defined(MOZILLA_PRESUME_MMX) + bool mmx_enabled + = sse_private::has_cpuid_bit(1u, sse_private::edx, (1u<<23)); +#endif + +#if !defined(MOZILLA_PRESUME_SSE) + bool sse_enabled + = sse_private::has_cpuid_bit(1u, sse_private::edx, (1u<<25)); +#endif + +#if !defined(MOZILLA_PRESUME_SSE2) + bool sse2_enabled + = sse_private::has_cpuid_bit(1u, sse_private::edx, (1u<<26)); +#endif + +#if !defined(MOZILLA_PRESUME_SSE3) + bool sse3_enabled + = sse_private::has_cpuid_bit(1u, sse_private::ecx, (1u<<0)); +#endif + +#if !defined(MOZILLA_PRESUME_SSSE3) + bool ssse3_enabled + = sse_private::has_cpuid_bit(1u, sse_private::ecx, (1u<<9)); +#endif + +#if !defined(MOZILLA_PRESUME_SSE4A) + bool sse4a_enabled + = sse_private::has_cpuid_bit(0x80000001u, sse_private::ecx, (1u<<6)); +#endif + +#if !defined(MOZILLA_PRESUME_SSE4_1) + bool sse4_1_enabled + = sse_private::has_cpuid_bit(1u, sse_private::ecx, (1u<<19)); +#endif + +#if !defined(MOZILLA_PRESUME_SSE4_2) + bool sse4_2_enabled + = sse_private::has_cpuid_bit(1u, sse_private::ecx, (1u<<20)); +#endif + +#endif + +} + +} + diff --git a/xpcom/glue/SSE.h b/xpcom/glue/SSE.h new file mode 100644 index 000000000000..da6725b57751 --- /dev/null +++ b/xpcom/glue/SSE.h @@ -0,0 +1,561 @@ +/* vim: set shiftwidth=4 tabstop=8 autoindent cindent expandtab: */ +/* ***** 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 SSE.h + * + * The Initial Developer of the Original Code is the Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * L. David Baron , Mozilla Corporation (original author) + * + * 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 ***** */ + +/* compile-time and runtime tests for whether to use SSE instructions */ + +#ifndef mozilla_SSE_h_ +#define mozilla_SSE_h_ + +// for definition of NS_COM_GLUE +#include "nscore.h" + +/** + * The public interface of this header consists of a set of macros and + * functions for Intel CPU features. + * + * CODE USING ASSEMBLY + * =================== + * + * For each feature handled here, this header defines a single function + * that can be used to test whether to use code written in *assembly*: + * mozilla::supports_mmx + * mozilla::supports_sse + * mozilla::supports_sse2 + * mozilla::supports_sse3 + * mozilla::supports_ssse3 + * mozilla::supports_sse4a + * mozilla::supports_sse4_1 + * mozilla::supports_sse4_2 + * Note that the dynamic detection depends on cpuid intrinsics only + * available in gcc 4.3 or later and MSVC 8.0 (Visual C++ 2005) or + * later, so the dynamic detection returns false in older compilers. + * (This could be fixed by replacing the code with inline assembly.) + * + * CODE USING INTRINSICS + * ===================== + * + * The remainder of the functions and macros that are the API from this + * header relate to code written using CPU intrinsics. + * + * In each macro-function pair, the function may not be available if the + * macro is undefined. They should be used in the following pattern: + * + * if (mozilla::use_abc()) { + * #ifdef MOZILLA_COMPILE_WITH_ABC + * // abc-specific code here + * #endif + * } else { + * // generic code here + * } + * + * In addition, on some platforms, the headers that contain the + * intrinsics for many of these features won't compile unless we define + * a particular macro first (to pretend that we gave gcc an appropriate + * -march option). Therefore, code using this header should NOT include + * the headers for intrinsics directly, but should instead request the + * header by defining the header macro given below *before* including + * this file (which, in practice, means before including *any* header + * files). + * + * The dynamic detection depends on cpuid intrinsics only available in + * gcc 4.3 or later and MSVC 8.0 (Visual C++ 2005) or later, so the + * dynamic detection returns false in older compilers. However, it + * could be extended to avoid this restriction; see the code in + * mozilla/jpeg/jdapimin.c for some hints. + * + * Macro: MOZILLA_COMPILE_WITH_MMX + * Function: mozilla::use_mmx + * Header Macro: MOZILLA_SSE_INCLUDE_HEADER_FOR_MMX + * Header: + * + * Macro: MOZILLA_COMPILE_WITH_SSE + * Function: mozilla::use_sse + * Header Macro: MOZILLA_SSE_INCLUDE_HEADER_FOR_SSE + * Header: + * + * Macro: MOZILLA_COMPILE_WITH_SSE2 + * Function: mozilla::use_sse2 + * Header Macro: MOZILLA_SSE_INCLUDE_HEADER_FOR_SSE2 + * Header: + * + * Macro: MOZILLA_COMPILE_WITH_SSE3 + * Function: mozilla::use_sse3 + * Header Macro: MOZILLA_SSE_INCLUDE_HEADER_FOR_SSE3 + * Header: + * + * Macro: MOZILLA_COMPILE_WITH_SSSE3 + * Function: mozilla::use_ssse3 + * Header Macro: MOZILLA_SSE_INCLUDE_HEADER_FOR_SSSE3 + * Header: + * + * Macro: MOZILLA_COMPILE_WITH_SSE4A + * Function: mozilla::use_sse4a + * Header Macro: MOZILLA_SSE_INCLUDE_HEADER_FOR_SSE4A + * Header: + * + * Macro: MOZILLA_COMPILE_WITH_SSE4_1 + * Function: mozilla::use_sse4_1 + * Header Macro: MOZILLA_SSE_INCLUDE_HEADER_FOR_SSE4_1 + * Header: + * + * Macro: MOZILLA_COMPILE_WITH_SSE4_2 + * Function: mozilla::use_sse4_2 + * Header Macro: MOZILLA_SSE_INCLUDE_HEADER_FOR_SSE4_2 + * Header: + */ + +#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) +// GCC + +// FIXME: Is any of this available on arm? GCC seems to offer mmintrin.h + +#if 0 + // #pragma target doesn't actually work yet; making it work depends on + // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39787 and + // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41201 being fixed. + // Note that this means there are cases where mozilla::use_abc() will + // return true even though we can't define MOZILLA_COMPILE_WITH_ABC. + #define MOZILLA_SSE_HAVE_PRAGMA_TARGET +#endif + +#ifdef MOZILLA_SSE_HAVE_PRAGMA_TARGET + // Limit compilation to compiler versions where the *intrin.h headers + // are present. (These ifdefs actually aren't useful because they're + // all (currently) weaker than MOZILLA_SSE_HAVE_PRAGMA_TARGET.) + #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) // GCC 3.1 and up + #define MOZILLA_COMPILE_WITH_MMX 1 + #define MOZILLA_COMPILE_WITH_SSE 1 + #endif // GCC 3.1 and up + #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) // GCC 3.3 and up + #define MOZILLA_COMPILE_WITH_SSE2 1 + #define MOZILLA_COMPILE_WITH_SSE3 1 + #endif // GCC 3.3 and up + #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) // GCC 4.3 and up + #define MOZILLA_COMPILE_WITH_SSSE3 1 + #define MOZILLA_COMPILE_WITH_SSE4A 1 + #define MOZILLA_COMPILE_WITH_SSE4_1 1 + #define MOZILLA_COMPILE_WITH_SSE4_2 1 + #endif // GCC 4.3 and up + // GCC 4.3 and GCC 4.4 shipped with SSE5, but it is being removed in GCC + // 4.5; see http://gcc.gnu.org/ml/gcc-patches/2009-07/msg01527.html and + // http://gcc.gnu.org/ml/gcc-patches/2009-07/msg01536.html +#else + #ifdef __MMX__ + #define MOZILLA_COMPILE_WITH_MMX 1 + #endif + #ifdef __SSE__ + #define MOZILLA_COMPILE_WITH_SSE 1 + #endif + #ifdef __SSE2__ + #define MOZILLA_COMPILE_WITH_SSE2 1 + #endif + #ifdef __SSE3__ + #define MOZILLA_COMPILE_WITH_SSE3 1 + #endif + #ifdef __SSSE3__ + #define MOZILLA_COMPILE_WITH_SSSE3 1 + #endif + #ifdef __SSE4A__ + #define MOZILLA_COMPILE_WITH_SSE4A 1 + #endif + #ifdef __SSE4_1__ + #define MOZILLA_COMPILE_WITH_SSE4_1 1 + #endif + #ifdef __SSE4_2__ + #define MOZILLA_COMPILE_WITH_SSE4_2 1 + #endif +#endif + +#ifdef __MMX__ + // It's ok to use MMX instructions based on the -march option (or + // the default for x86_64 or for Intel Mac). + #define MOZILLA_PRESUME_MMX 1 +#endif +#ifdef __SSE__ + // It's ok to use SSE instructions based on the -march option (or + // the default for x86_64 or for Intel Mac). + #define MOZILLA_PRESUME_SSE 1 +#endif +#ifdef __SSE2__ + // It's ok to use SSE2 instructions based on the -march option (or + // the default for x86_64 or for Intel Mac). + #define MOZILLA_PRESUME_SSE2 1 +#endif +#ifdef __SSE3__ + // It's ok to use SSE3 instructions based on the -march option (or the + // default for Intel Mac). + #define MOZILLA_PRESUME_SSE3 1 +#endif +#ifdef __SSSE3__ + // It's ok to use SSSE3 instructions based on the -march option. + #define MOZILLA_PRESUME_SSSE3 1 +#endif +#ifdef __SSE4A__ + // It's ok to use SSE4A instructions based on the -march option. + #define MOZILLA_PRESUME_SSE4A 1 +#endif +#ifdef __SSE4_1__ + // It's ok to use SSE4.1 instructions based on the -march option. + #define MOZILLA_PRESUME_SSE4_1 1 +#endif +#ifdef __SSE4_2__ + // It's ok to use SSE4.2 instructions based on the -march option. + #define MOZILLA_PRESUME_SSE4_2 1 +#endif + +#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) + +// cpuid.h is available on gcc 4.3 and higher on i386 and x86_64 +#include +#define MOZILLA_SSE_HAVE_CPUID_DETECTION + +namespace mozilla { + + namespace sse_private { + + enum CPUIDRegister { eax = 0, ebx = 1, ecx = 2, edx = 3 }; + + inline bool + has_cpuid_bit(unsigned int level, CPUIDRegister reg, unsigned int bit) + { + unsigned int regs[4]; + return __get_cpuid(level, ®s[0], ®s[1], ®s[2], ®s[3]) && + (regs[reg] & bit); + } + + } + +} + +#endif + +// We need to #include headers quite carefully for CPUID-tested +// compilation. GCC's headers for SSE intrinsics both: +// * have #error in them when the appropriate macro is not defined, and +// * depend on intrinsics that depend on -msse, etc. +// We could fix the first of these options with #define. However, we +// can fix the second only with #pragma directives introduced in GCC +// 4.4 (but not yet working quite well enough on any gcc version), whose +// availability influenced (above) whether MOZILLA_COMPILE_WITH_* is +// defined. + +#ifdef MOZILLA_SSE_HAVE_PRAGMA_TARGET +#pragma GCC push_options +#endif + +#if defined(MOZILLA_COMPILE_WITH_MMX) && \ + defined(MOZILLA_SSE_INCLUDE_HEADER_FOR_MMX) + #if !defined(__MMX__) + #pragma GCC target ("mmx") + #endif + #include +#endif + +#if defined(MOZILLA_COMPILE_WITH_SSE) && \ + defined(MOZILLA_SSE_INCLUDE_HEADER_FOR_SSE) + #if !defined(__SSE__) + #pragma GCC target ("sse") + #endif + #include +#endif + +#if defined(MOZILLA_COMPILE_WITH_SSE2) && \ + defined(MOZILLA_SSE_INCLUDE_HEADER_FOR_SSE2) + #if !defined(__SSE2__) + #pragma GCC target ("sse2") + #endif + #include +#endif + +#if defined(MOZILLA_COMPILE_WITH_SSE3) && \ + defined(MOZILLA_SSE_INCLUDE_HEADER_FOR_SSE3) + #if !defined(__SSE3__) + #pragma GCC target ("sse3") + #endif + #include +#endif + +#if defined(MOZILLA_COMPILE_WITH_SSSE3) && \ + defined(MOZILLA_SSE_INCLUDE_HEADER_FOR_SSSE3) + #if !defined(__SSSE3__) + #pragma GCC target ("ssse3") + #endif + #include +#endif + +#if defined(MOZILLA_COMPILE_WITH_SSE4A) && \ + defined(MOZILLA_SSE_INCLUDE_HEADER_FOR_SSE4A) + #if !defined(__SSE4A__) + #pragma GCC target ("sse4a") + #endif + #include +#endif + +#if defined(MOZILLA_COMPILE_WITH_SSE4_1) && \ + defined(MOZILLA_SSE_INCLUDE_HEADER_FOR_SSE4_1) + #if !defined(__SSE4_1__) + #pragma GCC target ("sse4.1") + #endif + #include +#endif + +#if defined(MOZILLA_COMPILE_WITH_SSE4_2) && \ + defined(MOZILLA_SSE_INCLUDE_HEADER_FOR_SSE4_2) + #if !defined(__SSE4_2__) + #pragma GCC target ("sse4.2") + #endif + #include +#endif + +#ifdef MOZILLA_SSE_HAVE_PRAGMA_TARGET +#pragma GCC pop_options +#endif + +#elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64)) +// MSVC on x86 or amd64 + +// Limit compilation to compiler versions where the *intrin.h headers +// are present +#if 1 // Available at least back to Visual Studio 2003 +#define MOZILLA_COMPILE_WITH_MMX 1 +#define MOZILLA_COMPILE_WITH_SSE 1 +#define MOZILLA_COMPILE_WITH_SSE2 1 +#endif // Available at least back to Visual Studio 2003 + +#if _MSC_VER >= 1400 +#include +#define MOZILLA_SSE_HAVE_CPUID_DETECTION + +namespace mozilla { + + namespace sse_private { + + enum CPUIDRegister { eax = 0, ebx = 1, ecx = 2, edx = 3 }; + + inline bool + has_cpuid_bit(unsigned int level, CPUIDRegister reg, unsigned int bit) + { + // Check that the level in question is supported. + int regs[4]; + __cpuid(regs, level & 0x80000000u); + if (unsigned(regs[0]) < level) + return false; + + __cpuid(regs, level); + return !!(unsigned(regs[reg]) & bit); + } + + } + +} + +#endif + +#if defined(_M_AMD64) + // MMX is always available on AMD64. + #define MOZILLA_PRESUME_MMX + // SSE is always available on AMD64. + #define MOZILLA_PRESUME_SSE + // SSE2 is always available on AMD64. + #define MOZILLA_PRESUME_SSE2 +#endif + +#if defined(MOZILLA_COMPILE_WITH_MMX) && \ + defined(MOZILLA_SSE_INCLUDE_HEADER_FOR_MMX) +#include +#endif + +#if defined(MOZILLA_COMPILE_WITH_SSE) && \ + defined(MOZILLA_SSE_INCLUDE_HEADER_FOR_SSE) +#include +#endif + +#if defined(MOZILLA_COMPILE_WITH_SSE2) && \ + defined(MOZILLA_SSE_INCLUDE_HEADER_FOR_SSE2) +#include +#endif + +#endif + +namespace mozilla { + + namespace sse_private { +#if defined(MOZILLA_SSE_HAVE_CPUID_DETECTION) +#if !defined(MOZILLA_PRESUME_MMX) + extern bool NS_COM_GLUE mmx_enabled; +#endif +#if !defined(MOZILLA_PRESUME_SSE) + extern bool NS_COM_GLUE sse_enabled; +#endif +#if !defined(MOZILLA_PRESUME_SSE2) + extern bool NS_COM_GLUE sse2_enabled; +#endif +#if !defined(MOZILLA_PRESUME_SSE3) + extern bool NS_COM_GLUE sse3_enabled; +#endif +#if !defined(MOZILLA_PRESUME_SSSE3) + extern bool NS_COM_GLUE ssse3_enabled; +#endif +#if !defined(MOZILLA_PRESUME_SSE4A) + extern bool NS_COM_GLUE sse4a_enabled; +#endif +#if !defined(MOZILLA_PRESUME_SSE4_1) + extern bool NS_COM_GLUE sse4_1_enabled; +#endif +#if !defined(MOZILLA_PRESUME_SSE4_2) + extern bool NS_COM_GLUE sse4_2_enabled; +#endif +#endif + } + +#if defined(MOZILLA_PRESUME_MMX) + inline bool supports_mmx() { return true; } +#elif defined(MOZILLA_SSE_HAVE_CPUID_DETECTION) + inline bool supports_mmx() { return sse_private::mmx_enabled; } +#else + inline bool supports_mmx() { return false; } +#endif + +#if defined(MOZILLA_PRESUME_SSE) + inline bool supports_sse() { return true; } +#elif defined(MOZILLA_SSE_HAVE_CPUID_DETECTION) + inline bool supports_sse() { return sse_private::sse_enabled; } +#else + inline bool supports_sse() { return false; } +#endif + +#if defined(MOZILLA_PRESUME_SSE2) + inline bool supports_sse2() { return true; } +#elif defined(MOZILLA_SSE_HAVE_CPUID_DETECTION) + inline bool supports_sse2() { return sse_private::sse2_enabled; } +#else + inline bool supports_sse2() { return false; } +#endif + +#if defined(MOZILLA_PRESUME_SSE3) + inline bool supports_sse3() { return true; } +#elif defined(MOZILLA_SSE_HAVE_CPUID_DETECTION) + inline bool supports_sse3() { return sse_private::sse3_enabled; } +#else + inline bool supports_sse3() { return false; } +#endif + +#if defined(MOZILLA_PRESUME_SSSE3) + inline bool supports_ssse3() { return true; } +#elif defined(MOZILLA_SSE_HAVE_CPUID_DETECTION) + inline bool supports_ssse3() { return sse_private::ssse3_enabled; } +#else + inline bool supports_ssse3() { return false; } +#endif + +#if defined(MOZILLA_PRESUME_SSE4A) + inline bool supports_sse4a() { return true; } +#elif defined(MOZILLA_SSE_HAVE_CPUID_DETECTION) + inline bool supports_sse4a() { return sse_private::sse4a_enabled; } +#else + inline bool supports_sse4a() { return false; } +#endif + +#if defined(MOZILLA_PRESUME_SSE4_1) + inline bool supports_sse4_1() { return true; } +#elif defined(MOZILLA_SSE_HAVE_CPUID_DETECTION) + inline bool supports_sse4_1() { return sse_private::sse4_1_enabled; } +#else + inline bool supports_sse4_1() { return false; } +#endif + +#if defined(MOZILLA_PRESUME_SSE4_2) + inline bool supports_sse4_2() { return true; } +#elif defined(MOZILLA_SSE_HAVE_CPUID_DETECTION) + inline bool supports_sse4_2() { return sse_private::sse4_2_enabled; } +#else + inline bool supports_sse4_2() { return false; } +#endif + + + +#ifdef MOZILLA_COMPILE_WITH_MMX + inline bool use_mmx() { return supports_mmx(); } +#else + inline bool use_mmx() { return false; } +#endif + +#ifdef MOZILLA_COMPILE_WITH_SSE + inline bool use_sse() { return supports_sse(); } +#else + inline bool use_sse() { return false; } +#endif + +#ifdef MOZILLA_COMPILE_WITH_SSE2 + inline bool use_sse2() { return supports_sse2(); } +#else + inline bool use_sse2() { return false; } +#endif + +#ifdef MOZILLA_COMPILE_WITH_SSE3 + inline bool use_sse3() { return supports_sse3(); } +#else + inline bool use_sse3() { return false; } +#endif + +#ifdef MOZILLA_COMPILE_WITH_SSSE3 + inline bool use_ssse3() { return supports_ssse3(); } +#else + inline bool use_ssse3() { return false; } +#endif + +#ifdef MOZILLA_COMPILE_WITH_SSE4a + inline bool use_sse4a() { return supports_sse4a(); } +#else + inline bool use_sse4a() { return false; } +#endif + +#ifdef MOZILLA_COMPILE_WITH_SSE4_1 + inline bool use_sse4_1() { return supports_sse4_1(); } +#else + inline bool use_sse4_1() { return false; } +#endif + +#ifdef MOZILLA_COMPILE_WITH_SSE4_2 + inline bool use_sse4_2() { return supports_sse4_2(); } +#else + inline bool use_sse4_2() { return false; } +#endif + +} + +#endif /* !defined(mozilla_SSE_h_) */ diff --git a/xpcom/glue/objs.mk b/xpcom/glue/objs.mk index 8e7135af7933..6010dcab8458 100644 --- a/xpcom/glue/objs.mk +++ b/xpcom/glue/objs.mk @@ -78,6 +78,7 @@ XPCOM_GLUE_SRC_CPPSRCS = $(addprefix $(topsrcdir)/xpcom/glue/, $(XPCOM_GLUE_SRC_ XPCOM_GLUENS_SRC_LCPPSRCS = \ BlockingResourceBase.cpp \ DeadlockDetector.cpp \ + SSE.cpp \ nsAutoLock.cpp \ nsGenericFactory.cpp \ nsProxyRelease.cpp \ diff --git a/xpcom/reflect/xptcall/tests/TestXPTCInvoke.cpp b/xpcom/reflect/xptcall/tests/TestXPTCInvoke.cpp index dc4725e56ca4..8ac823d24cee 100644 --- a/xpcom/reflect/xptcall/tests/TestXPTCInvoke.cpp +++ b/xpcom/reflect/xptcall/tests/TestXPTCInvoke.cpp @@ -46,10 +46,17 @@ #include "prinrval.h" #include "nsMemory.h" +// Allows us to mark unused functions as known-unused +#ifdef __GNUC__ +#define UNUSED __attribute__ ((unused)) +#else +#define UNUSED +#endif + // forward declration static void DoMultipleInheritenceTest(); static void DoMultipleInheritenceTest2(); -static void DoSpeedTest(); +static void UNUSED DoSpeedTest(); // {AAC1FB90-E099-11d2-984E-006008962422} #define INVOKETESTTARGET_IID \ @@ -317,7 +324,7 @@ InvokeTestTarget::AddMixedInts3(PRInt64 p1, PRInt64 p2, PRInt32 p3, PRInt64 p4, printf("P8 : %lld\n", p8); printf("P9 : %d\n", p9); printf("P10: %lld\n", p10); - printf("ret: %p\n", retval); + printf("ret: %p\n", static_cast(retval)); *retval = p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9 + p10; return NS_OK; } @@ -946,7 +953,7 @@ int main() var[2].ptr = &var[2].val.p; if(NS_SUCCEEDED(NS_InvokeByIndex(test, 15, 3, var))) - printf(" = %s\n", var[2].val.p); + printf(" = %s\n", static_cast(var[2].val.p)); else printf("\tFAILED"); @@ -1209,9 +1216,9 @@ static void DoMultipleInheritenceTest() if(NS_SUCCEEDED(impl->QueryInterface(NS_GET_IID(nsIFoo), (void**)&foo)) && NS_SUCCEEDED(impl->QueryInterface(NS_GET_IID(nsIBar), (void**)&bar))) { - printf("impl == %p\n", impl); - printf("foo == %p\n", foo); - printf("bar == %p\n", bar); + printf("impl == %p\n", static_cast(impl)); + printf("foo == %p\n", static_cast(foo)); + printf("bar == %p\n", static_cast(bar)); printf("Calling Foo...\n"); printf("direct calls:\n"); @@ -1379,9 +1386,9 @@ static void DoMultipleInheritenceTest2() if(NS_SUCCEEDED(impl->QueryInterface(NS_GET_IID(nsIFoo), (void**)&foo)) && NS_SUCCEEDED(impl->QueryInterface(NS_GET_IID(nsIBar), (void**)&bar))) { - printf("impl == %p\n", impl); - printf("foo == %p\n", foo); - printf("bar == %p\n", bar); + printf("impl == %p\n", static_cast(impl)); + printf("foo == %p\n", static_cast(foo)); + printf("bar == %p\n", static_cast(bar)); printf("Calling Foo...\n"); printf("direct calls:\n"); diff --git a/xpcom/tests/Makefile.in b/xpcom/tests/Makefile.in index 4e00a8b34e8f..b85bdd623c45 100644 --- a/xpcom/tests/Makefile.in +++ b/xpcom/tests/Makefile.in @@ -60,6 +60,7 @@ endif CPPSRCS = \ nsIFileEnumerator.cpp \ + ShowSSEConfig.cpp \ TestCallTemplates.cpp \ TestINIParser.cpp \ TestRacingServiceManager.cpp \ diff --git a/xpcom/tests/ShowSSEConfig.cpp b/xpcom/tests/ShowSSEConfig.cpp new file mode 100644 index 000000000000..548a2cf3e5f1 --- /dev/null +++ b/xpcom/tests/ShowSSEConfig.cpp @@ -0,0 +1,156 @@ +/* vim: set shiftwidth=2 tabstop=8 autoindent cindent expandtab: */ +/* ***** 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 ShowSSEConfig.cpp. + * + * The Initial Developer of the Original Code is the Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2009 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * L. David Baron , Mozilla Corporation (original author) + * + * 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 ***** */ + +#include "mozilla/SSE.h" +#include + +int main() +{ + printf("CPUID detection present: %s\n", +#ifdef MOZILLA_SSE_HAVE_CPUID_DETECTION + "yes" +#else + "no" +#endif + ); + +#ifdef MOZILLA_COMPILE_WITH_MMX +#define COMPILE_MMX_STRING "Y" +#else +#define COMPILE_MMX_STRING "-" +#endif +#ifdef MOZILLA_PRESUME_MMX +#define PRESUME_MMX_STRING "Y" +#else +#define PRESUME_MMX_STRING "-" +#endif + +#ifdef MOZILLA_COMPILE_WITH_SSE +#define COMPILE_SSE_STRING "Y" +#else +#define COMPILE_SSE_STRING "-" +#endif +#ifdef MOZILLA_PRESUME_SSE +#define PRESUME_SSE_STRING "Y" +#else +#define PRESUME_SSE_STRING "-" +#endif + +#ifdef MOZILLA_COMPILE_WITH_SSE2 +#define COMPILE_SSE2_STRING "Y" +#else +#define COMPILE_SSE2_STRING "-" +#endif +#ifdef MOZILLA_PRESUME_SSE2 +#define PRESUME_SSE2_STRING "Y" +#else +#define PRESUME_SSE2_STRING "-" +#endif + +#ifdef MOZILLA_COMPILE_WITH_SSE3 +#define COMPILE_SSE3_STRING "Y" +#else +#define COMPILE_SSE3_STRING "-" +#endif +#ifdef MOZILLA_PRESUME_SSE3 +#define PRESUME_SSE3_STRING "Y" +#else +#define PRESUME_SSE3_STRING "-" +#endif + +#ifdef MOZILLA_COMPILE_WITH_SSSE3 +#define COMPILE_SSSE3_STRING "Y" +#else +#define COMPILE_SSSE3_STRING "-" +#endif +#ifdef MOZILLA_PRESUME_SSSE3 +#define PRESUME_SSSE3_STRING "Y" +#else +#define PRESUME_SSSE3_STRING "-" +#endif + +#ifdef MOZILLA_COMPILE_WITH_SSE4A +#define COMPILE_SSE4A_STRING "Y" +#else +#define COMPILE_SSE4A_STRING "-" +#endif +#ifdef MOZILLA_PRESUME_SSE4A +#define PRESUME_SSE4A_STRING "Y" +#else +#define PRESUME_SSE4A_STRING "-" +#endif + +#ifdef MOZILLA_COMPILE_WITH_SSE4_1 +#define COMPILE_SSE4_1_STRING "Y" +#else +#define COMPILE_SSE4_1_STRING "-" +#endif +#ifdef MOZILLA_PRESUME_SSE4_1 +#define PRESUME_SSE4_1_STRING "Y" +#else +#define PRESUME_SSE4_1_STRING "-" +#endif + +#ifdef MOZILLA_COMPILE_WITH_SSE4_2 +#define COMPILE_SSE4_2_STRING "Y" +#else +#define COMPILE_SSE4_2_STRING "-" +#endif +#ifdef MOZILLA_PRESUME_SSE4_2 +#define PRESUME_SSE4_2_STRING "Y" +#else +#define PRESUME_SSE4_2_STRING "-" +#endif + + printf("Feature Presume Compile Support Use\n"); +#define SHOW_INFO(featurelc_, featureuc_) \ + printf( "%7s %1s %1s %1s %1s\n", \ + #featurelc_, \ + PRESUME_##featureuc_##_STRING, \ + COMPILE_##featureuc_##_STRING, \ + (mozilla::supports_##featurelc_() ? "Y" : "-"), \ + (mozilla::use_##featurelc_() ? "Y" : "-")); + SHOW_INFO(mmx, MMX) + SHOW_INFO(sse, SSE) + SHOW_INFO(sse2, SSE2) + SHOW_INFO(sse3, SSE3) + SHOW_INFO(ssse3, SSSE3) + SHOW_INFO(sse4a, SSE4A) + SHOW_INFO(sse4_1, SSE4_1) + SHOW_INFO(sse4_2, SSE4_2) + return 0; +}