LayoutTests:
authordarin <darin@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 11 Mar 2006 03:17:11 +0000 (03:17 +0000)
committerdarin <darin@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 11 Mar 2006 03:17:11 +0000 (03:17 +0000)
        Reviewed by Geoff, except for frame-name-reset, which was done by Alexey.

        - test for http://bugzilla.opendarwin.org/show_bug.cgi?id=3308
          Pop-up blocking blocks window.open for already open windows

        * fast/dom/Window/open-existing-pop-up-blocking-expected.checksum: Added.
        * fast/dom/Window/open-existing-pop-up-blocking-expected.png: Added.
        * fast/dom/Window/open-existing-pop-up-blocking-expected.txt: Added.
        * fast/dom/Window/open-existing-pop-up-blocking.html: Added.
        * fast/dom/Window/resources/open-sibling-subframe.html: Added.
        * fast/dom/Window/resources/sibling-subframe-content.html: Added.

        - test for http://bugzilla.opendarwin.org/show_bug.cgi?id=7422
          Setting a frame name to the same value resets it to a generated one

        * fast/frames/frame-name-reset.html: Added.
        * fast/frames/frame-name-reset-expected.txt: Added.

WebCore:

        Reviewed by Geoff.

        - fix http://bugzilla.opendarwin.org/show_bug.cgi?id=3308
          Pop-up blocking blocks window.open for already open windows

        - fix http://bugzilla.opendarwin.org/show_bug.cgi?id=7422
          Setting a frame name to the same value resets it to a generated one

        - refactor frame-name-related functions into the FrameTree object

        * WebCore.xcodeproj/project.pbxproj: Update for rename.
        * bridge/mac/MacFrame.h: Remove generateFrameName.
        * bridge/mac/MacFrame.mm: Ditto.
        * bridge/mac/PageMac.h: Added a declaration for WebCorePageBridge.

        * bridge/mac/WebCoreFrameBridge.h: Remove _frameNamespace, generateFrameName,
        setFrameNamespace, frameNamespace.
        * bridge/mac/WebCoreFrameBridge.mm:
        (-[WebCoreFrameBridge childFrameNamed:]): Change to call the new child
        function on the FrameTree.
        (-[WebCoreFrameBridge findFrameNamed:]): Change to call the new find
        function on the FrameTree.
        (-[WebCoreFrameBridge RenderObject::nodeInfoAtPoint:]): Change since the
        contentPart function has been renamed to contentFrame.

        * bridge/mac/WebCoreFrameNamespaces.h: Removed everything except for the
        one method still used on the WebKit side, framesInNamespace:.
        * bridge/mac/WebCoreFrameNamespaces.m: Renamed.
        * bridge/mac/WebCoreFrameNamespaces.mm: Added. Reimplemented the
        framesInNamespace method to use the namespace in WebCore::Page.

        * bridge/mac/WebCorePageBridge.h: Added setGroupName and groupName.
        * bridge/mac/WebCorePageBridge.mm:
        (-[WebCorePageBridge setGroupName:]): Added. Calls through to Page.
        (-[WebCorePageBridge groupName]): Ditto.

        * khtml/ecma/kjs_html.cpp:
        (KJS::HTMLDocument::namedItemGetter): Changed to call contentFrame by its new name.
        (KJS::HTMLElement::frameGetter): Ditto.
        (KJS::HTMLElement::iFrameGetter): Ditto.

        * khtml/ecma/kjs_window.cpp:
        (KJS::Window::getValueProperty): Changed to call FrameTree::childCount
        instead of Frame::frames.
        (KJS::Window::childFrameGetter): Changed to call FrameTree::child
        instead of Frame::childFrameNamed.
        (KJS::Window::namedFrameGetter): Changed to call FrameTree::find
        instead of Frame::findFrame.
        (KJS::Window::indexGetter): Changed to call FrameTree::child
        instead of Frame::frames.
        (KJS::Window::getOwnPropertySlot): Changed to call FrameTree::child,
        FrameTree::find, and FrameTree::childCount instead of Frame::childFrameNamed,
        and Frame::findFrame, and Frame::frames.
        (KJS::WindowFunc::callAsFunction): Call FrameTree::find to check if the window
        is already open when considering whether to block a pop-up.
        (KJS::FrameArray::getValueProperty): Changed to call FrameTree::childCount
        instead of Frame::frames.
        (KJS::FrameArray::indexGetter): Changed to call FrameTree::child
        instead of Frame::frames.
        (KJS::FrameArray::nameGetter): Changed to call FrameTree::child
        instead of Frame::findFrame.
        (KJS::FrameArray::getOwnPropertySlot): Changed to call FrameTree::child,
        and FrameTree::childCount instead of Frame::findFrame and Frame::frames.

        * khtml/html/html_baseimpl.h:
        * khtml/html/html_baseimpl.cpp:
        (WebCore::HTMLFrameElementImpl::isURLAllowed): Changed to call Page::frameCount
        instead of Frame::topLevelFrameCount.
        (WebCore::HTMLFrameElementImpl::openURL): Changed to call FrameTree::child
        instead of Frame::findFrame.
        (WebCore::HTMLFrameElementImpl::attach): Changed to call Page::incrementFrameCount
        instead of Frame::incrementFrameCount. Changed to call FrameTree::uniqueChildName
        instead of Frame::requestFrameName.
        (WebCore::HTMLFrameElementImpl::close): Changed to call Page::decrementFrameCount
        instead of Frame::decrementFrameCount. Changed to call FrameTree::child
        instead of Frame::findFrame.
        (WebCore::HTMLFrameElementImpl::contentFrame): Renamed from contentPart. Also
        changed to call FrameTree::child instead of Frame::findFrame.
        (WebCore::HTMLFrameElementImpl::contentDocument): Updated for name change of
        contentFrame from contentPart.
        (WebCore::HTMLIFrameElementImpl::attach): Changed to call Page::incrementFrameCount
        instead of Frame::incrementFrameCount. Changed to call FrameTree::uniqueChildName
        instead of Frame::requestFrameName.

        * rendering/render_frames.cpp: (WebCore::isURLAllowed): Changed to call Page::frameCount
        instead of Frame::topLevelFrameCount.

        * page/Frame.h: Removed frameNames, frames, childFrameNamed, findFrame, currentFrame,
        frameExists, incrementFrameCount, decrementFrameCount, topLevelFrameCount,
        generateFrameName, and requestFrameName functions.
        * page/Frame.cpp: (WebCore::Frame::requestFrame): Changed to use FrameTree::child
        instead of Frame::childFrameNamed.

        * page/FrameTree.h: Changed name to an atomic string. Changed childCount to unsigned.
        Added isDescendantOf, traverseNext, child, find, uniqueChildName.
        * page/FrameTree.cpp:
        (WebCore::FrameTree::setName): Changed to call uniqueChildName to handle name
        duplication logic.
        (WebCore::FrameTree::uniqueChildName): Added. Checks for duplication and generates
        an appropriate frame name if there is a duplicate.
        (WebCore::FrameTree::child): Added.
        (WebCore::FrameTree::find): Added.
        (WebCore::FrameTree::isDescendantOf): Added.
        (WebCore::FrameTree::traverseNext): Added.

        * page/Page.h: Added setGroupName, groupName, frameNamespace, incrementFrameCount,
        decrementFrameCount, and frameCount.
        * page/Page.cpp:
        (WebCore::Page::Page): Initialize m_frameCount to 0.
        (WebCore::Page::~Page): Call setGroupName to remove the page from any group it's in.
        (WebCore::Page::setGroupName): Added.
        (WebCore::Page::frameNamespace): Added.

        * platform/win/TemporaryLinkStubs.cpp: Removed FrameWin::generateFrameName.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@13257 268f45cc-cd09-0410-ab3c-d52691b4dbfc

32 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/dom/Window/open-existing-pop-up-blocking-expected.checksum [new file with mode: 0644]
LayoutTests/fast/dom/Window/open-existing-pop-up-blocking-expected.png [new file with mode: 0644]
LayoutTests/fast/dom/Window/open-existing-pop-up-blocking-expected.txt [new file with mode: 0644]
LayoutTests/fast/dom/Window/open-existing-pop-up-blocking.html [new file with mode: 0644]
LayoutTests/fast/dom/Window/resources/open-sibling-subframe.html [new file with mode: 0644]
LayoutTests/fast/dom/Window/resources/sibling-subframe-content.html [new file with mode: 0644]
LayoutTests/fast/frames/frame-name-reset-expected.txt [new file with mode: 0644]
LayoutTests/fast/frames/frame-name-reset.html [new file with mode: 0644]
WebCore/ChangeLog
WebCore/WebCore.xcodeproj/project.pbxproj
WebCore/bridge/mac/MacFrame.h
WebCore/bridge/mac/MacFrame.mm
WebCore/bridge/mac/PageMac.h
WebCore/bridge/mac/WebCoreFrameBridge.h
WebCore/bridge/mac/WebCoreFrameBridge.mm
WebCore/bridge/mac/WebCoreFrameNamespaces.h
WebCore/bridge/mac/WebCoreFrameNamespaces.mm [moved from WebCore/bridge/mac/WebCoreFrameNamespaces.m with 54% similarity]
WebCore/bridge/mac/WebCorePageBridge.h
WebCore/bridge/mac/WebCorePageBridge.mm
WebCore/khtml/ecma/kjs_html.cpp
WebCore/khtml/ecma/kjs_window.cpp
WebCore/khtml/html/html_baseimpl.cpp
WebCore/khtml/html/html_baseimpl.h
WebCore/page/Frame.cpp
WebCore/page/Frame.h
WebCore/page/FrameTree.cpp
WebCore/page/FrameTree.h
WebCore/page/Page.cpp
WebCore/page/Page.h
WebCore/platform/win/TemporaryLinkStubs.cpp
WebCore/rendering/render_frames.cpp

