Merge from Chromium at DEPS revision 37.0.2062.52

This commit was generated by merge_to_master.py.

Change-Id: I1bf506f391be506dc38ecd000e584736a4bbc4d5
diff --git a/Source/core/html/HTMLMetaElement-in.cpp b/Source/core/html/HTMLMetaElement-in.cpp
index ebf418a..7850520 100644
--- a/Source/core/html/HTMLMetaElement-in.cpp
+++ b/Source/core/html/HTMLMetaElement-in.cpp
@@ -72,13 +72,12 @@
     bool error = false;
 
     // Tread lightly in this code -- it was specifically designed to mimic Win IE's parsing behavior.
-    int keyBegin, keyEnd;
-    int valueBegin, valueEnd;
+    unsigned keyBegin, keyEnd;
+    unsigned valueBegin, valueEnd;
 
-    int i = 0;
-    int length = content.length();
     String buffer = content.lower();
-    while (i < length) {
+    unsigned length = buffer.length();
+    for (unsigned i = 0; i < length; /* no increment here */) {
         // skip to first non-separator, but don't skip past the end of the string
         while (isSeparator(buffer[i])) {
             if (i >= length)
@@ -90,6 +89,8 @@
         // skip to first separator
         while (!isSeparator(buffer[i])) {
             error |= isInvalidSeparator(buffer[i]);
+            if (i >= length)
+                break;
             i++;
         }
         keyEnd = i;
@@ -113,6 +114,8 @@
         // skip to first separator
         while (!isSeparator(buffer[i])) {
             error |= isInvalidSeparator(buffer[i]);
+            if (i >= length)
+                break;
             i++;
         }
         valueEnd = i;
diff --git a/Source/core/html/RadioNodeList.cpp b/Source/core/html/RadioNodeList.cpp
index ed77909..423badc 100644
--- a/Source/core/html/RadioNodeList.cpp
+++ b/Source/core/html/RadioNodeList.cpp
@@ -90,6 +90,11 @@
     }
 }
 
+bool RadioNodeList::matchesByIdOrName(const Element& testElement) const
+{
+    return testElement.getIdAttribute() == m_name || testElement.getNameAttribute() == m_name;
+}
+
 bool RadioNodeList::checkElementMatchesRadioNodeListFilter(const Element& testElement) const
 {
     ASSERT(!m_onlyMatchImgElements);
@@ -100,7 +105,7 @@
             return false;
     }
 
-    return testElement.getIdAttribute() == m_name || testElement.getNameAttribute() == m_name;
+    return matchesByIdOrName(testElement);
 }
 
 bool RadioNodeList::elementMatches(const Element& element) const
@@ -108,7 +113,11 @@
     if (m_onlyMatchImgElements) {
         if (!isHTMLImageElement(element))
             return false;
-        return toHTMLElement(element).formOwner() == ownerNode();
+
+        if (toHTMLElement(element).formOwner() != ownerNode())
+            return false;
+
+        return matchesByIdOrName(element);
     }
 
     if (!isHTMLObjectElement(element) && !element.isFormControlElement())
diff --git a/Source/core/html/RadioNodeList.h b/Source/core/html/RadioNodeList.h
index 09eb8d0..5dbd7b6 100644
--- a/Source/core/html/RadioNodeList.h
+++ b/Source/core/html/RadioNodeList.h
@@ -50,6 +50,8 @@
 
     bool checkElementMatchesRadioNodeListFilter(const Element&) const;
 
+    bool matchesByIdOrName(const Element&) const;
+
     virtual bool elementMatches(const Element&) const OVERRIDE;
 
     AtomicString m_name;
@@ -59,4 +61,3 @@
 } // namespace
 
 #endif
