offsetParent fails to consider continuations when searching for parent.

Block-level objects can have inline parents, but this triggers the
insertion of anonymous boxes and continuations, which offsetParent()
currently doesn't understand.

This change lets offsetParent() understand continuations better.
If an anonymous continuation is encountered when finding ancestors,
it will use the split inline as the ancestor, and continue searching
from there.

BUG=638177

Change-Id: I8850f9b5dacaffaa26b5f1c414f4f351709d7088
Reviewed-on: https://chromium-review.googlesource.com/674875
Reviewed-by: Emil A Eklund <eae@chromium.org>
Commit-Queue: Karl Anders Øygard <karlo@opera.com>
Cr-Commit-Position: refs/heads/master@{#503704}
diff --git a/third_party/WebKit/LayoutTests/fast/inline/inline-offsetParent-continuation.html b/third_party/WebKit/LayoutTests/fast/inline/inline-offsetParent-continuation.html
new file mode 100644
index 0000000..894dfbc
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/inline/inline-offsetParent-continuation.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+
+<span id="expectedOffsetParent" style="position:relative;">
+    <div id="elm"></div>
+</span>
+
+<script>
+test(function() {
+    var expectedOffsetParent = document.getElementById("expectedOffsetParent");
+    var actualOffsetParent = document.getElementById("elm").offsetParent;
+
+    assert_true(actualOffsetParent == expectedOffsetParent);
+}, 'offsetParent is correct for a block inside an inline.');
+</script>
diff --git a/third_party/WebKit/Source/core/layout/LayoutObject.cpp b/third_party/WebKit/Source/core/layout/LayoutObject.cpp
index 089b786..1c34cb8 100644
--- a/third_party/WebKit/Source/core/layout/LayoutObject.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutObject.cpp
@@ -3115,8 +3115,20 @@
 
     node = ancestor->GetNode();
 
-    if (!node)
-      continue;
+    if (!node) {
+      if (!ancestor->VirtualContinuation())
+        continue;
+
+      // This is an anonymous continuation; ie. our ancestor is really the split
+      // inline. Find it by spooling to the end of the continuation chain.
+
+      while (LayoutBoxModelObject* cont = ancestor->VirtualContinuation())
+        ancestor = cont;
+
+      node = ancestor->GetNode();
+
+      DCHECK(node);
+    }
 
     // TODO(kochi): If |base| or |node| is nested deep in shadow roots, this
     // loop may get expensive, as isUnclosedNodeOf() can take up to O(N+M) time