Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2000 Peter Kelly (pmk@post.com) | 2 * Copyright (C) 2000 Peter Kelly (pmk@post.com) |
| 3 * Copyright (C) 2005, 2006, 2008, 2014 Apple Inc. All rights reserved. | 3 * Copyright (C) 2005, 2006, 2008, 2014 Apple Inc. All rights reserved. |
| 4 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) | 4 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) |
| 5 * Copyright (C) 2007 Samuel Weinig (sam@webkit.org) | 5 * Copyright (C) 2007 Samuel Weinig (sam@webkit.org) |
| 6 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) | 6 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) |
| 7 * Copyright (C) 2008 Holger Hans Peter Freyther | 7 * Copyright (C) 2008 Holger Hans Peter Freyther |
| 8 * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmo bile.com/) | 8 * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmo bile.com/) |
| 9 * | 9 * |
| 10 * This library is free software; you can redistribute it and/or | 10 * This library is free software; you can redistribute it and/or |
| (...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 373 | 373 |
| 374 void XMLDocumentParser::handleError(XMLErrors::ErrorType type, const char* forma ttedMessage, TextPosition position) | 374 void XMLDocumentParser::handleError(XMLErrors::ErrorType type, const char* forma ttedMessage, TextPosition position) |
| 375 { | 375 { |
| 376 m_xmlErrors.handleError(type, formattedMessage, position); | 376 m_xmlErrors.handleError(type, formattedMessage, position); |
| 377 if (type != XMLErrors::ErrorTypeWarning) | 377 if (type != XMLErrors::ErrorTypeWarning) |
| 378 m_sawError = true; | 378 m_sawError = true; |
| 379 if (type == XMLErrors::ErrorTypeFatal) | 379 if (type == XMLErrors::ErrorTypeFatal) |
| 380 stopParsing(); | 380 stopParsing(); |
| 381 } | 381 } |
| 382 | 382 |
| 383 void XMLDocumentParser::enterText() | 383 void XMLDocumentParser::createLeafTextNodeIfNeeded() |
| 384 { | 384 { |
| 385 if (m_leafTextNode) | |
| 386 return; | |
| 387 | |
| 385 ASSERT(m_bufferedText.size() == 0); | 388 ASSERT(m_bufferedText.size() == 0); |
| 386 ASSERT(!m_leafTextNode); | |
| 387 m_leafTextNode = Text::create(m_currentNode->document(), ""); | 389 m_leafTextNode = Text::create(m_currentNode->document(), ""); |
| 388 m_currentNode->parserAppendChild(m_leafTextNode.get()); | 390 m_currentNode->parserAppendChild(m_leafTextNode.get()); |
| 389 } | 391 } |
| 390 | 392 |
| 391 void XMLDocumentParser::exitText() | 393 bool XMLDocumentParser::updateLeafTextNode() |
| 392 { | 394 { |
| 393 if (isStopped()) | 395 if (isStopped()) |
| 394 return; | 396 return false; |
| 395 | 397 |
| 396 if (!m_leafTextNode) | 398 if (!m_leafTextNode) |
| 397 return; | 399 return true; |
| 398 | 400 |
| 399 m_leafTextNode->appendData(toString(m_bufferedText.data(), m_bufferedText.si ze())); | 401 m_leafTextNode->appendData(toString(m_bufferedText.data(), m_bufferedText.si ze())); |
| 400 m_bufferedText.clear(); | 402 m_bufferedText.clear(); |
| 401 m_leafTextNode = nullptr; | 403 m_leafTextNode = nullptr; |
| 404 | |
| 405 // Mutation event handlers executed by appendData() might detach this parser . | |
| 406 return !isStopped(); | |
| 402 } | 407 } |
| 403 | 408 |
| 404 void XMLDocumentParser::detach() | 409 void XMLDocumentParser::detach() |
| 405 { | 410 { |
| 406 clearCurrentNodeStack(); | 411 clearCurrentNodeStack(); |
| 407 ScriptableDocumentParser::detach(); | 412 ScriptableDocumentParser::detach(); |
| 408 } | 413 } |
| 409 | 414 |
| 410 void XMLDocumentParser::end() | 415 void XMLDocumentParser::end() |
| 411 { | 416 { |
| 412 TRACE_EVENT0("blink", "XMLDocumentParser::end"); | 417 TRACE_EVENT0("blink", "XMLDocumentParser::end"); |
| 413 // XMLDocumentParserLibxml2 will do bad things to the document if doEnd() is called. | 418 // XMLDocumentParserLibxml2 will do bad things to the document if doEnd() is called. |
| 414 // I don't believe XMLDocumentParserQt needs doEnd called in the fragment ca se. | 419 // I don't believe XMLDocumentParserQt needs doEnd called in the fragment ca se. |
| 415 ASSERT(!m_parsingFragment); | 420 ASSERT(!m_parsingFragment); |
| 416 | 421 |
| 417 doEnd(); | 422 doEnd(); |
| 418 | 423 |
| 419 // doEnd() call above can detach the parser and null out its document. | 424 // doEnd() call above can detach the parser and null out its document. |
| 420 // In that case, we just bail out. | 425 // In that case, we just bail out. |
| 421 if (isDetached()) | 426 if (isDetached()) |
| 422 return; | 427 return; |
| 423 | 428 |
| 424 // doEnd() could process a script tag, thus pausing parsing. | 429 // doEnd() could process a script tag, thus pausing parsing. |
| 425 if (m_parserPaused) | 430 if (m_parserPaused) |
| 426 return; | 431 return; |
| 427 | 432 |
| 428 if (m_sawError) { | 433 if (m_sawError) { |
| 429 insertErrorMessageBlock(); | 434 insertErrorMessageBlock(); |
| 430 } else { | 435 } else { |
| 431 exitText(); | 436 updateLeafTextNode(); |
|
haraken
2015/08/04 12:37:58
Don't we need to early-return here?
sof
2015/08/04 12:42:35
No, we could be in a Stopped state and need to bot
sof
2015/08/04 13:52:31
Added clarifying comment.
| |
| 432 document()->styleResolverChanged(); | 437 document()->styleResolverChanged(); |
| 433 } | 438 } |
| 434 | 439 |
| 435 if (isParsing()) | 440 if (isParsing()) |
| 436 prepareToStopParsing(); | 441 prepareToStopParsing(); |
| 437 document()->setReadyState(Document::Interactive); | 442 document()->setReadyState(Document::Interactive); |
| 438 clearCurrentNodeStack(); | 443 clearCurrentNodeStack(); |
| 439 document()->finishedParsing(); | 444 document()->finishedParsing(); |
| 440 } | 445 } |
| 441 | 446 |
| (...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 985 { | 990 { |
| 986 if (isStopped()) | 991 if (isStopped()) |
| 987 return; | 992 return; |
| 988 | 993 |
| 989 if (m_parserPaused) { | 994 if (m_parserPaused) { |
| 990 m_pendingCallbacks.append(adoptPtr(new PendingStartElementNSCallback(loc alName, prefix, uri, nbNamespaces, libxmlNamespaces, | 995 m_pendingCallbacks.append(adoptPtr(new PendingStartElementNSCallback(loc alName, prefix, uri, nbNamespaces, libxmlNamespaces, |
| 991 nbAttributes, nbDefaulted, libxmlAttributes))); | 996 nbAttributes, nbDefaulted, libxmlAttributes))); |
| 992 return; | 997 return; |
| 993 } | 998 } |
| 994 | 999 |
| 995 exitText(); | 1000 if (!updateLeafTextNode()) |
| 1001 return; | |
| 996 | 1002 |
| 997 AtomicString adjustedURI = uri; | 1003 AtomicString adjustedURI = uri; |
| 998 if (m_parsingFragment && adjustedURI.isNull()) { | 1004 if (m_parsingFragment && adjustedURI.isNull()) { |
| 999 if (!prefix.isNull()) | 1005 if (!prefix.isNull()) |
| 1000 adjustedURI = m_prefixToNamespaceMap.get(prefix); | 1006 adjustedURI = m_prefixToNamespaceMap.get(prefix); |
| 1001 else | 1007 else |
| 1002 adjustedURI = m_defaultNamespaceURI; | 1008 adjustedURI = m_defaultNamespaceURI; |
| 1003 } | 1009 } |
| 1004 | 1010 |
| 1005 bool isFirstElement = !m_sawFirstElement; | 1011 bool isFirstElement = !m_sawFirstElement; |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1062 | 1068 |
| 1063 if (m_parserPaused) { | 1069 if (m_parserPaused) { |
| 1064 m_pendingCallbacks.append(adoptPtr(new PendingEndElementNSCallback())); | 1070 m_pendingCallbacks.append(adoptPtr(new PendingEndElementNSCallback())); |
| 1065 return; | 1071 return; |
| 1066 } | 1072 } |
| 1067 | 1073 |
| 1068 // JavaScript can detach the parser. Make sure this is not released before | 1074 // JavaScript can detach the parser. Make sure this is not released before |
| 1069 // the end of this method. | 1075 // the end of this method. |
| 1070 RefPtrWillBeRawPtr<XMLDocumentParser> protect(this); | 1076 RefPtrWillBeRawPtr<XMLDocumentParser> protect(this); |
| 1071 | 1077 |
| 1072 exitText(); | 1078 if (!updateLeafTextNode()) |
| 1079 return; | |
| 1073 | 1080 |
| 1074 RefPtrWillBeRawPtr<ContainerNode> n = m_currentNode; | 1081 RefPtrWillBeRawPtr<ContainerNode> n = m_currentNode; |
| 1075 if (m_currentNode->isElementNode()) | 1082 if (m_currentNode->isElementNode()) |
| 1076 toElement(n.get())->finishParsingChildren(); | 1083 toElement(n.get())->finishParsingChildren(); |
| 1077 | 1084 |
| 1078 if (!scriptingContentIsAllowed(parserContentPolicy()) && n->isElementNode() && toScriptLoaderIfPossible(toElement(n))) { | 1085 if (!scriptingContentIsAllowed(parserContentPolicy()) && n->isElementNode() && toScriptLoaderIfPossible(toElement(n))) { |
| 1079 popCurrentNode(); | 1086 popCurrentNode(); |
| 1080 n->remove(IGNORE_EXCEPTION); | 1087 n->remove(IGNORE_EXCEPTION); |
| 1081 return; | 1088 return; |
| 1082 } | 1089 } |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1138 void XMLDocumentParser::characters(const xmlChar* chars, int length) | 1145 void XMLDocumentParser::characters(const xmlChar* chars, int length) |
| 1139 { | 1146 { |
| 1140 if (isStopped()) | 1147 if (isStopped()) |
| 1141 return; | 1148 return; |
| 1142 | 1149 |
| 1143 if (m_parserPaused) { | 1150 if (m_parserPaused) { |
| 1144 m_pendingCallbacks.append(adoptPtr(new PendingCharactersCallback(chars, length))); | 1151 m_pendingCallbacks.append(adoptPtr(new PendingCharactersCallback(chars, length))); |
| 1145 return; | 1152 return; |
| 1146 } | 1153 } |
| 1147 | 1154 |
| 1148 if (!m_leafTextNode) | 1155 createLeafTextNodeIfNeeded(); |
| 1149 enterText(); | |
| 1150 m_bufferedText.append(chars, length); | 1156 m_bufferedText.append(chars, length); |
| 1151 } | 1157 } |
| 1152 | 1158 |
| 1153 void XMLDocumentParser::error(XMLErrors::ErrorType type, const char* message, va _list args) | 1159 void XMLDocumentParser::error(XMLErrors::ErrorType type, const char* message, va _list args) |
| 1154 { | 1160 { |
| 1155 if (isStopped()) | 1161 if (isStopped()) |
| 1156 return; | 1162 return; |
| 1157 | 1163 |
| 1158 char formattedMessage[1024]; | 1164 char formattedMessage[1024]; |
| 1159 vsnprintf(formattedMessage, sizeof(formattedMessage) - 1, message, args); | 1165 vsnprintf(formattedMessage, sizeof(formattedMessage) - 1, message, args); |
| 1160 | 1166 |
| 1161 if (m_parserPaused) { | 1167 if (m_parserPaused) { |
| 1162 m_pendingCallbacks.append(adoptPtr(new PendingErrorCallback(type, reinte rpret_cast<const xmlChar*>(formattedMessage), lineNumber(), columnNumber()))); | 1168 m_pendingCallbacks.append(adoptPtr(new PendingErrorCallback(type, reinte rpret_cast<const xmlChar*>(formattedMessage), lineNumber(), columnNumber()))); |
| 1163 return; | 1169 return; |
| 1164 } | 1170 } |
| 1165 | 1171 |
| 1166 handleError(type, formattedMessage, textPosition()); | 1172 handleError(type, formattedMessage, textPosition()); |
| 1167 } | 1173 } |
| 1168 | 1174 |
| 1169 void XMLDocumentParser::processingInstruction(const String& target, const String & data) | 1175 void XMLDocumentParser::processingInstruction(const String& target, const String & data) |
| 1170 { | 1176 { |
| 1171 if (isStopped()) | 1177 if (isStopped()) |
| 1172 return; | 1178 return; |
| 1173 | 1179 |
| 1174 if (m_parserPaused) { | 1180 if (m_parserPaused) { |
| 1175 m_pendingCallbacks.append(adoptPtr(new PendingProcessingInstructionCallb ack(target, data))); | 1181 m_pendingCallbacks.append(adoptPtr(new PendingProcessingInstructionCallb ack(target, data))); |
| 1176 return; | 1182 return; |
| 1177 } | 1183 } |
| 1178 | 1184 |
| 1179 exitText(); | 1185 if (!updateLeafTextNode()) |
| 1186 return; | |
| 1180 | 1187 |
| 1181 // ### handle exceptions | 1188 // ### handle exceptions |
| 1182 TrackExceptionState exceptionState; | 1189 TrackExceptionState exceptionState; |
| 1183 RefPtrWillBeRawPtr<ProcessingInstruction> pi = m_currentNode->document().cre ateProcessingInstruction(target, data, exceptionState); | 1190 RefPtrWillBeRawPtr<ProcessingInstruction> pi = m_currentNode->document().cre ateProcessingInstruction(target, data, exceptionState); |
| 1184 if (exceptionState.hadException()) | 1191 if (exceptionState.hadException()) |
| 1185 return; | 1192 return; |
| 1186 | 1193 |
| 1187 pi->setCreatedByParser(true); | 1194 pi->setCreatedByParser(true); |
| 1188 | 1195 |
| 1189 m_currentNode->parserAppendChild(pi.get()); | 1196 m_currentNode->parserAppendChild(pi.get()); |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 1211 void XMLDocumentParser::cdataBlock(const String& text) | 1218 void XMLDocumentParser::cdataBlock(const String& text) |
| 1212 { | 1219 { |
| 1213 if (isStopped()) | 1220 if (isStopped()) |
| 1214 return; | 1221 return; |
| 1215 | 1222 |
| 1216 if (m_parserPaused) { | 1223 if (m_parserPaused) { |
| 1217 m_pendingCallbacks.append(adoptPtr(new PendingCDATABlockCallback(text))) ; | 1224 m_pendingCallbacks.append(adoptPtr(new PendingCDATABlockCallback(text))) ; |
| 1218 return; | 1225 return; |
| 1219 } | 1226 } |
| 1220 | 1227 |
| 1221 exitText(); | 1228 if (!updateLeafTextNode()) |
| 1229 return; | |
| 1222 | 1230 |
| 1223 m_currentNode->parserAppendChild(CDATASection::create(m_currentNode->documen t(), text)); | 1231 m_currentNode->parserAppendChild(CDATASection::create(m_currentNode->documen t(), text)); |
| 1224 } | 1232 } |
| 1225 | 1233 |
| 1226 void XMLDocumentParser::comment(const String& text) | 1234 void XMLDocumentParser::comment(const String& text) |
| 1227 { | 1235 { |
| 1228 if (isStopped()) | 1236 if (isStopped()) |
| 1229 return; | 1237 return; |
| 1230 | 1238 |
| 1231 if (m_parserPaused) { | 1239 if (m_parserPaused) { |
| 1232 m_pendingCallbacks.append(adoptPtr(new PendingCommentCallback(text))); | 1240 m_pendingCallbacks.append(adoptPtr(new PendingCommentCallback(text))); |
| 1233 return; | 1241 return; |
| 1234 } | 1242 } |
| 1235 | 1243 |
| 1236 exitText(); | 1244 if (!updateLeafTextNode()) |
| 1245 return; | |
| 1237 | 1246 |
| 1238 m_currentNode->parserAppendChild(Comment::create(m_currentNode->document(), text)); | 1247 m_currentNode->parserAppendChild(Comment::create(m_currentNode->document(), text)); |
| 1239 } | 1248 } |
| 1240 | 1249 |
| 1241 enum StandaloneInfo { | 1250 enum StandaloneInfo { |
| 1242 StandaloneUnspecified = -2, | 1251 StandaloneUnspecified = -2, |
| 1243 NoXMlDeclaration, | 1252 NoXMlDeclaration, |
| 1244 StandaloneNo, | 1253 StandaloneNo, |
| 1245 StandaloneYes | 1254 StandaloneYes |
| 1246 }; | 1255 }; |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 1257 document()->setXMLVersion(version, ASSERT_NO_EXCEPTION); | 1266 document()->setXMLVersion(version, ASSERT_NO_EXCEPTION); |
| 1258 if (standalone != StandaloneUnspecified) | 1267 if (standalone != StandaloneUnspecified) |
| 1259 document()->setXMLStandalone(standaloneInfo == StandaloneYes, ASSERT_NO_ EXCEPTION); | 1268 document()->setXMLStandalone(standaloneInfo == StandaloneYes, ASSERT_NO_ EXCEPTION); |
| 1260 if (!encoding.isNull()) | 1269 if (!encoding.isNull()) |
| 1261 document()->setXMLEncoding(encoding); | 1270 document()->setXMLEncoding(encoding); |
| 1262 document()->setHasXMLDeclaration(true); | 1271 document()->setHasXMLDeclaration(true); |
| 1263 } | 1272 } |
| 1264 | 1273 |
| 1265 void XMLDocumentParser::endDocument() | 1274 void XMLDocumentParser::endDocument() |
| 1266 { | 1275 { |
| 1267 exitText(); | 1276 updateLeafTextNode(); |
| 1268 } | 1277 } |
| 1269 | 1278 |
| 1270 void XMLDocumentParser::internalSubset(const String& name, const String& externa lID, const String& systemID) | 1279 void XMLDocumentParser::internalSubset(const String& name, const String& externa lID, const String& systemID) |
| 1271 { | 1280 { |
| 1272 if (isStopped()) | 1281 if (isStopped()) |
| 1273 return; | 1282 return; |
| 1274 | 1283 |
| 1275 if (m_parserPaused) { | 1284 if (m_parserPaused) { |
| 1276 m_pendingCallbacks.append(adoptPtr(new PendingInternalSubsetCallback(nam e, externalID, systemID))); | 1285 m_pendingCallbacks.append(adoptPtr(new PendingInternalSubsetCallback(nam e, externalID, systemID))); |
| 1277 return; | 1286 return; |
| (...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1671 sax.initialized = XML_SAX2_MAGIC; | 1680 sax.initialized = XML_SAX2_MAGIC; |
| 1672 RefPtr<XMLParserContext> parser = XMLParserContext::createStringParser(&sax, &state); | 1681 RefPtr<XMLParserContext> parser = XMLParserContext::createStringParser(&sax, &state); |
| 1673 String parseString = "<?xml version=\"1.0\"?><attrs " + string + " />"; | 1682 String parseString = "<?xml version=\"1.0\"?><attrs " + string + " />"; |
| 1674 parseChunk(parser->context(), parseString); | 1683 parseChunk(parser->context(), parseString); |
| 1675 finishParsing(parser->context()); | 1684 finishParsing(parser->context()); |
| 1676 attrsOK = state.gotAttributes; | 1685 attrsOK = state.gotAttributes; |
| 1677 return state.attributes; | 1686 return state.attributes; |
| 1678 } | 1687 } |
| 1679 | 1688 |
| 1680 } // namespace blink | 1689 } // namespace blink |
| OLD | NEW |