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(); |
| 437 // Do not bail out if in a stopped state, but notify document that |
| 438 // parsing has finished. |
432 document()->styleResolverChanged(); | 439 document()->styleResolverChanged(); |
433 } | 440 } |
434 | 441 |
435 if (isParsing()) | 442 if (isParsing()) |
436 prepareToStopParsing(); | 443 prepareToStopParsing(); |
437 document()->setReadyState(Document::Interactive); | 444 document()->setReadyState(Document::Interactive); |
438 clearCurrentNodeStack(); | 445 clearCurrentNodeStack(); |
439 document()->finishedParsing(); | 446 document()->finishedParsing(); |
440 } | 447 } |
441 | 448 |
(...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
985 { | 992 { |
986 if (isStopped()) | 993 if (isStopped()) |
987 return; | 994 return; |
988 | 995 |
989 if (m_parserPaused) { | 996 if (m_parserPaused) { |
990 m_pendingCallbacks.append(adoptPtr(new PendingStartElementNSCallback(loc
alName, prefix, uri, nbNamespaces, libxmlNamespaces, | 997 m_pendingCallbacks.append(adoptPtr(new PendingStartElementNSCallback(loc
alName, prefix, uri, nbNamespaces, libxmlNamespaces, |
991 nbAttributes, nbDefaulted, libxmlAttributes))); | 998 nbAttributes, nbDefaulted, libxmlAttributes))); |
992 return; | 999 return; |
993 } | 1000 } |
994 | 1001 |
995 exitText(); | 1002 if (!updateLeafTextNode()) |
| 1003 return; |
996 | 1004 |
997 AtomicString adjustedURI = uri; | 1005 AtomicString adjustedURI = uri; |
998 if (m_parsingFragment && adjustedURI.isNull()) { | 1006 if (m_parsingFragment && adjustedURI.isNull()) { |
999 if (!prefix.isNull()) | 1007 if (!prefix.isNull()) |
1000 adjustedURI = m_prefixToNamespaceMap.get(prefix); | 1008 adjustedURI = m_prefixToNamespaceMap.get(prefix); |
1001 else | 1009 else |
1002 adjustedURI = m_defaultNamespaceURI; | 1010 adjustedURI = m_defaultNamespaceURI; |
1003 } | 1011 } |
1004 | 1012 |
1005 bool isFirstElement = !m_sawFirstElement; | 1013 bool isFirstElement = !m_sawFirstElement; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1062 | 1070 |
1063 if (m_parserPaused) { | 1071 if (m_parserPaused) { |
1064 m_pendingCallbacks.append(adoptPtr(new PendingEndElementNSCallback())); | 1072 m_pendingCallbacks.append(adoptPtr(new PendingEndElementNSCallback())); |
1065 return; | 1073 return; |
1066 } | 1074 } |
1067 | 1075 |
1068 // JavaScript can detach the parser. Make sure this is not released before | 1076 // JavaScript can detach the parser. Make sure this is not released before |
1069 // the end of this method. | 1077 // the end of this method. |
1070 RefPtrWillBeRawPtr<XMLDocumentParser> protect(this); | 1078 RefPtrWillBeRawPtr<XMLDocumentParser> protect(this); |
1071 | 1079 |
1072 exitText(); | 1080 if (!updateLeafTextNode()) |
| 1081 return; |
1073 | 1082 |
1074 RefPtrWillBeRawPtr<ContainerNode> n = m_currentNode; | 1083 RefPtrWillBeRawPtr<ContainerNode> n = m_currentNode; |
1075 if (m_currentNode->isElementNode()) | 1084 if (m_currentNode->isElementNode()) |
1076 toElement(n.get())->finishParsingChildren(); | 1085 toElement(n.get())->finishParsingChildren(); |
1077 | 1086 |
1078 if (!scriptingContentIsAllowed(parserContentPolicy()) && n->isElementNode()
&& toScriptLoaderIfPossible(toElement(n))) { | 1087 if (!scriptingContentIsAllowed(parserContentPolicy()) && n->isElementNode()
&& toScriptLoaderIfPossible(toElement(n))) { |
1079 popCurrentNode(); | 1088 popCurrentNode(); |
1080 n->remove(IGNORE_EXCEPTION); | 1089 n->remove(IGNORE_EXCEPTION); |
1081 return; | 1090 return; |
1082 } | 1091 } |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1138 void XMLDocumentParser::characters(const xmlChar* chars, int length) | 1147 void XMLDocumentParser::characters(const xmlChar* chars, int length) |
1139 { | 1148 { |
1140 if (isStopped()) | 1149 if (isStopped()) |
1141 return; | 1150 return; |
1142 | 1151 |
1143 if (m_parserPaused) { | 1152 if (m_parserPaused) { |
1144 m_pendingCallbacks.append(adoptPtr(new PendingCharactersCallback(chars,
length))); | 1153 m_pendingCallbacks.append(adoptPtr(new PendingCharactersCallback(chars,
length))); |
1145 return; | 1154 return; |
1146 } | 1155 } |
1147 | 1156 |
1148 if (!m_leafTextNode) | 1157 createLeafTextNodeIfNeeded(); |
1149 enterText(); | |
1150 m_bufferedText.append(chars, length); | 1158 m_bufferedText.append(chars, length); |
1151 } | 1159 } |
1152 | 1160 |
1153 void XMLDocumentParser::error(XMLErrors::ErrorType type, const char* message, va
_list args) | 1161 void XMLDocumentParser::error(XMLErrors::ErrorType type, const char* message, va
_list args) |
1154 { | 1162 { |
1155 if (isStopped()) | 1163 if (isStopped()) |
1156 return; | 1164 return; |
1157 | 1165 |
1158 char formattedMessage[1024]; | 1166 char formattedMessage[1024]; |
1159 vsnprintf(formattedMessage, sizeof(formattedMessage) - 1, message, args); | 1167 vsnprintf(formattedMessage, sizeof(formattedMessage) - 1, message, args); |
1160 | 1168 |
1161 if (m_parserPaused) { | 1169 if (m_parserPaused) { |
1162 m_pendingCallbacks.append(adoptPtr(new PendingErrorCallback(type, reinte
rpret_cast<const xmlChar*>(formattedMessage), lineNumber(), columnNumber()))); | 1170 m_pendingCallbacks.append(adoptPtr(new PendingErrorCallback(type, reinte
rpret_cast<const xmlChar*>(formattedMessage), lineNumber(), columnNumber()))); |
1163 return; | 1171 return; |
1164 } | 1172 } |
1165 | 1173 |
1166 handleError(type, formattedMessage, textPosition()); | 1174 handleError(type, formattedMessage, textPosition()); |
1167 } | 1175 } |
1168 | 1176 |
1169 void XMLDocumentParser::processingInstruction(const String& target, const String
& data) | 1177 void XMLDocumentParser::processingInstruction(const String& target, const String
& data) |
1170 { | 1178 { |
1171 if (isStopped()) | 1179 if (isStopped()) |
1172 return; | 1180 return; |
1173 | 1181 |
1174 if (m_parserPaused) { | 1182 if (m_parserPaused) { |
1175 m_pendingCallbacks.append(adoptPtr(new PendingProcessingInstructionCallb
ack(target, data))); | 1183 m_pendingCallbacks.append(adoptPtr(new PendingProcessingInstructionCallb
ack(target, data))); |
1176 return; | 1184 return; |
1177 } | 1185 } |
1178 | 1186 |
1179 exitText(); | 1187 if (!updateLeafTextNode()) |
| 1188 return; |
1180 | 1189 |
1181 // ### handle exceptions | 1190 // ### handle exceptions |
1182 TrackExceptionState exceptionState; | 1191 TrackExceptionState exceptionState; |
1183 RefPtrWillBeRawPtr<ProcessingInstruction> pi = m_currentNode->document().cre
ateProcessingInstruction(target, data, exceptionState); | 1192 RefPtrWillBeRawPtr<ProcessingInstruction> pi = m_currentNode->document().cre
ateProcessingInstruction(target, data, exceptionState); |
1184 if (exceptionState.hadException()) | 1193 if (exceptionState.hadException()) |
1185 return; | 1194 return; |
1186 | 1195 |
1187 pi->setCreatedByParser(true); | 1196 pi->setCreatedByParser(true); |
1188 | 1197 |
1189 m_currentNode->parserAppendChild(pi.get()); | 1198 m_currentNode->parserAppendChild(pi.get()); |
(...skipping 21 matching lines...) Expand all Loading... |
1211 void XMLDocumentParser::cdataBlock(const String& text) | 1220 void XMLDocumentParser::cdataBlock(const String& text) |
1212 { | 1221 { |
1213 if (isStopped()) | 1222 if (isStopped()) |
1214 return; | 1223 return; |
1215 | 1224 |
1216 if (m_parserPaused) { | 1225 if (m_parserPaused) { |
1217 m_pendingCallbacks.append(adoptPtr(new PendingCDATABlockCallback(text)))
; | 1226 m_pendingCallbacks.append(adoptPtr(new PendingCDATABlockCallback(text)))
; |
1218 return; | 1227 return; |
1219 } | 1228 } |
1220 | 1229 |
1221 exitText(); | 1230 if (!updateLeafTextNode()) |
| 1231 return; |
1222 | 1232 |
1223 m_currentNode->parserAppendChild(CDATASection::create(m_currentNode->documen
t(), text)); | 1233 m_currentNode->parserAppendChild(CDATASection::create(m_currentNode->documen
t(), text)); |
1224 } | 1234 } |
1225 | 1235 |
1226 void XMLDocumentParser::comment(const String& text) | 1236 void XMLDocumentParser::comment(const String& text) |
1227 { | 1237 { |
1228 if (isStopped()) | 1238 if (isStopped()) |
1229 return; | 1239 return; |
1230 | 1240 |
1231 if (m_parserPaused) { | 1241 if (m_parserPaused) { |
1232 m_pendingCallbacks.append(adoptPtr(new PendingCommentCallback(text))); | 1242 m_pendingCallbacks.append(adoptPtr(new PendingCommentCallback(text))); |
1233 return; | 1243 return; |
1234 } | 1244 } |
1235 | 1245 |
1236 exitText(); | 1246 if (!updateLeafTextNode()) |
| 1247 return; |
1237 | 1248 |
1238 m_currentNode->parserAppendChild(Comment::create(m_currentNode->document(),
text)); | 1249 m_currentNode->parserAppendChild(Comment::create(m_currentNode->document(),
text)); |
1239 } | 1250 } |
1240 | 1251 |
1241 enum StandaloneInfo { | 1252 enum StandaloneInfo { |
1242 StandaloneUnspecified = -2, | 1253 StandaloneUnspecified = -2, |
1243 NoXMlDeclaration, | 1254 NoXMlDeclaration, |
1244 StandaloneNo, | 1255 StandaloneNo, |
1245 StandaloneYes | 1256 StandaloneYes |
1246 }; | 1257 }; |
(...skipping 10 matching lines...) Expand all Loading... |
1257 document()->setXMLVersion(version, ASSERT_NO_EXCEPTION); | 1268 document()->setXMLVersion(version, ASSERT_NO_EXCEPTION); |
1258 if (standalone != StandaloneUnspecified) | 1269 if (standalone != StandaloneUnspecified) |
1259 document()->setXMLStandalone(standaloneInfo == StandaloneYes, ASSERT_NO_
EXCEPTION); | 1270 document()->setXMLStandalone(standaloneInfo == StandaloneYes, ASSERT_NO_
EXCEPTION); |
1260 if (!encoding.isNull()) | 1271 if (!encoding.isNull()) |
1261 document()->setXMLEncoding(encoding); | 1272 document()->setXMLEncoding(encoding); |
1262 document()->setHasXMLDeclaration(true); | 1273 document()->setHasXMLDeclaration(true); |
1263 } | 1274 } |
1264 | 1275 |
1265 void XMLDocumentParser::endDocument() | 1276 void XMLDocumentParser::endDocument() |
1266 { | 1277 { |
1267 exitText(); | 1278 updateLeafTextNode(); |
1268 } | 1279 } |
1269 | 1280 |
1270 void XMLDocumentParser::internalSubset(const String& name, const String& externa
lID, const String& systemID) | 1281 void XMLDocumentParser::internalSubset(const String& name, const String& externa
lID, const String& systemID) |
1271 { | 1282 { |
1272 if (isStopped()) | 1283 if (isStopped()) |
1273 return; | 1284 return; |
1274 | 1285 |
1275 if (m_parserPaused) { | 1286 if (m_parserPaused) { |
1276 m_pendingCallbacks.append(adoptPtr(new PendingInternalSubsetCallback(nam
e, externalID, systemID))); | 1287 m_pendingCallbacks.append(adoptPtr(new PendingInternalSubsetCallback(nam
e, externalID, systemID))); |
1277 return; | 1288 return; |
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1671 sax.initialized = XML_SAX2_MAGIC; | 1682 sax.initialized = XML_SAX2_MAGIC; |
1672 RefPtr<XMLParserContext> parser = XMLParserContext::createStringParser(&sax,
&state); | 1683 RefPtr<XMLParserContext> parser = XMLParserContext::createStringParser(&sax,
&state); |
1673 String parseString = "<?xml version=\"1.0\"?><attrs " + string + " />"; | 1684 String parseString = "<?xml version=\"1.0\"?><attrs " + string + " />"; |
1674 parseChunk(parser->context(), parseString); | 1685 parseChunk(parser->context(), parseString); |
1675 finishParsing(parser->context()); | 1686 finishParsing(parser->context()); |
1676 attrsOK = state.gotAttributes; | 1687 attrsOK = state.gotAttributes; |
1677 return state.attributes; | 1688 return state.attributes; |
1678 } | 1689 } |
1679 | 1690 |
1680 } // namespace blink | 1691 } // namespace blink |
OLD | NEW |