[Picture-in-Picture Web API] Implement HTMLVideoElement.requestPictureInPicture() / Document.exitPictureInPicture()
https://bugs.webkit.org/show_bug.cgi?id=201024

Patch by Peng Liu <peng.liu6@apple.com> on 2019-10-15
Reviewed by Eric Carlson.

LayoutTests/imported/w3c:

Import wpt/picture-in-picture.

* resources/import-expectations.json:
* web-platform-tests/picture-in-picture/META.yml: Added.
* web-platform-tests/picture-in-picture/css-selector.html: Added.
* web-platform-tests/picture-in-picture/disable-picture-in-picture.html: Added.
* web-platform-tests/picture-in-picture/enter-picture-in-picture.html: Added.
* web-platform-tests/picture-in-picture/exit-picture-in-picture.html: Added.
* web-platform-tests/picture-in-picture/idlharness.window.html: Added.
* web-platform-tests/picture-in-picture/idlharness.window.js: Added.
* web-platform-tests/picture-in-picture/leave-picture-in-picture.html: Added.
* web-platform-tests/picture-in-picture/mediastream.html: Added.
* web-platform-tests/picture-in-picture/picture-in-picture-element.html: Added.
* web-platform-tests/picture-in-picture/picture-in-picture-window.html: Added.
* web-platform-tests/picture-in-picture/request-picture-in-picture-twice.html: Added.
* web-platform-tests/picture-in-picture/request-picture-in-picture.html: Added.
* web-platform-tests/picture-in-picture/resources/picture-in-picture-helpers.js: Added.
(loadVideo):
(async.requestPictureInPictureWithTrustedClick):
* web-platform-tests/picture-in-picture/resources/w3c-import.log: Added.
* web-platform-tests/picture-in-picture/shadow-dom.html: Added.
* web-platform-tests/picture-in-picture/w3c-import.log: Added.

Source/JavaScriptCore:

Add configurations for Picture-in-Picture API.

* Configurations/FeatureDefines.xcconfig:

Source/WebCore:

Implement the support to enter and exit PiP mode with the Picture-in-Picture API.
Majority work of this patch was done by Carlos Eduardo Ramalho <cadubentzen@gmail.com>.

Also, fix a build error of Modules/webaudio/OfflineAudioContext.cpp because of this patch (due to unified build).

Tests: imported/w3c/web-platform-tests/picture-in-picture/css-selector.html
       imported/w3c/web-platform-tests/picture-in-picture/disable-picture-in-picture.html
       imported/w3c/web-platform-tests/picture-in-picture/enter-picture-in-picture.html
       imported/w3c/web-platform-tests/picture-in-picture/exit-picture-in-picture.html
       imported/w3c/web-platform-tests/picture-in-picture/idlharness.window.html
       imported/w3c/web-platform-tests/picture-in-picture/leave-picture-in-picture.html
       imported/w3c/web-platform-tests/picture-in-picture/mediastream.html
       imported/w3c/web-platform-tests/picture-in-picture/picture-in-picture-element.html
       imported/w3c/web-platform-tests/picture-in-picture/picture-in-picture-window.html
       imported/w3c/web-platform-tests/picture-in-picture/request-picture-in-picture-twice.html
       imported/w3c/web-platform-tests/picture-in-picture/request-picture-in-picture.html
       imported/w3c/web-platform-tests/picture-in-picture/shadow-dom.html

* CMakeLists.txt:
* Configurations/FeatureDefines.xcconfig:
* DerivedSources-input.xcfilelist:
* DerivedSources-output.xcfilelist:
* DerivedSources.make:
* Modules/pictureinpicture/DocumentPictureInPicture.cpp: Added.
(WebCore::DocumentPictureInPicture::exitPictureInPicture):
(WebCore::DocumentPictureInPicture::from):
* Modules/pictureinpicture/DocumentPictureInPicture.h: Added.
(WebCore::DocumentPictureInPicture::pictureInPictureEnabled):
(WebCore::DocumentPictureInPicture::supplementName):
* Modules/pictureinpicture/DocumentPictureInPicture.idl: Added.
* Modules/pictureinpicture/EnterPictureInPictureEvent.cpp: Added.
(WebCore::EnterPictureInPictureEvent::create):
(WebCore::EnterPictureInPictureEvent::EnterPictureInPictureEvent):
* Modules/pictureinpicture/EnterPictureInPictureEvent.h: Added.
* Modules/pictureinpicture/EnterPictureInPictureEvent.idl: Added.
* Modules/pictureinpicture/HTMLVideoElementPictureInPicture.cpp: Added.
(WebCore::HTMLVideoElementPictureInPicture::HTMLVideoElementPictureInPicture):
(WebCore::HTMLVideoElementPictureInPicture::~HTMLVideoElementPictureInPicture):
(WebCore::HTMLVideoElementPictureInPicture::from):
(WebCore::HTMLVideoElementPictureInPicture::requestPictureInPicture):
(WebCore::HTMLVideoElementPictureInPicture::autoPictureInPicture):
(WebCore::HTMLVideoElementPictureInPicture::setAutoPictureInPicture):
(WebCore::HTMLVideoElementPictureInPicture::disablePictureInPicture):
(WebCore::HTMLVideoElementPictureInPicture::setDisablePictureInPicture):
(WebCore::HTMLVideoElementPictureInPicture::exitPictureInPicture):
(WebCore::HTMLVideoElementPictureInPicture::didEnterPictureInPicture):
(WebCore::HTMLVideoElementPictureInPicture::didExitPictureInPicture):
* Modules/pictureinpicture/HTMLVideoElementPictureInPicture.h: Added.
(WebCore::HTMLVideoElementPictureInPicture::supplementName):
* Modules/pictureinpicture/HTMLVideoElementPictureInPicture.idl: Added.
* Modules/pictureinpicture/PictureInPictureWindow.cpp: Added.
(WebCore::PictureInPictureWindow::create):
(WebCore::PictureInPictureWindow::PictureInPictureWindow):
(WebCore::PictureInPictureWindow::activeDOMObjectName const):
(WebCore::PictureInPictureWindow::canSuspendForDocumentSuspension const):
(WebCore::PictureInPictureWindow::eventTargetInterface const):
(WebCore::PictureInPictureWindow::scriptExecutionContext const):
* Modules/pictureinpicture/PictureInPictureWindow.h: Added.
* Modules/pictureinpicture/PictureInPictureWindow.idl: Added.
* Modules/webaudio/OfflineAudioContext.cpp:
* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* bindings/js/WebCoreBuiltinNames.h:
* dom/Document.cpp:
(WebCore::Document::pictureInPictureElement const):
(WebCore::Document::setPictureInPictureElement):
* dom/Document.h:
* dom/DocumentOrShadowRoot.idl:
* dom/EventNames.h:
* dom/EventNames.in:
* dom/EventTargetFactory.in:
* dom/ShadowRoot.cpp:
(WebCore::ShadowRoot::pictureInPictureElement const):
* dom/ShadowRoot.h:
* html/HTMLVideoElement.cpp:
(WebCore::HTMLVideoElement::fullscreenModeChanged):
(WebCore::HTMLVideoElement::setPictureInPictureObserver):
* html/HTMLVideoElement.h:
* page/Settings.yaml:
* platform/PictureInPictureObserver.h: Added.
(WebCore::PictureInPictureObserver::~PictureInPictureObserver):
* testing/InternalSettings.h:

Source/WebCore/PAL:

Add configurations for the Picture-in-Picture API.

* Configurations/FeatureDefines.xcconfig:

Source/WebKit:

Add configurations for Picture-in-Picture API and add a preference option for it.

* Configurations/FeatureDefines.xcconfig:
* Shared/WebPreferences.yaml:

Source/WebKitLegacy/mac:

Add configurations for Picture-in-Picture API and also a preference option for it.

* Configurations/FeatureDefines.xcconfig:
* WebView/WebPreferenceKeysPrivate.h:
* WebView/WebPreferences.mm:
(+[WebPreferences initialize]):
(-[WebPreferences pictureInPictureAPIEnabled]):
(-[WebPreferences setPictureInPictureAPIEnabled:]):
* WebView/WebPreferencesPrivate.h:
* WebView/WebView.mm:
(-[WebView _preferencesChanged:]):

Tools:

Add configurations for Picture-in-Picture API and enable it in the test runner.

* Scripts/webkitperl/FeatureList.pm:
* TestWebKitAPI/Configurations/FeatureDefines.xcconfig:
* WebKitTestRunner/InjectedBundle/InjectedBundle.cpp:
(WTR::InjectedBundle::beginTesting):
* WebKitTestRunner/InjectedBundle/TestRunner.cpp:
(WTR::TestRunner::setPictureInPictureAPIEnabled):
* WebKitTestRunner/InjectedBundle/TestRunner.h:

LayoutTests:

Skip imported/w3c/web-platform-tests/picture-in-picture because of http://webkit.org/b/202617.

* TestExpectations:
* tests-options.json:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@251160 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index fa820b0..024dd76 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,15 @@
+2019-10-15  Peng Liu  <peng.liu6@apple.com>
+
+        [Picture-in-Picture Web API] Implement HTMLVideoElement.requestPictureInPicture() / Document.exitPictureInPicture()
+        https://bugs.webkit.org/show_bug.cgi?id=201024
+
+        Reviewed by Eric Carlson.
+
+        Skip imported/w3c/web-platform-tests/picture-in-picture because of http://webkit.org/b/202617.
+
+        * TestExpectations:
+        * tests-options.json:
+
 2019-10-15  Dean Jackson  <dino@apple.com>
 
         Layout test fast/events/touch/ios/passive-by-default-on-document-and-window.html is a flaky failure on Internal iOS Testers
diff --git a/LayoutTests/TestExpectations b/LayoutTests/TestExpectations
index 6117526..727348f 100644
--- a/LayoutTests/TestExpectations
+++ b/LayoutTests/TestExpectations
@@ -188,6 +188,8 @@
 # DataDetectors tests only make sense on Mac
 fast/events/do-not-drag-and-drop-data-detectors-link.html [ Skip ]
 
+webkit.org/b/202617 imported/w3c/web-platform-tests/picture-in-picture [ Skip ]
+
 # Shared Workers are unsupported
 imported/w3c/web-platform-tests/secure-contexts/basic-shared-worker.html [ Skip ]
 imported/w3c/web-platform-tests/secure-contexts/basic-shared-worker.https.html [ Skip ]
diff --git a/LayoutTests/imported/w3c/ChangeLog b/LayoutTests/imported/w3c/ChangeLog
index 9552aa16..4ebbc2d 100644
--- a/LayoutTests/imported/w3c/ChangeLog
+++ b/LayoutTests/imported/w3c/ChangeLog
@@ -1,3 +1,33 @@
+2019-10-15  Peng Liu  <peng.liu6@apple.com>
+
+        [Picture-in-Picture Web API] Implement HTMLVideoElement.requestPictureInPicture() / Document.exitPictureInPicture()
+        https://bugs.webkit.org/show_bug.cgi?id=201024
+
+        Reviewed by Eric Carlson.
+
+        Import wpt/picture-in-picture.
+
+        * resources/import-expectations.json:
+        * web-platform-tests/picture-in-picture/META.yml: Added.
+        * web-platform-tests/picture-in-picture/css-selector.html: Added.
+        * web-platform-tests/picture-in-picture/disable-picture-in-picture.html: Added.
+        * web-platform-tests/picture-in-picture/enter-picture-in-picture.html: Added.
+        * web-platform-tests/picture-in-picture/exit-picture-in-picture.html: Added.
+        * web-platform-tests/picture-in-picture/idlharness.window.html: Added.
+        * web-platform-tests/picture-in-picture/idlharness.window.js: Added.
+        * web-platform-tests/picture-in-picture/leave-picture-in-picture.html: Added.
+        * web-platform-tests/picture-in-picture/mediastream.html: Added.
+        * web-platform-tests/picture-in-picture/picture-in-picture-element.html: Added.
+        * web-platform-tests/picture-in-picture/picture-in-picture-window.html: Added.
+        * web-platform-tests/picture-in-picture/request-picture-in-picture-twice.html: Added.
+        * web-platform-tests/picture-in-picture/request-picture-in-picture.html: Added.
+        * web-platform-tests/picture-in-picture/resources/picture-in-picture-helpers.js: Added.
+        (loadVideo):
+        (async.requestPictureInPictureWithTrustedClick):
+        * web-platform-tests/picture-in-picture/resources/w3c-import.log: Added.
+        * web-platform-tests/picture-in-picture/shadow-dom.html: Added.
+        * web-platform-tests/picture-in-picture/w3c-import.log: Added.
+
 2019-10-14  Youenn Fablet  <youenn@apple.com>
 
         Handle service worker loads through NetworkResourceLoader
diff --git a/LayoutTests/imported/w3c/resources/import-expectations.json b/LayoutTests/imported/w3c/resources/import-expectations.json
index 3a73d46..cdf2b268 100644
--- a/LayoutTests/imported/w3c/resources/import-expectations.json
+++ b/LayoutTests/imported/w3c/resources/import-expectations.json
@@ -298,6 +298,7 @@
     "web-platform-tests/payment-method-id": "skip", 
     "web-platform-tests/payment-request": "import", 
     "web-platform-tests/performance-timeline": "skip", 
+    "web-platform-tests/picture-in-picture": "import", 
     "web-platform-tests/pointerevents": "import", 
     "web-platform-tests/pointerlock": "skip", 
     "web-platform-tests/preload": "skip", 
