Source/WebCore/ChangeLog

 12019-08-05 Chris Dumez <cdumez@apple.com>
 2
 3 navigator.geolocation wrapper should not become GC-collectable once its frame is detached
 4 https://bugs.webkit.org/show_bug.cgi?id=200436
 5
 6 Reviewed by Darin Adler.
 7
 8 navigator.geolocation wrapper should not become GC-collectable once its frame is detached, given
 9 that it can outlive the frame. Instead, tie the navigator.geolocation wrapper's lifetime to its
 10 Navigator's.
 11
 12 Test: fast/dom/navigator-property-gc-after-frame-detach.html
 13
 14 * Modules/geolocation/Geolocation.cpp:
 15 (WebCore::Geolocation::create):
 16 (WebCore::Geolocation::Geolocation):
 17 (WebCore::Geolocation::navigator):
 18 (WebCore::Geolocation::frame const):
 19 * Modules/geolocation/Geolocation.h:
 20 * Modules/geolocation/Geolocation.idl:
 21 * Modules/geolocation/NavigatorGeolocation.cpp:
 22 (WebCore::NavigatorGeolocation::NavigatorGeolocation):
 23 (WebCore::NavigatorGeolocation::from):
 24 (WebCore::NavigatorGeolocation::geolocation):
 25 (WebCore::NavigatorGeolocation::geolocation const):
 26 * Modules/geolocation/NavigatorGeolocation.h:
 27 * bindings/js/JSNavigatorCustom.cpp:
 28 (WebCore::JSNavigator::visitAdditionalChildren):
 29 * bindings/js/JSWorkerNavigatorCustom.cpp:
 30 (WebCore::JSWorkerNavigator::visitAdditionalChildren):
 31 * bindings/scripts/CodeGeneratorJS.pm:
 32 (GenerateImplementation):
 33 * bindings/scripts/IDLAttributes.json:
 34 * page/Navigator.cpp:
 35 (WebCore::Navigator::plugins):
 36 (WebCore::Navigator::mimeTypes):
 37 * page/NavigatorBase.h:
 38 * plugins/DOMMimeTypeArray.cpp:
 39 (WebCore::DOMMimeTypeArray::DOMMimeTypeArray):
 40 * plugins/DOMMimeTypeArray.h:
 41 * plugins/DOMMimeTypeArray.idl:
 42 * plugins/DOMPluginArray.cpp:
 43 (WebCore::DOMPluginArray::DOMPluginArray):
 44 * plugins/DOMPluginArray.h:
 45 * plugins/DOMPluginArray.idl:
 46 * workers/service/ServiceWorkerContainer.h:
 47 * workers/service/ServiceWorkerContainer.idl:
 48
1492019-08-05 Takashi Komori <Takashi.Komori@sony.com>
250
351 [Curl] implement CertificateInfo::summaryInfo

Source/WebCore/Modules/geolocation/Geolocation.cpp

3838#include "GeolocationError.h"
3939#include "GeolocationPosition.h"
4040#include "Geoposition.h"
 41#include "Navigator.h"
4142#include "Page.h"
4243#include "PositionError.h"
4344#include "RuntimeApplicationChecks.h"

@@void Geolocation::Watchers::getNotifiersVector(GeoNotifierVector& copy) const
129130 copy = copyToVector(m_idToNotifierMap.values());
130131}
131132
132 Ref<Geolocation> Geolocation::create(ScriptExecutionContext* context)
 133Ref<Geolocation> Geolocation::create(Navigator& navigator)
133134{
134  auto geolocation = adoptRef(*new Geolocation(context));
 135 auto geolocation = adoptRef(*new Geolocation(navigator));
135136 geolocation.get().suspendIfNeeded();
136137 return geolocation;
137138}
138139
139 Geolocation::Geolocation(ScriptExecutionContext* context)
140  : ActiveDOMObject(context)
141  , m_allowGeolocation(Unknown)
142  , m_isSuspended(false)
143  , m_hasChangedPosition(false)
 140Geolocation::Geolocation(Navigator& navigator)
 141 : ActiveDOMObject(navigator.scriptExecutionContext())
 142 , m_navigator(makeWeakPtr(navigator))
