зеркало из https://github.com/mozilla/pjs.git
Bug 207377: Change the way tbody-elements are inserted into tables to increase speed and make sure that only tablerows are inserted.
r=Pike sr=peterv
This commit is contained in:
Родитель
25cf119767
Коммит
b5688d68bb
|
@ -84,9 +84,11 @@ TX_ATOM(src, "src");
|
|||
TX_ATOM(style, "style");
|
||||
TX_ATOM(table, "table");
|
||||
TX_ATOM(target, "target");
|
||||
TX_ATOM(tbody, "tbody");
|
||||
TX_ATOM(td, "td");
|
||||
TX_ATOM(textarea, "textarea");
|
||||
TX_ATOM(th, "th");
|
||||
TX_ATOM(title, "title");
|
||||
TX_ATOM(tr, "tr");
|
||||
TX_ATOM(type, "type");
|
||||
TX_ATOM(ul, "ul");
|
||||
|
|
|
@ -93,7 +93,8 @@ txMozillaXMLOutput::txMozillaXMLOutput(const nsAString& aRootName,
|
|||
mDontAddCurrent(PR_FALSE),
|
||||
mHaveTitleElement(PR_FALSE),
|
||||
mHaveBaseElement(PR_FALSE),
|
||||
mCreatingNewDocument(PR_TRUE)
|
||||
mCreatingNewDocument(PR_TRUE),
|
||||
mTableState(NORMAL)
|
||||
{
|
||||
if (aObserver) {
|
||||
mNotifier = new txTransformNotifier();
|
||||
|
@ -114,7 +115,8 @@ txMozillaXMLOutput::txMozillaXMLOutput(txOutputFormat* aFormat,
|
|||
mDontAddCurrent(PR_FALSE),
|
||||
mHaveTitleElement(PR_FALSE),
|
||||
mHaveBaseElement(PR_FALSE),
|
||||
mCreatingNewDocument(PR_FALSE)
|
||||
mCreatingNewDocument(PR_FALSE),
|
||||
mTableState(NORMAL)
|
||||
{
|
||||
mOutputFormat.merge(*aFormat);
|
||||
mOutputFormat.setFromDefaults();
|
||||
|
@ -237,10 +239,22 @@ void txMozillaXMLOutput::endElement(const nsAString& aName, const PRInt32 aNsID)
|
|||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
if (mTableState != ADDED_TBODY) {
|
||||
nsAutoString nodeName;
|
||||
mCurrentNode->GetNodeName(nodeName);
|
||||
NS_ASSERTION(nodeName.Equals(aName, nsCaseInsensitiveStringComparator()),
|
||||
NS_ASSERTION(nodeName.Equals(aName,
|
||||
nsCaseInsensitiveStringComparator()),
|
||||
"Unbalanced startElement and endElement calls!");
|
||||
}
|
||||
else {
|
||||
nsCOMPtr<nsIDOMNode> parent;
|
||||
mCurrentNode->GetParentNode(getter_AddRefs(parent));
|
||||
nsAutoString nodeName;
|
||||
parent->GetNodeName(nodeName);
|
||||
NS_ASSERTION(nodeName.Equals(aName,
|
||||
nsCaseInsensitiveStringComparator()),
|
||||
"Unbalanced startElement and endElement calls!");
|
||||
}
|
||||
#endif
|
||||
|
||||
closePrevious(eCloseElement | eFlushText);
|
||||
|
@ -250,7 +264,7 @@ void txMozillaXMLOutput::endElement(const nsAString& aName, const PRInt32 aNsID)
|
|||
aNsID == kNameSpaceID_XHTML) {
|
||||
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(mCurrentNode);
|
||||
NS_ASSERTION(element, "endElement'ing non-element");
|
||||
endHTMLElement(element, aNsID == kNameSpaceID_XHTML);
|
||||
endHTMLElement(element);
|
||||
}
|
||||
|
||||
// Add the element to the tree if it wasn't added before and take one step
|
||||
|
@ -279,6 +293,9 @@ void txMozillaXMLOutput::endElement(const nsAString& aName, const PRInt32 aNsID)
|
|||
mCurrentNode->GetParentNode(getter_AddRefs(parent));
|
||||
mCurrentNode = parent;
|
||||
}
|
||||
|
||||
mTableState =
|
||||
NS_STATIC_CAST(TableState, NS_PTR_TO_INT32(mTableStateStack.pop()));
|
||||
}
|
||||
|
||||
void txMozillaXMLOutput::getOutputDocument(nsIDOMDocument** aDocument)
|
||||
|
@ -360,7 +377,11 @@ void txMozillaXMLOutput::startElement(const nsAString& aName,
|
|||
return;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
nsresult rv = mTableStateStack.push(NS_INT32_TO_PTR(mTableState));
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
}
|
||||
mTableState = NORMAL;
|
||||
|
||||
nsCOMPtr<nsIDOMElement> element;
|
||||
mDontAddCurrent = PR_FALSE;
|
||||
|
@ -381,7 +402,7 @@ void txMozillaXMLOutput::startElement(const nsAString& aName,
|
|||
return;
|
||||
}
|
||||
|
||||
startHTMLElement(element);
|
||||
startHTMLElement(element, PR_FALSE);
|
||||
}
|
||||
else {
|
||||
nsAutoString nsURI;
|
||||
|
@ -394,7 +415,7 @@ void txMozillaXMLOutput::startElement(const nsAString& aName,
|
|||
}
|
||||
|
||||
if (aNsID == kNameSpaceID_XHTML)
|
||||
startHTMLElement(element);
|
||||
startHTMLElement(element, PR_TRUE);
|
||||
}
|
||||
|
||||
if (mCreatingNewDocument) {
|
||||
|
@ -491,15 +512,54 @@ void txMozillaXMLOutput::closePrevious(PRInt8 aAction)
|
|||
}
|
||||
}
|
||||
|
||||
void txMozillaXMLOutput::startHTMLElement(nsIDOMElement* aElement)
|
||||
void txMozillaXMLOutput::startHTMLElement(nsIDOMElement* aElement, PRBool aXHTML)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
nsCOMPtr<nsIAtom> atom;
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
|
||||
content->GetTag(getter_AddRefs(atom));
|
||||
|
||||
mDontAddCurrent = (atom == txHTMLAtoms::script);
|
||||
|
||||
if (atom == txHTMLAtoms::head) {
|
||||
if ((atom != txHTMLAtoms::tr || aXHTML) &&
|
||||
NS_PTR_TO_INT32(mTableStateStack.peek()) == ADDED_TBODY) {
|
||||
nsCOMPtr<nsIDOMNode> parent;
|
||||
mCurrentNode->GetParentNode(getter_AddRefs(parent));
|
||||
mCurrentNode.swap(parent);
|
||||
mTableStateStack.pop();
|
||||
}
|
||||
|
||||
if (atom == txHTMLAtoms::table && !aXHTML) {
|
||||
mTableState = TABLE;
|
||||
}
|
||||
else if (atom == txHTMLAtoms::tr && !aXHTML &&
|
||||
NS_PTR_TO_INT32(mTableStateStack.peek()) == TABLE) {
|
||||
nsCOMPtr<nsIDOMElement> elem;
|
||||
if (mDocumentIsHTML) {
|
||||
rv = mDocument->CreateElement(NS_LITERAL_STRING("tbody"),
|
||||
getter_AddRefs(elem));
|
||||
}
|
||||
else {
|
||||
rv = mDocument->CreateElementNS(NS_LITERAL_STRING(kXHTMLNameSpaceURI),
|
||||
NS_LITERAL_STRING("tbody"),
|
||||
getter_AddRefs(elem));
|
||||
}
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
}
|
||||
nsCOMPtr<nsIDOMNode> dummy;
|
||||
rv = mCurrentNode->AppendChild(elem, getter_AddRefs(dummy));
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
}
|
||||
nsresult rv = mTableStateStack.push(NS_INT32_TO_PTR(ADDED_TBODY));
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
}
|
||||
mCurrentNode = elem;
|
||||
}
|
||||
else if (atom == txHTMLAtoms::head &&
|
||||
mOutputFormat.mMethod == eHTMLOutput) {
|
||||
// Insert META tag, according to spec, 16.2, like
|
||||
// <META http-equiv="Content-Type" content="text/html; charset=EUC-JP">
|
||||
nsresult rv;
|
||||
|
@ -531,8 +591,7 @@ void txMozillaXMLOutput::startHTMLElement(nsIDOMElement* aElement)
|
|||
}
|
||||
}
|
||||
|
||||
void txMozillaXMLOutput::endHTMLElement(nsIDOMElement* aElement,
|
||||
PRBool aXHTML)
|
||||
void txMozillaXMLOutput::endHTMLElement(nsIDOMElement* aElement)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
|
||||
|
@ -541,47 +600,20 @@ void txMozillaXMLOutput::endHTMLElement(nsIDOMElement* aElement,
|
|||
nsCOMPtr<nsIAtom> atom;
|
||||
content->GetTag(getter_AddRefs(atom));
|
||||
|
||||
// add <tbody> to tables if there is none (not in xhtml)
|
||||
if (atom == txHTMLAtoms::table && !aXHTML) {
|
||||
// Check if we have any table section.
|
||||
nsCOMPtr<nsIDOMHTMLTableSectionElement> section;
|
||||
nsCOMPtr<nsIContent> childContent;
|
||||
PRInt32 count, i = 0;
|
||||
if (mTableState == ADDED_TBODY) {
|
||||
NS_ASSERTION(atom == txHTMLAtoms::tbody,
|
||||
"Element flagged as added tbody isn't a tbody");
|
||||
nsCOMPtr<nsIDOMNode> parent;
|
||||
mCurrentNode->GetParentNode(getter_AddRefs(parent));
|
||||
mCurrentNode = parent;
|
||||
mTableState = NS_STATIC_CAST(TableState,
|
||||
NS_PTR_TO_INT32(mTableStateStack.pop()));
|
||||
|
||||
content->ChildCount(count);
|
||||
while (!section && (i < count)) {
|
||||
rv = content->ChildAt(i, getter_AddRefs(childContent));
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "Something went wrong while getting a child");
|
||||
section = do_QueryInterface(childContent);
|
||||
++i;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!section && (count > 0)) {
|
||||
// If no section, wrap table's children in a tbody.
|
||||
nsCOMPtr<nsIDOMElement> wrapper;
|
||||
|
||||
if (mDocumentIsHTML) {
|
||||
rv = mDocument->CreateElement(NS_LITERAL_STRING("tbody"),
|
||||
getter_AddRefs(wrapper));
|
||||
}
|
||||
else {
|
||||
rv = mDocument->CreateElementNS(NS_LITERAL_STRING(kXHTMLNameSpaceURI),
|
||||
NS_LITERAL_STRING("tbody"),
|
||||
getter_AddRefs(wrapper));
|
||||
}
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "Can't create tbody element");
|
||||
|
||||
if (wrapper) {
|
||||
nsCOMPtr<nsIDOMNode> resultNode;
|
||||
|
||||
wrapChildren(mCurrentNode, wrapper);
|
||||
rv = mCurrentNode->AppendChild(wrapper, getter_AddRefs(resultNode));
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "Can't append tbody element");
|
||||
}
|
||||
}
|
||||
}
|
||||
// Load scripts
|
||||
else if (mNotifier && atom == txHTMLAtoms::script) {
|
||||
if (mNotifier && atom == txHTMLAtoms::script) {
|
||||
// Add this script element to the array of loading script elements.
|
||||
nsCOMPtr<nsIDOMHTMLScriptElement> scriptElement =
|
||||
do_QueryInterface(mCurrentNode);
|
||||
|
@ -664,27 +696,6 @@ void txMozillaXMLOutput::processHTTPEquiv(nsIAtom* aHeader, const nsAString& aVa
|
|||
CopyUCS2toASCII(aValue, mRefreshString);
|
||||
}
|
||||
|
||||
void txMozillaXMLOutput::wrapChildren(nsIDOMNode* aCurrentNode,
|
||||
nsIDOMElement* aWrapper)
|
||||
{
|
||||
nsCOMPtr<nsIDOMNodeList> children;
|
||||
nsresult rv = aCurrentNode->GetChildNodes(getter_AddRefs(children));
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_ASSERTION(0, "Can't get children!");
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMNode> child, resultNode;
|
||||
PRUint32 count, i;
|
||||
children->GetLength(&count);
|
||||
for (i = 0; i < count; ++i) {
|
||||
rv = children->Item(0, getter_AddRefs(child));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
aWrapper->AppendChild(child, getter_AddRefs(resultNode));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
txMozillaXMLOutput::createResultDocument(const nsAString& aName, PRInt32 aNsID,
|
||||
nsIDOMDocument* aSourceDocument,
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#include "txOutputFormat.h"
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsICSSLoaderObserver.h"
|
||||
#include "txStack.h"
|
||||
|
||||
class nsIContent;
|
||||
class nsIDOMDocument;
|
||||
|
@ -102,10 +103,9 @@ public:
|
|||
|
||||
private:
|
||||
void closePrevious(PRInt8 aAction);
|
||||
void startHTMLElement(nsIDOMElement* aElement);
|
||||
void endHTMLElement(nsIDOMElement* aElement, PRBool aXHTML);
|
||||
void startHTMLElement(nsIDOMElement* aElement, PRBool aXHTML);
|
||||
void endHTMLElement(nsIDOMElement* aElement);
|
||||
void processHTTPEquiv(nsIAtom* aHeader, const nsAString& aValue);
|
||||
void wrapChildren(nsIDOMNode* aCurrentNode, nsIDOMElement* aWrapper);
|
||||
nsresult createResultDocument(const nsAString& aName, PRInt32 aNsID,
|
||||
nsIDOMDocument* aSourceDocument,
|
||||
nsIDOMDocument* aResultDocument);
|
||||
|
@ -123,6 +123,14 @@ private:
|
|||
PRUint32 mBadChildLevel;
|
||||
nsCString mRefreshString;
|
||||
|
||||
txStack mTableStateStack;
|
||||
enum TableState {
|
||||
NORMAL, // An element needing no special treatment
|
||||
TABLE, // A HTML table element
|
||||
ADDED_TBODY // An inserted tbody not coming from the stylesheet
|
||||
};
|
||||
TableState mTableState;
|
||||
|
||||
nsAutoString mText;
|
||||
|
||||
txOutputFormat mOutputFormat;
|
||||
|
|
Загрузка…
Ссылка в новой задаче