diff --git a/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/META.yml b/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/META.yml
new file mode 100644
index 0000000..b878dd5
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/META.yml
@@ -0,0 +1,4 @@
+spec: https://wicg.github.io/picture-in-picture/
+suggested_reviewers:
+  - beaufortfrancois
+  - mounirlamouri
diff --git a/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/css-selector.html b/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/css-selector.html
new file mode 100644
index 0000000..bf64a14
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/css-selector.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<title>Test CSS selector :picture-in-picture</title>
+<script src="/common/media.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script src="resources/picture-in-picture-helpers.js"></script>
+<style>
+  video {
+    color: rgb(0, 0, 255);
+  }
+  :picture-in-picture {
+    color: rgb(0, 255, 0);
+  }
+  /* illegal selector list */
+  video, :picture-in-picture(*) {
+    color: rgb(255, 0, 0);
+  }
+</style>
+<body></body>
+<script>
+promise_test(async t => {
+  const video = await loadVideo();
+  document.body.appendChild(video);
+  assert_equals(getComputedStyle(video).color, 'rgb(0, 0, 255)');
+
+  await requestPictureInPictureWithTrustedClick(video);
+  assert_equals(getComputedStyle(video).color, 'rgb(0, 255, 0)');
+
+  await document.exitPictureInPicture();
+  assert_equals(getComputedStyle(video).color, 'rgb(0, 0, 255)');
+}, 'Entering and leaving Picture-in-Picture toggles CSS selector');
+</script>
diff --git a/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/disable-picture-in-picture.html b/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/disable-picture-in-picture.html
new file mode 100644
index 0000000..5075c01
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/disable-picture-in-picture.html
@@ -0,0 +1,74 @@
+<!DOCTYPE html>
+<title>Test disable Picture-in-Picture</title>
+<script src="/common/media.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script src="resources/picture-in-picture-helpers.js"></script>
+<body></body>
+<script>
+test(t => {
+  const video = document.createElement('video');
+  assert_false(video.disablePictureInPicture); // default value
+
+  video.setAttribute('disablepictureinpicture', 'foo');
+  assert_true(video.disablePictureInPicture);
+
+  video.removeAttribute('disablepictureinpicture');
+  assert_false(video.disablePictureInPicture);
+
+  video.disablePictureInPicture = true;
+  assert_equals(video.getAttribute('disablepictureinpicture'), '');
+
+  video.disablePictureInPicture = false;
+  assert_equals(video.getAttribute('disablepictureinpicture'), null);
+}, 'Test disablePictureInPicture IDL attribute');
+
+promise_test(async t => {
+  const video = await loadVideo();
+  video.disablePictureInPicture = true;
+  return promise_rejects(t, 'InvalidStateError',
+      requestPictureInPictureWithTrustedClick(video));
+}, 'Request Picture-in-Picture rejects if disablePictureInPicture is true');
+
+promise_test(async t => {
+  const video = await loadVideo();
+  await test_driver.bless('request Picture-in-Picture');
+  const promise = video.requestPictureInPicture();
+  video.disablePictureInPicture = true;
+  await promise_rejects(t, 'InvalidStateError', promise);
+  assert_equals(document.pictureInPictureElement, null);
+}, 'Request Picture-in-Picture rejects if disablePictureInPicture becomes ' +
+   'true before promise resolves.');
+
+promise_test(async t => {
+  const video = await loadVideo();
+  return requestPictureInPictureWithTrustedClick(video)
+  .then(() => {
+    video.disablePictureInPicture = true;
+    video.addEventListener('leavepictureinpicture', t.step_func(() => {
+      assert_equals(document.pictureInPictureElement, null);
+    }));
+  });
+}, 'pictureInPictureElement is unset if disablePictureInPicture becomes true');
+
+promise_test(async t => {
+  const video = await loadVideo();
+  return requestPictureInPictureWithTrustedClick(video)
+  .then(() => {
+    video.disablePictureInPicture = false;
+    assert_equals(document.pictureInPictureElement, video);
+  });
+}, 'pictureInPictureElement is unchanged if disablePictureInPicture becomes false');
+
+promise_test(async t => {
+  const video = await loadVideo();
+  return requestPictureInPictureWithTrustedClick(video)
+  .then(() => {
+    document.createElement('video').disablePictureInPicture = true;
+    assert_equals(document.pictureInPictureElement, video);
+  });
+}, 'pictureInPictureElement is unchanged if disablePictureInPicture becomes ' +
+   'true for another video');
+</script>
diff --git a/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/enter-picture-in-picture.html b/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/enter-picture-in-picture.html
new file mode 100644
index 0000000..a9d7b5c
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/enter-picture-in-picture.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<title>Test enterpictureinpicture event</title>
+<script src="/common/media.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script src="resources/picture-in-picture-helpers.js"></script>
+<body></body>
+<script>
+promise_test(async t => {
+  let pictureInPictureWindow;
+  const video = await loadVideo();
+
+  video.addEventListener('enterpictureinpicture', t.step_func_done(event => {
+    pictureInPictureWindow = event.pictureInPictureWindow;
+
+    assert_equals(event.target, video);
+    assert_equals(event.bubbles, true);
+    assert_equals(event.cancelable, false);
+    assert_equals(event.composed, false);
+    assert_equals(document.pictureInPictureElement, video);
+  }));
+
+  return requestPictureInPictureWithTrustedClick(video)
+  .then(pipWindow => {
+    assert_equals(pipWindow, pictureInPictureWindow);
+  })
+});
+</script>
diff --git a/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/exit-picture-in-picture.html b/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/exit-picture-in-picture.html
new file mode 100644
index 0000000..c8d76f5
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/exit-picture-in-picture.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<title>Test exit Picture-in-Picture</title>
+<script src="/common/media.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script src="resources/picture-in-picture-helpers.js"></script>
+<body></body>
+<script>
+promise_test(async t => {
+  const video = await loadVideo();
+  return requestPictureInPictureWithTrustedClick(video)
+  .then(() => document.exitPictureInPicture());
+}, 'Exit Picture-in-Picture resolves when there is a Picture-in-Picture video');
+
+promise_test(t => {
+  return promise_rejects(t, 'InvalidStateError',
+      document.exitPictureInPicture());
+}, 'Exit Picture-in-Picture rejects when there is no Picture-in-Picture video');
+</script>
diff --git a/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/idlharness.window.html b/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/idlharness.window.html
new file mode 100644
index 0000000..2382913
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/idlharness.window.html
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/idlharness.window.js b/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/idlharness.window.js
new file mode 100644
index 0000000..31cd4a1
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/idlharness.window.js
@@ -0,0 +1,26 @@
+// META: script=/common/media.js
+// META: script=/resources/WebIDLParser.js
+// META: script=/resources/idlharness.js
+// META: script=/resources/testdriver.js
+// META: script=/resources/testdriver-vendor.js
+// META: script=resources/picture-in-picture-helpers.js
+
+'use strict';
+
+// https://wicg.github.io/picture-in-picture/
+
+idl_test(
+  ['picture-in-picture'],
+  ['html', 'dom'],
+  async idl_array => {
+    idl_array.add_objects({
+      Document: ['document'],
+      DocumentOrShadowRoot: ['document'],
+      HTMLVideoElement: ['video'],
+      PictureInPictureWindow: ['pipw'],
+    });
+
+    self.video = await loadVideo();
+    self.pipw = await requestPictureInPictureWithTrustedClick(video);
+  }
+);
diff --git a/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/leave-picture-in-picture.html b/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/leave-picture-in-picture.html
new file mode 100644
index 0000000..22445c2
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/leave-picture-in-picture.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<title>Test leavepictureinpicture event</title>
+<meta name="timeout" content="long">
+<script src="/common/media.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script src="resources/picture-in-picture-helpers.js"></script>
+<body></body>
+<script>
+promise_test(async t => {
+  const video = await loadVideo();
+
+  video.addEventListener('leavepictureinpicture', t.step_func_done(event => {
+    assert_equals(event.target, video);
+    assert_equals(event.bubbles, true);
+    assert_equals(event.cancelable, false);
+    assert_equals(event.composed, false);
+    assert_equals(document.pictureInPictureElement, null);
+  }));
+
+  return requestPictureInPictureWithTrustedClick(video)
+  .then(() => document.exitPictureInPicture());
+}, 'leavepictureinpicture event is fired if document.exitPictureInPicture');
+
+promise_test(async t => {
+  const video = await loadVideo();
+
+  video.addEventListener('leavepictureinpicture', t.step_func_done(event => {
+    assert_equals(event.target, video);
+    assert_equals(event.bubbles, true);
+    assert_equals(event.cancelable, false);
+    assert_equals(event.composed, false);
+    assert_equals(document.pictureInPictureElement, null);
+  }));
+
+  return requestPictureInPictureWithTrustedClick(video)
+  .then(() => {
+    video.disablePictureInPicture = true;
+  });
+}, 'leavepictureinpicture event is fired if video.disablePictureInPicture is set to true');
+</script>
diff --git a/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/mediastream.html b/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/mediastream.html
new file mode 100644
index 0000000..116a0f7
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/mediastream.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<title>Test mediastream video in Picture-in-Picture</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script src="resources/picture-in-picture-helpers.js"></script>
+<body></body>
+<script>
+promise_test(async t => {
+  const canvas = document.createElement('canvas');
+  const video = document.createElement('video');
+  canvas.getContext('2d').fillRect(0, 0, canvas.width, canvas.height);
+  video.muted = true;
+  video.srcObject = canvas.captureStream(60 /* fps */);
+  await video.play();
+
+  return requestPictureInPictureWithTrustedClick(video)
+  .then(pipWindow => {
+    assert_not_equals(pipWindow.width, 0);
+    assert_not_equals(pipWindow.height, 0);
+  });
+}, 'request Picture-in-Picture resolves on user click with Picture-in-Picture window');
+</script>
diff --git a/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/picture-in-picture-element.html b/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/picture-in-picture-element.html
new file mode 100644
index 0000000..2763eca
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/picture-in-picture-element.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<title>Test Picture-in-Picture element</title>
+<script src="/common/media.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script src="resources/picture-in-picture-helpers.js"></script>
+<body></body>
+<script>
+promise_test(async t => {
+  assert_equals(document.pictureInPictureElement, null);
+  const video = await loadVideo();
+
+  return requestPictureInPictureWithTrustedClick(video)
+  .then(() => {
+    assert_equals(document.pictureInPictureElement, video);
+    return document.exitPictureInPicture();
+  })
+  .then(() => {
+    assert_equals(document.pictureInPictureElement, null);
+  });
+});
+</script>
diff --git a/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/picture-in-picture-window.html b/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/picture-in-picture-window.html
new file mode 100644
index 0000000..ed1ad8e
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/picture-in-picture-window.html
@@ -0,0 +1,96 @@
+<!DOCTYPE html>
+<title>Test Picture-in-Picture window</title>
+<meta name="timeout" content="long">
+<script src="/common/media.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script src="resources/picture-in-picture-helpers.js"></script>
+<body></body>
+<script>
+promise_test(async t => {
+  const video = await loadVideo();
+  return requestPictureInPictureWithTrustedClick(video)
+  .then(pipWindow => {
+    assert_not_equals(pipWindow.width, 0);
+    assert_not_equals(pipWindow.height, 0);
+    const videoAspectRatio = video.videoWidth / video.videoHeight;
+    const pipWindowAspectRatio = pipWindow.width / pipWindow.height;
+    assert_approx_equals(videoAspectRatio, pipWindowAspectRatio, 0.01);
+  });
+}, 'Picture-in-Picture window dimensions are set after entering Picture-in-Picture');
+
+promise_test(async t => {
+  const video1 = await loadVideo();
+  const video2 = await loadVideo();
+  return requestPictureInPictureWithTrustedClick(video1)
+  .then(pipWindow1 => {
+    return requestPictureInPictureWithTrustedClick(video2)
+    .then(pipWindow2 => {
+      assert_equals(pipWindow1.width, 0);
+      assert_equals(pipWindow1.height, 0);
+      assert_not_equals(pipWindow2.width, 0);
+      assert_not_equals(pipWindow2.height, 0);
+    });
+  });
+}, 'Picture-in-Picture window dimensions are set to 0 after entering ' +
+   'Picture-in-Picture for another video');
+
+promise_test(async t => {
+  const video = await loadVideo();
+
+  video.addEventListener('leavepictureinpicture', t.step_func_done(event => {
+    assert_unreached('leavepictureinpicture event should not fire.')
+  }));
+
+  let enterCounts = 0;
+  video.addEventListener('enterpictureinpicture', event => {
+    enterCounts++;
+  });
+
+  return requestPictureInPictureWithTrustedClick(video)
+  .then(pipWindow1 => {
+    pipWindow1.onresize = function foo() {};
+    return requestPictureInPictureWithTrustedClick(video)
+    .then(pipWindow2 => {
+      assert_equals(pipWindow1, pipWindow2);
+      assert_equals(pipWindow1.width, pipWindow2.width);
+      assert_equals(pipWindow1.height, pipWindow2.height);
+      assert_equals(pipWindow1.onresize, pipWindow2.onresize);
+      assert_equals(enterCounts, 1);
+    });
+  });
+}, 'Picture-in-Picture window is unchanged after entering ' +
+   'Picture-in-Picture for video already in Picture-in-Picture');
+
+promise_test(async t => {
+  const video = await loadVideo();
+
+  return requestPictureInPictureWithTrustedClick(video)
+  .then(pipWindow => {
+    return document.exitPictureInPicture()
+    .then(() => {
+      assert_equals(pipWindow.width, 0);
+      assert_equals(pipWindow.height, 0);
+    });
+  });
+}, 'Picture-in-Picture window dimensions are set to 0 after exiting Picture-in-Picture');
+
+promise_test(async t => {
+  const video = await loadVideo();
+  let thePipWindow;
+
+  video.addEventListener('leavepictureinpicture', t.step_func_done(event => {
+    assert_equals(thePipWindow.width, 0);
+    assert_equals(thePipWindow.height, 0);
+  }));
+
+  return requestPictureInPictureWithTrustedClick(video)
+  .then(pipWindow => {
+    thePipWindow = pipWindow;
+    video.disablePictureInPicture = true;
+  });
+}, 'Picture-in-Picture window dimensions are set to 0 if ' +
+   'disablePictureInPicture becomes true');
+</script>
diff --git a/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/request-picture-in-picture-twice.html b/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/request-picture-in-picture-twice.html
new file mode 100644
index 0000000..bebf4fa
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/request-picture-in-picture-twice.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<title>Test request Picture-in-Picture on two videos</title>
+<meta name="timeout" content="long">
+<script src="/common/media.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script src="resources/picture-in-picture-helpers.js"></script>
+<body></body>
+<script>
+promise_test(async t => {
+  const video1 = await loadVideo();
+  const video2 = await loadVideo();
+  await test_driver.bless('request Picture-in-Picture');
+  const promise = video1.requestPictureInPicture();
+  await promise_rejects(t, 'NotAllowedError', video2.requestPictureInPicture());
+  return promise;
+}, 'request Picture-in-Picture consumes user gesture');
+
+promise_test(async t => {
+  const video1 = await loadVideo();
+  const video2 = await loadVideo();
+  await test_driver.bless('request Picture-in-Picture');
+  await video1.requestPictureInPicture();
+  assert_equals(document.pictureInPictureElement, video1);
+  return video2.requestPictureInPicture();
+}, 'request Picture-in-Picture does not require user gesture if document.pictureInPictureElement is set');
+</script>
diff --git a/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/request-picture-in-picture.html b/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/request-picture-in-picture.html
new file mode 100644
index 0000000..37ae948
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/request-picture-in-picture.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<title>Test request Picture-in-Picture</title>
+<script src="/common/media.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script src="resources/picture-in-picture-helpers.js"></script>
+<body></body>
+<script>
+promise_test(async t => {
+  const video = await loadVideo();
+  return promise_rejects(t, 'NotAllowedError', video.requestPictureInPicture());
+}, 'request Picture-in-Picture requires a user gesture');
+
+promise_test(t => {
+  const video = document.createElement('video');
+  return promise_rejects(t, 'InvalidStateError',
+      requestPictureInPictureWithTrustedClick(video));
+}, 'request Picture-in-Picture requires loaded metadata for the video element');
+
+promise_test(async t => {
+  const video = document.createElement('video');
+  await new Promise(resolve => {
+    video.src = getAudioURI('/media/sound_5');
+    video.onloadeddata = resolve;
+  }).then(() => {
+    return promise_rejects(t, 'InvalidStateError',
+      requestPictureInPictureWithTrustedClick(video));
+  })
+}, 'request Picture-in-Picture requires video track for the video element');
+
+promise_test(async t => {
+  const video = await loadVideo();
+  return requestPictureInPictureWithTrustedClick(video);
+}, 'request Picture-in-Picture resolves on user click');
+</script>
diff --git a/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/resources/picture-in-picture-helpers.js b/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/resources/picture-in-picture-helpers.js
new file mode 100644
index 0000000..7561944
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/resources/picture-in-picture-helpers.js
@@ -0,0 +1,15 @@
+function loadVideo(activeDocument, sourceUrl) {
+  return new Promise((resolve, reject) => {
+    const document = activeDocument || window.document;
+    const video = document.createElement('video');
+    video.src = sourceUrl || getVideoURI('/media/movie_5');
+    video.onloadedmetadata = () => { resolve(video); };
+    video.onerror = error => { reject(error); };
+  });
+}
+
+// Calls requestPictureInPicture() in a context that's 'allowed to request PiP'.
+async function requestPictureInPictureWithTrustedClick(videoElement) {
+  await test_driver.bless('request Picture-in-Picture');
+  return videoElement.requestPictureInPicture();
+}
diff --git a/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/resources/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/resources/w3c-import.log
new file mode 100644
index 0000000..115d23f
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/resources/w3c-import.log
@@ -0,0 +1,17 @@
+The tests in this directory were imported from the W3C repository.
+Do NOT modify these tests directly in WebKit.
+Instead, create a pull request on the WPT github:
+	https://github.com/web-platform-tests/wpt
+
+Then run the Tools/Scripts/import-w3c-tests in WebKit to reimport
+
+Do NOT modify or remove this file.
+
+------------------------------------------------------------------------
+Properties requiring vendor prefixes:
+None
+Property values requiring vendor prefixes:
+None
+------------------------------------------------------------------------
+List of files:
+/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/resources/picture-in-picture-helpers.js
diff --git a/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/shadow-dom.html b/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/shadow-dom.html
new file mode 100644
index 0000000..adcd659
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/shadow-dom.html
@@ -0,0 +1,88 @@
+<!DOCTYPE html>
+<title>Test for Picture-In-Picture and Shadow DOM</title>
+<script src="/common/media.js"></script>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script src="resources/picture-in-picture-helpers.js"></script>
+<script src="../shadow-dom/resources/shadow-dom.js"></script>
+<style>
+  #host2 { color: rgb(0, 0, 254); }
+  #host2:picture-in-picture { color: rgb(0, 0, 255); }
+</style>
+<body>
+<div id='host'>
+  <template data-mode='open' id='root'>
+    <slot></slot>
+  </template>
+  <div id='host2'>
+    <template data-mode='open' id='root2'>
+      <style>
+        #host3 { color: rgb(0, 0, 127); }
+        #host3:picture-in-picture { color: rgb(0, 0, 128); }
+      </style>
+      <div id='host3'>
+        <template data-mode='open' id='root3'>
+          <style>
+            video { color: rgb(0, 254, 0); }
+            video:picture-in-picture { color: rgb(0, 255, 0); }
+          </style>
+          <video id='video'></video>
+          <div id='host4'>
+            <template data-mode='open' id='root4'>
+              <div></div>
+            </template>
+          </div>
+        </template>
+      </div>
+      <div id='host5'>
+        <template data-mode='open' id='root5'>
+          <div></div>
+        </template>
+      </div>
+    </template>
+  </div>
+</div>
+</body>
+<script>
+promise_test(async t => {
+  const ids = createTestTree(host);
+  document.body.appendChild(ids.host);
+
+  assert_equals(document.pictureInPictureElement, null);
+  assert_equals(ids.root.pictureInPictureElement, null);
+  assert_equals(ids.root2.pictureInPictureElement, null);
+  assert_equals(ids.root3.pictureInPictureElement, null);
+  assert_equals(ids.root4.pictureInPictureElement, null);
+  assert_equals(ids.root5.pictureInPictureElement, null);
+
+  assert_equals(getComputedStyle(ids.video).color, 'rgb(0, 254, 0)');
+  assert_equals(getComputedStyle(ids.host3).color, 'rgb(0, 0, 127)');
+  assert_equals(getComputedStyle(ids.host2).color, 'rgb(0, 0, 254)');
+
+  await new Promise(resolve => {
+    ids.video.src = getVideoURI('/media/movie_5');
+    ids.video.onloadeddata = resolve;
+  })
+  .then(() => requestPictureInPictureWithTrustedClick(ids.video))
+  .then(() => {
+    assert_equals(document.pictureInPictureElement, ids.host2);
+    assert_equals(ids.root.pictureInPictureElement, null);
+    assert_equals(ids.root2.pictureInPictureElement, ids.host3);
+    assert_equals(ids.root3.pictureInPictureElement, ids.video);
+    assert_equals(ids.root4.pictureInPictureElement, null);
+    assert_equals(ids.root5.pictureInPictureElement, null);
+
+    assert_equals(getComputedStyle(ids.video).color, 'rgb(0, 255, 0)');
+    assert_equals(getComputedStyle(ids.host3).color, 'rgb(0, 0, 127)');
+    assert_equals(getComputedStyle(ids.host2).color, 'rgb(0, 0, 254)');
+  })
+  .then(() => document.exitPictureInPicture())
+  .then(() => {
+    assert_equals(getComputedStyle(ids.video).color, 'rgb(0, 254, 0)');
+    assert_equals(getComputedStyle(ids.host3).color, 'rgb(0, 0, 127)');
+    assert_equals(getComputedStyle(ids.host2).color, 'rgb(0, 0, 254)');
+  });
+});
+</script>
diff --git a/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/w3c-import.log
new file mode 100644
index 0000000..d118909
--- /dev/null
+++ b/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/w3c-import.log
@@ -0,0 +1,29 @@
+The tests in this directory were imported from the W3C repository.
+Do NOT modify these tests directly in WebKit.
+Instead, create a pull request on the WPT github:
+	https://github.com/web-platform-tests/wpt
+
+Then run the Tools/Scripts/import-w3c-tests in WebKit to reimport
+
+Do NOT modify or remove this file.
+
+------------------------------------------------------------------------
+Properties requiring vendor prefixes:
+None
+Property values requiring vendor prefixes:
+None
+------------------------------------------------------------------------
+List of files:
+/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/META.yml
+/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/css-selector.html
+/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/disable-picture-in-picture.html
+/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/enter-picture-in-picture.html
+/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/exit-picture-in-picture.html
+/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/idlharness.window.js
+/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/leave-picture-in-picture.html
+/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/mediastream.html
+/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/picture-in-picture-element.html
+/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/picture-in-picture-window.html
+/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/request-picture-in-picture-twice.html
+/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/request-picture-in-picture.html
+/LayoutTests/imported/w3c/web-platform-tests/picture-in-picture/shadow-dom.html
diff --git a/LayoutTests/tests-options.json b/LayoutTests/tests-options.json
index 8584f9e..0babbfc 100644
--- a/LayoutTests/tests-options.json
+++ b/LayoutTests/tests-options.json
@@ -1799,6 +1799,15 @@
     "imported/w3c/web-platform-tests/payment-request/payment-request-constructor-crash.https.html": [
         "slow"
     ],
+    "imported/w3c/web-platform-tests/picture-in-picture/leave-picture-in-picture.html": [
+        "slow"
+    ],
+    "imported/w3c/web-platform-tests/picture-in-picture/picture-in-picture-window.html": [
+        "slow"
+    ],
+    "imported/w3c/web-platform-tests/picture-in-picture/request-picture-in-picture-twice.html": [
+        "slow"
+    ],
     "imported/w3c/web-platform-tests/quirks/hashless-hex-color.html": [
         "slow"
     ],
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog
index fc5e472..5f16042 100644
--- a/Source/JavaScriptCore/ChangeLog
+++ b/Source/JavaScriptCore/ChangeLog
@@ -1,3 +1,14 @@
+2019-10-15  Peng Liu  <peng.liu6@apple.com>
+
+        [Picture-in-Picture Web API] Implement HTMLVideoElement.requestPictureInPicture() / Document.exitPictureInPicture()
+        https://bugs.webkit.org/show_bug.cgi?id=201024
+
+        Reviewed by Eric Carlson.
+
+        Add configurations for Picture-in-Picture API.
+
+        * Configurations/FeatureDefines.xcconfig:
+
 2019-10-15  Angelos Oikonomopoulos  <aoikonomopoulos@igalia.com>
 
         Interpreter: Don't assert that reference is nonnull
diff --git a/Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig b/Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig
index d808ee0..140ffe5 100644
--- a/Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig
+++ b/Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig
@@ -313,6 +313,9 @@
 
 ENABLE_PAYMENT_REQUEST = ENABLE_PAYMENT_REQUEST;
 
+ENABLE_PICTURE_IN_PICTURE_API = $(ENABLE_PICTURE_IN_PICTURE_API_$(WK_PLATFORM_NAME));
+ENABLE_PICTURE_IN_PICTURE_API_macosx = ENABLE_PICTURE_IN_PICTURE_API;
+
 ENABLE_PDFKIT_PLUGIN = $(ENABLE_PDFKIT_PLUGIN_$(WK_PLATFORM_NAME));
 ENABLE_PDFKIT_PLUGIN_macosx = ENABLE_PDFKIT_PLUGIN;
 
@@ -443,4 +446,4 @@
 
 ENABLE_XSLT = ENABLE_XSLT;
 
-FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCESSIBILITY_ISOLATED_TREE) $(ENABLE_APPLE_PAY) $(ENABLE_APPLE_PAY_SESSION_V3) $(ENABLE_APPLE_PAY_SESSION_V4) $(ENABLE_APPLICATION_MANIFEST) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_AVF_CAPTIONS) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSS3_TEXT) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_CONIC_GRADIENTS) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_PAINTING_API) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_CSS_TYPED_OM) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_C_LOOP) $(ENABLE_DARK_MODE_CSS) $(ENABLE_DATACUE_VALUE) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DATA_INTERACTION) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DRAG_SUPPORT) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_EXPERIMENTAL_FEATURES) $(ENABLE_FAST_JIT_PERMISSIONS) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FTL_JIT) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_INSPECTOR_ALTERNATE_DISPATCHERS) $(ENABLE_INTERSECTION_OBSERVER) $(ENABLE_INTL) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_JIT) $(ENABLE_KEYBOARD_CODE_ATTRIBUTE) $(ENABLE_KEYBOARD_KEY_ATTRIBUTE) $(ENABLE_LAYOUT_FORMATTING_CONTEXT) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_CUSTOM_PROTOCOL_MANAGER) $(ENABLE_LEGACY_ENCRYPTED_MEDIA) $(ENABLE_LETTERPRESS) $(ENABLE_MAC_GESTURE_EVENTS) $(ENABLE_MAC_VIDEO_TOOLBOX) $(ENABLE_MATHML) $(ENABLE_MEDIA_CAPTURE) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_MEMORY_SAMPLER) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_STANDALONE) $(ENABLE_NETWORK_CACHE_SPECULATIVE_REVALIDATION) $(ENABLE_NOTIFICATIONS) $(ENABLE_OVERFLOW_SCROLLING_TOUCH) $(ENABLE_PAYMENT_REQUEST) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_POINTER_EVENTS) $(ENABLE_POINTER_LOCK) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_RESIZE_OBSERVER) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RESOURCE_LOAD_STATISTICS) $(ENABLE_RESOURCE_USAGE) $(ENABLE_RUBBER_BANDING) $(ENABLE_SANDBOX_EXTENSIONS) $(ENABLE_SERVER_PRECONNECT) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_SERVICE_WORKER) $(ENABLE_SHAREABLE_RESOURCE) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_STREAMS_API) $(ENABLE_SVG_FONTS) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TOUCH_EVENTS) $(ENABLE_USERSELECT_ALL) $(ENABLE_USER_MESSAGE_HANDLERS) $(ENABLE_VARIATION_FONTS) $(ENABLE_VIDEO) $(ENABLE_VIDEO_PRESENTATION_MODE) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIDEO_USES_ELEMENT_FULLSCREEN) $(ENABLE_WEBASSEMBLY) $(ENABLE_WEBASSEMBLY_STREAMING_API) $(ENABLE_WEBDRIVER_MOUSE_INTERACTIONS) $(ENABLE_WEBDRIVER_KEYBOARD_INTERACTIONS) $(ENABLE_WEBDRIVER_TOUCH_INTERACTIONS) $(ENABLE_WEBGL) $(ENABLE_WEBGL2) $(ENABLE_WEBGPU) $(ENABLE_WEB_API_STATISTICS) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_AUTHN) $(ENABLE_WEB_CRYPTO) $(ENABLE_WEB_RTC) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_XSLT);
+FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCESSIBILITY_ISOLATED_TREE) $(ENABLE_APPLE_PAY) $(ENABLE_APPLE_PAY_SESSION_V3) $(ENABLE_APPLE_PAY_SESSION_V4) $(ENABLE_APPLICATION_MANIFEST) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_AVF_CAPTIONS) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSS3_TEXT) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_CONIC_GRADIENTS) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_PAINTING_API) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_CSS_TYPED_OM) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_C_LOOP) $(ENABLE_DARK_MODE_CSS) $(ENABLE_DATACUE_VALUE) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DATA_INTERACTION) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DRAG_SUPPORT) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_EXPERIMENTAL_FEATURES) $(ENABLE_FAST_JIT_PERMISSIONS) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FTL_JIT) $(ENABLE_FULLSCREEN_API) $(ENABLE_PICTURE_IN_PICTURE_API) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_INSPECTOR_ALTERNATE_DISPATCHERS) $(ENABLE_INTERSECTION_OBSERVER) $(ENABLE_INTL) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_JIT) $(ENABLE_KEYBOARD_CODE_ATTRIBUTE) $(ENABLE_KEYBOARD_KEY_ATTRIBUTE) $(ENABLE_LAYOUT_FORMATTING_CONTEXT) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_CUSTOM_PROTOCOL_MANAGER) $(ENABLE_LEGACY_ENCRYPTED_MEDIA) $(ENABLE_LETTERPRESS) $(ENABLE_MAC_GESTURE_EVENTS) $(ENABLE_MAC_VIDEO_TOOLBOX) $(ENABLE_MATHML) $(ENABLE_MEDIA_CAPTURE) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_MEMORY_SAMPLER) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_STANDALONE) $(ENABLE_NETWORK_CACHE_SPECULATIVE_REVALIDATION) $(ENABLE_NOTIFICATIONS) $(ENABLE_OVERFLOW_SCROLLING_TOUCH) $(ENABLE_PAYMENT_REQUEST) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_POINTER_EVENTS) $(ENABLE_POINTER_LOCK) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_RESIZE_OBSERVER) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RESOURCE_LOAD_STATISTICS) $(ENABLE_RESOURCE_USAGE) $(ENABLE_RUBBER_BANDING) $(ENABLE_SANDBOX_EXTENSIONS) $(ENABLE_SERVER_PRECONNECT) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_SERVICE_WORKER) $(ENABLE_SHAREABLE_RESOURCE) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_STREAMS_API) $(ENABLE_SVG_FONTS) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TOUCH_EVENTS) $(ENABLE_USERSELECT_ALL) $(ENABLE_USER_MESSAGE_HANDLERS) $(ENABLE_VARIATION_FONTS) $(ENABLE_VIDEO) $(ENABLE_VIDEO_PRESENTATION_MODE) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIDEO_USES_ELEMENT_FULLSCREEN) $(ENABLE_WEBASSEMBLY) $(ENABLE_WEBASSEMBLY_STREAMING_API) $(ENABLE_WEBDRIVER_MOUSE_INTERACTIONS) $(ENABLE_WEBDRIVER_KEYBOARD_INTERACTIONS) $(ENABLE_WEBDRIVER_TOUCH_INTERACTIONS) $(ENABLE_WEBGL) $(ENABLE_WEBGL2) $(ENABLE_WEBGPU) $(ENABLE_WEB_API_STATISTICS) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_AUTHN) $(ENABLE_WEB_CRYPTO) $(ENABLE_WEB_RTC) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_XSLT);
diff --git a/Source/WebCore/CMakeLists.txt b/Source/WebCore/CMakeLists.txt
index c99511b..96f27e8 100644
--- a/Source/WebCore/CMakeLists.txt
+++ b/Source/WebCore/CMakeLists.txt
@@ -401,6 +401,11 @@
     Modules/paymentrequest/PaymentShippingType.idl
     Modules/paymentrequest/PaymentValidationErrors.idl
 
+    Modules/pictureinpicture/DocumentPictureInPicture.idl
+    Modules/pictureinpicture/EnterPictureInPictureEvent.idl
+    Modules/pictureinpicture/HTMLVideoElementPictureInPicture.idl
+    Modules/pictureinpicture/PictureInPictureWindow.idl
+
     Modules/speech/DOMWindowSpeechSynthesis.idl
     Modules/speech/SpeechSynthesis.idl
     Modules/speech/SpeechSynthesisEvent.idl
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 26f554a..21166b7 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,93 @@
+2019-10-15  Peng Liu  <peng.liu6@apple.com>
+
+        [Picture-in-Picture Web API] Implement HTMLVideoElement.requestPictureInPicture() / Document.exitPictureInPicture()
+        https://bugs.webkit.org/show_bug.cgi?id=201024
+
+        Reviewed by Eric Carlson.
+
+        Implement the support to enter and exit PiP mode with the Picture-in-Picture API.
+        Majority work of this patch was done by Carlos Eduardo Ramalho <cadubentzen@gmail.com>.
+
+        Also, fix a build error of Modules/webaudio/OfflineAudioContext.cpp because of this patch (due to unified build).
+
+        Tests: imported/w3c/web-platform-tests/picture-in-picture/css-selector.html
+               imported/w3c/web-platform-tests/picture-in-picture/disable-picture-in-picture.html
+               imported/w3c/web-platform-tests/picture-in-picture/enter-picture-in-picture.html
+               imported/w3c/web-platform-tests/picture-in-picture/exit-picture-in-picture.html
+               imported/w3c/web-platform-tests/picture-in-picture/idlharness.window.html
+               imported/w3c/web-platform-tests/picture-in-picture/leave-picture-in-picture.html
+               imported/w3c/web-platform-tests/picture-in-picture/mediastream.html
+               imported/w3c/web-platform-tests/picture-in-picture/picture-in-picture-element.html
+               imported/w3c/web-platform-tests/picture-in-picture/picture-in-picture-window.html
+               imported/w3c/web-platform-tests/picture-in-picture/request-picture-in-picture-twice.html
+               imported/w3c/web-platform-tests/picture-in-picture/request-picture-in-picture.html
+               imported/w3c/web-platform-tests/picture-in-picture/shadow-dom.html
+
+        * CMakeLists.txt:
+        * Configurations/FeatureDefines.xcconfig:
+        * DerivedSources-input.xcfilelist:
+        * DerivedSources-output.xcfilelist:
+        * DerivedSources.make:
+        * Modules/pictureinpicture/DocumentPictureInPicture.cpp: Added.
+        (WebCore::DocumentPictureInPicture::exitPictureInPicture):
+        (WebCore::DocumentPictureInPicture::from):
+        * Modules/pictureinpicture/DocumentPictureInPicture.h: Added.
+        (WebCore::DocumentPictureInPicture::pictureInPictureEnabled):
+        (WebCore::DocumentPictureInPicture::supplementName):
+        * Modules/pictureinpicture/DocumentPictureInPicture.idl: Added.
+        * Modules/pictureinpicture/EnterPictureInPictureEvent.cpp: Added.
+        (WebCore::EnterPictureInPictureEvent::create):
+        (WebCore::EnterPictureInPictureEvent::EnterPictureInPictureEvent):
+        * Modules/pictureinpicture/EnterPictureInPictureEvent.h: Added.
+        * Modules/pictureinpicture/EnterPictureInPictureEvent.idl: Added.
+        * Modules/pictureinpicture/HTMLVideoElementPictureInPicture.cpp: Added.
+        (WebCore::HTMLVideoElementPictureInPicture::HTMLVideoElementPictureInPicture):
+        (WebCore::HTMLVideoElementPictureInPicture::~HTMLVideoElementPictureInPicture):
+        (WebCore::HTMLVideoElementPictureInPicture::from):
+        (WebCore::HTMLVideoElementPictureInPicture::requestPictureInPicture):
+        (WebCore::HTMLVideoElementPictureInPicture::autoPictureInPicture):
+        (WebCore::HTMLVideoElementPictureInPicture::setAutoPictureInPicture):
+        (WebCore::HTMLVideoElementPictureInPicture::disablePictureInPicture):
+        (WebCore::HTMLVideoElementPictureInPicture::setDisablePictureInPicture):
+        (WebCore::HTMLVideoElementPictureInPicture::exitPictureInPicture):
+        (WebCore::HTMLVideoElementPictureInPicture::didEnterPictureInPicture):
+        (WebCore::HTMLVideoElementPictureInPicture::didExitPictureInPicture):
+        * Modules/pictureinpicture/HTMLVideoElementPictureInPicture.h: Added.
+        (WebCore::HTMLVideoElementPictureInPicture::supplementName):
+        * Modules/pictureinpicture/HTMLVideoElementPictureInPicture.idl: Added.
+        * Modules/pictureinpicture/PictureInPictureWindow.cpp: Added.
+        (WebCore::PictureInPictureWindow::create):
+        (WebCore::PictureInPictureWindow::PictureInPictureWindow):
+        (WebCore::PictureInPictureWindow::activeDOMObjectName const):
+        (WebCore::PictureInPictureWindow::canSuspendForDocumentSuspension const):
+        (WebCore::PictureInPictureWindow::eventTargetInterface const):
+        (WebCore::PictureInPictureWindow::scriptExecutionContext const):
+        * Modules/pictureinpicture/PictureInPictureWindow.h: Added.
+        * Modules/pictureinpicture/PictureInPictureWindow.idl: Added.
+        * Modules/webaudio/OfflineAudioContext.cpp:
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * bindings/js/WebCoreBuiltinNames.h:
+        * dom/Document.cpp:
+        (WebCore::Document::pictureInPictureElement const):
+        (WebCore::Document::setPictureInPictureElement):
+        * dom/Document.h:
+        * dom/DocumentOrShadowRoot.idl:
+        * dom/EventNames.h:
+        * dom/EventNames.in:
+        * dom/EventTargetFactory.in:
+        * dom/ShadowRoot.cpp:
+        (WebCore::ShadowRoot::pictureInPictureElement const):
+        * dom/ShadowRoot.h:
+        * html/HTMLVideoElement.cpp:
+        (WebCore::HTMLVideoElement::fullscreenModeChanged):
+        (WebCore::HTMLVideoElement::setPictureInPictureObserver):
+        * html/HTMLVideoElement.h:
+        * page/Settings.yaml:
+        * platform/PictureInPictureObserver.h: Added.
+        (WebCore::PictureInPictureObserver::~PictureInPictureObserver):
+        * testing/InternalSettings.h:
+
 2019-10-15  Simon Fraser  <simon.fraser@apple.com>
 
         Add TextStream dumping for ThemeTypes enums
diff --git a/Source/WebCore/Configurations/FeatureDefines.xcconfig b/Source/WebCore/Configurations/FeatureDefines.xcconfig
index d808ee0..140ffe5 100644
--- a/Source/WebCore/Configurations/FeatureDefines.xcconfig
+++ b/Source/WebCore/Configurations/FeatureDefines.xcconfig
@@ -313,6 +313,9 @@
 
 ENABLE_PAYMENT_REQUEST = ENABLE_PAYMENT_REQUEST;
 
+ENABLE_PICTURE_IN_PICTURE_API = $(ENABLE_PICTURE_IN_PICTURE_API_$(WK_PLATFORM_NAME));
+ENABLE_PICTURE_IN_PICTURE_API_macosx = ENABLE_PICTURE_IN_PICTURE_API;
+
 ENABLE_PDFKIT_PLUGIN = $(ENABLE_PDFKIT_PLUGIN_$(WK_PLATFORM_NAME));
 ENABLE_PDFKIT_PLUGIN_macosx = ENABLE_PDFKIT_PLUGIN;
 
@@ -443,4 +446,4 @@
 
 ENABLE_XSLT = ENABLE_XSLT;
 
-FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCESSIBILITY_ISOLATED_TREE) $(ENABLE_APPLE_PAY) $(ENABLE_APPLE_PAY_SESSION_V3) $(ENABLE_APPLE_PAY_SESSION_V4) $(ENABLE_APPLICATION_MANIFEST) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_AVF_CAPTIONS) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSS3_TEXT) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_CONIC_GRADIENTS) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_PAINTING_API) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_CSS_TYPED_OM) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_C_LOOP) $(ENABLE_DARK_MODE_CSS) $(ENABLE_DATACUE_VALUE) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DATA_INTERACTION) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DRAG_SUPPORT) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_EXPERIMENTAL_FEATURES) $(ENABLE_FAST_JIT_PERMISSIONS) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FTL_JIT) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_INSPECTOR_ALTERNATE_DISPATCHERS) $(ENABLE_INTERSECTION_OBSERVER) $(ENABLE_INTL) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_JIT) $(ENABLE_KEYBOARD_CODE_ATTRIBUTE) $(ENABLE_KEYBOARD_KEY_ATTRIBUTE) $(ENABLE_LAYOUT_FORMATTING_CONTEXT) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_CUSTOM_PROTOCOL_MANAGER) $(ENABLE_LEGACY_ENCRYPTED_MEDIA) $(ENABLE_LETTERPRESS) $(ENABLE_MAC_GESTURE_EVENTS) $(ENABLE_MAC_VIDEO_TOOLBOX) $(ENABLE_MATHML) $(ENABLE_MEDIA_CAPTURE) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_MEMORY_SAMPLER) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_STANDALONE) $(ENABLE_NETWORK_CACHE_SPECULATIVE_REVALIDATION) $(ENABLE_NOTIFICATIONS) $(ENABLE_OVERFLOW_SCROLLING_TOUCH) $(ENABLE_PAYMENT_REQUEST) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_POINTER_EVENTS) $(ENABLE_POINTER_LOCK) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_RESIZE_OBSERVER) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RESOURCE_LOAD_STATISTICS) $(ENABLE_RESOURCE_USAGE) $(ENABLE_RUBBER_BANDING) $(ENABLE_SANDBOX_EXTENSIONS) $(ENABLE_SERVER_PRECONNECT) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_SERVICE_WORKER) $(ENABLE_SHAREABLE_RESOURCE) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_STREAMS_API) $(ENABLE_SVG_FONTS) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TOUCH_EVENTS) $(ENABLE_USERSELECT_ALL) $(ENABLE_USER_MESSAGE_HANDLERS) $(ENABLE_VARIATION_FONTS) $(ENABLE_VIDEO) $(ENABLE_VIDEO_PRESENTATION_MODE) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIDEO_USES_ELEMENT_FULLSCREEN) $(ENABLE_WEBASSEMBLY) $(ENABLE_WEBASSEMBLY_STREAMING_API) $(ENABLE_WEBDRIVER_MOUSE_INTERACTIONS) $(ENABLE_WEBDRIVER_KEYBOARD_INTERACTIONS) $(ENABLE_WEBDRIVER_TOUCH_INTERACTIONS) $(ENABLE_WEBGL) $(ENABLE_WEBGL2) $(ENABLE_WEBGPU) $(ENABLE_WEB_API_STATISTICS) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_AUTHN) $(ENABLE_WEB_CRYPTO) $(ENABLE_WEB_RTC) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_XSLT);
+FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCESSIBILITY_ISOLATED_TREE) $(ENABLE_APPLE_PAY) $(ENABLE_APPLE_PAY_SESSION_V3) $(ENABLE_APPLE_PAY_SESSION_V4) $(ENABLE_APPLICATION_MANIFEST) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_AVF_CAPTIONS) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSS3_TEXT) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_CONIC_GRADIENTS) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_PAINTING_API) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_CSS_TYPED_OM) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_C_LOOP) $(ENABLE_DARK_MODE_CSS) $(ENABLE_DATACUE_VALUE) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DATA_INTERACTION) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DRAG_SUPPORT) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_EXPERIMENTAL_FEATURES) $(ENABLE_FAST_JIT_PERMISSIONS) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FTL_JIT) $(ENABLE_FULLSCREEN_API) $(ENABLE_PICTURE_IN_PICTURE_API) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_INSPECTOR_ALTERNATE_DISPATCHERS) $(ENABLE_INTERSECTION_OBSERVER) $(ENABLE_INTL) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_JIT) $(ENABLE_KEYBOARD_CODE_ATTRIBUTE) $(ENABLE_KEYBOARD_KEY_ATTRIBUTE) $(ENABLE_LAYOUT_FORMATTING_CONTEXT) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_CUSTOM_PROTOCOL_MANAGER) $(ENABLE_LEGACY_ENCRYPTED_MEDIA) $(ENABLE_LETTERPRESS) $(ENABLE_MAC_GESTURE_EVENTS) $(ENABLE_MAC_VIDEO_TOOLBOX) $(ENABLE_MATHML) $(ENABLE_MEDIA_CAPTURE) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_MEMORY_SAMPLER) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_STANDALONE) $(ENABLE_NETWORK_CACHE_SPECULATIVE_REVALIDATION) $(ENABLE_NOTIFICATIONS) $(ENABLE_OVERFLOW_SCROLLING_TOUCH) $(ENABLE_PAYMENT_REQUEST) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_POINTER_EVENTS) $(ENABLE_POINTER_LOCK) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_RESIZE_OBSERVER) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RESOURCE_LOAD_STATISTICS) $(ENABLE_RESOURCE_USAGE) $(ENABLE_RUBBER_BANDING) $(ENABLE_SANDBOX_EXTENSIONS) $(ENABLE_SERVER_PRECONNECT) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_SERVICE_WORKER) $(ENABLE_SHAREABLE_RESOURCE) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_STREAMS_API) $(ENABLE_SVG_FONTS) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TOUCH_EVENTS) $(ENABLE_USERSELECT_ALL) $(ENABLE_USER_MESSAGE_HANDLERS) $(ENABLE_VARIATION_FONTS) $(ENABLE_VIDEO) $(ENABLE_VIDEO_PRESENTATION_MODE) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIDEO_USES_ELEMENT_FULLSCREEN) $(ENABLE_WEBASSEMBLY) $(ENABLE_WEBASSEMBLY_STREAMING_API) $(ENABLE_WEBDRIVER_MOUSE_INTERACTIONS) $(ENABLE_WEBDRIVER_KEYBOARD_INTERACTIONS) $(ENABLE_WEBDRIVER_TOUCH_INTERACTIONS) $(ENABLE_WEBGL) $(ENABLE_WEBGL2) $(ENABLE_WEBGPU) $(ENABLE_WEB_API_STATISTICS) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_AUTHN) $(ENABLE_WEB_CRYPTO) $(ENABLE_WEB_RTC) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_XSLT);
diff --git a/Source/WebCore/DerivedSources-input.xcfilelist b/Source/WebCore/DerivedSources-input.xcfilelist
index 8e84e68..a8b6228 100644
--- a/Source/WebCore/DerivedSources-input.xcfilelist
+++ b/Source/WebCore/DerivedSources-input.xcfilelist
@@ -235,6 +235,10 @@
 $(PROJECT_DIR)/Modules/paymentrequest/PaymentShippingOption.idl
 $(PROJECT_DIR)/Modules/paymentrequest/PaymentShippingType.idl
 $(PROJECT_DIR)/Modules/paymentrequest/PaymentValidationErrors.idl
