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 |