144143 , m_resumeTimer(*this, &Geolocation::resumeTimerFired)
145144{
146145}

@@void Geolocation::handlePendingPermissionNotifiers()
731730 }
732731}
733732
 733Navigator* Geolocation::navigator()
 734{
 735 return m_navigator.get();
 736}
 737
 738Frame* Geolocation::frame() const
 739{
 740 return m_navigator ? m_navigator->frame() : nullptr;
 741}
 742
734743} // namespace WebCore
735744
736745#endif // ENABLE(GEOLOCATION)

Source/WebCore/Modules/geolocation/Geolocation.h

@@namespace WebCore {
4545class Frame;
4646class GeoNotifier;
4747class GeolocationError;
 48class Navigator;
4849class Page;
4950class ScriptExecutionContext;
5051class SecurityOrigin;

@@class Geolocation final : public ScriptWrappable, public RefCounted<Geolocation>
5455 WTF_MAKE_ISO_ALLOCATED(Geolocation);
5556 friend class GeoNotifier;
5657public:
57  static Ref<Geolocation> create(ScriptExecutionContext*);
 58 static Ref<Geolocation> create(Navigator&);
5859 WEBCORE_EXPORT ~Geolocation();
5960
6061 WEBCORE_EXPORT void resetAllGeolocationPermission();
6162 Document* document() const { return downcast<Document>(scriptExecutionContext()); }
62  Frame* frame() const { return document() ? document()->frame() : nullptr; }
6363
6464 void getCurrentPosition(Ref<PositionCallback>&&, RefPtr<PositionErrorCallback>&&, PositionOptions&&);
6565 int watchPosition(Ref<PositionCallback>&&, RefPtr<PositionErrorCallback>&&, PositionOptions&&);

@@public:
7373 void setError(GeolocationError&);
7474 bool shouldBlockGeolocationRequests();
7575
 76 Navigator* navigator();
 77 WEBCORE_EXPORT Frame* frame() const;
 78
7679private:
77  explicit Geolocation(ScriptExecutionContext*);
 80 explicit Geolocation(Navigator&);
7881
7982 Geoposition* lastPosition();
8083

@@private:
144147 bool haveSuitableCachedPosition(const PositionOptions&);
145148 void makeCachedPositionCallbacks();
146149
 150 void resumeTimerFired();
 151
 152 WeakPtr<Navigator> m_navigator;
147153 GeoNotifierSet m_oneShots;
148154 Watchers m_watchers;
149155 GeoNotifierSet m_pendingForPermissionNotifiers;
150156 RefPtr<Geoposition> m_lastPosition;
151157
152  enum {
153  Unknown,
154  InProgress,
155  Yes,
156  No
157  } m_allowGeolocation;
158  bool m_isSuspended;
159  bool m_resetOnResume;
160  bool m_hasChangedPosition;
 158 enum { Unknown, InProgress, Yes, No } m_allowGeolocation { Unknown };
 159 bool m_isSuspended { false };
 160 bool m_resetOnResume { false };
 161 bool m_hasChangedPosition { false };
161162 RefPtr<PositionError> m_errorWaitingForResume;
162 
163  void resumeTimerFired();
164163 Timer m_resumeTimer;
165 
166164 GeoNotifierSet m_requestsAwaitingCachedPosition;
167165};
168166

Source/WebCore/Modules/geolocation/Geolocation.idl