+$(PROJECT_DIR)/Modules/pictureinpicture/DocumentPictureInPicture.idl
+$(PROJECT_DIR)/Modules/pictureinpicture/EnterPictureInPictureEvent.idl
+$(PROJECT_DIR)/Modules/pictureinpicture/HTMLVideoElementPictureInPicture.idl
+$(PROJECT_DIR)/Modules/pictureinpicture/PictureInPictureWindow.idl
 $(PROJECT_DIR)/Modules/plugins/QuickTimePluginReplacement.css
 $(PROJECT_DIR)/Modules/plugins/QuickTimePluginReplacement.idl
 $(PROJECT_DIR)/Modules/plugins/QuickTimePluginReplacement.js
diff --git a/Source/WebCore/DerivedSources-output.xcfilelist b/Source/WebCore/DerivedSources-output.xcfilelist
index 951ddf3..847d83e 100644
--- a/Source/WebCore/DerivedSources-output.xcfilelist
+++ b/Source/WebCore/DerivedSources-output.xcfilelist
@@ -483,6 +483,8 @@
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSDocumentFullscreen.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSDocumentOrShadowRoot.cpp
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSDocumentOrShadowRoot.h
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSDocumentPictureInPicture.cpp
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSDocumentPictureInPicture.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSDocumentStorageAccess.cpp
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSDocumentStorageAccess.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSDocumentTimeline.cpp
@@ -519,6 +521,8 @@
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSElement.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSElementCSSInlineStyle.cpp
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSElementCSSInlineStyle.h
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSEnterPictureInPictureEvent.cpp
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSEnterPictureInPictureEvent.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSErrorCallback.cpp
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSErrorCallback.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSErrorEvent.cpp
@@ -855,6 +859,8 @@
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSHTMLUnknownElement.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSHTMLVideoElement.cpp
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSHTMLVideoElement.h
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSHTMLVideoElementPictureInPicture.cpp
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSHTMLVideoElementPictureInPicture.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSHashChangeEvent.cpp
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSHashChangeEvent.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSHistory.cpp
@@ -1241,6 +1247,8 @@
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSPerformanceTiming.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSPeriodicWave.cpp
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSPeriodicWave.h
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSPictureInPictureWindow.cpp
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSPictureInPictureWindow.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSPlaybackDirection.cpp
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSPlaybackDirection.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSPointerEvent.cpp
diff --git a/Source/WebCore/DerivedSources.make b/Source/WebCore/DerivedSources.make
index f587cb32..64de599 100644
--- a/Source/WebCore/DerivedSources.make
+++ b/Source/WebCore/DerivedSources.make
@@ -51,6 +51,7 @@
     $(WebCore)/Modules/mediastream \
     $(WebCore)/Modules/notifications \
     $(WebCore)/Modules/paymentrequest \
+    $(WebCore)/Modules/pictureinpicture \
     $(WebCore)/Modules/plugins \
     $(WebCore)/Modules/quota \
     $(WebCore)/Modules/speech \
@@ -203,8 +204,8 @@
     $(WebCore)/Modules/indexeddb/WorkerGlobalScopeIndexedDatabase.idl \
     $(WebCore)/Modules/mediacapabilities/AudioConfiguration.idl \
     $(WebCore)/Modules/mediacapabilities/MediaCapabilities.idl \
-	$(WebCore)/Modules/mediacapabilities/MediaCapabilitiesDecodingInfo.idl \
-	$(WebCore)/Modules/mediacapabilities/MediaCapabilitiesEncodingInfo.idl \
+    $(WebCore)/Modules/mediacapabilities/MediaCapabilitiesDecodingInfo.idl \
+    $(WebCore)/Modules/mediacapabilities/MediaCapabilitiesEncodingInfo.idl \
     $(WebCore)/Modules/mediacapabilities/MediaCapabilitiesInfo.idl \
     $(WebCore)/Modules/mediacapabilities/MediaConfiguration.idl \
     $(WebCore)/Modules/mediacapabilities/MediaDecodingConfiguration.idl \
@@ -306,6 +307,10 @@
     $(WebCore)/Modules/paymentrequest/PaymentShippingOption.idl \
     $(WebCore)/Modules/paymentrequest/PaymentShippingType.idl \
     $(WebCore)/Modules/paymentrequest/PaymentValidationErrors.idl \
+    $(WebCore)/Modules/pictureinpicture/DocumentPictureInPicture.idl \
+    $(WebCore)/Modules/pictureinpicture/EnterPictureInPictureEvent.idl \
+    $(WebCore)/Modules/pictureinpicture/HTMLVideoElementPictureInPicture.idl \
+    $(WebCore)/Modules/pictureinpicture/PictureInPictureWindow.idl \
     $(WebCore)/Modules/plugins/QuickTimePluginReplacement.idl \
     $(WebCore)/Modules/quota/DOMWindowQuota.idl \
     $(WebCore)/Modules/quota/NavigatorStorageQuota.idl \
@@ -409,7 +414,7 @@
     $(WebCore)/Modules/webgpu/GPUValidationError.idl \
     $(WebCore)/Modules/webgpu/GPUVertexAttributeDescriptor.idl \
     $(WebCore)/Modules/webgpu/GPUVertexBufferDescriptor.idl \
-	$(WebCore)/Modules/webgpu/GPUVertexInputDescriptor.idl \
+    $(WebCore)/Modules/webgpu/GPUVertexInputDescriptor.idl \
     $(WebCore)/Modules/webgpu/NavigatorGPU.idl \
     $(WebCore)/Modules/webgpu/WebGPU.idl \
     $(WebCore)/Modules/webgpu/WebGPUAdapter.idl \
@@ -418,14 +423,14 @@
     $(WebCore)/Modules/webgpu/WebGPUBindGroupDescriptor.idl \
     $(WebCore)/Modules/webgpu/WebGPUBindGroupLayout.idl \
     $(WebCore)/Modules/webgpu/WebGPUBuffer.idl \
-	$(WebCore)/Modules/webgpu/WebGPUBufferBinding.idl \
+    $(WebCore)/Modules/webgpu/WebGPUBufferBinding.idl \
     $(WebCore)/Modules/webgpu/WebGPUCommandBuffer.idl \
     $(WebCore)/Modules/webgpu/WebGPUCommandEncoder.idl \
     $(WebCore)/Modules/webgpu/WebGPUComputePassEncoder.idl \
     $(WebCore)/Modules/webgpu/WebGPUComputePipeline.idl \
     $(WebCore)/Modules/webgpu/WebGPUComputePipelineDescriptor.idl \
     $(WebCore)/Modules/webgpu/WebGPUDevice.idl \
-	$(WebCore)/Modules/webgpu/WebGPUDeviceErrorScopes.idl \
+    $(WebCore)/Modules/webgpu/WebGPUDeviceErrorScopes.idl \
     $(WebCore)/Modules/webgpu/WebGPUDeviceEventHandler.idl \
     $(WebCore)/Modules/webgpu/WebGPUQueue.idl \
     $(WebCore)/Modules/webgpu/WebGPUPipelineDescriptorBase.idl \
@@ -552,7 +557,7 @@
     $(WebCore)/css/StyleSheetList.idl \
     $(WebCore)/css/typedom/StylePropertyMap.idl \
     $(WebCore)/css/typedom/StylePropertyMapReadOnly.idl \
-	$(WebCore)/css/typedom/TypedOMCSSImageValue.idl \
+    $(WebCore)/css/typedom/TypedOMCSSImageValue.idl \
     $(WebCore)/css/typedom/TypedOMCSSNumericValue.idl \
     $(WebCore)/css/typedom/TypedOMCSSStyleValue.idl \
     $(WebCore)/css/typedom/TypedOMCSSUnitValue.idl \