-
diff --git a/Source/core/rendering/RenderBlock.cpp b/Source/core/rendering/RenderBlock.cpp
index d926fee..0846060 100644
--- a/Source/core/rendering/RenderBlock.cpp
+++ b/Source/core/rendering/RenderBlock.cpp
@@ -1219,7 +1219,7 @@
         // we need to remove ourself and fix the continuation chain.
         if (!beingDestroyed() && isAnonymousBlockContinuation() && !oldChild->isListMarker()) {
             RenderObject* containingBlockIgnoringAnonymous = containingBlock();
-            while (containingBlockIgnoringAnonymous && containingBlockIgnoringAnonymous->isAnonymousBlock())
+            while (containingBlockIgnoringAnonymous && containingBlockIgnoringAnonymous->isAnonymous())
                 containingBlockIgnoringAnonymous = containingBlockIgnoringAnonymous->containingBlock();
             for (RenderObject* curr = this; curr; curr = curr->previousInPreOrder(containingBlockIgnoringAnonymous)) {
                 if (curr->virtualContinuation() != this)
diff --git a/Source/core/rendering/RenderLayer.cpp b/Source/core/rendering/RenderLayer.cpp
index 7a9aa24..6b7ba1c 100644
--- a/Source/core/rendering/RenderLayer.cpp
+++ b/Source/core/rendering/RenderLayer.cpp
@@ -1728,7 +1728,8 @@
     OverlapTestRequestMap overlapTestRequests;
 
     LayerPaintingInfo paintingInfo(this, enclosingIntRect(damageRect), paintBehavior, LayoutSize(), paintingRoot, &overlapTestRequests);
-    paintLayer(context, paintingInfo, paintFlags);
+    if (shouldPaintLayerInSoftwareMode(context, paintingInfo, paintFlags))
+        paintLayer(context, paintingInfo, paintFlags);
 
     OverlapTestRequestMap::iterator end = overlapTestRequests.end();
     for (OverlapTestRequestMap::iterator it = overlapTestRequests.begin(); it != end; ++it)
@@ -1815,11 +1816,6 @@
     overlapTestRequests.removeAll(overlappedRequestClients);
 }
 
-static bool shouldDoSoftwarePaint(const RenderLayer* layer, bool paintingReflection)
-{
-    return paintingReflection && !layer->has3DTransform();
-}
-
 static inline bool shouldSuppressPaintingLayer(RenderLayer* layer)
 {
     // Avoid painting descendants of the root layer when stylesheets haven't loaded. This eliminates FOUC.
@@ -1846,17 +1842,9 @@
     // https://code.google.com/p/chromium/issues/detail?id=343772
     DisableCompositingQueryAsserts disabler;
 
-    if (compositingState() != NotComposited && compositingState() != PaintsIntoGroupedBacking) {
-        // The updatingControlTints() painting pass goes through compositing layers,
-        // but we need to ensure that we don't cache clip rects computed with the wrong root in this case.
+    if (compositingState() != NotComposited) {
         if (context->updatingControlTints() || (paintingInfo.paintBehavior & PaintBehaviorFlattenCompositingLayers)) {
             paintFlags |= PaintLayerTemporaryClipRects;
-        } else if (!compositedLayerMapping()->paintsIntoCompositedAncestor()
-            && !shouldDoSoftwarePaint(this, paintFlags & PaintLayerPaintingReflection)
-            && !paintForFixedRootBackground(this, paintFlags)) {
-            // If this RenderLayer should paint into its own backing, that will be done via CompositedLayerMapping::paintContents()
-            // and CompositedLayerMapping::doPaintTask().
-            return;
         }
     } else if (viewportConstrainedNotCompositedReason() == NotCompositedForBoundsOutOfView) {
         // Don't paint out-of-view viewport constrained layers (when doing prepainting) because they will never be visible
@@ -2186,6 +2174,18 @@
     paintLayerContentsAndReflection(context, transformedPaintingInfo, paintFlags);
 }
 
+bool RenderLayer::shouldPaintLayerInSoftwareMode(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags)
+{
+    DisableCompositingQueryAsserts disabler;
+
+    return compositingState() == NotComposited
+        || compositingState() == HasOwnBackingButPaintsIntoAncestor
+        || context->updatingControlTints()
+        || (paintingInfo.paintBehavior & PaintBehaviorFlattenCompositingLayers)
+        || ((paintFlags & PaintLayerPaintingReflection) && !has3DTransform())
+        || paintForFixedRootBackground(this, paintFlags);
+}
+
 void RenderLayer::paintChildren(unsigned childrenToVisit, GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags)
 {
     if (!hasSelfPaintingLayerDescendant())
@@ -2198,9 +2198,9 @@
     RenderLayerStackingNodeIterator iterator(*m_stackingNode, childrenToVisit);
     while (RenderLayerStackingNode* child = iterator.next()) {
         RenderLayer* childLayer = child->layer();
-
-        // Squashed RenderLayers should not paint into their ancestor.
-        if (childLayer->compositingState() == PaintsIntoGroupedBacking)
+        // If this RenderLayer should paint into its own backing or a grouped backing, that will be done via CompositedLayerMapping::paintContents()
+        // and CompositedLayerMapping::doPaintTask().
+        if (!childLayer->shouldPaintLayerInSoftwareMode(context, paintingInfo, paintFlags))
             continue;
 
         if (!childLayer->isPaginated())
diff --git a/Source/core/rendering/RenderLayer.h b/Source/core/rendering/RenderLayer.h
index 804bab9..6e43a0b 100644
--- a/Source/core/rendering/RenderLayer.h
+++ b/Source/core/rendering/RenderLayer.h
@@ -526,6 +526,11 @@
 
     void paintLayerContentsAndReflection(GraphicsContext*, const LayerPaintingInfo&, PaintLayerFlags);
     void paintLayerByApplyingTransform(GraphicsContext*, const LayerPaintingInfo&, PaintLayerFlags, const LayoutPoint& translationOffset = LayoutPoint());
+
+    // Returns whether this layer should be painted during sofware painting (i.e., not via calls from CompositedLayerMapping to draw into composited
+    // layers).
+    bool shouldPaintLayerInSoftwareMode(GraphicsContext*, const LayerPaintingInfo&, PaintLayerFlags paintFlags);
+
     void paintChildren(unsigned childrenToVisit, GraphicsContext*, const LayerPaintingInfo&, PaintLayerFlags);
     void paintPaginatedChildLayer(RenderLayer* childLayer, GraphicsContext*, const LayerPaintingInfo&, PaintLayerFlags);
     void paintChildLayerIntoColumns(RenderLayer* childLayer, GraphicsContext*, const LayerPaintingInfo&, PaintLayerFlags, const Vector<RenderLayer*>& columnLayers, size_t columnIndex);
diff --git a/Source/devtools/front_end/console/ConsoleView.js b/Source/devtools/front_end/console/ConsoleView.js
index 42770fa..4ae9cf5 100644
--- a/Source/devtools/front_end/console/ConsoleView.js
+++ b/Source/devtools/front_end/console/ConsoleView.js
@@ -172,6 +172,14 @@
     },
 
     /**
+     * @return {number}
+     */
+    minimumRowHeight: function()
+    {
+        return 16;
+    },
+
+    /**
      * @param {!WebInspector.Target} target
      */
     targetAdded: function(target)
diff --git a/Source/devtools/front_end/console/ConsoleViewMessage.js b/Source/devtools/front_end/console/ConsoleViewMessage.js
index b79e3eb..80697a5 100644
--- a/Source/devtools/front_end/console/ConsoleViewMessage.js
+++ b/Source/devtools/front_end/console/ConsoleViewMessage.js
@@ -105,7 +105,7 @@
     {
         if (this._cachedHeight)
             return this._cachedHeight;
-        const defaultConsoleRowHeight = 17;
+        const defaultConsoleRowHeight = 16;
         if (this._message.type === WebInspector.ConsoleMessage.MessageType.Table) {
             var table = this._message.parameters[0];
             if (table && table.preview)
diff --git a/Source/devtools/front_end/sources/FilteredItemSelectionDialog.js b/Source/devtools/front_end/sources/FilteredItemSelectionDialog.js
index e0558bb..b5deee9 100644
--- a/Source/devtools/front_end/sources/FilteredItemSelectionDialog.js
+++ b/Source/devtools/front_end/sources/FilteredItemSelectionDialog.js
@@ -379,6 +379,14 @@
         return new WebInspector.StaticViewportElement(element);
     },
 
+    /**
+     * @return {number}
+     */
+    minimumRowHeight: function()
+    {
+        return this.fastHeight(0);
+    },
+
     __proto__: WebInspector.DialogDelegate.prototype
 }
 
diff --git a/Source/devtools/front_end/ui/ViewportControl.js b/Source/devtools/front_end/ui/ViewportControl.js
index 130cfbc..87d9165 100644
--- a/Source/devtools/front_end/ui/ViewportControl.js
+++ b/Source/devtools/front_end/ui/ViewportControl.js
@@ -77,6 +77,11 @@
     itemCount: function() { return 0; },
 
     /**
+     * @return {number}
+     */
+    minimumRowHeight: function() { return 0; },
+
+    /**
      * @param {number} index
      * @return {?WebInspector.ViewportElement}
      */
@@ -364,10 +369,12 @@
         this._rebuildCumulativeHeightsIfNeeded();
         if (shouldStickToBottom) {
             this._lastVisibleIndex = itemCount - 1;
-            this._firstVisibleIndex = Math.max(Array.prototype.lowerBound.call(this._cumulativeHeights, this._cumulativeHeights[this._cumulativeHeights.length - 1] - clientHeight), 0);
+            this._firstVisibleIndex = Math.max(itemCount - Math.ceil(clientHeight / this._provider.minimumRowHeight()), 0);
         } else {
-            this._firstVisibleIndex = Math.max(Array.prototype.lowerBound.call(this._cumulativeHeights, visibleFrom), 0);
-            this._lastVisibleIndex = Math.min(Array.prototype.upperBound.call(this._cumulativeHeights, visibleFrom + clientHeight - 1), itemCount - 1);
+            this._firstVisibleIndex = Math.max(Array.prototype.lowerBound.call(this._cumulativeHeights, visibleFrom + 1), 0);
+            // Proactively render more rows in case some of them will be collapsed without triggering refresh. @see crbug.com/390169
+            this._lastVisibleIndex = this._firstVisibleIndex + Math.ceil(clientHeight / this._provider.minimumRowHeight()) - 1;
+            this._lastVisibleIndex = Math.min(this._lastVisibleIndex, itemCount - 1);
         }
         var topGapHeight = this._cumulativeHeights[this._firstVisibleIndex - 1] || 0;
         var bottomGapHeight = this._cumulativeHeights[this._cumulativeHeights.length - 1] - this._cumulativeHeights[this._lastVisibleIndex];
@@ -443,8 +450,6 @@
      */
     _textOffsetInNode: function(itemElement, container, offset)
     {
-        if (!offset)
-            return 0;
         var chars = 0;
         var node = itemElement;
         while ((node = node.traverseNextTextNode()) && node !== container)
diff --git a/Source/modules/EventTargetModulesFactory.in b/Source/modules/EventTargetModulesFactory.in
index c06ac2c..a0de143 100644
--- a/Source/modules/EventTargetModulesFactory.in
+++ b/Source/modules/EventTargetModulesFactory.in
@@ -21,6 +21,7 @@
 modules/serviceworkers/ServiceWorker
 modules/serviceworkers/ServiceWorkerGlobalScope
 modules/speech/SpeechRecognition
+modules/speech/SpeechSynthesis
 modules/speech/SpeechSynthesisUtterance
 modules/webaudio/AudioContext Conditional=WEB_AUDIO
 modules/webaudio/AudioNode Conditional=WEB_AUDIO
diff --git a/Source/modules/speech/SpeechSynthesis.cpp b/Source/modules/speech/SpeechSynthesis.cpp
index 64f7297..39c384d 100644
--- a/Source/modules/speech/SpeechSynthesis.cpp
+++ b/Source/modules/speech/SpeechSynthesis.cpp
@@ -230,7 +230,7 @@
 
 const AtomicString& SpeechSynthesis::interfaceName() const
 {
-    return EventTargetNames::SpeechSynthesisUtterance;
+    return EventTargetNames::SpeechSynthesis;
 }
 
 void SpeechSynthesis::trace(Visitor* visitor)
diff --git a/Source/platform/RuntimeEnabledFeatures.in b/Source/platform/RuntimeEnabledFeatures.in
index 709bfb3..9bedcea 100644
--- a/Source/platform/RuntimeEnabledFeatures.in
+++ b/Source/platform/RuntimeEnabledFeatures.in
@@ -58,7 +58,7 @@
 EncryptedMediaAnyVersion status=stable
 ExperimentalCanvasFeatures status=test
 ExperimentalContentSecurityPolicyFeatures status=experimental
-ExperimentalWebSocket status=stable
+ExperimentalWebSocket status=test
 FastMobileScrolling
 FileAPIBlobClose status=experimental
 FileConstructor status=experimental
diff --git a/Source/platform/fonts/win/FontFallbackWin.cpp b/Source/platform/fonts/win/FontFallbackWin.cpp
index a83e339..d8afcdc 100644
--- a/Source/platform/fonts/win/FontFallbackWin.cpp
+++ b/Source/platform/fonts/win/FontFallbackWin.cpp
@@ -69,6 +69,22 @@
 // which works well since the range of UScriptCode values is small.
 typedef const UChar* ScriptToFontMap[USCRIPT_CODE_LIMIT];
 
+void initializeScriptMonospaceFontMap(ScriptToFontMap& scriptFontMap, SkFontMgr* fontManager)
+{
+    struct FontMap {
+        UScriptCode script;
+        const UChar* family;
+    };
+
+    static const FontMap fontMap[] = {
+        { USCRIPT_HEBREW, L"courier new" },
+        { USCRIPT_ARABIC, L"courier new" },
+    };
+
+    for (size_t i = 0; i < WTF_ARRAY_LENGTH(fontMap); ++i)
+        scriptFontMap[fontMap[i].script] = fontMap[i].family;
+}
+
 void initializeScriptFontMap(ScriptToFontMap& scriptFontMap, SkFontMgr* fontManager)
 {
     struct FontMap {
@@ -259,14 +275,18 @@
     SkFontMgr* fontManager)
 {
     static ScriptToFontMap scriptFontMap;
+    static ScriptToFontMap scriptMonospaceFontMap;
     static bool initialized = false;
     if (!initialized) {
         initializeScriptFontMap(scriptFontMap, fontManager);
+        initializeScriptMonospaceFontMap(scriptMonospaceFontMap, fontManager);
         initialized = true;
     }
     if (script == USCRIPT_INVALID_CODE)
         return 0;
     ASSERT(script < USCRIPT_CODE_LIMIT);
+    if (generic == FontDescription::MonospaceFamily && scriptMonospaceFontMap[script])
+        return scriptMonospaceFontMap[script];
     return scriptFontMap[script];
 }
 
diff --git a/Source/platform/heap/Heap.cpp b/Source/platform/heap/Heap.cpp
index df3f5a8..55ce1f2 100644
--- a/Source/platform/heap/Heap.cpp
+++ b/Source/platform/heap/Heap.cpp
@@ -841,10 +841,11 @@
             // threads alive until their heaps become empty instead of
             // forcing the threads to die immediately?
             ASSERT(Heap::lastGCWasConservative() || basicHeader->isFree());
+            if (basicHeader->isFree())
+                addToFreeList(headerAddress, basicHeader->size());
             headerAddress += basicHeader->size();
         }
         ASSERT(headerAddress == end);
-        addToFreeList(page->payload(), end - page->payload());
     }
 
     ASSERT(Heap::lastGCWasConservative() || !m_firstLargeHeapObject);
diff --git a/Source/web/tests/ViewportTest.cpp b/Source/web/tests/ViewportTest.cpp
index 1851db5..9484b63 100644
--- a/Source/web/tests/ViewportTest.cpp
+++ b/Source/web/tests/ViewportTest.cpp
@@ -2529,6 +2529,24 @@
     EXPECT_TRUE(page->viewportDescription().userZoom);
 }
 
+TEST_F(ViewportTest, viewport138)
+{
+    registerMockedHttpURLLoad("viewport/viewport-138.html");
+
+    FrameTestHelpers::WebViewHelper webViewHelper;
+    webViewHelper.initializeAndLoad(m_baseURL + "viewport/viewport-138.html", true, 0, 0, setViewportSettings);
+
+    Page* page = webViewHelper.webViewImpl()->page();
+    PageScaleConstraints constraints = runViewportTest(page, 320, 352);
+
+    EXPECT_NEAR(123.0f, constraints.layoutSize.width(), 0.01);
+    EXPECT_NEAR(135.3f, constraints.layoutSize.height(), 0.01);
+    EXPECT_NEAR(2.60f, constraints.initialScale, 0.01f);
+    EXPECT_NEAR(2.60f, constraints.minimumScale, 0.01f);
+    EXPECT_NEAR(5.0f, constraints.maximumScale, 0.01f);
+    EXPECT_TRUE(page->viewportDescription().userZoom);
+}
+
 TEST_F(ViewportTest, viewportLegacyHandheldFriendly)
 {
     UseMockScrollbarSettings mockScrollbarSettings;
diff --git a/Source/web/tests/data/viewport/viewport-138.html b/Source/web/tests/data/viewport/viewport-138.html
new file mode 100644
index 0000000..5ae398e
--- /dev/null
+++ b/Source/web/tests/data/viewport/viewport-138.html
@@ -0,0 +1,10 @@
+<head>
+    <title>width=123 proceded by trash with special unicode folding</title>
+    <!-- 2x LATIN CAPITAL LETTER I WITH DOT ABOVE followed by =ignore,width=123
+         During parsing the content will be converted to lower case with proper
+         unicode folding (F = full) meaning that the U+0130's each will be
+         converted into two chars - lowercase i followed by U+0307 (COMBINING
+         DOT ABOVE). This test case checks that we iterate over the lowered
+         string length and ends up with 123 as width, instead of 1. -->
+    <meta name="viewport" content="&#x0130;&#x0130;=ignore,width=123">
+</head>
diff --git a/Tools/Scripts/webkitpy/layout_tests/port/base.py b/Tools/Scripts/webkitpy/layout_tests/port/base.py
index 4e717d1..3e1fa69 100644
--- a/Tools/Scripts/webkitpy/layout_tests/port/base.py
+++ b/Tools/Scripts/webkitpy/layout_tests/port/base.py
@@ -1618,6 +1618,10 @@
                              ['--stable-release-mode',
                               '--force-compositing-mode']),
             VirtualTestSuite('stable',
+                             'http/tests/websocket',
+                             ['--stable-release-mode',
+                              '--force-compositing-mode']),
+            VirtualTestSuite('stable',
                              'web-animations-api',
                              ['--stable-release-mode',
                               '--force-compositing-mode']),