index ed273d131ab9dd65883f0a69ac8f1d8ad6174089..40547a5542dc3af9ffac22659ca7703658db7ab2 100644 (file)
@@ -1,3 +1,23 @@
+2006-03-10  Darin Adler  <darin@apple.com>
+
+        Reviewed by Geoff, except for frame-name-reset, which was done by Alexey.
+
+        - test for http://bugzilla.opendarwin.org/show_bug.cgi?id=3308
+          Pop-up blocking blocks window.open for already open windows
+
+        * fast/dom/Window/open-existing-pop-up-blocking-expected.checksum: Added.
+        * fast/dom/Window/open-existing-pop-up-blocking-expected.png: Added.
+        * fast/dom/Window/open-existing-pop-up-blocking-expected.txt: Added.
+        * fast/dom/Window/open-existing-pop-up-blocking.html: Added.
+        * fast/dom/Window/resources/open-sibling-subframe.html: Added.
+        * fast/dom/Window/resources/sibling-subframe-content.html: Added.
+
+        - test for http://bugzilla.opendarwin.org/show_bug.cgi?id=7422
+          Setting a frame name to the same value resets it to a generated one
+
+        * fast/frames/frame-name-reset.html: Added.
+        * fast/frames/frame-name-reset-expected.txt: Added.
+
 2006-03-10  Adele Peterson  <adele@apple.com>
 
         - Test for <rdar://problem/4469419> 
diff --git a/LayoutTests/fast/dom/Window/open-existing-pop-up-blocking-expected.checksum b/LayoutTests/fast/dom/Window/open-existing-pop-up-blocking-expected.checksum
new file mode 100644 (file)
index 0000000..545237f
--- /dev/null
@@ -0,0 +1 @@
+01f3db4d8bac43e99b526eee46d40a74
\ No newline at end of file
diff --git a/LayoutTests/fast/dom/Window/open-existing-pop-up-blocking-expected.png b/LayoutTests/fast/dom/Window/open-existing-pop-up-blocking-expected.png
new file mode 100644 (file)
index 0000000..f8f4657
Binary files /dev/null and b/LayoutTests/fast/dom/Window/open-existing-pop-up-blocking-expected.png differ
diff --git a/LayoutTests/fast/dom/Window/open-existing-pop-up-blocking-expected.txt b/LayoutTests/fast/dom/Window/open-existing-pop-up-blocking-expected.txt
new file mode 100644 (file)
index 0000000..148b339
--- /dev/null
@@ -0,0 +1,30 @@
+layer at (0,0) size 800x600
+  RenderCanvas at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderBlock {HTML} at (0,0) size 800x600
+    RenderBody {BODY} at (8,8) size 784x584
+      RenderPartObject {IFRAME} at (0,0) size 300x150
+        layer at (0,0) size 300x150
+          RenderCanvas at (0,0) size 300x150
+        layer at (0,0) size 300x150
+          RenderBlock {HTML} at (0,0) size 300x150
+            RenderBody {BODY} at (8,8) size 284x134
+              RenderText {TEXT} at (0,0) size 278x72
+                text run at (0,0) width 278: "This frame will try to replace the contents of"
+                text run at (0,18) width 275: "the frame to the right. If the bug still occurs,"
+                text run at (0,36) width 269: "pop-up blocking will prevent it from doing"
+                text run at (0,54) width 18: "so."
+              RenderText {TEXT} at (0,0) size 0x0
+      RenderText {TEXT} at (300,136) size 4x18
+        text run at (300,136) width 4: " "
+      RenderPartObject {IFRAME} at (304,0) size 300x150
+        layer at (0,0) size 300x150
+          RenderCanvas at (0,0) size 300x150
+        layer at (0,0) size 300x150
+          RenderBlock {HTML} at (0,0) size 300x150
+            RenderBody {BODY} at (8,8) size 284x134
+              RenderText {TEXT} at (0,0) size 267x36
+                text run at (0,0) width 267: "This text successfully replaced the original"
+                text run at (0,18) width 211: "text in the frame. Test succeeded!"
+              RenderText {TEXT} at (0,0) size 0x0
+      RenderText {TEXT} at (0,0) size 0x0
diff --git a/LayoutTests/fast/dom/Window/open-existing-pop-up-blocking.html b/LayoutTests/fast/dom/Window/open-existing-pop-up-blocking.html
new file mode 100644 (file)
index 0000000..83a5a6b
--- /dev/null
@@ -0,0 +1,6 @@
+<script>
+if (window.layoutTestController)
+    layoutTestController.waitUntilDone();
+</script>
+<iframe src="resources/open-sibling-subframe.html"></iframe>
+<iframe name="sibling" src="data:text/html,If you can still see this text, the test failed."></iframe>
diff --git a/LayoutTests/fast/dom/Window/resources/open-sibling-subframe.html b/LayoutTests/fast/dom/Window/resources/open-sibling-subframe.html
new file mode 100644 (file)
index 0000000..633e31b
--- /dev/null
@@ -0,0 +1,10 @@
+<script>
+function test()
+{
+    open("sibling-subframe-content.html", "sibling");
+}
+</script>
+<body onload="test()">
+This frame will try to replace the contents of the frame to the right.
+If the bug still occurs, pop-up blocking will prevent it from doing so.
+</body>
diff --git a/LayoutTests/fast/dom/Window/resources/sibling-subframe-content.html b/LayoutTests/fast/dom/Window/resources/sibling-subframe-content.html
new file mode 100644 (file)
index 0000000..76b52d5
--- /dev/null
@@ -0,0 +1,9 @@
+<script>
+function loaded() {
+    if (window.layoutTestController)
+        layoutTestController.notifyDone();
+}
+</script>
+<body onload="loaded()">
+This text successfully replaced the original text in the frame. Test succeeded!
+</body>
diff --git a/LayoutTests/fast/frames/frame-name-reset-expected.txt b/LayoutTests/fast/frames/frame-name-reset-expected.txt
new file mode 100644 (file)
index 0000000..064737f
--- /dev/null
@@ -0,0 +1,2 @@
+ALERT: SUCCESS
+
diff --git a/LayoutTests/fast/frames/frame-name-reset.html b/LayoutTests/fast/frames/frame-name-reset.html
new file mode 100644 (file)
index 0000000..7fc9211
--- /dev/null
@@ -0,0 +1,24 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
+<head>
+       <title>Bug 7422</title>
+       <script>
+               if (window.layoutTestController)
+                   layoutTestController.dumpAsText();
+       </script>
+</head>
+       <frameset cols="400,*" rows="*" id="mainFrameset">
+               <frame frameborder="1" name="frame_1" id="frame_1" src="data:text/html, Test for <a href='http://bugzilla.opendarwin.org/show_bug.cgi?id=7422' target='_top'> bug 7422</a>: setting a frame name to the same value resets it to a generated one." />
+               <frame frameborder="1" src="javascript:
+                       
+                       var oldName = window.parent.frames[0].name;
+                       window.parent.frames[0].name = oldName;
+                       if (window.parent.frames[0].name == oldName) {
+                               alert('SUCCESS');
+                       } else {
+                               alert('FAILURE: ' + window.parent.frames[0].name);
+                       }
+               
+               " />
+       </frameset>
+</html>
index e0f2005a3b8e613ced7c30e7ba754168a8db1f58..f883e13d135b0e857cd499023c66560c8f8f28df 100644 (file)
@@ -1,3 +1,120 @@
+2006-03-10  Darin Adler  <darin@apple.com>
+
+        Reviewed by Geoff.
+
+        - fix http://bugzilla.opendarwin.org/show_bug.cgi?id=3308
+          Pop-up blocking blocks window.open for already open windows
+
+        - fix http://bugzilla.opendarwin.org/show_bug.cgi?id=7422
+          Setting a frame name to the same value resets it to a generated one
+
+        - refactor frame-name-related functions into the FrameTree object
+
+        * WebCore.xcodeproj/project.pbxproj: Update for rename.
+        * bridge/mac/MacFrame.h: Remove generateFrameName.
+        * bridge/mac/MacFrame.mm: Ditto.
+        * bridge/mac/PageMac.h: Added a declaration for WebCorePageBridge.
+
+        * bridge/mac/WebCoreFrameBridge.h: Remove _frameNamespace, generateFrameName,
+        setFrameNamespace, frameNamespace.
+        * bridge/mac/WebCoreFrameBridge.mm:
+        (-[WebCoreFrameBridge childFrameNamed:]): Change to call the new child
+        function on the FrameTree.
+        (-[WebCoreFrameBridge findFrameNamed:]): Change to call the new find
+        function on the FrameTree.
+        (-[WebCoreFrameBridge RenderObject::nodeInfoAtPoint:]): Change since the
+        contentPart function has been renamed to contentFrame.
+
+        * bridge/mac/WebCoreFrameNamespaces.h: Removed everything except for the
+        one method still used on the WebKit side, framesInNamespace:.
+        * bridge/mac/WebCoreFrameNamespaces.m: Renamed.
+        * bridge/mac/WebCoreFrameNamespaces.mm: Added. Reimplemented the
+        framesInNamespace method to use the namespace in WebCore::Page.
+
+        * bridge/mac/WebCorePageBridge.h: Added setGroupName and groupName.
+        * bridge/mac/WebCorePageBridge.mm:
+        (-[WebCorePageBridge setGroupName:]): Added. Calls through to Page.
+        (-[WebCorePageBridge groupName]): Ditto.
+
+        * khtml/ecma/kjs_html.cpp:
+        (KJS::HTMLDocument::namedItemGetter): Changed to call contentFrame by its new name.
+        (KJS::HTMLElement::frameGetter): Ditto.
+        (KJS::HTMLElement::iFrameGetter): Ditto.
+
+        * khtml/ecma/kjs_window.cpp:
+        (KJS::Window::getValueProperty): Changed to call FrameTree::childCount
+        instead of Frame::frames.
+        (KJS::Window::childFrameGetter): Changed to call FrameTree::child
+        instead of Frame::childFrameNamed.
+        (KJS::Window::namedFrameGetter): Changed to call FrameTree::find
+        instead of Frame::findFrame.
+        (KJS::Window::indexGetter): Changed to call FrameTree::child
+        instead of Frame::frames.
+        (KJS::Window::getOwnPropertySlot): Changed to call FrameTree::child,
+        FrameTree::find, and FrameTree::childCount instead of Frame::childFrameNamed,
+        and Frame::findFrame, and Frame::frames.
+        (KJS::WindowFunc::callAsFunction): Call FrameTree::find to check if the window
+        is already open when considering whether to block a pop-up.
+        (KJS::FrameArray::getValueProperty): Changed to call FrameTree::childCount
+        instead of Frame::frames.
+        (KJS::FrameArray::indexGetter): Changed to call FrameTree::child
+        instead of Frame::frames.
+        (KJS::FrameArray::nameGetter): Changed to call FrameTree::child
+        instead of Frame::findFrame.
+        (KJS::FrameArray::getOwnPropertySlot): Changed to call FrameTree::child,
+        and FrameTree::childCount instead of Frame::findFrame and Frame::frames.
+
+        * khtml/html/html_baseimpl.h:
+        * khtml/html/html_baseimpl.cpp:
+        (WebCore::HTMLFrameElementImpl::isURLAllowed): Changed to call Page::frameCount
+        instead of Frame::topLevelFrameCount.
+        (WebCore::HTMLFrameElementImpl::openURL): Changed to call FrameTree::child
+        instead of Frame::findFrame.
+        (WebCore::HTMLFrameElementImpl::attach): Changed to call Page::incrementFrameCount
+        instead of Frame::incrementFrameCount. Changed to call FrameTree::uniqueChildName
+        instead of Frame::requestFrameName.
+        (WebCore::HTMLFrameElementImpl::close): Changed to call Page::decrementFrameCount
+        instead of Frame::decrementFrameCount. Changed to call FrameTree::child
+        instead of Frame::findFrame.
+        (WebCore::HTMLFrameElementImpl::contentFrame): Renamed from contentPart. Also
+        changed to call FrameTree::child instead of Frame::findFrame.
+        (WebCore::HTMLFrameElementImpl::contentDocument): Updated for name change of
+        contentFrame from contentPart.
+        (WebCore::HTMLIFrameElementImpl::attach): Changed to call Page::incrementFrameCount
+        instead of Frame::incrementFrameCount. Changed to call FrameTree::uniqueChildName
+        instead of Frame::requestFrameName.
+
+        * rendering/render_frames.cpp: (WebCore::isURLAllowed): Changed to call Page::frameCount
+        instead of Frame::topLevelFrameCount.
+
+        * page/Frame.h: Removed frameNames, frames, childFrameNamed, findFrame, currentFrame,
+        frameExists, incrementFrameCount, decrementFrameCount, topLevelFrameCount,
+        generateFrameName, and requestFrameName functions.
+        * page/Frame.cpp: (WebCore::Frame::requestFrame): Changed to use FrameTree::child
+        instead of Frame::childFrameNamed.
+
+        * page/FrameTree.h: Changed name to an atomic string. Changed childCount to unsigned.
+        Added isDescendantOf, traverseNext, child, find, uniqueChildName.
+        * page/FrameTree.cpp:
+        (WebCore::FrameTree::setName): Changed to call uniqueChildName to handle name
+        duplication logic.
+        (WebCore::FrameTree::uniqueChildName): Added. Checks for duplication and generates
+        an appropriate frame name if there is a duplicate.
+        (WebCore::FrameTree::child): Added.
+        (WebCore::FrameTree::find): Added.
+        (WebCore::FrameTree::isDescendantOf): Added.
+        (WebCore::FrameTree::traverseNext): Added.
+
+        * page/Page.h: Added setGroupName, groupName, frameNamespace, incrementFrameCount,
+        decrementFrameCount, and frameCount.
+        * page/Page.cpp:
+        (WebCore::Page::Page): Initialize m_frameCount to 0.
+        (WebCore::Page::~Page): Call setGroupName to remove the page from any group it's in.
+        (WebCore::Page::setGroupName): Added.
+        (WebCore::Page::frameNamespace): Added.
+
+        * platform/win/TemporaryLinkStubs.cpp: Removed FrameWin::generateFrameName.
+
 2006-03-10  Justin Garcia  <justin.garcia@apple.com>
         
         Reviewed by darin, harrison