diff --git a/Source/WebCore/Modules/pictureinpicture/DocumentPictureInPicture.cpp b/Source/WebCore/Modules/pictureinpicture/DocumentPictureInPicture.cpp
new file mode 100644
index 0000000..6af3c36
--- /dev/null
+++ b/Source/WebCore/Modules/pictureinpicture/DocumentPictureInPicture.cpp
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2019 Carlos Eduardo Ramalho <cadubentzen@gmail.com>.
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DocumentPictureInPicture.h"
+
+#if ENABLE(PICTURE_IN_PICTURE_API)
+
+#include "Document.h"
+#include "HTMLVideoElementPictureInPicture.h"
+#include "JSDOMPromiseDeferred.h"
+#include <wtf/IsoMallocInlines.h>
+
+namespace WebCore {
+
+WTF_MAKE_ISO_ALLOCATED_IMPL(DocumentPictureInPicture);
+
+DocumentPictureInPicture::~DocumentPictureInPicture() = default;
+
+void DocumentPictureInPicture::exitPictureInPicture(Document& document, Ref<DeferredPromise>&& promise)
+{
+    auto element = document.pictureInPictureElement();
+
+    if (!element) {
+        promise->reject(InvalidStateError);
+        return;
+    }
+
+    HTMLVideoElementPictureInPicture::from(*element)->exitPictureInPicture(WTFMove(promise));
+}
+
+DocumentPictureInPicture* DocumentPictureInPicture::from(Document& document)
+{
+    DocumentPictureInPicture* supplement = static_cast<DocumentPictureInPicture*>(Supplement<Document>::from(&document, supplementName()));
+    if (!supplement) {
+        auto newSupplement = makeUnique<DocumentPictureInPicture>();
+        supplement = newSupplement.get();
+        provideTo(&document, supplementName(), WTFMove(newSupplement));
+    }
+    return supplement;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(PICTURE_IN_PICTURE_API)
diff --git a/Source/WebCore/Modules/pictureinpicture/DocumentPictureInPicture.h b/Source/WebCore/Modules/pictureinpicture/DocumentPictureInPicture.h
new file mode 100644
index 0000000..2cce978
--- /dev/null
+++ b/Source/WebCore/Modules/pictureinpicture/DocumentPictureInPicture.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2019 Carlos Eduardo Ramalho <cadubentzen@gmail.com>.
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(PICTURE_IN_PICTURE_API)
+
+#include "HTMLVideoElement.h"
+#include "Supplementable.h"
+#include <wtf/IsoMalloc.h>
+
+namespace WebCore {
+
+class DeferredPromise;
+class Document;
+
+class DocumentPictureInPicture : public Supplement<Document> {
+    WTF_MAKE_ISO_ALLOCATED(DocumentPictureInPicture);
+public:
+    virtual ~DocumentPictureInPicture();
+
+    static bool pictureInPictureEnabled(Document&) { return true; }
+    static void exitPictureInPicture(Document&, Ref<DeferredPromise>&&);
+
+    static DocumentPictureInPicture* from(Document&);
+
+private:
+    static const char* supplementName() { return "DocumentPictureInPicture"; };
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(PICTURE_IN_PICTURE_API)
diff --git a/Source/WebCore/Modules/pictureinpicture/DocumentPictureInPicture.idl b/Source/WebCore/Modules/pictureinpicture/DocumentPictureInPicture.idl
new file mode 100644
index 0000000..c5b0d29
--- /dev/null
+++ b/Source/WebCore/Modules/pictureinpicture/DocumentPictureInPicture.idl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2019 Carlos Eduardo Ramalho <cadubentzen@gmail.com>.
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+[
+    Conditional=PICTURE_IN_PICTURE_API,
+    EnabledBySetting=PictureInPictureAPI
+] partial interface Document {
+    readonly attribute boolean pictureInPictureEnabled;
+
+    [NewObject] Promise<void> exitPictureInPicture();
+};
diff --git a/Source/WebCore/Modules/pictureinpicture/EnterPictureInPictureEvent.cpp b/Source/WebCore/Modules/pictureinpicture/EnterPictureInPictureEvent.cpp
new file mode 100644
index 0000000..84d843e
--- /dev/null
+++ b/Source/WebCore/Modules/pictureinpicture/EnterPictureInPictureEvent.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2019 Carlos Eduardo Ramalho <cadubentzen@gmail.com>.
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "EnterPictureInPictureEvent.h"
+
+#if ENABLE(PICTURE_IN_PICTURE_API)
+
+#include "PictureInPictureWindow.h"
+#include <wtf/IsoMallocInlines.h>
+
+namespace WebCore {
+
+WTF_MAKE_ISO_ALLOCATED_IMPL(EnterPictureInPictureEvent);
+
+Ref<EnterPictureInPictureEvent> EnterPictureInPictureEvent::create(const AtomString& type, Init&& init, IsTrusted isTrusted)
+{
+    return adoptRef(*new EnterPictureInPictureEvent(type, WTFMove(init), isTrusted));
+}
+
+EnterPictureInPictureEvent::EnterPictureInPictureEvent(const AtomString& type, Init&& init, IsTrusted isTrusted)
+    : Event(type, init, isTrusted)
+    , m_pictureInPictureWindow(init.pictureInPictureWindow.releaseNonNull())
+{
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(PICTURE_IN_PICTURE_API)
diff --git a/Source/WebCore/Modules/pictureinpicture/EnterPictureInPictureEvent.h b/Source/WebCore/Modules/pictureinpicture/EnterPictureInPictureEvent.h
new file mode 100644
index 0000000..e2c4df7
--- /dev/null
+++ b/Source/WebCore/Modules/pictureinpicture/EnterPictureInPictureEvent.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2019 Carlos Eduardo Ramalho <cadubentzen@gmail.com>.
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(PICTURE_IN_PICTURE_API)
+
+#include "Event.h"
+
+namespace WebCore {
+
+class PictureInPictureWindow;
+
+class EnterPictureInPictureEvent final : public Event {
+    WTF_MAKE_ISO_ALLOCATED(EnterPictureInPictureEvent);
+public:
+    struct Init : EventInit {
+        RefPtr<PictureInPictureWindow> pictureInPictureWindow;
+    };
+
+    static Ref<EnterPictureInPictureEvent> create(const AtomString&, Init&&, IsTrusted = IsTrusted::No);
+
+    PictureInPictureWindow& pictureInPictureWindow() const { return m_pictureInPictureWindow.get(); }
+
+    EventInterface eventInterface() const final { return EnterPictureInPictureEventInterfaceType; }
+
+private:
+    EnterPictureInPictureEvent(const AtomString&, Init&&, IsTrusted = IsTrusted::No);
+
+    Ref<PictureInPictureWindow> m_pictureInPictureWindow;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(PICTURE_IN_PICTURE_API)
diff --git a/Source/WebCore/Modules/pictureinpicture/EnterPictureInPictureEvent.idl b/Source/WebCore/Modules/pictureinpicture/EnterPictureInPictureEvent.idl
new file mode 100644
index 0000000..ad36c49
--- /dev/null
+++ b/Source/WebCore/Modules/pictureinpicture/EnterPictureInPictureEvent.idl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2019 Carlos Eduardo Ramalho <cadubentzen@gmail.com>.
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+[
+    Conditional=PICTURE_IN_PICTURE_API,
+    EnabledBySetting=PictureInPictureAPI
+] dictionary EnterPictureInPictureEventInit : EventInit {
+    required PictureInPictureWindow pictureInPictureWindow;
+};
+
+[
+    Conditional=PICTURE_IN_PICTURE_API,
+    EnabledBySetting=PictureInPictureAPI,
+    Constructor(DOMString type, EnterPictureInPictureEventInit eventInitDict),
+    Exposed=Window
+] interface EnterPictureInPictureEvent : Event {
+    [SameObject] readonly attribute PictureInPictureWindow pictureInPictureWindow;
+};
diff --git a/Source/WebCore/Modules/pictureinpicture/HTMLVideoElementPictureInPicture.cpp b/Source/WebCore/Modules/pictureinpicture/HTMLVideoElementPictureInPicture.cpp
new file mode 100644
index 0000000..df960b2
--- /dev/null
+++ b/Source/WebCore/Modules/pictureinpicture/HTMLVideoElementPictureInPicture.cpp
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2019 Carlos Eduardo Ramalho <cadubentzen@gmail.com>.
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "HTMLVideoElementPictureInPicture.h"
+
+#if ENABLE(PICTURE_IN_PICTURE_API)
+
+#include "HTMLVideoElement.h"
+#include "JSDOMPromiseDeferred.h"
+#include "PictureInPictureWindow.h"
+#include "VideoTrackList.h"
+#include <wtf/IsoMallocInlines.h>
+
+namespace WebCore {
+
+WTF_MAKE_ISO_ALLOCATED_IMPL(HTMLVideoElementPictureInPicture);
+
+HTMLVideoElementPictureInPicture::HTMLVideoElementPictureInPicture(HTMLVideoElement& videoElement)
+    : m_videoElement(videoElement)
+{
+    m_videoElement.setPictureInPictureObserver(this);
+}
+
+HTMLVideoElementPictureInPicture::~HTMLVideoElementPictureInPicture()
+{
+    m_videoElement.setPictureInPictureObserver(nullptr);
+}
+
+HTMLVideoElementPictureInPicture* HTMLVideoElementPictureInPicture::from(HTMLVideoElement& videoElement)
+{
+    HTMLVideoElementPictureInPicture* supplement = static_cast<HTMLVideoElementPictureInPicture*>(Supplement<HTMLVideoElement>::from(&videoElement, supplementName()));
+    if (!supplement) {
+        auto newSupplement = makeUnique<HTMLVideoElementPictureInPicture>(videoElement);
+        supplement = newSupplement.get();
+        provideTo(&videoElement, supplementName(), WTFMove(newSupplement));
+    }
+    return supplement;
+}
+
+void HTMLVideoElementPictureInPicture::requestPictureInPicture(HTMLVideoElement& videoElement, Ref<DeferredPromise>&& promise)
+{
+    if (!videoElement.player() || !videoElement.player()->supportsPictureInPicture()) {
+        promise->reject(NotSupportedError);
+        return;
+    }
+
+    if (videoElement.readyState() == HTMLMediaElementEnums::HAVE_NOTHING) {
+        promise->reject(InvalidStateError);
+        return;
+    }
+
+#if ENABLE(VIDEO_TRACK)
+    if (!videoElement.videoTracks() || !videoElement.videoTracks()->length()) {
+        promise->reject(InvalidStateError);
+        return;
+    }
+#endif
+
+    bool userActivationRequired = !videoElement.document().pictureInPictureElement();
+    if (userActivationRequired && !UserGestureIndicator::processingUserGesture()) {
+        promise->reject(NotAllowedError);
+        return;
+    }
+
+    if (videoElement.document().pictureInPictureElement() == &videoElement) {
+        promise->reject(NotAllowedError);
+        return;
+    }
+
+    auto videoElementPictureInPicture = HTMLVideoElementPictureInPicture::from(videoElement);
+    if (videoElementPictureInPicture->m_enterPictureInPicturePromise || videoElementPictureInPicture->m_exitPictureInPicturePromise) {
+        promise->reject(NotAllowedError);
+        return;
+    }
+
+    if (videoElement.webkitSupportsPresentationMode(HTMLVideoElement::VideoPresentationMode::PictureInPicture)) {
+        videoElementPictureInPicture->m_enterPictureInPicturePromise = WTFMove(promise);
+        videoElement.webkitSetPresentationMode(HTMLVideoElement::VideoPresentationMode::PictureInPicture);
+    } else
+        promise->reject(NotSupportedError);
+}
+
+bool HTMLVideoElementPictureInPicture::autoPictureInPicture(HTMLVideoElement& videoElement)
+{
+    return HTMLVideoElementPictureInPicture::from(videoElement)->m_autoPictureInPicture;
+}
+
+void HTMLVideoElementPictureInPicture::setAutoPictureInPicture(HTMLVideoElement& videoElement, bool autoPictureInPicture)
+{
+    HTMLVideoElementPictureInPicture::from(videoElement)->m_autoPictureInPicture = autoPictureInPicture;
+}
+
+bool HTMLVideoElementPictureInPicture::disablePictureInPicture(HTMLVideoElement& videoElement)
+{
+    return HTMLVideoElementPictureInPicture::from(videoElement)->m_disablePictureInPicture;
+}
+
+void HTMLVideoElementPictureInPicture::setDisablePictureInPicture(HTMLVideoElement& videoElement, bool disablePictureInPicture)
+{
+    HTMLVideoElementPictureInPicture::from(videoElement)->m_disablePictureInPicture = disablePictureInPicture;
+}
+
+void HTMLVideoElementPictureInPicture::exitPictureInPicture(Ref<DeferredPromise>&& promise)
+{
+    if (m_enterPictureInPicturePromise || m_exitPictureInPicturePromise) {
+        promise->reject(NotAllowedError);
+        return;
+    }
+
+    m_exitPictureInPicturePromise = WTFMove(promise);
+    m_videoElement.webkitSetPresentationMode(HTMLVideoElement::VideoPresentationMode::Inline);
+}
+
+void HTMLVideoElementPictureInPicture::didEnterPictureInPicture()
+{
+    m_videoElement.document().setPictureInPictureElement(&m_videoElement);
+    if (m_enterPictureInPicturePromise) {
+        m_enterPictureInPicturePromise->resolve();
+        m_enterPictureInPicturePromise = nullptr;
+    }
+}
+
+void HTMLVideoElementPictureInPicture::didExitPictureInPicture()
+{
+    m_videoElement.document().setPictureInPictureElement(nullptr);
+    if (m_exitPictureInPicturePromise) {
+        m_exitPictureInPicturePromise->resolve();
+        m_exitPictureInPicturePromise = nullptr;
+    }
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(PICTURE_IN_PICTURE_API)
diff --git a/Source/WebCore/Modules/pictureinpicture/HTMLVideoElementPictureInPicture.h b/Source/WebCore/Modules/pictureinpicture/HTMLVideoElementPictureInPicture.h
new file mode 100644
index 0000000..5311c02
--- /dev/null
+++ b/Source/WebCore/Modules/pictureinpicture/HTMLVideoElementPictureInPicture.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2019 Carlos Eduardo Ramalho <cadubentzen@gmail.com>.
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(PICTURE_IN_PICTURE_API)
+
+#include "PictureInPictureObserver.h"
+#include "Supplementable.h"
+#include <wtf/IsoMalloc.h>
+
+namespace WebCore {
+
+class DeferredPromise;
+class HTMLVideoElement;
+class PictureInPictureWindow;
+
+class HTMLVideoElementPictureInPicture
+    : public Supplement<HTMLVideoElement>
+    , public PictureInPictureObserver {
+    WTF_MAKE_ISO_ALLOCATED(HTMLVideoElementPictureInPicture);
+public:
+    HTMLVideoElementPictureInPicture(HTMLVideoElement&);
+    static HTMLVideoElementPictureInPicture* from(HTMLVideoElement&);
+    virtual ~HTMLVideoElementPictureInPicture();
+
+    static void requestPictureInPicture(HTMLVideoElement&, Ref<DeferredPromise>&&);
+    static bool autoPictureInPicture(HTMLVideoElement&);
+    static void setAutoPictureInPicture(HTMLVideoElement&, bool);
+    static bool disablePictureInPicture(HTMLVideoElement&);
+    static void setDisablePictureInPicture(HTMLVideoElement&, bool);
+
+    void exitPictureInPicture(Ref<DeferredPromise>&&);
+
+    void didEnterPictureInPicture();
+    void didExitPictureInPicture();
+
+private:
+    static const char* supplementName() { return "HTMLVideoElementPictureInPicture"; }
+
+    bool m_autoPictureInPicture { false };
+    bool m_disablePictureInPicture { false };
+
+    HTMLVideoElement& m_videoElement;
+    RefPtr<DeferredPromise> m_enterPictureInPicturePromise;
+    RefPtr<DeferredPromise> m_exitPictureInPicturePromise;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(PICTURE_IN_PICTURE_API)
diff --git a/Source/WebCore/Modules/pictureinpicture/HTMLVideoElementPictureInPicture.idl b/Source/WebCore/Modules/pictureinpicture/HTMLVideoElementPictureInPicture.idl
new file mode 100644
index 0000000..f95000b
--- /dev/null
+++ b/Source/WebCore/Modules/pictureinpicture/HTMLVideoElementPictureInPicture.idl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2019 Carlos Eduardo Ramalho <cadubentzen@gmail.com>.
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+[
+    Conditional=PICTURE_IN_PICTURE_API,
+    EnabledBySetting=PictureInPictureAPI
+] partial interface HTMLVideoElement {
+  [NewObject] Promise<PictureInPictureWindow> requestPictureInPicture();
+
+  attribute EventHandler onenterpictureinpicture;
+  attribute EventHandler onleavepictureinpicture;
+
+  [CEReactions] attribute boolean autoPictureInPicture;
+  [CEReactions] attribute boolean disablePictureInPicture;
+};
diff --git a/Source/WebCore/Modules/pictureinpicture/PictureInPictureWindow.cpp b/Source/WebCore/Modules/pictureinpicture/PictureInPictureWindow.cpp
new file mode 100644
index 0000000..49ec747
--- /dev/null
+++ b/Source/WebCore/Modules/pictureinpicture/PictureInPictureWindow.cpp
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2019 Carlos Eduardo Ramalho <cadubentzen@gmail.com>.
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PictureInPictureWindow.h"
+
+#if ENABLE(PICTURE_IN_PICTURE_API)
+
+#include <wtf/IsoMallocInlines.h>
+
+namespace WebCore {
+
+WTF_MAKE_ISO_ALLOCATED_IMPL(PictureInPictureWindow);
+
+Ref<PictureInPictureWindow> PictureInPictureWindow::create(ScriptExecutionContext& scriptExecutionContext, int width, int height)
+{
+    return adoptRef(*new PictureInPictureWindow(scriptExecutionContext, width, height));
+}
+
+PictureInPictureWindow::PictureInPictureWindow(ScriptExecutionContext& scriptExecutionContext, int width, int height)
+    : ActiveDOMObject(&scriptExecutionContext)
+    , m_width(width)
+    , m_height(height)
+{
+}
+
+PictureInPictureWindow::~PictureInPictureWindow() = default;
+
+const char* PictureInPictureWindow::activeDOMObjectName() const
+{
+    return "PictureInPictureWindow";
+}
+
+bool PictureInPictureWindow::canSuspendForDocumentSuspension() const
+{
+    return true;
+}
+
+EventTargetInterface PictureInPictureWindow::eventTargetInterface() const
+{
+    return PictureInPictureWindowEventTargetInterfaceType;
+}
+
+ScriptExecutionContext* PictureInPictureWindow::scriptExecutionContext() const
+{
+    return ActiveDOMObject::scriptExecutionContext();
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(PICTURE_IN_PICTURE_API)
diff --git a/Source/WebCore/Modules/pictureinpicture/PictureInPictureWindow.h b/Source/WebCore/Modules/pictureinpicture/PictureInPictureWindow.h
new file mode 100644
index 0000000..7ae5a6b
--- /dev/null
+++ b/Source/WebCore/Modules/pictureinpicture/PictureInPictureWindow.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2019 Carlos Eduardo Ramalho <cadubentzen@gmail.com>.
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(PICTURE_IN_PICTURE_API)
+
+#include "ActiveDOMObject.h"
+#include "EventTarget.h"
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class PictureInPictureWindow final
+    : public RefCounted<PictureInPictureWindow>
+    , public ActiveDOMObject
+    , public EventTargetWithInlineData {
+    WTF_MAKE_ISO_ALLOCATED(PictureInPictureWindow);
+public:
+    static Ref<PictureInPictureWindow> create(ScriptExecutionContext&, int, int);
+    virtual ~PictureInPictureWindow();
+
+    int width() const { return m_width; }
+    int height() const { return m_height; }
+
+    // ActiveDOMObject
+    const char* activeDOMObjectName() const final;
+    bool canSuspendForDocumentSuspension() const final;
+
+    using RefCounted<PictureInPictureWindow>::ref;
+    using RefCounted<PictureInPictureWindow>::deref;
+
+private:
+    PictureInPictureWindow(ScriptExecutionContext&, int, int);
+
+    // EventTarget
+    void refEventTarget() final { ref(); }
+    void derefEventTarget() final { deref(); }
+    EventTargetInterface eventTargetInterface() const;
+    ScriptExecutionContext* scriptExecutionContext() const;
+
+    int m_width;
+    int m_height;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(PICTURE_IN_PICTURE_API)
diff --git a/Source/WebCore/Modules/pictureinpicture/PictureInPictureWindow.idl b/Source/WebCore/Modules/pictureinpicture/PictureInPictureWindow.idl
new file mode 100644
index 0000000..3e0b5d2
--- /dev/null
+++ b/Source/WebCore/Modules/pictureinpicture/PictureInPictureWindow.idl
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2019 Carlos Eduardo Ramalho <cadubentzen@gmail.com>.
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+[
+    ActiveDOMObject,
+    Conditional=PICTURE_IN_PICTURE_API,
+    EnabledBySetting=PictureInPictureAPI,
+    Exposed=Window
+] interface PictureInPictureWindow : EventTarget {
+  readonly attribute long width;
+  readonly attribute long height;
+
+  attribute EventHandler onresize;
+};
diff --git a/Source/WebCore/Modules/webaudio/OfflineAudioContext.cpp b/Source/WebCore/Modules/webaudio/OfflineAudioContext.cpp
index 11be75a..68fc8d6 100644
--- a/Source/WebCore/Modules/webaudio/OfflineAudioContext.cpp
+++ b/Source/WebCore/Modules/webaudio/OfflineAudioContext.cpp
@@ -28,6 +28,7 @@
 
 #include "OfflineAudioContext.h"
 
+#include "AudioBuffer.h"
 #include "Document.h"
 #include <wtf/IsoMallocInlines.h>
 
diff --git a/Source/WebCore/PAL/ChangeLog b/Source/WebCore/PAL/ChangeLog
index bb6f516..15ecd70 100644
--- a/Source/WebCore/PAL/ChangeLog
+++ b/Source/WebCore/PAL/ChangeLog
@@ -1,3 +1,14 @@
+2019-10-15  Peng Liu  <peng.liu6@apple.com>
+
+        [Picture-in-Picture Web API] Implement HTMLVideoElement.requestPictureInPicture() / Document.exitPictureInPicture()
+        https://bugs.webkit.org/show_bug.cgi?id=201024
+
+        Reviewed by Eric Carlson.
+
+        Add configurations for the Picture-in-Picture API.
+
+        * Configurations/FeatureDefines.xcconfig:
+
 2019-10-07  Alexey Proskuryakov  <ap@apple.com>
 
         Build failure in WebHTMLView.mm with the public SDK (Xcode 11 and Mojave)
diff --git a/Source/WebCore/PAL/Configurations/FeatureDefines.xcconfig b/Source/WebCore/PAL/Configurations/FeatureDefines.xcconfig
index d808ee0..140ffe5 100644
--- a/Source/WebCore/PAL/Configurations/FeatureDefines.xcconfig
+++ b/Source/WebCore/PAL/Configurations/FeatureDefines.xcconfig
@@ -313,6 +313,9 @@
 
 ENABLE_PAYMENT_REQUEST = ENABLE_PAYMENT_REQUEST;
 
+ENABLE_PICTURE_IN_PICTURE_API = $(ENABLE_PICTURE_IN_PICTURE_API_$(WK_PLATFORM_NAME));
+ENABLE_PICTURE_IN_PICTURE_API_macosx = ENABLE_PICTURE_IN_PICTURE_API;
+
 ENABLE_PDFKIT_PLUGIN = $(ENABLE_PDFKIT_PLUGIN_$(WK_PLATFORM_NAME));
 ENABLE_PDFKIT_PLUGIN_macosx = ENABLE_PDFKIT_PLUGIN;
 
@@ -443,4 +446,4 @@
 
 ENABLE_XSLT = ENABLE_XSLT;
 
-FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCESSIBILITY_ISOLATED_TREE) $(ENABLE_APPLE_PAY) $(ENABLE_APPLE_PAY_SESSION_V3) $(ENABLE_APPLE_PAY_SESSION_V4) $(ENABLE_APPLICATION_MANIFEST) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_AVF_CAPTIONS) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSS3_TEXT) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_CONIC_GRADIENTS) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_PAINTING_API) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_CSS_TYPED_OM) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_C_LOOP) $(ENABLE_DARK_MODE_CSS) $(ENABLE_DATACUE_VALUE) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DATA_INTERACTION) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DRAG_SUPPORT) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_EXPERIMENTAL_FEATURES) $(ENABLE_FAST_JIT_PERMISSIONS) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FTL_JIT) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_INSPECTOR_ALTERNATE_DISPATCHERS) $(ENABLE_INTERSECTION_OBSERVER) $(ENABLE_INTL) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_JIT) $(ENABLE_KEYBOARD_CODE_ATTRIBUTE) $(ENABLE_KEYBOARD_KEY_ATTRIBUTE) $(ENABLE_LAYOUT_FORMATTING_CONTEXT) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_CUSTOM_PROTOCOL_MANAGER) $(ENABLE_LEGACY_ENCRYPTED_MEDIA) $(ENABLE_LETTERPRESS) $(ENABLE_MAC_GESTURE_EVENTS) $(ENABLE_MAC_VIDEO_TOOLBOX) $(ENABLE_MATHML) $(ENABLE_MEDIA_CAPTURE) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_MEMORY_SAMPLER) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_STANDALONE) $(ENABLE_NETWORK_CACHE_SPECULATIVE_REVALIDATION) $(ENABLE_NOTIFICATIONS) $(ENABLE_OVERFLOW_SCROLLING_TOUCH) $(ENABLE_PAYMENT_REQUEST) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_POINTER_EVENTS) $(ENABLE_POINTER_LOCK) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_RESIZE_OBSERVER) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RESOURCE_LOAD_STATISTICS) $(ENABLE_RESOURCE_USAGE) $(ENABLE_RUBBER_BANDING) $(ENABLE_SANDBOX_EXTENSIONS) $(ENABLE_SERVER_PRECONNECT) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_SERVICE_WORKER) $(ENABLE_SHAREABLE_RESOURCE) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_STREAMS_API) $(ENABLE_SVG_FONTS) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TOUCH_EVENTS) $(ENABLE_USERSELECT_ALL) $(ENABLE_USER_MESSAGE_HANDLERS) $(ENABLE_VARIATION_FONTS) $(ENABLE_VIDEO) $(ENABLE_VIDEO_PRESENTATION_MODE) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIDEO_USES_ELEMENT_FULLSCREEN) $(ENABLE_WEBASSEMBLY) $(ENABLE_WEBASSEMBLY_STREAMING_API) $(ENABLE_WEBDRIVER_MOUSE_INTERACTIONS) $(ENABLE_WEBDRIVER_KEYBOARD_INTERACTIONS) $(ENABLE_WEBDRIVER_TOUCH_INTERACTIONS) $(ENABLE_WEBGL) $(ENABLE_WEBGL2) $(ENABLE_WEBGPU) $(ENABLE_WEB_API_STATISTICS) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_AUTHN) $(ENABLE_WEB_CRYPTO) $(ENABLE_WEB_RTC) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_XSLT);
+FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCESSIBILITY_ISOLATED_TREE) $(ENABLE_APPLE_PAY) $(ENABLE_APPLE_PAY_SESSION_V3) $(ENABLE_APPLE_PAY_SESSION_V4) $(ENABLE_APPLICATION_MANIFEST) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_AVF_CAPTIONS) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSS3_TEXT) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_CONIC_GRADIENTS) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_PAINTING_API) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_CSS_TYPED_OM) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_C_LOOP) $(ENABLE_DARK_MODE_CSS) $(ENABLE_DATACUE_VALUE) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DATA_INTERACTION) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DRAG_SUPPORT) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_EXPERIMENTAL_FEATURES) $(ENABLE_FAST_JIT_PERMISSIONS) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FTL_JIT) $(ENABLE_FULLSCREEN_API) $(ENABLE_PICTURE_IN_PICTURE_API) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_INSPECTOR_ALTERNATE_DISPATCHERS) $(ENABLE_INTERSECTION_OBSERVER) $(ENABLE_INTL) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_JIT) $(ENABLE_KEYBOARD_CODE_ATTRIBUTE) $(ENABLE_KEYBOARD_KEY_ATTRIBUTE) $(ENABLE_LAYOUT_FORMATTING_CONTEXT) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_CUSTOM_PROTOCOL_MANAGER) $(ENABLE_LEGACY_ENCRYPTED_MEDIA) $(ENABLE_LETTERPRESS) $(ENABLE_MAC_GESTURE_EVENTS) $(ENABLE_MAC_VIDEO_TOOLBOX) $(ENABLE_MATHML) $(ENABLE_MEDIA_CAPTURE) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_MEMORY_SAMPLER) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_STANDALONE) $(ENABLE_NETWORK_CACHE_SPECULATIVE_REVALIDATION) $(ENABLE_NOTIFICATIONS) $(ENABLE_OVERFLOW_SCROLLING_TOUCH) $(ENABLE_PAYMENT_REQUEST) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_POINTER_EVENTS) $(ENABLE_POINTER_LOCK) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_RESIZE_OBSERVER) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RESOURCE_LOAD_STATISTICS) $(ENABLE_RESOURCE_USAGE) $(ENABLE_RUBBER_BANDING) $(ENABLE_SANDBOX_EXTENSIONS) $(ENABLE_SERVER_PRECONNECT) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_SERVICE_WORKER) $(ENABLE_SHAREABLE_RESOURCE) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_STREAMS_API) $(ENABLE_SVG_FONTS) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TOUCH_EVENTS) $(ENABLE_USERSELECT_ALL) $(ENABLE_USER_MESSAGE_HANDLERS) $(ENABLE_VARIATION_FONTS) $(ENABLE_VIDEO) $(ENABLE_VIDEO_PRESENTATION_MODE) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIDEO_USES_ELEMENT_FULLSCREEN) $(ENABLE_WEBASSEMBLY) $(ENABLE_WEBASSEMBLY_STREAMING_API) $(ENABLE_WEBDRIVER_MOUSE_INTERACTIONS) $(ENABLE_WEBDRIVER_KEYBOARD_INTERACTIONS) $(ENABLE_WEBDRIVER_TOUCH_INTERACTIONS) $(ENABLE_WEBGL) $(ENABLE_WEBGL2) $(ENABLE_WEBGPU) $(ENABLE_WEB_API_STATISTICS) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_AUTHN) $(ENABLE_WEB_CRYPTO) $(ENABLE_WEB_RTC) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_XSLT);
diff --git a/Source/WebCore/Sources.txt b/Source/WebCore/Sources.txt
index 329af4b..e8fcb1e 100644
--- a/Source/WebCore/Sources.txt
+++ b/Source/WebCore/Sources.txt
@@ -204,6 +204,11 @@
 Modules/paymentrequest/PaymentRequestUpdateEvent.cpp
 Modules/paymentrequest/PaymentResponse.cpp
 
+Modules/pictureinpicture/DocumentPictureInPicture.cpp
+Modules/pictureinpicture/EnterPictureInPictureEvent.cpp
+Modules/pictureinpicture/HTMLVideoElementPictureInPicture.cpp
+Modules/pictureinpicture/PictureInPictureWindow.cpp
+
 Modules/speech/DOMWindowSpeechSynthesis.cpp
 Modules/speech/SpeechSynthesis.cpp
 Modules/speech/SpeechSynthesisEvent.cpp
@@ -2795,6 +2800,7 @@
 JSDocumentAndElementEventHandlers.cpp
 JSDocumentFragment.cpp
 JSDocumentOrShadowRoot.cpp
+JSDocumentPictureInPicture.cpp
 JSDocumentType.cpp
 JSDoubleRange.cpp
 JSDynamicsCompressorNode.cpp
@@ -2803,6 +2809,7 @@
 JSEcdsaParams.cpp
 JSElement.cpp
 JSElementCSSInlineStyle.cpp
+JSEnterPictureInPictureEvent.cpp
 JSErrorCallback.cpp
 JSErrorEvent.cpp
 JSEvent.cpp
@@ -2960,6 +2967,7 @@
 JSHTMLUListElement.cpp
 JSHTMLUnknownElement.cpp
 JSHTMLVideoElement.cpp
+JSHTMLVideoElementPictureInPicture.cpp
 JSHashChangeEvent.cpp
 JSHistory.cpp
 JSHkdfParams.cpp
@@ -3116,6 +3124,7 @@
 JSPerformanceServerTiming.cpp
 JSPerformanceTiming.cpp
 JSPeriodicWave.cpp
+JSPictureInPictureWindow.cpp
 JSPlaybackDirection.cpp
 JSPointerEvent.cpp
 JSPopStateEvent.cpp
diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
index a07ac6f..b2cab02 100644
--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj
+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
@@ -625,7 +625,12 @@
 		1CCD81502231F83E0065FC2B /* WebCoreResourceHandleAsOperationQueueDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = E152551416FD234F003D7ADB /* WebCoreResourceHandleAsOperationQueueDelegate.mm */; };
 		1CCDF5BE1990332400BCEBAD /* SVGToOTFFontConversion.h in Headers */ = {isa = PBXBuildFile; fileRef = 1CCDF5BC1990332400BCEBAD /* SVGToOTFFontConversion.h */; };
 		1CFAE3230A6D6A3F0032593D /* libobjc.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 1CFAE3220A6D6A3F0032593D /* libobjc.dylib */; };
