Merge from Chromium at DEPS revision 37.0.2062.76

This commit was generated by merge_to_master.py.

Change-Id: I73dce78cc2074876872ac401e31113b97b6cc67c
diff --git a/Source/core/css/mediaControls.css b/Source/core/css/mediaControls.css
index d3b5536..d95e26e 100644
--- a/Source/core/css/mediaControls.css
+++ b/Source/core/css/mediaControls.css
@@ -79,6 +79,8 @@
     height: 30px;
     background-color: rgba(20, 20, 20, 0.8);
     border-radius: 5px;
+    /* The duration is also specified in MediaControlElements.cpp and LayoutTests/media/media-controls.js */
+    transition: opacity 0.3s;
 }
 
 video:-webkit-full-page-media {
diff --git a/Source/core/css/parser/CSSPropertyParser.cpp b/Source/core/css/parser/CSSPropertyParser.cpp
index 5431a1a..00096d7 100644
--- a/Source/core/css/parser/CSSPropertyParser.cpp
+++ b/Source/core/css/parser/CSSPropertyParser.cpp
@@ -189,7 +189,7 @@
 
 bool CSSPropertyParser::validCalculationUnit(CSSParserValue* value, Units unitflags, ReleaseParsedCalcValueCondition releaseCalc)
 {
-    bool mustBeNonNegative = unitflags & FNonNeg;
+    bool mustBeNonNegative = unitflags & (FNonNeg | FPositiveInteger);
 
     if (!parseCalculation(value, mustBeNonNegative ? ValueRangeNonNegative : ValueRangeAll))
         return false;
@@ -199,17 +199,31 @@
     case CalcLength:
         b = (unitflags & FLength);
         break;
-    case CalcPercent:
-        b = (unitflags & FPercent);
-        if (b && mustBeNonNegative && m_parsedCalculation->isNegative())
-            b = false;
-        break;
     case CalcNumber:
         b = (unitflags & FNumber);
-        if (!b && (unitflags & FInteger) && m_parsedCalculation->isInt())
+        if (!b && (unitflags & (FInteger | FPositiveInteger)) && m_parsedCalculation->isInt())
             b = true;
         if (b && mustBeNonNegative && m_parsedCalculation->isNegative())
             b = false;
+        // Always resolve calc() to a CSS_NUMBER in the CSSParserValue if there are no non-numbers specified in the unitflags.
+        if (b && !(unitflags & ~(FInteger | FNumber | FPositiveInteger | FNonNeg))) {
+            double number = m_parsedCalculation->doubleValue();
+            if ((unitflags & FPositiveInteger) && number <= 0) {
+                b = false;
+            } else {
+                delete value->function;
+                value->unit = CSSPrimitiveValue::CSS_NUMBER;
+                value->fValue = number;
+                value->isInt = m_parsedCalculation->isInt();
+            }
+            m_parsedCalculation.release();
+            return b;
+        }
+        break;
+    case CalcPercent:
+        b = (unitflags & FPercent);
+        if (b && mustBeNonNegative && m_parsedCalculation->isNegative())
+            b = false;
         break;
     case CalcPercentLength:
         b = (unitflags & FPercent) && (unitflags & FLength);
@@ -606,7 +620,7 @@
 
             Vector<int> coords;
             value = m_valueList->next();
-            while (value && value->unit == CSSPrimitiveValue::CSS_NUMBER) {
+            while (value && validUnit(value, FNumber)) {
                 coords.append(int(value->fValue));
                 value = m_valueList->next();
             }
@@ -1282,10 +1296,7 @@
             validPrimitive = validUnit(value, FLength | FNonNeg);
         break;
     case CSSPropertyWebkitColumnSpan: // none | all | 1 (will be dropped in the unprefixed property)
-        if (id == CSSValueAll || id == CSSValueNone)
-            validPrimitive = true;
-        else
-            validPrimitive = validUnit(value, FNumber | FNonNeg) && value->fValue == 1;
+        validPrimitive = id == CSSValueAll || id == CSSValueNone || (value->unit == CSSPrimitiveValue::CSS_NUMBER && value->fValue == 1);
         break;
     case CSSPropertyWebkitColumnWidth:         // auto | <length>
         parsedValue = parseColumnWidth();
@@ -1957,8 +1968,7 @@
     CSSParserValue* value = m_valueList->current();
     // Always parse lengths in strict mode here, since it would be ambiguous otherwise when used in
     // the 'columns' shorthand property.
-    if (value->id == CSSValueAuto
-        || (validUnit(value, FLength | FNonNeg, HTMLStandardMode) && value->fValue)) {
+    if (value->id == CSSValueAuto || (validUnit(value, FLength | FNonNeg, HTMLStandardMode) && (m_parsedCalculation || value->fValue != 0))) {
         RefPtrWillBeRawPtr<CSSValue> parsedValue = parseValidPrimitive(value->id, value);
         m_valueList->next();
         return parsedValue;
@@ -4721,7 +4731,7 @@
         addProperty(CSSPropertyFontWeight, cssValuePool().createIdentifierValue(value->id), important);
         return true;
     }
-    if (validUnit(value, FInteger | FNonNeg, HTMLQuirksMode)) {
+    if (value->unit == CSSPrimitiveValue::CSS_NUMBER) {
         int weight = static_cast<int>(value->fValue);
         if (!(weight % 100) && weight >= 100 && weight <= 900) {
             addProperty(CSSPropertyFontWeight, cssValuePool().createIdentifierValue(static_cast<CSSValueID>(CSSValue100 + weight / 100 - 1)), important);
@@ -5216,14 +5226,6 @@
 
 template bool CSSPropertyParser::fastParseColor(RGBA32&, const String&, bool strict);
 
-inline double CSSPropertyParser::parsedDouble(CSSParserValue *v, ReleaseParsedCalcValueCondition releaseCalc)
-{
-    const double result = m_parsedCalculation ? m_parsedCalculation->doubleValue() : v->fValue;
-    if (releaseCalc == ReleaseParsedCalcValue)
-        m_parsedCalculation.release();
-    return result;
-}
-
 bool CSSPropertyParser::isCalculation(CSSParserValue* value)
 {
     return (value->unit == CSSParserValue::Function)
@@ -5236,13 +5238,16 @@
 inline int CSSPropertyParser::colorIntFromValue(CSSParserValue* v)
 {
     bool isPercent;
+    double value;
 
-    if (m_parsedCalculation)
+    if (m_parsedCalculation) {
         isPercent = m_parsedCalculation->category() == CalcPercent;
-    else
+        value = m_parsedCalculation->doubleValue();
+        m_parsedCalculation.release();
+    } else {
         isPercent = v->unit == CSSPrimitiveValue::CSS_PERCENTAGE;
-
-    const double value = parsedDouble(v, ReleaseParsedCalcValue);
+        value = v->fValue;
+    }
 
     if (value <= 0.0)
         return 0;
@@ -5289,10 +5294,9 @@
         v = args->next();
         if (!validUnit(v, FNumber, HTMLStandardMode))
             return false;
-        const double value = parsedDouble(v, ReleaseParsedCalcValue);
         // Convert the floating pointer number of alpha to an integer in the range [0, 256),
         // with an equal distribution across all 256 values.
-        colorArray[3] = static_cast<int>(std::max(0.0, std::min(1.0, value)) * nextafter(256.0, 0.0));
+        colorArray[3] = static_cast<int>(std::max(0.0, std::min(1.0, v->fValue)) * nextafter(256.0, 0.0));
     }
     return true;
 }
@@ -5310,7 +5314,7 @@
     if (!validUnit(v, FNumber, HTMLStandardMode))
         return false;
     // normalize the Hue value and change it to be between 0 and 1.0
-    colorArray[0] = (((static_cast<int>(parsedDouble(v, ReleaseParsedCalcValue)) % 360) + 360) % 360) / 360.0;
+    colorArray[0] = (((static_cast<int>(v->fValue) % 360) + 360) % 360) / 360.0;
     for (int i = 1; i < 3; i++) {
         v = args->next();
         if (v->unit != CSSParserValue::Operator && v->iValue != ',')
@@ -5318,7 +5322,8 @@
         v = args->next();
         if (!validUnit(v, FPercent, HTMLStandardMode))
             return false;
-        colorArray[i] = std::max(0.0, std::min(100.0, parsedDouble(v, ReleaseParsedCalcValue))) / 100.0; // needs to be value between 0 and 1.0
+        double percentValue = m_parsedCalculation ? m_parsedCalculation.release()->doubleValue() : v->fValue;
+        colorArray[i] = std::max(0.0, std::min(100.0, percentValue)) / 100.0; // needs to be value between 0 and 1.0
     }
     if (parseAlpha) {
         v = args->next();
@@ -5327,7 +5332,7 @@
         v = args->next();
         if (!validUnit(v, FNumber, HTMLStandardMode))
             return false;
-        colorArray[3] = std::max(0.0, std::min(1.0, parsedDouble(v, ReleaseParsedCalcValue)));
+        colorArray[3] = std::max(0.0, std::min(1.0, v->fValue));
     }
     return true;
 }
@@ -7261,10 +7266,13 @@
 
         if (args->size()) {
             CSSParserValue* value = args->current();
-            if (!validUnit(value, FNumber | FPercent | FNonNeg, HTMLStandardMode))
+            // FIXME (crbug.com/397061): Support calc expressions like calc(10% + 0.5)
+            if (value->unit != CSSPrimitiveValue::CSS_PERCENTAGE && !validUnit(value, FNumber | FNonNeg, HTMLStandardMode))
                 return nullptr;
 
             double amount = value->fValue;
+            if (amount < 0)
+                return nullptr;
 
             // Saturate and Contrast allow values over 100%.
             if (filterType != CSSFilterValue::SaturateFilterOperation
@@ -7285,7 +7293,8 @@
 
         if (args->size()) {
             CSSParserValue* value = args->current();
-            if (!validUnit(value, FNumber | FPercent, HTMLStandardMode))
+            // FIXME (crbug.com/397061): Support calc expressions like calc(10% + 0.5)
+            if (value->unit != CSSPrimitiveValue::CSS_PERCENTAGE && !validUnit(value, FNumber, HTMLStandardMode))
                 return nullptr;
 
             filterValue->append(cssValuePool().createValue(value->fValue, static_cast<CSSPrimitiveValue::UnitType>(value->unit)));
diff --git a/Source/core/css/parser/CSSPropertyParser.h b/Source/core/css/parser/CSSPropertyParser.h
index 1fc7656..482e240 100644
--- a/Source/core/css/parser/CSSPropertyParser.h
+++ b/Source/core/css/parser/CSSPropertyParser.h
@@ -366,7 +366,6 @@
 
     bool parseBorderImageQuad(Units, RefPtrWillBeRawPtr<CSSPrimitiveValue>&);
     int colorIntFromValue(CSSParserValue*);
-    double parsedDouble(CSSParserValue*, ReleaseParsedCalcValueCondition releaseCalc = DoNotReleaseParsedCalcValue);
     bool isCalculation(CSSParserValue*);
 
 private:
diff --git a/Source/core/dom/ContainerNode.cpp b/Source/core/dom/ContainerNode.cpp
index 18da27a..815c331 100644
--- a/Source/core/dom/ContainerNode.cpp
+++ b/Source/core/dom/ContainerNode.cpp
@@ -294,6 +294,8 @@
     if (nextChild.previousSibling() == newChild || &nextChild == newChild) // nothing to do
         return;
 
+    RefPtrWillBeRawPtr<Node> protect(this);
+
     if (document() != newChild->document())
         document().adoptNode(newChild.get(), ASSERT_NO_EXCEPTION);
 
@@ -303,9 +305,7 @@
 
     ChildListMutationScope(*this).childAdded(*newChild);
 
-    childrenChanged(true, newChild->previousSibling(), &nextChild, 1);
-
-    notifyNodeInserted(*newChild);
+    notifyNodeInserted(*newChild, ChildrenChangeSourceParser);
 }
 
 void ContainerNode::replaceChild(PassRefPtrWillBeRawPtr<Node> newChild, Node* oldChild, ExceptionState& exceptionState)
@@ -482,8 +482,8 @@
         Node* prev = child->previousSibling();
         Node* next = child->nextSibling();
         removeBetween(prev, next, *child);
-        childrenChanged(false, prev, next, -1);
         notifyNodeRemoved(*child);
+        childrenChanged(false, prev, next, -1);
     }
     dispatchSubtreeModifiedEvent();
 }
@@ -564,23 +564,29 @@
         document().nodeChildrenWillBeRemoved(*this);
     }
 
-
+    // FIXME: Remove this NodeVector. Right now WebPluginContainerImpl::m_element is a
+    // raw ptr which means the code below can drop the last ref to a plugin element and
+    // then the code in UpdateSuspendScope::performDeferredWidgetTreeOperations will
+    // try to destroy the plugin which will be a use-after-free. We should use a RefPtr
+    // in the WebPluginContainerImpl instead.
     NodeVector removedChildren;
     {
         HTMLFrameOwnerElement::UpdateSuspendScope suspendWidgetHierarchyUpdates;
+
         {
             NoEventDispatchAssertion assertNoEventDispatch;
+            ScriptForbiddenScope forbidScript;
+
             removedChildren.reserveInitialCapacity(countChildren());
-            while (m_firstChild) {
-                removedChildren.append(m_firstChild);
-                removeBetween(0, m_firstChild->nextSibling(), *m_firstChild);
+
+            while (RefPtrWillBeRawPtr<Node> child = m_firstChild) {
+                removeBetween(0, child->nextSibling(), *child);
+                removedChildren.append(child.get());
+                notifyNodeRemoved(*child);
             }
         }
 
         childrenChanged(false, 0, 0, -static_cast<int>(removedChildren.size()));
-
-        for (size_t i = 0; i < removedChildren.size(); ++i)
-            notifyNodeRemoved(*removedChildren[i]);
     }
 
     dispatchSubtreeModifiedEvent();
@@ -651,11 +657,11 @@
     ASSERT(!newChild->isDocumentFragment());
     ASSERT(!isHTMLTemplateElement(this));
 
+    RefPtrWillBeRawPtr<Node> protect(this);
+
     if (document() != newChild->document())
         document().adoptNode(newChild.get(), ASSERT_NO_EXCEPTION);
 
-    Node* last = m_lastChild;
-
     {
         NoEventDispatchAssertion assertNoEventDispatch;
         ScriptForbiddenScope forbidScript;
@@ -666,11 +672,10 @@
         ChildListMutationScope(*this).childAdded(*newChild);
     }
 
-    childrenChanged(true, last, 0, 1);
-    notifyNodeInserted(*newChild);
+    notifyNodeInserted(*newChild, ChildrenChangeSourceParser);
 }
 
-void ContainerNode::notifyNodeInserted(Node& root)
+void ContainerNode::notifyNodeInserted(Node& root, ChildrenChangeSource source)
 {
     ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
 
@@ -682,6 +687,14 @@
     NodeVector postInsertionNotificationTargets;
     notifyNodeInsertedInternal(root, postInsertionNotificationTargets);
 
+    // ShadowRoots are not real children, we don't need to tell host that it's
+    // children changed when one is added.
+    // FIXME: We should have a separate code path for ShadowRoot since it only
+    // needs to call insertedInto and the rest of this logic is not needed.
+    if (!root.isShadowRoot()) {
+        childrenChanged(source == ChildrenChangeSourceParser, root.previousSibling(), root.nextSibling(), 1);
+    }
+
     for (size_t i = 0; i < postInsertionNotificationTargets.size(); ++i) {
         Node* targetNode = postInsertionNotificationTargets[i].get();
         if (targetNode->inDocument())
@@ -1093,8 +1106,6 @@
 
     ChildListMutationScope(*this).childAdded(child);
 
-    childrenChanged(false, child.previousSibling(), child.nextSibling(), 1);
-
     notifyNodeInserted(child);
 
     dispatchChildInsertionEvents(child);
diff --git a/Source/core/dom/ContainerNode.h b/Source/core/dom/ContainerNode.h
index 4df98d4..d625acb 100644
--- a/Source/core/dom/ContainerNode.h
+++ b/Source/core/dom/ContainerNode.h
@@ -165,7 +165,8 @@
 
     virtual void trace(Visitor*) OVERRIDE;
 
-    void notifyNodeInserted(Node&);
+    enum ChildrenChangeSource { ChildrenChangeSourceAPI, ChildrenChangeSourceParser };
+    void notifyNodeInserted(Node&, ChildrenChangeSource = ChildrenChangeSourceAPI);
     void notifyNodeRemoved(Node&);
 
 protected:
diff --git a/Source/core/dom/Document.cpp b/Source/core/dom/Document.cpp
index fe9c3b0..1d157db 100644
--- a/Source/core/dom/Document.cpp
+++ b/Source/core/dom/Document.cpp
@@ -576,10 +576,8 @@
     if (m_styleSheetList)
         m_styleSheetList->detachFromDocument();
 
-    if (m_importsController) {
-        m_importsController->wasDetachedFrom(*this);
-        m_importsController = nullptr;
-    }
+    if (m_importsController)
+        HTMLImportsController::removeFrom(*this);
 
     m_timeline->detachFromDocument();
 
@@ -633,10 +631,8 @@
 
     m_registrationContext.clear();
 
-    if (m_importsController) {
-        m_importsController->wasDetachedFrom(*this);
-        m_importsController = nullptr;
-    }
+    if (m_importsController)
+        HTMLImportsController::removeFrom(*this);
 
     // removeDetachedChildren() doesn't always unregister IDs,
     // so tear down scope information upfront to avoid having stale references in the map.
@@ -1811,6 +1807,9 @@
 {
     ASSERT(isMainThread());
 
+    if (!view() || !isActive())
+        return;
+
     if (change != Force && !needsRenderTreeUpdate())
         return;
 
diff --git a/Source/core/dom/Element.cpp b/Source/core/dom/Element.cpp
index a75add2..428a617 100644
--- a/Source/core/dom/Element.cpp
+++ b/Source/core/dom/Element.cpp
@@ -2504,12 +2504,15 @@
 {
     if (!hasAttributes())
         return;
-    // attributeCount() cannot be cached before the loop because the attributes
-    // list is altered while iterating.
-    for (unsigned i = 0; i < attributeCount(); ++i) {
-        if (RefPtrWillBeRawPtr<Attr> attr = attrIfExists(attributeAt(i).name()))
-            attr->normalize();
-    }
+    WillBeHeapVector<RefPtrWillBeMember<Attr> >* attrNodes = attrNodeList();
+    if (!attrNodes)
+        return;
+    // Copy the Attr Vector because Node::normalize() can fire synchronous JS
+    // events (e.g. DOMSubtreeModified) and a JS listener could add / remove
+    // attributes while we are iterating.
+    WillBeHeapVector<RefPtrWillBeMember<Attr> > attrNodesCopy(*attrNodes);
+    for (size_t i = 0; i < attrNodesCopy.size(); ++i)
+        attrNodesCopy[i]->normalize();
 }
 
 void Element::updatePseudoElement(PseudoId pseudoId, StyleRecalcChange change)
@@ -3203,14 +3206,6 @@
     return true;
 }
 
-bool Element::setInlineStyleProperty(CSSPropertyID propertyID, CSSPropertyID identifier, bool important)
-{
-    ASSERT(isStyledElement());
-    ensureMutableInlineStyle().setProperty(propertyID, cssValuePool().createIdentifierValue(identifier), important);
-    inlineStyleChanged();
-    return true;
-}
-
 bool Element::setInlineStyleProperty(CSSPropertyID propertyID, double value, CSSPrimitiveValue::UnitType unit, bool important)
 {
     ASSERT(isStyledElement());
diff --git a/Source/core/dom/Element.h b/Source/core/dom/Element.h
index b3972e8..ed0c3fa 100644
--- a/Source/core/dom/Element.h
+++ b/Source/core/dom/Element.h
@@ -271,7 +271,6 @@
     const StylePropertySet* inlineStyle() const { return elementData() ? elementData()->m_inlineStyle.get() : 0; }
 
     bool setInlineStyleProperty(CSSPropertyID, CSSValueID identifier, bool important = false);
-    bool setInlineStyleProperty(CSSPropertyID, CSSPropertyID identifier, bool important = false);
     bool setInlineStyleProperty(CSSPropertyID, double value, CSSPrimitiveValue::UnitType, bool important = false);
     bool setInlineStyleProperty(CSSPropertyID, const String& value, bool important = false);
     bool removeInlineStyleProperty(CSSPropertyID);
diff --git a/Source/core/dom/FullscreenElementStack.cpp b/Source/core/dom/FullscreenElementStack.cpp
index b5363bc..b22f3a2 100644
--- a/Source/core/dom/FullscreenElementStack.cpp
+++ b/Source/core/dom/FullscreenElementStack.cpp
@@ -126,7 +126,7 @@
     m_fullScreenErrorEventTargetQueue.clear();
 
     if (m_fullScreenRenderer)
-        setFullScreenRenderer(0);
+        m_fullScreenRenderer->destroy();
 
 #if ENABLE(OILPAN)
     m_fullScreenElement = nullptr;
@@ -475,7 +475,7 @@
     }
 
     if (m_fullScreenRenderer)
-        m_fullScreenRenderer->destroy();
+        m_fullScreenRenderer->unwrapRenderer();
     ASSERT(!m_fullScreenRenderer);
 
     m_fullScreenRenderer = renderer;
diff --git a/Source/core/dom/ProcessingInstruction.cpp b/Source/core/dom/ProcessingInstruction.cpp
index bff917d..6390e04 100644
--- a/Source/core/dom/ProcessingInstruction.cpp
+++ b/Source/core/dom/ProcessingInstruction.cpp
@@ -57,7 +57,7 @@
 {
 #if !ENABLE(OILPAN)
     if (m_sheet)
-        m_sheet->clearOwnerNode();
+        clearSheet();
 
     // FIXME: ProcessingInstruction should not be in document here.
     // However, if we add ASSERT(!inDocument()), fast/xsl/xslt-entity.xml
@@ -90,8 +90,9 @@
 
 void ProcessingInstruction::didAttributeChanged()
 {
-    ASSERT(!m_sheet);
-    ASSERT(!isLoading());
+    if (m_sheet)
+        clearSheet();
+
     String href;
     String charset;
     if (!checkStyleSheet(href, charset))
@@ -211,6 +212,11 @@
 
 void ProcessingInstruction::setXSLStyleSheet(const String& href, const KURL& baseURL, const String& sheet)
 {
+    if (!inDocument()) {
+        ASSERT(!m_sheet);
+        return;
+    }
+
     ASSERT(m_isXSL);
     m_sheet = XSLStyleSheet::create(this, href, baseURL);
     parseStyleSheet(sheet);
@@ -274,8 +280,7 @@
 
     if (m_sheet) {
         ASSERT(m_sheet->ownerNode() == this);
-        m_sheet->clearOwnerNode();
-        m_sheet = nullptr;
+        clearSheet();
     }
 
     // If we're in document teardown, then we don't need to do any notification of our sheet's removal.
@@ -283,6 +288,14 @@
         document().removedStyleSheet(removedSheet.get());
 }
 
+void ProcessingInstruction::clearSheet()
+{
+    ASSERT(m_sheet);
+    if (m_sheet->isLoading())
+        document().styleEngine()->removePendingSheet(this);
+    m_sheet.release()->clearOwnerNode();
+}
+
 void ProcessingInstruction::trace(Visitor* visitor)
 {
     visitor->trace(m_sheet);
diff --git a/Source/core/dom/ProcessingInstruction.h b/Source/core/dom/ProcessingInstruction.h
index 60528e0..5f50a72 100644
--- a/Source/core/dom/ProcessingInstruction.h
+++ b/Source/core/dom/ProcessingInstruction.h
@@ -71,6 +71,7 @@
     virtual bool sheetLoaded() OVERRIDE;
 
     void parseStyleSheet(const String& sheet);
+    void clearSheet();
 
     String m_target;
     String m_localHref;
diff --git a/Source/core/editing/FrameSelection.cpp b/Source/core/editing/FrameSelection.cpp
index e8802b2..a737752 100644
--- a/Source/core/editing/FrameSelection.cpp
+++ b/Source/core/editing/FrameSelection.cpp
@@ -222,7 +222,7 @@
     bool shouldClearTypingStyle = options & ClearTypingStyle;
     EUserTriggered userTriggered = selectionOptionsToUserTriggered(options);
 
-    VisibleSelection s = newSelection;
+    VisibleSelection s = validateSelection(newSelection);
     if (shouldAlwaysUseDirectionalSelection(m_frame))
         s.setIsDirectional(true);
 
@@ -1838,6 +1838,28 @@
     m_observingVisibleSelection = false;
 }
 
+VisibleSelection FrameSelection::validateSelection(const VisibleSelection& selection)
+{
+    if (!m_frame || selection.isNone())
+        return selection;
+
+    Position base = selection.base();
+    Position extent = selection.extent();
+    bool isBaseValid = base.document() == m_frame->document();
+    bool isExtentValid = extent.document() == m_frame->document();
+
+    if (isBaseValid && isExtentValid)
+        return selection;
+
+    VisibleSelection newSelection;
+    if (isBaseValid) {
+        newSelection.setWithoutValidation(base, base);
+    } else if (isExtentValid) {
+        newSelection.setWithoutValidation(extent, extent);
+    }
+    return newSelection;
+}
+
 void FrameSelection::startObservingVisibleSelectionChange()
 {
     ASSERT(!m_observingVisibleSelection);
diff --git a/Source/core/editing/FrameSelection.h b/Source/core/editing/FrameSelection.h
index c3555ae..bd4838b 100644
--- a/Source/core/editing/FrameSelection.h
+++ b/Source/core/editing/FrameSelection.h
@@ -261,6 +261,8 @@
     void startObservingVisibleSelectionChange();
     void stopObservingVisibleSelectionChangeIfNecessary();
 
+    VisibleSelection validateSelection(const VisibleSelection&);
+
     LocalFrame* m_frame;
 
     LayoutUnit m_xPosForVerticalArrowNavigation;
diff --git a/Source/core/html/HTMLFormElement.cpp b/Source/core/html/HTMLFormElement.cpp
index 18ef044..b9d57bf 100644
--- a/Source/core/html/HTMLFormElement.cpp
+++ b/Source/core/html/HTMLFormElement.cpp
@@ -70,6 +70,8 @@
     , m_hasElementsAssociatedByParser(false)
     , m_didFinishParsingChildren(false)
     , m_wasUserSubmitted(false)
+    , m_isSubmittingOrInUserJSSubmitEvent(false)
+    , m_shouldSubmit(false)
     , m_isInResetFunction(false)
     , m_wasDemoted(false)
     , m_pendingAutocompleteEventsQueue(GenericEventQueue::create(this))
@@ -307,16 +309,24 @@
 {
     RefPtrWillBeRawPtr<HTMLFormElement> protector(this);
     LocalFrame* frame = document().frame();
-    if (!frame)
+    if (!frame || m_isSubmittingOrInUserJSSubmitEvent)
         return;
 
     // Interactive validation must be done before dispatching the submit event.
     if (!validateInteractively(event))
         return;
 
+    m_isSubmittingOrInUserJSSubmitEvent = true;
+    m_shouldSubmit = false;
+
     frame->loader().client()->dispatchWillSendSubmitEvent(this);
 
     if (dispatchEvent(Event::createCancelableBubble(EventTypeNames::submit)))
+        m_shouldSubmit = true;
+
+    m_isSubmittingOrInUserJSSubmitEvent = false;
+
+    if (m_shouldSubmit)
         submit(event, true, true, NotSubmittedByJavaScript);
 }
 
@@ -347,6 +357,12 @@
     if (!view || !frame || !frame->page())
         return;
 
+    if (m_isSubmittingOrInUserJSSubmitEvent) {
+        m_shouldSubmit = true;
+        return;
+    }
+
+    m_isSubmittingOrInUserJSSubmitEvent = true;
     m_wasUserSubmitted = processingUserGesture;
 
     RefPtrWillBeRawPtr<HTMLFormControlElement> firstSuccessfulSubmitButton = nullptr;
@@ -378,6 +394,9 @@
 
     if (needButtonActivation && firstSuccessfulSubmitButton)
         firstSuccessfulSubmitButton->setActivatedSubmit(false);
+
+    m_shouldSubmit = false;
+    m_isSubmittingOrInUserJSSubmitEvent = false;
 }
 
 void HTMLFormElement::scheduleFormSubmission(PassRefPtrWillBeRawPtr<FormSubmission> submission)
@@ -491,7 +510,7 @@
         // If the new action attribute is pointing to insecure "action" location from a secure page
         // it is marked as "passive" mixed content.
         KURL actionURL = document().completeURL(m_attributes.action().isEmpty() ? document().url().string() : m_attributes.action());
-        if (MixedContentChecker::isMixedContent(document().securityOrigin(), actionURL))
+        if (document().frame() && MixedContentChecker::isMixedContent(document().securityOrigin(), actionURL))
             document().frame()->loader().mixedContentChecker()->canSubmitToInsecureForm(document().securityOrigin(), actionURL);
     } else if (name == targetAttr)
         m_attributes.setTarget(value);
diff --git a/Source/core/html/HTMLFormElement.h b/Source/core/html/HTMLFormElement.h
index b4fb479..3453700 100644
--- a/Source/core/html/HTMLFormElement.h
+++ b/Source/core/html/HTMLFormElement.h
@@ -177,6 +177,8 @@
     bool m_didFinishParsingChildren;
 
     bool m_wasUserSubmitted;
+    bool m_isSubmittingOrInUserJSSubmitEvent;
+    bool m_shouldSubmit;
 
     bool m_isInResetFunction;
 
diff --git a/Source/core/html/HTMLOptionElement.cpp b/Source/core/html/HTMLOptionElement.cpp
index 79239f4..c2ae7a7 100644
--- a/Source/core/html/HTMLOptionElement.cpp
+++ b/Source/core/html/HTMLOptionElement.cpp
@@ -343,6 +343,14 @@
     return HTMLElement::insertedInto(insertionPoint);
 }
 
+void HTMLOptionElement::removedFrom(ContainerNode* insertionPoint)
+{
+    if (HTMLSelectElement* select = Traversal<HTMLSelectElement>::firstAncestorOrSelf(*insertionPoint)) {
+        select->setRecalcListItems();
+    }
+    HTMLElement::removedFrom(insertionPoint);
+}
+
 String HTMLOptionElement::collectOptionInnerText() const
 {
     StringBuilder text;
diff --git a/Source/core/html/HTMLOptionElement.h b/Source/core/html/HTMLOptionElement.h
index 65e1a23..611aa19 100644
--- a/Source/core/html/HTMLOptionElement.h
+++ b/Source/core/html/HTMLOptionElement.h
@@ -68,6 +68,8 @@
 
     bool isDisplayNone() const;
 
+    virtual void removedFrom(ContainerNode* insertionPoint) OVERRIDE;
+
 private:
     explicit HTMLOptionElement(Document&);
 
diff --git a/Source/core/html/imports/HTMLImportTreeRoot.cpp b/Source/core/html/imports/HTMLImportTreeRoot.cpp
index bfe0bed..3b53834 100644
--- a/Source/core/html/imports/HTMLImportTreeRoot.cpp
+++ b/Source/core/html/imports/HTMLImportTreeRoot.cpp
@@ -22,7 +22,7 @@
     , m_document(document)
     , m_recalcTimer(this, &HTMLImportTreeRoot::recalcTimerFired)
 {
-    recalcTreeState(this); // This recomputes initial state.
+    scheduleRecalcState(); // This recomputes initial state.
 }
 
 HTMLImportTreeRoot::~HTMLImportTreeRoot()
diff --git a/Source/core/html/imports/HTMLImportsController.cpp b/Source/core/html/imports/HTMLImportsController.cpp
index 8afd0dd..c6e165a 100644
--- a/Source/core/html/imports/HTMLImportsController.cpp
+++ b/Source/core/html/imports/HTMLImportsController.cpp
@@ -42,12 +42,23 @@
 
 namespace WebCore {
 
-void HTMLImportsController::provideTo(Document& master)
+const char* HTMLImportsController::supplementName()
 {
     DEFINE_STATIC_LOCAL(const char*, name, ("HTMLImportsController"));
+    return name;
+}
+
+void HTMLImportsController::provideTo(Document& master)
+{
     OwnPtrWillBeRawPtr<HTMLImportsController> controller = adoptPtrWillBeNoop(new HTMLImportsController(master));
     master.setImportsController(controller.get());
-    DocumentSupplement::provideTo(master, name, controller.release());
+    DocumentSupplement::provideTo(master, supplementName(), controller.release());
+}
+
+void HTMLImportsController::removeFrom(Document& master)
+{
+    static_cast<DocumentSupplementable&>(master).removeSupplement(supplementName());
+    master.setImportsController(nullptr);
 }
 
 HTMLImportsController::HTMLImportsController(Document& master)
@@ -59,24 +70,13 @@
 HTMLImportsController::~HTMLImportsController()
 {
 #if !ENABLE(OILPAN)
-    ASSERT(!m_root);
-#endif
-}
-
-#if !ENABLE(OILPAN)
-void HTMLImportsController::clear()
-{
-    Document* master = root()->document();
     m_root.clear();
 
     for (size_t i = 0; i < m_loaders.size(); ++i)
         m_loaders[i]->importDestroyed();
     m_loaders.clear();
-
-    if (master)
-        master->setImportsController(0);
-}
 #endif
+}
 
 static bool makesCycle(HTMLImport* parent, const KURL& url)
 {
@@ -144,15 +144,6 @@
     return root()->state().shouldBlockScriptExecution();
 }
 
-#if !ENABLE(OILPAN)
-void HTMLImportsController::wasDetachedFrom(const Document& document)
-{
-    ASSERT(document.importsController() == this);
-    if (master() == &document)
-        clear();
-}
-#endif
-
 HTMLImportLoader* HTMLImportsController::createLoader()
 {
     m_loaders.append(HTMLImportLoader::create(this));
diff --git a/Source/core/html/imports/HTMLImportsController.h b/Source/core/html/imports/HTMLImportsController.h
index 414fe46..4cbc5d7 100644
--- a/Source/core/html/imports/HTMLImportsController.h
+++ b/Source/core/html/imports/HTMLImportsController.h
@@ -55,7 +55,9 @@
     WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(HTMLImportsController);
     WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
 public:
+    static const char* supplementName();
     static void provideTo(Document&);
+    static void removeFrom(Document&);
 
     explicit HTMLImportsController(Document&);
     virtual ~HTMLImportsController();
@@ -63,9 +65,6 @@
     HTMLImportTreeRoot* root() const { return m_root.get(); }
 
     bool shouldBlockScriptExecution(const Document&) const;
-#if !ENABLE(OILPAN)
-    void wasDetachedFrom(const Document&);
-#endif
     HTMLImportChild* load(HTMLImport* parent, HTMLImportChildClient*, FetchRequest);
 
     Document* master() const;
@@ -81,9 +80,6 @@
 
 private:
     HTMLImportChild* createChild(const KURL&, HTMLImportLoader*, HTMLImport* parent, HTMLImportChildClient*);
-#if !ENABLE(OILPAN)
-    void clear();
-#endif
 
     OwnPtrWillBeMember<HTMLImportTreeRoot> m_root;
     typedef WillBeHeapVector<OwnPtrWillBeMember<HTMLImportLoader> > LoaderList;
diff --git a/Source/core/html/shadow/MediaControlElements.cpp b/Source/core/html/shadow/MediaControlElements.cpp
index 674675f..12c6f22 100644
--- a/Source/core/html/shadow/MediaControlElements.cpp
+++ b/Source/core/html/shadow/MediaControlElements.cpp
@@ -55,9 +55,7 @@
 static const AtomicString& getMediaControlCurrentTimeDisplayElementShadowPseudoId();
 static const AtomicString& getMediaControlTimeRemainingDisplayElementShadowPseudoId();
 
-// If you change any of the following fade durations, then also update the
-// corresponding values in LayoutTests/media/media-controls.js.
-static const double fadeInDuration = 0.1;
+// This is the duration from mediaControls.css
 static const double fadeOutDuration = 0.3;
 
 MediaControlPanelElement::MediaControlPanelElement(MediaControls& mediaControls)
@@ -120,10 +118,7 @@
     if (m_opaque)
         return;
 
-    setInlineStyleProperty(CSSPropertyTransitionProperty, CSSPropertyOpacity);
-    setInlineStyleProperty(CSSPropertyTransitionDuration, fadeInDuration, CSSPrimitiveValue::CSS_S);
     setInlineStyleProperty(CSSPropertyOpacity, 1.0, CSSPrimitiveValue::CSS_NUMBER);
-
     m_opaque = true;
 
     if (m_isDisplayed)
@@ -135,8 +130,6 @@
     if (!m_opaque)
         return;
 
-    setInlineStyleProperty(CSSPropertyTransitionProperty, CSSPropertyOpacity);
-    setInlineStyleProperty(CSSPropertyTransitionDuration, fadeOutDuration, CSSPrimitiveValue::CSS_S);
     setInlineStyleProperty(CSSPropertyOpacity, 0.0, CSSPrimitiveValue::CSS_NUMBER);
 
     m_opaque = false;
diff --git a/Source/core/html/shadow/SliderThumbElement.cpp b/Source/core/html/shadow/SliderThumbElement.cpp
index 3e9ab2f..7e200bc 100644
--- a/Source/core/html/shadow/SliderThumbElement.cpp
+++ b/Source/core/html/shadow/SliderThumbElement.cpp
@@ -193,6 +193,11 @@
         // so nothing else would otherwise invalidate the slider.
         paintInvalidationForWholeRenderer();
     }
+
+    // We need one-off invalidation code here because painting of the timeline element does not go through style.
+    // Instead it has a custom implementation in C++ code.
+    // Therefore the style system cannot understand when it needs to be repainted.
+    setShouldDoFullPaintInvalidationAfterLayout(true);
 }
 
 // --------------------------------
diff --git a/Source/core/loader/MixedContentChecker.cpp b/Source/core/loader/MixedContentChecker.cpp
index 75e9737..5202917 100644
--- a/Source/core/loader/MixedContentChecker.cpp
+++ b/Source/core/loader/MixedContentChecker.cpp
@@ -90,6 +90,17 @@
     return allowed;
 }
 
+bool MixedContentChecker::canSubmitToInsecureForm(SecurityOrigin* securityOrigin, const KURL& url) const
+{
+    // For whatever reason, some folks handle forms via JavaScript, and submit to `javascript:void(0)`
+    // rather than calling `preventDefault()`. We special-case `javascript:` URLs here, as they don't
+    // introduce MixedContent for form submissions.
+    if (url.protocolIs("javascript"))
+        return true;
+
+    return canDisplayInsecureContentInternal(securityOrigin, url, MixedContentChecker::Submission);
+}
+
 void MixedContentChecker::logWarning(bool allowed, const KURL& target, const MixedContentType type) const
 {
     StringBuilder message;
diff --git a/Source/core/loader/MixedContentChecker.h b/Source/core/loader/MixedContentChecker.h
index e749b67..8fd99e6 100644
--- a/Source/core/loader/MixedContentChecker.h
+++ b/Source/core/loader/MixedContentChecker.h
@@ -49,10 +49,6 @@
     {
         return canDisplayInsecureContentInternal(securityOrigin, url, MixedContentChecker::Display);
     }
-    bool canSubmitToInsecureForm(SecurityOrigin* securityOrigin, const KURL& url) const
-    {
-        return canDisplayInsecureContentInternal(securityOrigin, url, MixedContentChecker::Submission);
-    }
 
     bool canRunInsecureContent(SecurityOrigin* securityOrigin, const KURL& url) const
     {
@@ -62,6 +58,8 @@
     {
         return canRunInsecureContentInternal(securityOrigin, url, MixedContentChecker::WebSocket);
     }
+
+    bool canSubmitToInsecureForm(SecurityOrigin*, const KURL&) const;
     static bool isMixedContent(SecurityOrigin*, const KURL&);
 
 private:
diff --git a/Source/core/rendering/HitTestResult.cpp b/Source/core/rendering/HitTestResult.cpp
index bce5019..60ef749 100644
--- a/Source/core/rendering/HitTestResult.cpp
+++ b/Source/core/rendering/HitTestResult.cpp
@@ -275,6 +275,16 @@
 
 KURL HitTestResult::absoluteImageURL() const
 {
+    return absoluteImageURLInternal(false);
+}
+
+KURL HitTestResult::absoluteImageURLIncludingCanvasDataURL() const
+{
+    return absoluteImageURLInternal(true);
+}
+
+KURL HitTestResult::absoluteImageURLInternal(bool allowCanvas) const
+{
     if (!m_innerNonSharedNode)
         return KURL();
 
@@ -283,7 +293,7 @@
         return KURL();
 
     AtomicString urlString;
-    if (isHTMLCanvasElement(*m_innerNonSharedNode)
+    if ((allowCanvas && isHTMLCanvasElement(*m_innerNonSharedNode))
         || isHTMLEmbedElement(*m_innerNonSharedNode)
         || isHTMLImageElement(*m_innerNonSharedNode)
         || isHTMLInputElement(*m_innerNonSharedNode)
diff --git a/Source/core/rendering/HitTestResult.h b/Source/core/rendering/HitTestResult.h
index 4db557a..12984ca 100644
--- a/Source/core/rendering/HitTestResult.h
+++ b/Source/core/rendering/HitTestResult.h
@@ -103,6 +103,9 @@
     Image* image() const;
     IntRect imageRect() const;
     KURL absoluteImageURL() const;
+    // This variant of absoluteImageURL will also convert <canvas> elements
+    // to huge image data URLs (very expensive).
+    KURL absoluteImageURLIncludingCanvasDataURL() const;
     KURL absoluteMediaURL() const;
     KURL absoluteLinkURL() const;
     String textContent() const;
@@ -125,6 +128,7 @@
     Node* targetNode() const;
 
 private:
+    KURL absoluteImageURLInternal(bool allowCanvas) const;
     NodeSet& mutableRectBasedTestResult(); // See above.
     HTMLMediaElement* mediaElement() const;
 
diff --git a/Source/core/rendering/RenderBox.cpp b/Source/core/rendering/RenderBox.cpp
index 93d8928..1804c3b 100644
--- a/Source/core/rendering/RenderBox.cpp
+++ b/Source/core/rendering/RenderBox.cpp
@@ -4135,11 +4135,18 @@
 
     if (style()->hasOutline()) {
         LayoutUnit outlineSize = style()->outlineSize();
-
-        overflowMinX = min(overflowMinX, borderBox.x() - outlineSize);
-        overflowMaxX = max(overflowMaxX, borderBox.maxX() + outlineSize);
-        overflowMinY = min(overflowMinY, borderBox.y() - outlineSize);
-        overflowMaxY = max(overflowMaxY, borderBox.maxY() + outlineSize);
+        LayoutRect outlineBox;
+        if (style()->outlineStyleIsAuto()) {
+            Vector<IntRect> focusRingRects;
+            addFocusRingRects(focusRingRects, LayoutPoint(), this);
+            outlineBox = unionRect(focusRingRects);
+        } else {
+            outlineBox = borderBox;
+        }
+        overflowMinX = min(overflowMinX, outlineBox.x() - outlineSize);
+        overflowMaxX = max(overflowMaxX, outlineBox.maxX() + outlineSize);
+        overflowMinY = min(overflowMinY, outlineBox.y() - outlineSize);
+        overflowMaxY = max(overflowMaxY, outlineBox.maxY() + outlineSize);
     }
 
     // Add in the final overflow with shadows, outsets and outline combined.
diff --git a/Source/core/rendering/RenderFullScreen.cpp b/Source/core/rendering/RenderFullScreen.cpp
index 9ce9810..e767450 100644
--- a/Source/core/rendering/RenderFullScreen.cpp
+++ b/Source/core/rendering/RenderFullScreen.cpp
@@ -170,7 +170,7 @@
     if (placeholder())
         placeholder()->remove();
     remove();
-    FullscreenElementStack::from(document()).setFullScreenRenderer(0);
+    destroy();
 }
 
 void RenderFullScreen::setPlaceholder(RenderBlock* placeholder)
diff --git a/Source/core/rendering/RenderInline.cpp b/Source/core/rendering/RenderInline.cpp
index 80664b5..79bca9c 100644
--- a/Source/core/rendering/RenderInline.cpp
+++ b/Source/core/rendering/RenderInline.cpp
@@ -147,16 +147,29 @@
 static void updateStyleOfAnonymousBlockContinuations(RenderObject* block, const RenderStyle* newStyle, const RenderStyle* oldStyle)
 {
     for (;block && block->isAnonymousBlock(); block = block->nextSibling()) {
-        if (!toRenderBlock(block)->isAnonymousBlockContinuation() || block->style()->position() == newStyle->position())
+        if (!toRenderBlock(block)->isAnonymousBlockContinuation())
             continue;
-        // If we are no longer in-flow positioned but our descendant block(s) still have an in-flow positioned ancestor then
-        // their containing anonymous block should keep its in-flow positioning.
+
         RenderInline* cont = toRenderBlock(block)->inlineElementContinuation();
-        if (oldStyle->hasInFlowPosition() && inFlowPositionedInlineAncestor(cont))
-            continue;
         RefPtr<RenderStyle> blockStyle = RenderStyle::createAnonymousStyleWithDisplay(block->style(), BLOCK);
-        blockStyle->setPosition(newStyle->position());
-        block->setStyle(blockStyle);
+
+        if (!block->style()->isOutlineEquivalent(newStyle)) {
+            blockStyle->setOutlineWidth(newStyle->outlineWidth());
+            blockStyle->setOutlineStyle(newStyle->outlineStyle());
+            blockStyle->setOutlineOffset(newStyle->outlineOffset());
+            blockStyle->setOutlineColor(block->resolveColor(newStyle, CSSPropertyOutlineColor));
+            blockStyle->setOutlineStyleIsAuto(newStyle->outlineStyleIsAuto());
+            block->setStyle(blockStyle);
+        }
+
+        if (block->style()->position() != newStyle->position()) {
+            // If we are no longer in-flow positioned but our descendant block(s) still have an in-flow positioned ancestor then
+            // their containing anonymous block should keep its in-flow positioning.
+            if (oldStyle->hasInFlowPosition() && inFlowPositionedInlineAncestor(cont))
+                continue;
+            blockStyle->setPosition(newStyle->position());
+            block->setStyle(blockStyle);
+        }
     }
 }
 
@@ -181,12 +194,13 @@
 
     // If an inline's in-flow positioning has changed then any descendant blocks will need to change their in-flow positioning accordingly.
     // Do this by updating the position of the descendant blocks' containing anonymous blocks - there may be more than one.
-    if (continuation && oldStyle && newStyle->position() != oldStyle->position()
-        && (newStyle->hasInFlowPosition() || oldStyle->hasInFlowPosition())) {
+    if (continuation && oldStyle
+        && (!newStyle->isOutlineEquivalent(oldStyle)
+            || (newStyle->position() != oldStyle->position() && (newStyle->hasInFlowPosition() || oldStyle->hasInFlowPosition())))) {
         // If any descendant blocks exist then they will be in the next anonymous block and its siblings.
         RenderObject* block = containingBlock()->nextSibling();
-        ASSERT(block && block->isAnonymousBlock());
-        updateStyleOfAnonymousBlockContinuations(block, newStyle, oldStyle);
+        if (block && block->isAnonymousBlock())
+            updateStyleOfAnonymousBlockContinuations(block, newStyle, oldStyle);
     }
 
     if (!m_alwaysCreateLineBoxes) {
diff --git a/Source/core/rendering/RenderObject.cpp b/Source/core/rendering/RenderObject.cpp
index 90af71b..ccabfcd 100644
--- a/Source/core/rendering/RenderObject.cpp
+++ b/Source/core/rendering/RenderObject.cpp
@@ -2148,7 +2148,9 @@
             container->setNeedsOverflowRecalcAfterStyleChange();
     }
 
-    if (updatedDiff.needsRepaint()) {
+    if (updatedDiff.needsRepaintLayer()) {
+        toRenderLayerModelObject(this)->layer()->repainter().repaintIncludingNonCompositingDescendants();
+    } else if (updatedDiff.needsRepaint()) {
         // Invalidate paints with the new style, e.g., for example if we go from not having
         // an outline to having an outline.
         if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled() && needsLayout())
diff --git a/Source/core/rendering/compositing/RenderLayerCompositor.cpp b/Source/core/rendering/compositing/RenderLayerCompositor.cpp
index 5d35300..925084c 100644
--- a/Source/core/rendering/compositing/RenderLayerCompositor.cpp
+++ b/Source/core/rendering/compositing/RenderLayerCompositor.cpp
@@ -390,6 +390,9 @@
         ASSERT(!layer->hasCompositedLayerMapping());
         setCompositingModeEnabled(true);
 
+        // If we need to repaint, do so before allocating the compositedLayerMapping and clearing out the groupedMapping.
+        repaintOnCompositingChange(layer);
+
         // If this layer was previously squashed, we need to remove its reference to a groupedMapping right away, so
         // that computing repaint rects will know the layer's correct compositingState.
         // FIXME: do we need to also remove the layer from it's location in the squashing list of its groupedMapping?
@@ -398,8 +401,6 @@
         layer->setLostGroupedMapping(false);
         layer->setGroupedMapping(0);
 
-        // If we need to repaint, do so before allocating the compositedLayerMapping
-        repaintOnCompositingChange(layer);
         layer->ensureCompositedLayerMapping();
         compositedLayerMappingChanged = true;
 
diff --git a/Source/core/rendering/style/RenderStyle.h b/Source/core/rendering/style/RenderStyle.h
index 543c815..ba527a5 100644
--- a/Source/core/rendering/style/RenderStyle.h
+++ b/Source/core/rendering/style/RenderStyle.h
@@ -1084,6 +1084,13 @@
     void setOutlineStyleIsAuto(OutlineIsAuto isAuto) { SET_VAR(m_background, m_outline.m_isAuto, isAuto); }
     void setOutlineStyle(EBorderStyle v) { SET_VAR(m_background, m_outline.m_style, v); }
     void setOutlineColor(const StyleColor& v) { SET_BORDERVALUE_COLOR(m_background, m_outline, v); }
+    bool isOutlineEquivalent(const RenderStyle* otherStyle) const
+    {
+        // No other style, so we don't have an outline then we consider them to be the same.
+        if (!otherStyle)
+            return !hasOutline();
+        return m_background->outline().visuallyEqual(otherStyle->m_background->outline());
+    }
 
     void setOverflowX(EOverflow v) { noninherited_flags._overflowX = v; }
     void setOverflowY(EOverflow v) { noninherited_flags._overflowY = v; }
diff --git a/Source/core/rendering/svg/RenderSVGResourceFilter.cpp b/Source/core/rendering/svg/RenderSVGResourceFilter.cpp
index 80f0a30..744419f 100644
--- a/Source/core/rendering/svg/RenderSVGResourceFilter.cpp
+++ b/Source/core/rendering/svg/RenderSVGResourceFilter.cpp
@@ -146,10 +146,16 @@
         filterData->filter->enableCache();
     FloatRect boundaries = enclosingIntRect(filterData->boundaries);
     context->save();
-    float scaledArea = boundaries.width() * boundaries.height();
+
+    FloatSize deviceSize = context->getCTM().mapSize(boundaries.size());
+    float scaledArea = deviceSize.width() * deviceSize.height();
 
     // If area of scaled size is bigger than the upper limit, adjust the scale
-    // to fit.
+    // to fit. Note that this only really matters in the non-impl-side painting
+    // case, since the impl-side case never allocates a full-sized backing
+    // store, only tile-sized.
+    // FIXME: remove this once all platforms are using impl-side painting.
+    // crbug.com/169282.
     if (scaledArea > FilterEffect::maxFilterArea()) {
         float scale = sqrtf(FilterEffect::maxFilterArea() / scaledArea);
         context->scale(scale, scale);
diff --git a/Source/platform/fonts/Character.cpp b/Source/platform/fonts/Character.cpp
index a9898c9..40ccd3e 100644
--- a/Source/platform/fonts/Character.cpp
+++ b/Source/platform/fonts/Character.cpp
@@ -112,12 +112,6 @@
         0x1A00, 0x1CFF,
         // U+1DC0 through U+1DFF Comining diacritical mark supplement
         0x1DC0, 0x1DFF,
-        // RIGHT-TO-LEFT MARK
-        0x200B, 0x200F,
-        // RIGHT-TO-LEFT OVERRIDE
-        0x202A, 0x202E,
-        // Nominal Digit Shape
-        0x2060, 0x206F,
         // U+20D0 through U+20FF Combining marks for symbols
         0x20D0, 0x20FF,
         // U+2CEF through U+2CF1 Combining marks for Coptic
diff --git a/Source/web/WebViewImpl.cpp b/Source/web/WebViewImpl.cpp
index 26b579f..6eed6fc 100644
--- a/Source/web/WebViewImpl.cpp
+++ b/Source/web/WebViewImpl.cpp
@@ -3179,7 +3179,7 @@
 
     HitTestResult result = hitTestResultForWindowPos(point);
 
-    if (result.absoluteImageURL().isEmpty()) {
+    if (result.absoluteImageURLIncludingCanvasDataURL().isEmpty()) {
         // There isn't actually an image at these coordinates.  Might be because
         // the window scrolled while the context menu was open or because the page
         // changed itself between when we thought there was an image here and when
@@ -3198,7 +3198,7 @@
     if (!m_page)
         return;
 
-    KURL url = hitTestResultForWindowPos(point).absoluteImageURL();
+    KURL url = hitTestResultForWindowPos(point).absoluteImageURLIncludingCanvasDataURL();
 
     if (url.isEmpty())
         return;