diff options
Diffstat (limited to 'chromium/third_party/WebKit')
46 files changed, 549 insertions, 164 deletions
diff --git a/chromium/third_party/WebKit/Source/core/dom/ContainerNode.cpp b/chromium/third_party/WebKit/Source/core/dom/ContainerNode.cpp index 69d48678008..d48a00fe39b 100644 --- a/chromium/third_party/WebKit/Source/core/dom/ContainerNode.cpp +++ b/chromium/third_party/WebKit/Source/core/dom/ContainerNode.cpp @@ -835,8 +835,8 @@ void ContainerNode::notifyNodeInsertedInternal(Node& root, NodeVector& postInser for (Node& node : NodeTraversal::inclusiveDescendantsOf(root)) { // As an optimization we don't notify leaf nodes when when inserting - // into detached subtrees. - if (!inDocument() && !node.isContainerNode()) + // into detached subtrees that are not in a shadow tree. + if (!inDocument() && !isInShadowTree() && !node.isContainerNode()) continue; if (Node::InsertionShouldCallDidNotifySubtreeInsertions == node.insertedInto(this)) postInsertionNotificationTargets.append(&node); @@ -935,12 +935,15 @@ bool ContainerNode::getUpperLeftCorner(FloatPoint& point) const if (p->node() && p->node() == this && o->isText() && !o->isBR() && !toLayoutText(o)->hasTextBoxes()) { // Do nothing - skip unrendered whitespace that is a child or next sibling of the anchor. + // FIXME: This fails to skip a whitespace sibling when there was also a whitespace child (because p has moved). } else if ((o->isText() && !o->isBR()) || o->isReplaced()) { point = FloatPoint(); - if (o->isText() && toLayoutText(o)->firstTextBox()) { - point.move(toLayoutText(o)->linesBoundingBox().x(), toLayoutText(o)->firstTextBox()->root().lineTop().toFloat()); + if (o->isText()) { + if (toLayoutText(o)->firstTextBox()) + point.move(toLayoutText(o)->linesBoundingBox().x(), toLayoutText(o)->firstTextBox()->root().lineTop().toFloat()); point = o->localToAbsolute(point, UseTransforms); - } else if (o->isBox()) { + } else { + ASSERT(o->isBox()); LayoutBox* box = toLayoutBox(o); point.moveBy(box->location()); point = o->container()->localToAbsolute(point, UseTransforms); diff --git a/chromium/third_party/WebKit/Source/core/dom/Document.cpp b/chromium/third_party/WebKit/Source/core/dom/Document.cpp index fe2806a36f0..68fd1ca1d44 100644 --- a/chromium/third_party/WebKit/Source/core/dom/Document.cpp +++ b/chromium/third_party/WebKit/Source/core/dom/Document.cpp @@ -986,6 +986,7 @@ PassRefPtrWillBeRawPtr<Node> Document::adoptNode(PassRefPtrWillBeRawPtr<Node> so source->parentNode()->removeChild(source.get(), exceptionState); if (exceptionState.hadException()) return nullptr; + RELEASE_ASSERT(!source->parentNode()); } } @@ -1721,8 +1722,16 @@ void Document::updateLayoutTree(StyleRecalcChange change) if (!view() || !isActive()) return; - if (change != Force && !needsLayoutTreeUpdate()) + if (change != Force && !needsLayoutTreeUpdate()) { + if (lifecycle().state() < DocumentLifecycle::StyleClean) { + // needsLayoutTreeUpdate may change to false without any actual layout tree update. + // For example, needsAnimationTimingUpdate may change to false when time elapses. + // Advance lifecycle to StyleClean because style is actually clean now. + lifecycle().advanceTo(DocumentLifecycle::InStyleRecalc); + lifecycle().advanceTo(DocumentLifecycle::StyleClean); + } return; + } if (inStyleRecalc()) return; @@ -2145,7 +2154,17 @@ void Document::detach(const AttachContext& context) if (!isActive()) return; + // Frame navigation can cause a new Document to be attached. Don't allow that, since that will + // cause a situation where LocalFrame still has a Document attached after this finishes! + // Normally, it shouldn't actually be possible to trigger navigation here. However, plugins + // (see below) can cause lots of crazy things to happen, since plugin detach involves nested + // message loops. + FrameNavigationDisabler navigationDisabler(*m_frame); + // Defer widget updates to avoid plugins trying to run script inside ScriptForbiddenScope, + // which will crash the renderer after https://crrev.com/200984 HTMLFrameOwnerElement::UpdateSuspendScope suspendWidgetHierarchyUpdates; + // Don't allow script to run in the middle of detach() because a detaching Document is not in a + // consistent state. ScriptForbiddenScope forbidScript; view()->dispose(); m_markers->prepareForDestruction(); diff --git a/chromium/third_party/WebKit/Source/core/dom/Element.h b/chromium/third_party/WebKit/Source/core/dom/Element.h index 61a4cc34516..32f02125b20 100644 --- a/chromium/third_party/WebKit/Source/core/dom/Element.h +++ b/chromium/third_party/WebKit/Source/core/dom/Element.h @@ -804,7 +804,7 @@ inline Node::InsertionNotificationRequest Node::insertedInto(ContainerNode* inse { ASSERT(!childNeedsStyleInvalidation()); ASSERT(!needsStyleInvalidation()); - ASSERT(insertionPoint->inDocument() || isContainerNode()); + ASSERT(insertionPoint->inDocument() || insertionPoint->isInShadowTree() || isContainerNode()); if (insertionPoint->inDocument()) { setFlag(InDocumentFlag); insertionPoint->document().incrementNodeCount(); diff --git a/chromium/third_party/WebKit/Source/core/editing/PositionIterator.cpp b/chromium/third_party/WebKit/Source/core/editing/PositionIterator.cpp index a7b7258df5f..4943b0a9a9a 100644 --- a/chromium/third_party/WebKit/Source/core/editing/PositionIterator.cpp +++ b/chromium/third_party/WebKit/Source/core/editing/PositionIterator.cpp @@ -28,12 +28,25 @@ namespace blink { +static const int kInvalidOffset = -1; + template <typename Strategy> PositionIteratorAlgorithm<Strategy>::PositionIteratorAlgorithm(Node* anchorNode, int offsetInAnchor) : m_anchorNode(anchorNode) , m_nodeAfterPositionInAnchor(Strategy::childAt(*anchorNode, offsetInAnchor)) , m_offsetInAnchor(m_nodeAfterPositionInAnchor ? 0 : offsetInAnchor) + , m_depthToAnchorNode(0) + , m_domTreeVersion(anchorNode->document().domTreeVersion()) { + for (Node* node = Strategy::parent(*anchorNode); node; node = Strategy::parent(*node)) { + // Each m_offsetsInAnchorNode[offset] should be an index of node in + // parent, but delay to calculate the index until it is needed for + // performance. + m_offsetsInAnchorNode.append(kInvalidOffset); + ++m_depthToAnchorNode; + } + if (m_nodeAfterPositionInAnchor) + m_offsetsInAnchorNode.append(offsetInAnchor); } template <typename Strategy> PositionIteratorAlgorithm<Strategy>::PositionIteratorAlgorithm(const PositionTemplate<Strategy>& pos) @@ -46,18 +59,23 @@ PositionIteratorAlgorithm<Strategy>::PositionIteratorAlgorithm() : m_anchorNode(nullptr) , m_nodeAfterPositionInAnchor(nullptr) , m_offsetInAnchor(0) + , m_depthToAnchorNode(0) + , m_domTreeVersion(0) { } template <typename Strategy> PositionTemplate<Strategy> PositionIteratorAlgorithm<Strategy>::deprecatedComputePosition() const { + // TODO(yoichio): Share code to check domTreeVersion with EphemeralRange. + ASSERT(isValid()); if (m_nodeAfterPositionInAnchor) { ASSERT(Strategy::parent(*m_nodeAfterPositionInAnchor) == m_anchorNode); + ASSERT(m_offsetsInAnchorNode[m_depthToAnchorNode] != kInvalidOffset); // FIXME: This check is inadaquete because any ancestor could be ignored by editing if (Strategy::editingIgnoresContent(Strategy::parent(*m_nodeAfterPositionInAnchor))) return PositionTemplate<Strategy>::beforeNode(m_anchorNode); - return PositionTemplate<Strategy>::inParentBeforeNode(*m_nodeAfterPositionInAnchor); + return PositionTemplate<Strategy>(m_anchorNode, m_offsetsInAnchorNode[m_depthToAnchorNode]); } if (Strategy::hasChildren(*m_anchorNode)) return PositionTemplate<Strategy>::lastPositionInOrAfterNode(m_anchorNode); @@ -67,37 +85,100 @@ PositionTemplate<Strategy> PositionIteratorAlgorithm<Strategy>::deprecatedComput template <typename Strategy> PositionTemplate<Strategy> PositionIteratorAlgorithm<Strategy>::computePosition() const { + ASSERT(isValid()); + // Assume that we have the following DOM tree: + // A + // |-B + // | |-E + // | +-F + // | + // |-C + // +-D + // |-G + // +-H if (m_nodeAfterPositionInAnchor) { + // For example, position is before E, F. ASSERT(Strategy::parent(*m_nodeAfterPositionInAnchor) == m_anchorNode); - return PositionTemplate<Strategy>::inParentBeforeNode(*m_nodeAfterPositionInAnchor); + ASSERT(m_offsetsInAnchorNode[m_depthToAnchorNode] != kInvalidOffset); + // TODO(yoichio): This should be equivalent to + // PositionTemplate<Strategy>(m_anchorNode, PositionAnchorType::BeforeAnchor); + return PositionTemplate<Strategy>(m_anchorNode, m_offsetsInAnchorNode[m_depthToAnchorNode]); } if (Strategy::hasChildren(*m_anchorNode)) + // For example, position is the end of B. return PositionTemplate<Strategy>::lastPositionInOrAfterNode(m_anchorNode); if (m_anchorNode->isTextNode()) return PositionTemplate<Strategy>(m_anchorNode, m_offsetInAnchor); if (m_offsetInAnchor) + // For example, position is after G. return PositionTemplate<Strategy>(m_anchorNode, PositionAnchorType::AfterAnchor); + // For example, position is before G. return PositionTemplate<Strategy>(m_anchorNode, PositionAnchorType::BeforeAnchor); } template <typename Strategy> void PositionIteratorAlgorithm<Strategy>::increment() { + ASSERT(isValid()); if (!m_anchorNode) return; + // Assume that we have the following DOM tree: + // A + // |-B + // | |-E + // | +-F + // | + // |-C + // +-D + // |-G + // +-H + // Let |anchor| as |m_anchorNode| and + // |child| as |m_nodeAfterPositionInAnchor|. if (m_nodeAfterPositionInAnchor) { + // Case #1: Move to position before the first child of + // |m_nodeAfterPositionInAnchor|. + // This is a point just before |child|. + // Let |anchor| is A and |child| is B, + // then next |anchor| is B and |child| is E. m_anchorNode = m_nodeAfterPositionInAnchor; m_nodeAfterPositionInAnchor = Strategy::firstChild(*m_anchorNode); m_offsetInAnchor = 0; + // Increment depth intializing with 0. + ++m_depthToAnchorNode; + if (m_depthToAnchorNode == m_offsetsInAnchorNode.size()) + m_offsetsInAnchorNode.append(0); + else + m_offsetsInAnchorNode[m_depthToAnchorNode] = 0; return; } if (m_anchorNode->layoutObject() && !Strategy::hasChildren(*m_anchorNode) && m_offsetInAnchor < Strategy::lastOffsetForEditing(m_anchorNode)) { + // Case #2. This is the next of Case #1 or #2 itself. + // Position is (|anchor|, |m_offsetInAchor|). + // In this case |anchor| is a leaf(E,F,C,G or H) and + // |m_offsetInAnchor| is not on the end of |anchor|. + // Then just increment |m_offsetInAnchor|. m_offsetInAnchor = uncheckedNextOffset(m_anchorNode, m_offsetInAnchor); } else { + // Case #3. This is the next of Case #2 or #3. + // Position is the end of |anchor|. + // 3-a. If |anchor| has next sibling (let E), + // next |anchor| is B and |child| is F (next is Case #1.) + // 3-b. If |anchor| doesn't have next sibling (let F), + // next |anchor| is B and |child| is null. (next is Case #3.) m_nodeAfterPositionInAnchor = m_anchorNode; m_anchorNode = Strategy::parent(*m_nodeAfterPositionInAnchor); + if (!m_anchorNode) + return; + ASSERT(m_depthToAnchorNode > 0); + --m_depthToAnchorNode; + // Increment offset of |child| or initialize if it have never been + // used. + if (m_offsetsInAnchorNode[m_depthToAnchorNode] == kInvalidOffset) + m_offsetsInAnchorNode[m_depthToAnchorNode] = Strategy::index(*m_nodeAfterPositionInAnchor) + 1; + else + ++m_offsetsInAnchorNode[m_depthToAnchorNode]; m_nodeAfterPositionInAnchor = Strategy::nextSibling(*m_nodeAfterPositionInAnchor); m_offsetInAnchor = 0; } @@ -106,31 +187,100 @@ void PositionIteratorAlgorithm<Strategy>::increment() template <typename Strategy> void PositionIteratorAlgorithm<Strategy>::decrement() { + ASSERT(isValid()); if (!m_anchorNode) return; + // Assume that we have the following DOM tree: + // A + // |-B + // | |-E + // | +-F + // | + // |-C + // +-D + // |-G + // +-H + // Let |anchor| as |m_anchorNode| and + // |child| as |m_nodeAfterPositionInAnchor|. + // decrement() is complex but logically reverse of increment(), of course:) if (m_nodeAfterPositionInAnchor) { m_anchorNode = Strategy::previousSibling(*m_nodeAfterPositionInAnchor); if (m_anchorNode) { + // Case #1-a. This is a revese of increment()::Case#3-a. + // |child| has a previous sibling. + // Let |anchor| is B and |child| is F, + // next |anchor| is E and |child| is null. m_nodeAfterPositionInAnchor = nullptr; m_offsetInAnchor = Strategy::hasChildren(*m_anchorNode) ? 0 : Strategy::lastOffsetForEditing(m_anchorNode); + // Decrement offset of |child| or initialize if it have never been + // used. + if (m_offsetsInAnchorNode[m_depthToAnchorNode] == kInvalidOffset) + m_offsetsInAnchorNode[m_depthToAnchorNode] = Strategy::index(*m_nodeAfterPositionInAnchor); + else + --m_offsetsInAnchorNode[m_depthToAnchorNode]; + ASSERT(m_offsetsInAnchorNode[m_depthToAnchorNode] >= 0); + // Increment depth intializing with last offset. + ++m_depthToAnchorNode; + if (m_depthToAnchorNode >= m_offsetsInAnchorNode.size()) + m_offsetsInAnchorNode.append(m_offsetInAnchor); + else + m_offsetsInAnchorNode[m_depthToAnchorNode] = m_offsetInAnchor; + return; } else { + // Case #1-b. This is a revese of increment()::Case#1. + // |child| doesn't have a previous sibling. + // Let |anchor| is B and |child| is E, + // next |anchor| is A and |child| is B. m_nodeAfterPositionInAnchor = Strategy::parent(*m_nodeAfterPositionInAnchor); m_anchorNode = Strategy::parent(*m_nodeAfterPositionInAnchor); + if (!m_anchorNode) + return; m_offsetInAnchor = 0; + // Decrement depth and intialize if needs. + ASSERT(m_depthToAnchorNode > 0); + --m_depthToAnchorNode; + if (m_offsetsInAnchorNode[m_depthToAnchorNode] == kInvalidOffset) + m_offsetsInAnchorNode[m_depthToAnchorNode] = Strategy::index(*m_nodeAfterPositionInAnchor); } return; } if (Strategy::hasChildren(*m_anchorNode)) { + // Case #2. This is a reverse of increment()::Case3-b. + // Let |anchor| is B, next |anchor| is F. m_anchorNode = Strategy::lastChild(*m_anchorNode); m_offsetInAnchor = Strategy::hasChildren(*m_anchorNode)? 0 : Strategy::lastOffsetForEditing(m_anchorNode); + // Decrement depth initializing with -1 because + // |m_nodeAfterPositionInAnchor| is null so still unneeded. + if (m_depthToAnchorNode >= m_offsetsInAnchorNode.size()) + m_offsetsInAnchorNode.append(kInvalidOffset); + else + m_offsetsInAnchorNode[m_depthToAnchorNode] = kInvalidOffset; + ++m_depthToAnchorNode; + return; } else { if (m_offsetInAnchor && m_anchorNode->layoutObject()) { + // Case #3-a. This is a reverse of increment()::Case#2. + // In this case |anchor| is a leaf(E,F,C,G or H) and + // |m_offsetInAnchor| is not on the beginning of |anchor|. + // Then just decrement |m_offsetInAnchor|. m_offsetInAnchor = uncheckedPreviousOffset(m_anchorNode, m_offsetInAnchor); + return; } else { + // Case #3-b. This is a reverse of increment()::Case#1. + // In this case |anchor| is a leaf(E,F,C,G or H) and + // |m_offsetInAnchor| is on the beginning of |anchor|. + // Let |anchor| is E, + // next |anchor| is B and |child| is E. m_nodeAfterPositionInAnchor = m_anchorNode; m_anchorNode = Strategy::parent(*m_anchorNode); + if (!m_anchorNode) + return; + ASSERT(m_depthToAnchorNode > 0); + --m_depthToAnchorNode; + if (m_offsetsInAnchorNode[m_depthToAnchorNode] == kInvalidOffset) + m_offsetsInAnchorNode[m_depthToAnchorNode] = Strategy::index(*m_nodeAfterPositionInAnchor); } } } @@ -138,6 +288,7 @@ void PositionIteratorAlgorithm<Strategy>::decrement() template <typename Strategy> bool PositionIteratorAlgorithm<Strategy>::atStart() const { + ASSERT(isValid()); if (!m_anchorNode) return true; if (Strategy::parent(*m_anchorNode)) @@ -148,6 +299,7 @@ bool PositionIteratorAlgorithm<Strategy>::atStart() const template <typename Strategy> bool PositionIteratorAlgorithm<Strategy>::atEnd() const { + ASSERT(isValid()); if (!m_anchorNode) return true; if (m_nodeAfterPositionInAnchor) @@ -158,6 +310,7 @@ bool PositionIteratorAlgorithm<Strategy>::atEnd() const template <typename Strategy> bool PositionIteratorAlgorithm<Strategy>::atStartOfNode() const { + ASSERT(isValid()); if (!m_anchorNode) return true; if (!m_nodeAfterPositionInAnchor) @@ -168,6 +321,7 @@ bool PositionIteratorAlgorithm<Strategy>::atStartOfNode() const template <typename Strategy> bool PositionIteratorAlgorithm<Strategy>::atEndOfNode() const { + ASSERT(isValid()); if (!m_anchorNode) return true; if (m_nodeAfterPositionInAnchor) diff --git a/chromium/third_party/WebKit/Source/core/editing/PositionIterator.h b/chromium/third_party/WebKit/Source/core/editing/PositionIterator.h index 0383cf1fff1..b62f3e91d9f 100644 --- a/chromium/third_party/WebKit/Source/core/editing/PositionIterator.h +++ b/chromium/third_party/WebKit/Source/core/editing/PositionIterator.h @@ -34,9 +34,11 @@ namespace blink { -// A Position iterator with constant-time +// A Position iterator with nearly constant-time // increment, decrement, and several predicates on the Position it is at. -// Conversion to/from Position is O(n) in the offset. +// Conversion from Position is O(n) in the depth. +// Conversion to Position is O(1). +// PositionIteratorAlgorithm must be used without DOM tree change. template <typename Strategy> class PositionIteratorAlgorithm { STACK_ALLOCATED(); @@ -49,7 +51,14 @@ public: PositionTemplate<Strategy> deprecatedComputePosition() const; PositionTemplate<Strategy> computePosition() const; + // increment() takes O(1) other than incrementing to a element that has + // new parent. + // In the later case, it takes time of O(<number of childlen>) but the case + // happens at most depth-of-the-tree times over whole tree traversal. void increment(); + // decrement() takes O(1) other than decrement into new node that has + // childlen. + // In the later case, it takes time of O(<number of childlen>). void decrement(); Node* node() const { return m_anchorNode; } @@ -63,9 +72,17 @@ public: private: PositionIteratorAlgorithm(Node* anchorNode, int offsetInAnchorNode); + bool isValid() const { return !m_anchorNode || m_domTreeVersion == m_anchorNode->document().domTreeVersion(); } + RawPtrWillBeMember<Node> m_anchorNode; RawPtrWillBeMember<Node> m_nodeAfterPositionInAnchor; // If this is non-null, Strategy::parent(*m_nodeAfterPositionInAnchor) == m_anchorNode; int m_offsetInAnchor; + size_t m_depthToAnchorNode; + // If |m_nodeAfterPositionInAnchor| is not null, + // m_offsetsInAnchorNode[m_depthToAnchorNode] == + // Strategy::index(m_nodeAfterPositionInAnchor). + Vector<int> m_offsetsInAnchorNode; + uint64_t m_domTreeVersion; }; extern template class PositionIteratorAlgorithm<EditingStrategy>; diff --git a/chromium/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp b/chromium/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp index 5eef8486a3b..eeb07523341 100644 --- a/chromium/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp +++ b/chromium/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp @@ -919,7 +919,7 @@ static inline HTMLElement* elementToSplitToAvoidPastingIntoInlineElementsWithSty void ReplaceSelectionCommand::doApply() { - VisibleSelection selection = endingSelection(); + const VisibleSelection selection = endingSelection(); ASSERT(selection.isCaretOrRange()); ASSERT(selection.start().anchorNode()); if (!selection.isNonOrphanedCaretOrRange() || !selection.start().anchorNode()) @@ -942,17 +942,16 @@ void ReplaceSelectionCommand::doApply() m_insertionStyle->mergeTypingStyle(&document()); } - VisiblePosition visibleStart = selection.visibleStart(); - VisiblePosition visibleEnd = selection.visibleEnd(); + const VisiblePosition visibleStart = selection.visibleStart(); + const VisiblePosition visibleEnd = selection.visibleEnd(); - bool selectionEndWasEndOfParagraph = isEndOfParagraph(visibleEnd); - bool selectionStartWasStartOfParagraph = isStartOfParagraph(visibleStart); + const bool selectionEndWasEndOfParagraph = isEndOfParagraph(visibleEnd); + const bool selectionStartWasStartOfParagraph = isStartOfParagraph(visibleStart); Element* enclosingBlockOfVisibleStart = enclosingBlock(visibleStart.deepEquivalent().anchorNode()); - Position insertionPos = selection.start(); - bool startIsInsideMailBlockquote = enclosingNodeOfType(insertionPos, isMailHTMLBlockquoteElement, CanCrossEditingBoundary); - bool selectionIsPlainText = !selection.isContentRichlyEditable(); + const bool startIsInsideMailBlockquote = enclosingNodeOfType(selection.start(), isMailHTMLBlockquoteElement, CanCrossEditingBoundary); + const bool selectionIsPlainText = !selection.isContentRichlyEditable(); Element* currentRoot = selection.rootEditableElement(); if ((selectionStartWasStartOfParagraph && selectionEndWasEndOfParagraph && !startIsInsideMailBlockquote) @@ -973,43 +972,38 @@ void ReplaceSelectionCommand::doApply() // FIXME: We should only expand to include fully selected special elements if we are copying a // selection and pasting it on top of itself. deleteSelection(false, mergeBlocksAfterDelete, false); - visibleStart = endingSelection().visibleStart(); if (fragment.hasInterchangeNewlineAtStart()) { - if (isEndOfParagraph(visibleStart) && !isStartOfParagraph(visibleStart)) { - if (!isEndOfEditableOrNonEditableContent(visibleStart)) - setEndingSelection(nextPositionOf(visibleStart)); - } else { + VisiblePosition startAfterDelete = endingSelection().visibleStart(); + if (isEndOfParagraph(startAfterDelete) && !isStartOfParagraph(startAfterDelete) && !isEndOfEditableOrNonEditableContent(startAfterDelete)) + setEndingSelection(nextPositionOf(startAfterDelete)); + else insertParagraphSeparator(); - } } - insertionPos = endingSelection().start(); } else { ASSERT(selection.isCaret()); if (fragment.hasInterchangeNewlineAtStart()) { - VisiblePosition next = nextPositionOf(visibleStart, CannotCrossEditingBoundary); - if (isEndOfParagraph(visibleStart) && !isStartOfParagraph(visibleStart) && next.isNotNull()) { + const VisiblePosition next = nextPositionOf(visibleStart, CannotCrossEditingBoundary); + if (isEndOfParagraph(visibleStart) && !isStartOfParagraph(visibleStart) && next.isNotNull()) setEndingSelection(next); - } else { + else insertParagraphSeparator(); - visibleStart = endingSelection().visibleStart(); - } } // We split the current paragraph in two to avoid nesting the blocks from the fragment inside the current block. // For example paste <div>foo</div><div>bar</div><div>baz</div> into <div>x^x</div>, where ^ is the caret. // As long as the div styles are the same, visually you'd expect: <div>xbar</div><div>bar</div><div>bazx</div>, // not <div>xbar<div>bar</div><div>bazx</div></div>. // Don't do this if the selection started in a Mail blockquote. - if (m_preventNesting && !startIsInsideMailBlockquote && !isEndOfParagraph(visibleStart) && !isStartOfParagraph(visibleStart)) { + if (m_preventNesting && !startIsInsideMailBlockquote && !isEndOfParagraph(endingSelection().visibleStart()) && !isStartOfParagraph(endingSelection().visibleStart())) { insertParagraphSeparator(); setEndingSelection(previousPositionOf(endingSelection().visibleStart())); } - insertionPos = endingSelection().start(); } + Position insertionPos = endingSelection().start(); // We don't want any of the pasted content to end up nested in a Mail blockquote, so first break // out of any surrounding Mail blockquotes. Unless we're inserting in a table, in which case // breaking the blockquote will prevent the content from actually being inserted in the table. - if (startIsInsideMailBlockquote && m_preventNesting && !(enclosingNodeOfType(insertionPos, &isTableStructureNode))) { + if (enclosingNodeOfType(insertionPos, isMailHTMLBlockquoteElement, CanCrossEditingBoundary) && m_preventNesting && !(enclosingNodeOfType(insertionPos, &isTableStructureNode))) { applyCommandToComposite(BreakBlockquoteCommand::create(document())); // This will leave a br between the split. Node* br = endingSelection().start().anchorNode(); diff --git a/chromium/third_party/WebKit/Source/core/frame/LocalFrame.cpp b/chromium/third_party/WebKit/Source/core/frame/LocalFrame.cpp index c0b3b8d0f8d..9fa4c754154 100644 --- a/chromium/third_party/WebKit/Source/core/frame/LocalFrame.cpp +++ b/chromium/third_party/WebKit/Source/core/frame/LocalFrame.cpp @@ -257,6 +257,8 @@ void LocalFrame::navigate(Document& originDocument, const KURL& url, bool replac void LocalFrame::navigate(const FrameLoadRequest& request) { + if (!isNavigationAllowed()) + return; m_loader.load(request); } @@ -314,7 +316,28 @@ void LocalFrame::detach(FrameDetachType type) // Signal frame destruction here rather than in the destructor. // Main motivation is to avoid being dependent on its exact timing (Oilpan.) LocalFrameLifecycleNotifier::notifyContextDestroyed(); + // TODO(dcheng): Temporary, to debug https://crbug.com/531291. + // If this is true, we somehow re-entered LocalFrame::detach. But this is + // probably OK? + if (m_supplementStatus == SupplementStatus::Cleared) + RELEASE_ASSERT(m_supplements.isEmpty()); + // If this is true, we somehow re-entered LocalFrame::detach in the middle + // of cleaning up supplements. + RELEASE_ASSERT(m_supplementStatus != SupplementStatus::Clearing); + RELEASE_ASSERT(m_supplementStatus == SupplementStatus::Uncleared); + m_supplementStatus = SupplementStatus::Clearing; + + // TODO(haraken): Temporary code to debug https://crbug.com/531291. + // Check that m_supplements doesn't duplicate OwnPtrs. + HashSet<void*> supplementPointers; + for (auto& it : m_supplements) { + void* pointer = reinterpret_cast<void*>(it.value.get()); + RELEASE_ASSERT(!supplementPointers.contains(pointer)); + supplementPointers.add(pointer); + } + m_supplements.clear(); + m_supplementStatus = SupplementStatus::Cleared; WeakIdentifierMap<LocalFrame>::notifyObjectDestroyed(this); } @@ -852,6 +875,7 @@ inline LocalFrame::LocalFrame(FrameLoaderClient* client, FrameHost* host, FrameO , m_eventHandler(adoptPtrWillBeNoop(new EventHandler(this))) , m_console(FrameConsole::create(*this)) , m_inputMethodController(InputMethodController::create(*this)) + , m_navigationDisableCount(0) , m_pageZoomFactor(parentPageZoomFactor(this)) , m_textZoomFactor(parentTextZoomFactor(this)) , m_inViewSourceMode(false) @@ -883,4 +907,15 @@ void LocalFrame::updateFrameSecurityOrigin() DEFINE_WEAK_IDENTIFIER_MAP(LocalFrame); +FrameNavigationDisabler::FrameNavigationDisabler(LocalFrame& frame) + : m_frame(&frame) +{ + m_frame->disableNavigation(); +} + +FrameNavigationDisabler::~FrameNavigationDisabler() +{ + m_frame->enableNavigation(); +} + } // namespace blink diff --git a/chromium/third_party/WebKit/Source/core/frame/LocalFrame.h b/chromium/third_party/WebKit/Source/core/frame/LocalFrame.h index ce17bb37a70..c686ead465c 100644 --- a/chromium/third_party/WebKit/Source/core/frame/LocalFrame.h +++ b/chromium/third_party/WebKit/Source/core/frame/LocalFrame.h @@ -188,7 +188,11 @@ public: WebFrameScheduler* frameScheduler(); void updateFrameSecurityOrigin(); + bool isNavigationAllowed() const { return m_navigationDisableCount == 0; } + private: + friend class FrameNavigationDisabler; + LocalFrame(FrameLoaderClient*, FrameHost*, FrameOwner*); // Internal Frame helper overrides: @@ -202,6 +206,9 @@ private: RespectImageOrientationEnum shouldRespectImageOrientation, const GlobalPaintFlags, IntRect paintingRect, float opacity = 1); + void enableNavigation() { --m_navigationDisableCount; } + void disableNavigation() { ++m_navigationDisableCount; } + mutable FrameLoader m_loader; OwnPtrWillBeMember<NavigationScheduler> m_navigationScheduler; @@ -219,6 +226,8 @@ private: const OwnPtrWillBeMember<InputMethodController> m_inputMethodController; OwnPtr<WebFrameScheduler> m_frameScheduler; + int m_navigationDisableCount; + #if ENABLE(OILPAN) // Oilpan: in order to reliably finalize plugin elements with // renderer-less plugins, the frame keeps track of them. When @@ -242,6 +251,10 @@ private: bool m_inViewSourceMode; RefPtrWillBeMember<InstrumentingAgents> m_instrumentingAgents; + + // TODO(dcheng): Temporary to try to debug https://crbug.com/531291 + enum class SupplementStatus { Uncleared, Clearing, Cleared }; + SupplementStatus m_supplementStatus = SupplementStatus::Uncleared; }; inline void LocalFrame::init() @@ -320,6 +333,17 @@ DEFINE_TYPE_CASTS(LocalFrame, Frame, localFrame, localFrame->isLocalFrame(), loc DECLARE_WEAK_IDENTIFIER_MAP(LocalFrame); +class FrameNavigationDisabler { + WTF_MAKE_NONCOPYABLE(FrameNavigationDisabler); + STACK_ALLOCATED(); +public: + explicit FrameNavigationDisabler(LocalFrame&); + ~FrameNavigationDisabler(); + +private: + RawPtrWillBeMember<LocalFrame> m_frame; +}; + } // namespace blink // During refactoring, there are some places where we need to do type conversions that diff --git a/chromium/third_party/WebKit/Source/core/frame/UseCounter.h b/chromium/third_party/WebKit/Source/core/frame/UseCounter.h index 0d96fea7a2b..fa0e664c45b 100644 --- a/chromium/third_party/WebKit/Source/core/frame/UseCounter.h +++ b/chromium/third_party/WebKit/Source/core/frame/UseCounter.h @@ -838,6 +838,12 @@ public: CredentialManagerGetWithoutUI = 962, CredentialManagerStore = 963, CredentialManagerRequireUserMediation = 964, + MeterElementWithContinuousCapacityAppearance = 991, + MeterElementWithDiscreteCapacityAppearance = 992, + MeterElementWithMeterAppearance = 993, + MeterElementWithNoneAppearance = 994, + MeterElementWithRatingAppearance = 995, + MeterElementWithRelevancyAppearance = 996, // Add new features immediately above this line. Don't change assigned // numbers of any item, and don't reuse removed slots. diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLFormElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLFormElement.cpp index a552cb1b96b..6cd1c1e4f59 100644 --- a/chromium/third_party/WebKit/Source/core/html/HTMLFormElement.cpp +++ b/chromium/third_party/WebKit/Source/core/html/HTMLFormElement.cpp @@ -836,12 +836,14 @@ void HTMLFormElement::anonymousNamedGetter(const AtomicString& name, RadioNodeLi getNamedElements(name, elements); ASSERT(!elements.isEmpty()); + bool onlyMatchImg = !elements.isEmpty() && isHTMLImageElement(*elements.first()); + if (onlyMatchImg) + UseCounter::count(document(), UseCounter::FormNameAccessForImageElement); if (elements.size() == 1) { returnValue.setElement(elements.at(0)); return; } - bool onlyMatchImg = !elements.isEmpty() && isHTMLImageElement(*elements.first()); returnValue.setRadioNodeList(radioNodeList(name, onlyMatchImg)); } diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp index f9b471659ee..16caecec08c 100644 --- a/chromium/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp +++ b/chromium/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp @@ -1979,7 +1979,7 @@ void HTMLMediaElement::play() if (m_userGestureRequiredForPlay) { recordAutoplayMetric(PlayMethodFailed); String message = ExceptionMessages::failedToExecute("play", "HTMLMediaElement", "API can only be initiated by a user gesture."); - document().executionContext()->addConsoleMessage(ConsoleMessage::create(JSMessageSource, WarningMessageLevel, message)); + document().addConsoleMessage(ConsoleMessage::create(JSMessageSource, WarningMessageLevel, message)); return; } } else if (m_userGestureRequiredForPlay) { diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLMeterElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLMeterElement.cpp index 97587fa1243..d91601fe2f9 100644 --- a/chromium/third_party/WebKit/Source/core/html/HTMLMeterElement.cpp +++ b/chromium/third_party/WebKit/Source/core/html/HTMLMeterElement.cpp @@ -57,6 +57,28 @@ PassRefPtrWillBeRawPtr<HTMLMeterElement> HTMLMeterElement::create(Document& docu LayoutObject* HTMLMeterElement::createLayoutObject(const ComputedStyle& style) { + switch (style.appearance()) { + case ContinuousCapacityLevelIndicatorPart: + UseCounter::count(document(), UseCounter::MeterElementWithContinuousCapacityAppearance); + break; + case DiscreteCapacityLevelIndicatorPart: + UseCounter::count(document(), UseCounter::MeterElementWithDiscreteCapacityAppearance); + break; + case MeterPart: + UseCounter::count(document(), UseCounter::MeterElementWithMeterAppearance); + break; + case NoControlPart: + UseCounter::count(document(), UseCounter::MeterElementWithNoneAppearance); + break; + case RatingLevelIndicatorPart: + UseCounter::count(document(), UseCounter::MeterElementWithRatingAppearance); + break; + case RelevancyLevelIndicatorPart: + UseCounter::count(document(), UseCounter::MeterElementWithRelevancyAppearance); + break; + default: + break; + } if (openShadowRoot() || !LayoutTheme::theme().supportsMeter(style.appearance())) return LayoutObject::createObject(this, style); return new LayoutMeter(this); diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLScriptElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLScriptElement.cpp index 6bf842423a6..39447c04c48 100644 --- a/chromium/third_party/WebKit/Source/core/html/HTMLScriptElement.cpp +++ b/chromium/third_party/WebKit/Source/core/html/HTMLScriptElement.cpp @@ -68,7 +68,8 @@ const QualifiedName& HTMLScriptElement::subResourceAttributeName() const void HTMLScriptElement::childrenChanged(const ChildrenChange& change) { HTMLElement::childrenChanged(change); - m_loader->childrenChanged(); + if (change.isChildInsertion()) + m_loader->childrenChanged(); } void HTMLScriptElement::didMoveToNewDocument(Document& oldDocument) diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp index 868e71e8c16..a7436bc1a0d 100644 --- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp +++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp @@ -28,6 +28,7 @@ #include "core/HTMLNames.h" #include "core/css/MediaValuesCached.h" +#include "core/css/resolver/StyleResolver.h" #include "core/dom/DocumentFragment.h" #include "core/dom/DocumentLifecycleObserver.h" #include "core/dom/Element.h" @@ -775,6 +776,10 @@ void HTMLDocumentParser::startBackgroundParser() ASSERT(document()); m_haveBackgroundParser = true; + // Make sure that a resolver is set up, so that the correct viewport dimensions will be fed to the background parser and preload scanner. + if (document()->loader()) + document()->ensureStyleResolver(); + RefPtr<WeakReference<BackgroundHTMLParser>> reference = WeakReference<BackgroundHTMLParser>::createUnbound(); m_backgroundParser = WeakPtr<BackgroundHTMLParser>(reference); @@ -789,6 +794,7 @@ void HTMLDocumentParser::startBackgroundParser() config->parser = m_weakFactory.createWeakPtr(); config->xssAuditor = adoptPtr(new XSSAuditor); config->xssAuditor->init(document(), &m_xssAuditorDelegate); + config->preloadScanner = adoptPtr(new TokenPreloadScanner(document()->url().copy(), CachedDocumentParameters::create(document()))); config->decoder = takeDecoder(); if (document()->settings()) { diff --git a/chromium/third_party/WebKit/Source/core/inspector/DebuggerScript.js b/chromium/third_party/WebKit/Source/core/inspector/DebuggerScript.js index 22483edfca4..69995fd035f 100644 --- a/chromium/third_party/WebKit/Source/core/inspector/DebuggerScript.js +++ b/chromium/third_party/WebKit/Source/core/inspector/DebuggerScript.js @@ -57,6 +57,8 @@ DebuggerScript.getAfterCompileScript = function(eventData) DebuggerScript.getFunctionScopes = function(fun) { var mirror = MakeMirror(fun); + if (!mirror.isFunction()) + return null; var count = mirror.scopeCount(); if (count == 0) return null; diff --git a/chromium/third_party/WebKit/Source/core/inspector/v8/V8Debugger.h b/chromium/third_party/WebKit/Source/core/inspector/v8/V8Debugger.h index a0d402ff4a9..72a6a20e90b 100644 --- a/chromium/third_party/WebKit/Source/core/inspector/v8/V8Debugger.h +++ b/chromium/third_party/WebKit/Source/core/inspector/v8/V8Debugger.h @@ -46,7 +46,7 @@ public: virtual bool pausingOnNextStatement() = 0; // TODO: these methods will not be public once InjectedScriptHost is in the implementation. - virtual v8::Local<v8::Value> functionScopes(v8::Local<v8::Function>) = 0; + virtual v8::MaybeLocal<v8::Value> functionScopes(v8::Local<v8::Function>) = 0; virtual v8::Local<v8::Value> generatorObjectDetails(v8::Local<v8::Object>&) = 0; virtual v8::Local<v8::Value> collectionEntries(v8::Local<v8::Object>&) = 0; virtual v8::MaybeLocal<v8::Value> setFunctionVariableValue(v8::Local<v8::Value> functionValue, int scopeNumber, const String& variableName, v8::Local<v8::Value> newValue) = 0; diff --git a/chromium/third_party/WebKit/Source/core/inspector/v8/V8DebuggerImpl.cpp b/chromium/third_party/WebKit/Source/core/inspector/v8/V8DebuggerImpl.cpp index 5c9a6269d28..ee81bdf17a0 100644 --- a/chromium/third_party/WebKit/Source/core/inspector/v8/V8DebuggerImpl.cpp +++ b/chromium/third_party/WebKit/Source/core/inspector/v8/V8DebuggerImpl.cpp @@ -696,14 +696,14 @@ v8::Local<v8::String> V8DebuggerImpl::v8InternalizedString(const char* str) cons return v8::String::NewFromUtf8(m_isolate, str, v8::NewStringType::kInternalized).ToLocalChecked(); } -v8::Local<v8::Value> V8DebuggerImpl::functionScopes(v8::Local<v8::Function> function) +v8::MaybeLocal<v8::Value> V8DebuggerImpl::functionScopes(v8::Local<v8::Function> function) { if (!enabled()) { ASSERT_NOT_REACHED(); return v8::Local<v8::Value>::New(m_isolate, v8::Undefined(m_isolate)); } v8::Local<v8::Value> argv[] = { function }; - return callDebuggerMethod("getFunctionScopes", 1, argv).ToLocalChecked(); + return callDebuggerMethod("getFunctionScopes", 1, argv); } v8::Local<v8::Value> V8DebuggerImpl::generatorObjectDetails(v8::Local<v8::Object>& object) diff --git a/chromium/third_party/WebKit/Source/core/inspector/v8/V8DebuggerImpl.h b/chromium/third_party/WebKit/Source/core/inspector/v8/V8DebuggerImpl.h index fec7a4fc8fc..94423ee01a1 100644 --- a/chromium/third_party/WebKit/Source/core/inspector/v8/V8DebuggerImpl.h +++ b/chromium/third_party/WebKit/Source/core/inspector/v8/V8DebuggerImpl.h @@ -82,7 +82,7 @@ public: bool isPaused(); - v8::Local<v8::Value> functionScopes(v8::Local<v8::Function>) override; + v8::MaybeLocal<v8::Value> functionScopes(v8::Local<v8::Function>) override; v8::Local<v8::Value> generatorObjectDetails(v8::Local<v8::Object>&) override; v8::Local<v8::Value> collectionEntries(v8::Local<v8::Object>&) override; v8::MaybeLocal<v8::Value> setFunctionVariableValue(v8::Local<v8::Value> functionValue, int scopeNumber, const String& variableName, v8::Local<v8::Value> newValue) override; diff --git a/chromium/third_party/WebKit/Source/core/inspector/v8/V8InjectedScriptHost.cpp b/chromium/third_party/WebKit/Source/core/inspector/v8/V8InjectedScriptHost.cpp index 7229e361bdc..f4470bad04c 100644 --- a/chromium/third_party/WebKit/Source/core/inspector/v8/V8InjectedScriptHost.cpp +++ b/chromium/third_party/WebKit/Source/core/inspector/v8/V8InjectedScriptHost.cpp @@ -212,9 +212,9 @@ void V8InjectedScriptHost::functionDetailsCallback(const v8::FunctionCallbackInf InjectedScriptHost* host = V8InjectedScriptHost::unwrap(info.Holder()); V8Debugger& debugger = host->debugger(); - v8::Local<v8::Value> scopes = debugger.functionScopes(function); - if (!scopes.IsEmpty() && scopes->IsArray()) - result->Set(v8AtomicString(isolate, "rawScopes"), scopes); + v8::MaybeLocal<v8::Value> scopes = debugger.functionScopes(function); + if (!scopes.IsEmpty() && scopes.ToLocalChecked()->IsArray()) + result->Set(v8AtomicString(isolate, "rawScopes"), scopes.ToLocalChecked()); v8SetReturnValue(info, result); } diff --git a/chromium/third_party/WebKit/Source/core/layout/FloatingObjects.cpp b/chromium/third_party/WebKit/Source/core/layout/FloatingObjects.cpp index 28dc9405943..8a256450277 100644 --- a/chromium/third_party/WebKit/Source/core/layout/FloatingObjects.cpp +++ b/chromium/third_party/WebKit/Source/core/layout/FloatingObjects.cpp @@ -46,7 +46,8 @@ FloatingObject::FloatingObject(LayoutBox* layoutObject) : m_layoutObject(layoutObject) , m_originatingLine(nullptr) , m_paginationStrut(0) - , m_ownership(DirectlyContained) + , m_shouldPaint(true) + , m_isDescendant(false) , m_isPlaced(false) , m_isLowestNonOverhangingFloatInChild(false) #if ENABLE(ASSERT) @@ -61,13 +62,14 @@ FloatingObject::FloatingObject(LayoutBox* layoutObject) m_type = FloatRight; } -FloatingObject::FloatingObject(LayoutBox* layoutObject, Type type, const LayoutRect& frameRect, Ownership ownership, bool isLowestNonOverhangingFloatInChild) +FloatingObject::FloatingObject(LayoutBox* layoutObject, Type type, const LayoutRect& frameRect, bool shouldPaint, bool isDescendant, bool isLowestNonOverhangingFloatInChild) : m_layoutObject(layoutObject) , m_originatingLine(nullptr) , m_frameRect(frameRect) , m_paginationStrut(0) , m_type(type) - , m_ownership(ownership) + , m_shouldPaint(shouldPaint) + , m_isDescendant(isDescendant) , m_isPlaced(true) , m_isLowestNonOverhangingFloatInChild(isLowestNonOverhangingFloatInChild) #if ENABLE(ASSERT) @@ -78,17 +80,21 @@ FloatingObject::FloatingObject(LayoutBox* layoutObject, Type type, const LayoutR PassOwnPtr<FloatingObject> FloatingObject::create(LayoutBox* layoutObject) { - return adoptPtr(new FloatingObject(layoutObject)); + OwnPtr<FloatingObject> newObj = adoptPtr(new FloatingObject(layoutObject)); + newObj->setShouldPaint(!layoutObject->hasSelfPaintingLayer()); // If a layer exists, the float will paint itself. Otherwise someone else will. + newObj->setIsDescendant(true); + + return newObj.release(); } -PassOwnPtr<FloatingObject> FloatingObject::copyToNewContainer(LayoutSize offset, Ownership ownership) const +PassOwnPtr<FloatingObject> FloatingObject::copyToNewContainer(LayoutSize offset, bool shouldPaint, bool isDescendant) const { - return adoptPtr(new FloatingObject(layoutObject(), type(), LayoutRect(frameRect().location() - offset, frameRect().size()), ownership, isLowestNonOverhangingFloatInChild())); + return adoptPtr(new FloatingObject(layoutObject(), type(), LayoutRect(frameRect().location() - offset, frameRect().size()), shouldPaint, isDescendant, isLowestNonOverhangingFloatInChild())); } PassOwnPtr<FloatingObject> FloatingObject::unsafeClone() const { - OwnPtr<FloatingObject> cloneObject = adoptPtr(new FloatingObject(layoutObject(), type(), m_frameRect, static_cast<Ownership>(m_ownership), false)); + OwnPtr<FloatingObject> cloneObject = adoptPtr(new FloatingObject(layoutObject(), type(), m_frameRect, m_shouldPaint, m_isDescendant, false)); cloneObject->m_paginationStrut = m_paginationStrut; cloneObject->m_isPlaced = m_isPlaced; return cloneObject.release(); diff --git a/chromium/third_party/WebKit/Source/core/layout/FloatingObjects.h b/chromium/third_party/WebKit/Source/core/layout/FloatingObjects.h index 7d678b906ec..7b446538a18 100644 --- a/chromium/third_party/WebKit/Source/core/layout/FloatingObjects.h +++ b/chromium/third_party/WebKit/Source/core/layout/FloatingObjects.h @@ -49,11 +49,9 @@ public: // Note that Type uses bits so you can use FloatLeftRight as a mask to query for both left and right. enum Type { FloatLeft = 1, FloatRight = 2, FloatLeftRight = 3 }; - enum Ownership { DirectlyContained, IndirectlyContained, IntrudingNonDescendant }; - static PassOwnPtr<FloatingObject> create(LayoutBox*); - PassOwnPtr<FloatingObject> copyToNewContainer(LayoutSize, Ownership) const; + PassOwnPtr<FloatingObject> copyToNewContainer(LayoutSize, bool shouldPaint = false, bool isDescendant = false) const; PassOwnPtr<FloatingObject> unsafeClone() const; @@ -85,8 +83,10 @@ public: void setIsInPlacedTree(bool value) { m_isInPlacedTree = value; } #endif - bool isDirectlyContained() const { return m_ownership == DirectlyContained; } - bool isDescendant() const { return m_ownership == DirectlyContained || m_ownership == IndirectlyContained; } + bool shouldPaint() const { return m_shouldPaint; } + void setShouldPaint(bool shouldPaint) { m_shouldPaint = shouldPaint; } + bool isDescendant() const { return m_isDescendant; } + void setIsDescendant(bool isDescendant) { m_isDescendant = isDescendant; } bool isLowestNonOverhangingFloatInChild() const { return m_isLowestNonOverhangingFloatInChild; } void setIsLowestNonOverhangingFloatInChild(bool isLowestNonOverhangingFloatInChild) { m_isLowestNonOverhangingFloatInChild = isLowestNonOverhangingFloatInChild; } @@ -96,7 +96,7 @@ public: private: explicit FloatingObject(LayoutBox*); - FloatingObject(LayoutBox*, Type, const LayoutRect&, Ownership, bool isLowestNonOverhangingFloatInChild); + FloatingObject(LayoutBox*, Type, const LayoutRect&, bool shouldPaint, bool isDescendant, bool isLowestNonOverhangingFloatInChild); LayoutBox* m_layoutObject; RootInlineBox* m_originatingLine; @@ -104,7 +104,8 @@ private: int m_paginationStrut; // FIXME: Is this class size-sensitive? Does this need 32-bits? unsigned m_type : 2; // Type (left or right aligned) - unsigned m_ownership : 2; // Ownership + unsigned m_shouldPaint : 1; + unsigned m_isDescendant : 1; unsigned m_isPlaced : 1; unsigned m_isLowestNonOverhangingFloatInChild : 1; #if ENABLE(ASSERT) diff --git a/chromium/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp b/chromium/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp index d08012e40a7..54318f0149e 100644 --- a/chromium/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp +++ b/chromium/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp @@ -469,7 +469,7 @@ void LayoutBlockFlow::addLowestFloatFromChildren(LayoutBlockFlow* block) if (!m_floatingObjects) createFloatingObjects(); - FloatingObject* newFloatingObject = m_floatingObjects->add(floatingObject->copyToNewContainer(offset, FloatingObject::IndirectlyContained)); + FloatingObject* newFloatingObject = m_floatingObjects->add(floatingObject->copyToNewContainer(offset, false, true)); newFloatingObject->setIsLowestNonOverhangingFloatInChild(true); } @@ -1758,7 +1758,7 @@ void LayoutBlockFlow::addOverflowFromFloats() FloatingObjectSetIterator end = floatingObjectSet.end(); for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) { const FloatingObject& floatingObject = *it->get(); - if (floatingObject.isDirectlyContained()) + if (floatingObject.isDescendant()) addOverflowFromChild(floatingObject.layoutObject(), LayoutSize(xPositionForFloatIncludingMargin(floatingObject), yPositionForFloatIncludingMargin(floatingObject))); } } @@ -2046,12 +2046,12 @@ void LayoutBlockFlow::invalidatePaintForOverhangingFloats(bool paintAllDescendan FloatingObjectSetIterator end = floatingObjectSet.end(); for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) { const FloatingObject& floatingObject = *it->get(); - // Only issue paint invalidations for the object if it is overhanging, is not in its own layer, and - // is our responsibility to paint (isDirectlyContained). When paintAllDescendants is true, the latter + // Only issue paint invaldiations for the object if it is overhanging, is not in its own layer, and + // is our responsibility to paint (m_shouldPaint is set). When paintAllDescendants is true, the latter // condition is replaced with being a descendant of us. if (logicalBottomForFloat(floatingObject) > logicalHeight() && !floatingObject.layoutObject()->hasSelfPaintingLayer() - && (floatingObject.isDirectlyContained() || (paintAllDescendants && floatingObject.isDescendant()))) { + && (floatingObject.shouldPaint() || (paintAllDescendants && floatingObject.layoutObject()->isDescendantOf(this)))) { LayoutBox* floatingLayoutBox = floatingObject.layoutObject(); floatingLayoutBox->setShouldDoFullPaintInvalidation(); @@ -2512,7 +2512,7 @@ void LayoutBlockFlow::addIntrudingFloats(LayoutBlockFlow* prev, LayoutUnit logic ? LayoutSize(logicalLeftOffset - (prev != parent() ? prev->marginLeft() : LayoutUnit()), logicalTopOffset) : LayoutSize(logicalTopOffset, logicalLeftOffset - (prev != parent() ? prev->marginTop() : LayoutUnit())); - m_floatingObjects->add(floatingObject.copyToNewContainer(offset, FloatingObject::IntrudingNonDescendant)); + m_floatingObjects->add(floatingObject.copyToNewContainer(offset)); } } } @@ -2539,10 +2539,37 @@ void LayoutBlockFlow::addOverhangingFloats(LayoutBlockFlow* child, bool makeChil // If the object is not in the list, we add it now. if (!containsFloat(floatingObject.layoutObject())) { LayoutSize offset = isHorizontalWritingMode() ? LayoutSize(-childLogicalLeft, -childLogicalTop) : LayoutSize(-childLogicalTop, -childLogicalLeft); + bool shouldPaint = false; + + // The nearest enclosing layer always paints the float (so that zindex and stacking + // behaves properly). We always want to propagate the desire to paint the float as + // far out as we can, to the outermost block that overlaps the float, stopping only + // if we hit a self-painting layer boundary. + if (floatingObject.layoutObject()->enclosingFloatPaintingLayer() == enclosingFloatPaintingLayer() && !floatingObject.isLowestNonOverhangingFloatInChild()) { + floatingObject.setShouldPaint(false); + shouldPaint = true; + } + // We create the floating object list lazily. if (!m_floatingObjects) createFloatingObjects(); - m_floatingObjects->add(floatingObject.copyToNewContainer(offset, FloatingObject::IndirectlyContained)); + + m_floatingObjects->add(floatingObject.copyToNewContainer(offset, shouldPaint, true)); } + } else { + if (makeChildPaintOtherFloats && !floatingObject.shouldPaint() && !floatingObject.layoutObject()->hasSelfPaintingLayer() && !floatingObject.isLowestNonOverhangingFloatInChild() + && floatingObject.layoutObject()->isDescendantOf(child) && floatingObject.layoutObject()->enclosingFloatPaintingLayer() == child->enclosingFloatPaintingLayer()) { + // The float is not overhanging from this block, so if it is a descendant of the child, the child should + // paint it (the other case is that it is intruding into the child), unless it has its own layer or enclosing + // layer. + // If makeChildPaintOtherFloats is false, it means that the child must already know about all the floats + // it should paint. + floatingObject.setShouldPaint(true); + } + + // Since the float doesn't overhang, it didn't get put into our list. We need to go ahead and add its overflow in to the + // child now. + if (floatingObject.isDescendant()) + child->addOverflowFromChild(floatingObject.layoutObject(), LayoutSize(xPositionForFloatIncludingMargin(floatingObject), yPositionForFloatIncludingMargin(floatingObject))); } } } @@ -2596,7 +2623,7 @@ bool LayoutBlockFlow::hitTestFloats(HitTestResult& result, const HitTestLocation for (FloatingObjectSetIterator it = floatingObjectSet.end(); it != begin;) { --it; const FloatingObject& floatingObject = *it->get(); - if (floatingObject.isDirectlyContained() && !floatingObject.layoutObject()->hasSelfPaintingLayer()) { + if (floatingObject.shouldPaint() && !floatingObject.layoutObject()->hasSelfPaintingLayer()) { LayoutUnit xOffset = xPositionForFloatIncludingMargin(floatingObject) - floatingObject.layoutObject()->location().x(); LayoutUnit yOffset = yPositionForFloatIncludingMargin(floatingObject) - floatingObject.layoutObject()->location().y(); LayoutPoint childPoint = flipFloatForWritingModeForChild(floatingObject, adjustedLocation + LayoutSize(xOffset, yOffset)); diff --git a/chromium/third_party/WebKit/Source/core/layout/LayoutBlockFlowLine.cpp b/chromium/third_party/WebKit/Source/core/layout/LayoutBlockFlowLine.cpp index b69cb4fa6f9..98e2002a915 100644 --- a/chromium/third_party/WebKit/Source/core/layout/LayoutBlockFlowLine.cpp +++ b/chromium/third_party/WebKit/Source/core/layout/LayoutBlockFlowLine.cpp @@ -1830,6 +1830,7 @@ bool LayoutBlockFlow::matchedEndLine(LineLayoutState& layoutState, const InlineB } bool LayoutBlockFlow::generatesLineBoxesForInlineChild(LayoutObject* inlineObj) + { ASSERT(inlineObj->parent() == this); @@ -1841,9 +1842,13 @@ bool LayoutBlockFlow::generatesLineBoxesForInlineChild(LayoutObject* inlineObj) return !it.atEnd(); } + void LayoutBlockFlow::addOverflowFromInlineChildren() { LayoutUnit endPadding = hasOverflowClip() ? paddingEnd() : LayoutUnit(); + // FIXME: Need to find another way to do this, since scrollbars could show when we don't want them to. + if (hasOverflowClip() && !endPadding && node() && node()->isRootEditableElement() && style()->isLeftToRightDirection()) + endPadding = 1; for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) { addLayoutOverflow(curr->paddedLayoutOverflowRect(endPadding)); LayoutRect visualOverflow = curr->visualOverflowRect(curr->lineTop(), curr->lineBottom()); diff --git a/chromium/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.cpp b/chromium/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.cpp index 8d6760f61ee..073353a347f 100644 --- a/chromium/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.cpp +++ b/chromium/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.cpp @@ -364,6 +364,7 @@ void LayoutMultiColumnFlowThread::layoutColumns(bool relayoutChildren, SubtreeLa continue; } LayoutMultiColumnSet* columnSet = toLayoutMultiColumnSet(columnBox); + layoutScope.setChildNeedsLayout(columnSet); if (!m_inBalancingPass) { // This is the initial layout pass. We need to reset the column height, because contents // typically have changed. @@ -391,16 +392,8 @@ bool LayoutMultiColumnFlowThread::recalculateColumnHeights() // passes than that, though, but the number of retries should not exceed the number of // columns, unless we have a bug. bool needsRelayout = false; - for (LayoutMultiColumnSet* multicolSet = firstMultiColumnSet(); multicolSet; multicolSet = multicolSet->nextSiblingMultiColumnSet()) { + for (LayoutMultiColumnSet* multicolSet = firstMultiColumnSet(); multicolSet; multicolSet = multicolSet->nextSiblingMultiColumnSet()) needsRelayout |= multicolSet->recalculateColumnHeight(m_inBalancingPass ? StretchBySpaceShortage : GuessFromFlowThreadPortion); - if (needsRelayout) { - // Once a column set gets a new column height, that column set and all successive column - // sets need to be laid out over again, since their logical top will be affected by - // this, and therefore their column heights may change as well, at least if the multicol - // height is constrained. - multicolSet->setChildNeedsLayout(MarkOnlyThis); - } - } if (needsRelayout) setChildNeedsLayout(MarkOnlyThis); @@ -536,7 +529,6 @@ void LayoutMultiColumnFlowThread::createAndInsertSpannerPlaceholder(LayoutBox* s // a new spanner placeholder between them. setToSplit = mapDescendantToColumnSet(previousLayoutObject); ASSERT(setToSplit == mapDescendantToColumnSet(insertedBeforeInFlowThread)); - setToSplit->setNeedsLayoutAndFullPaintInvalidation(LayoutInvalidationReason::ColumnsChanged); insertBeforeColumnBox = setToSplit->nextSiblingMultiColumnBox(); // We've found out which set that needs to be split. Now proceed to // inserting the spanner placeholder, and then insert a second column set. @@ -563,7 +555,6 @@ void LayoutMultiColumnFlowThread::destroySpannerPlaceholder(LayoutMultiColumnSpa && previousColumnBox && previousColumnBox->isLayoutMultiColumnSet()) { // Need to merge two column sets. nextColumnBox->destroy(); - previousColumnBox->setNeedsLayout(LayoutInvalidationReason::ColumnsChanged); invalidateColumnSets(); } } diff --git a/chromium/third_party/WebKit/Source/core/layout/MultiColumnFragmentainerGroup.cpp b/chromium/third_party/WebKit/Source/core/layout/MultiColumnFragmentainerGroup.cpp index 8c647886072..2a2ca3845bd 100644 --- a/chromium/third_party/WebKit/Source/core/layout/MultiColumnFragmentainerGroup.cpp +++ b/chromium/third_party/WebKit/Source/core/layout/MultiColumnFragmentainerGroup.cpp @@ -48,8 +48,6 @@ void MultiColumnFragmentainerGroup::resetColumnHeight() m_maxColumnHeight = calculateMaxColumnHeight(); - LayoutUnit oldColumnHeight = m_columnHeight; - LayoutMultiColumnFlowThread* flowThread = m_columnSet.multiColumnFlowThread(); LayoutMultiColumnFlowThread* enclosingFlowThread = flowThread->enclosingFlowThread(); if (enclosingFlowThread && enclosingFlowThread->isPageLogicalHeightKnown()) { @@ -63,9 +61,6 @@ void MultiColumnFragmentainerGroup::resetColumnHeight() setAndConstrainColumnHeight(heightAdjustedForRowOffset(flowThread->columnHeightAvailable())); } - if (m_columnHeight != oldColumnHeight) - m_columnSet.setChildNeedsLayout(MarkOnlyThis); - // Content runs are only needed in the initial layout pass, in order to find an initial column // height, and should have been deleted afterwards. We're about to rebuild the content runs, so // the list needs to be empty. diff --git a/chromium/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp b/chromium/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp index 384e4150c71..a72f8eb429c 100644 --- a/chromium/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp +++ b/chromium/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp @@ -200,7 +200,7 @@ CompositedLayerMapping::~CompositedLayerMapping() updateForegroundLayer(false); updateBackgroundLayer(false); updateMaskLayer(false); - updateClippingMaskLayers(false); + updateChildClippingMaskLayer(false); updateScrollingLayers(false); updateSquashingLayers(false); destroyGraphicsLayers(); @@ -466,29 +466,48 @@ bool CompositedLayerMapping::updateGraphicsLayerConfiguration() // that's plugged into another GraphicsLayer that is part of the hierarchy. // It has no parent or child GraphicsLayer. For that reason, we process it // here, after the hierarchy has been updated. - bool maskLayerChanged = false; - if (updateMaskLayer(layoutObject->hasMask())) { - maskLayerChanged = true; + bool maskLayerChanged = updateMaskLayer(layoutObject->hasMask()); + if (maskLayerChanged) m_graphicsLayer->setMaskLayer(m_maskLayer.get()); - } bool hasChildClippingLayer = compositor->clipsCompositingDescendants(&m_owningLayer) && (hasClippingLayer() || hasScrollingLayer()); // If we have a border radius or clip path on a scrolling layer, we need a clipping mask to properly // clip the scrolled contents, even if there are no composited descendants. bool hasClipPath = layoutObject->style()->clipPath(); bool needsChildClippingMask = (hasClipPath || layoutObject->style()->hasBorderRadius()) && (hasChildClippingLayer || isAcceleratedContents(layoutObject) || hasScrollingLayer()); - if (updateClippingMaskLayers(needsChildClippingMask)) { - // Clip path clips the entire subtree, including scrollbars. It must be attached directly onto - // the main m_graphicsLayer. - if (hasClipPath) + + GraphicsLayer* layerToApplyChildClippingMask = nullptr; + bool shouldApplyChildClippingMaskOnContents = false; + if (needsChildClippingMask) { + if (hasClipPath) { + // Clip path clips the entire subtree, including scrollbars. It must be attached directly onto + // the main m_graphicsLayer. + layerToApplyChildClippingMask = m_graphicsLayer.get(); + } else if (hasClippingLayer()) { + layerToApplyChildClippingMask = clippingLayer(); + } else if (hasScrollingLayer()) { + layerToApplyChildClippingMask = scrollingLayer(); + } else if (isAcceleratedContents(layoutObject)) { + shouldApplyChildClippingMaskOnContents = true; + } + } + + updateChildClippingMaskLayer(needsChildClippingMask); + + if (layerToApplyChildClippingMask == m_graphicsLayer) { + if (m_graphicsLayer->maskLayer() != m_childClippingMaskLayer.get()) { m_graphicsLayer->setMaskLayer(m_childClippingMaskLayer.get()); - else if (hasClippingLayer()) - clippingLayer()->setMaskLayer(m_childClippingMaskLayer.get()); - else if (hasScrollingLayer()) - scrollingLayer()->setMaskLayer(m_childClippingMaskLayer.get()); - else if (isAcceleratedContents(layoutObject)) - m_graphicsLayer->setContentsClippingMaskLayer(m_childClippingMaskLayer.get()); + maskLayerChanged = true; + } + } else if (m_graphicsLayer->maskLayer() && m_graphicsLayer->maskLayer() != m_maskLayer.get()) { + m_graphicsLayer->setMaskLayer(nullptr); + maskLayerChanged = true; } + if (hasClippingLayer()) + clippingLayer()->setMaskLayer(layerToApplyChildClippingMask == clippingLayer() ? m_childClippingMaskLayer.get() : nullptr); + if (hasScrollingLayer()) + scrollingLayer()->setMaskLayer(layerToApplyChildClippingMask == scrollingLayer() ? m_childClippingMaskLayer.get() : nullptr); + m_graphicsLayer->setContentsClippingMaskLayer(shouldApplyChildClippingMaskOnContents ? m_childClippingMaskLayer.get() : nullptr); if (m_owningLayer.reflectionInfo()) { if (m_owningLayer.reflectionInfo()->reflectionLayer()->hasCompositedLayerMapping()) { @@ -1542,20 +1561,16 @@ bool CompositedLayerMapping::updateMaskLayer(bool needsMaskLayer) return layerChanged; } -bool CompositedLayerMapping::updateClippingMaskLayers(bool needsChildClippingMaskLayer) +void CompositedLayerMapping::updateChildClippingMaskLayer(bool needsChildClippingMaskLayer) { - bool layerChanged = false; if (needsChildClippingMaskLayer) { if (!m_childClippingMaskLayer) { m_childClippingMaskLayer = createGraphicsLayer(CompositingReasonLayerForClippingMask); m_childClippingMaskLayer->setPaintingPhase(GraphicsLayerPaintChildClippingMask); - layerChanged = true; } - } else if (m_childClippingMaskLayer) { - m_childClippingMaskLayer = nullptr; - layerChanged = true; + return; } - return layerChanged; + m_childClippingMaskLayer = nullptr; } bool CompositedLayerMapping::updateScrollingLayers(bool needsScrollingLayers) diff --git a/chromium/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.h b/chromium/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.h index e083d9dfa20..66d68a9fc74 100644 --- a/chromium/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.h +++ b/chromium/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.h @@ -239,7 +239,7 @@ private: bool updateForegroundLayer(bool needsForegroundLayer); bool updateBackgroundLayer(bool needsBackgroundLayer); bool updateMaskLayer(bool needsMaskLayer); - bool updateClippingMaskLayers(bool needsChildClippingMaskLayer); + void updateChildClippingMaskLayer(bool needsChildClippingMaskLayer); bool requiresHorizontalScrollbarLayer() const { return m_owningLayer.scrollableArea() && m_owningLayer.scrollableArea()->horizontalScrollbar(); } bool requiresVerticalScrollbarLayer() const { return m_owningLayer.scrollableArea() && m_owningLayer.scrollableArea()->verticalScrollbar(); } bool requiresScrollCornerLayer() const { return m_owningLayer.scrollableArea() && !m_owningLayer.scrollableArea()->scrollCornerAndResizerRect().isEmpty(); } diff --git a/chromium/third_party/WebKit/Source/core/loader/FrameLoader.cpp b/chromium/third_party/WebKit/Source/core/loader/FrameLoader.cpp index 05fe06764a6..170fce2d028 100644 --- a/chromium/third_party/WebKit/Source/core/loader/FrameLoader.cpp +++ b/chromium/third_party/WebKit/Source/core/loader/FrameLoader.cpp @@ -315,7 +315,7 @@ void FrameLoader::clear() // This is the <iframe src="javascript:'html'"> case. void FrameLoader::replaceDocumentWhileExecutingJavaScriptURL(const String& source, Document* ownerDocument) { - if (!m_frame->document()->loader()) + if (!m_frame->document()->loader() || m_frame->document()->pageDismissalEventBeingDispatched() != Document::NoDismissal) return; // DocumentLoader::replaceDocumentWhileExecutingJavaScriptURL can cause the DocumentLoader to get deref'ed and possible destroyed, @@ -1058,7 +1058,7 @@ bool FrameLoader::prepareForCommit() if (pdl != m_provisionalDocumentLoader) return false; if (m_documentLoader) { - FrameNavigationDisabler navigationDisabler(m_frame); + FrameNavigationDisabler navigationDisabler(*m_frame); detachDocumentLoader(m_documentLoader); } // detachFromFrame() will abort XHRs that haven't completed, which can diff --git a/chromium/third_party/WebKit/Source/core/loader/NavigationScheduler.cpp b/chromium/third_party/WebKit/Source/core/loader/NavigationScheduler.cpp index ac4236b1b8d..04f28fe197d 100644 --- a/chromium/third_party/WebKit/Source/core/loader/NavigationScheduler.cpp +++ b/chromium/third_party/WebKit/Source/core/loader/NavigationScheduler.cpp @@ -56,17 +56,6 @@ namespace blink { unsigned NavigationDisablerForBeforeUnload::s_navigationDisableCount = 0; -FrameNavigationDisabler::FrameNavigationDisabler(LocalFrame* frame) - : m_navigationScheduler(&frame->navigationScheduler()) -{ - m_navigationScheduler->disableFrameNavigation(); -} - -FrameNavigationDisabler::~FrameNavigationDisabler() -{ - m_navigationScheduler->enableFrameNavigation(); -} - class ScheduledNavigation : public NoBaseWillBeGarbageCollectedFinalized<ScheduledNavigation> { WTF_MAKE_NONCOPYABLE(ScheduledNavigation); WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED(ScheduledNavigation); public: @@ -269,7 +258,6 @@ private: NavigationScheduler::NavigationScheduler(LocalFrame* frame) : m_frame(frame) , m_navigateTaskFactory(CancellableTaskFactory::create(this, &NavigationScheduler::navigateTask)) - , m_navigationDisableCount(0) { } @@ -293,12 +281,12 @@ bool NavigationScheduler::isNavigationScheduled() const inline bool NavigationScheduler::shouldScheduleReload() const { - return m_frame->page() && isFrameNavigationAllowed() && NavigationDisablerForBeforeUnload::isNavigationAllowed(); + return m_frame->page() && m_frame->isNavigationAllowed() && NavigationDisablerForBeforeUnload::isNavigationAllowed(); } inline bool NavigationScheduler::shouldScheduleNavigation(const String& url) const { - return m_frame->page() && isFrameNavigationAllowed() && (protocolIsJavaScript(url) || NavigationDisablerForBeforeUnload::isNavigationAllowed()); + return m_frame->page() && m_frame->isNavigationAllowed() && (protocolIsJavaScript(url) || NavigationDisablerForBeforeUnload::isNavigationAllowed()); } void NavigationScheduler::scheduleRedirect(double delay, const String& url) diff --git a/chromium/third_party/WebKit/Source/core/loader/NavigationScheduler.h b/chromium/third_party/WebKit/Source/core/loader/NavigationScheduler.h index f51dabe08b9..dc7c114aa0c 100644 --- a/chromium/third_party/WebKit/Source/core/loader/NavigationScheduler.h +++ b/chromium/third_party/WebKit/Source/core/loader/NavigationScheduler.h @@ -75,13 +75,8 @@ public: DECLARE_TRACE(); private: - friend class FrameNavigationDisabler; explicit NavigationScheduler(LocalFrame*); - void disableFrameNavigation() { ++m_navigationDisableCount; } - void enableFrameNavigation() { --m_navigationDisableCount; } - bool isFrameNavigationAllowed() const { return !m_navigationDisableCount; } - bool shouldScheduleReload() const; bool shouldScheduleNavigation(const String& url) const; @@ -93,7 +88,6 @@ private: RawPtrWillBeMember<LocalFrame> m_frame; OwnPtr<CancellableTaskFactory> m_navigateTaskFactory; OwnPtrWillBeMember<ScheduledNavigation> m_redirect; - int m_navigationDisableCount; }; class NavigationDisablerForBeforeUnload { @@ -115,17 +109,6 @@ private: static unsigned s_navigationDisableCount; }; -class FrameNavigationDisabler { - WTF_MAKE_NONCOPYABLE(FrameNavigationDisabler); - STACK_ALLOCATED(); -public: - explicit FrameNavigationDisabler(LocalFrame*); - ~FrameNavigationDisabler(); - -private: - RawPtrWillBeMember<NavigationScheduler> m_navigationScheduler; -}; - } // namespace blink #endif // NavigationScheduler_h diff --git a/chromium/third_party/WebKit/Source/core/paint/BlockFlowPainter.cpp b/chromium/third_party/WebKit/Source/core/paint/BlockFlowPainter.cpp index f2211c1aeb0..d7384cac1ac 100644 --- a/chromium/third_party/WebKit/Source/core/paint/BlockFlowPainter.cpp +++ b/chromium/third_party/WebKit/Source/core/paint/BlockFlowPainter.cpp @@ -23,7 +23,8 @@ void BlockFlowPainter::paintFloats(const PaintInfo& paintInfo, const LayoutPoint FloatingObjectSetIterator end = floatingObjectSet.end(); for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) { const FloatingObject& floatingObject = *it->get(); - if (floatingObject.isDirectlyContained() && !floatingObject.layoutObject()->hasSelfPaintingLayer()) { + // Only paint the object if our m_shouldPaint flag is set. + if (floatingObject.shouldPaint() && !floatingObject.layoutObject()->hasSelfPaintingLayer()) { PaintInfo currentPaintInfo(paintInfo); currentPaintInfo.phase = preservePhase ? paintInfo.phase : PaintPhaseBlockBackground; // FIXME: LayoutPoint version of xPositionForFloatIncludingMargin would make this much cleaner. diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/bindings/SASSSourceMapping.js b/chromium/third_party/WebKit/Source/devtools/front_end/bindings/SASSSourceMapping.js index 370fe3bdc50..642139b42b3 100644 --- a/chromium/third_party/WebKit/Source/devtools/front_end/bindings/SASSSourceMapping.js +++ b/chromium/third_party/WebKit/Source/devtools/front_end/bindings/SASSSourceMapping.js @@ -142,9 +142,11 @@ WebInspector.SASSSourceMapping.prototype = { if (!sourceURL || !header.sourceMapURL || !this._completeSourceMapURLForCSSURL[sourceURL]) return; var sourceMap = this._sourceMapByStyleSheetURL[sourceURL]; - var sources = sourceMap.sources(); - for (var i = 0; i < sources.length; ++i) - this._sassURLToCSSURLs.remove(sources[i], sourceURL); + if (sourceMap) { + var sources = sourceMap.sources(); + for (var i = 0; i < sources.length; ++i) + this._sassURLToCSSURLs.remove(sources[i], sourceURL); + } delete this._sourceMapByStyleSheetURL[sourceURL]; delete this._completeSourceMapURLForCSSURL[sourceURL]; diff --git a/chromium/third_party/WebKit/Source/devtools/front_end/timeline/timelineStatusDialog.css b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/timelineStatusDialog.css index e5ffd8b2916..83a6023b3e3 100644 --- a/chromium/third_party/WebKit/Source/devtools/front_end/timeline/timelineStatusDialog.css +++ b/chromium/third_party/WebKit/Source/devtools/front_end/timeline/timelineStatusDialog.css @@ -15,9 +15,11 @@ margin-top: -1px; } -.timeline-status-dialog div { +.timeline-status-dialog > div { margin: 2px; height: 14px; + display: flex; + align-items: baseline; } .timeline-status-dialog ::before { @@ -57,7 +59,7 @@ } .timeline-status-dialog .stop-button { - text-align: center; margin-top: 8px; height: 100%; + align-self: center; } diff --git a/chromium/third_party/WebKit/Source/platform/fonts/Character.cpp b/chromium/third_party/WebKit/Source/platform/fonts/Character.cpp index ea33001aaeb..5ea155b1d48 100644 --- a/chromium/third_party/WebKit/Source/platform/fonts/Character.cpp +++ b/chromium/third_party/WebKit/Source/platform/fonts/Character.cpp @@ -148,6 +148,14 @@ CodePath Character::characterRangeCodePath(const UChar* characters, unsigned len if (supplementaryCharacter <= 0x1F1FF) return ComplexPath; + // Man and Woman Emojies, + // in order to support emoji joiner combinations for family and couple pictographs. + // Compare http://unicode.org/reports/tr51/#Emoji_ZWJ_Sequences + if (supplementaryCharacter < 0x1F468) + continue; + if (supplementaryCharacter <= 0x1F469) + return ComplexPath; + if (supplementaryCharacter < 0xE0100) // U+E0100 through U+E01EF Unicode variation selectors. continue; if (supplementaryCharacter <= 0xE01EF) diff --git a/chromium/third_party/WebKit/Source/platform/fonts/Character.h b/chromium/third_party/WebKit/Source/platform/fonts/Character.h index bb6ef77c32f..f14fa089168 100644 --- a/chromium/third_party/WebKit/Source/platform/fonts/Character.h +++ b/chromium/third_party/WebKit/Source/platform/fonts/Character.h @@ -93,6 +93,11 @@ public: } static bool canReceiveTextEmphasis(UChar32); + static bool isModifier(UChar32 c) + { + return c >= 0x1F3FB && c <= 0x1F3FF; + } + static inline UChar normalizeSpaces(UChar character) { if (treatAsSpace(character)) diff --git a/chromium/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaper.cpp b/chromium/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaper.cpp index 65c28dffe4a..cffaf3fb73e 100644 --- a/chromium/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaper.cpp +++ b/chromium/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaper.cpp @@ -610,6 +610,8 @@ static void normalizeCharacters(const TextRun& run, unsigned length, UChar* dest character = spaceCharacter; else if (Character::treatAsZeroWidthSpaceInComplexScript(character)) character = zeroWidthSpaceCharacter; + else if (Character::isModifier(character)) + character = zeroWidthSpaceCharacter; U16_APPEND(destination, *destinationLength, length, character, error); ASSERT_UNUSED(error, !error); diff --git a/chromium/third_party/WebKit/Source/web/ChromeClientImpl.cpp b/chromium/third_party/WebKit/Source/web/ChromeClientImpl.cpp index 557722836f8..78a128c89a7 100644 --- a/chromium/third_party/WebKit/Source/web/ChromeClientImpl.cpp +++ b/chromium/third_party/WebKit/Source/web/ChromeClientImpl.cpp @@ -633,6 +633,7 @@ void ChromeClientImpl::openFileChooser(LocalFrame* frame, PassRefPtr<FileChooser params.initialValue = params.selectedFiles[0]; params.useMediaCapture = fileChooser->settings().useMediaCapture; params.needLocalPath = fileChooser->settings().allowsDirectoryUpload; + params.requestor = frame->document()->url(); WebFileChooserCompletionImpl* chooserCompletion = new WebFileChooserCompletionImpl(fileChooser); if (client->runFileChooser(params, chooserCompletion)) diff --git a/chromium/third_party/WebKit/Source/web/DevToolsEmulator.cpp b/chromium/third_party/WebKit/Source/web/DevToolsEmulator.cpp index 5d33126a0ef..63afccf836d 100644 --- a/chromium/third_party/WebKit/Source/web/DevToolsEmulator.cpp +++ b/chromium/third_party/WebKit/Source/web/DevToolsEmulator.cpp @@ -245,13 +245,13 @@ void DevToolsEmulator::enableMobileEmulation() m_emulateMobileEnabled = true; m_isOverlayScrollbarsEnabled = RuntimeEnabledFeatures::overlayScrollbarsEnabled(); RuntimeEnabledFeatures::setOverlayScrollbarsEnabled(true); + m_webViewImpl->page()->settings().setUseMobileViewportStyle(true); m_webViewImpl->enableViewport(); m_webViewImpl->settings()->setViewportMetaEnabled(true); m_webViewImpl->page()->frameHost().visualViewport().initializeScrollbars(); m_webViewImpl->settings()->setShrinksViewportContentToFit(true); m_webViewImpl->page()->settings().setTextAutosizingEnabled(true); m_webViewImpl->page()->settings().setPreferCompositingToLCDTextEnabled(true); - m_webViewImpl->page()->settings().setUseMobileViewportStyle(true); m_webViewImpl->page()->settings().setPluginsEnabled(false); m_webViewImpl->page()->settings().setAvailablePointerTypes(PointerTypeCoarse); m_webViewImpl->page()->settings().setPrimaryPointerType(PointerTypeCoarse); diff --git a/chromium/third_party/WebKit/Source/web/WebPagePopupImpl.cpp b/chromium/third_party/WebKit/Source/web/WebPagePopupImpl.cpp index 70009483bcc..fc6103311f0 100644 --- a/chromium/third_party/WebKit/Source/web/WebPagePopupImpl.cpp +++ b/chromium/third_party/WebKit/Source/web/WebPagePopupImpl.cpp @@ -124,7 +124,7 @@ private: if (m_popup->isAcceleratedCompositingActive()) { ASSERT(m_popup->m_layerTreeView); - m_popup->m_layerTreeView->setNeedsCompositorUpdate(); + m_popup->m_layerTreeView->setNeedsBeginFrame(); return; } m_popup->m_widgetClient->scheduleAnimation(); diff --git a/chromium/third_party/WebKit/Source/web/WebPageSerializerImpl.cpp b/chromium/third_party/WebKit/Source/web/WebPageSerializerImpl.cpp index 34bc016e83c..93c697a708a 100644 --- a/chromium/third_party/WebKit/Source/web/WebPageSerializerImpl.cpp +++ b/chromium/third_party/WebKit/Source/web/WebPageSerializerImpl.cpp @@ -453,9 +453,9 @@ WebPageSerializerImpl::WebPageSerializerImpl(WebFrame* frame, bool WebPageSerializerImpl::serialize() { bool didSerialization = false; - KURL mainURL = m_specifiedWebLocalFrameImpl->frame()->document()->url(); WebLocalFrameImpl* webFrame = m_specifiedWebLocalFrameImpl; + bool isMainFrame = webFrame->frame()->isMainFrame(); Document* document = webFrame->frame()->document(); const KURL& url = document->url(); @@ -463,7 +463,7 @@ bool WebPageSerializerImpl::serialize() didSerialization = true; const WTF::TextEncoding& textEncoding = document->encoding().isValid() ? document->encoding() : UTF8Encoding(); - String directoryName = url == mainURL ? m_localDirectoryName : ""; + String directoryName = isMainFrame ? m_localDirectoryName : ""; SerializeDomParam param(url, textEncoding, document, directoryName); diff --git a/chromium/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp b/chromium/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp index 5715802c81c..bd2e7d0eb13 100644 --- a/chromium/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp +++ b/chromium/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp @@ -724,8 +724,10 @@ void WebPluginContainerImpl::dispose() for (size_t i = 0; i < m_pluginLoadObservers.size(); ++i) m_pluginLoadObservers[i]->clearPluginContainer(); - if (m_webPlugin) + if (m_webPlugin) { + RELEASE_ASSERT(!m_webPlugin->container() || m_webPlugin->container() == this); m_webPlugin->destroy(); + } m_webPlugin = nullptr; if (m_webLayer) { diff --git a/chromium/third_party/WebKit/Source/wtf/HashTable.h b/chromium/third_party/WebKit/Source/wtf/HashTable.h index c85ddc2ad79..f8741730afd 100644 --- a/chromium/third_party/WebKit/Source/wtf/HashTable.h +++ b/chromium/third_party/WebKit/Source/wtf/HashTable.h @@ -151,6 +151,7 @@ private: // ListHashSet, which has its own iterators that tolerate modification // of the underlying set. ASSERT(m_containerModifications == m_container->modifications()); + ASSERT(!m_container->accessForbidden()); } public: @@ -411,7 +412,10 @@ public: ASSERT(!Allocator::isGarbageCollected); if (LIKELY(!m_table)) return; + RELEASE_ASSERT(!m_accessForbidden); + m_accessForbidden = true; deleteAllBucketsAndDeallocate(m_table, m_tableSize); + m_accessForbidden = false; m_table = nullptr; } @@ -428,9 +432,21 @@ public: const_iterator begin() const { return isEmpty() ? end() : makeConstIterator(m_table); } const_iterator end() const { return makeKnownGoodConstIterator(m_table + m_tableSize); } - unsigned size() const { return m_keyCount; } - unsigned capacity() const { return m_tableSize; } - bool isEmpty() const { return !m_keyCount; } + unsigned size() const + { + RELEASE_ASSERT(!m_accessForbidden); + return m_keyCount; + } + unsigned capacity() const + { + RELEASE_ASSERT(!m_accessForbidden); + return m_tableSize; + } + bool isEmpty() const + { + RELEASE_ASSERT(!m_accessForbidden); + return !m_keyCount; + } void reserveCapacityForSize(unsigned size); @@ -468,6 +484,7 @@ public: template <typename VisitorDispatcher> void trace(VisitorDispatcher); + bool accessForbidden() const { return m_accessForbidden; } #if ENABLE(ASSERT) int64_t modifications() const { return m_modifications; } void registerModification() { m_modifications++; } @@ -513,7 +530,11 @@ private: ValueType* reinsert(ValueType&); static void initializeBucket(ValueType& bucket); - static void deleteBucket(ValueType& bucket) { bucket.~ValueType(); Traits::constructDeletedValue(bucket, Allocator::isGarbageCollected); } + static void deleteBucket(ValueType& bucket) + { + bucket.~ValueType(); + Traits::constructDeletedValue(bucket, Allocator::isGarbageCollected); + } FullLookupType makeLookupResult(ValueType* position, bool found, unsigned hash) { return FullLookupType(LookupType(position, found), hash); } @@ -540,8 +561,9 @@ private: ValueType* m_table; unsigned m_tableSize; unsigned m_keyCount; - unsigned m_deletedCount:31; + unsigned m_deletedCount:30; unsigned m_queueFlag:1; + unsigned m_accessForbidden:1; #if ENABLE(ASSERT) unsigned m_modifications; #endif @@ -602,6 +624,7 @@ inline HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Alloca , m_keyCount(0) , m_deletedCount(0) , m_queueFlag(false) + , m_accessForbidden(false) #if ENABLE(ASSERT) , m_modifications(0) #endif @@ -652,6 +675,7 @@ template <typename Key, typename Value, typename Extractor, typename HashFunctio template <typename HashTranslator, typename T> inline const Value* HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>::lookup(T key) const { + RELEASE_ASSERT(!m_accessForbidden); ASSERT((HashTableKeyChecker<HashTranslator, KeyTraits, HashFunctions::safeToCompareToEmptyOrDeleted>::checkKey(key))); const ValueType* table = m_table; if (!table) @@ -691,6 +715,7 @@ template <typename Key, typename Value, typename Extractor, typename HashFunctio template <typename HashTranslator, typename T> inline typename HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>::LookupType HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>::lookupForWriting(const T& key) { + RELEASE_ASSERT(!m_accessForbidden); ASSERT(m_table); registerModification(); @@ -733,6 +758,7 @@ template <typename Key, typename Value, typename Extractor, typename HashFunctio template <typename HashTranslator, typename T> inline typename HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>::FullLookupType HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>::fullLookupForWriting(const T& key) { + RELEASE_ASSERT(!m_accessForbidden); ASSERT(m_table); registerModification(); @@ -801,6 +827,7 @@ template <typename Key, typename Value, typename Extractor, typename HashFunctio template <typename HashTranslator, typename T, typename Extra> typename HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>::AddResult HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>::add(const T& key, const Extra& extra) { + RELEASE_ASSERT(!m_accessForbidden); ASSERT(Allocator::isAllocationAllowed()); if (!m_table) expand(); @@ -866,6 +893,7 @@ template <typename Key, typename Value, typename Extractor, typename HashFunctio template <typename HashTranslator, typename T, typename Extra> typename HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>::AddResult HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>::addPassingHashCode(const T& key, const Extra& extra) { + RELEASE_ASSERT(!m_accessForbidden); ASSERT(Allocator::isAllocationAllowed()); if (!m_table) expand(); @@ -947,6 +975,7 @@ bool HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocato template <typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits, typename Allocator> void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>::remove(ValueType* pos) { + RELEASE_ASSERT(!m_accessForbidden); registerModification(); #if DUMP_HASHTABLE_STATS atomicIncrement(&HashTableStats::numRemoves); @@ -955,7 +984,10 @@ void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocato ++m_stats->numRemoves; #endif + RELEASE_ASSERT(!m_accessForbidden); + m_accessForbidden = true; deleteBucket(*pos); + m_accessForbidden = false; ++m_deletedCount; --m_keyCount; @@ -1092,7 +1124,11 @@ Value* HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Alloca initializeBucket(originalTable[i]); } newEntry = rehashTo(originalTable, newTableSize, newEntry); + + RELEASE_ASSERT(!m_accessForbidden); + m_accessForbidden = true; deleteAllBucketsAndDeallocate(temporaryTable, oldTableSize); + m_accessForbidden = false; return newEntry; } @@ -1162,7 +1198,11 @@ Value* HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Alloca ValueType* newTable = allocateTable(newTableSize); Value* newEntry = rehashTo(newTable, newTableSize, entry); + + RELEASE_ASSERT(!m_accessForbidden); + m_accessForbidden = true; deleteAllBucketsAndDeallocate(oldTable, oldTableSize); + m_accessForbidden = false; return newEntry; } @@ -1174,7 +1214,10 @@ void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocato if (!m_table) return; + RELEASE_ASSERT(!m_accessForbidden); + m_accessForbidden = true; deleteAllBucketsAndDeallocate(m_table, m_tableSize); + m_accessForbidden = false; m_table = nullptr; m_tableSize = 0; m_keyCount = 0; @@ -1187,6 +1230,7 @@ HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>::H , m_keyCount(0) , m_deletedCount(0) , m_queueFlag(false) + , m_accessForbidden(false) #if ENABLE(ASSERT) , m_modifications(0) #endif @@ -1205,6 +1249,7 @@ HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>::H template <typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits, typename Allocator> void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>::swap(HashTable& other) { + RELEASE_ASSERT(!m_accessForbidden); std::swap(m_table, other.m_table); std::swap(m_tableSize, other.m_tableSize); std::swap(m_keyCount, other.m_keyCount); diff --git a/chromium/third_party/WebKit/Source/wtf/PartitionAlloc.cpp b/chromium/third_party/WebKit/Source/wtf/PartitionAlloc.cpp index d076568fcfc..8a4b0dec169 100644 --- a/chromium/third_party/WebKit/Source/wtf/PartitionAlloc.cpp +++ b/chromium/third_party/WebKit/Source/wtf/PartitionAlloc.cpp @@ -164,9 +164,9 @@ void partitionAllocInit(PartitionRoot* root, size_t numBuckets, size_t maxAlloca void partitionAllocGenericInit(PartitionRootGeneric* root) { - partitionAllocBaseInit(root); + spinLockLock(&root->lock); - root->lock = 0; + partitionAllocBaseInit(root); // Precalculate some shift and mask constants used in the hot path. // Example: malloc(41) == 101001 binary. @@ -241,6 +241,8 @@ void partitionAllocGenericInit(PartitionRootGeneric* root) // And there's one last bucket lookup that will be hit for e.g. malloc(-1), // which tries to overflow to a non-existant order. *bucketPtr = &PartitionRootGeneric::gPagedBucket; + + spinLockUnlock(&root->lock); } static bool partitionAllocShutdownBucket(PartitionBucket* bucket) diff --git a/chromium/third_party/WebKit/Source/wtf/Partitions.cpp b/chromium/third_party/WebKit/Source/wtf/Partitions.cpp index 60b30dbba20..64e3b2f1276 100644 --- a/chromium/third_party/WebKit/Source/wtf/Partitions.cpp +++ b/chromium/third_party/WebKit/Source/wtf/Partitions.cpp @@ -73,18 +73,26 @@ void Partitions::setHistogramEnumeration(HistogramEnumerationFunction histogramE void Partitions::shutdown() { + spinLockLock(&s_initializationLock); + // We could ASSERT here for a memory leak within the partition, but it leads // to very hard to diagnose ASSERTs, so it's best to leave leak checking for // the valgrind and heapcheck bots, which run without partitions. - (void) m_layoutAllocator.shutdown(); - (void) m_nodeAllocator.shutdown(); - (void) m_bufferAllocator.shutdown(); - (void) m_fastMallocAllocator.shutdown(); + if (s_initialized) { + (void) m_layoutAllocator.shutdown(); + (void) m_nodeAllocator.shutdown(); + (void) m_bufferAllocator.shutdown(); + (void) m_fastMallocAllocator.shutdown(); + } + + spinLockUnlock(&s_initializationLock); } void Partitions::decommitFreeableMemory() { - ASSERT(isMainThread()); + RELEASE_ASSERT(isMainThread()); + if (!s_initialized) + return; partitionPurgeMemoryGeneric(bufferPartition(), PartitionPurgeDecommitEmptyPages); partitionPurgeMemoryGeneric(fastMallocPartition(), PartitionPurgeDecommitEmptyPages); diff --git a/chromium/third_party/WebKit/public/web/WebFileChooserParams.h b/chromium/third_party/WebKit/public/web/WebFileChooserParams.h index eaef3110659..8924f2f7360 100644 --- a/chromium/third_party/WebKit/public/web/WebFileChooserParams.h +++ b/chromium/third_party/WebKit/public/web/WebFileChooserParams.h @@ -32,6 +32,7 @@ #define WebFileChooserParams_h #include "../platform/WebString.h" +#include "../platform/WebURL.h" #include "../platform/WebVector.h" #include "WebFileChooserCompletion.h" @@ -76,6 +77,9 @@ struct WebFileChooserParams { // WebFileChooserCompletion that can handle files without local paths, // 'false' should be specified to the flag. bool needLocalPath; + // If non-empty, represents the URL of the requestor if the request was + // initiated by a document. + WebURL requestor; WebFileChooserParams() : multiSelect(false) diff --git a/chromium/third_party/WebKit/public/web/WebPlugin.h b/chromium/third_party/WebKit/public/web/WebPlugin.h index 20aaf7884cd..58888f6c19f 100644 --- a/chromium/third_party/WebKit/public/web/WebPlugin.h +++ b/chromium/third_party/WebKit/public/web/WebPlugin.h @@ -61,14 +61,21 @@ template <typename T> class WebVector; class WebPlugin { public: + // Perform any initialization work given the container this plugin will use to + // communicate with renderer code. Plugins that return false here must + // subsequently return nullptr for the container() method. virtual bool initialize(WebPluginContainer*) = 0; + + // Plugins must arrange for themselves to be deleted sometime during or after this + // method is called. virtual void destroy() = 0; - virtual WebPluginContainer* container() const { return 0; } + // Must return null container when the initialize() method returns false. + virtual WebPluginContainer* container() const { return nullptr; } virtual void containerDidDetachFromParent() { } - virtual NPObject* scriptableObject() { return 0; } - virtual struct _NPP* pluginNPP() { return 0; } + virtual NPObject* scriptableObject() { return nullptr; } + virtual struct _NPP* pluginNPP() { return nullptr; } // The same as scriptableObject() but allows to expose scriptable interface // through plain v8 object instead of NPObject. |