+		1D2F8E03234474EF00993B68 /* DocumentPictureInPicture.h in Headers */ = {isa = PBXBuildFile; fileRef = 1DEF06DD233D2E1C00EE228D /* DocumentPictureInPicture.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		1D2F8E042344751600993B68 /* EnterPictureInPictureEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 1DEF06CA233C3D0B00EE228D /* EnterPictureInPictureEvent.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		1D2F8E052344751D00993B68 /* HTMLVideoElementPictureInPicture.h in Headers */ = {isa = PBXBuildFile; fileRef = 1DEF06CC233C3D2000EE228D /* HTMLVideoElementPictureInPicture.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		1D2F8E062344752300993B68 /* PictureInPictureWindow.h in Headers */ = {isa = PBXBuildFile; fileRef = 1DEF06CD233C3D2A00EE228D /* PictureInPictureWindow.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		1D9F0FC12122029B005D8FD4 /* ShareData.h in Headers */ = {isa = PBXBuildFile; fileRef = 1DC55400211BA8C8004B780E /* ShareData.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		1DBC1B562347B3D200B901AF /* PictureInPictureObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = 1DBC1B552347B3D200B901AF /* PictureInPictureObserver.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		1F36EA9C1E21BA1700621E25 /* WebBackgroundTaskController.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F36EA9A1E21BA1700621E25 /* WebBackgroundTaskController.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		1F3C3BEB135CAF3C00B8C1AC /* MediaControls.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F3C3BE9135CAF3C00B8C1AC /* MediaControls.h */; };
 		1F72BF0B187FD45C0009BCB3 /* TileControllerMemoryHandlerIOS.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F72BF09187FD4270009BCB3 /* TileControllerMemoryHandlerIOS.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -6440,9 +6445,22 @@
 		1CECB3C721F59C8700F44542 /* WHLSLNativeTypeWriter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLNativeTypeWriter.h; sourceTree = "<group>"; };
 		1CF0BFD42298706800ED2074 /* TextSizeAdjustment.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TextSizeAdjustment.cpp; sourceTree = "<group>"; };
 		1CFAE3220A6D6A3F0032593D /* libobjc.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libobjc.dylib; path = /usr/lib/libobjc.dylib; sourceTree = "<absolute>"; };
+		1DBC1B552347B3D200B901AF /* PictureInPictureObserver.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PictureInPictureObserver.h; sourceTree = "<group>"; };
 		1DC553FD211BA12A004B780E /* NavigatorShare.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = NavigatorShare.idl; sourceTree = "<group>"; };
 		1DC553FF211BA841004B780E /* ShareData.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ShareData.idl; sourceTree = "<group>"; };
 		1DC55400211BA8C8004B780E /* ShareData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShareData.h; sourceTree = "<group>"; };
+		1DEF06CA233C3D0B00EE228D /* EnterPictureInPictureEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EnterPictureInPictureEvent.h; sourceTree = "<group>"; };
+		1DEF06CB233C3D1500EE228D /* EnterPictureInPictureEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EnterPictureInPictureEvent.cpp; sourceTree = "<group>"; };
+		1DEF06CC233C3D2000EE228D /* HTMLVideoElementPictureInPicture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLVideoElementPictureInPicture.h; sourceTree = "<group>"; };
+		1DEF06CD233C3D2A00EE228D /* PictureInPictureWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PictureInPictureWindow.h; sourceTree = "<group>"; };
+		1DEF06CE233C3D3100EE228D /* PictureInPictureWindow.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PictureInPictureWindow.cpp; sourceTree = "<group>"; };
+		1DEF06CF233C3D3800EE228D /* HTMLVideoElementPictureInPicture.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = HTMLVideoElementPictureInPicture.idl; sourceTree = "<group>"; };
+		1DEF06D0233C3D4100EE228D /* EnterPictureInPictureEvent.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = EnterPictureInPictureEvent.idl; sourceTree = "<group>"; };
+		1DEF06D1233C3D4B00EE228D /* PictureInPictureWindow.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = PictureInPictureWindow.idl; sourceTree = "<group>"; };
+		1DEF06D2233C3D5600EE228D /* HTMLVideoElementPictureInPicture.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTMLVideoElementPictureInPicture.cpp; sourceTree = "<group>"; };
+		1DEF06DC233D2E1C00EE228D /* DocumentPictureInPicture.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DocumentPictureInPicture.cpp; sourceTree = "<group>"; };
+		1DEF06DD233D2E1C00EE228D /* DocumentPictureInPicture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DocumentPictureInPicture.h; sourceTree = "<group>"; };
+		1DEF06DE233D2E1C00EE228D /* DocumentPictureInPicture.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DocumentPictureInPicture.idl; sourceTree = "<group>"; };
 		1F36EA9A1E21BA1700621E25 /* WebBackgroundTaskController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebBackgroundTaskController.h; sourceTree = "<group>"; };
 		1F36EA9B1E21BA1700621E25 /* WebBackgroundTaskController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebBackgroundTaskController.mm; sourceTree = "<group>"; };
 		1F3C3BE8135CAF3C00B8C1AC /* MediaControls.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MediaControls.cpp; sourceTree = "<group>"; };
@@ -17353,6 +17371,25 @@
 			path = Metal;
 			sourceTree = "<group>";
 		};
+		1DEF06A2233C32DB00EE228D /* pictureinpicture */ = {
+			isa = PBXGroup;
+			children = (
+				1DEF06DC233D2E1C00EE228D /* DocumentPictureInPicture.cpp */,
+				1DEF06DD233D2E1C00EE228D /* DocumentPictureInPicture.h */,
+				1DEF06DE233D2E1C00EE228D /* DocumentPictureInPicture.idl */,
+				1DEF06CB233C3D1500EE228D /* EnterPictureInPictureEvent.cpp */,
+				1DEF06CA233C3D0B00EE228D /* EnterPictureInPictureEvent.h */,
+				1DEF06D0233C3D4100EE228D /* EnterPictureInPictureEvent.idl */,
+				1DEF06D2233C3D5600EE228D /* HTMLVideoElementPictureInPicture.cpp */,
+				1DEF06CC233C3D2000EE228D /* HTMLVideoElementPictureInPicture.h */,
+				1DEF06CF233C3D3800EE228D /* HTMLVideoElementPictureInPicture.idl */,
+				1DEF06CE233C3D3100EE228D /* PictureInPictureWindow.cpp */,
+				1DEF06CD233C3D2A00EE228D /* PictureInPictureWindow.h */,
+				1DEF06D1233C3D4B00EE228D /* PictureInPictureWindow.idl */,
+			);
+			path = pictureinpicture;
+			sourceTree = "<group>";
+		};
 		26B9998D1803ADFA00D01121 /* cssjit */ = {
 			isa = PBXGroup;
 			children = (
@@ -22001,6 +22038,7 @@
 				71D6AA391DA4EAF700B23969 /* modern-media-controls */,
 				333F703D0FB49C16008E12A6 /* notifications */,
 				A1F76B0E1F44C0CF0014C318 /* paymentrequest */,
+				1DEF06A2233C32DB00EE228D /* pictureinpicture */,
 				072AE1DE183C0513000A5988 /* plugins */,
 				89F60B08157F68350075E157 /* quota */,
 				AA2A5AB716A485A400975A25 /* speech */,
@@ -25608,6 +25646,7 @@
 				C5F765B414E1D414006C899B /* PasteboardStrategy.h */,
 				1AF5E4D21E56735A004A1F01 /* PasteboardWriterData.cpp */,
 				1AF5E4D31E56735A004A1F01 /* PasteboardWriterData.h */,
+				1DBC1B552347B3D200B901AF /* PictureInPictureObserver.h */,
 				A14978701ABAF3A500CEF7E4 /* PlatformContentFilter.h */,
 				BC5C76291497FE1400BC4775 /* PlatformEvent.h */,
 				A723F77A1484CA4C008C6DBE /* PlatformExportMacros.h */,
@@ -29250,6 +29289,7 @@
 				ED2BA83C09A24B91006C0AC4 /* DocumentMarker.h in Headers */,
 				CE057FA61220731100A476D5 /* DocumentMarkerController.h in Headers */,
 				BCCFBAE80B5152ED0001F1D7 /* DocumentParser.h in Headers */,
+				1D2F8E03234474EF00993B68 /* DocumentPictureInPicture.h in Headers */,
 				4A4F48AA16B0DFC000EDBB29 /* DocumentRuleSets.h in Headers */,
 				AD6E71AD1668899D00320C13 /* DocumentSharedObjectPool.h in Headers */,
 				6BDB5DC2227BD3B800919770 /* DocumentStorageAccess.h in Headers */,
@@ -29361,6 +29401,7 @@
 				B25599A50D00D8BA00BB825C /* EmptyClients.h in Headers */,
 				414DEDE71F9FE91E0047C40D /* EmptyFrameLoaderClient.h in Headers */,
 				515BE1901D54F5FB00DD7C68 /* EmptyGamepadProvider.h in Headers */,
+				1D2F8E042344751600993B68 /* EnterPictureInPictureEvent.h in Headers */,
 				FD31609312B026F700C1A359 /* EqualPowerPanner.h in Headers */,
 				8371AC3B1F509BE400FBF284 /* ErrorCallback.h in Headers */,
 				2ECF7AE210162B5800427DE7 /* ErrorEvent.h in Headers */,
@@ -29748,6 +29789,7 @@
 				A8EA79F20A1916DF00A8EF5F /* HTMLUListElement.h in Headers */,
 				AD49914318F0815100BF0092 /* HTMLUnknownElement.h in Headers */,
 				E44613AB0CD6331000FADA75 /* HTMLVideoElement.h in Headers */,
+				1D2F8E052344751D00993B68 /* HTMLVideoElementPictureInPicture.h in Headers */,
 				839AAFED1A0C0C8D00605F99 /* HTMLWBRElement.h in Headers */,
 				5CA1DEC61F71F1C700E71BD3 /* HTTPHeaderField.h in Headers */,
 				514C76710CE923A1007EF3CD /* HTTPHeaderMap.h in Headers */,
@@ -31274,6 +31316,8 @@
 				A554B5F31E38393A001D4E03 /* PerformanceUserTiming.h in Headers */,
 				FD581FB51520F93B003A7A75 /* PeriodicWave.h in Headers */,
 				49D5DC2E0F423A73008F20FD /* PerspectiveTransformOperation.h in Headers */,
+				1DBC1B562347B3D200B901AF /* PictureInPictureObserver.h in Headers */,
+				1D2F8E062344752300993B68 /* PictureInPictureWindow.h in Headers */,
 				D0FF2A5E11F8C45A007E74E0 /* PingLoader.h in Headers */,
 				CD7D33441C7A123F00041293 /* PixelBufferConformerCV.h in Headers */,
 				CDEFA2281E7669E8000AE99C /* PlatformAudioData.h in Headers */,
diff --git a/Source/WebCore/bindings/js/WebCoreBuiltinNames.h b/Source/WebCore/bindings/js/WebCoreBuiltinNames.h
index cce4fae..7712d21 100644
--- a/Source/WebCore/bindings/js/WebCoreBuiltinNames.h
+++ b/Source/WebCore/bindings/js/WebCoreBuiltinNames.h
@@ -72,6 +72,7 @@
     macro(DataTransferItem) \
     macro(DataTransferItemList) \
     macro(DocumentTimeline) \
+    macro(EnterPictureInPictureEvent) \
     macro(ExtendableEvent) \
     macro(ExtendableMessageEvent) \
     macro(FetchEvent) \
@@ -164,6 +165,7 @@
     macro(PaymentRequest) \
     macro(PaymentRequestUpdateEvent) \
     macro(PaymentResponse) \
+    macro(PictureInPictureWindow) \
     macro(SQLError) \
     macro(SQLResultSet) \
     macro(SQLResultSetRowList) \
diff --git a/Source/WebCore/dom/Document.cpp b/Source/WebCore/dom/Document.cpp
index 190cc70..586324b 100644
--- a/Source/WebCore/dom/Document.cpp
+++ b/Source/WebCore/dom/Document.cpp
@@ -325,6 +325,10 @@
 #include "PointerCaptureController.h"
 #endif
 
+#if ENABLE(PICTURE_IN_PICTURE_API)
+#include "HTMLVideoElement.h"
+#endif
+
 namespace WebCore {
 
 WTF_MAKE_ISO_ALLOCATED_IMPL(Document);
@@ -8296,5 +8300,16 @@
 }
 #endif
 
+#if ENABLE(PICTURE_IN_PICTURE_API)
+HTMLVideoElement* Document::pictureInPictureElement() const
+{
+    return m_pictureInPictureElement.get();
+};
+
+void Document::setPictureInPictureElement(HTMLVideoElement* element)
+{
+    m_pictureInPictureElement = makeWeakPtr(element);
+}
+#endif
 
 } // namespace WebCore
diff --git a/Source/WebCore/dom/Document.h b/Source/WebCore/dom/Document.h
index 4684dda..75315fe 100644
--- a/Source/WebCore/dom/Document.h
+++ b/Source/WebCore/dom/Document.h
@@ -140,6 +140,7 @@
 class HTMLImageElement;
 class HTMLMapElement;
 class HTMLMediaElement;
+class HTMLVideoElement;
 class HTMLPictureElement;
 class HTMLScriptElement;
 class HitTestLocation;
@@ -1545,6 +1546,11 @@
     WEBCORE_EXPORT void dispatchSystemPreviewActionEvent(const String& message);
 #endif
 
+#if ENABLE(PICTURE_IN_PICTURE_API)
+    HTMLVideoElement* pictureInPictureElement() const;
+    void setPictureInPictureElement(HTMLVideoElement*);
+#endif
+
 protected:
     enum ConstructionFlags { Synthesized = 1, NonRenderedPlaceholder = 1 << 1 };
     Document(Frame*, const URL&, unsigned = DefaultDocumentClass, unsigned constructionFlags = 0);
@@ -2068,6 +2074,10 @@
     std::unique_ptr<DOMTimerHoldingTank> m_domTimerHoldingTank;
 #endif
 
+#if ENABLE(PICTURE_IN_PICTURE_API)
+    WeakPtr<HTMLVideoElement> m_pictureInPictureElement;
+#endif
+
     HashMap<Element*, ElementIdentifier> m_identifiedElementsMap;
 };
 
diff --git a/Source/WebCore/dom/DocumentOrShadowRoot.idl b/Source/WebCore/dom/DocumentOrShadowRoot.idl
index 6387665..b9b23f1 100644
--- a/Source/WebCore/dom/DocumentOrShadowRoot.idl
+++ b/Source/WebCore/dom/DocumentOrShadowRoot.idl
@@ -40,4 +40,7 @@
 
     // Extensions from Pointer Lock API (https://w3c.github.io/pointerlock/#extensions-to-the-documentorshadowroot-mixin).
     [Conditional=POINTER_LOCK] readonly attribute Element? pointerLockElement;
+
+    // Extensions from Picture-in-Picture API (https://wicg.github.io/picture-in-picture/#documentorshadowroot-extension)
+    [Conditional=PICTURE_IN_PICTURE_API, EnabledBySetting=PictureInPictureAPI] readonly attribute Element? pictureInPictureElement;
 };
diff --git a/Source/WebCore/dom/EventNames.h b/Source/WebCore/dom/EventNames.h
index 7188ae3..73c4f1e 100644
--- a/Source/WebCore/dom/EventNames.h
+++ b/Source/WebCore/dom/EventNames.h
@@ -122,6 +122,7 @@
     macro(endEvent) \
     macro(ended) \
     macro(enter) \
+    macro(enterpictureinpicture) \
     macro(error) \
     macro(exit) \
     macro(fetch) \
@@ -153,6 +154,7 @@
     macro(keystatuseschange) \
     macro(keyup) \
     macro(languagechange) \
+    macro(leavepictureinpicture) \
     macro(levelchange) \
     macro(load) \
     macro(loadeddata) \
diff --git a/Source/WebCore/dom/EventNames.in b/Source/WebCore/dom/EventNames.in
index 752ffd3..969fbff 100644
--- a/Source/WebCore/dom/EventNames.in
+++ b/Source/WebCore/dom/EventNames.in
@@ -84,3 +84,4 @@
 VRDisplayEvent
 PointerEvent conditional=POINTER_EVENTS
 GPUUncapturedErrorEvent conditional=WEBGPU
+EnterPictureInPictureEvent conditional=PICTURE_IN_PICTURE_API
diff --git a/Source/WebCore/dom/EventTargetFactory.in b/Source/WebCore/dom/EventTargetFactory.in
index 28270f2..50d1cb5 100644
--- a/Source/WebCore/dom/EventTargetFactory.in
+++ b/Source/WebCore/dom/EventTargetFactory.in
@@ -33,6 +33,7 @@
 PaymentRequest conditional=PAYMENT_REQUEST
 PaymentResponse conditional=PAYMENT_REQUEST
 Performance
+PictureInPictureWindow conditional=PICTURE_IN_PICTURE_API
 RTCDataChannel conditional=WEB_RTC
 RTCDTMFSender conditional=WEB_RTC
 RTCPeerConnection conditional=WEB_RTC
diff --git a/Source/WebCore/dom/ShadowRoot.cpp b/Source/WebCore/dom/ShadowRoot.cpp
index 03398b2..6f4f4c4 100644
--- a/Source/WebCore/dom/ShadowRoot.cpp
+++ b/Source/WebCore/dom/ShadowRoot.cpp
@@ -32,6 +32,9 @@
 #include "ElementTraversal.h"
 #include "HTMLParserIdioms.h"
 #include "HTMLSlotElement.h"
+#if ENABLE(PICTURE_IN_PICTURE_API)
+#include "NotImplemented.h"
+#endif
 #include "RenderElement.h"
 #include "RuntimeEnabledFeatures.h"
 #include "SlotAssignment.h"
@@ -356,4 +359,12 @@
     return result;
 }
 
+#if ENABLE(PICTURE_IN_PICTURE_API)
+HTMLVideoElement* ShadowRoot::pictureInPictureElement() const
+{
+    notImplemented();
+    return nullptr;
+}
+#endif
+
 }
diff --git a/Source/WebCore/dom/ShadowRoot.h b/Source/WebCore/dom/ShadowRoot.h
index 6615e05..dbe16a7 100644
--- a/Source/WebCore/dom/ShadowRoot.h
+++ b/Source/WebCore/dom/ShadowRoot.h
@@ -29,6 +29,9 @@
 #include "Document.h"
 #include "DocumentFragment.h"
 #include "Element.h"
+#if ENABLE(PICTURE_IN_PICTURE_API)
+#include "HTMLVideoElement.h"
+#endif
 #include "ShadowRootMode.h"
 #include <wtf/HashMap.h>
 
@@ -104,6 +107,10 @@
     const PartMappings& partMappings() const;
     void invalidatePartMappings();
 
+#if ENABLE(PICTURE_IN_PICTURE_API)
+    HTMLVideoElement* pictureInPictureElement() const;
+#endif
+
 private:
     ShadowRoot(Document&, ShadowRootMode, DelegatesFocus);
     ShadowRoot(Document&, std::unique_ptr<SlotAssignment>&&);
diff --git a/Source/WebCore/html/HTMLVideoElement.cpp b/Source/WebCore/html/HTMLVideoElement.cpp
index 67ff212..d9c336c 100644
--- a/Source/WebCore/html/HTMLVideoElement.cpp
+++ b/Source/WebCore/html/HTMLVideoElement.cpp
@@ -47,6 +47,7 @@
 #include <wtf/text/TextStream.h>
 
 #if ENABLE(VIDEO_PRESENTATION_MODE)
+#include "PictureInPictureObserver.h"
 #include "VideoFullscreenModel.h"
 #endif
 
@@ -485,6 +486,18 @@
     if (mode != fullscreenMode()) {
         ALWAYS_LOG(LOGIDENTIFIER, "changed from ", fullscreenMode(), ", to ", mode);
         scheduleEvent(eventNames().webkitpresentationmodechangedEvent);
+
+#if ENABLE(PICTURE_IN_PICTURE_API)
+        if (m_pictureInPictureObserver) {
+            HTMLVideoElement::VideoPresentationMode targetVideoPresentationMode = toPresentationMode(mode);
+            HTMLVideoElement::VideoPresentationMode sourceVideoPresentationMode = toPresentationMode(fullscreenMode());
+
+            if (targetVideoPresentationMode == HTMLVideoElement::VideoPresentationMode::PictureInPicture && sourceVideoPresentationMode != HTMLVideoElement::VideoPresentationMode::PictureInPicture)
+                m_pictureInPictureObserver->didEnterPictureInPicture();
+            else if (targetVideoPresentationMode != HTMLVideoElement::VideoPresentationMode::PictureInPicture && sourceVideoPresentationMode == HTMLVideoElement::VideoPresentationMode::PictureInPicture)
+                m_pictureInPictureObserver->didExitPictureInPicture();
+        }
+#endif
     }
 
     if (player())
