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 Peter Kelly (pmk@post.com) | 4 * (C) 2001 Peter Kelly (pmk@post.com) |
5 * (C) 2001 Dirk Mueller (mueller@kde.org) | 5 * (C) 2001 Dirk Mueller (mueller@kde.org) |
6 * (C) 2007 David Smith (catfish.man@gmail.com) | 6 * (C) 2007 David Smith (catfish.man@gmail.com) |
7 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012, 2013 Apple Inc. All rights reserved. | 7 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012, 2013 Apple Inc. All rights reserved. |
8 * (C) 2007 Eric Seidel (eric@webkit.org) | 8 * (C) 2007 Eric Seidel (eric@webkit.org) |
9 * | 9 * |
10 * This library is free software; you can redistribute it and/or | 10 * This library is free software; you can redistribute it and/or |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
49 #include "core/css/resolver/StyleResolverParentScope.h" | 49 #include "core/css/resolver/StyleResolverParentScope.h" |
50 #include "core/dom/Attr.h" | 50 #include "core/dom/Attr.h" |
51 #include "core/dom/CSSSelectorWatch.h" | 51 #include "core/dom/CSSSelectorWatch.h" |
52 #include "core/dom/ClientRect.h" | 52 #include "core/dom/ClientRect.h" |
53 #include "core/dom/ClientRectList.h" | 53 #include "core/dom/ClientRectList.h" |
54 #include "core/dom/DatasetDOMStringMap.h" | 54 #include "core/dom/DatasetDOMStringMap.h" |
55 #include "core/dom/ElementDataCache.h" | 55 #include "core/dom/ElementDataCache.h" |
56 #include "core/dom/ElementRareData.h" | 56 #include "core/dom/ElementRareData.h" |
57 #include "core/dom/ElementTraversal.h" | 57 #include "core/dom/ElementTraversal.h" |
58 #include "core/dom/ExceptionCode.h" | 58 #include "core/dom/ExceptionCode.h" |
59 #include "core/dom/FirstLetterPseudoElement.h" | |
59 #include "core/dom/Fullscreen.h" | 60 #include "core/dom/Fullscreen.h" |
60 #include "core/dom/MutationObserverInterestGroup.h" | 61 #include "core/dom/MutationObserverInterestGroup.h" |
61 #include "core/dom/MutationRecord.h" | 62 #include "core/dom/MutationRecord.h" |
62 #include "core/dom/NamedNodeMap.h" | 63 #include "core/dom/NamedNodeMap.h" |
63 #include "core/dom/NodeRenderStyle.h" | 64 #include "core/dom/NodeRenderStyle.h" |
64 #include "core/dom/PresentationAttributeStyle.h" | 65 #include "core/dom/PresentationAttributeStyle.h" |
65 #include "core/dom/PseudoElement.h" | 66 #include "core/dom/PseudoElement.h" |
66 #include "core/dom/RenderTreeBuilder.h" | 67 #include "core/dom/RenderTreeBuilder.h" |
67 #include "core/dom/ScriptableDocumentParser.h" | 68 #include "core/dom/ScriptableDocumentParser.h" |
68 #include "core/dom/SelectorQuery.h" | 69 #include "core/dom/SelectorQuery.h" |
70 #include "core/dom/StyleChangeReason.h" | |
69 #include "core/dom/StyleEngine.h" | 71 #include "core/dom/StyleEngine.h" |
70 #include "core/dom/Text.h" | 72 #include "core/dom/Text.h" |
71 #include "core/dom/custom/CustomElement.h" | 73 #include "core/dom/custom/CustomElement.h" |
72 #include "core/dom/custom/CustomElementRegistrationContext.h" | 74 #include "core/dom/custom/CustomElementRegistrationContext.h" |
73 #include "core/dom/shadow/InsertionPoint.h" | 75 #include "core/dom/shadow/InsertionPoint.h" |
74 #include "core/dom/shadow/ShadowRoot.h" | 76 #include "core/dom/shadow/ShadowRoot.h" |
75 #include "core/editing/FrameSelection.h" | 77 #include "core/editing/FrameSelection.h" |
76 #include "core/editing/TextIterator.h" | 78 #include "core/editing/TextIterator.h" |
77 #include "core/editing/htmlediting.h" | 79 #include "core/editing/htmlediting.h" |
78 #include "core/editing/markup.h" | 80 #include "core/editing/markup.h" |
(...skipping 18 matching lines...) Expand all Loading... | |
97 #include "core/html/HTMLTableRowsCollection.h" | 99 #include "core/html/HTMLTableRowsCollection.h" |
98 #include "core/html/HTMLTemplateElement.h" | 100 #include "core/html/HTMLTemplateElement.h" |
99 #include "core/html/parser/HTMLParserIdioms.h" | 101 #include "core/html/parser/HTMLParserIdioms.h" |
100 #include "core/inspector/InspectorInstrumentation.h" | 102 #include "core/inspector/InspectorInstrumentation.h" |
101 #include "core/page/Chrome.h" | 103 #include "core/page/Chrome.h" |
102 #include "core/page/ChromeClient.h" | 104 #include "core/page/ChromeClient.h" |
103 #include "core/page/FocusController.h" | 105 #include "core/page/FocusController.h" |
104 #include "core/page/Page.h" | 106 #include "core/page/Page.h" |
105 #include "core/page/PointerLockController.h" | 107 #include "core/page/PointerLockController.h" |
106 #include "core/rendering/RenderLayer.h" | 108 #include "core/rendering/RenderLayer.h" |
109 #include "core/rendering/RenderTextFragment.h" | |
107 #include "core/rendering/RenderView.h" | 110 #include "core/rendering/RenderView.h" |
108 #include "core/rendering/compositing/RenderLayerCompositor.h" | 111 #include "core/rendering/compositing/RenderLayerCompositor.h" |
109 #include "core/svg/SVGDocumentExtensions.h" | 112 #include "core/svg/SVGDocumentExtensions.h" |
110 #include "core/svg/SVGElement.h" | 113 #include "core/svg/SVGElement.h" |
111 #include "platform/EventDispatchForbiddenScope.h" | 114 #include "platform/EventDispatchForbiddenScope.h" |
112 #include "platform/RuntimeEnabledFeatures.h" | 115 #include "platform/RuntimeEnabledFeatures.h" |
113 #include "platform/UserGestureIndicator.h" | 116 #include "platform/UserGestureIndicator.h" |
114 #include "platform/scroll/ScrollableArea.h" | 117 #include "platform/scroll/ScrollableArea.h" |
115 #include "wtf/BitVector.h" | 118 #include "wtf/BitVector.h" |
116 #include "wtf/HashFunctions.h" | 119 #include "wtf/HashFunctions.h" |
(...skipping 1204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1321 | 1324 |
1322 // When a shadow root exists, it does the work of attaching the children. | 1325 // When a shadow root exists, it does the work of attaching the children. |
1323 if (ElementShadow* shadow = this->shadow()) | 1326 if (ElementShadow* shadow = this->shadow()) |
1324 shadow->attach(context); | 1327 shadow->attach(context); |
1325 | 1328 |
1326 ContainerNode::attach(context); | 1329 ContainerNode::attach(context); |
1327 | 1330 |
1328 createPseudoElementIfNeeded(AFTER); | 1331 createPseudoElementIfNeeded(AFTER); |
1329 createPseudoElementIfNeeded(BACKDROP); | 1332 createPseudoElementIfNeeded(BACKDROP); |
1330 | 1333 |
1334 // We create the first-letter element after the :before, :after and | |
1335 // children are attached because the first letter text could come | |
1336 // from any of them. | |
1337 createPseudoElementIfNeeded(FIRST_LETTER); | |
1338 | |
1331 if (hasRareData() && !renderer()) { | 1339 if (hasRareData() && !renderer()) { |
1332 if (ActiveAnimations* activeAnimations = elementRareData()->activeAnimat ions()) { | 1340 if (ActiveAnimations* activeAnimations = elementRareData()->activeAnimat ions()) { |
1333 activeAnimations->cssAnimations().cancel(); | 1341 activeAnimations->cssAnimations().cancel(); |
1334 activeAnimations->setAnimationStyleChange(false); | 1342 activeAnimations->setAnimationStyleChange(false); |
1335 } | 1343 } |
1336 } | 1344 } |
1337 } | 1345 } |
1338 | 1346 |
1339 void Element::detach(const AttachContext& context) | 1347 void Element::detach(const AttachContext& context) |
1340 { | 1348 { |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1481 for (ShadowRoot* root = youngestShadowRoot(); root; root = root->old erShadowRoot()) { | 1489 for (ShadowRoot* root = youngestShadowRoot(); root; root = root->old erShadowRoot()) { |
1482 if (root->shouldCallRecalcStyle(change)) | 1490 if (root->shouldCallRecalcStyle(change)) |
1483 root->recalcStyle(change); | 1491 root->recalcStyle(change); |
1484 } | 1492 } |
1485 recalcChildStyle(change); | 1493 recalcChildStyle(change); |
1486 } | 1494 } |
1487 | 1495 |
1488 updatePseudoElement(AFTER, change); | 1496 updatePseudoElement(AFTER, change); |
1489 updatePseudoElement(BACKDROP, change); | 1497 updatePseudoElement(BACKDROP, change); |
1490 | 1498 |
1499 // If our children have changed then we need to force the first-letter | |
1500 // checks as we don't know if they effected the first letter or not. | |
1501 // This can be seen when a child transitions from floating to | |
1502 // non-floating we have to take it into account for the first letter. | |
1503 updatePseudoElement(FIRST_LETTER, childNeedsStyleRecalc() ? Force : chan ge); | |
1504 | |
1491 clearChildNeedsStyleRecalc(); | 1505 clearChildNeedsStyleRecalc(); |
1492 } | 1506 } |
1493 | 1507 |
1494 if (hasCustomStyleCallbacks()) | 1508 if (hasCustomStyleCallbacks()) |
1495 didRecalcStyle(change); | 1509 didRecalcStyle(change); |
1496 | 1510 |
1497 if (change == Reattach) | 1511 if (change == Reattach) |
1498 reattachWhitespaceSiblings(nextTextSibling); | 1512 reattachWhitespaceSiblings(nextTextSibling); |
1499 } | 1513 } |
1500 | 1514 |
(...skipping 961 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2462 // attributes while we are iterating. | 2476 // attributes while we are iterating. |
2463 WillBeHeapVector<RefPtrWillBeMember<Attr> > attrNodesCopy(*attrNodes); | 2477 WillBeHeapVector<RefPtrWillBeMember<Attr> > attrNodesCopy(*attrNodes); |
2464 for (size_t i = 0; i < attrNodesCopy.size(); ++i) | 2478 for (size_t i = 0; i < attrNodesCopy.size(); ++i) |
2465 attrNodesCopy[i]->normalize(); | 2479 attrNodesCopy[i]->normalize(); |
2466 } | 2480 } |
2467 | 2481 |
2468 void Element::updatePseudoElement(PseudoId pseudoId, StyleRecalcChange change) | 2482 void Element::updatePseudoElement(PseudoId pseudoId, StyleRecalcChange change) |
2469 { | 2483 { |
2470 ASSERT(!needsStyleRecalc()); | 2484 ASSERT(!needsStyleRecalc()); |
2471 PseudoElement* element = pseudoElement(pseudoId); | 2485 PseudoElement* element = pseudoElement(pseudoId); |
2486 | |
2472 if (element && (change == UpdatePseudoElements || element->shouldCallRecalcS tyle(change))) { | 2487 if (element && (change == UpdatePseudoElements || element->shouldCallRecalcS tyle(change))) { |
2488 if (pseudoId == FIRST_LETTER && updateFirstLetter(element)) | |
2489 return; | |
2473 | 2490 |
2474 // Need to clear the cached style if the PseudoElement wants a recalc so it | 2491 // Need to clear the cached style if the PseudoElement wants a recalc so it |
2475 // computes a new style. | 2492 // computes a new style. |
2476 if (element->needsStyleRecalc()) | 2493 if (element->needsStyleRecalc()) |
2477 renderer()->style()->removeCachedPseudoStyle(pseudoId); | 2494 renderer()->style()->removeCachedPseudoStyle(pseudoId); |
2478 | 2495 |
2479 // PseudoElement styles hang off their parent element's style so if we n eeded | 2496 // PseudoElement styles hang off their parent element's style so if we n eeded |
2480 // a style recalc we should Force one on the pseudo. | 2497 // a style recalc we should Force one on the pseudo. |
2481 // FIXME: We should figure out the right text sibling to pass. | 2498 // FIXME: We should figure out the right text sibling to pass. |
2482 element->recalcStyle(change == UpdatePseudoElements ? Force : change); | 2499 element->recalcStyle(change == UpdatePseudoElements ? Force : change); |
2483 | 2500 |
2484 // Wait until our parent is not displayed or pseudoElementRendererIsNeed ed | 2501 // Wait until our parent is not displayed or pseudoElementRendererIsNeed ed |
2485 // is false, otherwise we could continously create and destroy PseudoEle ments | 2502 // is false, otherwise we could continuously create and destroy PseudoEl ements |
2486 // when RenderObject::isChildAllowed on our parent returns false for the | 2503 // when RenderObject::isChildAllowed on our parent returns false for the |
2487 // PseudoElement's renderer for each style recalc. | 2504 // PseudoElement's renderer for each style recalc. |
2488 if (!renderer() || !pseudoElementRendererIsNeeded(renderer()->getCachedP seudoStyle(pseudoId))) | 2505 if (!renderer() || !pseudoElementRendererIsNeeded(renderer()->getCachedP seudoStyle(pseudoId))) |
2489 elementRareData()->setPseudoElement(pseudoId, nullptr); | 2506 elementRareData()->setPseudoElement(pseudoId, nullptr); |
2507 } else if (pseudoId == FIRST_LETTER && element && change >= UpdatePseudoElem ents && !FirstLetterPseudoElement::firstLetterTextRenderer(*element)) { | |
2508 // This can happen if we change to a float, for example. We need to clea nup the | |
2509 // first-letter pseudoElement and then fix the text of the original rema ining | |
2510 // text renderer. | |
2511 // This can be seen in Test 7 of fast/css/first-letter-removed-added.htm l | |
2512 elementRareData()->setPseudoElement(pseudoId, nullptr); | |
2490 } else if (change >= UpdatePseudoElements) { | 2513 } else if (change >= UpdatePseudoElements) { |
2491 createPseudoElementIfNeeded(pseudoId); | 2514 createPseudoElementIfNeeded(pseudoId); |
2492 } | 2515 } |
2493 } | 2516 } |
2494 | 2517 |
2518 // If we're updating first letter, and the current first letter renderer | |
2519 // is not the same as the one we're currently using we need to re-create | |
2520 // the first letter renderer. | |
2521 bool Element::updateFirstLetter(Element* element) | |
2522 { | |
2523 RenderObject* remainingTextRenderer = FirstLetterPseudoElement::firstLetterT extRenderer(*element); | |
2524 if (!remainingTextRenderer || remainingTextRenderer != toFirstLetterPseudoEl ement(element)->remainingTextRenderer() | |
2525 || toFirstLetterPseudoElement(element)->needsUpdate()) { | |
2526 // We have to clear out the old first letter here because when it is | |
2527 // disposed it will set the original text back on the remaining text | |
2528 // renderer. If we dispose after creating the new one we will get | |
2529 // incorrect results due to setting the first letter back. | |
Julien - ping for review
2014/11/14 19:31:00
Is there any way we can detect this with some ASSE
dsinclair
2014/11/14 20:17:39
I don't think so, the disposed element won't know
| |
2530 if (remainingTextRenderer) | |
2531 element->reattach(); | |
2532 else | |
2533 elementRareData()->setPseudoElement(FIRST_LETTER, nullptr); | |
2534 return true; | |
2535 } | |
2536 return false; | |
2537 } | |
2538 | |
2495 void Element::createPseudoElementIfNeeded(PseudoId pseudoId) | 2539 void Element::createPseudoElementIfNeeded(PseudoId pseudoId) |
2496 { | 2540 { |
2497 if (isPseudoElement()) | 2541 if (isPseudoElement()) |
2498 return; | 2542 return; |
2499 | 2543 |
2500 // Document::ensureStyleResolver is not inlined and shows up on profiles, av oid it here. | 2544 // Document::ensureStyleResolver is not inlined and shows up on profiles, av oid it here. |
2501 StyleEngine* engine = document().styleEngine(); | 2545 StyleEngine* engine = document().styleEngine(); |
2502 RefPtrWillBeRawPtr<PseudoElement> element = engine->ensureResolver().createP seudoElementIfNeeded(*this, pseudoId); | 2546 RefPtrWillBeRawPtr<PseudoElement> element = engine->ensureResolver().createP seudoElementIfNeeded(*this, pseudoId); |
2503 if (!element) | 2547 if (!element) |
2504 return; | 2548 return; |
(...skipping 746 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3251 return wrapper; | 3295 return wrapper; |
3252 | 3296 |
3253 CustomElementBinding* binding = perContextData->customElementBinding(customE lementDefinition()); | 3297 CustomElementBinding* binding = perContextData->customElementBinding(customE lementDefinition()); |
3254 | 3298 |
3255 wrapper->SetPrototype(binding->prototype()); | 3299 wrapper->SetPrototype(binding->prototype()); |
3256 | 3300 |
3257 return V8DOMWrapper::associateObjectWithWrapper(isolate, this, wrapperType, wrapper); | 3301 return V8DOMWrapper::associateObjectWithWrapper(isolate, this, wrapperType, wrapper); |
3258 } | 3302 } |
3259 | 3303 |
3260 } // namespace blink | 3304 } // namespace blink |
OLD | NEW |