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:
sicking%bigfoot.com 2005-11-02 07:41:05 +00:00
Родитель 25cf119767
Коммит b5688d68bb
3 изменённых файлов: 97 добавлений и 76 удалений

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

@ -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
nsAutoString nodeName;
mCurrentNode->GetNodeName(nodeName);
NS_ASSERTION(nodeName.Equals(aName, nsCaseInsensitiveStringComparator()),
"Unbalanced startElement and endElement calls!");
if (mTableState != ADDED_TBODY) {
nsAutoString nodeName;
mCurrentNode->GetNodeName(nodeName);
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;
}
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");
}
}
return;
}
// 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;