From 26439d820f1e976932185cbf9e1b377e2a7a96b7 Mon Sep 17 00:00:00 2001
From: Christophe Chapuis <chris.chapuis@gmail.com>
Date: Sun, 27 Sep 2015 21:39:56 +0200
Subject: [PATCH 03/10] WebContents: provide additional features from
 window.open to the client side

* Also, parse these features in a way that take into account JSON values.
* Also redirect calls to old AddNewContent to the new API, with empty additional features.

Signed-off-by: Christophe Chapuis <chris.chapuis@gmail.com>
Signed-off-by: Christophe Chapuis <chris.chapuis@gmail.com>
---
 .../browser/web_contents/web_contents_impl.cc      |  2 +-
 .../content/public/browser/web_contents_delegate.h | 21 ++++++++++++++++++-
 .../WebKit/Source/core/page/WindowFeatures.cpp     | 24 +++++++++++++++++++---
 3 files changed, 42 insertions(+), 5 deletions(-)

diff --git a/src/3rdparty/chromium/content/browser/web_contents/web_contents_impl.cc b/src/3rdparty/chromium/content/browser/web_contents/web_contents_impl.cc
index c7df36d..5eed7db 100644
--- a/src/3rdparty/chromium/content/browser/web_contents/web_contents_impl.cc
+++ b/src/3rdparty/chromium/content/browser/web_contents/web_contents_impl.cc
@@ -2163,7 +2163,7 @@ void WebContentsImpl::CreateNewWindow(
       gfx::Rect initial_rect;
       delegate_->AddNewContents(
           this, new_contents, params.disposition, initial_rect,
-          params.user_gesture, &was_blocked);
+          params.user_gesture, &was_blocked, params.additional_features);
     }
     if (!was_blocked) {
       OpenURLParams open_params(params.target_url, params.referrer,
diff --git a/src/3rdparty/chromium/content/public/browser/web_contents_delegate.h b/src/3rdparty/chromium/content/public/browser/web_contents_delegate.h
index 2beb83c..aec4195 100644
--- a/src/3rdparty/chromium/content/public/browser/web_contents_delegate.h
+++ b/src/3rdparty/chromium/content/public/browser/web_contents_delegate.h
@@ -118,7 +118,26 @@ class CONTENT_EXPORT WebContentsDelegate {
                               WindowOpenDisposition disposition,
                               const gfx::Rect& initial_rect,
                               bool user_gesture,
-                              bool* was_blocked) {}
+                              bool* was_blocked) {
+      std::vector<base::string16> additional_features;
+      AddNewContents(source,new_contents,disposition,initial_rect,user_gesture,was_blocked, additional_features);
+  }
+
+  // Creates a new tab with the already-created WebContents 'new_contents'.
+  // The window for the added contents should be reparented correctly when this
+  // method returns.  If |disposition| is NEW_POPUP, |initial_rect| should hold
+  // the initial position. If |was_blocked| is non-NULL, then |*was_blocked|
+  // will be set to true if the popup gets blocked, and left unchanged
+  // otherwise.
+  virtual void AddNewContents(WebContents* source,
+                              WebContents* new_contents,
+                              WindowOpenDisposition disposition,
+                              const gfx::Rect& initial_rect,
+                              bool user_gesture,
+                              bool* was_blocked,
+                              std::vector<base::string16> additional_features) {
+      AddNewContents(source,new_contents,disposition,initial_rect,user_gesture,was_blocked);
+  }
 
   // Selects the specified contents, bringing its container to the front.
   virtual void ActivateContents(WebContents* contents) {}
diff --git a/src/3rdparty/chromium/third_party/WebKit/Source/core/page/WindowFeatures.cpp b/src/3rdparty/chromium/third_party/WebKit/Source/core/page/WindowFeatures.cpp
index f1d78f9..82614af 100644
--- a/src/3rdparty/chromium/third_party/WebKit/Source/core/page/WindowFeatures.cpp
+++ b/src/3rdparty/chromium/third_party/WebKit/Source/core/page/WindowFeatures.cpp
@@ -89,7 +89,7 @@ WindowFeatures::WindowFeatures(const String& features)
 
     // skip to first separator
     while (i < length && !isWindowFeaturesSeparator(buffer[i]))
-      i++;
+        i++;
     keyEnd = i;
 
     SECURITY_DCHECK(i <= length);
@@ -115,8 +115,24 @@ WindowFeatures::WindowFeatures(const String& features)
     SECURITY_DCHECK(i <= length);
 
     // skip to first separator
-    while (i < length && !isWindowFeaturesSeparator(buffer[i]))
-      i++;
+    if (i < length && buffer[i] == '{') {
+        // json value: go to the matching '}'
+        int unmatchedBraceCount = 0;
+        while (i < length) {
+            if (buffer[i] == '{')
+                unmatchedBraceCount++;
+            else if (buffer[i] == '}')
+                unmatchedBraceCount--;
+            i++;
+            if (unmatchedBraceCount <= 0)
+                break;
+        }
+    }
+    else {
+        // classic case: skip to first separator
+        while (i < length && !isWindowFeaturesSeparator(buffer[i]))
+          i++;
+    }
     valueEnd = i;
 
     SECURITY_DCHECK(i <= length);
@@ -166,6 +182,8 @@ void WindowFeatures::setWindowFeature(const String& keyString,
     fullscreen = value;
   } else if (keyString == "scrollbars") {
     scrollbarsVisible = value;
+  } else if (keyString == "attributes") {
+    additionalFeatures.append(keyString+"="+valueString);
   } else if (keyString == "noopener") {
     noopener = true;
   } else if (value == 1) {
-- 
2.7.4