2727[
2828 NoInterfaceObject,
2929 Conditional=GEOLOCATION,
30  GenerateIsReachable=ImplFrame,
 30 GenerateIsReachable=ReachableFromNavigator,
3131] interface Geolocation {
3232 // FIXME: PositionErrorCallback should not be nullable
3333 void getCurrentPosition(PositionCallback successCallback,

Source/WebCore/Modules/geolocation/NavigatorGeolocation.cpp

3434
3535namespace WebCore {
3636
37 NavigatorGeolocation::NavigatorGeolocation(DOMWindow* window)
38  : DOMWindowProperty(window)
 37NavigatorGeolocation::NavigatorGeolocation(Navigator& navigator)
 38 : m_navigator(navigator)
3939{
4040}
4141

@@const char* NavigatorGeolocation::supplementName()
4646 return "NavigatorGeolocation";
4747}
4848
49 NavigatorGeolocation* NavigatorGeolocation::from(Navigator* navigator)
 49NavigatorGeolocation* NavigatorGeolocation::from(Navigator& navigator)
5050{
51  NavigatorGeolocation* supplement = static_cast<NavigatorGeolocation*>(Supplement<Navigator>::from(navigator, supplementName()));
 51 NavigatorGeolocation* supplement = static_cast<NavigatorGeolocation*>(Supplement<Navigator>::from(&navigator, supplementName()));
5252 if (!supplement) {
53  auto newSupplement = std::make_unique<NavigatorGeolocation>(navigator->window());
 53 auto newSupplement = std::make_unique<NavigatorGeolocation>(navigator);
5454 supplement = newSupplement.get();
55  provideTo(navigator, supplementName(), WTFMove(newSupplement));
 55 provideTo(&navigator, supplementName(), WTFMove(newSupplement));
5656 }
5757 return supplement;
5858}

@@void NavigatorGeolocation::resetAllGeolocationPermission()
6767
6868Geolocation* NavigatorGeolocation::geolocation(Navigator& navigator)
6969{
70  return NavigatorGeolocation::from(&navigator)->geolocation();
 70 return NavigatorGeolocation::from(navigator)->geolocation();
7171}
7272
7373Geolocation* NavigatorGeolocation::geolocation() const
7474{
7575 if (!m_geolocation)
76  m_geolocation = Geolocation::create(window() ? window()->document() : nullptr);
 76 m_geolocation = Geolocation::create(m_navigator);
7777 return m_geolocation.get();
7878}
7979

Source/WebCore/Modules/geolocation/NavigatorGeolocation.h

@@namespace WebCore {
2929class Geolocation;
3030class Navigator;
3131
32 class NavigatorGeolocation : public Supplement<Navigator>, public DOMWindowProperty {
 32class NavigatorGeolocation : public Supplement<Navigator> {
3333 WTF_MAKE_FAST_ALLOCATED;
3434public:
35  explicit NavigatorGeolocation(DOMWindow*);
 35 explicit NavigatorGeolocation(Navigator&);
3636 virtual ~NavigatorGeolocation();
37  static NavigatorGeolocation* from(Navigator*);
 37 static NavigatorGeolocation* from(Navigator&);
3838
3939 static Geolocation* geolocation(Navigator&);
4040 Geolocation* geolocation() const;

@@private:
4747 static const char* supplementName();
4848
4949 mutable RefPtr<Geolocation> m_geolocation;
 50 Navigator& m_navigator;
5051};
5152
5253} // namespace WebCore

Source/WebCore/bindings/js/JSNavigatorCustom.cpp

@@namespace WebCore {
3030
3131void JSNavigator::visitAdditionalChildren(JSC::SlotVisitor& visitor)
3232{
33 #if ENABLE(SERVICE_WORKER)
34  visitor.addOpaqueRoot(wrapped().serviceWorkerIfExists());
35 #else
36  UNUSED_PARAM(visitor);
37 #endif
 33 visitor.addOpaqueRoot(static_cast<NavigatorBase*>(&wrapped()));
3834}
3935
4036}

Source/WebCore/bindings/js/JSWorkerNavigatorCustom.cpp

@@namespace WebCore {
3030
3131void JSWorkerNavigator::visitAdditionalChildren(JSC::SlotVisitor& visitor)
3232{
33 #if ENABLE(SERVICE_WORKER)
34  visitor.addOpaqueRoot(wrapped().serviceWorkerIfExists());
35 #else
36  UNUSED_PARAM(visitor);
37 #endif
 33 visitor.addOpaqueRoot(static_cast<NavigatorBase*>(&wrapped()));
3834}
3935
4036}

Source/WebCore/bindings/scripts/CodeGeneratorJS.pm

@@sub GenerateImplementation
46744674 $rootString = " WebGLRenderingContextBase* root = WTF::getPtr(js${interfaceName}->wrapped().context());\n";
46754675 $rootString .= " if (UNLIKELY(reason))\n";
46764676 $rootString .= " *reason = \"Reachable from ${interfaceName}\";\n";
4677  } elsif (GetGenerateIsReachable($interface) eq "ImplFrame") {
4678  $rootString = " Frame* root = WTF::getPtr(js${interfaceName}->wrapped().frame());\n";
4679  $rootString .= " if (!root)\n";
4680  $rootString .= " return false;\n";
4681  $rootString .= " if (UNLIKELY(reason))\n";
4682  $rootString .= " *reason = \"Reachable from Frame\";\n";
46834677 } elsif (GetGenerateIsReachable($interface) eq "ReachableFromDOMWindow") {
46844678 $rootString = " auto* root = WTF::getPtr(js${interfaceName}->wrapped().window());\n";
46854679 $rootString .= " if (!root)\n";
46864680 $rootString .= " return false;\n";
46874681 $rootString .= " if (UNLIKELY(reason))\n";
46884682 $rootString .= " *reason = \"Reachable from Window\";\n";
 4683 } elsif (GetGenerateIsReachable($interface) eq "ReachableFromNavigator") {
 4684 $implIncludes{"Navigator.h"} = 1;
 4685 $implIncludes{"WorkerNavigator.h"} = 1;
 4686 $rootString = " NavigatorBase* root = WTF::getPtr(js${interfaceName}->wrapped().navigator());\n";
 4687 $rootString .= " if (!root)\n";
 4688 $rootString .= " return false;\n";
 4689 $rootString .= " if (UNLIKELY(reason))\n";
 4690 $rootString .= " *reason = \"Reachable from Navigator\";\n";
46894691 } elsif (GetGenerateIsReachable($interface) eq "ImplDocument") {
46904692 $rootString = " Document* root = WTF::getPtr(js${interfaceName}->wrapped().document());\n";
46914693 $rootString .= " if (!root)\n";

Source/WebCore/bindings/scripts/IDLAttributes.json

226226 },
227227 "GenerateIsReachable": {
228228 "contextsAllowed": ["interface"],
229  "values": ["", "Impl", "ImplWebGLRenderingContext", "ImplDocument", "ImplElementRoot", "ImplFrame", "ImplOwnerNodeRoot", "ImplScriptExecutionContext", "ReachableFromDOMWindow"]
 229 "values": ["", "Impl", "ImplWebGLRenderingContext", "ImplDocument", "ImplElementRoot", "ImplOwnerNodeRoot", "ImplScriptExecutionContext", "ReachableFromDOMWindow", "ReachableFromNavigator"]
230230 },
231231 "Global": {
232232 "contextsAllowed": ["interface"],

Source/WebCore/page/DOMWindow.cpp

@@void DOMWindow::resetAllGeolocationPermission()
20502050 // FIXME: Can we remove the PLATFORM(IOS_FAMILY)-guard?
20512051#if ENABLE(GEOLOCATION) && PLATFORM(IOS_FAMILY)
20522052 if (m_navigator)
2053  NavigatorGeolocation::from(m_navigator.get())->resetAllGeolocationPermission();
 2053 NavigatorGeolocation::from(*m_navigator)->resetAllGeolocationPermission();
20542054#endif
20552055}
20562056

Source/WebCore/page/Navigator.cpp

@@DOMPluginArray& Navigator::plugins()
153153 ResourceLoadObserver::shared().logNavigatorAPIAccessed(*frame->document(), ResourceLoadStatistics::NavigatorAPI::Plugins);
154154 }
155155 if (!m_plugins)
156  m_plugins = DOMPluginArray::create(window());
 156 m_plugins = DOMPluginArray::create(*this);
157157 return *m_plugins;
158158}
159159