index 7908568dc8b05f133e2d635d687e1e5a1a238387..cb8b846985e28a92965c53e0e550048e03b9a1ae 100644 (file)
@@ -36,7 +36,7 @@
                6550B6A5099DF0270090D781 /* TextImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6550B69B099DF0270090D781 /* TextImpl.cpp */; };
                6550B6A6099DF0270090D781 /* TextImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = 6550B69C099DF0270090D781 /* TextImpl.h */; };
                6552E7AA096AA11B0006F248 /* WebCoreFrameNamespaces.h in Headers */ = {isa = PBXBuildFile; fileRef = 6552E7A8096AA11B0006F248 /* WebCoreFrameNamespaces.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               6552E7AB096AA11B0006F248 /* WebCoreFrameNamespaces.m in Sources */ = {isa = PBXBuildFile; fileRef = 6552E7A9096AA11B0006F248 /* WebCoreFrameNamespaces.m */; };
+               6552E7AB096AA11B0006F248 /* WebCoreFrameNamespaces.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6552E7A9096AA11B0006F248 /* WebCoreFrameNamespaces.mm */; };
                65743B52097076F8001E7CEF /* RenderSVGText.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65743B50097076F8001E7CEF /* RenderSVGText.cpp */; };
                65743B53097076F8001E7CEF /* RenderSVGText.h in Headers */ = {isa = PBXBuildFile; fileRef = 65743B51097076F8001E7CEF /* RenderSVGText.h */; };
                6576F9D609B2484A000041F7 /* TextEncodingMac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6576F9D509B2484A000041F7 /* TextEncodingMac.cpp */; };
                6550B69B099DF0270090D781 /* TextImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = TextImpl.cpp; sourceTree = "<group>"; };
                6550B69C099DF0270090D781 /* TextImpl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = TextImpl.h; sourceTree = "<group>"; };
                6552E7A8096AA11B0006F248 /* WebCoreFrameNamespaces.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = WebCoreFrameNamespaces.h; sourceTree = "<group>"; };
-               6552E7A9096AA11B0006F248 /* WebCoreFrameNamespaces.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = WebCoreFrameNamespaces.m; sourceTree = "<group>"; };
+               6552E7A9096AA11B0006F248 /* WebCoreFrameNamespaces.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = WebCoreFrameNamespaces.mm; sourceTree = "<group>"; };
                65743B50097076F8001E7CEF /* RenderSVGText.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = RenderSVGText.cpp; sourceTree = "<group>"; };
                65743B51097076F8001E7CEF /* RenderSVGText.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = RenderSVGText.h; sourceTree = "<group>"; };
                6576F9D509B2484A000041F7 /* TextEncodingMac.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = TextEncodingMac.cpp; sourceTree = "<group>"; };
                                654EC60F097778F500DAB52C /* WebCoreFrameBridge.h */,
                                654EC610097778F500DAB52C /* WebCoreFrameBridge.mm */,
                                6552E7A8096AA11B0006F248 /* WebCoreFrameNamespaces.h */,
-                               6552E7A9096AA11B0006F248 /* WebCoreFrameNamespaces.m */,
+                               6552E7A9096AA11B0006F248 /* WebCoreFrameNamespaces.mm */,
                                F587854C02DE375901EA4122 /* WebCoreFrameView.h */,
                                F5B2A52B02E22573018635CB /* WebCoreJavaScript.h */,
                                F5B2A52C02E22573018635CB /* WebCoreJavaScript.mm */,
                                A88AD51D0952499F001DD196 /* XLinkNamesWrapper.cpp in Sources */,
                                A88AD51E0952499F001DD196 /* SVGNamesWrapper.cpp in Sources */,
                                A88AD5AA09525131001DD196 /* SVGCSSStyleSelector.cpp in Sources */,
-                               6552E7AB096AA11B0006F248 /* WebCoreFrameNamespaces.m in Sources */,
+                               6552E7AB096AA11B0006F248 /* WebCoreFrameNamespaces.mm in Sources */,
                                A81655D5096BBEAC00601058 /* KCanvasMaskerQuartz.mm in Sources */,
                                A81655E4096BC13900601058 /* SVGMaskElementImpl.cpp in Sources */,
                                65743B52097076F8001E7CEF /* RenderSVGText.cpp in Sources */,
index 17f797249b732bccba82e8a9a27987525496a35b..b2ddde76b06803a02d61aa32179ae0ee89fb62ff 100644 (file)
@@ -316,8 +316,6 @@ public:
     virtual void print();
 
 protected:
-    virtual DOMString generateFrameName();
-
     virtual void startRedirectionTimer();
     virtual void stopRedirectionTimer();
     virtual void redirectionTimerFired(Timer<Frame>*);
index f0d35b154c4dda21a161d4c9af3ba27aff2264e5..0434216ccf91303321301cf034cd014506b9f9bd 100644 (file)
@@ -152,15 +152,6 @@ void MacFrame::freeClipboard()
         _dragClipboard->setAccessPolicy(KWQClipboard::Numb);
 }
 