@@ -493,6 +506,13 @@
     HTMLMediaElement::fullscreenModeChanged(mode);
 }
 
+#if ENABLE(PICTURE_IN_PICTURE_API)
+void HTMLVideoElement::setPictureInPictureObserver(PictureInPictureObserver* observer)
+{
+    m_pictureInPictureObserver = observer;
+}
+#endif
+
 #endif
 
 #if PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE)
diff --git a/Source/WebCore/html/HTMLVideoElement.h b/Source/WebCore/html/HTMLVideoElement.h
index 1e95258..83e0954 100644
--- a/Source/WebCore/html/HTMLVideoElement.h
+++ b/Source/WebCore/html/HTMLVideoElement.h
@@ -28,14 +28,16 @@
 #if ENABLE(VIDEO)
 
 #include "HTMLMediaElement.h"
+#include "Supplementable.h"
 #include <memory>
 
 namespace WebCore {
 
 class HTMLImageLoader;
 class RenderVideo;
+class PictureInPictureObserver;
 
-class HTMLVideoElement final : public HTMLMediaElement {
+class HTMLVideoElement final : public HTMLMediaElement, public Supplementable<HTMLVideoElement> {
     WTF_MAKE_ISO_ALLOCATED(HTMLVideoElement);
 public:
     WEBCORE_EXPORT static Ref<HTMLVideoElement> create(Document&);
@@ -86,6 +88,10 @@
     VideoPresentationMode webkitPresentationMode() const;
     void setFullscreenMode(VideoFullscreenMode);
     void fullscreenModeChanged(VideoFullscreenMode) final;
+
+#if ENABLE(PICTURE_IN_PICTURE_API)
+    void setPictureInPictureObserver(PictureInPictureObserver*);
+#endif
 #endif
 
 #if PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE)
@@ -123,6 +129,10 @@
 
     unsigned m_lastReportedVideoWidth { 0 };
     unsigned m_lastReportedVideoHeight { 0 };
+
+#if ENABLE(PICTURE_IN_PICTURE_API)
+    PictureInPictureObserver* m_pictureInPictureObserver { nullptr };
+#endif
 };
 
 } // namespace WebCore
diff --git a/Source/WebCore/page/Settings.yaml b/Source/WebCore/page/Settings.yaml
index 72fe8c0..0ae7742 100644
--- a/Source/WebCore/page/Settings.yaml
+++ b/Source/WebCore/page/Settings.yaml
@@ -293,6 +293,8 @@
   initial: defaultInlineMediaPlaybackRequiresPlaysInlineAttribute
 allowsPictureInPictureMediaPlayback:
   initial: defaultAllowsPictureInPictureMediaPlayback
+pictureInPictureAPIEnabled:
+  initial: false
 mediaControlsScaleWithPageZoom:
   initial: defaultMediaControlsScaleWithPageZoom
 invisibleAutoplayNotPermitted:
diff --git a/Source/WebCore/platform/PictureInPictureObserver.h b/Source/WebCore/platform/PictureInPictureObserver.h
new file mode 100644
index 0000000..ae40670
--- /dev/null
+++ b/Source/WebCore/platform/PictureInPictureObserver.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(PICTURE_IN_PICTURE_API)
+
+namespace WebCore {
+
+class PictureInPictureObserver : public CanMakeWeakPtr<PictureInPictureObserver> {
+public:
+    virtual ~PictureInPictureObserver() { };
+    virtual void didEnterPictureInPicture() = 0;
+    virtual void didExitPictureInPicture() = 0;
+};
+
+}
+
+#endif
diff --git a/Source/WebCore/testing/InternalSettings.h b/Source/WebCore/testing/InternalSettings.h
index 73e1018..8a68292 100644
--- a/Source/WebCore/testing/InternalSettings.h
+++ b/Source/WebCore/testing/InternalSettings.h
@@ -128,6 +128,7 @@
     static void setWebGL2Enabled(bool);
     static void setWebGPUEnabled(bool);
     static void setWebVREnabled(bool);
+    static void setPictureInPictureAPIEnabled(bool);
     static void setScreenCaptureEnabled(bool);
 
     static bool webAnimationsCSSIntegrationEnabled();
diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog
index 5ebd03e..327753a 100644
--- a/Source/WebKit/ChangeLog
+++ b/Source/WebKit/ChangeLog
@@ -1,3 +1,15 @@
+2019-10-15  Peng Liu  <peng.liu6@apple.com>
+
+        [Picture-in-Picture Web API] Implement HTMLVideoElement.requestPictureInPicture() / Document.exitPictureInPicture()
+        https://bugs.webkit.org/show_bug.cgi?id=201024
+
+        Reviewed by Eric Carlson.
+
+        Add configurations for Picture-in-Picture API and add a preference option for it.
+
+        * Configurations/FeatureDefines.xcconfig:
+        * Shared/WebPreferences.yaml:
+
 2019-10-15  youenn fablet  <youenn@apple.com>
 
         Move headers to keep from a HTTPHeaderNameSet to an OptionSet
diff --git a/Source/WebKit/Configurations/FeatureDefines.xcconfig b/Source/WebKit/Configurations/FeatureDefines.xcconfig
index d808ee0..140ffe5 100644
--- a/Source/WebKit/Configurations/FeatureDefines.xcconfig
+++ b/Source/WebKit/Configurations/FeatureDefines.xcconfig
@@ -313,6 +313,9 @@
 
 ENABLE_PAYMENT_REQUEST = ENABLE_PAYMENT_REQUEST;
 
+ENABLE_PICTURE_IN_PICTURE_API = $(ENABLE_PICTURE_IN_PICTURE_API_$(WK_PLATFORM_NAME));
+ENABLE_PICTURE_IN_PICTURE_API_macosx = ENABLE_PICTURE_IN_PICTURE_API;
+
 ENABLE_PDFKIT_PLUGIN = $(ENABLE_PDFKIT_PLUGIN_$(WK_PLATFORM_NAME));
 ENABLE_PDFKIT_PLUGIN_macosx = ENABLE_PDFKIT_PLUGIN;
 
@@ -443,4 +446,4 @@
 
 ENABLE_XSLT = ENABLE_XSLT;
 
-FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCESSIBILITY_ISOLATED_TREE) $(ENABLE_APPLE_PAY) $(ENABLE_APPLE_PAY_SESSION_V3) $(ENABLE_APPLE_PAY_SESSION_V4) $(ENABLE_APPLICATION_MANIFEST) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_AVF_CAPTIONS) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSS3_TEXT) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_CONIC_GRADIENTS) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_PAINTING_API) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_CSS_TYPED_OM) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_C_LOOP) $(ENABLE_DARK_MODE_CSS) $(ENABLE_DATACUE_VALUE) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DATA_INTERACTION) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DRAG_SUPPORT) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_EXPERIMENTAL_FEATURES) $(ENABLE_FAST_JIT_PERMISSIONS) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FTL_JIT) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_INSPECTOR_ALTERNATE_DISPATCHERS) $(ENABLE_INTERSECTION_OBSERVER) $(ENABLE_INTL) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_JIT) $(ENABLE_KEYBOARD_CODE_ATTRIBUTE) $(ENABLE_KEYBOARD_KEY_ATTRIBUTE) $(ENABLE_LAYOUT_FORMATTING_CONTEXT) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_CUSTOM_PROTOCOL_MANAGER) $(ENABLE_LEGACY_ENCRYPTED_MEDIA) $(ENABLE_LETTERPRESS) $(ENABLE_MAC_GESTURE_EVENTS) $(ENABLE_MAC_VIDEO_TOOLBOX) $(ENABLE_MATHML) $(ENABLE_MEDIA_CAPTURE) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_MEMORY_SAMPLER) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_STANDALONE) $(ENABLE_NETWORK_CACHE_SPECULATIVE_REVALIDATION) $(ENABLE_NOTIFICATIONS) $(ENABLE_OVERFLOW_SCROLLING_TOUCH) $(ENABLE_PAYMENT_REQUEST) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_POINTER_EVENTS) $(ENABLE_POINTER_LOCK) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_RESIZE_OBSERVER) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RESOURCE_LOAD_STATISTICS) $(ENABLE_RESOURCE_USAGE) $(ENABLE_RUBBER_BANDING) $(ENABLE_SANDBOX_EXTENSIONS) $(ENABLE_SERVER_PRECONNECT) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_SERVICE_WORKER) $(ENABLE_SHAREABLE_RESOURCE) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_STREAMS_API) $(ENABLE_SVG_FONTS) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TOUCH_EVENTS) $(ENABLE_USERSELECT_ALL) $(ENABLE_USER_MESSAGE_HANDLERS) $(ENABLE_VARIATION_FONTS) $(ENABLE_VIDEO) $(ENABLE_VIDEO_PRESENTATION_MODE) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIDEO_USES_ELEMENT_FULLSCREEN) $(ENABLE_WEBASSEMBLY) $(ENABLE_WEBASSEMBLY_STREAMING_API) $(ENABLE_WEBDRIVER_MOUSE_INTERACTIONS) $(ENABLE_WEBDRIVER_KEYBOARD_INTERACTIONS) $(ENABLE_WEBDRIVER_TOUCH_INTERACTIONS) $(ENABLE_WEBGL) $(ENABLE_WEBGL2) $(ENABLE_WEBGPU) $(ENABLE_WEB_API_STATISTICS) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_AUTHN) $(ENABLE_WEB_CRYPTO) $(ENABLE_WEB_RTC) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_XSLT);
+FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCESSIBILITY_ISOLATED_TREE) $(ENABLE_APPLE_PAY) $(ENABLE_APPLE_PAY_SESSION_V3) $(ENABLE_APPLE_PAY_SESSION_V4) $(ENABLE_APPLICATION_MANIFEST) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_AVF_CAPTIONS) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSS3_TEXT) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_CONIC_GRADIENTS) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_PAINTING_API) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_CSS_TYPED_OM) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_C_LOOP) $(ENABLE_DARK_MODE_CSS) $(ENABLE_DATACUE_VALUE) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DATA_INTERACTION) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DRAG_SUPPORT) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_EXPERIMENTAL_FEATURES) $(ENABLE_FAST_JIT_PERMISSIONS) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FTL_JIT) $(ENABLE_FULLSCREEN_API) $(ENABLE_PICTURE_IN_PICTURE_API) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_INSPECTOR_ALTERNATE_DISPATCHERS) $(ENABLE_INTERSECTION_OBSERVER) $(ENABLE_INTL) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_JIT) $(ENABLE_KEYBOARD_CODE_ATTRIBUTE) $(ENABLE_KEYBOARD_KEY_ATTRIBUTE) $(ENABLE_LAYOUT_FORMATTING_CONTEXT) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_CUSTOM_PROTOCOL_MANAGER) $(ENABLE_LEGACY_ENCRYPTED_MEDIA) $(ENABLE_LETTERPRESS) $(ENABLE_MAC_GESTURE_EVENTS) $(ENABLE_MAC_VIDEO_TOOLBOX) $(ENABLE_MATHML) $(ENABLE_MEDIA_CAPTURE) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_MEMORY_SAMPLER) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_STANDALONE) $(ENABLE_NETWORK_CACHE_SPECULATIVE_REVALIDATION) $(ENABLE_NOTIFICATIONS) $(ENABLE_OVERFLOW_SCROLLING_TOUCH) $(ENABLE_PAYMENT_REQUEST) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_POINTER_EVENTS) $(ENABLE_POINTER_LOCK) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_RESIZE_OBSERVER) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RESOURCE_LOAD_STATISTICS) $(ENABLE_RESOURCE_USAGE) $(ENABLE_RUBBER_BANDING) $(ENABLE_SANDBOX_EXTENSIONS) $(ENABLE_SERVER_PRECONNECT) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_SERVICE_WORKER) $(ENABLE_SHAREABLE_RESOURCE) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_STREAMS_API) $(ENABLE_SVG_FONTS) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TOUCH_EVENTS) $(ENABLE_USERSELECT_ALL) $(ENABLE_USER_MESSAGE_HANDLERS) $(ENABLE_VARIATION_FONTS) $(ENABLE_VIDEO) $(ENABLE_VIDEO_PRESENTATION_MODE) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIDEO_USES_ELEMENT_FULLSCREEN) $(ENABLE_WEBASSEMBLY) $(ENABLE_WEBASSEMBLY_STREAMING_API) $(ENABLE_WEBDRIVER_MOUSE_INTERACTIONS) $(ENABLE_WEBDRIVER_KEYBOARD_INTERACTIONS) $(ENABLE_WEBDRIVER_TOUCH_INTERACTIONS) $(ENABLE_WEBGL) $(ENABLE_WEBGL2) $(ENABLE_WEBGPU) $(ENABLE_WEB_API_STATISTICS) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_AUTHN) $(ENABLE_WEB_CRYPTO) $(ENABLE_WEB_RTC) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_XSLT);
diff --git a/Source/WebKit/Shared/WebPreferences.yaml b/Source/WebKit/Shared/WebPreferences.yaml
index 7418948..974618f 100644
--- a/Source/WebKit/Shared/WebPreferences.yaml
+++ b/Source/WebKit/Shared/WebPreferences.yaml
@@ -1780,6 +1780,14 @@
     humanReadableDescription: "Enable the proposed IsLoggedIn web API"
     category: experimental
 
+PictureInPictureAPIEnabled:
+  type: bool
+  defaultValue: false
+  humanReadableName: "Picture-in-Picture API"
+  humanReadableDescription: "Enable Picture-in-Picture API support"
+  category: experimental
+  condition: ENABLE(PICTURE_IN_PICTURE_API)
+
 # Deprecated
 
 ICECandidateFilteringEnabled:
diff --git a/Source/WebKitLegacy/mac/ChangeLog b/Source/WebKitLegacy/mac/ChangeLog
index c581876..898a14f 100644
--- a/Source/WebKitLegacy/mac/ChangeLog
+++ b/Source/WebKitLegacy/mac/ChangeLog
@@ -1,3 +1,22 @@
+2019-10-15  Peng Liu  <peng.liu6@apple.com>
+
+        [Picture-in-Picture Web API] Implement HTMLVideoElement.requestPictureInPicture() / Document.exitPictureInPicture()
+        https://bugs.webkit.org/show_bug.cgi?id=201024
+
+        Reviewed by Eric Carlson.
+
+        Add configurations for Picture-in-Picture API and also a preference option for it.
+
+        * Configurations/FeatureDefines.xcconfig:
+        * WebView/WebPreferenceKeysPrivate.h:
+        * WebView/WebPreferences.mm:
+        (+[WebPreferences initialize]):
+        (-[WebPreferences pictureInPictureAPIEnabled]):
+        (-[WebPreferences setPictureInPictureAPIEnabled:]):
+        * WebView/WebPreferencesPrivate.h:
+        * WebView/WebView.mm:
+        (-[WebView _preferencesChanged:]):
+
 2019-10-14  Chris Dumez  <cdumez@apple.com>
 
         [WK2] Have WebBackForwardCache class coordinate page caching in all WebProcesses
diff --git a/Source/WebKitLegacy/mac/Configurations/FeatureDefines.xcconfig b/Source/WebKitLegacy/mac/Configurations/FeatureDefines.xcconfig
index d808ee0..140ffe5 100644
--- a/Source/WebKitLegacy/mac/Configurations/FeatureDefines.xcconfig
+++ b/Source/WebKitLegacy/mac/Configurations/FeatureDefines.xcconfig
@@ -313,6 +313,9 @@
 
 ENABLE_PAYMENT_REQUEST = ENABLE_PAYMENT_REQUEST;
 
+ENABLE_PICTURE_IN_PICTURE_API = $(ENABLE_PICTURE_IN_PICTURE_API_$(WK_PLATFORM_NAME));
+ENABLE_PICTURE_IN_PICTURE_API_macosx = ENABLE_PICTURE_IN_PICTURE_API;
+
 ENABLE_PDFKIT_PLUGIN = $(ENABLE_PDFKIT_PLUGIN_$(WK_PLATFORM_NAME));
 ENABLE_PDFKIT_PLUGIN_macosx = ENABLE_PDFKIT_PLUGIN;
 
@@ -443,4 +446,4 @@
 
 ENABLE_XSLT = ENABLE_XSLT;
 
-FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCESSIBILITY_ISOLATED_TREE) $(ENABLE_APPLE_PAY) $(ENABLE_APPLE_PAY_SESSION_V3) $(ENABLE_APPLE_PAY_SESSION_V4) $(ENABLE_APPLICATION_MANIFEST) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_AVF_CAPTIONS) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSS3_TEXT) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_CONIC_GRADIENTS) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_PAINTING_API) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_CSS_TYPED_OM) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_C_LOOP) $(ENABLE_DARK_MODE_CSS) $(ENABLE_DATACUE_VALUE) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DATA_INTERACTION) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DRAG_SUPPORT) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_EXPERIMENTAL_FEATURES) $(ENABLE_FAST_JIT_PERMISSIONS) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FTL_JIT) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_INSPECTOR_ALTERNATE_DISPATCHERS) $(ENABLE_INTERSECTION_OBSERVER) $(ENABLE_INTL) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_JIT) $(ENABLE_KEYBOARD_CODE_ATTRIBUTE) $(ENABLE_KEYBOARD_KEY_ATTRIBUTE) $(ENABLE_LAYOUT_FORMATTING_CONTEXT) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_CUSTOM_PROTOCOL_MANAGER) $(ENABLE_LEGACY_ENCRYPTED_MEDIA) $(ENABLE_LETTERPRESS) $(ENABLE_MAC_GESTURE_EVENTS) $(ENABLE_MAC_VIDEO_TOOLBOX) $(ENABLE_MATHML) $(ENABLE_MEDIA_CAPTURE) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_MEMORY_SAMPLER) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_STANDALONE) $(ENABLE_NETWORK_CACHE_SPECULATIVE_REVALIDATION) $(ENABLE_NOTIFICATIONS) $(ENABLE_OVERFLOW_SCROLLING_TOUCH) $(ENABLE_PAYMENT_REQUEST) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_POINTER_EVENTS) $(ENABLE_POINTER_LOCK) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_RESIZE_OBSERVER) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RESOURCE_LOAD_STATISTICS) $(ENABLE_RESOURCE_USAGE) $(ENABLE_RUBBER_BANDING) $(ENABLE_SANDBOX_EXTENSIONS) $(ENABLE_SERVER_PRECONNECT) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_SERVICE_WORKER) $(ENABLE_SHAREABLE_RESOURCE) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_STREAMS_API) $(ENABLE_SVG_FONTS) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TOUCH_EVENTS) $(ENABLE_USERSELECT_ALL) $(ENABLE_USER_MESSAGE_HANDLERS) $(ENABLE_VARIATION_FONTS) $(ENABLE_VIDEO) $(ENABLE_VIDEO_PRESENTATION_MODE) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIDEO_USES_ELEMENT_FULLSCREEN) $(ENABLE_WEBASSEMBLY) $(ENABLE_WEBASSEMBLY_STREAMING_API) $(ENABLE_WEBDRIVER_MOUSE_INTERACTIONS) $(ENABLE_WEBDRIVER_KEYBOARD_INTERACTIONS) $(ENABLE_WEBDRIVER_TOUCH_INTERACTIONS) $(ENABLE_WEBGL) $(ENABLE_WEBGL2) $(ENABLE_WEBGPU) $(ENABLE_WEB_API_STATISTICS) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_AUTHN) $(ENABLE_WEB_CRYPTO) $(ENABLE_WEB_RTC) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_XSLT);
+FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCESSIBILITY_ISOLATED_TREE) $(ENABLE_APPLE_PAY) $(ENABLE_APPLE_PAY_SESSION_V3) $(ENABLE_APPLE_PAY_SESSION_V4) $(ENABLE_APPLICATION_MANIFEST) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_AVF_CAPTIONS) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSS3_TEXT) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_CONIC_GRADIENTS) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_PAINTING_API) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_CSS_TYPED_OM) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_C_LOOP) $(ENABLE_DARK_MODE_CSS) $(ENABLE_DATACUE_VALUE) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DATA_INTERACTION) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DRAG_SUPPORT) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_EXPERIMENTAL_FEATURES) $(ENABLE_FAST_JIT_PERMISSIONS) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FTL_JIT) $(ENABLE_FULLSCREEN_API) $(ENABLE_PICTURE_IN_PICTURE_API) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_INSPECTOR_ALTERNATE_DISPATCHERS) $(ENABLE_INTERSECTION_OBSERVER) $(ENABLE_INTL) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_JIT) $(ENABLE_KEYBOARD_CODE_ATTRIBUTE) $(ENABLE_KEYBOARD_KEY_ATTRIBUTE) $(ENABLE_LAYOUT_FORMATTING_CONTEXT) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_CUSTOM_PROTOCOL_MANAGER) $(ENABLE_LEGACY_ENCRYPTED_MEDIA) $(ENABLE_LETTERPRESS) $(ENABLE_MAC_GESTURE_EVENTS) $(ENABLE_MAC_VIDEO_TOOLBOX) $(ENABLE_MATHML) $(ENABLE_MEDIA_CAPTURE) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_MEMORY_SAMPLER) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_STANDALONE) $(ENABLE_NETWORK_CACHE_SPECULATIVE_REVALIDATION) $(ENABLE_NOTIFICATIONS) $(ENABLE_OVERFLOW_SCROLLING_TOUCH) $(ENABLE_PAYMENT_REQUEST) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_POINTER_EVENTS) $(ENABLE_POINTER_LOCK) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_RESIZE_OBSERVER) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RESOURCE_LOAD_STATISTICS) $(ENABLE_RESOURCE_USAGE) $(ENABLE_RUBBER_BANDING) $(ENABLE_SANDBOX_EXTENSIONS) $(ENABLE_SERVER_PRECONNECT) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_SERVICE_WORKER) $(ENABLE_SHAREABLE_RESOURCE) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_STREAMS_API) $(ENABLE_SVG_FONTS) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TOUCH_EVENTS) $(ENABLE_USERSELECT_ALL) $(ENABLE_USER_MESSAGE_HANDLERS) $(ENABLE_VARIATION_FONTS) $(ENABLE_VIDEO) $(ENABLE_VIDEO_PRESENTATION_MODE) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIDEO_USES_ELEMENT_FULLSCREEN) $(ENABLE_WEBASSEMBLY) $(ENABLE_WEBASSEMBLY_STREAMING_API) $(ENABLE_WEBDRIVER_MOUSE_INTERACTIONS) $(ENABLE_WEBDRIVER_KEYBOARD_INTERACTIONS) $(ENABLE_WEBDRIVER_TOUCH_INTERACTIONS) $(ENABLE_WEBGL) $(ENABLE_WEBGL2) $(ENABLE_WEBGPU) $(ENABLE_WEB_API_STATISTICS) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_AUTHN) $(ENABLE_WEB_CRYPTO) $(ENABLE_WEB_RTC) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_XSLT);
diff --git a/Source/WebKitLegacy/mac/WebView/WebPreferenceKeysPrivate.h b/Source/WebKitLegacy/mac/WebView/WebPreferenceKeysPrivate.h
index 7ace802..b3da2d6 100644
--- a/Source/WebKitLegacy/mac/WebView/WebPreferenceKeysPrivate.h
+++ b/Source/WebKitLegacy/mac/WebView/WebPreferenceKeysPrivate.h
@@ -259,6 +259,7 @@
 #define WebKitMediaContentTypesRequiringHardwareSupportPreferenceKey @"WebKitMediaContentTypesRequiringHardwareSupport"
 #define WebKitLegacyEncryptedMediaAPIEnabledKey @"WebKitLegacyEncryptedMediaAPIEnabled"
 #define WebKitEncryptedMediaAPIEnabledKey @"WebKitEncryptedMediaAPIEnabled"
+#define WebKitPictureInPictureAPIEnabledKey @"WebKitPictureInPictureAPIEnabled"
 #define WebKitAllowMediaContentTypesRequiringHardwareSupportAsFallbackKey @"WebKitAllowMediaContentTypesRequiringHardwareSupportAsFallback"
 #define WebKitInspectorAdditionsEnabledPreferenceKey @"WebKitInspectorAdditionsEnabled"
 #define WebKitAccessibilityObjectModelEnabledPreferenceKey @"WebKitAccessibilityObjectModelEnabled"
diff --git a/Source/WebKitLegacy/mac/WebView/WebPreferences.mm b/Source/WebKitLegacy/mac/WebView/WebPreferences.mm
index 1104f5a..9934890 100644
--- a/Source/WebKitLegacy/mac/WebView/WebPreferences.mm
+++ b/Source/WebKitLegacy/mac/WebView/WebPreferences.mm
@@ -609,6 +609,11 @@
 #if ENABLE(LEGACY_ENCRYPTED_MEDIA)
         @"~/Library/WebKit/MediaKeys", WebKitMediaKeysStorageDirectoryKey,
 #endif
+
+#if ENABLE(PICTURE_IN_PICTURE_API)
+        @NO, WebKitPictureInPictureAPIEnabledKey,
+#endif
+
 #if ENABLE(MEDIA_STREAM)
         @NO, WebKitMockCaptureDevicesEnabledPreferenceKey,
         @YES, WebKitMockCaptureDevicesPromptEnabledPreferenceKey,
@@ -3330,6 +3335,16 @@
     [self _setBoolValue:flag forKey:WebKitEncryptedMediaAPIEnabledKey];
 }
 
+- (BOOL)pictureInPictureAPIEnabled
+{
+    return [self _boolValueForKey:WebKitPictureInPictureAPIEnabledKey];
+}
+
+- (void)setPictureInPictureAPIEnabled:(BOOL)flag
+{
+    [self _setBoolValue:flag forKey:WebKitPictureInPictureAPIEnabledKey];
+}
+
 - (BOOL)viewportFitEnabled
 {
     return [self _boolValueForKey:WebKitViewportFitEnabledPreferenceKey];
diff --git a/Source/WebKitLegacy/mac/WebView/WebPreferencesPrivate.h b/Source/WebKitLegacy/mac/WebView/WebPreferencesPrivate.h
index da5d04e..dad23c1 100644
--- a/Source/WebKitLegacy/mac/WebView/WebPreferencesPrivate.h
+++ b/Source/WebKitLegacy/mac/WebView/WebPreferencesPrivate.h
@@ -643,6 +643,7 @@
 @property (nonatomic) BOOL isSecureContextAttributeEnabled;
 @property (nonatomic) BOOL legacyEncryptedMediaAPIEnabled;
 @property (nonatomic) BOOL encryptedMediaAPIEnabled;
+@property (nonatomic) BOOL pictureInPictureAPIEnabled;
 @property (nonatomic) BOOL viewportFitEnabled;
 @property (nonatomic) BOOL constantPropertiesEnabled;
 @property (nonatomic) BOOL colorFilterEnabled;
diff --git a/Source/WebKitLegacy/mac/WebView/WebView.mm b/Source/WebKitLegacy/mac/WebView/WebView.mm
index ee67b5b..559ed84 100644
--- a/Source/WebKitLegacy/mac/WebView/WebView.mm
+++ b/Source/WebKitLegacy/mac/WebView/WebView.mm
@@ -3198,6 +3198,10 @@
     RuntimeEnabledFeatures::sharedFeatures().setEncryptedMediaAPIEnabled(preferences.encryptedMediaAPIEnabled);
 #endif
 
+#if ENABLE(PICTURE_IN_PICTURE_API)
+    settings.setPictureInPictureAPIEnabled(preferences.pictureInPictureAPIEnabled);
+#endif
+
     RuntimeEnabledFeatures::sharedFeatures().setInspectorAdditionsEnabled(preferences.inspectorAdditionsEnabled);
 
     settings.setAllowMediaContentTypesRequiringHardwareSupportAsFallback(preferences.allowMediaContentTypesRequiringHardwareSupportAsFallback);
diff --git a/Tools/ChangeLog b/Tools/ChangeLog
index dea4dbb..bbd51bf 100644
--- a/Tools/ChangeLog
+++ b/Tools/ChangeLog
@@ -1,3 +1,20 @@
+2019-10-15  Peng Liu  <peng.liu6@apple.com>
+
+        [Picture-in-Picture Web API] Implement HTMLVideoElement.requestPictureInPicture() / Document.exitPictureInPicture()
+        https://bugs.webkit.org/show_bug.cgi?id=201024
+
+        Reviewed by Eric Carlson.
+
+        Add configurations for Picture-in-Picture API and enable it in the test runner.
+
+        * Scripts/webkitperl/FeatureList.pm:
+        * TestWebKitAPI/Configurations/FeatureDefines.xcconfig:
+        * WebKitTestRunner/InjectedBundle/InjectedBundle.cpp:
+        (WTR::InjectedBundle::beginTesting):
+        * WebKitTestRunner/InjectedBundle/TestRunner.cpp:
+        (WTR::TestRunner::setPictureInPictureAPIEnabled):
+        * WebKitTestRunner/InjectedBundle/TestRunner.h:
+
 2019-10-15  Jiewen Tan  <jiewen_tan@apple.com>
 
         [WebAuthn] Rename -[WKUIDelegatePrivate webView:runWebAuthenticationPanel:initiatedByFrame:completionHandler:] to -[WKUIDelegatePrivate _webView:runWebAuthenticationPanel:initiatedByFrame:completionHandler:]
diff --git a/Tools/Scripts/webkitperl/FeatureList.pm b/Tools/Scripts/webkitperl/FeatureList.pm
index ca6e5ec..5aa48c1 100644
--- a/Tools/Scripts/webkitperl/FeatureList.pm
+++ b/Tools/Scripts/webkitperl/FeatureList.pm
@@ -137,6 +137,7 @@
     $orientationEventsSupport,
     $paymentRequestSupport,
     $pdfkitPluginSupport,
+    $pictureInPictureAPISupport,
     $pointerLockSupport,
     $publicSuffixListSupport,
     $quotaSupport,
@@ -443,6 +444,9 @@
     { option => "pdfkit-plugin", desc => "Toggle PDFKit plugin support",
       define => "ENABLE_PDFKIT_PLUGIN", value => \$pdfkitPluginSupport },
 
+    { option => "picture-in-picture-api", desc => "Toggle Picture-in-Picture API support",
+      define => "ENABLE_PICTURE_IN_PICTURE_API", value => \$pictureInPictureAPISupport },
+
     { option => "pointer-lock", desc => "Toggle pointer lock support",
       define => "ENABLE_POINTER_LOCK", value => \$pointerLockSupport },
 
diff --git a/Tools/TestWebKitAPI/Configurations/FeatureDefines.xcconfig b/Tools/TestWebKitAPI/Configurations/FeatureDefines.xcconfig
index d808ee0..140ffe5 100644
--- a/Tools/TestWebKitAPI/Configurations/FeatureDefines.xcconfig
+++ b/Tools/TestWebKitAPI/Configurations/FeatureDefines.xcconfig
@@ -313,6 +313,9 @@
 
 ENABLE_PAYMENT_REQUEST = ENABLE_PAYMENT_REQUEST;
 
+ENABLE_PICTURE_IN_PICTURE_API = $(ENABLE_PICTURE_IN_PICTURE_API_$(WK_PLATFORM_NAME));
+ENABLE_PICTURE_IN_PICTURE_API_macosx = ENABLE_PICTURE_IN_PICTURE_API;
+
 ENABLE_PDFKIT_PLUGIN = $(ENABLE_PDFKIT_PLUGIN_$(WK_PLATFORM_NAME));
 ENABLE_PDFKIT_PLUGIN_macosx = ENABLE_PDFKIT_PLUGIN;
 
@@ -443,4 +446,4 @@
 
 ENABLE_XSLT = ENABLE_XSLT;
 
-FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCESSIBILITY_ISOLATED_TREE) $(ENABLE_APPLE_PAY) $(ENABLE_APPLE_PAY_SESSION_V3) $(ENABLE_APPLE_PAY_SESSION_V4) $(ENABLE_APPLICATION_MANIFEST) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_AVF_CAPTIONS) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSS3_TEXT) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_CONIC_GRADIENTS) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_PAINTING_API) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_CSS_TYPED_OM) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_C_LOOP) $(ENABLE_DARK_MODE_CSS) $(ENABLE_DATACUE_VALUE) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DATA_INTERACTION) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DRAG_SUPPORT) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_EXPERIMENTAL_FEATURES) $(ENABLE_FAST_JIT_PERMISSIONS) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FTL_JIT) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_INSPECTOR_ALTERNATE_DISPATCHERS) $(ENABLE_INTERSECTION_OBSERVER) $(ENABLE_INTL) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_JIT) $(ENABLE_KEYBOARD_CODE_ATTRIBUTE) $(ENABLE_KEYBOARD_KEY_ATTRIBUTE) $(ENABLE_LAYOUT_FORMATTING_CONTEXT) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_CUSTOM_PROTOCOL_MANAGER) $(ENABLE_LEGACY_ENCRYPTED_MEDIA) $(ENABLE_LETTERPRESS) $(ENABLE_MAC_GESTURE_EVENTS) $(ENABLE_MAC_VIDEO_TOOLBOX) $(ENABLE_MATHML) $(ENABLE_MEDIA_CAPTURE) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_MEMORY_SAMPLER) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_STANDALONE) $(ENABLE_NETWORK_CACHE_SPECULATIVE_REVALIDATION) $(ENABLE_NOTIFICATIONS) $(ENABLE_OVERFLOW_SCROLLING_TOUCH) $(ENABLE_PAYMENT_REQUEST) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_POINTER_EVENTS) $(ENABLE_POINTER_LOCK) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_RESIZE_OBSERVER) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RESOURCE_LOAD_STATISTICS) $(ENABLE_RESOURCE_USAGE) $(ENABLE_RUBBER_BANDING) $(ENABLE_SANDBOX_EXTENSIONS) $(ENABLE_SERVER_PRECONNECT) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_SERVICE_WORKER) $(ENABLE_SHAREABLE_RESOURCE) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_STREAMS_API) $(ENABLE_SVG_FONTS) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TOUCH_EVENTS) $(ENABLE_USERSELECT_ALL) $(ENABLE_USER_MESSAGE_HANDLERS) $(ENABLE_VARIATION_FONTS) $(ENABLE_VIDEO) $(ENABLE_VIDEO_PRESENTATION_MODE) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIDEO_USES_ELEMENT_FULLSCREEN) $(ENABLE_WEBASSEMBLY) $(ENABLE_WEBASSEMBLY_STREAMING_API) $(ENABLE_WEBDRIVER_MOUSE_INTERACTIONS) $(ENABLE_WEBDRIVER_KEYBOARD_INTERACTIONS) $(ENABLE_WEBDRIVER_TOUCH_INTERACTIONS) $(ENABLE_WEBGL) $(ENABLE_WEBGL2) $(ENABLE_WEBGPU) $(ENABLE_WEB_API_STATISTICS) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_AUTHN) $(ENABLE_WEB_CRYPTO) $(ENABLE_WEB_RTC) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_XSLT);
+FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCESSIBILITY_ISOLATED_TREE) $(ENABLE_APPLE_PAY) $(ENABLE_APPLE_PAY_SESSION_V3) $(ENABLE_APPLE_PAY_SESSION_V4) $(ENABLE_APPLICATION_MANIFEST) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_AVF_CAPTIONS) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSS3_TEXT) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_CONIC_GRADIENTS) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_PAINTING_API) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_CSS_TYPED_OM) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_C_LOOP) $(ENABLE_DARK_MODE_CSS) $(ENABLE_DATACUE_VALUE) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DATA_INTERACTION) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DRAG_SUPPORT) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_EXPERIMENTAL_FEATURES) $(ENABLE_FAST_JIT_PERMISSIONS) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FTL_JIT) $(ENABLE_FULLSCREEN_API) $(ENABLE_PICTURE_IN_PICTURE_API) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_INSPECTOR_ALTERNATE_DISPATCHERS) $(ENABLE_INTERSECTION_OBSERVER) $(ENABLE_INTL) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_JIT) $(ENABLE_KEYBOARD_CODE_ATTRIBUTE) $(ENABLE_KEYBOARD_KEY_ATTRIBUTE) $(ENABLE_LAYOUT_FORMATTING_CONTEXT) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_CUSTOM_PROTOCOL_MANAGER) $(ENABLE_LEGACY_ENCRYPTED_MEDIA) $(ENABLE_LETTERPRESS) $(ENABLE_MAC_GESTURE_EVENTS) $(ENABLE_MAC_VIDEO_TOOLBOX) $(ENABLE_MATHML) $(ENABLE_MEDIA_CAPTURE) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_MEMORY_SAMPLER) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_STANDALONE) $(ENABLE_NETWORK_CACHE_SPECULATIVE_REVALIDATION) $(ENABLE_NOTIFICATIONS) $(ENABLE_OVERFLOW_SCROLLING_TOUCH) $(ENABLE_PAYMENT_REQUEST) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_POINTER_EVENTS) $(ENABLE_POINTER_LOCK) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_RESIZE_OBSERVER) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RESOURCE_LOAD_STATISTICS) $(ENABLE_RESOURCE_USAGE) $(ENABLE_RUBBER_BANDING) $(ENABLE_SANDBOX_EXTENSIONS) $(ENABLE_SERVER_PRECONNECT) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_SERVICE_WORKER) $(ENABLE_SHAREABLE_RESOURCE) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_STREAMS_API) $(ENABLE_SVG_FONTS) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TOUCH_EVENTS) $(ENABLE_USERSELECT_ALL) $(ENABLE_USER_MESSAGE_HANDLERS) $(ENABLE_VARIATION_FONTS) $(ENABLE_VIDEO) $(ENABLE_VIDEO_PRESENTATION_MODE) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIDEO_USES_ELEMENT_FULLSCREEN) $(ENABLE_WEBASSEMBLY) $(ENABLE_WEBASSEMBLY_STREAMING_API) $(ENABLE_WEBDRIVER_MOUSE_INTERACTIONS) $(ENABLE_WEBDRIVER_KEYBOARD_INTERACTIONS) $(ENABLE_WEBDRIVER_TOUCH_INTERACTIONS) $(ENABLE_WEBGL) $(ENABLE_WEBGL2) $(ENABLE_WEBGPU) $(ENABLE_WEB_API_STATISTICS) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_AUTHN) $(ENABLE_WEB_CRYPTO) $(ENABLE_WEB_RTC) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_XSLT);
diff --git a/Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp b/Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp
index eb8735c..e7ad015 100644
--- a/Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp
+++ b/Tools/WebKitTestRunner/InjectedBundle/InjectedBundle.cpp
@@ -548,6 +548,7 @@
     m_testRunner->setReadableByteStreamAPIEnabled(true);
 
     m_testRunner->setEncryptedMediaAPIEnabled(true);
+    m_testRunner->setPictureInPictureAPIEnabled(true);
 
     m_testRunner->setCloseRemainingWindowsWhenComplete(false);
     m_testRunner->setAcceptsEditing(true);
diff --git a/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp b/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp
index 917de41..ba5993c7a 100644
--- a/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp
+++ b/Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp
@@ -483,6 +483,13 @@
     WKBundleOverrideBoolPreferenceForTestRunner(injectedBundle.bundle(), injectedBundle.pageGroup(), key.get(), enabled);
 }
 
+void TestRunner::setPictureInPictureAPIEnabled(bool enabled)
+{
+    WKRetainPtr<WKStringRef> key = adoptWK(WKStringCreateWithUTF8CString("WebKitPictureInPictureAPIEnabled"));
+    auto& injectedBundle = InjectedBundle::singleton();
+    WKBundleOverrideBoolPreferenceForTestRunner(injectedBundle.bundle(), injectedBundle.pageGroup(), key.get(), enabled);
+}
+
 void TestRunner::setAllowsAnySSLCertificate(bool enabled)
 {
     auto& injectedBundle = InjectedBundle::singleton();
diff --git a/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h b/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h
index d91db78..c1f124f 100644
--- a/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h
+++ b/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h
@@ -129,6 +129,7 @@
     void setShouldSwapToEphemeralSessionOnNextNavigation(bool);
     void setShouldSwapToDefaultSessionOnNextNavigation(bool);
     void setEncryptedMediaAPIEnabled(bool);
+    void setPictureInPictureAPIEnabled(bool);
     void setMediaDevicesEnabled(bool);
     void setWebRTCMDNSICECandidatesEnabled(bool);
     void setCustomUserAgent(JSStringRef);