@@DOMMimeTypeArray& Navigator::mimeTypes()
164164 ResourceLoadObserver::shared().logNavigatorAPIAccessed(*frame->document(), ResourceLoadStatistics::NavigatorAPI::MimeTypes);
165165 }
166166 if (!m_mimeTypes)
167  m_mimeTypes = DOMMimeTypeArray::create(window());
 167 m_mimeTypes = DOMMimeTypeArray::create(*this);
168168 return *m_mimeTypes;
169169}
170170

Source/WebCore/page/NavigatorBase.h

3131#include <wtf/RefCounted.h>
3232#include <wtf/UniqueRef.h>
3333#include <wtf/Vector.h>
 34#include <wtf/WeakPtr.h>
3435
3536namespace WebCore {
3637
3738class ScriptExecutionContext;
3839class ServiceWorkerContainer;
3940
40 class NavigatorBase : public RefCounted<NavigatorBase>, public ContextDestructionObserver {
 41class NavigatorBase : public RefCounted<NavigatorBase>, public ContextDestructionObserver, public CanMakeWeakPtr<NavigatorBase> {
4142public:
4243 virtual ~NavigatorBase();
4344

Source/WebCore/plugins/DOMMimeTypeArray.cpp

@@namespace WebCore {
3131
3232WTF_MAKE_ISO_ALLOCATED_IMPL(DOMMimeTypeArray);
3333
34 DOMMimeTypeArray::DOMMimeTypeArray(DOMWindow* window)
35  : DOMWindowProperty(window)
 34DOMMimeTypeArray::DOMMimeTypeArray(Navigator& navigator)
 35 : m_navigator(makeWeakPtr(navigator))
3636{
3737}
3838

Source/WebCore/plugins/DOMMimeTypeArray.h

2121#pragma once
2222
2323#include "DOMMimeType.h"
24 #include "DOMWindowProperty.h"
 24#include "Navigator.h"
2525#include "ScriptWrappable.h"
2626#include <wtf/RefCounted.h>
2727

@@namespace WebCore {
2929
3030class PluginData;
3131
32 class DOMMimeTypeArray final : public ScriptWrappable, public RefCounted<DOMMimeTypeArray>, public DOMWindowProperty {
 32class DOMMimeTypeArray final : public ScriptWrappable, public RefCounted<DOMMimeTypeArray> {
3333 WTF_MAKE_ISO_ALLOCATED(DOMMimeTypeArray);
3434public:
35  static Ref<DOMMimeTypeArray> create(DOMWindow* window) { return adoptRef(*new DOMMimeTypeArray(window)); }
 35 static Ref<DOMMimeTypeArray> create(Navigator& navigator) { return adoptRef(*new DOMMimeTypeArray(navigator)); }
3636 ~DOMMimeTypeArray();
3737
3838 unsigned length() const;
3939 RefPtr<DOMMimeType> item(unsigned index);
4040 RefPtr<DOMMimeType> namedItem(const AtomString& propertyName);
4141 Vector<AtomString> supportedPropertyNames();
 42
 43 Navigator* navigator() { return m_navigator.get(); }
4244
4345private:
44  explicit DOMMimeTypeArray(DOMWindow*);
 46 explicit DOMMimeTypeArray(Navigator&);
4547 PluginData* getPluginData() const;
 48 Frame* frame() const { return m_navigator ? m_navigator->frame() : nullptr; }
 49
 50 WeakPtr<Navigator> m_navigator;
4651};
4752
4853} // namespace WebCore

Source/WebCore/plugins/DOMMimeTypeArray.idl

1919*/
2020
2121[
22  GenerateIsReachable=ReachableFromDOMWindow,
 22 GenerateIsReachable=ReachableFromNavigator,
2323 LegacyUnenumerableNamedProperties,
2424 ImplementationLacksVTable,
2525 InterfaceName=MimeTypeArray,

Source/WebCore/plugins/DOMPluginArray.cpp

@@namespace WebCore {
3131
3232WTF_MAKE_ISO_ALLOCATED_IMPL(DOMPluginArray);
3333
34 DOMPluginArray::DOMPluginArray(DOMWindow* window)
35  : DOMWindowProperty(window)
 34DOMPluginArray::DOMPluginArray(Navigator& navigator)
 35 : m_navigator(makeWeakPtr(navigator))
3636{
3737}
3838

Source/WebCore/plugins/DOMPluginArray.h

2222
2323#include "DOMPlugin.h"
2424#include "DOMWindowProperty.h"
 25#include "Navigator.h"
2526#include "ScriptWrappable.h"
2627#include <wtf/RefCounted.h>
2728

@@namespace WebCore {
2930
3031class PluginData;
3132
32 class DOMPluginArray final : public ScriptWrappable, public RefCounted<DOMPluginArray>, public DOMWindowProperty {
 33class DOMPluginArray final : public ScriptWrappable, public RefCounted<DOMPluginArray> {
3334 WTF_MAKE_ISO_ALLOCATED(DOMPluginArray);
3435public:
35  static Ref<DOMPluginArray> create(DOMWindow* window) { return adoptRef(*new DOMPluginArray(window)); }
 36 static Ref<DOMPluginArray> create(Navigator& navigator) { return adoptRef(*new DOMPluginArray(navigator)); }
3637 ~DOMPluginArray();
3738
3839 unsigned length() const;

@@public:
4142 Vector<AtomString> supportedPropertyNames();
4243
4344 void refresh(bool reloadPages);
 45
 46 Navigator* navigator() { return m_navigator.get(); }
4447
4548private:
46  explicit DOMPluginArray(DOMWindow*);
 49 explicit DOMPluginArray(Navigator&);
 50
4751 PluginData* pluginData() const;
 52 Frame* frame() const { return m_navigator ? m_navigator->frame() : nullptr; }
 53
 54 WeakPtr<Navigator> m_navigator;
4855};
4956
5057} // namespace WebCore

Source/WebCore/plugins/DOMPluginArray.idl

1919*/
2020
2121[
22  GenerateIsReachable=ReachableFromDOMWindow,
 22 GenerateIsReachable=ReachableFromNavigator,
2323 LegacyUnenumerableNamedProperties,
2424 ImplementationLacksVTable,
2525 InterfaceName=PluginArray,

Source/WebCore/workers/service/ServiceWorkerContainer.h

@@public:
8787
8888 bool isAlwaysOnLoggingAllowed() const;
8989
 90 NavigatorBase* navigator() { return &m_navigator; }
 91
9092private:
9193 void scheduleJob(std::unique_ptr<ServiceWorkerJob>&&);
9294

Source/WebCore/workers/service/ServiceWorkerContainer.idl

3131 Exposed=(Window,ServiceWorker),
3232 Conditional=SERVICE_WORKER,
3333 EnabledAtRuntime=ServiceWorker,
34  GenerateIsReachable=Impl,
 34 GenerateIsReachable=ReachableFromNavigator
3535] interface ServiceWorkerContainer : EventTarget {
3636 readonly attribute ServiceWorker? controller;
3737 readonly attribute Promise<ServiceWorkerRegistration> ready;

LayoutTests/ChangeLog

 12019-08-05 Chris Dumez <cdumez@apple.com>
 2
 3 navigator.geolocation wrapper should not become GC-collectable once its frame is detached
 4 https://bugs.webkit.org/show_bug.cgi?id=200436
 5
 6 Reviewed by Darin Adler.
 7
 8 Add layout test coverage.
 9
 10 * fast/dom/navigator-property-gc-after-frame-detach-expected.txt: Added.
 11 * fast/dom/navigator-property-gc-after-frame-detach.html: Added.
 12
1132019-08-05 Takashi Komori <Takashi.Komori@sony.com>
214
315 [Curl] implement CertificateInfo::summaryInfo

LayoutTests/fast/dom/navigator-property-gc-after-frame-detach-expected.txt

 1Tests that Navigator properties do not get GC'd before their Navigator object.
 2
 3On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 4
 5
 6PASS frameNavigator.geolocation.foo is 1
 7PASS frameNavigator.mimeTypes.foo is 1
 8PASS frameNavigator.plugins.foo is 1
 9PASS frameNavigator.serviceWorker.foo is 1
 10
 11PASS frameNavigator.geolocation.foo is 1
 12PASS frameNavigator.mimeTypes.foo is 1
 13PASS frameNavigator.plugins.foo is 1
 14PASS frameNavigator.serviceWorker.foo is 1
 15
 16PASS frameNavigator.geolocation.foo is 1
 17PASS frameNavigator.mimeTypes.foo is 1
 18PASS frameNavigator.plugins.foo is 1
 19PASS frameNavigator.serviceWorker.foo is 1
 20PASS successfullyParsed is true
 21
 22TEST COMPLETE
 23

LayoutTests/fast/dom/navigator-property-gc-after-frame-detach.html

 1<!DOCTYPE html>
 2<html>
 3<body>
 4<script src="../../resources/js-test.js"></script>
 5<iframe id="testFrame" src="about:blank"></iframe>
 6<script>
 7description("Tests that Navigator properties do not get GC'd before their Navigator object.");
 8jsTestIsAsync = true;
 9
 10var navigatorProperties = [ "geolocation", "mimeTypes", "plugins" ];
 11if (navigator.serviceWorker)
 12 navigatorProperties.push("serviceWorker");
 13
 14onload = function() {
 15 frameNavigator = document.getElementById("testFrame").contentWindow.navigator;
 16 for (let navigatorProperty of navigatorProperties)
 17 eval("frameNavigator." + navigatorProperty + ".foo = 1;");
 18 document.getElementById("testFrame").remove();
 19 for (let navigatorProperty of navigatorProperties)
 20 shouldBe("frameNavigator." + navigatorProperty + ".foo", "1");
 21 debug("");
 22 gc();
 23 for (let navigatorProperty of navigatorProperties)
 24 shouldBe("frameNavigator." + navigatorProperty + ".foo", "1");
 25 debug("");
 26 setTimeout(() => {
 27 gc();
 28 for (let navigatorProperty of navigatorProperties)
 29 shouldBe("frameNavigator." + navigatorProperty + ".foo", "1");
 30 finishJSTest();
 31 }, 10);
 32}
 33</script>
 34</body>

LayoutTests/platform/mac-wk1/fast/dom/navigator-property-gc-after-frame-detach-expected.txt

 1Tests that Navigator properties do not get GC'd before their Navigator object.
 2
 3On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 4
 5
 6PASS frameNavigator.geolocation.foo is 1
 7PASS frameNavigator.mimeTypes.foo is 1
 8PASS frameNavigator.plugins.foo is 1
 9
 10PASS frameNavigator.geolocation.foo is 1
 11PASS frameNavigator.mimeTypes.foo is 1
 12PASS frameNavigator.plugins.foo is 1
 13
 14PASS frameNavigator.geolocation.foo is 1
 15PASS frameNavigator.mimeTypes.foo is 1
 16PASS frameNavigator.plugins.foo is 1
 17PASS successfullyParsed is true
 18
 19TEST COMPLETE
 20

LayoutTests/platform/win/fast/dom/navigator-property-gc-after-frame-detach-expected.txt

 1Tests that Navigator properties do not get GC'd before their Navigator object.
 2
 3On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 4
 5
 6PASS frameNavigator.geolocation.foo is 1
 7PASS frameNavigator.mimeTypes.foo is 1
 8PASS frameNavigator.plugins.foo is 1
 9
 10PASS frameNavigator.geolocation.foo is 1
 11PASS frameNavigator.mimeTypes.foo is 1
 12PASS frameNavigator.plugins.foo is 1
 13
 14PASS frameNavigator.geolocation.foo is 1
 15PASS frameNavigator.mimeTypes.foo is 1
 16PASS frameNavigator.plugins.foo is 1
 17PASS successfullyParsed is true
 18
 19TEST COMPLETE
 20

LayoutTests/platform/wk2/TestExpectations

@@plugins/npruntime/embed-property-iframe-equality.html
160160
161161webkit.org/b/105952 fast/loader/submit-form-while-parsing-2.html [ Pass Failure ]
162162
163 webkit.org/b/141122 editing/selection/programmatic-selection-on-mac-is-directionless.html [ Pass Failure ]
164 
165163webkit.org/b/149087 http/tests/cache/disk-cache/disk-cache-cancel.html [ Pass Failure ]
166164
167165http/tests/appcache/decide-navigation-policy-after-delay.html [ Pass ]