-DOMString MacFrame::generateFrameName()
-{
-    KWQ_BLOCK_EXCEPTIONS;
-    return [_bridge generateFrameName];
-    KWQ_UNBLOCK_EXCEPTIONS;
-
-    return QString();
-}
-
 bool MacFrame::openURL(const KURL &url)
 {
     KWQ_BLOCK_EXCEPTIONS;
index b961094288a61fefac0157f6150f2744961ad227..7e72206df3106987a12ccf72528808a05f203caf 100644 (file)
 
 #include "Page.h"
 
+#ifdef __OBJC__
+@class WebCorePageBridge;
+#else
+class WebCorePageBridge;
+#endif
+
 namespace WebCore {
 
     class PageMac : public Page {
index 23c288d7a8eafbfa1d9619cce7cbd4af35baf9dc..d8f444bc39c7ff51bca3c855451165bb3cf42310 100644 (file)
@@ -172,8 +172,6 @@ typedef enum {
 {
     WebCoreMacFrame *m_frame;
     BOOL _shouldCreateRenderers;
-
-    NSString *_frameNamespace;
 }
 
 + (WebCoreFrameBridge *)bridgeForDOMDocument:(DOMDocument *)document;
@@ -187,8 +185,6 @@ typedef enum {
 
 - (void)setName:(NSString *)name;
 - (NSString *)name;
-/* Creates a name for an frame unnamed in the HTML.  It should produce repeatable results for loads of the same frameset. */
-- (NSString *)generateFrameName;
 
 - (WebCorePageBridge *)page;
 
@@ -212,9 +208,6 @@ typedef enum {
 - (WebCoreFrameBridge *)childFrameNamed:(NSString *)name;
 - (WebCoreFrameBridge *)findFrameNamed:(NSString *)name;
 
-- (void)setFrameNamespace:(NSString *)ns;
-- (NSString *)frameNamespace;
-
 - (void)provisionalLoadStarted;
 
 - (void)openURL:(NSURL *)URL reload:(BOOL)reload
index acac08ae994ae44be3e97ed4323d49f5fc62e91c..293b26536a82c13c98a73172fc40ca9d8b5ce745 100644 (file)
@@ -49,7 +49,6 @@
 #import "NodeImpl.h"
 #import "PageMac.h"
 #import "SelectionController.h"
-#import "WebCoreFrameNamespaces.h"
 #import "WebCorePageBridge.h"
 #import "WebCoreSettings.h"
 #import "WebCoreTextRendererFactory.h"
@@ -330,13 +329,7 @@ static inline WebCoreFrameBridge *bridge(Frame *frame)
 
 - (WebCoreFrameBridge *)childFrameNamed:(NSString *)name
 {
-    // FIXME: with a better data structure this could be O(1) instead of O(n) in number 
-    // of child frames
-    for (WebCoreFrameBridge *child = [self firstChild]; child; child = [child nextSibling])
-        if ([[child name] isEqualToString:name])
-            return child;
-
-    return nil;
+    return bridge(m_frame->tree()->child(name));
 }
 
 // Returns the last child of us and any children, or self
@@ -377,25 +370,6 @@ static inline WebCoreFrameBridge *bridge(Frame *frame)
     return nil;
 }
 
-- (void)setFrameNamespace:(NSString *)ns
-{
-    ASSERT(self == [[self page] mainFrame]);
-
-    if (ns != _frameNamespace){
-        [WebCoreFrameNamespaces removeFrame:self fromNamespace:_frameNamespace];
-        ns = [ns copy];
-        [_frameNamespace release];
-        _frameNamespace = ns;
-        [WebCoreFrameNamespaces addFrame:self toNamespace:_frameNamespace];
-    }
-}
-
-- (NSString *)frameNamespace
-{
-    ASSERT(self == [[self page] mainFrame]);
-    return _frameNamespace;
-}
-
 - (BOOL)_shouldAllowAccessFrom:(WebCoreFrameBridge *)source
 {
     // if no source frame, allow access
@@ -435,64 +409,9 @@ static inline WebCoreFrameBridge *bridge(Frame *frame)
     return NO;
 }
 
-- (WebCoreFrameBridge *)_descendantFrameNamed:(NSString *)name sourceFrame:(WebCoreFrameBridge *)source
-{
-    for (WebCoreFrameBridge *frame = self; frame; frame = [frame traverseNextFrameStayWithin:self])
-        // for security reasons, we do not want to even make frames visible to frames that
-        // can't access them 
-        if ([[frame name] isEqualToString:name] && [frame _shouldAllowAccessFrom:source])
-            return frame;
-
-    return nil;
-}
-
-- (WebCoreFrameBridge *)_frameInAnyWindowNamed:(NSString *)name sourceFrame:(WebCoreFrameBridge *)source
-{
-    ASSERT(self == [[self page] mainFrame]);
-
-    // Try this WebView first.
-    WebCoreFrameBridge *frame = [self _descendantFrameNamed:name sourceFrame:source];
-
-    if (frame != nil)
-        return frame;
-
-    // Try other WebViews in the same set
-
-    if ([self frameNamespace] != nil) {
-        NSEnumerator *enumerator = [WebCoreFrameNamespaces framesInNamespace:[self frameNamespace]];
-        WebCoreFrameBridge *searchFrame;
-        while ((searchFrame = [enumerator nextObject]))
-            frame = [searchFrame _descendantFrameNamed:name sourceFrame:source];
-    }
-
-    return frame;
-}
-
 - (WebCoreFrameBridge *)findFrameNamed:(NSString *)name
 {
-    // First, deal with 'special' names.
-    if ([name isEqualToString:@"_self"] || [name isEqualToString:@"_current"])
-        return self;
-    
-    if ([name isEqualToString:@"_top"])
-        return [[self page] mainFrame];
-    
-    if ([name isEqualToString:@"_parent"]) {
-        WebCoreFrameBridge *parent = [self parent];
-        return parent ? parent : self;
-    }
-    
-    if ([name isEqualToString:@"_blank"])
-        return nil;
-
-    // Search from this frame down.
-    WebCoreFrameBridge *frame = [self _descendantFrameNamed:name sourceFrame:self];
-
-    // Search in the main frame for this window then in others.
-    if (!frame)
-        frame = [[[self page] mainFrame] _frameInAnyWindowNamed:name sourceFrame:self];
-
-    return frame;
+    return bridge(m_frame->tree()->find(name));
 }
 
 + (NSArray *)supportedMIMETypes
@@ -1492,38 +1411,6 @@ static HTMLFormElementImpl *formElementFromDOMElement(DOMElement *element)
     return m_frame->tree()->name();
 }
 
-- (void)_addFramePathToString:(NSMutableString *)path
-{
-    NSString *name = [self name];
-    if ([name hasPrefix:@"<!--framePath "]) {
-        // we have a generated name - take the path from our name
-        NSRange ourPathRange = {14, [name length] - 14 - 3};
-        [path appendString:[name substringWithRange:ourPathRange]];
-    } else {
-        // we don't have a generated name - just add our simple name to the end
-        [[self parent] _addFramePathToString:path];
-        [path appendString:@"/"];
-        if (name)
-            [path appendString:name];
-    }
-}
-
-// Generate a repeatable name for a child about to be added to us.  The name must be
-// unique within the frame tree.  The string we generate includes a "path" of names
-// from the root frame down to us.  For this path to be unique, each set of siblings must
-// contribute a unique name to the path, which can't collide with any HTML-assigned names.
-// We generate this path component by index in the child list along with an unlikely frame name.
-- (NSString *)generateFrameName
-{
-    NSMutableString *path = [NSMutableString stringWithCapacity:256];
-    [path insertString:@"<!--framePath " atIndex:0];
-    [self _addFramePathToString:path];
-    // The new child's path component is all but the 1st char and the last 3 chars
-    // FIXME: Shouldn't this number be the index of this frame in its parent rather than the child count?
-    [path appendFormat:@"/<!--frame%d-->-->", [self childCount]];
-    return path;
-}
-
 - (NSURL *)URL
 {
     return m_frame->url().getNSURL();
@@ -1987,7 +1874,7 @@ static HTMLFormElementImpl *formElementFromDOMElement(DOMElement *element)
 }
 
 // Determines whether whitespace needs to be added around aString to preserve proper spacing and
-// punctuation when it’s inserted into the receiver’s text over charRange. Returns by reference
+// punctuation when itÕs inserted into the receiverÕs text over charRange. Returns by reference
 // in beforeString and afterString any whitespace that should be added, unless either or both are
 // nil. Both are returned as nil if aString is nil or if smart insertion and deletion are disabled.
 - (void)smartInsertForString:(NSString *)pasteString replacingRange:(DOMRange *)rangeToReplace beforeString:(NSString **)beforeString afterString:(NSString **)afterString
@@ -2575,8 +2462,8 @@ static HTMLFormElementImpl *formElementFromDOMElement(DOMElement *element)
         widget = static_cast<RenderWidget *>(n->renderer())->widget();
         if (!widget || !widget->isFrameView())
             break;
-        Frame *kpart = static_cast<HTMLFrameElementImpl *>(n)->contentPart();
-        if (!kpart || !static_cast<MacFrame *>(kpart)->renderer())
+        Frame* frame = static_cast<HTMLFrameElementImpl *>(n)->contentFrame();
+        if (!frame || !frame->renderer())
             break;
         int absX, absY;
         n->renderer()->absolutePosition(absX, absY, true);
@@ -2585,7 +2472,7 @@ static HTMLFormElementImpl *formElementFromDOMElement(DOMElement *element)
         widgetPoint.setY(widgetPoint.y() - absY + view->contentsY());
 
         RenderObject::NodeInfo widgetNodeInfo(true, true);
-        static_cast<MacFrame *>(kpart)->renderer()->layer()->hitTest(widgetNodeInfo, widgetPoint.x(), widgetPoint.y());
+        frame->renderer()->layer()->hitTest(widgetNodeInfo, widgetPoint.x(), widgetPoint.y());
         nodeInfo = widgetNodeInfo;
     }
     
index ddd8d58b828d3929082ce5529b2f7d09f16780bb..9659c575eb075bb9185e1a703607bf9fa360f35c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2005 Apple Computer, Inc.  All rights reserved.
+ * Copyright (C) 2005, 2006 Apple Computer, Inc.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 #import <Foundation/Foundation.h>
 
-@class WebCoreFrameBridge;
-
 @interface WebCoreFrameNamespaces : NSObject
-+ (void)addFrame:(WebCoreFrameBridge *)frame toNamespace:(NSString *)name;
-+ (void)removeFrame:(WebCoreFrameBridge *)frame fromNamespace:(NSString *)name;
 + (NSEnumerator *)framesInNamespace:(NSString *)name;
 @end
similarity index 54%
rename from WebCore/bridge/mac/WebCoreFrameNamespaces.m
rename to WebCore/bridge/mac/WebCoreFrameNamespaces.mm
index 93257dc5d7b314efdd5923681bf27545b4c70604..9f34e09e90875121ef2f65c7df3e075429fe9239 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2005 Apple Computer, Inc.  All rights reserved.
+ * Copyright (C) 2005, 2006 Apple Computer, Inc.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include "config.h"
+#import "config.h"
 #import "WebCoreFrameNamespaces.h"
 
-static CFSetCallBacks NonRetainingSetCallbacks = {
-0,
-NULL,
-NULL,
-CFCopyDescription,
-CFEqual,
-CFHash
-};
+#import "PageMac.h"
 
-@implementation WebCoreFrameNamespaces
-
-NSMutableDictionary *namespaces = nil;
-
-+(void)addFrame:(WebCoreFrameBridge *)frame toNamespace:(NSString *)name
-{
-    if (!name)
-        return;
-
-    if (!namespaces)
-        namespaces = [[NSMutableDictionary alloc] init];
-
-    CFMutableSetRef namespace = (CFMutableSetRef)[namespaces objectForKey:name];
-
-    if (!namespace) {
-        namespace = CFSetCreateMutable(NULL, 0, &NonRetainingSetCallbacks);
-        [namespaces setObject:(id)namespace forKey:name];
-        CFRelease(namespace);
-    }
-    
-    CFSetSetValue(namespace, frame);
-}
-
-+(void)removeFrame:(WebCoreFrameBridge *)frame fromNamespace:(NSString *)name
-{
-    if (!name)
-        return;
-
-    CFMutableSetRef namespace = (CFMutableSetRef)[namespaces objectForKey:name];
-
-    if (!namespace)
-        return;
+using namespace WebCore;
 
-    CFSetRemoveValue(namespace, frame);
-
-    if (CFSetGetCount(namespace) == 0)
-        [namespaces removeObjectForKey:name];
-}
+@implementation WebCoreFrameNamespaces
 
-+(NSEnumerator *)framesInNamespace:(NSString *)name;
++ (NSEnumerator *)framesInNamespace:(NSString *)name;
 {
-    if (!name)
+    const HashSet<Page*>* set = Page::frameNamespace(name);
+    if (!set)
         return [[[NSEnumerator alloc] init] autorelease];
-
-    CFMutableSetRef namespace = (CFMutableSetRef)[namespaces objectForKey:name];
-
-    if (!namespace)
-        return [[[NSEnumerator alloc] init] autorelease];
-    
-    return [(NSSet *)namespace objectEnumerator];
+    NSMutableArray* array = [[NSMutableArray alloc] initWithCapacity:set->size()];
+    HashSet<Page*>::const_iterator end = set->end();
+    for (HashSet<Page*>::const_iterator it = set->begin(); it != end; ++it) {
+        [array addObject:Mac(*it)->bridge()];
+    }
+    NSEnumerator* enumerator = [array objectEnumerator];
+    [array release];
+    return enumerator;
 }
 
 @end
index 92405f01a857c6a8503db54845237bf4af8826ea..c1c9a98f758e4f6e22e005f2d58b2ff2538cafd4 100644 (file)
@@ -54,6 +54,9 @@ class WebCoreFrameBridge;
 
 - (WebCoreFrameBridge *)mainFrame;
 
+- (void)setGroupName:(NSString *)groupName;
+- (NSString *)groupName;
+
 @end
 
 // The WebCorePageBridge protocol contains methods for use by the WebCore side of the bridge.
index b69335f490fcd0f7e63b1e626d831f9bcf620b61..66fda3d7280a3d910e65f2ecf273ffa63f4c01a0 100644 (file)
@@ -89,6 +89,16 @@ static void initializeLoggingChannelsIfNecessary()
     return Mac(_page->mainFrame())->bridge();
 }
 
+- (void)setGroupName:(NSString *)groupName
+{
+    _page->setGroupName(groupName);
+}
+
+- (NSString *)groupName
+{
+    return _page->groupName();
+}
+
 @end
 
 @implementation WebCorePageBridge (WebCoreInternalUse)
index 5088afcc088e307843e05cdc63d5733be77cff14..22e0d2e6e049dba9a479cdb459a58a7242e07c64 100644 (file)
@@ -208,12 +208,10 @@ JSValue *HTMLDocument::namedItemGetter(ExecState *exec, JSObject *originalObject
   RefPtr<DOM::HTMLCollectionImpl> collection = doc.documentNamedItems(name);
 
   if (collection->length() == 1) {
-    NodeImpl *node = collection->firstItem();
+    NodeImplnode = collection->firstItem();
     Frame *frame;
-    if (node->hasTagName(iframeTag) && 
-        (frame = static_cast<DOM::HTMLIFrameElementImpl *>(node)->contentPart()))
+    if (node->hasTagName(iframeTag) && (frame = static_cast<DOM::HTMLIFrameElementImpl *>(node)->contentFrame()))
       return Window::retrieve(frame);
-
     return getDOMNode(exec, node);
   }
 
@@ -2091,7 +2089,7 @@ JSValue *HTMLElement::frameGetter(ExecState* exec, int token) const
         case FrameContentDocument: return checkNodeSecurity(exec,frameElement.contentDocument()) ? 
                                           getDOMNode(exec, frameElement.contentDocument()) : jsUndefined();
         case FrameContentWindow:   return checkNodeSecurity(exec,frameElement.contentDocument())
-                                        ? Window::retrieve(frameElement.contentPart())
+                                        ? Window::retrieve(frameElement.contentFrame())
                                         : jsUndefined();
         case FrameFrameBorder:     return jsString(frameElement.frameBorder());
         case FrameLongDesc:        return jsString(frameElement.longDesc());
@@ -2117,8 +2115,8 @@ JSValue *HTMLElement::iFrameGetter(ExecState* exec, int token) const
         case IFrameDocument: // non-standard, mapped to contentDocument
         case IFrameContentDocument: return checkNodeSecurity(exec,iFrame.contentDocument()) ? 
                                       getDOMNode(exec, iFrame.contentDocument()) : jsUndefined();
-        case IFrameContentWindow:       return checkNodeSecurity(exec,iFrame.contentDocument()) 
-                                        ? Window::retrieve(iFrame.contentPart())
+        case IFrameContentWindow:   return checkNodeSecurity(exec,iFrame.contentDocument()) 
+                                        ? Window::retrieve(iFrame.contentFrame())
                                         : jsUndefined();
         case IFrameFrameBorder:     return jsString(iFrame.frameBorder());
         case IFrameHeight:          return jsString(iFrame.height());
index a2ff7749071873cd7eff30cff605432f584e224e..b9d2fd8eb1674fc8b4c79ad6f2246eea6411037a 100644 (file)
@@ -699,7 +699,7 @@ JSValue *Window::getValueProperty(ExecState *exec, int token) const
         return jsUndefined();
       return jsNumber(m_frame->view()->visibleWidth());
     case Length:
-      return jsNumber(m_frame->frames().count());
+      return jsNumber(m_frame->tree()->childCount());
     case _Location:
       return location();
     case Name:
@@ -890,27 +890,23 @@ JSValue *Window::getValueProperty(ExecState *exec, int token) const
    return jsUndefined();
 }
 
-JSValue *Window::childFrameGetter(ExecState *exec, JSObject *originalObject, const Identifier& propertyName, const PropertySlot& slot)
+JSValue* Window::childFrameGetter(ExecState*, JSObject*, const Identifier& propertyName, const PropertySlot& slot)
 {
-  Window *thisObj = static_cast<Window *>(slot.slotBase());
-  return retrieve(thisObj->m_frame->childFrameNamed(propertyName.qstring()));
+    return retrieve(static_cast<Window*>(slot.slotBase())->m_frame->tree()->child(AtomicString(propertyName.domString())));
 }
 
-JSValue *Window::namedFrameGetter(ExecState *exec, JSObject *originalObject, const Identifier& propertyName, const PropertySlot& slot)
+JSValue* Window::namedFrameGetter(ExecState*, JSObject*, const Identifier& propertyName, const PropertySlot& slot)
 {
-  Window *thisObj = static_cast<Window *>(slot.slotBase());
-  return retrieve(thisObj->m_frame->findFrame(propertyName.qstring()));
+    // FIXME: I'm pretty sure this is wrong, because it's the same as the function above.
+    // There's no point in checking for child frames twice. I suspect this should be using
+    // find instead of "child". But I don't want to change the behavior without testing,
+    // so I'm leaving this as-is for now.
+    return retrieve(static_cast<Window*>(slot.slotBase())->m_frame->tree()->child(AtomicString(propertyName.domString())));
 }
 
-JSValue* Window::indexGetter(ExecState* exec, JSObject* originalObject, const Identifier& propertyName, const PropertySlot& slot)
+JSValue* Window::indexGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot& slot)
 {
-  Window* thisObj = static_cast<Window*>(slot.slotBase());
-  
-  QPtrList<Frame> frames = thisObj->m_frame->frames();
-  Frame* frame = frames.at(slot.index());
-  ASSERT(frame);
-
-  return retrieve(frame);
+    return retrieve(static_cast<Window*>(slot.slotBase())->m_frame->tree()->child(slot.index()));
 }
 
 JSValue *Window::namedItemGetter(ExecState *exec, JSObject *originalObject, const Identifier& propertyName, const PropertySlot& slot)
@@ -960,8 +956,8 @@ bool Window::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName,
   // naming frames things that conflict with window properties that
   // are in Moz but not IE. Since we have some of these, we have to do
   // it the Moz way.
-  Frame *childFrame = m_frame->childFrameNamed(propertyName.qstring());
-  if (childFrame) {
+  AtomicString atomicPropertyName = AtomicString(propertyName.domString());
+  if (m_frame->tree()->child(atomicPropertyName)) {
     slot.setCustom(this, childFrameGetter);
     return true;
   }
@@ -990,32 +986,27 @@ bool Window::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName,
     return true;
   }
 
-  Frame *kp = m_frame->findFrame(propertyName.qstring());
-  if (kp) {
+  // FIXME: I'm pretty sure this is wrong, because it's the same as childFrameGetter above.
+  // There's no point in checking for child frames twice. I suspect this should be using
+  // find instead of "child". But I don't want to change the behavior without testing,
+  // so I'm leaving this as-is for now.
+  if (m_frame->tree()->child(atomicPropertyName)) {
     slot.setCustom(this, namedFrameGetter);
     return true;
   }
 
   // allow window[1] or parent[1] etc. (#56983)
   bool ok;
-  unsigned int i = propertyName.toArrayIndex(&ok);
-  if (ok) {
-    QPtrList<Frame> frames = m_frame->frames();
-    unsigned int len = frames.count();
-    if (i < len) {
-      Frame* frame = frames.at(i);
-      if (frame) {
-        slot.setCustomIndex(this, i, indexGetter);
-        return true;
-      }
-    }
+  unsigned i = propertyName.toArrayIndex(&ok);
+  if (ok && i < m_frame->tree()->childCount()) {
+    slot.setCustomIndex(this, i, indexGetter);
+    return true;
   }
 
   // allow shortcuts like 'Image1' instead of document.images.Image1
   DocumentImpl *doc = m_frame->document();
   if (isSafeScript(exec) && doc && doc->isHTMLDocument()) {
-    AtomicString name = propertyName.domString().impl();
-    if (static_cast<HTMLDocumentImpl *>(doc)->hasNamedItem(name) || doc->getElementById(name)) {
+    if (static_cast<HTMLDocumentImpl*>(doc)->hasNamedItem(atomicPropertyName) || doc->getElementById(atomicPropertyName)) {
       slot.setCustom(this, namedItemGetter);
       return true;
     }
@@ -1583,9 +1574,9 @@ JSValue *WindowFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const Li
   }
   case Window::Open:
   {
-      QString frameName = args[1]->isUndefinedOrNull() ? QString("_blank") : args[1]->toString(exec).qstring();
-      if (!allowPopUp(exec, window)
-            && !(frameName == "_top" || frameName == "_parent" || frameName == "_self" || frame->findFrame(frameName)))
+      AtomicString frameName = args[1]->isUndefinedOrNull()
+        ? "_blank" : AtomicString(args[1]->toString(exec).domString());
+      if (!allowPopUp(exec, window) && !frame->tree()->find(frameName))
           return jsUndefined();
       
       WindowArgs windowArgs;
@@ -1600,7 +1591,7 @@ JSValue *WindowFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const Li
           url = activePart->document()->completeURL(str.qstring());
 
       URLArgs uargs;
-      uargs.frameName = frameName;
+      uargs.frameName = frameName.qstring();
       if (uargs.frameName == "_top") {
           while (frame->tree()->parent())
               frame = frame->tree()->parent();
@@ -2023,11 +2014,8 @@ location        FrameArray::Location    DontDelete|ReadOnly
 JSValue *FrameArray::getValueProperty(ExecState *exec, int token)
 {
   switch (token) {
-  case Length: {
-    QPtrList<Frame> frames = m_frame->frames();
-    unsigned int len = frames.count();
-    return jsNumber(len);
-  }
+  case Length:
+    return jsNumber(m_frame->tree()->childCount());
   case Location:
     // non-standard property, but works in NS and IE
     if (JSObject *obj = Window::retrieveWindow(m_frame))
@@ -2039,26 +2027,14 @@ JSValue *FrameArray::getValueProperty(ExecState *exec, int token)
   }
 }
 
-JSValue *FrameArray::indexGetter(ExecState *exec, JSObject *originalObject, const Identifier& propertyName, const PropertySlot& slot)
+JSValue* FrameArray::indexGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot& slot)
 {
-  FrameArray *thisObj = static_cast<FrameArray *>(slot.slotBase());
-  Frame* frame = thisObj->m_frame->frames().at(slot.index());
-
-  if (frame)
-    return Window::retrieve(frame);
-
-  return jsUndefined();
+    return Window::retrieve(static_cast<FrameArray*>(slot.slotBase())->m_frame->tree()->child(slot.index()));
 }
-
-JSValue *FrameArray::nameGetter(ExecState *exec, JSObject *originalObject, const Identifier& propertyName, const PropertySlot& slot)
+  
+JSValue* FrameArray::nameGetter(ExecState*, JSObject*, const Identifier& propertyName, const PropertySlot& slot)
 {
-  FrameArray *thisObj = static_cast<FrameArray *>(slot.slotBase());
-  Frame* frame = thisObj->m_frame->findFrame(propertyName.qstring());
-
-  if (frame)
-    return Window::retrieve(frame);
-
-  return jsUndefined();
+    return Window::retrieve(static_cast<FrameArray*>(slot.slotBase())->m_frame->tree()->child(AtomicString(propertyName.domString())));
 }
 
 bool FrameArray::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
@@ -2075,15 +2051,14 @@ bool FrameArray::getOwnPropertySlot(ExecState *exec, const Identifier& propertyN
   }
 
   // check for the name or number
-  Frame* frame = m_frame->findFrame(propertyName.qstring());
-  if (frame) {
+  if (m_frame->tree()->child(AtomicString(propertyName.domString()))) {
     slot.setCustom(this, nameGetter);
     return true;
   }
 
   bool ok;
-  unsigned int i = propertyName.toArrayIndex(&ok);
-  if (ok && i < m_frame->frames().count()) {
+  unsigned i = propertyName.toArrayIndex(&ok);
+  if (ok && i < m_frame->tree()->childCount()) {
     slot.setCustomIndex(this, i, indexGetter);
     return true;
   }
index ea3eb27aa61a52aaacd187f468bf50bdca6d9faf..900712d53804932f271be03effb278f4dbd78a86 100644 (file)
@@ -5,7 +5,7 @@
  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
  *           (C) 2000 Simon Hausmann (hausmann@kde.org)
  *           (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004 Apple Computer, Inc.
+ * Copyright (C) 2004, 2006 Apple Computer, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
 #include "config.h"
 #include "html_baseimpl.h"
 
-#include "html/html_documentimpl.h"
-
-#include "FrameView.h"
+#include "EventNames.h"
 #include "Frame.h"
 #include "FrameTree.h"
-
-#include "rendering/render_frames.h"
-#include "css/cssstyleselector.h"
-#include "css/css_stylesheetimpl.h"
+#include "FrameView.h"
+#include "KURL.h"
+#include "Page.h"
+#include "PlatformString.h"
+#include "css_stylesheetimpl.h"
+#include "csshelper.h"
 #include "cssproperties.h"
+#include "cssstyleselector.h"
 #include "cssvalues.h"
-#include "css/csshelper.h"
-#include "loader.h"
-#include "PlatformString.h"
 #include "dom2_eventsimpl.h"
-#include "EventNames.h"
+#include "html_documentimpl.h"
 #include "htmlnames.h"
-
-#include <KURL.h>
+#include "loader.h"
+#include "render_frames.h"
 
 namespace WebCore {
+
 using namespace EventNames;
 using namespace HTMLNames;
 
@@ -299,7 +298,7 @@ bool HTMLFrameElementImpl::isURLAllowed(const AtomicString &URLString) const
     // FIXME: This limit could be higher, but WebKit has some
     // algorithms that happen while loading which appear to be N^2 or
     // worse in the number of frames
-    if (w->frame()->topLevelFrameCount() >= 200) {
+    if (w->frame()->page()->frameCount() >= 200) {
         return false;
     }
 
@@ -324,23 +323,19 @@ void HTMLFrameElementImpl::openURL()
 {
     DocumentImpl *d = getDocument();
     FrameView *w = d ? d->view() : 0;
-    if (!w) {
+    if (!w)
         return;
-    }
     
     AtomicString relativeURL = m_URL;
-    if (relativeURL.isEmpty()) {
+    if (relativeURL.isEmpty())
         relativeURL = "about:blank";
-    }
 
     // Load the frame contents.
-    Frame *frame = w->frame();
-    Frame *framePart = frame->findFrame(m_name.qstring());
-    if (framePart) {
-        framePart->openURL(getDocument()->completeURL(relativeURL.qstring()));
-    } else {
-        frame->requestFrame(static_cast<RenderFrame *>(renderer()), relativeURL.qstring(), m_name.qstring());
-    }
+    Frame* parentFrame = w->frame();
+    if (Frame* childFrame = parentFrame->tree()->child(m_name))
+        childFrame->openURL(getDocument()->completeURL(relativeURL.qstring()));
+    else
+        parentFrame->requestFrame(static_cast<RenderFrame *>(renderer()), relativeURL.qstring(), m_name.qstring());
 }
 
 
@@ -421,21 +416,18 @@ void HTMLFrameElementImpl::attach()
     if (!renderer())
         return;
 
-    Frame *frame = getDocument()->frame();
+    Frameframe = getDocument()->frame();
 
     if (!frame)
         return;
 
-    frame->incrementFrameCount();
+    frame->page()->incrementFrameCount();
     
     AtomicString relativeURL = m_URL;
-    if (relativeURL.isEmpty()) {
+    if (relativeURL.isEmpty())
         relativeURL = "about:blank";
-    }
 
-    // we need a unique name for every frame in the frameset. Hope that's unique enough.
-    if (m_name.isEmpty() || frame->frameExists(m_name.qstring()))
-        m_name = AtomicString(frame->requestFrameName());
+    m_name = frame->tree()->uniqueChildName(m_name);
 
     // load the frame contents
     frame->requestFrame(static_cast<RenderFrame*>(renderer()), relativeURL.qstring(), m_name.qstring());
@@ -443,13 +435,11 @@ void HTMLFrameElementImpl::attach()
 
 void HTMLFrameElementImpl::close()
 {
-    Frame *frame = getDocument()->frame();
-
+    Frame* frame = getDocument()->frame();
     if (renderer() && frame) {
-        frame->decrementFrameCount();
-        Frame *framePart = frame->findFrame(m_name.qstring());
-        if (framePart)
-            framePart->frameDetached();
+        frame->page()->decrementFrameCount();
+        if (Frame* childFrame = frame->tree()->child(m_name))
+            childFrame->frameDetached();
     }
 }
 
@@ -513,26 +503,22 @@ void HTMLFrameElementImpl::setFocus(bool received)
         renderFrame->widget()->clearFocus();
 }
 
-Frame* HTMLFrameElementImpl::contentPart() const
+Frame* HTMLFrameElementImpl::contentFrame() const
 {
     // Start with the part that contains this element, our ownerDocument.
-    Frame* ownerDocumentPart = getDocument()->frame();
-    if (!ownerDocumentPart) {
+    Frame* parentFrame = getDocument()->frame();
+    if (!parentFrame)
         return 0;
-    }
 
     // Find the part for the subframe that this element represents.
-    return ownerDocumentPart->findFrame(m_name.qstring());
+    return parentFrame->tree()->child(m_name);
 }
 
 DocumentImpl* HTMLFrameElementImpl::contentDocument() const
 {
-    Frame *frame = contentPart();
-    if (!frame) {
+    Frame* frame = contentFrame();
+    if (!frame)
         return 0;
-    }
-
-    // Return the document for that part, which is our contentDocument.
     return frame->document();
 }
 
@@ -916,16 +902,13 @@ void HTMLIFrameElementImpl::attach()
     m_name = getAttribute(nameAttr);
     if (m_name.isNull())
         m_name = getAttribute(idAttr);
-    
-    HTMLElementImpl::attach();
 
-    Frame *frame = getDocument()->frame();
-    if (renderer() && frame) {
-        // we need a unique name for every frame in the frameset. Hope that's unique enough.
-        frame->incrementFrameCount();
-        if (m_name.isEmpty() || frame->frameExists(m_name.qstring()))
-            m_name = AtomicString(frame->requestFrameName());
+    HTMLElementImpl::attach();
 
+    Frame* parentFrame = getDocument()->frame();
+    if (renderer() && parentFrame) {
+        parentFrame->page()->incrementFrameCount();
+        m_name = parentFrame->tree()->uniqueChildName(m_name);
         static_cast<RenderPartObject*>(renderer())->updateWidget();
         needWidgetUpdate = false;
     }
index 5e58145c0f21bea21894b51051a133b5a782f2de..ecd0ee194a43c77d55a3f99b45ee3023224ab356 100644 (file)
@@ -110,7 +110,7 @@ public:
     virtual bool isFocusable() const;
     virtual void setFocus(bool);
 
-    Frame* contentPart() const;
+    Frame* contentFrame() const;
     DocumentImpl* contentDocument() const;
     
     virtual bool isURLAttribute(AttributeImpl *attr) const;
index 73748def64eda701326da85a5d56f14642a099fc..eeaaa7f2f1a4d63af98c72a887422ee8e956c1da 100644 (file)
@@ -1355,11 +1355,6 @@ void Frame::urlSelected(const QString &url, const QString& _target, const URLArg
   urlSelected(cURL, argsCopy);
 }
 
-DOMString Frame::requestFrameName()
-{
-    return generateFrameName();
-}
-
 bool Frame::requestFrame(RenderPart* renderer, const QString& _url, const QString& frameName)
 {
     // Support for <frame src="javascript:string">
@@ -1371,7 +1366,7 @@ bool Frame::requestFrame(RenderPart* renderer, const QString& _url, const QStrin
     } else
         url = completeURL(_url);
 
-    Frame* frame = childFrameNamed(frameName);
+    Frame* frame = tree()->child(frameName);
     if (frame) {
         URLArgs args;
         args.metaData().set("referrer", d->m_referrer);
@@ -1591,21 +1586,6 @@ void Frame::childCompleted(bool complete)
     checkCompleted();
 }
 
-Frame* Frame::findFrame(const QString& f)
-{
-    // FIXME: this only finds child frames, is it ever appropriate to use this?
-    // ### http://www.w3.org/TR/html4/appendix/notes.html#notes-frames
-    for (Frame* child = tree()->firstChild(); child; child = child->tree()->nextSibling())
-        if (child->tree()->name() == f)
-            return child;
-    return 0;
-}
-
-bool Frame::frameExists(const QString& frameName)
-{
-    return findFrame(frameName);
-}
-
 int Frame::zoomFactor() const
 {
   return d->m_zoomFactor;
@@ -1680,34 +1660,6 @@ void Frame::reparseConfiguration()
   if(d->m_doc) d->m_doc->updateStyleSelector();
 }
 
-QStringList Frame::frameNames() const
-{
-  QStringList res;
-
-  for (Frame* child = tree()->firstChild(); child; child = child->tree()->nextSibling())
-      res += child->tree()->name().qstring();
-
-  return res;
-}
-
-QPtrList<Frame> Frame::frames() const
-{
-  QPtrList<Frame> res;
-
-  for (Frame* child = tree()->firstChild(); child; child = child->tree()->nextSibling())
-      res.append(child);
-
-  return res;
-}
-
-Frame* Frame::childFrameNamed(const QString& name) const
-{
-    for (Frame* child = tree()->firstChild(); child; child = child->tree()->nextSibling())
-        if (child->tree()->name() == name)
-            return child;
-    return 0;
-}
-
 bool Frame::shouldDragAutoNode(NodeImpl *node, int x, int y) const
 {
     // No KDE impl yet
@@ -2138,30 +2090,6 @@ bool Frame::restored() const
   return d->m_restored;
 }
 
-void Frame::incrementFrameCount()
-{
-    // FIXME: this should be in Page
-    frameCount++;
-    if (tree()->parent())
-        tree()->parent()->incrementFrameCount();
-}
-
-void Frame::decrementFrameCount()
-{
-    // FIXME: this should be in Page
-    frameCount--;
-    if (tree()->parent())
-        tree()->parent()->decrementFrameCount();
-}
-
-int Frame::topLevelFrameCount()
-{
-    // FIXME: this should be in Page
-    if (tree()->parent())
-        return tree()->parent()->topLevelFrameCount();
-    return frameCount;
-}
-
 bool Frame::tabsToLinks() const
 {
     return true;
index bc41b1f3355bf5b84679f77b8d113c137dcff871..174b0b3dcb8270d19bb56dc1b7b60e8e3582cb87 100644 (file)
@@ -502,40 +502,9 @@ public:
    */
   void clearTypingStyle();
 
-  virtual void tokenizerProcessedData() {};
+  virtual void tokenizerProcessedData() {}
 
-  const KHTMLSettings *settings() const;
-
-  /**
-   * Returns a list of names of all frame (including iframe) objects of
-   * the current document. Note that this method is not working recursively
-   * for sub-frames.
-   */
-  QStringList frameNames() const;
-
-  QPtrList<Frame> frames() const;
-
-  Frame *childFrameNamed(const QString &name) const;
-
-  /**
-   * Finds a frame by name. Returns 0L if frame can't be found.
-   */
-  Frame *findFrame( const QString &f );
-
-  /**
-   * Return the current frame (the one that has focus)
-   * Not necessarily a direct child of ours, framesets can be nested.
-   * Returns "this" if this part isn't a frameset.
-   */
-  Frame* currentFrame() const;
-
-  /**
-   * Returns whether a frame with the specified name is exists or not.
-   * In contrary to the @ref findFrame method this one also returns true
-   * if the frame is defined but no displaying component has been
-   * found/loaded, yet.
-   */
-  bool frameExists( const QString &frameName );
+  const KHTMLSettings* settings() const;
 
   void setJSStatusBarText(const String&);
   void setJSDefaultStatusBarText(const String&);
@@ -565,10 +534,6 @@ public:
 
   bool restored() const;
 
-  void incrementFrameCount();
-  void decrementFrameCount();
-  int topLevelFrameCount();
-
   // Editing operations.
   // Not clear if these will be wanted in Frame by KDE,
   // but for now these bridge so we don't have to pepper the
@@ -690,7 +655,6 @@ public:
   virtual bool lastEventIsMouseUp() const = 0;
   virtual QString overrideMediaType() const = 0;
 protected:
-  virtual String generateFrameName() = 0;
   virtual Plugin* createPlugin(const KURL& url, const QStringList& paramNames, const QStringList& paramValues, const QString& mimeType) = 0;
   virtual Frame* createFrame(const KURL& url, const QString& name, RenderPart* renderer, const String& referrer) = 0;
   virtual ObjectContentType objectContentType(const KURL& url, const QString& mimeType) = 0;
@@ -753,7 +717,6 @@ public:
   bool requestObject(RenderPart *frame, const QString &url, const QString &frameName,
                      const QString &serviceType, const QStringList &paramNames, const QStringList &paramValues);
   bool requestFrame(RenderPart *frame, const QString &url, const QString &frameName);
-  String requestFrameName();
 
   DocumentImpl *document() const;
   void setDocument(DocumentImpl* newDoc);
index 007bbe7591b4c0d77debab60186029afaa52dd6c..09f4ac288d7a890c91f065c5f1a52f2a1be79a41 100644 (file)
 #include "config.h"
 #include "FrameTree.h"
 
-#include <kxmlcore/Assertions.h>
 #include "Frame.h"
 #include "NodeImpl.h"
-
+#include "Page.h"
 #include <algorithm>
+#include <kxmlcore/Assertions.h>
+#include <kxmlcore/Vector.h>
 
 using std::swap;
 
 namespace WebCore {
 
+// This belongs in some header file where multiple clients can share it.
+#if WIN32
+int snprintf(char* str, size_t size, const char* format, ...)
+{
+    va_list args;
+    va_start(args, format);
+    int result = vsnprintf_s(str, size, _TRUNCATE, format, args);
+    va_end(args);
+    return result;
+}
+#endif
+
 FrameTree::~FrameTree()
 {
     for (Frame* child = firstChild(); child; child = child->tree()->nextSibling())
         child->detachFromView();
 }
 
-void FrameTree::setName(const DOMString& name) 
-{ 
-    DOMString n = name;
-        
-    // FIXME: is the blank rule needed or useful?
-    if (parent() && (name.isEmpty() || parent()->frameExists(name.qstring()) || name == "_blank"))
-        n = parent()->requestFrameName();
-    
-    m_name = n;
+void FrameTree::setName(const AtomicString& name) 
+{
+    if (!parent()) {
+        m_name = name;
+        return;
+    }
+    m_name = AtomicString(); // Remove our old frame name so it's not considered in uniqueChildName.
+    m_name = parent()->tree()->uniqueChildName(name);
 }
 
 void FrameTree::appendChild(PassRefPtr<Frame> child)
@@ -86,4 +98,152 @@ void FrameTree::removeChild(Frame* child)
     m_childCount--;
 }
 
+AtomicString FrameTree::uniqueChildName(const AtomicString& requestedName) const
+{
+    if (!requestedName.isEmpty() && !child(requestedName) && requestedName != "_blank")
+        return requestedName;
+
+    // Create a repeatable name for a child about to be added to us. The name must be
+    // unique within the frame tree. The string we generate includes a "path" of names
+    // from the root frame down to us. For this path to be unique, each set of siblings must
+    // contribute a unique name to the path, which can't collide with any HTML-assigned names.
+    // We generate this path component by index in the child list along with an unlikely
+    // frame name that can't be set in HTML because it collides with comment syntax.
+
+    const char framePathPrefix[] = "<!--framePath ";
+    const int framePathPrefixLength = 14;
+    const int framePathSuffixLength = 3;
+
+    // Find the nearest parent that has a frame with a path in it.
+    Vector<Frame*, 16> chain;
+    Frame* frame;
+    for (frame = m_thisFrame; frame; frame = frame->tree()->parent()) {
+        if (frame->tree()->name().startsWith(framePathPrefix))
+            break;
+        chain.append(frame);
+    }
+    String name;
+    name += framePathPrefix;
+    if (frame)
+        name += frame->tree()->name().domString().substring(framePathPrefixLength,
+            frame->tree()->name().length() - framePathPrefixLength - framePathSuffixLength);
+    for (int i = chain.size() - 1; i >= 0; --i) {
+        frame = chain[i];
+        name += "/";
+        name += frame->tree()->name();
+    }
+
+    // Suffix buffer has more than enough space for:
+    //     10 characters before the number
+    //     a number (3 digits for the highest this gets in practice, 20 digits for the largest 64-bit integer)
+    //     6 characters after the number
+    //     trailing null byte
+    // But we still use snprintf just to be extra-safe.
+    char suffix[40];
+    snprintf(suffix, sizeof(suffix), "/<!--frame%u-->-->", childCount());
+
+    name += suffix;
+
+    return AtomicString(name);
+}
+
+Frame* FrameTree::child(unsigned index) const
+{
+    Frame* result = firstChild();
+    for (unsigned i = 0; result && i != index; ++i)
+        result = result->tree()->nextSibling();
+    return result;
+}
+
+Frame* FrameTree::child(const AtomicString& name) const
+{
+    for (Frame* child = firstChild(); child; child = child->tree()->nextSibling())
+        if (child->tree()->name() == name)
+            return child;
+    return 0;
+}
+
+Frame* FrameTree::find(const AtomicString& name) const
+{
+    if (name == "_self" || name == "_current")
+        return m_thisFrame;
+    
+    if (name == "_top")
+        return m_thisFrame->page()->mainFrame();
+    
+    if (name == "_parent")
+        return parent() ? parent() : m_thisFrame;
+
+    // Since "_blank" should never be any frame's name, the following just amounts to an optimization.
+    if (name == "_blank")
+        return 0;
+
+    // Search subtree starting with this frame first.
+    for (Frame* frame = m_thisFrame; frame; frame = frame->tree()->traverseNext(m_thisFrame))
+        if (frame->tree()->name() == name)
+            return frame;
+
+    // Search the entire tree for this page next.
+    Page* page = m_thisFrame->page();
+    for (Frame* frame = page->mainFrame(); frame; frame = frame->tree()->traverseNext())
+        if (frame->tree()->name() == name)
+            return frame;
+
+    // Search the entire tree for all other pages in this namespace.
+    const HashSet<Page*>* pages = page->frameNamespace();
+    if (pages) {
+        HashSet<Page*>::const_iterator end = pages->end();
+        for (HashSet<Page*>::const_iterator it = pages->begin(); it != end; ++it) {
+            Page* otherPage = *it;
+            if (otherPage != page)
+                for (Frame* frame = otherPage->mainFrame(); frame; frame = frame->tree()->traverseNext())
+                    if (frame->tree()->name() == name)
+                        return frame;
+        }
+    }
+
+    return 0;
+}
+
+bool FrameTree::isDescendantOf(Frame* ancestor) const
+{
+    for (Frame* frame = m_thisFrame; frame; frame = frame->tree()->parent())
+        if (frame == ancestor)
+            return true;
+    return false;
+}
+
+Frame* FrameTree::traverseNext(Frame* stayWithin) const
+{
+    Frame* child = firstChild();
+    if (child) {
+        ASSERT(!stayWithin || child->tree()->isDescendantOf(stayWithin));
+        return child;
+    }
+
+    if (m_thisFrame == stayWithin)
+        return 0;
+
+    Frame* sibling = nextSibling();
+    if (sibling) {
+        ASSERT(!stayWithin || sibling->tree()->isDescendantOf(stayWithin));
+        return sibling;
+    }
+
+    Frame* frame = m_thisFrame;
+    while (!sibling && (!stayWithin || frame->tree()->parent() != stayWithin)) {
+        frame = frame->tree()->parent();
+        if (!frame)
+            return 0;
+        sibling = frame->tree()->nextSibling();
+    }
+
+    if (frame) {
+        ASSERT(!stayWithin || !sibling || sibling->tree()->isDescendantOf(stayWithin));
+        return sibling;
+    }
+
+    return 0;
+}
+
 }
index 19ba0005bdaa980fb19237d221cfb90cebaab029..185646cfc6002292b92039ddd475fd9dd05dbe2c 100644 (file)
 #ifndef FRAME_TREE_H
 #define FRAME_TREE_H
 
+#include "AtomicString.h"
 #include <kxmlcore/Noncopyable.h>
 #include <kxmlcore/PassRefPtr.h>
 #include <kxmlcore/RefPtr.h>
-#include "PlatformString.h"
 
 namespace WebCore {
 
     class Frame;
 
-    class FrameTree : Noncopyable
-    {
+    class FrameTree : Noncopyable {
     public:
         FrameTree(Frame* thisFrame, Frame* parentFrame) 
             : m_thisFrame(thisFrame)
@@ -42,9 +41,9 @@ namespace WebCore {
         {
         }
         ~FrameTree();
-        
-        const String& name() const { return m_name; }
-        void setName(const String&);
+
+        const AtomicString& name() const { return m_name; }
+        void setName(const AtomicString&);
         Frame* parent() const { return m_parent; }
         void setParent(Frame* parent) { m_parent = parent; }
         
@@ -52,23 +51,32 @@ namespace WebCore {
         Frame* previousSibling() const { return m_previousSibling; }
         Frame* firstChild() const { return m_firstChild.get(); }
         Frame* lastChild() const { return m_lastChild; }
-        int childCount() const { return m_childCount; }
+        unsigned childCount() const { return m_childCount; }
+
+        bool isDescendantOf(Frame* ancestor) const;
+        Frame* traverseNext(Frame* stayWithin = 0) const;
         
         void appendChild(PassRefPtr<Frame>);
         void removeChild(Frame*);
-        
+
+        Frame* child(unsigned index) const;
+        Frame* child(const AtomicString& name) const;
+        Frame* find(const AtomicString& name) const;
+
+        AtomicString uniqueChildName(const AtomicString& requestedName) const;
+
     private:
         Frame* m_thisFrame;
-        
+
         Frame* m_parent;
-        String m_name;
-        
+        AtomicString m_name;
+
         // FIXME: use ListRefPtr?
         RefPtr<Frame> m_nextSibling;
         Frame* m_previousSibling;
         RefPtr<Frame> m_firstChild;
         Frame* m_lastChild;
-        int m_childCount;
+        unsigned m_childCount;
     };
 
 } // namespace WebCore
index 6f2e290dbac2ac9c0c736559a3cb1094d34c4f66..19c0ee9e6b78f362f1ad0699c28a30d74f2c5bf3 100644 (file)
 #include "Frame.h"
 #include <kjs/collector.h>
 #include <kjs/JSLock.h>
+#include <kxmlcore/HashMap.h>
 
 using namespace KJS;
 
 namespace WebCore {
 
 static int pageCount;
+static HashMap<String, HashSet<Page*>*>* frameNamespaces;
 
-Page::Page() 
+Page::Page() : m_frameCount(0)
 {
     ++pageCount;
 }
 
 Page::~Page() 
-{ 
+{
     m_mainFrame->detachFromView(); 
+    setGroupName(String());
     if (!--pageCount) {
         Frame::endAllLifeSupport();
 #ifndef NDEBUG
@@ -55,4 +58,39 @@ void Page::setMainFrame(PassRefPtr<Frame> mainFrame)
     m_mainFrame = mainFrame;
 }
 
+void Page::setGroupName(const String& name)
+{
+    if (frameNamespaces && !m_groupName.isEmpty()) {
+        HashSet<Page*>* oldNamespace = frameNamespaces->get(m_groupName);
+        if (oldNamespace) {
+            oldNamespace->remove(this);
+            if (oldNamespace->isEmpty()) {
+                frameNamespaces->remove(m_groupName);
+                delete oldNamespace;
+            }
+        }
+    }
+    m_groupName = name;
+    if (!name.isEmpty()) {
+        if (!frameNamespaces)
+            frameNamespaces = new HashMap<String, HashSet<Page*>*>;
+        HashSet<Page*>* newNamespace = frameNamespaces->get(name);
+        if (!newNamespace) {
+            newNamespace = new HashSet<Page*>;
+            frameNamespaces->add(name, newNamespace);
+        }
+        newNamespace->add(this);
+    }
+}
+
+const HashSet<Page*>* Page::frameNamespace() const
+{
+    return (frameNamespaces && !m_groupName.isEmpty()) ? frameNamespaces->get(m_groupName) : 0;
+}
+
+const HashSet<Page*>* Page::frameNamespace(const String& groupName)
+{
+    return (frameNamespaces && !groupName.isEmpty()) ? frameNamespaces->get(groupName) : 0;
+}
+
 }
index 95e2fd32804d82af0cc0fdfc67584bc441a6513d..da2a6fb5dd5aaba9cfa07963f7abcee5815e0072 100644 (file)
@@ -21,6 +21,8 @@
 #ifndef PAGE_H
 #define PAGE_H
 
+#include "PlatformString.h"
+#include <kxmlcore/HashSet.h>
 #include <kxmlcore/Noncopyable.h>
 #include <kxmlcore/PassRefPtr.h>
 #include <kxmlcore/RefPtr.h>
 namespace WebCore {
 
     class Frame;
+    class FrameNamespace;
     
     class Page : Noncopyable {
     public:
         Page();
         virtual ~Page();
+
         void setMainFrame(PassRefPtr<Frame> mainFrame);
         Frame* mainFrame() { return m_mainFrame.get(); }
+
+        void setGroupName(const String&);
+        String groupName() const { return m_groupName; }
+        const HashSet<Page*>* frameNamespace() const;
+        static const HashSet<Page*>* frameNamespace(const String&);
+
+        void incrementFrameCount() { ++m_frameCount; }
+        void decrementFrameCount() { --m_frameCount; }
+        int frameCount() const { return m_frameCount; }
+
     private:
         RefPtr<Frame> m_mainFrame;
+        int m_frameCount;
+        String m_groupName;
     };
 
 } // namespace WebCore
index 18ae2e07e3f55a71ac4172c4003c4dbbcd6a46bc..340a77f4e32f9919990e47cb3e320d04c1c714b9 100644 (file)
@@ -245,7 +245,6 @@ bool FrameWin::lastEventIsMouseUp() const { return false; }
 void FrameWin::addMessageToConsole(String const&,unsigned int,String const&) { }
 bool FrameWin::shouldChangeSelection(SelectionController const&,SelectionController const&,WebCore::EAffinity,bool) const { return 0; }
 static int frameNumber = 0;
-String FrameWin::generateFrameName() { return QString::number(frameNumber++); }
 Frame* FrameWin::createFrame(KURL const&,QString const&,RenderPart*,String const&) { return 0; }
 void FrameWin::saveDocumentState(void) { }
 void FrameWin::clearUndoRedoOperations(void) { }
index 9190cb15d059991cd6775aaaec5620638f773a87..ba096a27044c6cfff4b13d20595781db9f92d036 100644 (file)
@@ -33,6 +33,7 @@
 #include "FrameTree.h"
 #include "FrameView.h"
 #include "GraphicsContext.h"
+#include "Page.h"
 #include "TextImpl.h"
 #include "dom2_eventsimpl.h"
 #include "html_baseimpl.h"
@@ -681,7 +682,7 @@ static bool isURLAllowed(DOM::DocumentImpl *doc, const QString &url)
     KURL newURL(doc->completeURL(url));
     newURL.setRef(QString::null);
     
-    if (doc->frame()->topLevelFrameCount() >= 200)
+    if (doc->frame()->page()->frameCount() >= 200)
         return false;
 
     // We allow one level of self-reference because some sites depend on that.