OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
4 * (C) 2001 Dirk Mueller (mueller@kde.org) | 4 * (C) 2001 Dirk Mueller (mueller@kde.org) |
5 * (C) 2006 Alexey Proskuryakov (ap@webkit.org) | 5 * (C) 2006 Alexey Proskuryakov (ap@webkit.org) |
6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012 Apple Inc. All r
ights reserved. | 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012 Apple Inc. All |
7 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t
orchmobile.com/) | 7 * rights reserved. |
| 8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. |
| 9 * (http://www.torchmobile.com/) |
8 * Copyright (C) 2008, 2009, 2011, 2012 Google Inc. All rights reserved. | 10 * Copyright (C) 2008, 2009, 2011, 2012 Google Inc. All rights reserved. |
9 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) | 11 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) |
10 * Copyright (C) Research In Motion Limited 2010-2011. All rights reserved. | 12 * Copyright (C) Research In Motion Limited 2010-2011. All rights reserved. |
11 * | 13 * |
12 * This library is free software; you can redistribute it and/or | 14 * This library is free software; you can redistribute it and/or |
13 * modify it under the terms of the GNU Library General Public | 15 * modify it under the terms of the GNU Library General Public |
14 * License as published by the Free Software Foundation; either | 16 * License as published by the Free Software Foundation; either |
15 * version 2 of the License, or (at your option) any later version. | 17 * version 2 of the License, or (at your option) any later version. |
16 * | 18 * |
17 * This library is distributed in the hope that it will be useful, | 19 * This library is distributed in the hope that it will be useful, |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
259 blink::PersistentHeapHashSet<blink::WeakMember<blink::Document>>; | 261 blink::PersistentHeapHashSet<blink::WeakMember<blink::Document>>; |
260 static WeakDocumentSet& liveDocumentSet(); | 262 static WeakDocumentSet& liveDocumentSet(); |
261 #endif | 263 #endif |
262 | 264 |
263 namespace blink { | 265 namespace blink { |
264 | 266 |
265 using namespace HTMLNames; | 267 using namespace HTMLNames; |
266 | 268 |
267 static const unsigned cMaxWriteRecursionDepth = 21; | 269 static const unsigned cMaxWriteRecursionDepth = 21; |
268 | 270 |
269 // This amount of time must have elapsed before we will even consider scheduling
a layout without a delay. | 271 // This amount of time must have elapsed before we will even consider scheduling |
270 // FIXME: For faster machines this value can really be lowered to 200. 250 is a
dequate, but a little high | 272 // a layout without a delay. |
271 // for dual G5s. :) | 273 // FIXME: For faster machines this value can really be lowered to 200. 250 is |
| 274 // adequate, but a little high for dual G5s. :) |
272 static const int cLayoutScheduleThreshold = 250; | 275 static const int cLayoutScheduleThreshold = 250; |
273 | 276 |
274 // DOM Level 2 says (letters added): | 277 // DOM Level 2 says (letters added): |
275 // | 278 // |
276 // a) Name start characters must have one of the categories Ll, Lu, Lo, Lt, Nl. | 279 // a) Name start characters must have one of the categories Ll, Lu, Lo, Lt, Nl. |
277 // b) Name characters other than Name-start characters must have one of the cate
gories Mc, Me, Mn, Lm, or Nd. | 280 // b) Name characters other than Name-start characters must have one of the |
278 // c) Characters in the compatibility area (i.e. with character code greater tha
n #xF900 and less than #xFFFE) are not allowed in XML names. | 281 // categories Mc, Me, Mn, Lm, or Nd. |
279 // d) Characters which have a font or compatibility decomposition (i.e. those wi
th a "compatibility formatting tag" in field 5 of the database -- marked by fiel
d 5 beginning with a "<") are not allowed. | 282 // c) Characters in the compatibility area (i.e. with character code greater |
280 // e) The following characters are treated as name-start characters rather than
name characters, because the property file classifies them as Alphabetic: [#x02B
B-#x02C1], #x0559, #x06E5, #x06E6. | 283 // than #xF900 and less than #xFFFE) are not allowed in XML names. |
281 // f) Characters #x20DD-#x20E0 are excluded (in accordance with Unicode, section
5.14). | 284 // d) Characters which have a font or compatibility decomposition (i.e. those |
282 // g) Character #x00B7 is classified as an extender, because the property list s
o identifies it. | 285 // with a "compatibility formatting tag" in field 5 of the database -- marked |
283 // h) Character #x0387 is added as a name character, because #x00B7 is its canon
ical equivalent. | 286 // by field 5 beginning with a "<") are not allowed. |
| 287 // e) The following characters are treated as name-start characters rather than |
| 288 // name characters, because the property file classifies them as Alphabetic: |
| 289 // [#x02BB-#x02C1], #x0559, #x06E5, #x06E6. |
| 290 // f) Characters #x20DD-#x20E0 are excluded (in accordance with Unicode, section |
| 291 // 5.14). |
| 292 // g) Character #x00B7 is classified as an extender, because the property list |
| 293 // so identifies it. |
| 294 // h) Character #x0387 is added as a name character, because #x00B7 is its |
| 295 // canonical equivalent. |
284 // i) Characters ':' and '_' are allowed as name-start characters. | 296 // i) Characters ':' and '_' are allowed as name-start characters. |
285 // j) Characters '-' and '.' are allowed as name characters. | 297 // j) Characters '-' and '.' are allowed as name characters. |
286 // | 298 // |
287 // It also contains complete tables. If we decide it's better, we could include
those instead of the following code. | 299 // It also contains complete tables. If we decide it's better, we could include |
| 300 // those instead of the following code. |
288 | 301 |
289 static inline bool isValidNameStart(UChar32 c) { | 302 static inline bool isValidNameStart(UChar32 c) { |
290 // rule (e) above | 303 // rule (e) above |
291 if ((c >= 0x02BB && c <= 0x02C1) || c == 0x559 || c == 0x6E5 || c == 0x6E6) | 304 if ((c >= 0x02BB && c <= 0x02C1) || c == 0x559 || c == 0x6E5 || c == 0x6E6) |
292 return true; | 305 return true; |
293 | 306 |
294 // rule (i) above | 307 // rule (i) above |
295 if (c == ':' || c == '_') | 308 if (c == ':' || c == '_') |
296 return true; | 309 return true; |
297 | 310 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 if (decompType == DecompositionFont || decompType == DecompositionCompat) | 356 if (decompType == DecompositionFont || decompType == DecompositionCompat) |
344 return false; | 357 return false; |
345 | 358 |
346 return true; | 359 return true; |
347 } | 360 } |
348 | 361 |
349 static bool shouldInheritSecurityOriginFromOwner(const KURL& url) { | 362 static bool shouldInheritSecurityOriginFromOwner(const KURL& url) { |
350 // http://www.whatwg.org/specs/web-apps/current-work/#origin-0 | 363 // http://www.whatwg.org/specs/web-apps/current-work/#origin-0 |
351 // | 364 // |
352 // If a Document has the address "about:blank" | 365 // If a Document has the address "about:blank" |
353 // The origin of the Document is the origin it was assigned when its brows
ing context was created. | 366 // The origin of the Document is the origin it was assigned when its |
| 367 // browsing context was created. |
354 // | 368 // |
355 // Note: We generalize this to all "blank" URLs and invalid URLs because we | 369 // Note: We generalize this to all "blank" URLs and invalid URLs because we |
356 // treat all of these URLs as about:blank. | 370 // treat all of these URLs as about:blank. |
357 // | 371 // |
358 return url.isEmpty() || url.protocolIsAbout(); | 372 return url.isEmpty() || url.protocolIsAbout(); |
359 } | 373 } |
360 | 374 |
361 static Widget* widgetForElement(const Element& focusedElement) { | 375 static Widget* widgetForElement(const Element& focusedElement) { |
362 LayoutObject* layoutObject = focusedElement.layoutObject(); | 376 LayoutObject* layoutObject = focusedElement.layoutObject(); |
363 if (!layoutObject || !layoutObject->isLayoutPart()) | 377 if (!layoutObject || !layoutObject->isLayoutPart()) |
(...skipping 13 matching lines...) Expand all Loading... |
377 | 391 |
378 // This doesn't work with non-Document ExecutionContext. | 392 // This doesn't work with non-Document ExecutionContext. |
379 static void runAutofocusTask(ExecutionContext* context) { | 393 static void runAutofocusTask(ExecutionContext* context) { |
380 Document* document = toDocument(context); | 394 Document* document = toDocument(context); |
381 if (Element* element = document->autofocusElement()) { | 395 if (Element* element = document->autofocusElement()) { |
382 document->setAutofocusElement(0); | 396 document->setAutofocusElement(0); |
383 element->focus(); | 397 element->focus(); |
384 } | 398 } |
385 } | 399 } |
386 | 400 |
387 // These are logged to UMA, so don't re-arrange them without creating a new hist
ogram. | 401 // These are logged to UMA, so don't re-arrange them without creating a new |
| 402 // histogram. |
388 enum DocumentVisibilityForDeferredLoading { | 403 enum DocumentVisibilityForDeferredLoading { |
389 Created, | 404 Created, |
390 WouldLoadBecauseVisible, | 405 WouldLoadBecauseVisible, |
391 // TODO(dgrogan): Add WouldLoadBecauseTopOrLeft, WouldLoadBecauseDisplayNone,
etc | 406 // TODO(dgrogan): Add WouldLoadBecauseTopOrLeft, WouldLoadBecauseDisplayNone, |
| 407 // etc |
392 | 408 |
393 DocumentVisibilityForDeferredLoadingEnd | 409 DocumentVisibilityForDeferredLoadingEnd |
394 }; | 410 }; |
395 | 411 |
396 static void RecordStateToHistogram(DocumentVisibilityForDeferredLoading state) { | 412 static void RecordStateToHistogram(DocumentVisibilityForDeferredLoading state) { |
397 DEFINE_STATIC_LOCAL(EnumerationHistogram, unseenFrameHistogram, | 413 DEFINE_STATIC_LOCAL(EnumerationHistogram, unseenFrameHistogram, |
398 ("Navigation.DeferredDocumentLoading.StatesV1", | 414 ("Navigation.DeferredDocumentLoading.StatesV1", |
399 DocumentVisibilityForDeferredLoadingEnd)); | 415 DocumentVisibilityForDeferredLoadingEnd)); |
400 unseenFrameHistogram.count(state); | 416 unseenFrameHistogram.count(state); |
401 } | 417 } |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
521 | 537 |
522 InstanceCounters::incrementCounter(InstanceCounters::DocumentCounter); | 538 InstanceCounters::incrementCounter(InstanceCounters::DocumentCounter); |
523 | 539 |
524 m_lifecycle.advanceTo(DocumentLifecycle::Inactive); | 540 m_lifecycle.advanceTo(DocumentLifecycle::Inactive); |
525 | 541 |
526 // Since CSSFontSelector requires Document::m_fetcher and StyleEngine owns | 542 // Since CSSFontSelector requires Document::m_fetcher and StyleEngine owns |
527 // CSSFontSelector, need to initialize m_styleEngine after initializing | 543 // CSSFontSelector, need to initialize m_styleEngine after initializing |
528 // m_fetcher. | 544 // m_fetcher. |
529 m_styleEngine = StyleEngine::create(*this); | 545 m_styleEngine = StyleEngine::create(*this); |
530 | 546 |
531 // The parent's parser should be suspended together with all the other objects
, | 547 // The parent's parser should be suspended together with all the other |
532 // else this new Document would have a new ExecutionContext which suspended st
ate | 548 // objects, else this new Document would have a new ExecutionContext which |
533 // would not match the one from the parent, and could start loading resources | 549 // suspended state would not match the one from the parent, and could start |
534 // ignoring the defersLoading flag. | 550 // loading resources ignoring the defersLoading flag. |
535 DCHECK(!parentDocument() || | 551 DCHECK(!parentDocument() || |
536 !parentDocument()->activeDOMObjectsAreSuspended()); | 552 !parentDocument()->activeDOMObjectsAreSuspended()); |
537 | 553 |
538 #ifndef NDEBUG | 554 #ifndef NDEBUG |
539 liveDocumentSet().add(this); | 555 liveDocumentSet().add(this); |
540 #endif | 556 #endif |
541 } | 557 } |
542 | 558 |
543 Document::~Document() { | 559 Document::~Document() { |
544 DCHECK(layoutViewItem().isNull()); | 560 DCHECK(layoutViewItem().isNull()); |
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
929 } | 945 } |
930 case kAttributeNode: | 946 case kAttributeNode: |
931 return Attr::create( | 947 return Attr::create( |
932 *this, | 948 *this, |
933 QualifiedName(nullAtom, AtomicString(toAttr(importedNode)->name()), | 949 QualifiedName(nullAtom, AtomicString(toAttr(importedNode)->name()), |
934 nullAtom), | 950 nullAtom), |
935 toAttr(importedNode)->value()); | 951 toAttr(importedNode)->value()); |
936 case kDocumentFragmentNode: { | 952 case kDocumentFragmentNode: { |
937 if (importedNode->isShadowRoot()) { | 953 if (importedNode->isShadowRoot()) { |
938 // ShadowRoot nodes should not be explicitly importable. | 954 // ShadowRoot nodes should not be explicitly importable. |
939 // Either they are imported along with their host node, or created impli
citly. | 955 // Either they are imported along with their host node, or created |
| 956 // implicitly. |
940 exceptionState.throwDOMException( | 957 exceptionState.throwDOMException( |
941 NotSupportedError, | 958 NotSupportedError, |
942 "The node provided is a shadow root, which may not be imported."); | 959 "The node provided is a shadow root, which may not be imported."); |
943 return nullptr; | 960 return nullptr; |
944 } | 961 } |
945 DocumentFragment* oldFragment = toDocumentFragment(importedNode); | 962 DocumentFragment* oldFragment = toDocumentFragment(importedNode); |
946 DocumentFragment* newFragment = createDocumentFragment(); | 963 DocumentFragment* newFragment = createDocumentFragment(); |
947 if (deep && | 964 if (deep && |
948 !importContainerNodeChildren(oldFragment, newFragment, | 965 !importContainerNodeChildren(oldFragment, newFragment, |
949 exceptionState)) | 966 exceptionState)) |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1007 } | 1024 } |
1008 | 1025 |
1009 this->adoptIfNeeded(*source); | 1026 this->adoptIfNeeded(*source); |
1010 | 1027 |
1011 return source; | 1028 return source; |
1012 } | 1029 } |
1013 | 1030 |
1014 bool Document::hasValidNamespaceForElements(const QualifiedName& qName) { | 1031 bool Document::hasValidNamespaceForElements(const QualifiedName& qName) { |
1015 // These checks are from DOM Core Level 2, createElementNS | 1032 // These checks are from DOM Core Level 2, createElementNS |
1016 // http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-DocCrElNS | 1033 // http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-DocCrElNS |
1017 if (!qName.prefix().isEmpty() && | 1034 // createElementNS(null, "html:div") |
1018 qName.namespaceURI().isNull()) // createElementNS(null, "html:div") | 1035 if (!qName.prefix().isEmpty() && qName.namespaceURI().isNull()) |
1019 return false; | 1036 return false; |
| 1037 // createElementNS("http://www.example.com", "xml:lang") |
1020 if (qName.prefix() == xmlAtom && | 1038 if (qName.prefix() == xmlAtom && |
1021 qName.namespaceURI() != | 1039 qName.namespaceURI() != XMLNames::xmlNamespaceURI) |
1022 XMLNames:: | |
1023 xmlNamespaceURI) // createElementNS("http://www.example.com", "xm
l:lang") | |
1024 return false; | 1040 return false; |
1025 | 1041 |
1026 // Required by DOM Level 3 Core and unspecified by DOM Level 2 Core: | 1042 // Required by DOM Level 3 Core and unspecified by DOM Level 2 Core: |
1027 // http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#ID-DocCrE
lNS | 1043 // http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#ID-DocCrE
lNS |
1028 // createElementNS("http://www.w3.org/2000/xmlns/", "foo:bar"), createElementN
S(null, "xmlns:bar"), createElementNS(null, "xmlns") | 1044 // createElementNS("http://www.w3.org/2000/xmlns/", "foo:bar"), |
| 1045 // createElementNS(null, "xmlns:bar"), createElementNS(null, "xmlns") |
1029 if (qName.prefix() == xmlnsAtom || | 1046 if (qName.prefix() == xmlnsAtom || |
1030 (qName.prefix().isEmpty() && qName.localName() == xmlnsAtom)) | 1047 (qName.prefix().isEmpty() && qName.localName() == xmlnsAtom)) |
1031 return qName.namespaceURI() == XMLNSNames::xmlnsNamespaceURI; | 1048 return qName.namespaceURI() == XMLNSNames::xmlnsNamespaceURI; |
1032 return qName.namespaceURI() != XMLNSNames::xmlnsNamespaceURI; | 1049 return qName.namespaceURI() != XMLNSNames::xmlnsNamespaceURI; |
1033 } | 1050 } |
1034 | 1051 |
1035 bool Document::hasValidNamespaceForAttributes(const QualifiedName& qName) { | 1052 bool Document::hasValidNamespaceForAttributes(const QualifiedName& qName) { |
1036 return hasValidNamespaceForElements(qName); | 1053 return hasValidNamespaceForElements(qName); |
1037 } | 1054 } |
1038 | 1055 |
1039 // FIXME: This should really be in a possible ElementFactory class | 1056 // FIXME: This should really be in a possible ElementFactory class |
1040 Element* Document::createElement(const QualifiedName& qName, | 1057 Element* Document::createElement(const QualifiedName& qName, |
1041 CreateElementFlags flags) { | 1058 CreateElementFlags flags) { |
1042 Element* e = nullptr; | 1059 Element* e = nullptr; |
1043 | 1060 |
1044 // FIXME: Use registered namespaces and look up in a hash to find the right fa
ctory. | 1061 // FIXME: Use registered namespaces and look up in a hash to find the right |
| 1062 // factory. |
1045 if (qName.namespaceURI() == xhtmlNamespaceURI) | 1063 if (qName.namespaceURI() == xhtmlNamespaceURI) |
1046 e = HTMLElementFactory::createHTMLElement(qName.localName(), *this, 0, | 1064 e = HTMLElementFactory::createHTMLElement(qName.localName(), *this, 0, |
1047 flags); | 1065 flags); |
1048 else if (qName.namespaceURI() == SVGNames::svgNamespaceURI) | 1066 else if (qName.namespaceURI() == SVGNames::svgNamespaceURI) |
1049 e = SVGElementFactory::createSVGElement(qName.localName(), *this, flags); | 1067 e = SVGElementFactory::createSVGElement(qName.localName(), *this, flags); |
1050 | 1068 |
1051 if (e) | 1069 if (e) |
1052 m_sawElementsInKnownNamespaces = true; | 1070 m_sawElementsInKnownNamespaces = true; |
1053 else | 1071 else |
1054 e = Element::create(qName, this); | 1072 e = Element::create(qName, this); |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1307 | 1325 |
1308 if (isHTMLTitleElement(m_titleElement)) | 1326 if (isHTMLTitleElement(m_titleElement)) |
1309 toHTMLTitleElement(m_titleElement)->setText(title); | 1327 toHTMLTitleElement(m_titleElement)->setText(title); |
1310 else if (isSVGTitleElement(m_titleElement)) | 1328 else if (isSVGTitleElement(m_titleElement)) |
1311 toSVGTitleElement(m_titleElement)->setText(title); | 1329 toSVGTitleElement(m_titleElement)->setText(title); |
1312 else | 1330 else |
1313 updateTitle(title); | 1331 updateTitle(title); |
1314 } | 1332 } |
1315 | 1333 |
1316 void Document::setTitleElement(Element* titleElement) { | 1334 void Document::setTitleElement(Element* titleElement) { |
1317 // If the root element is an svg element in the SVG namespace, then let value
be the child text content | 1335 // If the root element is an svg element in the SVG namespace, then let value |
1318 // of the first title element in the SVG namespace that is a child of the root
element. | 1336 // be the child text content of the first title element in the SVG namespace |
| 1337 // that is a child of the root element. |
1319 if (isSVGSVGElement(documentElement())) { | 1338 if (isSVGSVGElement(documentElement())) { |
1320 m_titleElement = Traversal<SVGTitleElement>::firstChild(*documentElement()); | 1339 m_titleElement = Traversal<SVGTitleElement>::firstChild(*documentElement()); |
1321 } else { | 1340 } else { |
1322 if (m_titleElement && m_titleElement != titleElement) | 1341 if (m_titleElement && m_titleElement != titleElement) |
1323 m_titleElement = Traversal<HTMLTitleElement>::firstWithin(*this); | 1342 m_titleElement = Traversal<HTMLTitleElement>::firstWithin(*this); |
1324 else | 1343 else |
1325 m_titleElement = titleElement; | 1344 m_titleElement = titleElement; |
1326 | 1345 |
1327 // If the root element isn't an svg element in the SVG namespace and the tit
le element is | 1346 // If the root element isn't an svg element in the SVG namespace and the |
1328 // in the SVG namespace, it is ignored. | 1347 // title element is in the SVG namespace, it is ignored. |
1329 if (isSVGTitleElement(m_titleElement)) { | 1348 if (isSVGTitleElement(m_titleElement)) { |
1330 m_titleElement = nullptr; | 1349 m_titleElement = nullptr; |
1331 return; | 1350 return; |
1332 } | 1351 } |
1333 } | 1352 } |
1334 | 1353 |
1335 if (isHTMLTitleElement(m_titleElement)) | 1354 if (isHTMLTitleElement(m_titleElement)) |
1336 updateTitle(toHTMLTitleElement(m_titleElement)->text()); | 1355 updateTitle(toHTMLTitleElement(m_titleElement)->text()); |
1337 else if (isSVGTitleElement(m_titleElement)) | 1356 else if (isSVGTitleElement(m_titleElement)) |
1338 updateTitle(toSVGTitleElement(m_titleElement)->textContent()); | 1357 updateTitle(toSVGTitleElement(m_titleElement)->textContent()); |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1498 if (!isActive() || !view()) | 1517 if (!isActive() || !view()) |
1499 return false; | 1518 return false; |
1500 if (!m_useElementsNeedingUpdate.isEmpty()) | 1519 if (!m_useElementsNeedingUpdate.isEmpty()) |
1501 return true; | 1520 return true; |
1502 if (!m_layerUpdateSVGFilterElements.isEmpty()) | 1521 if (!m_layerUpdateSVGFilterElements.isEmpty()) |
1503 return true; | 1522 return true; |
1504 if (needsStyleRecalc()) | 1523 if (needsStyleRecalc()) |
1505 return true; | 1524 return true; |
1506 if (needsStyleInvalidation()) | 1525 if (needsStyleInvalidation()) |
1507 return true; | 1526 return true; |
1508 // FIXME: The childNeedsDistributionRecalc bit means either self or children,
we should fix that. | 1527 // FIXME: The childNeedsDistributionRecalc bit means either self or children, |
| 1528 // we should fix that. |
1509 if (childNeedsDistributionRecalc()) | 1529 if (childNeedsDistributionRecalc()) |
1510 return true; | 1530 return true; |
1511 if (DocumentAnimations::needsAnimationTimingUpdate(*this)) | 1531 if (DocumentAnimations::needsAnimationTimingUpdate(*this)) |
1512 return true; | 1532 return true; |
1513 return false; | 1533 return false; |
1514 } | 1534 } |
1515 | 1535 |
1516 bool Document::shouldScheduleLayoutTreeUpdate() const { | 1536 bool Document::shouldScheduleLayoutTreeUpdate() const { |
1517 if (!isActive()) | 1537 if (!isActive()) |
1518 return false; | 1538 return false; |
1519 if (inStyleRecalc()) | 1539 if (inStyleRecalc()) |
1520 return false; | 1540 return false; |
1521 // InPreLayout will recalc style itself. There's no reason to schedule another
recalc. | 1541 // InPreLayout will recalc style itself. There's no reason to schedule another |
| 1542 // recalc. |
1522 if (m_lifecycle.state() == DocumentLifecycle::InPreLayout) | 1543 if (m_lifecycle.state() == DocumentLifecycle::InPreLayout) |
1523 return false; | 1544 return false; |
1524 if (!shouldScheduleLayout()) | 1545 if (!shouldScheduleLayout()) |
1525 return false; | 1546 return false; |
1526 return true; | 1547 return true; |
1527 } | 1548 } |
1528 | 1549 |
1529 void Document::scheduleLayoutTreeUpdate() { | 1550 void Document::scheduleLayoutTreeUpdate() { |
1530 DCHECK(!hasPendingVisualUpdate()); | 1551 DCHECK(!hasPendingVisualUpdate()); |
1531 DCHECK(shouldScheduleLayoutTreeUpdate()); | 1552 DCHECK(shouldScheduleLayoutTreeUpdate()); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1593 body->clearAnimationStyleChange(); | 1614 body->clearAnimationStyleChange(); |
1594 if (!bodyStyle || body->needsStyleRecalc() || didRecalcDocumentElement) | 1615 if (!bodyStyle || body->needsStyleRecalc() || didRecalcDocumentElement) |
1595 bodyStyle = ensureStyleResolver().styleForElement( | 1616 bodyStyle = ensureStyleResolver().styleForElement( |
1596 body, documentElementStyle.get()); | 1617 body, documentElementStyle.get()); |
1597 rootWritingMode = bodyStyle->getWritingMode(); | 1618 rootWritingMode = bodyStyle->getWritingMode(); |
1598 rootDirection = bodyStyle->direction(); | 1619 rootDirection = bodyStyle->direction(); |
1599 } | 1620 } |
1600 | 1621 |
1601 const ComputedStyle* backgroundStyle = documentElementStyle.get(); | 1622 const ComputedStyle* backgroundStyle = documentElementStyle.get(); |
1602 // http://www.w3.org/TR/css3-background/#body-background | 1623 // http://www.w3.org/TR/css3-background/#body-background |
1603 // <html> root element with no background steals background from its first <bo
dy> child. | 1624 // <html> root element with no background steals background from its first |
| 1625 // <body> child. |
1604 // Also see LayoutBoxModelObject::backgroundStolenForBeingBody() | 1626 // Also see LayoutBoxModelObject::backgroundStolenForBeingBody() |
1605 if (isHTMLHtmlElement(documentElement()) && isHTMLBodyElement(body) && | 1627 if (isHTMLHtmlElement(documentElement()) && isHTMLBodyElement(body) && |
1606 !backgroundStyle->hasBackground()) | 1628 !backgroundStyle->hasBackground()) |
1607 backgroundStyle = bodyStyle.get(); | 1629 backgroundStyle = bodyStyle.get(); |
1608 Color backgroundColor = | 1630 Color backgroundColor = |
1609 backgroundStyle->visitedDependentColor(CSSPropertyBackgroundColor); | 1631 backgroundStyle->visitedDependentColor(CSSPropertyBackgroundColor); |
1610 FillLayer backgroundLayers = backgroundStyle->backgroundLayers(); | 1632 FillLayer backgroundLayers = backgroundStyle->backgroundLayers(); |
1611 for (auto currentLayer = &backgroundLayers; currentLayer; | 1633 for (auto currentLayer = &backgroundLayers; currentLayer; |
1612 currentLayer = currentLayer->next()) { | 1634 currentLayer = currentLayer->next()) { |
1613 // http://www.w3.org/TR/css3-background/#root-background | 1635 // http://www.w3.org/TR/css3-background/#root-background |
1614 // The root element background always have painting area of the whole canvas
. | 1636 // The root element background always have painting area of the whole |
| 1637 // canvas. |
1615 currentLayer->setClip(BorderFillBox); | 1638 currentLayer->setClip(BorderFillBox); |
1616 | 1639 |
1617 // The root element doesn't scroll. It always propagates its layout overflow | 1640 // The root element doesn't scroll. It always propagates its layout overflow |
1618 // to the viewport. Positioning background against either box is equivalent
to | 1641 // to the viewport. Positioning background against either box is equivalent |
1619 // positioning against the scrolled box of the viewport. | 1642 // to positioning against the scrolled box of the viewport. |
1620 if (currentLayer->attachment() == ScrollBackgroundAttachment) | 1643 if (currentLayer->attachment() == ScrollBackgroundAttachment) |
1621 currentLayer->setAttachment(LocalBackgroundAttachment); | 1644 currentLayer->setAttachment(LocalBackgroundAttachment); |
1622 } | 1645 } |
1623 EImageRendering imageRendering = backgroundStyle->imageRendering(); | 1646 EImageRendering imageRendering = backgroundStyle->imageRendering(); |
1624 | 1647 |
1625 const ComputedStyle* overflowStyle = nullptr; | 1648 const ComputedStyle* overflowStyle = nullptr; |
1626 if (Element* element = viewportDefiningElement(documentElementStyle.get())) { | 1649 if (Element* element = viewportDefiningElement(documentElementStyle.get())) { |
1627 if (element == body) { | 1650 if (element == body) { |
1628 overflowStyle = bodyStyle.get(); | 1651 overflowStyle = bodyStyle.get(); |
1629 } else { | 1652 } else { |
1630 DCHECK_EQ(element, documentElement()); | 1653 DCHECK_EQ(element, documentElement()); |
1631 overflowStyle = documentElementStyle.get(); | 1654 overflowStyle = documentElementStyle.get(); |
1632 | 1655 |
1633 // The body element has its own scrolling box, independent from the viewpo
rt. | 1656 // The body element has its own scrolling box, independent from the |
1634 // This is a bit of a weird edge case in the CSS spec that we might want t
o try to | 1657 // viewport. This is a bit of a weird edge case in the CSS spec that we |
1635 // eliminate some day (eg. for ScrollTopLeftInterop - see http://crbug.com
/157855). | 1658 // might want to try to eliminate some day (eg. for ScrollTopLeftInterop - |
| 1659 // see http://crbug.com/157855). |
1636 if (bodyStyle && !bodyStyle->isOverflowVisible()) | 1660 if (bodyStyle && !bodyStyle->isOverflowVisible()) |
1637 UseCounter::count(*this, UseCounter::BodyScrollsInAdditionToViewport); | 1661 UseCounter::count(*this, UseCounter::BodyScrollsInAdditionToViewport); |
1638 } | 1662 } |
1639 } | 1663 } |
1640 | 1664 |
1641 // Resolved rem units are stored in the matched properties cache so we need to
make sure to | 1665 // Resolved rem units are stored in the matched properties cache so we need to |
1642 // invalidate the cache if the documentElement needed to reattach or the font
size changed | 1666 // make sure to invalidate the cache if the documentElement needed to reattach |
1643 // and then trigger a full document recalc. We also need to clear it here sinc
e the | 1667 // or the font size changed and then trigger a full document recalc. We also |
1644 // call to styleForElement on the body above can cache bad values for rem unit
s if the | 1668 // need to clear it here since the call to styleForElement on the body above |
1645 // documentElement's style was dirty. We could keep track of which elements de
pend on | 1669 // can cache bad values for rem units if the documentElement's style was |
1646 // rem units like we do for viewport styles, but we assume root font size chan
ges are | 1670 // dirty. We could keep track of which elements depend on rem units like we do |
1647 // rare and just invalidate the cache for now. | 1671 // for viewport styles, but we assume root font size changes are rare and just |
| 1672 // invalidate the cache for now. |
1648 if (styleEngine().usesRemUnits() && | 1673 if (styleEngine().usesRemUnits() && |
1649 (documentElement()->needsAttach() || | 1674 (documentElement()->needsAttach() || |
1650 !documentElement()->computedStyle() || | 1675 !documentElement()->computedStyle() || |
1651 documentElement()->computedStyle()->fontSize() != | 1676 documentElement()->computedStyle()->fontSize() != |
1652 documentElementStyle->fontSize())) { | 1677 documentElementStyle->fontSize())) { |
1653 ensureStyleResolver().invalidateMatchedPropertiesCache(); | 1678 ensureStyleResolver().invalidateMatchedPropertiesCache(); |
1654 documentElement()->setNeedsStyleRecalc( | 1679 documentElement()->setNeedsStyleRecalc( |
1655 SubtreeStyleChange, | 1680 SubtreeStyleChange, |
1656 StyleChangeReasonForTracing::create(StyleChangeReason::FontSizeChange)); | 1681 StyleChangeReasonForTracing::create(StyleChangeReason::FontSizeChange)); |
1657 } | 1682 } |
1658 | 1683 |
1659 EOverflowAnchor overflowAnchor = AnchorAuto; | 1684 EOverflowAnchor overflowAnchor = AnchorAuto; |
1660 EOverflow overflowX = OverflowAuto; | 1685 EOverflow overflowX = OverflowAuto; |
1661 EOverflow overflowY = OverflowAuto; | 1686 EOverflow overflowY = OverflowAuto; |
1662 float columnGap = 0; | 1687 float columnGap = 0; |
1663 if (overflowStyle) { | 1688 if (overflowStyle) { |
1664 overflowAnchor = overflowStyle->overflowAnchor(); | 1689 overflowAnchor = overflowStyle->overflowAnchor(); |
1665 overflowX = overflowStyle->overflowX(); | 1690 overflowX = overflowStyle->overflowX(); |
1666 overflowY = overflowStyle->overflowY(); | 1691 overflowY = overflowStyle->overflowY(); |
1667 // Visible overflow on the viewport is meaningless, and the spec says to tre
at it as 'auto': | 1692 // Visible overflow on the viewport is meaningless, and the spec says to |
| 1693 // treat it as 'auto': |
1668 if (overflowX == OverflowVisible) | 1694 if (overflowX == OverflowVisible) |
1669 overflowX = OverflowAuto; | 1695 overflowX = OverflowAuto; |
1670 if (overflowY == OverflowVisible) | 1696 if (overflowY == OverflowVisible) |
1671 overflowY = OverflowAuto; | 1697 overflowY = OverflowAuto; |
1672 if (overflowAnchor == AnchorVisible) | 1698 if (overflowAnchor == AnchorVisible) |
1673 overflowAnchor = AnchorAuto; | 1699 overflowAnchor = AnchorAuto; |
1674 // Column-gap is (ab)used by the current paged overflow implementation (in l
ack of other | 1700 // Column-gap is (ab)used by the current paged overflow implementation (in |
1675 // ways to specify gaps between pages), so we have to propagate it too. | 1701 // lack of other ways to specify gaps between pages), so we have to |
| 1702 // propagate it too. |
1676 columnGap = overflowStyle->columnGap(); | 1703 columnGap = overflowStyle->columnGap(); |
1677 } | 1704 } |
1678 | 1705 |
1679 ScrollSnapType snapType = overflowStyle->getScrollSnapType(); | 1706 ScrollSnapType snapType = overflowStyle->getScrollSnapType(); |
1680 const LengthPoint& snapDestination = overflowStyle->scrollSnapDestination(); | 1707 const LengthPoint& snapDestination = overflowStyle->scrollSnapDestination(); |
1681 | 1708 |
1682 RefPtr<ComputedStyle> documentStyle = layoutViewItem().mutableStyle(); | 1709 RefPtr<ComputedStyle> documentStyle = layoutViewItem().mutableStyle(); |
1683 if (documentStyle->getWritingMode() != rootWritingMode || | 1710 if (documentStyle->getWritingMode() != rootWritingMode || |
1684 documentStyle->direction() != rootDirection || | 1711 documentStyle->direction() != rootDirection || |
1685 documentStyle->visitedDependentColor(CSSPropertyBackgroundColor) != | 1712 documentStyle->visitedDependentColor(CSSPropertyBackgroundColor) != |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1746 shadowRoot = shadowRoot->olderShadowRoot()) | 1773 shadowRoot = shadowRoot->olderShadowRoot()) |
1747 assertLayoutTreeUpdated(*shadowRoot); | 1774 assertLayoutTreeUpdated(*shadowRoot); |
1748 } | 1775 } |
1749 } | 1776 } |
1750 #endif | 1777 #endif |
1751 | 1778 |
1752 void Document::updateStyleAndLayoutTree() { | 1779 void Document::updateStyleAndLayoutTree() { |
1753 DCHECK(isMainThread()); | 1780 DCHECK(isMainThread()); |
1754 | 1781 |
1755 ScriptForbiddenScope forbidScript; | 1782 ScriptForbiddenScope forbidScript; |
1756 // We should forbid script execution for plugins here because update while lay
out is changing, | 1783 // We should forbid script execution for plugins here because update while |
1757 // HTMLPlugin element can be reattached and plugin can be destroyed. Plugin ca
n execute scripts | 1784 // layout is changing, HTMLPlugin element can be reattached and plugin can be |
1758 // on destroy. It produces crash without PluginScriptForbiddenScope: crbug.com
/550427. | 1785 // destroyed. Plugin can execute scripts on destroy. It produces crash without |
| 1786 // PluginScriptForbiddenScope: crbug.com/550427. |
1759 PluginScriptForbiddenScope pluginForbidScript; | 1787 PluginScriptForbiddenScope pluginForbidScript; |
1760 | 1788 |
1761 if (!view() || !isActive()) | 1789 if (!view() || !isActive()) |
1762 return; | 1790 return; |
1763 | 1791 |
1764 if (view()->shouldThrottleRendering()) | 1792 if (view()->shouldThrottleRendering()) |
1765 return; | 1793 return; |
1766 | 1794 |
1767 if (!needsLayoutTreeUpdate()) { | 1795 if (!needsLayoutTreeUpdate()) { |
1768 if (lifecycle().state() < DocumentLifecycle::StyleClean) { | 1796 if (lifecycle().state() < DocumentLifecycle::StyleClean) { |
1769 // needsLayoutTreeUpdate may change to false without any actual layout tre
e update. | 1797 // needsLayoutTreeUpdate may change to false without any actual layout |
1770 // For example, needsAnimationTimingUpdate may change to false when time e
lapses. | 1798 // tree update. For example, needsAnimationTimingUpdate may change to |
1771 // Advance lifecycle to StyleClean because style is actually clean now. | 1799 // false when time elapses. Advance lifecycle to StyleClean because style |
| 1800 // is actually clean now. |
1772 lifecycle().advanceTo(DocumentLifecycle::InStyleRecalc); | 1801 lifecycle().advanceTo(DocumentLifecycle::InStyleRecalc); |
1773 lifecycle().advanceTo(DocumentLifecycle::StyleClean); | 1802 lifecycle().advanceTo(DocumentLifecycle::StyleClean); |
1774 } | 1803 } |
1775 return; | 1804 return; |
1776 } | 1805 } |
1777 | 1806 |
1778 if (inStyleRecalc()) | 1807 if (inStyleRecalc()) |
1779 return; | 1808 return; |
1780 | 1809 |
1781 // Entering here from inside layout, paint etc. would be catastrophic since re
calcStyle can | 1810 // Entering here from inside layout, paint etc. would be catastrophic since |
1782 // tear down the layout tree or (unfortunately) run script. Kill the whole lay
outObject if | 1811 // recalcStyle can tear down the layout tree or (unfortunately) run |
1783 // someone managed to get into here in states not allowing tree mutations. | 1812 // script. Kill the whole layoutObject if someone managed to get into here in |
| 1813 // states not allowing tree mutations. |
1784 RELEASE_ASSERT(lifecycle().stateAllowsTreeMutations()); | 1814 RELEASE_ASSERT(lifecycle().stateAllowsTreeMutations()); |
1785 | 1815 |
1786 TRACE_EVENT_BEGIN1("blink,devtools.timeline", "UpdateLayoutTree", "beginData", | 1816 TRACE_EVENT_BEGIN1("blink,devtools.timeline", "UpdateLayoutTree", "beginData", |
1787 InspectorRecalculateStylesEvent::data(frame())); | 1817 InspectorRecalculateStylesEvent::data(frame())); |
1788 TRACE_EVENT_SCOPED_SAMPLING_STATE("blink", "UpdateLayoutTree"); | 1818 TRACE_EVENT_SCOPED_SAMPLING_STATE("blink", "UpdateLayoutTree"); |
1789 | 1819 |
1790 unsigned startElementCount = styleEngine().styleForElementCount(); | 1820 unsigned startElementCount = styleEngine().styleForElementCount(); |
1791 | 1821 |
1792 InspectorInstrumentation::willRecalculateStyle(this); | 1822 InspectorInstrumentation::willRecalculateStyle(this); |
1793 | 1823 |
1794 DocumentAnimations::updateAnimationTimingIfNeeded(*this); | 1824 DocumentAnimations::updateAnimationTimingIfNeeded(*this); |
1795 evaluateMediaQueryListIfNeeded(); | 1825 evaluateMediaQueryListIfNeeded(); |
1796 updateUseShadowTreesIfNeeded(); | 1826 updateUseShadowTreesIfNeeded(); |
1797 updateDistribution(); | 1827 updateDistribution(); |
1798 updateStyleInvalidationIfNeeded(); | 1828 updateStyleInvalidationIfNeeded(); |
1799 | 1829 |
1800 // FIXME: We should update style on our ancestor chain before proceeding | 1830 // FIXME: We should update style on our ancestor chain before proceeding |
1801 // however doing so currently causes several tests to crash, as LocalFrame::se
tDocument calls Document::attach | 1831 // however doing so currently causes several tests to crash, as |
1802 // before setting the LocalDOMWindow on the LocalFrame, or the SecurityOrigin
on the document. The attach, in turn | 1832 // LocalFrame::setDocument calls Document::attach before setting the |
1803 // resolves style (here) and then when we resolve style on the parent chain, w
e may end up | 1833 // LocalDOMWindow on the LocalFrame, or the SecurityOrigin on the |
1804 // re-attaching our containing iframe, which when asked HTMLFrameElementBase::
isURLAllowed | 1834 // document. The attach, in turn resolves style (here) and then when we |
1805 // hits a null-dereference due to security code always assuming the document h
as a SecurityOrigin. | 1835 // resolve style on the parent chain, we may end up re-attaching our |
| 1836 // containing iframe, which when asked HTMLFrameElementBase::isURLAllowed hits |
| 1837 // a null-dereference due to security code always assuming the document has a |
| 1838 // SecurityOrigin. |
1806 | 1839 |
1807 updateStyle(); | 1840 updateStyle(); |
1808 | 1841 |
1809 notifyLayoutTreeOfSubtreeChanges(); | 1842 notifyLayoutTreeOfSubtreeChanges(); |
1810 | 1843 |
1811 // As a result of the style recalculation, the currently hovered element might
have been | 1844 // As a result of the style recalculation, the currently hovered element might |
1812 // detached (for example, by setting display:none in the :hover style), schedu
le another mouseMove event | 1845 // have been detached (for example, by setting display:none in the :hover |
1813 // to check if any other elements ended up under the mouse pointer due to re-l
ayout. | 1846 // style), schedule another mouseMove event to check if any other elements |
| 1847 // ended up under the mouse pointer due to re-layout. |
1814 if (hoverNode() && !hoverNode()->layoutObject() && frame()) | 1848 if (hoverNode() && !hoverNode()->layoutObject() && frame()) |
1815 frame()->eventHandler().dispatchFakeMouseMoveEventSoon(); | 1849 frame()->eventHandler().dispatchFakeMouseMoveEventSoon(); |
1816 | 1850 |
1817 if (m_focusedElement && !m_focusedElement->isFocusable()) | 1851 if (m_focusedElement && !m_focusedElement->isFocusable()) |
1818 clearFocusedElementSoon(); | 1852 clearFocusedElementSoon(); |
1819 layoutViewItem().clearHitTestCache(); | 1853 layoutViewItem().clearHitTestCache(); |
1820 | 1854 |
1821 DCHECK(!DocumentAnimations::needsAnimationTimingUpdate(*this)); | 1855 DCHECK(!DocumentAnimations::needsAnimationTimingUpdate(*this)); |
1822 | 1856 |
1823 unsigned elementCount = | 1857 unsigned elementCount = |
(...skipping 17 matching lines...) Expand all Loading... |
1841 | 1875 |
1842 HTMLFrameOwnerElement::UpdateSuspendScope suspendWidgetHierarchyUpdates; | 1876 HTMLFrameOwnerElement::UpdateSuspendScope suspendWidgetHierarchyUpdates; |
1843 m_lifecycle.advanceTo(DocumentLifecycle::InStyleRecalc); | 1877 m_lifecycle.advanceTo(DocumentLifecycle::InStyleRecalc); |
1844 | 1878 |
1845 StyleRecalcChange change = NoChange; | 1879 StyleRecalcChange change = NoChange; |
1846 if (getStyleChangeType() >= SubtreeStyleChange) | 1880 if (getStyleChangeType() >= SubtreeStyleChange) |
1847 change = Force; | 1881 change = Force; |
1848 | 1882 |
1849 NthIndexCache nthIndexCache(*this); | 1883 NthIndexCache nthIndexCache(*this); |
1850 | 1884 |
1851 // FIXME: Cannot access the ensureStyleResolver() before calling styleForDocum
ent below because | 1885 // FIXME: Cannot access the ensureStyleResolver() before calling |
1852 // apparently the StyleResolver's constructor has side effects. We should fix
it. | 1886 // styleForDocument below because apparently the StyleResolver's constructor |
1853 // See printing/setPrinting.html, printing/width-overflow.html though they onl
y fail on | 1887 // has side effects. We should fix it. See printing/setPrinting.html, |
1854 // mac when accessing the resolver by what appears to be a viewport size diffe
rence. | 1888 // printing/width-overflow.html though they only fail on mac when accessing |
| 1889 // the resolver by what appears to be a viewport size difference. |
1855 | 1890 |
1856 if (change == Force) { | 1891 if (change == Force) { |
1857 m_hasNodesWithPlaceholderStyle = false; | 1892 m_hasNodesWithPlaceholderStyle = false; |
1858 RefPtr<ComputedStyle> documentStyle = | 1893 RefPtr<ComputedStyle> documentStyle = |
1859 StyleResolver::styleForDocument(*this); | 1894 StyleResolver::styleForDocument(*this); |
1860 StyleRecalcChange localChange = ComputedStyle::stylePropagationDiff( | 1895 StyleRecalcChange localChange = ComputedStyle::stylePropagationDiff( |
1861 documentStyle.get(), layoutViewItem().style()); | 1896 documentStyle.get(), layoutViewItem().style()); |
1862 if (localChange != NoChange) | 1897 if (localChange != NoChange) |
1863 layoutViewItem().setStyle(documentStyle.release()); | 1898 layoutViewItem().setStyle(documentStyle.release()); |
1864 } | 1899 } |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2027 // FIXME: This is a bad idea and needs to be removed eventually. | 2062 // FIXME: This is a bad idea and needs to be removed eventually. |
2028 // Other browsers load stylesheets before they continue parsing the web page. | 2063 // Other browsers load stylesheets before they continue parsing the web page. |
2029 // Since we don't, we can run JavaScript code that needs answers before the | 2064 // Since we don't, we can run JavaScript code that needs answers before the |
2030 // stylesheets are loaded. Doing a layout ignoring the pending stylesheets | 2065 // stylesheets are loaded. Doing a layout ignoring the pending stylesheets |
2031 // lets us get reasonable answers. The long term solution to this problem is | 2066 // lets us get reasonable answers. The long term solution to this problem is |
2032 // to instead suspend JavaScript execution. | 2067 // to instead suspend JavaScript execution. |
2033 void Document::updateStyleAndLayoutTreeIgnorePendingStylesheets() { | 2068 void Document::updateStyleAndLayoutTreeIgnorePendingStylesheets() { |
2034 StyleEngine::IgnoringPendingStylesheet ignoring(styleEngine()); | 2069 StyleEngine::IgnoringPendingStylesheet ignoring(styleEngine()); |
2035 | 2070 |
2036 if (styleEngine().hasPendingScriptBlockingSheets()) { | 2071 if (styleEngine().hasPendingScriptBlockingSheets()) { |
2037 // FIXME: We are willing to attempt to suppress painting with outdated style
info only once. | 2072 // FIXME: We are willing to attempt to suppress painting with outdated style |
2038 // Our assumption is that it would be dangerous to try to stop it a second t
ime, after page | 2073 // info only once. Our assumption is that it would be dangerous to try to |
2039 // content has already been loaded and displayed with accurate style informa
tion. (Our | 2074 // stop it a second time, after page content has already been loaded and |
2040 // suppression involves blanking the whole page at the moment. If it were mo
re refined, we | 2075 // displayed with accurate style information. (Our suppression involves |
2041 // might be able to do something better.) It's worth noting though that this
entire method | 2076 // blanking the whole page at the moment. If it were more refined, we might |
2042 // is a hack, since what we really want to do is suspend JS instead of doing
a layout with | 2077 // be able to do something better.) It's worth noting though that this |
2043 // inaccurate information. | 2078 // entire method is a hack, since what we really want to do is suspend JS |
| 2079 // instead of doing a layout with inaccurate information. |
2044 HTMLElement* bodyElement = body(); | 2080 HTMLElement* bodyElement = body(); |
2045 if (bodyElement && !bodyElement->layoutObject() && | 2081 if (bodyElement && !bodyElement->layoutObject() && |
2046 m_pendingSheetLayout == NoLayoutWithPendingSheets) { | 2082 m_pendingSheetLayout == NoLayoutWithPendingSheets) { |
2047 m_pendingSheetLayout = DidLayoutWithPendingSheets; | 2083 m_pendingSheetLayout = DidLayoutWithPendingSheets; |
2048 styleEngine().resolverChanged(FullStyleUpdate); | 2084 styleEngine().resolverChanged(FullStyleUpdate); |
2049 } else if (m_hasNodesWithPlaceholderStyle) { | 2085 } else if (m_hasNodesWithPlaceholderStyle) { |
2050 // If new nodes have been added or style recalc has been done with style s
heets still | 2086 // If new nodes have been added or style recalc has been done with style |
2051 // pending, some nodes may not have had their real style calculated yet. N
ormally this | 2087 // sheets still pending, some nodes may not have had their real style |
2052 // gets cleaned when style sheets arrive but here we need up-to-date style
immediately. | 2088 // calculated yet. Normally this gets cleaned when style sheets arrive |
| 2089 // but here we need up-to-date style immediately. |
2053 setNeedsStyleRecalc(SubtreeStyleChange, | 2090 setNeedsStyleRecalc(SubtreeStyleChange, |
2054 StyleChangeReasonForTracing::create( | 2091 StyleChangeReasonForTracing::create( |
2055 StyleChangeReason::CleanupPlaceholderStyles)); | 2092 StyleChangeReason::CleanupPlaceholderStyles)); |
2056 } | 2093 } |
2057 } | 2094 } |
2058 updateStyleAndLayoutTree(); | 2095 updateStyleAndLayoutTree(); |
2059 } | 2096 } |
2060 | 2097 |
2061 void Document::updateStyleAndLayoutIgnorePendingStylesheets( | 2098 void Document::updateStyleAndLayoutIgnorePendingStylesheets( |
2062 Document::RunPostLayoutTasks runPostLayoutTasks) { | 2099 Document::RunPostLayoutTasks runPostLayoutTasks) { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2113 FloatSize size = style->pageSize(); | 2150 FloatSize size = style->pageSize(); |
2114 width = size.width(); | 2151 width = size.width(); |
2115 height = size.height(); | 2152 height = size.height(); |
2116 break; | 2153 break; |
2117 } | 2154 } |
2118 default: | 2155 default: |
2119 ASSERT_NOT_REACHED(); | 2156 ASSERT_NOT_REACHED(); |
2120 } | 2157 } |
2121 pageSize = DoubleSize(width, height); | 2158 pageSize = DoubleSize(width, height); |
2122 | 2159 |
2123 // The percentage is calculated with respect to the width even for margin top
and bottom. | 2160 // The percentage is calculated with respect to the width even for margin top |
| 2161 // and bottom. |
2124 // http://www.w3.org/TR/CSS2/box.html#margin-properties | 2162 // http://www.w3.org/TR/CSS2/box.html#margin-properties |
2125 marginTop = style->marginTop().isAuto() | 2163 marginTop = style->marginTop().isAuto() |
2126 ? marginTop | 2164 ? marginTop |
2127 : intValueForLength(style->marginTop(), width); | 2165 : intValueForLength(style->marginTop(), width); |
2128 marginRight = style->marginRight().isAuto() | 2166 marginRight = style->marginRight().isAuto() |
2129 ? marginRight | 2167 ? marginRight |
2130 : intValueForLength(style->marginRight(), width); | 2168 : intValueForLength(style->marginRight(), width); |
2131 marginBottom = style->marginBottom().isAuto() | 2169 marginBottom = style->marginBottom().isAuto() |
2132 ? marginBottom | 2170 ? marginBottom |
2133 : intValueForLength(style->marginBottom(), width); | 2171 : intValueForLength(style->marginBottom(), width); |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2206 m_layoutView = new LayoutView(this); | 2244 m_layoutView = new LayoutView(this); |
2207 setLayoutObject(m_layoutView); | 2245 setLayoutObject(m_layoutView); |
2208 | 2246 |
2209 m_layoutView->setIsInWindow(true); | 2247 m_layoutView->setIsInWindow(true); |
2210 m_layoutView->setStyle(StyleResolver::styleForDocument(*this)); | 2248 m_layoutView->setStyle(StyleResolver::styleForDocument(*this)); |
2211 m_layoutView->compositor()->setNeedsCompositingUpdate( | 2249 m_layoutView->compositor()->setNeedsCompositingUpdate( |
2212 CompositingUpdateAfterCompositingInputChange); | 2250 CompositingUpdateAfterCompositingInputChange); |
2213 | 2251 |
2214 ContainerNode::attachLayoutTree(); | 2252 ContainerNode::attachLayoutTree(); |
2215 | 2253 |
2216 // The TextAutosizer can't update layout view info while the Document is detac
hed, so update now in case anything changed. | 2254 // The TextAutosizer can't update layout view info while the Document is |
| 2255 // detached, so update now in case anything changed. |
2217 if (TextAutosizer* autosizer = textAutosizer()) | 2256 if (TextAutosizer* autosizer = textAutosizer()) |
2218 autosizer->updatePageInfo(); | 2257 autosizer->updatePageInfo(); |
2219 | 2258 |
2220 m_frame->selection().documentAttached(this); | 2259 m_frame->selection().documentAttached(this); |
2221 m_lifecycle.advanceTo(DocumentLifecycle::StyleClean); | 2260 m_lifecycle.advanceTo(DocumentLifecycle::StyleClean); |
2222 | 2261 |
2223 if (view()) | 2262 if (view()) |
2224 view()->didAttachDocument(); | 2263 view()->didAttachDocument(); |
2225 } | 2264 } |
2226 | 2265 |
2227 void Document::shutdown() { | 2266 void Document::shutdown() { |
2228 TRACE_EVENT0("blink", "Document::shutdown"); | 2267 TRACE_EVENT0("blink", "Document::shutdown"); |
2229 RELEASE_ASSERT(!m_frame || m_frame->tree().childCount() == 0); | 2268 RELEASE_ASSERT(!m_frame || m_frame->tree().childCount() == 0); |
2230 if (!isActive()) | 2269 if (!isActive()) |
2231 return; | 2270 return; |
2232 | 2271 |
2233 // Frame navigation can cause a new Document to be attached. Don't allow that,
since that will | 2272 // Frame navigation can cause a new Document to be attached. Don't allow that, |
2234 // cause a situation where LocalFrame still has a Document attached after this
finishes! | 2273 // since that will cause a situation where LocalFrame still has a Document |
2235 // Normally, it shouldn't actually be possible to trigger navigation here. How
ever, plugins | 2274 // attached after this finishes! Normally, it shouldn't actually be possible |
2236 // (see below) can cause lots of crazy things to happen, since plugin detach i
nvolves nested | 2275 // to trigger navigation here. However, plugins (see below) can cause lots of |
2237 // message loops. | 2276 // crazy things to happen, since plugin detach involves nested message loops. |
2238 FrameNavigationDisabler navigationDisabler(*m_frame); | 2277 FrameNavigationDisabler navigationDisabler(*m_frame); |
2239 // Defer widget updates to avoid plugins trying to run script inside ScriptFor
biddenScope, | 2278 // Defer widget updates to avoid plugins trying to run script inside |
2240 // which will crash the renderer after https://crrev.com/200984 | 2279 // ScriptForbiddenScope, which will crash the renderer after |
| 2280 // https://crrev.com/200984 |
2241 HTMLFrameOwnerElement::UpdateSuspendScope suspendWidgetHierarchyUpdates; | 2281 HTMLFrameOwnerElement::UpdateSuspendScope suspendWidgetHierarchyUpdates; |
2242 // Don't allow script to run in the middle of detachLayoutTree() because a det
aching Document is not in a | 2282 // Don't allow script to run in the middle of detachLayoutTree() because a |
2243 // consistent state. | 2283 // detaching Document is not in a consistent state. |
2244 ScriptForbiddenScope forbidScript; | 2284 ScriptForbiddenScope forbidScript; |
2245 view()->dispose(); | 2285 view()->dispose(); |
2246 m_markers->prepareForDestruction(); | 2286 m_markers->prepareForDestruction(); |
2247 | 2287 |
2248 m_lifecycle.advanceTo(DocumentLifecycle::Stopping); | 2288 m_lifecycle.advanceTo(DocumentLifecycle::Stopping); |
2249 | 2289 |
2250 if (page()) | 2290 if (page()) |
2251 page()->documentDetached(this); | 2291 page()->documentDetached(this); |
2252 InspectorInstrumentation::documentDetached(this); | 2292 InspectorInstrumentation::documentDetached(this); |
2253 | 2293 |
2254 if (m_frame->loader().client()->sharedWorkerRepositoryClient()) | 2294 if (m_frame->loader().client()->sharedWorkerRepositoryClient()) |
2255 m_frame->loader() | 2295 m_frame->loader() |
2256 .client() | 2296 .client() |
2257 ->sharedWorkerRepositoryClient() | 2297 ->sharedWorkerRepositoryClient() |
2258 ->documentDetached(this); | 2298 ->documentDetached(this); |
2259 | 2299 |
2260 stopActiveDOMObjects(); | 2300 stopActiveDOMObjects(); |
2261 | 2301 |
2262 // FIXME: consider using ActiveDOMObject. | 2302 // FIXME: consider using ActiveDOMObject. |
2263 if (m_scriptedAnimationController) | 2303 if (m_scriptedAnimationController) |
2264 m_scriptedAnimationController->clearDocumentPointer(); | 2304 m_scriptedAnimationController->clearDocumentPointer(); |
2265 m_scriptedAnimationController.clear(); | 2305 m_scriptedAnimationController.clear(); |
2266 | 2306 |
2267 m_scriptedIdleTaskController.clear(); | 2307 m_scriptedIdleTaskController.clear(); |
2268 | 2308 |
2269 if (svgExtensions()) | 2309 if (svgExtensions()) |
2270 accessSVGExtensions().pauseAnimations(); | 2310 accessSVGExtensions().pauseAnimations(); |
2271 | 2311 |
2272 // FIXME: This shouldn't be needed once LocalDOMWindow becomes ExecutionContex
t. | 2312 // FIXME: This shouldn't be needed once LocalDOMWindow becomes |
| 2313 // ExecutionContext. |
2273 if (m_domWindow) | 2314 if (m_domWindow) |
2274 m_domWindow->clearEventQueue(); | 2315 m_domWindow->clearEventQueue(); |
2275 | 2316 |
2276 if (m_layoutView) | 2317 if (m_layoutView) |
2277 m_layoutView->setIsInWindow(false); | 2318 m_layoutView->setIsInWindow(false); |
2278 | 2319 |
2279 if (registrationContext()) | 2320 if (registrationContext()) |
2280 registrationContext()->documentWasDetached(); | 2321 registrationContext()->documentWasDetached(); |
2281 | 2322 |
2282 m_hoverNode = nullptr; | 2323 m_hoverNode = nullptr; |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2344 m_lifecycle.advanceTo(DocumentLifecycle::Stopped); | 2385 m_lifecycle.advanceTo(DocumentLifecycle::Stopped); |
2345 | 2386 |
2346 // FIXME: Currently we call notifyContextDestroyed() only in | 2387 // FIXME: Currently we call notifyContextDestroyed() only in |
2347 // Document::detachLayoutTree(), which means that we don't call | 2388 // Document::detachLayoutTree(), which means that we don't call |
2348 // notifyContextDestroyed() for a document that doesn't get detached. | 2389 // notifyContextDestroyed() for a document that doesn't get detached. |
2349 // If such a document has any observer, the observer won't get | 2390 // If such a document has any observer, the observer won't get |
2350 // a contextDestroyed() notification. This can happen for a document | 2391 // a contextDestroyed() notification. This can happen for a document |
2351 // created by DOMImplementation::createDocument(). | 2392 // created by DOMImplementation::createDocument(). |
2352 ExecutionContext::notifyContextDestroyed(); | 2393 ExecutionContext::notifyContextDestroyed(); |
2353 | 2394 |
2354 // This is required, as our LocalFrame might delete itself as soon as it detac
hes | 2395 // This is required, as our LocalFrame might delete itself as soon as it |
2355 // us. However, this violates Node::detachLayoutTree() semantics, as it's neve
r | 2396 // detaches us. However, this violates Node::detachLayoutTree() semantics, as |
2356 // possible to re-attach. Eventually Document::detachLayoutTree() should be re
named, | 2397 // it's never possible to re-attach. Eventually Document::detachLayoutTree() |
2357 // or this setting of the frame to 0 could be made explicit in each of the | 2398 // should be renamed, or this setting of the frame to 0 could be made explicit |
2358 // callers of Document::detachLayoutTree(). | 2399 // in each of the callers of Document::detachLayoutTree(). |
2359 m_frame = nullptr; | 2400 m_frame = nullptr; |
2360 } | 2401 } |
2361 | 2402 |
2362 void Document::removeAllEventListeners() { | 2403 void Document::removeAllEventListeners() { |
2363 ContainerNode::removeAllEventListeners(); | 2404 ContainerNode::removeAllEventListeners(); |
2364 | 2405 |
2365 if (LocalDOMWindow* domWindow = this->domWindow()) | 2406 if (LocalDOMWindow* domWindow = this->domWindow()) |
2366 domWindow->removeAllEventListeners(); | 2407 domWindow->removeAllEventListeners(); |
2367 } | 2408 } |
2368 | 2409 |
(...skipping 25 matching lines...) Expand all Loading... |
2394 | 2435 |
2395 return axObjectCacheOwner().m_axObjectCache.get(); | 2436 return axObjectCacheOwner().m_axObjectCache.get(); |
2396 } | 2437 } |
2397 | 2438 |
2398 AXObjectCache* Document::axObjectCache() const { | 2439 AXObjectCache* Document::axObjectCache() const { |
2399 Settings* settings = this->settings(); | 2440 Settings* settings = this->settings(); |
2400 if (!settings || !settings->accessibilityEnabled()) | 2441 if (!settings || !settings->accessibilityEnabled()) |
2401 return 0; | 2442 return 0; |
2402 | 2443 |
2403 // The only document that actually has a AXObjectCache is the top-level | 2444 // The only document that actually has a AXObjectCache is the top-level |
2404 // document. This is because we need to be able to get from any WebCoreAXObje
ct | 2445 // document. This is because we need to be able to get from any |
2405 // to any other WebCoreAXObject on the same page. Using a single cache allows | 2446 // WebCoreAXObject to any other WebCoreAXObject on the same page. Using a |
2406 // lookups across nested webareas (i.e. multiple documents). | 2447 // single cache allows lookups across nested webareas (i.e. multiple |
| 2448 // documents). |
2407 Document& cacheOwner = this->axObjectCacheOwner(); | 2449 Document& cacheOwner = this->axObjectCacheOwner(); |
2408 | 2450 |
2409 // If the document has already been detached, do not make a new axObjectCache. | 2451 // If the document has already been detached, do not make a new axObjectCache. |
2410 if (!cacheOwner.layoutView()) | 2452 if (!cacheOwner.layoutView()) |
2411 return 0; | 2453 return 0; |
2412 | 2454 |
2413 DCHECK(&cacheOwner == this || !m_axObjectCache); | 2455 DCHECK(&cacheOwner == this || !m_axObjectCache); |
2414 if (!cacheOwner.m_axObjectCache) | 2456 if (!cacheOwner.m_axObjectCache) |
2415 cacheOwner.m_axObjectCache = AXObjectCache::create(cacheOwner); | 2457 cacheOwner.m_axObjectCache = AXObjectCache::create(cacheOwner); |
2416 return cacheOwner.m_axObjectCache.get(); | 2458 return cacheOwner.m_axObjectCache.get(); |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2620 HTMLHeadElement* Document::head() const { | 2662 HTMLHeadElement* Document::head() const { |
2621 Node* de = documentElement(); | 2663 Node* de = documentElement(); |
2622 if (!de) | 2664 if (!de) |
2623 return 0; | 2665 return 0; |
2624 | 2666 |
2625 return Traversal<HTMLHeadElement>::firstChild(*de); | 2667 return Traversal<HTMLHeadElement>::firstChild(*de); |
2626 } | 2668 } |
2627 | 2669 |
2628 Element* Document::viewportDefiningElement( | 2670 Element* Document::viewportDefiningElement( |
2629 const ComputedStyle* rootStyle) const { | 2671 const ComputedStyle* rootStyle) const { |
2630 // If a BODY element sets non-visible overflow, it is to be propagated to the
viewport, as long | 2672 // If a BODY element sets non-visible overflow, it is to be propagated to the |
2631 // as the following conditions are all met: | 2673 // viewport, as long as the following conditions are all met: |
2632 // (1) The root element is HTML. | 2674 // (1) The root element is HTML. |
2633 // (2) It is the primary BODY element (we only assert for this, expecting call
ers to behave). | 2675 // (2) It is the primary BODY element (we only assert for this, expecting |
| 2676 // callers to behave). |
2634 // (3) The root element has visible overflow. | 2677 // (3) The root element has visible overflow. |
2635 // Otherwise it's the root element's properties that are to be propagated. | 2678 // Otherwise it's the root element's properties that are to be propagated. |
2636 Element* rootElement = documentElement(); | 2679 Element* rootElement = documentElement(); |
2637 Element* bodyElement = body(); | 2680 Element* bodyElement = body(); |
2638 if (!rootElement) | 2681 if (!rootElement) |
2639 return 0; | 2682 return 0; |
2640 if (!rootStyle) { | 2683 if (!rootStyle) { |
2641 rootStyle = rootElement->computedStyle(); | 2684 rootStyle = rootElement->computedStyle(); |
2642 if (!rootStyle) | 2685 if (!rootStyle) |
2643 return 0; | 2686 return 0; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2679 !scriptableDocumentParser()->wasCreatedByScript() || | 2722 !scriptableDocumentParser()->wasCreatedByScript() || |
2680 !scriptableDocumentParser()->isParsing()) | 2723 !scriptableDocumentParser()->isParsing()) |
2681 return; | 2724 return; |
2682 | 2725 |
2683 if (DocumentParser* parser = m_parser) | 2726 if (DocumentParser* parser = m_parser) |
2684 parser->finish(); | 2727 parser->finish(); |
2685 | 2728 |
2686 if (!m_frame) { | 2729 if (!m_frame) { |
2687 // Because we have no frame, we don't know if all loading has completed, | 2730 // Because we have no frame, we don't know if all loading has completed, |
2688 // so we just call implicitClose() immediately. FIXME: This might fire | 2731 // so we just call implicitClose() immediately. FIXME: This might fire |
2689 // the load event prematurely <http://bugs.webkit.org/show_bug.cgi?id=14568>
. | 2732 // the load event prematurely |
| 2733 // <http://bugs.webkit.org/show_bug.cgi?id=14568>. |
2690 implicitClose(); | 2734 implicitClose(); |
2691 return; | 2735 return; |
2692 } | 2736 } |
2693 | 2737 |
2694 m_frame->loader().checkCompleted(); | 2738 m_frame->loader().checkCompleted(); |
2695 } | 2739 } |
2696 | 2740 |
2697 void Document::implicitClose() { | 2741 void Document::implicitClose() { |
2698 DCHECK(!inStyleRecalc()); | 2742 DCHECK(!inStyleRecalc()); |
2699 if (processingLoadEvent() || !m_parser) | 2743 if (processingLoadEvent() || !m_parser) |
(...skipping 12 matching lines...) Expand all Loading... |
2712 // onLoad event handler, as in Radar 3206524. | 2756 // onLoad event handler, as in Radar 3206524. |
2713 detachParser(); | 2757 detachParser(); |
2714 | 2758 |
2715 if (frame() && frame()->script().canExecuteScripts(NotAboutToExecuteScript)) { | 2759 if (frame() && frame()->script().canExecuteScripts(NotAboutToExecuteScript)) { |
2716 ImageLoader::dispatchPendingLoadEvents(); | 2760 ImageLoader::dispatchPendingLoadEvents(); |
2717 ImageLoader::dispatchPendingErrorEvents(); | 2761 ImageLoader::dispatchPendingErrorEvents(); |
2718 | 2762 |
2719 HTMLStyleElement::dispatchPendingLoadEvents(); | 2763 HTMLStyleElement::dispatchPendingLoadEvents(); |
2720 } | 2764 } |
2721 | 2765 |
2722 // JS running below could remove the frame or destroy the LayoutView so we cal
l | 2766 // JS running below could remove the frame or destroy the LayoutView so we |
2723 // those two functions repeatedly and don't save them on the stack. | 2767 // call those two functions repeatedly and don't save them on the stack. |
2724 | 2768 |
2725 // To align the HTML load event and the SVGLoad event for the outermost <svg>
element, fire it from | 2769 // To align the HTML load event and the SVGLoad event for the outermost <svg> |
2726 // here, instead of doing it from SVGElement::finishedParsingChildren. | 2770 // element, fire it from here, instead of doing it from |
| 2771 // SVGElement::finishedParsingChildren. |
2727 if (svgExtensions()) | 2772 if (svgExtensions()) |
2728 accessSVGExtensions().dispatchSVGLoadEventToOutermostSVGElements(); | 2773 accessSVGExtensions().dispatchSVGLoadEventToOutermostSVGElements(); |
2729 | 2774 |
2730 if (this->domWindow()) | 2775 if (this->domWindow()) |
2731 this->domWindow()->documentWasClosed(); | 2776 this->domWindow()->documentWasClosed(); |
2732 | 2777 |
2733 if (frame()) { | 2778 if (frame()) { |
2734 frame()->loader().client()->dispatchDidHandleOnloadEvents(); | 2779 frame()->loader().client()->dispatchDidHandleOnloadEvents(); |
2735 loader()->applicationCacheHost()->stopDeferringEvents(); | 2780 loader()->applicationCacheHost()->stopDeferringEvents(); |
2736 } | 2781 } |
2737 | 2782 |
2738 if (!frame()) { | 2783 if (!frame()) { |
2739 m_loadEventProgress = LoadEventCompleted; | 2784 m_loadEventProgress = LoadEventCompleted; |
2740 return; | 2785 return; |
2741 } | 2786 } |
2742 | 2787 |
2743 // Make sure both the initial layout and reflow happen after the onload | 2788 // Make sure both the initial layout and reflow happen after the onload |
2744 // fires. This will improve onload scores, and other browsers do it. | 2789 // fires. This will improve onload scores, and other browsers do it. |
2745 // If they wanna cheat, we can too. -dwh | 2790 // If they wanna cheat, we can too. -dwh |
2746 | 2791 |
2747 if (frame()->navigationScheduler().locationChangePending() && | 2792 if (frame()->navigationScheduler().locationChangePending() && |
2748 elapsedTime() < cLayoutScheduleThreshold) { | 2793 elapsedTime() < cLayoutScheduleThreshold) { |
2749 // Just bail out. Before or during the onload we were shifted to another pag
e. | 2794 // Just bail out. Before or during the onload we were shifted to another |
2750 // The old i-Bench suite does this. When this happens don't bother painting
or laying out. | 2795 // page. The old i-Bench suite does this. When this happens don't bother |
| 2796 // painting or laying out. |
2751 m_loadEventProgress = LoadEventCompleted; | 2797 m_loadEventProgress = LoadEventCompleted; |
2752 return; | 2798 return; |
2753 } | 2799 } |
2754 | 2800 |
2755 // We used to force a synchronous display and flush here. This really isn't | 2801 // We used to force a synchronous display and flush here. This really isn't |
2756 // necessary and can in fact be actively harmful if pages are loading at a rat
e of > 60fps | 2802 // necessary and can in fact be actively harmful if pages are loading at a |
| 2803 // rate of > 60fps |
2757 // (if your platform is syncing flushes and limiting them to 60fps). | 2804 // (if your platform is syncing flushes and limiting them to 60fps). |
2758 if (!localOwner() || (localOwner()->layoutObject() && | 2805 if (!localOwner() || (localOwner()->layoutObject() && |
2759 !localOwner()->layoutObject()->needsLayout())) { | 2806 !localOwner()->layoutObject()->needsLayout())) { |
2760 updateStyleAndLayoutTree(); | 2807 updateStyleAndLayoutTree(); |
2761 | 2808 |
2762 // Always do a layout after loading if needed. | 2809 // Always do a layout after loading if needed. |
2763 if (view() && !layoutViewItem().isNull() && | 2810 if (view() && !layoutViewItem().isNull() && |
2764 (!layoutViewItem().firstChild() || layoutViewItem().needsLayout())) | 2811 (!layoutViewItem().firstChild() || layoutViewItem().needsLayout())) |
2765 view()->layout(); | 2812 view()->layout(); |
2766 } | 2813 } |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2866 m_frame->localDOMWindow()->dispatchEvent(unloadEvent, | 2913 m_frame->localDOMWindow()->dispatchEvent(unloadEvent, |
2867 m_frame->document()); | 2914 m_frame->document()); |
2868 } | 2915 } |
2869 } | 2916 } |
2870 m_loadEventProgress = UnloadEventHandled; | 2917 m_loadEventProgress = UnloadEventHandled; |
2871 } | 2918 } |
2872 | 2919 |
2873 if (!m_frame) | 2920 if (!m_frame) |
2874 return; | 2921 return; |
2875 | 2922 |
2876 // Don't remove event listeners from a transitional empty document (see https:
//bugs.webkit.org/show_bug.cgi?id=28716 for more information). | 2923 // Don't remove event listeners from a transitional empty document (see |
| 2924 // https://bugs.webkit.org/show_bug.cgi?id=28716 for more information). |
2877 bool keepEventListeners = | 2925 bool keepEventListeners = |
2878 m_frame->loader().provisionalDocumentLoader() && | 2926 m_frame->loader().provisionalDocumentLoader() && |
2879 m_frame->shouldReuseDefaultView( | 2927 m_frame->shouldReuseDefaultView( |
2880 m_frame->loader().provisionalDocumentLoader()->url()); | 2928 m_frame->loader().provisionalDocumentLoader()->url()); |
2881 if (!keepEventListeners) | 2929 if (!keepEventListeners) |
2882 removeAllEventListenersRecursively(); | 2930 removeAllEventListenersRecursively(); |
2883 } | 2931 } |
2884 | 2932 |
2885 Document::PageDismissalType Document::pageDismissalEventBeingDispatched() | 2933 Document::PageDismissalType Document::pageDismissalEventBeingDispatched() |
2886 const { | 2934 const { |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3062 | 3110 |
3063 KURL Document::validBaseElementURL() const { | 3111 KURL Document::validBaseElementURL() const { |
3064 if (m_baseElementURL.isValid()) | 3112 if (m_baseElementURL.isValid()) |
3065 return m_baseElementURL; | 3113 return m_baseElementURL; |
3066 | 3114 |
3067 return KURL(); | 3115 return KURL(); |
3068 } | 3116 } |
3069 | 3117 |
3070 void Document::updateBaseURL() { | 3118 void Document::updateBaseURL() { |
3071 KURL oldBaseURL = m_baseURL; | 3119 KURL oldBaseURL = m_baseURL; |
3072 // DOM 3 Core: When the Document supports the feature "HTML" [DOM Level 2 HTML
], the base URI is computed using | 3120 // DOM 3 Core: When the Document supports the feature "HTML" [DOM Level 2 |
3073 // first the value of the href attribute of the HTML BASE element if any, and
the value of the documentURI attribute | 3121 // HTML], the base URI is computed using first the value of the href attribute |
3074 // from the Document interface otherwise (which we store, preparsed, in m_url)
. | 3122 // of the HTML BASE element if any, and the value of the documentURI attribute |
| 3123 // from the Document interface otherwise (which we store, preparsed, in |
| 3124 // m_url). |
3075 if (!m_baseElementURL.isEmpty()) | 3125 if (!m_baseElementURL.isEmpty()) |
3076 m_baseURL = m_baseElementURL; | 3126 m_baseURL = m_baseElementURL; |
3077 else if (!m_baseURLOverride.isEmpty()) | 3127 else if (!m_baseURLOverride.isEmpty()) |
3078 m_baseURL = m_baseURLOverride; | 3128 m_baseURL = m_baseURLOverride; |
3079 else | 3129 else |
3080 m_baseURL = m_url; | 3130 m_baseURL = m_url; |
3081 | 3131 |
3082 selectorQueryCache().invalidate(); | 3132 selectorQueryCache().invalidate(); |
3083 | 3133 |
3084 if (!m_baseURL.isValid()) | 3134 if (!m_baseURL.isValid()) |
3085 m_baseURL = KURL(); | 3135 m_baseURL = KURL(); |
3086 | 3136 |
3087 if (m_elemSheet) { | 3137 if (m_elemSheet) { |
3088 // Element sheet is silly. It never contains anything. | 3138 // Element sheet is silly. It never contains anything. |
3089 DCHECK(!m_elemSheet->contents()->ruleCount()); | 3139 DCHECK(!m_elemSheet->contents()->ruleCount()); |
3090 m_elemSheet = CSSStyleSheet::createInline(*this, m_baseURL); | 3140 m_elemSheet = CSSStyleSheet::createInline(*this, m_baseURL); |
3091 } | 3141 } |
3092 | 3142 |
3093 if (!equalIgnoringFragmentIdentifier(oldBaseURL, m_baseURL)) { | 3143 if (!equalIgnoringFragmentIdentifier(oldBaseURL, m_baseURL)) { |
3094 // Base URL change changes any relative visited links. | 3144 // Base URL change changes any relative visited links. |
3095 // FIXME: There are other URLs in the tree that would need to be re-evaluate
d on dynamic base URL change. Style should be invalidated too. | 3145 // FIXME: There are other URLs in the tree that would need to be |
| 3146 // re-evaluated on dynamic base URL change. Style should be invalidated too. |
3096 for (HTMLAnchorElement& anchor : | 3147 for (HTMLAnchorElement& anchor : |
3097 Traversal<HTMLAnchorElement>::startsAfter(*this)) | 3148 Traversal<HTMLAnchorElement>::startsAfter(*this)) |
3098 anchor.invalidateCachedVisitedLinkHash(); | 3149 anchor.invalidateCachedVisitedLinkHash(); |
3099 } | 3150 } |
3100 } | 3151 } |
3101 | 3152 |
3102 void Document::setBaseURLOverride(const KURL& url) { | 3153 void Document::setBaseURLOverride(const KURL& url) { |
3103 m_baseURLOverride = url; | 3154 m_baseURLOverride = url; |
3104 updateBaseURL(); | 3155 updateBaseURL(); |
3105 } | 3156 } |
3106 | 3157 |
3107 void Document::processBaseElement() { | 3158 void Document::processBaseElement() { |
3108 // Find the first href attribute in a base element and the first target attrib
ute in a base element. | 3159 // Find the first href attribute in a base element and the first target |
| 3160 // attribute in a base element. |
3109 const AtomicString* href = 0; | 3161 const AtomicString* href = 0; |
3110 const AtomicString* target = 0; | 3162 const AtomicString* target = 0; |
3111 for (HTMLBaseElement* base = Traversal<HTMLBaseElement>::firstWithin(*this); | 3163 for (HTMLBaseElement* base = Traversal<HTMLBaseElement>::firstWithin(*this); |
3112 base && (!href || !target); | 3164 base && (!href || !target); |
3113 base = Traversal<HTMLBaseElement>::next(*base)) { | 3165 base = Traversal<HTMLBaseElement>::next(*base)) { |
3114 if (!href) { | 3166 if (!href) { |
3115 const AtomicString& value = base->fastGetAttribute(hrefAttr); | 3167 const AtomicString& value = base->fastGetAttribute(hrefAttr); |
3116 if (!value.isNull()) | 3168 if (!value.isNull()) |
3117 href = &value; | 3169 href = &value; |
3118 } | 3170 } |
3119 if (!target) { | 3171 if (!target) { |
3120 const AtomicString& value = base->fastGetAttribute(targetAttr); | 3172 const AtomicString& value = base->fastGetAttribute(targetAttr); |
3121 if (!value.isNull()) | 3173 if (!value.isNull()) |
3122 target = &value; | 3174 target = &value; |
3123 } | 3175 } |
3124 if (contentSecurityPolicy()->isActive()) | 3176 if (contentSecurityPolicy()->isActive()) |
3125 UseCounter::count(*this, | 3177 UseCounter::count(*this, |
3126 UseCounter::ContentSecurityPolicyWithBaseElement); | 3178 UseCounter::ContentSecurityPolicyWithBaseElement); |
3127 } | 3179 } |
3128 | 3180 |
3129 // FIXME: Since this doesn't share code with completeURL it may not handle enc
odings correctly. | 3181 // FIXME: Since this doesn't share code with completeURL it may not handle |
| 3182 // encodings correctly. |
3130 KURL baseElementURL; | 3183 KURL baseElementURL; |
3131 if (href) { | 3184 if (href) { |
3132 String strippedHref = stripLeadingAndTrailingHTMLSpaces(*href); | 3185 String strippedHref = stripLeadingAndTrailingHTMLSpaces(*href); |
3133 if (!strippedHref.isEmpty()) | 3186 if (!strippedHref.isEmpty()) |
3134 baseElementURL = KURL(url(), strippedHref); | 3187 baseElementURL = KURL(url(), strippedHref); |
3135 } | 3188 } |
3136 if (m_baseElementURL != baseElementURL && | 3189 if (m_baseElementURL != baseElementURL && |
3137 contentSecurityPolicy()->allowBaseURI(baseElementURL)) { | 3190 contentSecurityPolicy()->allowBaseURI(baseElementURL)) { |
3138 m_baseElementURL = baseElementURL; | 3191 m_baseElementURL = baseElementURL; |
3139 updateBaseURL(); | 3192 updateBaseURL(); |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3252 const ViewportDescription& viewportDescription) { | 3305 const ViewportDescription& viewportDescription) { |
3253 if (viewportDescription.isLegacyViewportType()) { | 3306 if (viewportDescription.isLegacyViewportType()) { |
3254 if (viewportDescription == m_legacyViewportDescription) | 3307 if (viewportDescription == m_legacyViewportDescription) |
3255 return; | 3308 return; |
3256 m_legacyViewportDescription = viewportDescription; | 3309 m_legacyViewportDescription = viewportDescription; |
3257 } else { | 3310 } else { |
3258 if (viewportDescription == m_viewportDescription) | 3311 if (viewportDescription == m_viewportDescription) |
3259 return; | 3312 return; |
3260 m_viewportDescription = viewportDescription; | 3313 m_viewportDescription = viewportDescription; |
3261 | 3314 |
3262 // The UA-defined min-width is considered specifically by Android WebView qu
irks mode. | 3315 // The UA-defined min-width is considered specifically by Android WebView |
| 3316 // quirks mode. |
3263 if (!viewportDescription.isSpecifiedByAuthor()) | 3317 if (!viewportDescription.isSpecifiedByAuthor()) |
3264 m_viewportDefaultMinWidth = viewportDescription.minWidth; | 3318 m_viewportDefaultMinWidth = viewportDescription.minWidth; |
3265 } | 3319 } |
3266 | 3320 |
3267 updateViewportDescription(); | 3321 updateViewportDescription(); |
3268 } | 3322 } |
3269 | 3323 |
3270 ViewportDescription Document::viewportDescription() const { | 3324 ViewportDescription Document::viewportDescription() const { |
3271 ViewportDescription appliedViewportDescription = m_viewportDescription; | 3325 ViewportDescription appliedViewportDescription = m_viewportDescription; |
3272 bool viewportMetaEnabled = settings() && settings()->viewportMetaEnabled(); | 3326 bool viewportMetaEnabled = settings() && settings()->viewportMetaEnabled(); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3308 } | 3362 } |
3309 return referrerDocument->m_url.strippedForUseAsReferrer(); | 3363 return referrerDocument->m_url.strippedForUseAsReferrer(); |
3310 } | 3364 } |
3311 | 3365 |
3312 MouseEventWithHitTestResults Document::prepareMouseEvent( | 3366 MouseEventWithHitTestResults Document::prepareMouseEvent( |
3313 const HitTestRequest& request, | 3367 const HitTestRequest& request, |
3314 const LayoutPoint& documentPoint, | 3368 const LayoutPoint& documentPoint, |
3315 const PlatformMouseEvent& event) { | 3369 const PlatformMouseEvent& event) { |
3316 DCHECK(layoutViewItem().isNull() || layoutViewItem().isLayoutView()); | 3370 DCHECK(layoutViewItem().isNull() || layoutViewItem().isLayoutView()); |
3317 | 3371 |
3318 // LayoutView::hitTest causes a layout, and we don't want to hit that until th
e first | 3372 // LayoutView::hitTest causes a layout, and we don't want to hit that until |
3319 // layout because until then, there is nothing shown on the screen - the user
can't | 3373 // the first layout because until then, there is nothing shown on the screen - |
3320 // have intentionally clicked on something belonging to this page. Furthermore
, | 3374 // the user can't have intentionally clicked on something belonging to this |
3321 // mousemove events before the first layout should not lead to a premature lay
out() | 3375 // page. Furthermore, mousemove events before the first layout should not |
3322 // happening, which could show a flash of white. | 3376 // lead to a premature layout() happening, which could show a flash of white. |
3323 // See also the similar code in EventHandler::hitTestResultAtPoint. | 3377 // See also the similar code in EventHandler::hitTestResultAtPoint. |
3324 if (layoutViewItem().isNull() || !view() || !view()->didFirstLayout()) | 3378 if (layoutViewItem().isNull() || !view() || !view()->didFirstLayout()) |
3325 return MouseEventWithHitTestResults(event, | 3379 return MouseEventWithHitTestResults(event, |
3326 HitTestResult(request, LayoutPoint())); | 3380 HitTestResult(request, LayoutPoint())); |
3327 | 3381 |
3328 HitTestResult result(request, documentPoint); | 3382 HitTestResult result(request, documentPoint); |
3329 layoutViewItem().hitTest(result); | 3383 layoutViewItem().hitTest(result); |
3330 | 3384 |
3331 if (!request.readOnly()) | 3385 if (!request.readOnly()) |
3332 updateHoverActiveState(request, result.innerElement()); | 3386 updateHoverActiveState(request, result.innerElement()); |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3576 ensureStyleResolver().notifyResizeForViewportUnits(); | 3630 ensureStyleResolver().notifyResizeForViewportUnits(); |
3577 setNeedsStyleRecalcForViewportUnits(); | 3631 setNeedsStyleRecalcForViewportUnits(); |
3578 } | 3632 } |
3579 | 3633 |
3580 void Document::styleResolverMayHaveChanged() { | 3634 void Document::styleResolverMayHaveChanged() { |
3581 styleEngine().resolverChanged( | 3635 styleEngine().resolverChanged( |
3582 hasNodesWithPlaceholderStyle() ? FullStyleUpdate : AnalyzedStyleUpdate); | 3636 hasNodesWithPlaceholderStyle() ? FullStyleUpdate : AnalyzedStyleUpdate); |
3583 | 3637 |
3584 if (didLayoutWithPendingStylesheets() && | 3638 if (didLayoutWithPendingStylesheets() && |
3585 !styleEngine().hasPendingScriptBlockingSheets()) { | 3639 !styleEngine().hasPendingScriptBlockingSheets()) { |
3586 // We need to manually repaint because we avoid doing all repaints in layout
or style | 3640 // We need to manually repaint because we avoid doing all repaints in layout |
3587 // recalc while sheets are still loading to avoid FOUC. | 3641 // or style recalc while sheets are still loading to avoid FOUC. |
3588 m_pendingSheetLayout = IgnoreLayoutWithPendingSheets; | 3642 m_pendingSheetLayout = IgnoreLayoutWithPendingSheets; |
3589 | 3643 |
3590 DCHECK(!layoutViewItem().isNull() || importsController()); | 3644 DCHECK(!layoutViewItem().isNull() || importsController()); |
3591 if (!layoutViewItem().isNull()) | 3645 if (!layoutViewItem().isNull()) |
3592 layoutViewItem().invalidatePaintForViewAndCompositedLayers(); | 3646 layoutViewItem().invalidatePaintForViewAndCompositedLayers(); |
3593 } | 3647 } |
3594 } | 3648 } |
3595 | 3649 |
3596 void Document::setHoverNode(Node* newHoverNode) { | 3650 void Document::setHoverNode(Node* newHoverNode) { |
3597 m_hoverNode = newHoverNode; | 3651 m_hoverNode = newHoverNode; |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3690 return true; | 3744 return true; |
3691 | 3745 |
3692 bool focusChangeBlocked = false; | 3746 bool focusChangeBlocked = false; |
3693 Element* oldFocusedElement = m_focusedElement; | 3747 Element* oldFocusedElement = m_focusedElement; |
3694 m_focusedElement = nullptr; | 3748 m_focusedElement = nullptr; |
3695 | 3749 |
3696 // Remove focus from the existing focus node (if any) | 3750 // Remove focus from the existing focus node (if any) |
3697 if (oldFocusedElement) { | 3751 if (oldFocusedElement) { |
3698 oldFocusedElement->setFocus(false); | 3752 oldFocusedElement->setFocus(false); |
3699 | 3753 |
3700 // Dispatch the blur event and let the node do any other blur related activi
ties (important for text fields) | 3754 // Dispatch the blur event and let the node do any other blur related |
| 3755 // activities (important for text fields) |
3701 // If page lost focus, blur event will have already been dispatched | 3756 // If page lost focus, blur event will have already been dispatched |
3702 if (page() && (page()->focusController().isFocused())) { | 3757 if (page() && (page()->focusController().isFocused())) { |
3703 oldFocusedElement->dispatchBlurEvent(newFocusedElement, params.type, | 3758 oldFocusedElement->dispatchBlurEvent(newFocusedElement, params.type, |
3704 params.sourceCapabilities); | 3759 params.sourceCapabilities); |
3705 | 3760 |
3706 if (m_focusedElement) { | 3761 if (m_focusedElement) { |
3707 // handler shifted focus | 3762 // handler shifted focus |
3708 focusChangeBlocked = true; | 3763 focusChangeBlocked = true; |
3709 newFocusedElement = nullptr; | 3764 newFocusedElement = nullptr; |
3710 } | 3765 } |
3711 | 3766 |
3712 oldFocusedElement->dispatchFocusOutEvent( | 3767 // 'focusout' is a DOM level 3 name for the bubbling blur event. |
3713 EventTypeNames::focusout, newFocusedElement, | 3768 oldFocusedElement->dispatchFocusOutEvent(EventTypeNames::focusout, |
3714 params | 3769 newFocusedElement, |
3715 .sourceCapabilities); // DOM level 3 name for the bubbling blur e
vent. | 3770 params.sourceCapabilities); |
3716 // FIXME: We should remove firing DOMFocusOutEvent event when we are sure
no content depends | 3771 // 'DOMFocusOut' is a DOM level 2 name for compatibility. |
3717 // on it, probably when <rdar://problem/8503958> is resolved. | 3772 // FIXME: We should remove firing DOMFocusOutEvent event when we are sure |
3718 oldFocusedElement->dispatchFocusOutEvent( | 3773 // no content depends on it, probably when <rdar://problem/8503958> is |
3719 EventTypeNames::DOMFocusOut, newFocusedElement, | 3774 // resolved. |
3720 params.sourceCapabilities); // DOM level 2 name for compatibility. | 3775 oldFocusedElement->dispatchFocusOutEvent(EventTypeNames::DOMFocusOut, |
| 3776 newFocusedElement, |
| 3777 params.sourceCapabilities); |
3721 | 3778 |
3722 if (m_focusedElement) { | 3779 if (m_focusedElement) { |
3723 // handler shifted focus | 3780 // handler shifted focus |
3724 focusChangeBlocked = true; | 3781 focusChangeBlocked = true; |
3725 newFocusedElement = nullptr; | 3782 newFocusedElement = nullptr; |
3726 } | 3783 } |
3727 } | 3784 } |
3728 | 3785 |
3729 if (view()) { | 3786 if (view()) { |
3730 Widget* oldWidget = widgetForElement(*oldFocusedElement); | 3787 Widget* oldWidget = widgetForElement(*oldFocusedElement); |
(...skipping 19 matching lines...) Expand all Loading... |
3750 | 3807 |
3751 m_focusedElement->setFocus(true); | 3808 m_focusedElement->setFocus(true); |
3752 // Element::setFocus for frames can dispatch events. | 3809 // Element::setFocus for frames can dispatch events. |
3753 if (m_focusedElement != newFocusedElement) { | 3810 if (m_focusedElement != newFocusedElement) { |
3754 focusChangeBlocked = true; | 3811 focusChangeBlocked = true; |
3755 goto SetFocusedElementDone; | 3812 goto SetFocusedElementDone; |
3756 } | 3813 } |
3757 cancelFocusAppearanceUpdate(); | 3814 cancelFocusAppearanceUpdate(); |
3758 m_focusedElement->updateFocusAppearance(params.selectionBehavior); | 3815 m_focusedElement->updateFocusAppearance(params.selectionBehavior); |
3759 | 3816 |
3760 // Dispatch the focus event and let the node do any other focus related acti
vities (important for text fields) | 3817 // Dispatch the focus event and let the node do any other focus related |
3761 // If page lost focus, event will be dispatched on page focus, don't duplica
te | 3818 // activities (important for text fields) |
| 3819 // If page lost focus, event will be dispatched on page focus, don't |
| 3820 // duplicate |
3762 if (page() && (page()->focusController().isFocused())) { | 3821 if (page() && (page()->focusController().isFocused())) { |
3763 m_focusedElement->dispatchFocusEvent(oldFocusedElement, params.type, | 3822 m_focusedElement->dispatchFocusEvent(oldFocusedElement, params.type, |
3764 params.sourceCapabilities); | 3823 params.sourceCapabilities); |
3765 | 3824 |
3766 if (m_focusedElement != newFocusedElement) { | 3825 if (m_focusedElement != newFocusedElement) { |
3767 // handler shifted focus | 3826 // handler shifted focus |
3768 focusChangeBlocked = true; | 3827 focusChangeBlocked = true; |
3769 goto SetFocusedElementDone; | 3828 goto SetFocusedElementDone; |
3770 } | 3829 } |
3771 m_focusedElement->dispatchFocusInEvent( | 3830 // DOM level 3 bubbling focus event. |
3772 EventTypeNames::focusin, oldFocusedElement, params.type, | 3831 m_focusedElement->dispatchFocusInEvent(EventTypeNames::focusin, |
3773 params.sourceCapabilities); // DOM level 3 bubbling focus event. | 3832 oldFocusedElement, params.type, |
| 3833 params.sourceCapabilities); |
3774 | 3834 |
3775 if (m_focusedElement != newFocusedElement) { | 3835 if (m_focusedElement != newFocusedElement) { |
3776 // handler shifted focus | 3836 // handler shifted focus |
3777 focusChangeBlocked = true; | 3837 focusChangeBlocked = true; |
3778 goto SetFocusedElementDone; | 3838 goto SetFocusedElementDone; |
3779 } | 3839 } |
3780 | 3840 |
3781 // FIXME: We should remove firing DOMFocusInEvent event when we are sure n
o content depends | 3841 // For DOM level 2 compatibility. |
3782 // on it, probably when <rdar://problem/8503958> is m. | 3842 // FIXME: We should remove firing DOMFocusInEvent event when we are sure |
3783 m_focusedElement->dispatchFocusInEvent( | 3843 // no content depends on it, probably when <rdar://problem/8503958> is m. |
3784 EventTypeNames::DOMFocusIn, oldFocusedElement, params.type, | 3844 m_focusedElement->dispatchFocusInEvent(EventTypeNames::DOMFocusIn, |
3785 params.sourceCapabilities); // DOM level 2 for compatibility. | 3845 oldFocusedElement, params.type, |
| 3846 params.sourceCapabilities); |
3786 | 3847 |
3787 if (m_focusedElement != newFocusedElement) { | 3848 if (m_focusedElement != newFocusedElement) { |
3788 // handler shifted focus | 3849 // handler shifted focus |
3789 focusChangeBlocked = true; | 3850 focusChangeBlocked = true; |
3790 goto SetFocusedElementDone; | 3851 goto SetFocusedElementDone; |
3791 } | 3852 } |
3792 } | 3853 } |
3793 | 3854 |
3794 if (isRootEditableElement(*m_focusedElement)) | 3855 if (isRootEditableElement(*m_focusedElement)) |
3795 frame()->spellChecker().didBeginEditing(m_focusedElement.get()); | 3856 frame()->spellChecker().didBeginEditing(m_focusedElement.get()); |
(...skipping 11 matching lines...) Expand all Loading... |
3807 focusWidget = widgetForElement(*m_focusedElement); | 3868 focusWidget = widgetForElement(*m_focusedElement); |
3808 } | 3869 } |
3809 if (focusWidget) | 3870 if (focusWidget) |
3810 focusWidget->setFocus(true, params.type); | 3871 focusWidget->setFocus(true, params.type); |
3811 else | 3872 else |
3812 view()->setFocus(true, params.type); | 3873 view()->setFocus(true, params.type); |
3813 } | 3874 } |
3814 } | 3875 } |
3815 | 3876 |
3816 if (!focusChangeBlocked && m_focusedElement) { | 3877 if (!focusChangeBlocked && m_focusedElement) { |
3817 // Create the AXObject cache in a focus change because Chromium relies on it
. | 3878 // Create the AXObject cache in a focus change because Chromium relies on |
| 3879 // it. |
3818 if (AXObjectCache* cache = axObjectCache()) | 3880 if (AXObjectCache* cache = axObjectCache()) |
3819 cache->handleFocusedUIElementChanged(oldFocusedElement, | 3881 cache->handleFocusedUIElementChanged(oldFocusedElement, |
3820 newFocusedElement); | 3882 newFocusedElement); |
3821 } | 3883 } |
3822 | 3884 |
3823 if (!focusChangeBlocked && frameHost()) | 3885 if (!focusChangeBlocked && frameHost()) |
3824 frameHost()->chromeClient().focusedNodeChanged(oldFocusedElement, | 3886 frameHost()->chromeClient().focusedNodeChanged(oldFocusedElement, |
3825 m_focusedElement.get()); | 3887 m_focusedElement.get()); |
3826 | 3888 |
3827 SetFocusedElementDone: | 3889 SetFocusedElementDone: |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3922 void Document::unregisterNodeListWithIdNameCache(const LiveNodeListBase* list) { | 3984 void Document::unregisterNodeListWithIdNameCache(const LiveNodeListBase* list) { |
3923 DCHECK(m_nodeLists[InvalidateOnIdNameAttrChange].contains(list)); | 3985 DCHECK(m_nodeLists[InvalidateOnIdNameAttrChange].contains(list)); |
3924 m_nodeLists[InvalidateOnIdNameAttrChange].remove(list); | 3986 m_nodeLists[InvalidateOnIdNameAttrChange].remove(list); |
3925 } | 3987 } |
3926 | 3988 |
3927 void Document::attachNodeIterator(NodeIterator* ni) { | 3989 void Document::attachNodeIterator(NodeIterator* ni) { |
3928 m_nodeIterators.add(ni); | 3990 m_nodeIterators.add(ni); |
3929 } | 3991 } |
3930 | 3992 |
3931 void Document::detachNodeIterator(NodeIterator* ni) { | 3993 void Document::detachNodeIterator(NodeIterator* ni) { |
3932 // The node iterator can be detached without having been attached if its root
node didn't have a document | 3994 // The node iterator can be detached without having been attached if its root |
3933 // when the iterator was created, but has it now. | 3995 // node didn't have a document when the iterator was created, but has it now. |
3934 m_nodeIterators.remove(ni); | 3996 m_nodeIterators.remove(ni); |
3935 } | 3997 } |
3936 | 3998 |
3937 void Document::moveNodeIteratorsToNewDocument(Node& node, | 3999 void Document::moveNodeIteratorsToNewDocument(Node& node, |
3938 Document& newDocument) { | 4000 Document& newDocument) { |
3939 HeapHashSet<WeakMember<NodeIterator>> nodeIteratorsList = m_nodeIterators; | 4001 HeapHashSet<WeakMember<NodeIterator>> nodeIteratorsList = m_nodeIterators; |
3940 for (NodeIterator* ni : nodeIteratorsList) { | 4002 for (NodeIterator* ni : nodeIteratorsList) { |
3941 if (ni->root() == node) { | 4003 if (ni->root() == node) { |
3942 detachNodeIterator(ni); | 4004 detachNodeIterator(ni); |
3943 newDocument.attachNodeIterator(ni); | 4005 newDocument.attachNodeIterator(ni); |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4063 | 4125 |
4064 void Document::enqueueAnimationFrameEvent(Event* event) { | 4126 void Document::enqueueAnimationFrameEvent(Event* event) { |
4065 ensureScriptedAnimationController().enqueueEvent(event); | 4127 ensureScriptedAnimationController().enqueueEvent(event); |
4066 } | 4128 } |
4067 | 4129 |
4068 void Document::enqueueUniqueAnimationFrameEvent(Event* event) { | 4130 void Document::enqueueUniqueAnimationFrameEvent(Event* event) { |
4069 ensureScriptedAnimationController().enqueuePerFrameEvent(event); | 4131 ensureScriptedAnimationController().enqueuePerFrameEvent(event); |
4070 } | 4132 } |
4071 | 4133 |
4072 void Document::enqueueScrollEventForNode(Node* target) { | 4134 void Document::enqueueScrollEventForNode(Node* target) { |
4073 // Per the W3C CSSOM View Module only scroll events fired at the document shou
ld bubble. | 4135 // Per the W3C CSSOM View Module only scroll events fired at the document |
| 4136 // should bubble. |
4074 Event* scrollEvent = target->isDocumentNode() | 4137 Event* scrollEvent = target->isDocumentNode() |
4075 ? Event::createBubble(EventTypeNames::scroll) | 4138 ? Event::createBubble(EventTypeNames::scroll) |
4076 : Event::create(EventTypeNames::scroll); | 4139 : Event::create(EventTypeNames::scroll); |
4077 scrollEvent->setTarget(target); | 4140 scrollEvent->setTarget(target); |
4078 ensureScriptedAnimationController().enqueuePerFrameEvent(scrollEvent); | 4141 ensureScriptedAnimationController().enqueuePerFrameEvent(scrollEvent); |
4079 } | 4142 } |
4080 | 4143 |
4081 void Document::enqueueResizeEvent() { | 4144 void Document::enqueueResizeEvent() { |
4082 Event* event = Event::create(EventTypeNames::resize); | 4145 Event* event = Event::create(EventTypeNames::resize); |
4083 event->setTarget(domWindow()); | 4146 event->setTarget(domWindow()); |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4185 eventType == EventTypeNames::transitionend) { | 4248 eventType == EventTypeNames::transitionend) { |
4186 addListenerType(TRANSITIONEND_LISTENER); | 4249 addListenerType(TRANSITIONEND_LISTENER); |
4187 } else if (eventType == EventTypeNames::scroll) { | 4250 } else if (eventType == EventTypeNames::scroll) { |
4188 addListenerType(SCROLL_LISTENER); | 4251 addListenerType(SCROLL_LISTENER); |
4189 } | 4252 } |
4190 } | 4253 } |
4191 | 4254 |
4192 HTMLFrameOwnerElement* Document::localOwner() const { | 4255 HTMLFrameOwnerElement* Document::localOwner() const { |
4193 if (!frame()) | 4256 if (!frame()) |
4194 return 0; | 4257 return 0; |
4195 // FIXME: This probably breaks the attempts to layout after a load is finished
in implicitClose(), and probably tons of other things... | 4258 // FIXME: This probably breaks the attempts to layout after a load is finished |
| 4259 // in implicitClose(), and probably tons of other things... |
4196 return frame()->deprecatedLocalOwner(); | 4260 return frame()->deprecatedLocalOwner(); |
4197 } | 4261 } |
4198 | 4262 |
4199 bool Document::isInInvisibleSubframe() const { | 4263 bool Document::isInInvisibleSubframe() const { |
4200 if (!localOwner()) | 4264 if (!localOwner()) |
4201 return false; // this is a local root element | 4265 return false; // this is a local root element |
4202 | 4266 |
4203 // TODO(bokan): This looks like it doesn't work in OOPIF. | 4267 // TODO(bokan): This looks like it doesn't work in OOPIF. |
4204 DCHECK(frame()); | 4268 DCHECK(frame()); |
4205 return frame()->ownerLayoutItem().isNull(); | 4269 return frame()->ownerLayoutItem().isNull(); |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4358 // TODO(mkwst): This doesn't properly handle HTML Import documents. | 4422 // TODO(mkwst): This doesn't properly handle HTML Import documents. |
4359 | 4423 |
4360 // If this is an imported document, grab its master document's first-party: | 4424 // If this is an imported document, grab its master document's first-party: |
4361 if (importsController() && importsController()->master() && | 4425 if (importsController() && importsController()->master() && |
4362 importsController()->master() != this) | 4426 importsController()->master() != this) |
4363 return importsController()->master()->firstPartyForCookies(); | 4427 return importsController()->master()->firstPartyForCookies(); |
4364 | 4428 |
4365 if (!frame()) | 4429 if (!frame()) |
4366 return SecurityOrigin::urlWithUniqueSecurityOrigin(); | 4430 return SecurityOrigin::urlWithUniqueSecurityOrigin(); |
4367 | 4431 |
4368 // TODO(mkwst): This doesn't correctly handle sandboxed documents; we want to
look at their URL, | 4432 // TODO(mkwst): This doesn't correctly handle sandboxed documents; we want to |
4369 // but we can't because we don't know what it is. | 4433 // look at their URL, but we can't because we don't know what it is. |
4370 Frame* top = frame()->tree().top(); | 4434 Frame* top = frame()->tree().top(); |
4371 KURL topDocumentURL = | 4435 KURL topDocumentURL = |
4372 top->isLocalFrame() | 4436 top->isLocalFrame() |
4373 ? toLocalFrame(top)->document()->url() | 4437 ? toLocalFrame(top)->document()->url() |
4374 : KURL(KURL(), | 4438 : KURL(KURL(), |
4375 top->securityContext()->getSecurityOrigin()->toString()); | 4439 top->securityContext()->getSecurityOrigin()->toString()); |
4376 if (SchemeRegistry::shouldTreatURLSchemeAsFirstPartyWhenTopLevel( | 4440 if (SchemeRegistry::shouldTreatURLSchemeAsFirstPartyWhenTopLevel( |
4377 topDocumentURL.protocol())) | 4441 topDocumentURL.protocol())) |
4378 return topDocumentURL; | 4442 return topDocumentURL; |
4379 | 4443 |
4380 // We're intentionally using the URL of each document rather than the document
's SecurityOrigin. | 4444 // We're intentionally using the URL of each document rather than the |
4381 // Sandboxing a document into a unique origin shouldn't effect first-/third-pa
rty status for | 4445 // document's SecurityOrigin. Sandboxing a document into a unique origin |
4382 // cookies and site data. | 4446 // shouldn't effect first-/third-party status for cookies and site data. |
4383 const OriginAccessEntry& accessEntry = | 4447 const OriginAccessEntry& accessEntry = |
4384 top->isLocalFrame() | 4448 top->isLocalFrame() |
4385 ? toLocalFrame(top)->document()->accessEntryFromURL() | 4449 ? toLocalFrame(top)->document()->accessEntryFromURL() |
4386 : OriginAccessEntry(topDocumentURL.protocol(), topDocumentURL.host(), | 4450 : OriginAccessEntry(topDocumentURL.protocol(), topDocumentURL.host(), |
4387 OriginAccessEntry::AllowRegisterableDomains); | 4451 OriginAccessEntry::AllowRegisterableDomains); |
4388 const Frame* currentFrame = frame(); | 4452 const Frame* currentFrame = frame(); |
4389 while (currentFrame) { | 4453 while (currentFrame) { |
4390 // Skip over srcdoc documents, as they are always same-origin with their clo
sest non-srcdoc parent. | 4454 // Skip over srcdoc documents, as they are always same-origin with their |
| 4455 // closest non-srcdoc parent. |
4391 while (currentFrame->isLocalFrame() && | 4456 while (currentFrame->isLocalFrame() && |
4392 toLocalFrame(currentFrame)->document()->isSrcdocDocument()) | 4457 toLocalFrame(currentFrame)->document()->isSrcdocDocument()) |
4393 currentFrame = currentFrame->tree().parent(); | 4458 currentFrame = currentFrame->tree().parent(); |
4394 DCHECK(currentFrame); | 4459 DCHECK(currentFrame); |
4395 | 4460 |
4396 // We use 'matchesDomain' here, as it turns out that some folks embed HTTPS
login forms | 4461 // We use 'matchesDomain' here, as it turns out that some folks embed HTTPS |
| 4462 // login forms |
4397 // into HTTP pages; we should allow this kind of upgrade. | 4463 // into HTTP pages; we should allow this kind of upgrade. |
4398 if (accessEntry.matchesDomain( | 4464 if (accessEntry.matchesDomain( |
4399 *currentFrame->securityContext()->getSecurityOrigin()) == | 4465 *currentFrame->securityContext()->getSecurityOrigin()) == |
4400 OriginAccessEntry::DoesNotMatchOrigin) | 4466 OriginAccessEntry::DoesNotMatchOrigin) |
4401 return SecurityOrigin::urlWithUniqueSecurityOrigin(); | 4467 return SecurityOrigin::urlWithUniqueSecurityOrigin(); |
4402 | 4468 |
4403 currentFrame = currentFrame->tree().parent(); | 4469 currentFrame = currentFrame->tree().parent(); |
4404 } | 4470 } |
4405 | 4471 |
4406 return topDocumentURL; | 4472 return topDocumentURL; |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4581 | 4647 |
4582 if (returnValue.status == QNInvalidStartChar || | 4648 if (returnValue.status == QNInvalidStartChar || |
4583 returnValue.status == QNInvalidChar) | 4649 returnValue.status == QNInvalidChar) |
4584 exceptionState.throwDOMException(InvalidCharacterError, message.toString()); | 4650 exceptionState.throwDOMException(InvalidCharacterError, message.toString()); |
4585 else | 4651 else |
4586 exceptionState.throwDOMException(NamespaceError, message.toString()); | 4652 exceptionState.throwDOMException(NamespaceError, message.toString()); |
4587 return false; | 4653 return false; |
4588 } | 4654 } |
4589 | 4655 |
4590 void Document::setEncodingData(const DocumentEncodingData& newData) { | 4656 void Document::setEncodingData(const DocumentEncodingData& newData) { |
4591 // It's possible for the encoding of the document to change while we're decodi
ng | 4657 // It's possible for the encoding of the document to change while we're |
4592 // data. That can only occur while we're processing the <head> portion of the | 4658 // decoding data. That can only occur while we're processing the <head> |
4593 // document. There isn't much user-visible content in the <head>, but there is | 4659 // portion of the document. There isn't much user-visible content in the |
4594 // the <title> element. This function detects that situation and re-decodes th
e | 4660 // <head>, but there is the <title> element. This function detects that |
4595 // document's title so that the user doesn't see an incorrectly decoded title | 4661 // situation and re-decodes the document's title so that the user doesn't see |
4596 // in the title bar. | 4662 // an incorrectly decoded title in the title bar. |
4597 if (m_titleElement && encoding() != newData.encoding() && | 4663 if (m_titleElement && encoding() != newData.encoding() && |
4598 !ElementTraversal::firstWithin(*m_titleElement) && | 4664 !ElementTraversal::firstWithin(*m_titleElement) && |
4599 encoding() == Latin1Encoding() && | 4665 encoding() == Latin1Encoding() && |
4600 m_titleElement->textContent().containsOnlyLatin1()) { | 4666 m_titleElement->textContent().containsOnlyLatin1()) { |
4601 CString originalBytes = m_titleElement->textContent().latin1(); | 4667 CString originalBytes = m_titleElement->textContent().latin1(); |
4602 std::unique_ptr<TextCodec> codec = newTextCodec(newData.encoding()); | 4668 std::unique_ptr<TextCodec> codec = newTextCodec(newData.encoding()); |
4603 String correctlyDecodedTitle = | 4669 String correctlyDecodedTitle = |
4604 codec->decode(originalBytes.data(), originalBytes.length(), DataEOF); | 4670 codec->decode(originalBytes.data(), originalBytes.length(), DataEOF); |
4605 m_titleElement->setTextContent(correctlyDecodedTitle); | 4671 m_titleElement->setTextContent(correctlyDecodedTitle); |
4606 } | 4672 } |
4607 | 4673 |
4608 DCHECK(newData.encoding().isValid()); | 4674 DCHECK(newData.encoding().isValid()); |
4609 m_encodingData = newData; | 4675 m_encodingData = newData; |
4610 | 4676 |
4611 // FIXME: Should be removed as part of https://code.google.com/p/chromium/issu
es/detail?id=319643 | 4677 // FIXME: Should be removed as part of |
| 4678 // https://code.google.com/p/chromium/issues/detail?id=319643 |
4612 bool shouldUseVisualOrdering = m_encodingData.encoding().usesVisualOrdering(); | 4679 bool shouldUseVisualOrdering = m_encodingData.encoding().usesVisualOrdering(); |
4613 if (shouldUseVisualOrdering != m_visuallyOrdered) { | 4680 if (shouldUseVisualOrdering != m_visuallyOrdered) { |
4614 m_visuallyOrdered = shouldUseVisualOrdering; | 4681 m_visuallyOrdered = shouldUseVisualOrdering; |
4615 // FIXME: How is possible to not have a layoutObject here? | 4682 // FIXME: How is possible to not have a layoutObject here? |
4616 if (!layoutViewItem().isNull()) | 4683 if (!layoutViewItem().isNull()) |
4617 layoutViewItem().mutableStyleRef().setRTLOrdering( | 4684 layoutViewItem().mutableStyleRef().setRTLOrdering( |
4618 m_visuallyOrdered ? VisualOrder : LogicalOrder); | 4685 m_visuallyOrdered ? VisualOrder : LogicalOrder); |
4619 setNeedsStyleRecalc(SubtreeStyleChange, | 4686 setNeedsStyleRecalc(SubtreeStyleChange, |
4620 StyleChangeReasonForTracing::create( | 4687 StyleChangeReasonForTracing::create( |
4621 StyleChangeReason::VisuallyOrdered)); | 4688 StyleChangeReason::VisuallyOrdered)); |
4622 } | 4689 } |
4623 } | 4690 } |
4624 | 4691 |
4625 KURL Document::completeURL(const String& url) const { | 4692 KURL Document::completeURL(const String& url) const { |
4626 return completeURLWithOverride(url, m_baseURL); | 4693 return completeURLWithOverride(url, m_baseURL); |
4627 } | 4694 } |
4628 | 4695 |
4629 KURL Document::completeURLWithOverride(const String& url, | 4696 KURL Document::completeURLWithOverride(const String& url, |
4630 const KURL& baseURLOverride) const { | 4697 const KURL& baseURLOverride) const { |
4631 DCHECK(baseURLOverride.isEmpty() || baseURLOverride.isValid()); | 4698 DCHECK(baseURLOverride.isEmpty() || baseURLOverride.isValid()); |
4632 | 4699 |
4633 // Always return a null URL when passed a null string. | 4700 // Always return a null URL when passed a null string. |
4634 // FIXME: Should we change the KURL constructor to have this behavior? | 4701 // FIXME: Should we change the KURL constructor to have this behavior? |
4635 // See also [CSS]StyleSheet::completeURL(const String&) | 4702 // See also [CSS]StyleSheet::completeURL(const String&) |
4636 if (url.isNull()) | 4703 if (url.isNull()) |
4637 return KURL(); | 4704 return KURL(); |
4638 // This logic is deliberately spread over many statements in an attempt to tra
ck down http://crbug.com/312410. | 4705 // This logic is deliberately spread over many statements in an attempt to |
| 4706 // track down http://crbug.com/312410. |
4639 const KURL& baseURL = baseURLForOverride(baseURLOverride); | 4707 const KURL& baseURL = baseURLForOverride(baseURLOverride); |
4640 if (!encoding().isValid()) | 4708 if (!encoding().isValid()) |
4641 return KURL(baseURL, url); | 4709 return KURL(baseURL, url); |
4642 return KURL(baseURL, url, encoding()); | 4710 return KURL(baseURL, url, encoding()); |
4643 } | 4711 } |
4644 | 4712 |
4645 const KURL& Document::baseURLForOverride(const KURL& baseURLOverride) const { | 4713 const KURL& Document::baseURLForOverride(const KURL& baseURLOverride) const { |
4646 // This logic is deliberately spread over many statements in an attempt to tra
ck down http://crbug.com/312410. | 4714 // This logic is deliberately spread over many statements in an attempt to |
| 4715 // track down http://crbug.com/312410. |
4647 const KURL* baseURLFromParent = 0; | 4716 const KURL* baseURLFromParent = 0; |
4648 bool shouldUseParentBaseURL = baseURLOverride.isEmpty(); | 4717 bool shouldUseParentBaseURL = baseURLOverride.isEmpty(); |
4649 if (!shouldUseParentBaseURL) { | 4718 if (!shouldUseParentBaseURL) { |
4650 const KURL& aboutBlankURL = blankURL(); | 4719 const KURL& aboutBlankURL = blankURL(); |
4651 shouldUseParentBaseURL = (baseURLOverride == aboutBlankURL); | 4720 shouldUseParentBaseURL = (baseURLOverride == aboutBlankURL); |
4652 } | 4721 } |
4653 if (shouldUseParentBaseURL) { | 4722 if (shouldUseParentBaseURL) { |
4654 if (Document* parent = parentDocument()) | 4723 if (Document* parent = parentDocument()) |
4655 baseURLFromParent = &parent->baseURL(); | 4724 baseURLFromParent = &parent->baseURL(); |
4656 } | 4725 } |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4862 Document* Document::parentDocument() const { | 4931 Document* Document::parentDocument() const { |
4863 if (!m_frame) | 4932 if (!m_frame) |
4864 return 0; | 4933 return 0; |
4865 Frame* parent = m_frame->tree().parent(); | 4934 Frame* parent = m_frame->tree().parent(); |
4866 if (!parent || !parent->isLocalFrame()) | 4935 if (!parent || !parent->isLocalFrame()) |
4867 return 0; | 4936 return 0; |
4868 return toLocalFrame(parent)->document(); | 4937 return toLocalFrame(parent)->document(); |
4869 } | 4938 } |
4870 | 4939 |
4871 Document& Document::topDocument() const { | 4940 Document& Document::topDocument() const { |
4872 // FIXME: Not clear what topDocument() should do in the OOPI case--should it r
eturn the topmost | 4941 // FIXME: Not clear what topDocument() should do in the OOPI case--should it |
4873 // available Document, or something else? | 4942 // return the topmost available Document, or something else? |
4874 Document* doc = const_cast<Document*>(this); | 4943 Document* doc = const_cast<Document*>(this); |
4875 for (HTMLFrameOwnerElement* element = doc->localOwner(); element; | 4944 for (HTMLFrameOwnerElement* element = doc->localOwner(); element; |
4876 element = doc->localOwner()) | 4945 element = doc->localOwner()) |
4877 doc = &element->document(); | 4946 doc = &element->document(); |
4878 | 4947 |
4879 DCHECK(doc); | 4948 DCHECK(doc); |
4880 return *doc; | 4949 return *doc; |
4881 } | 4950 } |
4882 | 4951 |
4883 Document* Document::contextDocument() { | 4952 Document* Document::contextDocument() { |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4977 return ensureCachedCollection<DocumentNameCollection>(DocumentNamedItems, | 5046 return ensureCachedCollection<DocumentNameCollection>(DocumentNamedItems, |
4978 name); | 5047 name); |
4979 } | 5048 } |
4980 | 5049 |
4981 void Document::finishedParsing() { | 5050 void Document::finishedParsing() { |
4982 DCHECK(!scriptableDocumentParser() || !m_parser->isParsing()); | 5051 DCHECK(!scriptableDocumentParser() || !m_parser->isParsing()); |
4983 DCHECK(!scriptableDocumentParser() || m_readyState != Loading); | 5052 DCHECK(!scriptableDocumentParser() || m_readyState != Loading); |
4984 setParsingState(InDOMContentLoaded); | 5053 setParsingState(InDOMContentLoaded); |
4985 DocumentParserTiming::from(*this).markParserStop(); | 5054 DocumentParserTiming::from(*this).markParserStop(); |
4986 | 5055 |
4987 // FIXME: DOMContentLoaded is dispatched synchronously, but this should be dis
patched in a queued task, | 5056 // FIXME: DOMContentLoaded is dispatched synchronously, but this should be |
4988 // See https://crbug.com/425790 | 5057 // dispatched in a queued task, see https://crbug.com/425790 |
4989 if (!m_documentTiming.domContentLoadedEventStart()) | 5058 if (!m_documentTiming.domContentLoadedEventStart()) |
4990 m_documentTiming.markDomContentLoadedEventStart(); | 5059 m_documentTiming.markDomContentLoadedEventStart(); |
4991 dispatchEvent(Event::createBubble(EventTypeNames::DOMContentLoaded)); | 5060 dispatchEvent(Event::createBubble(EventTypeNames::DOMContentLoaded)); |
4992 if (!m_documentTiming.domContentLoadedEventEnd()) | 5061 if (!m_documentTiming.domContentLoadedEventEnd()) |
4993 m_documentTiming.markDomContentLoadedEventEnd(); | 5062 m_documentTiming.markDomContentLoadedEventEnd(); |
4994 setParsingState(FinishedParsing); | 5063 setParsingState(FinishedParsing); |
4995 | 5064 |
4996 // Ensure Custom Element callbacks are drained before DOMContentLoaded. | 5065 // Ensure Custom Element callbacks are drained before DOMContentLoaded. |
4997 // FIXME: Remove this ad-hoc checkpoint when DOMContentLoaded is dispatched in
a | 5066 // FIXME: Remove this ad-hoc checkpoint when DOMContentLoaded is dispatched in |
4998 // queued task, which will do a checkpoint anyway. https://crbug.com/425790 | 5067 // a queued task, which will do a checkpoint anyway. https://crbug.com/425790 |
4999 Microtask::performCheckpoint(V8PerIsolateData::mainThreadIsolate()); | 5068 Microtask::performCheckpoint(V8PerIsolateData::mainThreadIsolate()); |
5000 | 5069 |
5001 if (LocalFrame* frame = this->frame()) { | 5070 if (LocalFrame* frame = this->frame()) { |
5002 // Don't update the layout tree if we haven't requested the main resource ye
t to avoid | 5071 // Don't update the layout tree if we haven't requested the main resource |
5003 // adding extra latency. Note that the first layout tree update can be expen
sive since it | 5072 // yet to avoid adding extra latency. Note that the first layout tree update |
5004 // triggers the parsing of the default stylesheets which are compiled-in. | 5073 // can be expensive since it triggers the parsing of the default stylesheets |
| 5074 // which are compiled-in. |
5005 const bool mainResourceWasAlreadyRequested = | 5075 const bool mainResourceWasAlreadyRequested = |
5006 frame->loader().stateMachine()->committedFirstRealDocumentLoad(); | 5076 frame->loader().stateMachine()->committedFirstRealDocumentLoad(); |
5007 | 5077 |
5008 // FrameLoader::finishedParsing() might end up calling Document::implicitClo
se() if all | 5078 // FrameLoader::finishedParsing() might end up calling |
5009 // resource loads are complete. HTMLObjectElements can start loading their r
esources from | 5079 // Document::implicitClose() if all resource loads are |
5010 // post attach callbacks triggered by recalcStyle(). This means if we parse
out an <object> | 5080 // complete. HTMLObjectElements can start loading their resources from post |
5011 // tag and then reach the end of the document without updating styles, we mi
ght not have yet | 5081 // attach callbacks triggered by recalcStyle(). This means if we parse out |
5012 // started the resource load and might fire the window load event too early.
To avoid this | 5082 // an <object> tag and then reach the end of the document without updating |
5013 // we force the styles to be up to date before calling FrameLoader::finished
Parsing(). | 5083 // styles, we might not have yet started the resource load and might fire |
5014 // See https://bugs.webkit.org/show_bug.cgi?id=36864 starting around comment
35. | 5084 // the window load event too early. To avoid this we force the styles to be |
| 5085 // up to date before calling FrameLoader::finishedParsing(). See |
| 5086 // https://bugs.webkit.org/show_bug.cgi?id=36864 starting around comment 35. |
5015 if (mainResourceWasAlreadyRequested) | 5087 if (mainResourceWasAlreadyRequested) |
5016 updateStyleAndLayoutTree(); | 5088 updateStyleAndLayoutTree(); |
5017 | 5089 |
5018 beginLifecycleUpdatesIfRenderingReady(); | 5090 beginLifecycleUpdatesIfRenderingReady(); |
5019 | 5091 |
5020 frame->loader().finishedParsing(); | 5092 frame->loader().finishedParsing(); |
5021 | 5093 |
5022 TRACE_EVENT_INSTANT1("devtools.timeline", "MarkDOMContent", | 5094 TRACE_EVENT_INSTANT1("devtools.timeline", "MarkDOMContent", |
5023 TRACE_EVENT_SCOPE_THREAD, "data", | 5095 TRACE_EVENT_SCOPE_THREAD, "data", |
5024 InspectorMarkLoadEvent::data(frame)); | 5096 InspectorMarkLoadEvent::data(frame)); |
5025 InspectorInstrumentation::domContentLoadedEventFired(frame); | 5097 InspectorInstrumentation::domContentLoadedEventFired(frame); |
5026 } | 5098 } |
5027 | 5099 |
5028 // Schedule dropping of the ElementDataCache. We keep it alive for a while aft
er parsing finishes | 5100 // Schedule dropping of the ElementDataCache. We keep it alive for a while |
5029 // so that dynamically inserted content can also benefit from sharing optimiza
tions. | 5101 // after parsing finishes so that dynamically inserted content can also |
5030 // Note that we don't refresh the timer on cache access since that could lead
to huge caches being kept | 5102 // benefit from sharing optimizations. Note that we don't refresh the timer |
5031 // alive indefinitely by something innocuous like JS setting .innerHTML repeat
edly on a timer. | 5103 // on cache access since that could lead to huge caches being kept alive |
| 5104 // indefinitely by something innocuous like JS setting .innerHTML repeatedly |
| 5105 // on a timer. |
5032 m_elementDataCacheClearTimer.startOneShot(10, BLINK_FROM_HERE); | 5106 m_elementDataCacheClearTimer.startOneShot(10, BLINK_FROM_HERE); |
5033 | 5107 |
5034 // Parser should have picked up all preloads by now | 5108 // Parser should have picked up all preloads by now |
5035 m_fetcher->clearPreloads(ResourceFetcher::ClearSpeculativeMarkupPreloads); | 5109 m_fetcher->clearPreloads(ResourceFetcher::ClearSpeculativeMarkupPreloads); |
5036 } | 5110 } |
5037 | 5111 |
5038 void Document::elementDataCacheClearTimerFired(TimerBase*) { | 5112 void Document::elementDataCacheClearTimerFired(TimerBase*) { |
5039 m_elementDataCache.clear(); | 5113 m_elementDataCache.clear(); |
5040 } | 5114 } |
5041 | 5115 |
(...skipping 12 matching lines...) Expand all Loading... |
5054 frame->page()->chromeClient().beginLifecycleUpdates(); | 5128 frame->page()->chromeClient().beginLifecycleUpdates(); |
5055 } | 5129 } |
5056 } | 5130 } |
5057 | 5131 |
5058 Vector<IconURL> Document::iconURLs(int iconTypesMask) { | 5132 Vector<IconURL> Document::iconURLs(int iconTypesMask) { |
5059 IconURL firstFavicon; | 5133 IconURL firstFavicon; |
5060 IconURL firstTouchIcon; | 5134 IconURL firstTouchIcon; |
5061 IconURL firstTouchPrecomposedIcon; | 5135 IconURL firstTouchPrecomposedIcon; |
5062 Vector<IconURL> secondaryIcons; | 5136 Vector<IconURL> secondaryIcons; |
5063 | 5137 |
5064 // Start from the last child node so that icons seen later take precedence as
required by the spec. | 5138 // Start from the last child node so that icons seen later take precedence as |
| 5139 // required by the spec. |
5065 for (HTMLLinkElement* linkElement = | 5140 for (HTMLLinkElement* linkElement = |
5066 head() ? Traversal<HTMLLinkElement>::firstChild(*head()) : 0; | 5141 head() ? Traversal<HTMLLinkElement>::firstChild(*head()) : 0; |
5067 linkElement; | 5142 linkElement; |
5068 linkElement = Traversal<HTMLLinkElement>::nextSibling(*linkElement)) { | 5143 linkElement = Traversal<HTMLLinkElement>::nextSibling(*linkElement)) { |
5069 if (!(linkElement->getIconType() & iconTypesMask)) | 5144 if (!(linkElement->getIconType() & iconTypesMask)) |
5070 continue; | 5145 continue; |
5071 if (linkElement->href().isEmpty()) | 5146 if (linkElement->href().isEmpty()) |
5072 continue; | 5147 continue; |
5073 | 5148 |
5074 IconURL newURL(linkElement->href(), linkElement->iconSizes(), | 5149 IconURL newURL(linkElement->href(), linkElement->iconSizes(), |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5117 return color; | 5192 return color; |
5118 } | 5193 } |
5119 return Color(); | 5194 return Color(); |
5120 } | 5195 } |
5121 | 5196 |
5122 HTMLLinkElement* Document::linkManifest() const { | 5197 HTMLLinkElement* Document::linkManifest() const { |
5123 HTMLHeadElement* head = this->head(); | 5198 HTMLHeadElement* head = this->head(); |
5124 if (!head) | 5199 if (!head) |
5125 return 0; | 5200 return 0; |
5126 | 5201 |
5127 // The first link element with a manifest rel must be used. Others are ignored
. | 5202 // The first link element with a manifest rel must be used. Others are |
| 5203 // ignored. |
5128 for (HTMLLinkElement* linkElement = | 5204 for (HTMLLinkElement* linkElement = |
5129 Traversal<HTMLLinkElement>::firstChild(*head); | 5205 Traversal<HTMLLinkElement>::firstChild(*head); |
5130 linkElement; | 5206 linkElement; |
5131 linkElement = Traversal<HTMLLinkElement>::nextSibling(*linkElement)) { | 5207 linkElement = Traversal<HTMLLinkElement>::nextSibling(*linkElement)) { |
5132 if (!linkElement->relAttribute().isManifest()) | 5208 if (!linkElement->relAttribute().isManifest()) |
5133 continue; | 5209 continue; |
5134 return linkElement; | 5210 return linkElement; |
5135 } | 5211 } |
5136 | 5212 |
5137 return 0; | 5213 return 0; |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5207 // "Local" security origins (like 'file://...') are treated as having | 5283 // "Local" security origins (like 'file://...') are treated as having |
5208 // a local address space. | 5284 // a local address space. |
5209 // | 5285 // |
5210 // TODO(mkwst): It's not entirely clear that this is a good idea. | 5286 // TODO(mkwst): It's not entirely clear that this is a good idea. |
5211 setAddressSpace(WebAddressSpaceLocal); | 5287 setAddressSpace(WebAddressSpaceLocal); |
5212 } else { | 5288 } else { |
5213 setAddressSpace(WebAddressSpacePublic); | 5289 setAddressSpace(WebAddressSpacePublic); |
5214 } | 5290 } |
5215 | 5291 |
5216 if (importsController()) { | 5292 if (importsController()) { |
5217 // If this document is an HTML import, grab a reference to it's master docum
ent's Content | 5293 // If this document is an HTML import, grab a reference to it's master |
5218 // Security Policy. We don't call 'initContentSecurityPolicy' in this case,
as we can't | 5294 // document's Content Security Policy. We don't call |
5219 // rebind the master document's policy object: its ExecutionContext needs to
remain tied | 5295 // 'initContentSecurityPolicy' in this case, as we can't rebind the master |
5220 // to the master document. | 5296 // document's policy object: its ExecutionContext needs to remain tied to |
| 5297 // the master document. |
5221 setContentSecurityPolicy( | 5298 setContentSecurityPolicy( |
5222 importsController()->master()->contentSecurityPolicy()); | 5299 importsController()->master()->contentSecurityPolicy()); |
5223 } else { | 5300 } else { |
5224 initContentSecurityPolicy(); | 5301 initContentSecurityPolicy(); |
5225 } | 5302 } |
5226 | 5303 |
5227 if (getSecurityOrigin()->hasSuborigin()) | 5304 if (getSecurityOrigin()->hasSuborigin()) |
5228 enforceSuborigin(*getSecurityOrigin()->suborigin()); | 5305 enforceSuborigin(*getSecurityOrigin()->suborigin()); |
5229 | 5306 |
5230 if (Settings* settings = initializer.settings()) { | 5307 if (Settings* settings = initializer.settings()) { |
5231 if (!settings->webSecurityEnabled()) { | 5308 if (!settings->webSecurityEnabled()) { |
5232 // Web security is turned off. We should let this document access every ot
her document. This is used primary by testing | 5309 // Web security is turned off. We should let this document access every |
5233 // harnesses for web sites. | 5310 // other document. This is used primary by testing harnesses for web |
| 5311 // sites. |
5234 getSecurityOrigin()->grantUniversalAccess(); | 5312 getSecurityOrigin()->grantUniversalAccess(); |
5235 } else if (getSecurityOrigin()->isLocal()) { | 5313 } else if (getSecurityOrigin()->isLocal()) { |
5236 if (settings->allowUniversalAccessFromFileURLs()) { | 5314 if (settings->allowUniversalAccessFromFileURLs()) { |
5237 // Some clients want local URLs to have universal access, but that setti
ng is dangerous for other clients. | 5315 // Some clients want local URLs to have universal access, but that |
| 5316 // setting is dangerous for other clients. |
5238 getSecurityOrigin()->grantUniversalAccess(); | 5317 getSecurityOrigin()->grantUniversalAccess(); |
5239 } else if (!settings->allowFileAccessFromFileURLs()) { | 5318 } else if (!settings->allowFileAccessFromFileURLs()) { |
5240 // Some clients do not want local URLs to have access to other local URL
s. | 5319 // Some clients do not want local URLs to have access to other local |
| 5320 // URLs. |
5241 getSecurityOrigin()->blockLocalAccessFromLocalOrigin(); | 5321 getSecurityOrigin()->blockLocalAccessFromLocalOrigin(); |
5242 } | 5322 } |
5243 } | 5323 } |
5244 } | 5324 } |
5245 | 5325 |
5246 if (initializer.shouldTreatURLAsSrcdocDocument()) { | 5326 if (initializer.shouldTreatURLAsSrcdocDocument()) { |
5247 m_isSrcdocDocument = true; | 5327 m_isSrcdocDocument = true; |
5248 setBaseURLOverride(initializer.parentBaseURL()); | 5328 setBaseURLOverride(initializer.parentBaseURL()); |
5249 } | 5329 } |
5250 | 5330 |
(...skipping 30 matching lines...) Expand all Loading... |
5281 | 5361 |
5282 bool Document::allowInlineEventHandler(Node* node, | 5362 bool Document::allowInlineEventHandler(Node* node, |
5283 EventListener* listener, | 5363 EventListener* listener, |
5284 const String& contextURL, | 5364 const String& contextURL, |
5285 const WTF::OrdinalNumber& contextLine) { | 5365 const WTF::OrdinalNumber& contextLine) { |
5286 if (!ContentSecurityPolicy::shouldBypassMainWorld(this) && | 5366 if (!ContentSecurityPolicy::shouldBypassMainWorld(this) && |
5287 !contentSecurityPolicy()->allowInlineEventHandler( | 5367 !contentSecurityPolicy()->allowInlineEventHandler( |
5288 listener->code(), contextURL, contextLine)) | 5368 listener->code(), contextURL, contextLine)) |
5289 return false; | 5369 return false; |
5290 | 5370 |
5291 // HTML says that inline script needs browsing context to create its execution
environment. | 5371 // HTML says that inline script needs browsing context to create its execution |
| 5372 // environment. |
5292 // http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html
#event-handler-attributes | 5373 // http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html
#event-handler-attributes |
5293 // Also, if the listening node came from other document, which happens on cont
ext-less event dispatching, | 5374 // Also, if the listening node came from other document, which happens on |
5294 // we also need to ask the owner document of the node. | 5375 // context-less event dispatching, we also need to ask the owner document of |
| 5376 // the node. |
5295 LocalFrame* frame = executingFrame(); | 5377 LocalFrame* frame = executingFrame(); |
5296 if (!frame) | 5378 if (!frame) |
5297 return false; | 5379 return false; |
5298 if (!frame->script().canExecuteScripts(NotAboutToExecuteScript)) | 5380 if (!frame->script().canExecuteScripts(NotAboutToExecuteScript)) |
5299 return false; | 5381 return false; |
5300 if (node && node->document() != this && | 5382 if (node && node->document() != this && |
5301 !node->document().allowInlineEventHandler(node, listener, contextURL, | 5383 !node->document().allowInlineEventHandler(node, listener, contextURL, |
5302 contextLine)) | 5384 contextLine)) |
5303 return false; | 5385 return false; |
5304 | 5386 |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5456 lineNumber = parser->lineNumber().oneBasedInt(); | 5538 lineNumber = parser->lineNumber().oneBasedInt(); |
5457 } | 5539 } |
5458 consoleMessage = ConsoleMessage::create( | 5540 consoleMessage = ConsoleMessage::create( |
5459 consoleMessage->source(), consoleMessage->level(), | 5541 consoleMessage->source(), consoleMessage->level(), |
5460 consoleMessage->message(), | 5542 consoleMessage->message(), |
5461 SourceLocation::create(url().getString(), lineNumber, 0, nullptr)); | 5543 SourceLocation::create(url().getString(), lineNumber, 0, nullptr)); |
5462 } | 5544 } |
5463 m_frame->console().addMessage(consoleMessage); | 5545 m_frame->console().addMessage(consoleMessage); |
5464 } | 5546 } |
5465 | 5547 |
5466 // FIXME(crbug.com/305497): This should be removed after ExecutionContext-LocalD
OMWindow migration. | 5548 // FIXME(crbug.com/305497): This should be removed after |
| 5549 // ExecutionContext-LocalDOMWindow migration. |
5467 void Document::postTask(const WebTraceLocation& location, | 5550 void Document::postTask(const WebTraceLocation& location, |
5468 std::unique_ptr<ExecutionContextTask> task, | 5551 std::unique_ptr<ExecutionContextTask> task, |
5469 const String& taskNameForInstrumentation) { | 5552 const String& taskNameForInstrumentation) { |
5470 m_taskRunner->postTask(location, std::move(task), taskNameForInstrumentation); | 5553 m_taskRunner->postTask(location, std::move(task), taskNameForInstrumentation); |
5471 } | 5554 } |
5472 | 5555 |
5473 void Document::postInspectorTask(const WebTraceLocation& location, | 5556 void Document::postInspectorTask(const WebTraceLocation& location, |
5474 std::unique_ptr<ExecutionContextTask> task) { | 5557 std::unique_ptr<ExecutionContextTask> task) { |
5475 m_taskRunner->postInspectorTask(location, std::move(task)); | 5558 m_taskRunner->postInspectorTask(location, std::move(task)); |
5476 } | 5559 } |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5594 } | 5677 } |
5595 return m_loadEventDelayCount; | 5678 return m_loadEventDelayCount; |
5596 } | 5679 } |
5597 | 5680 |
5598 void Document::loadEventDelayTimerFired(TimerBase*) { | 5681 void Document::loadEventDelayTimerFired(TimerBase*) { |
5599 if (frame()) | 5682 if (frame()) |
5600 frame()->loader().checkCompleted(); | 5683 frame()->loader().checkCompleted(); |
5601 } | 5684 } |
5602 | 5685 |
5603 void Document::loadPluginsSoon() { | 5686 void Document::loadPluginsSoon() { |
5604 // FIXME: Remove this timer once we don't need to compute layout to load plugi
ns. | 5687 // FIXME: Remove this timer once we don't need to compute layout to load |
| 5688 // plugins. |
5605 if (!m_pluginLoadingTimer.isActive()) | 5689 if (!m_pluginLoadingTimer.isActive()) |
5606 m_pluginLoadingTimer.startOneShot(0, BLINK_FROM_HERE); | 5690 m_pluginLoadingTimer.startOneShot(0, BLINK_FROM_HERE); |
5607 } | 5691 } |
5608 | 5692 |
5609 void Document::pluginLoadingTimerFired(TimerBase*) { | 5693 void Document::pluginLoadingTimerFired(TimerBase*) { |
5610 updateStyleAndLayout(); | 5694 updateStyleAndLayout(); |
5611 } | 5695 } |
5612 | 5696 |
5613 ScriptedAnimationController& Document::ensureScriptedAnimationController() { | 5697 ScriptedAnimationController& Document::ensureScriptedAnimationController() { |
5614 if (!m_scriptedAnimationController) { | 5698 if (!m_scriptedAnimationController) { |
5615 m_scriptedAnimationController = ScriptedAnimationController::create(this); | 5699 m_scriptedAnimationController = ScriptedAnimationController::create(this); |
5616 // We need to make sure that we don't start up the animation controller on a
background tab, for example. | 5700 // We need to make sure that we don't start up the animation controller on a |
| 5701 // background tab, for example. |
5617 if (!page()) | 5702 if (!page()) |
5618 m_scriptedAnimationController->suspend(); | 5703 m_scriptedAnimationController->suspend(); |
5619 } | 5704 } |
5620 return *m_scriptedAnimationController; | 5705 return *m_scriptedAnimationController; |
5621 } | 5706 } |
5622 | 5707 |
5623 int Document::requestAnimationFrame(FrameRequestCallback* callback) { | 5708 int Document::requestAnimationFrame(FrameRequestCallback* callback) { |
5624 return ensureScriptedAnimationController().registerCallback(callback); | 5709 return ensureScriptedAnimationController().registerCallback(callback); |
5625 } | 5710 } |
5626 | 5711 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5658 EventTarget* target, | 5743 EventTarget* target, |
5659 int identifier, | 5744 int identifier, |
5660 double pageX, | 5745 double pageX, |
5661 double pageY, | 5746 double pageY, |
5662 double screenX, | 5747 double screenX, |
5663 double screenY, | 5748 double screenY, |
5664 double radiusX, | 5749 double radiusX, |
5665 double radiusY, | 5750 double radiusY, |
5666 float rotationAngle, | 5751 float rotationAngle, |
5667 float force) const { | 5752 float force) const { |
5668 // Match behavior from when these types were integers, and avoid surprises fro
m someone explicitly | 5753 // Match behavior from when these types were integers, and avoid surprises |
| 5754 // from someone explicitly |
5669 // passing Infinity/NaN. | 5755 // passing Infinity/NaN. |
5670 if (!std::isfinite(pageX)) | 5756 if (!std::isfinite(pageX)) |
5671 pageX = 0; | 5757 pageX = 0; |
5672 if (!std::isfinite(pageY)) | 5758 if (!std::isfinite(pageY)) |
5673 pageY = 0; | 5759 pageY = 0; |
5674 if (!std::isfinite(screenX)) | 5760 if (!std::isfinite(screenX)) |
5675 screenX = 0; | 5761 screenX = 0; |
5676 if (!std::isfinite(screenY)) | 5762 if (!std::isfinite(screenY)) |
5677 screenY = 0; | 5763 screenY = 0; |
5678 if (!std::isfinite(radiusX)) | 5764 if (!std::isfinite(radiusX)) |
5679 radiusX = 0; | 5765 radiusX = 0; |
5680 if (!std::isfinite(radiusY)) | 5766 if (!std::isfinite(radiusY)) |
5681 radiusY = 0; | 5767 radiusY = 0; |
5682 if (!std::isfinite(rotationAngle)) | 5768 if (!std::isfinite(rotationAngle)) |
5683 rotationAngle = 0; | 5769 rotationAngle = 0; |
5684 if (!std::isfinite(force)) | 5770 if (!std::isfinite(force)) |
5685 force = 0; | 5771 force = 0; |
5686 | 5772 |
5687 if (radiusX || radiusY || rotationAngle || force) | 5773 if (radiusX || radiusY || rotationAngle || force) |
5688 UseCounter::count(*this, | 5774 UseCounter::count(*this, |
5689 UseCounter::DocumentCreateTouchMoreThanSevenArguments); | 5775 UseCounter::DocumentCreateTouchMoreThanSevenArguments); |
5690 | 5776 |
5691 // FIXME: It's not clear from the documentation at | 5777 // FIXME: It's not clear from the documentation at |
5692 // http://developer.apple.com/library/safari/#documentation/UserExperience/Ref
erence/DocumentAdditionsReference/DocumentAdditions/DocumentAdditions.html | 5778 // http://developer.apple.com/library/safari/#documentation/UserExperience/Ref
erence/DocumentAdditionsReference/DocumentAdditions/DocumentAdditions.html |
5693 // when this method should throw and nor is it by inspection of iOS behavior.
It would be nice to verify any cases where it throws under iOS | 5779 // when this method should throw and nor is it by inspection of iOS behavior. |
5694 // and implement them here. See https://bugs.webkit.org/show_bug.cgi?id=47819 | 5780 // It would be nice to verify any cases where it throws under iOS and |
| 5781 // implement them here. See https://bugs.webkit.org/show_bug.cgi?id=47819 |
5695 LocalFrame* frame = window && window->isLocalDOMWindow() | 5782 LocalFrame* frame = window && window->isLocalDOMWindow() |
5696 ? blink::toLocalDOMWindow(window)->frame() | 5783 ? blink::toLocalDOMWindow(window)->frame() |
5697 : this->frame(); | 5784 : this->frame(); |
5698 return Touch::create(frame, target, identifier, FloatPoint(screenX, screenY), | 5785 return Touch::create(frame, target, identifier, FloatPoint(screenX, screenY), |
5699 FloatPoint(pageX, pageY), FloatSize(radiusX, radiusY), | 5786 FloatPoint(pageX, pageY), FloatSize(radiusX, radiusY), |
5700 rotationAngle, force, String()); | 5787 rotationAngle, force, String()); |
5701 } | 5788 } |
5702 | 5789 |
5703 TouchList* Document::createTouchList(HeapVector<Member<Touch>>& touches) const { | 5790 TouchList* Document::createTouchList(HeapVector<Member<Touch>>& touches) const { |
5704 return TouchList::adopt(touches); | 5791 return TouchList::adopt(touches); |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5806 Element* innerElementInDocument = innerElement; | 5893 Element* innerElementInDocument = innerElement; |
5807 while (innerElementInDocument && innerElementInDocument->document() != this) { | 5894 while (innerElementInDocument && innerElementInDocument->document() != this) { |
5808 innerElementInDocument->document().updateHoverActiveState( | 5895 innerElementInDocument->document().updateHoverActiveState( |
5809 request, innerElementInDocument); | 5896 request, innerElementInDocument); |
5810 innerElementInDocument = innerElementInDocument->document().localOwner(); | 5897 innerElementInDocument = innerElementInDocument->document().localOwner(); |
5811 } | 5898 } |
5812 | 5899 |
5813 updateDistribution(); | 5900 updateDistribution(); |
5814 Element* oldActiveElement = activeHoverElement(); | 5901 Element* oldActiveElement = activeHoverElement(); |
5815 if (oldActiveElement && !request.active()) { | 5902 if (oldActiveElement && !request.active()) { |
5816 // The oldActiveElement layoutObject is null, dropped on :active by setting
display: none, | 5903 // The oldActiveElement layoutObject is null, dropped on :active by setting |
5817 // for instance. We still need to clear the ActiveChain as the mouse is rele
ased. | 5904 // display: none, for instance. We still need to clear the ActiveChain as |
| 5905 // the mouse is released. |
5818 for (Node* node = oldActiveElement; node; | 5906 for (Node* node = oldActiveElement; node; |
5819 node = FlatTreeTraversal::parent(*node)) { | 5907 node = FlatTreeTraversal::parent(*node)) { |
5820 DCHECK(!node->isTextNode()); | 5908 DCHECK(!node->isTextNode()); |
5821 node->setActive(false); | 5909 node->setActive(false); |
5822 m_userActionElements.setInActiveChain(node, false); | 5910 m_userActionElements.setInActiveChain(node, false); |
5823 } | 5911 } |
5824 setActiveHoverElement(nullptr); | 5912 setActiveHoverElement(nullptr); |
5825 } else { | 5913 } else { |
5826 Element* newActiveElement = innerElementInDocument; | 5914 Element* newActiveElement = innerElementInDocument; |
5827 if (!oldActiveElement && newActiveElement && | 5915 if (!oldActiveElement && newActiveElement && |
5828 !newActiveElement->isDisabledFormControl() && request.active() && | 5916 !newActiveElement->isDisabledFormControl() && request.active() && |
5829 !request.touchMove()) { | 5917 !request.touchMove()) { |
5830 // We are setting the :active chain and freezing it. If future moves happe
n, they | 5918 // We are setting the :active chain and freezing it. If future moves |
5831 // will need to reference this chain. | 5919 // happen, they will need to reference this chain. |
5832 for (Node* node = newActiveElement; node; | 5920 for (Node* node = newActiveElement; node; |
5833 node = FlatTreeTraversal::parent(*node)) { | 5921 node = FlatTreeTraversal::parent(*node)) { |
5834 DCHECK(!node->isTextNode()); | 5922 DCHECK(!node->isTextNode()); |
5835 m_userActionElements.setInActiveChain(node, true); | 5923 m_userActionElements.setInActiveChain(node, true); |
5836 } | 5924 } |
5837 setActiveHoverElement(newActiveElement); | 5925 setActiveHoverElement(newActiveElement); |
5838 } | 5926 } |
5839 } | 5927 } |
5840 // If the mouse has just been pressed, set :active on the chain. Those (and on
ly those) | 5928 // If the mouse has just been pressed, set :active on the chain. Those (and |
5841 // nodes should remain :active until the mouse is released. | 5929 // only those) nodes should remain :active until the mouse is released. |
5842 bool allowActiveChanges = !oldActiveElement && activeHoverElement(); | 5930 bool allowActiveChanges = !oldActiveElement && activeHoverElement(); |
5843 | 5931 |
5844 // If the mouse is down and if this is a mouse move event, we want to restrict
changes in | 5932 // If the mouse is down and if this is a mouse move event, we want to restrict |
5845 // :hover/:active to only apply to elements that are in the :active chain that
we froze | 5933 // changes in :hover/:active to only apply to elements that are in the :active |
5846 // at the time the mouse went down. | 5934 // chain that we froze at the time the mouse went down. |
5847 bool mustBeInActiveChain = request.active() && request.move(); | 5935 bool mustBeInActiveChain = request.active() && request.move(); |
5848 | 5936 |
5849 Node* oldHoverNode = hoverNode(); | 5937 Node* oldHoverNode = hoverNode(); |
5850 | 5938 |
5851 // Check to see if the hovered node has changed. | 5939 // Check to see if the hovered node has changed. |
5852 // If it hasn't, we do not need to do anything. | 5940 // If it hasn't, we do not need to do anything. |
5853 Node* newHoverNode = innerElementInDocument; | 5941 Node* newHoverNode = innerElementInDocument; |
5854 while (newHoverNode && !newHoverNode->layoutObject()) | 5942 while (newHoverNode && !newHoverNode->layoutObject()) |
5855 newHoverNode = newHoverNode->parentOrShadowHostNode(); | 5943 newHoverNode = newHoverNode->parentOrShadowHostNode(); |
5856 | 5944 |
5857 // Update our current hover node. | 5945 // Update our current hover node. |
5858 setHoverNode(newHoverNode); | 5946 setHoverNode(newHoverNode); |
5859 | 5947 |
5860 // We have two different objects. Fetch their layoutObjects. | 5948 // We have two different objects. Fetch their layoutObjects. |
5861 LayoutObject* oldHoverObj = | 5949 LayoutObject* oldHoverObj = |
5862 oldHoverNode ? oldHoverNode->layoutObject() : nullptr; | 5950 oldHoverNode ? oldHoverNode->layoutObject() : nullptr; |
5863 LayoutObject* newHoverObj = | 5951 LayoutObject* newHoverObj = |
5864 newHoverNode ? newHoverNode->layoutObject() : nullptr; | 5952 newHoverNode ? newHoverNode->layoutObject() : nullptr; |
5865 | 5953 |
5866 // Locate the common ancestor layout object for the two layoutObjects. | 5954 // Locate the common ancestor layout object for the two layoutObjects. |
5867 LayoutObject* ancestor = nearestCommonHoverAncestor(oldHoverObj, newHoverObj); | 5955 LayoutObject* ancestor = nearestCommonHoverAncestor(oldHoverObj, newHoverObj); |
5868 Node* ancestorNode(ancestor ? ancestor->node() : nullptr); | 5956 Node* ancestorNode(ancestor ? ancestor->node() : nullptr); |
5869 | 5957 |
5870 HeapVector<Member<Node>, 32> nodesToRemoveFromChain; | 5958 HeapVector<Member<Node>, 32> nodesToRemoveFromChain; |
5871 HeapVector<Member<Node>, 32> nodesToAddToChain; | 5959 HeapVector<Member<Node>, 32> nodesToAddToChain; |
5872 | 5960 |
5873 if (oldHoverObj != newHoverObj) { | 5961 if (oldHoverObj != newHoverObj) { |
5874 // If the old hovered node is not nil but it's layoutObject is, it was proba
bly detached as part of the :hover style | 5962 // If the old hovered node is not nil but it's layoutObject is, it was |
5875 // (for instance by setting display:none in the :hover pseudo-class). In thi
s case, the old hovered element (and its ancestors) | 5963 // probably detached as part of the :hover style (for instance by setting |
5876 // must be updated, to ensure it's normal style is re-applied. | 5964 // display:none in the :hover pseudo-class). In this case, the old hovered |
| 5965 // element (and its ancestors) must be updated, to ensure it's normal style |
| 5966 // is re-applied. |
5877 if (oldHoverNode && !oldHoverObj) { | 5967 if (oldHoverNode && !oldHoverObj) { |
5878 for (Node& node : NodeTraversal::inclusiveAncestorsOf(*oldHoverNode)) { | 5968 for (Node& node : NodeTraversal::inclusiveAncestorsOf(*oldHoverNode)) { |
5879 if (!mustBeInActiveChain || | 5969 if (!mustBeInActiveChain || |
5880 (node.isElementNode() && toElement(node).inActiveChain())) | 5970 (node.isElementNode() && toElement(node).inActiveChain())) |
5881 nodesToRemoveFromChain.append(node); | 5971 nodesToRemoveFromChain.append(node); |
5882 } | 5972 } |
5883 } | 5973 } |
5884 | 5974 |
5885 // The old hover path only needs to be cleared up to (and not including) the
common ancestor; | 5975 // The old hover path only needs to be cleared up to (and not including) the |
| 5976 // common ancestor; |
5886 for (LayoutObject* curr = oldHoverObj; curr && curr != ancestor; | 5977 for (LayoutObject* curr = oldHoverObj; curr && curr != ancestor; |
5887 curr = curr->hoverAncestor()) { | 5978 curr = curr->hoverAncestor()) { |
5888 if (curr->node() && !curr->isText() && | 5979 if (curr->node() && !curr->isText() && |
5889 (!mustBeInActiveChain || curr->node()->inActiveChain())) | 5980 (!mustBeInActiveChain || curr->node()->inActiveChain())) |
5890 nodesToRemoveFromChain.append(curr->node()); | 5981 nodesToRemoveFromChain.append(curr->node()); |
5891 } | 5982 } |
5892 | 5983 |
5893 // TODO(mustaq): The two loops above may push a single node twice into nodes
ToRemoveFromChain. There must be a better way. | 5984 // TODO(mustaq): The two loops above may push a single node twice into |
| 5985 // nodesToRemoveFromChain. There must be a better way. |
5894 } | 5986 } |
5895 | 5987 |
5896 // Now set the hover state for our new object up to the root. | 5988 // Now set the hover state for our new object up to the root. |
5897 for (LayoutObject* curr = newHoverObj; curr; curr = curr->hoverAncestor()) { | 5989 for (LayoutObject* curr = newHoverObj; curr; curr = curr->hoverAncestor()) { |
5898 if (curr->node() && !curr->isText() && | 5990 if (curr->node() && !curr->isText() && |
5899 (!mustBeInActiveChain || curr->node()->inActiveChain())) | 5991 (!mustBeInActiveChain || curr->node()->inActiveChain())) |
5900 nodesToAddToChain.append(curr->node()); | 5992 nodesToAddToChain.append(curr->node()); |
5901 } | 5993 } |
5902 | 5994 |
5903 size_t removeCount = nodesToRemoveFromChain.size(); | 5995 size_t removeCount = nodesToRemoveFromChain.size(); |
5904 for (size_t i = 0; i < removeCount; ++i) { | 5996 for (size_t i = 0; i < removeCount; ++i) { |
5905 nodesToRemoveFromChain[i]->setHovered(false); | 5997 nodesToRemoveFromChain[i]->setHovered(false); |
5906 } | 5998 } |
5907 | 5999 |
5908 bool sawCommonAncestor = false; | 6000 bool sawCommonAncestor = false; |
5909 size_t addCount = nodesToAddToChain.size(); | 6001 size_t addCount = nodesToAddToChain.size(); |
5910 for (size_t i = 0; i < addCount; ++i) { | 6002 for (size_t i = 0; i < addCount; ++i) { |
5911 // Elements past the common ancestor do not change hover state, but might ch
ange active state. | 6003 // Elements past the common ancestor do not change hover state, but might |
| 6004 // change active state. |
5912 if (ancestorNode && nodesToAddToChain[i] == ancestorNode) | 6005 if (ancestorNode && nodesToAddToChain[i] == ancestorNode) |
5913 sawCommonAncestor = true; | 6006 sawCommonAncestor = true; |
5914 if (allowActiveChanges) | 6007 if (allowActiveChanges) |
5915 nodesToAddToChain[i]->setActive(true); | 6008 nodesToAddToChain[i]->setActive(true); |
5916 if (!sawCommonAncestor || nodesToAddToChain[i] == m_hoverNode) { | 6009 if (!sawCommonAncestor || nodesToAddToChain[i] == m_hoverNode) { |
5917 nodesToAddToChain[i]->setHovered(true); | 6010 nodesToAddToChain[i]->setHovered(true); |
5918 } | 6011 } |
5919 } | 6012 } |
5920 } | 6013 } |
5921 | 6014 |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6062 styleEngine().platformColorsChanged(); | 6155 styleEngine().platformColorsChanged(); |
6063 } | 6156 } |
6064 | 6157 |
6065 v8::Local<v8::Object> Document::wrap(v8::Isolate* isolate, | 6158 v8::Local<v8::Object> Document::wrap(v8::Isolate* isolate, |
6066 v8::Local<v8::Object> creationContext) { | 6159 v8::Local<v8::Object> creationContext) { |
6067 DCHECK(!DOMDataStore::containsWrapper(this, isolate)); | 6160 DCHECK(!DOMDataStore::containsWrapper(this, isolate)); |
6068 | 6161 |
6069 const WrapperTypeInfo* wrapperType = wrapperTypeInfo(); | 6162 const WrapperTypeInfo* wrapperType = wrapperTypeInfo(); |
6070 | 6163 |
6071 if (frame() && frame()->script().initializeMainWorld()) { | 6164 if (frame() && frame()->script().initializeMainWorld()) { |
6072 // initializeMainWorld may have created a wrapper for the object, retry from
the start. | 6165 // initializeMainWorld may have created a wrapper for the object, retry from |
| 6166 // the start. |
6073 v8::Local<v8::Object> wrapper = DOMDataStore::getWrapper(this, isolate); | 6167 v8::Local<v8::Object> wrapper = DOMDataStore::getWrapper(this, isolate); |
6074 if (!wrapper.IsEmpty()) | 6168 if (!wrapper.IsEmpty()) |
6075 return wrapper; | 6169 return wrapper; |
6076 } | 6170 } |
6077 | 6171 |
6078 v8::Local<v8::Object> wrapper = | 6172 v8::Local<v8::Object> wrapper = |
6079 V8DOMWrapper::createWrapper(isolate, creationContext, wrapperType); | 6173 V8DOMWrapper::createWrapper(isolate, creationContext, wrapperType); |
6080 DCHECK(!wrapper.IsEmpty()); | 6174 DCHECK(!wrapper.IsEmpty()); |
6081 return associateWithWrapper(isolate, wrapperType, wrapper); | 6175 return associateWithWrapper(isolate, wrapperType, wrapper); |
6082 } | 6176 } |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6275 } | 6369 } |
6276 | 6370 |
6277 void showLiveDocumentInstances() { | 6371 void showLiveDocumentInstances() { |
6278 WeakDocumentSet& set = liveDocumentSet(); | 6372 WeakDocumentSet& set = liveDocumentSet(); |
6279 fprintf(stderr, "There are %u documents currently alive:\n", set.size()); | 6373 fprintf(stderr, "There are %u documents currently alive:\n", set.size()); |
6280 for (Document* document : set) | 6374 for (Document* document : set) |
6281 fprintf(stderr, "- Document %p URL: %s\n", document, | 6375 fprintf(stderr, "- Document %p URL: %s\n", document, |
6282 document->url().getString().utf8().data()); | 6376 document->url().getString().utf8().data()); |
6283 } | 6377 } |
6284 #endif | 6378 #endif |
OLD | NEW |