diff options
| author | dglazkov@google.com <dglazkov@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-12-12 20:41:20 +0000 |
|---|---|---|
| committer | dglazkov@google.com <dglazkov@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-12-12 20:41:20 +0000 |
| commit | dd1691b4492f038d0727fec567786c8b88e79c84 (patch) | |
| tree | 7fb516a0f4f415327ae72b103eecc797e0dba32e | |
| parent | 465b34b73d11d017dfc546821c8dcb8e4dbe4b56 (diff) | |
| download | chromium_src-dd1691b4492f038d0727fec567786c8b88e79c84.zip chromium_src-dd1691b4492f038d0727fec567786c8b88e79c84.tar.gz chromium_src-dd1691b4492f038d0727fec567786c8b88e79c84.tar.bz2 | |
Remove JSC masquerade, implement ScriptState (2/2).
Review URL: http://codereview.chromium.org/14056
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@6923 0039d316-1c4b-4281-b951-d872f2087c98
| -rw-r--r-- | webkit/build/V8Bindings/V8Bindings.vcproj | 20 | ||||
| -rw-r--r-- | webkit/port/bindings/v8/JSDOMBinding.cpp | 1 | ||||
| -rw-r--r-- | webkit/port/bindings/v8/JSDOMBinding.h | 3 | ||||
| -rwxr-xr-x | webkit/port/bindings/v8/ScriptState.h | 16 | ||||
| -rw-r--r-- | webkit/port/bindings/v8/interpreter/CallFrame.h | 50 | ||||
| -rw-r--r-- | webkit/port/bindings/v8/runtime/JSLock.h | 38 | ||||
| -rw-r--r-- | webkit/port/bindings/v8/v8_custom.cpp | 75 | ||||
| -rw-r--r-- | webkit/port/bindings/v8/v8_nodefilter.cpp | 6 | ||||
| -rw-r--r-- | webkit/port/bindings/v8/v8_nodefilter.h | 7 | ||||
| -rw-r--r-- | webkit/webkit.xcodeproj/project.pbxproj | 14 |
10 files changed, 64 insertions, 166 deletions
diff --git a/webkit/build/V8Bindings/V8Bindings.vcproj b/webkit/build/V8Bindings/V8Bindings.vcproj index 4ef3c7b..bf54ed6 100644 --- a/webkit/build/V8Bindings/V8Bindings.vcproj +++ b/webkit/build/V8Bindings/V8Bindings.vcproj @@ -2424,22 +2424,6 @@ >
</File>
</Filter>
- <Filter
- Name="interpreter"
- >
- <File
- RelativePath="..\..\port\bindings\v8\interpreter\CallFrame.h"
- >
- </File>
- </Filter>
- <Filter
- Name="runtime"
- >
- <File
- RelativePath="..\..\port\bindings\v8\runtime\JSLock.h"
- >
- </File>
- </Filter>
<File
RelativePath="..\..\port\bindings\v8\dom_wrapper_map.h"
>
@@ -2529,6 +2513,10 @@ >
</File>
<File
+ RelativePath="..\..\port\bindings\v8\ScriptState.h"
+ >
+ </File>
+ <File
RelativePath="..\..\port\bindings\v8\ScriptValue.cpp"
>
</File>
diff --git a/webkit/port/bindings/v8/JSDOMBinding.cpp b/webkit/port/bindings/v8/JSDOMBinding.cpp index 7749083..7796fc5 100644 --- a/webkit/port/bindings/v8/JSDOMBinding.cpp +++ b/webkit/port/bindings/v8/JSDOMBinding.cpp @@ -30,7 +30,6 @@ #include "config.h" #include "JSDOMBinding.h" -#include <interpreter/CallFrame.h> #include "Document.h" #include "Node.h" diff --git a/webkit/port/bindings/v8/JSDOMBinding.h b/webkit/port/bindings/v8/JSDOMBinding.h index 815472b..6d52e3f 100644 --- a/webkit/port/bindings/v8/JSDOMBinding.h +++ b/webkit/port/bindings/v8/JSDOMBinding.h @@ -34,11 +34,10 @@ #ifndef JSDOMBinding_h #define JSDOMBinding_h -#include "ScriptState.h" - namespace WebCore { class Node; class Document; + class ScriptState; void updateDOMNodeDocument(Node*, Document* oldDocument, Document* newDocument); diff --git a/webkit/port/bindings/v8/ScriptState.h b/webkit/port/bindings/v8/ScriptState.h index c86e30d..3991037 100755 --- a/webkit/port/bindings/v8/ScriptState.h +++ b/webkit/port/bindings/v8/ScriptState.h @@ -30,9 +30,21 @@ #ifndef ScriptState_h #define ScriptState_h -#include "interpreter/CallFrame.h" +#include <v8.h> namespace WebCore { - typedef JSC::ExecState ScriptState; + class ScriptState { + public: + bool hadException() { return !m_exception.IsEmpty(); } + void setException(v8::Local<v8::Value> exception) + { + m_exception = exception; + } + v8::Local<v8::Value> exception() { return m_exception; } + + private: + v8::Local<v8::Value> m_exception; + }; } + #endif // ScriptState_h diff --git a/webkit/port/bindings/v8/interpreter/CallFrame.h b/webkit/port/bindings/v8/interpreter/CallFrame.h deleted file mode 100644 index 5e968a2..0000000 --- a/webkit/port/bindings/v8/interpreter/CallFrame.h +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) 2008, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef ExecState_h -#define ExecState_h - -#include <v8.h> - -namespace JSC { - class ExecState { - public: - bool hadException() { return !m_exception.IsEmpty(); } - void setException(v8::Local<v8::Value> exception) - { - m_exception = exception; - } - v8::Local<v8::Value> exception() { return m_exception; } - - private: - v8::Local<v8::Value> m_exception; - }; -} - -#endif // ExecState_h diff --git a/webkit/port/bindings/v8/runtime/JSLock.h b/webkit/port/bindings/v8/runtime/JSLock.h deleted file mode 100644 index c52e5c3..0000000 --- a/webkit/port/bindings/v8/runtime/JSLock.h +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) 2008, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef JSLock_h -#define JSLock_h - -namespace JSC { - class JSLock { - }; -} - -#endif // JSLock_h diff --git a/webkit/port/bindings/v8/v8_custom.cpp b/webkit/port/bindings/v8/v8_custom.cpp index ced5794..da488ba 100644 --- a/webkit/port/bindings/v8/v8_custom.cpp +++ b/webkit/port/bindings/v8/v8_custom.cpp @@ -25,7 +25,6 @@ #include <Assertions.h> #include <wtf/ASCIICType.h> -#include <interpreter/CallFrame.h> #include "v8_proxy.h" #include "v8_events.h" @@ -88,6 +87,7 @@ #include "HTMLSelectElement.h" #include "History.h" #include "JSXPathNSResolver.h" +#include "JSDOMBinding.h" #include "KURL.h" #include "Location.h" #include "MessageChannel.h" @@ -101,6 +101,7 @@ #include "RenderWidget.h" #include "ScheduledAction.h" #include "ScriptCallContext.h" +#include "ScriptState.h" #include "ScriptController.h" #include "SecurityOrigin.h" #include "Settings.h" @@ -3040,10 +3041,10 @@ CALLBACK_FUNC_DECL(TreeWalkerParentNode) { TreeWalker* treeWalker = V8Proxy::ToNativeObject<TreeWalker>( V8ClassIndex::TREEWALKER, args.Holder()); - JSC::ExecState exec; - RefPtr<Node> result = treeWalker->parentNode(&exec); - if (exec.hadException()) { - v8::ThrowException(exec.exception()); + ScriptState state; + RefPtr<Node> result = treeWalker->parentNode(&state); + if (state.hadException()) { + v8::ThrowException(state.exception()); return v8::Undefined(); } if (!result) return v8::Null(); @@ -3055,10 +3056,10 @@ CALLBACK_FUNC_DECL(TreeWalkerFirstChild) { TreeWalker* treeWalker = V8Proxy::ToNativeObject<TreeWalker>( V8ClassIndex::TREEWALKER, args.Holder()); - JSC::ExecState exec; - RefPtr<Node> result = treeWalker->firstChild(&exec); - if (exec.hadException()) { - v8::ThrowException(exec.exception()); + ScriptState state; + RefPtr<Node> result = treeWalker->firstChild(&state); + if (state.hadException()) { + v8::ThrowException(state.exception()); return v8::Undefined(); } if (!result) return v8::Null(); @@ -3070,10 +3071,10 @@ CALLBACK_FUNC_DECL(TreeWalkerLastChild) { TreeWalker* treeWalker = V8Proxy::ToNativeObject<TreeWalker>( V8ClassIndex::TREEWALKER, args.Holder()); - JSC::ExecState exec; - RefPtr<Node> result = treeWalker->lastChild(&exec); - if (exec.hadException()) { - v8::ThrowException(exec.exception()); + ScriptState state; + RefPtr<Node> result = treeWalker->lastChild(&state); + if (state.hadException()) { + v8::ThrowException(state.exception()); return v8::Undefined(); } if (!result) return v8::Null(); @@ -3085,10 +3086,10 @@ CALLBACK_FUNC_DECL(TreeWalkerNextNode) { TreeWalker* treeWalker = V8Proxy::ToNativeObject<TreeWalker>( V8ClassIndex::TREEWALKER, args.Holder()); - JSC::ExecState exec; - RefPtr<Node> result = treeWalker->nextNode(&exec); - if (exec.hadException()) { - v8::ThrowException(exec.exception()); + ScriptState state; + RefPtr<Node> result = treeWalker->nextNode(&state); + if (state.hadException()) { + v8::ThrowException(state.exception()); return v8::Undefined(); } if (!result) return v8::Null(); @@ -3100,10 +3101,10 @@ CALLBACK_FUNC_DECL(TreeWalkerPreviousNode) { TreeWalker* treeWalker = V8Proxy::ToNativeObject<TreeWalker>( V8ClassIndex::TREEWALKER, args.Holder()); - JSC::ExecState exec; - RefPtr<Node> result = treeWalker->previousNode(&exec); - if (exec.hadException()) { - v8::ThrowException(exec.exception()); + ScriptState state; + RefPtr<Node> result = treeWalker->previousNode(&state); + if (state.hadException()) { + v8::ThrowException(state.exception()); return v8::Undefined(); } if (!result) return v8::Null(); @@ -3115,10 +3116,10 @@ CALLBACK_FUNC_DECL(TreeWalkerNextSibling) { TreeWalker* treeWalker = V8Proxy::ToNativeObject<TreeWalker>( V8ClassIndex::TREEWALKER, args.Holder()); - JSC::ExecState exec; - RefPtr<Node> result = treeWalker->nextSibling(&exec); - if (exec.hadException()) { - v8::ThrowException(exec.exception()); + ScriptState state; + RefPtr<Node> result = treeWalker->nextSibling(&state); + if (state.hadException()) { + v8::ThrowException(state.exception()); return v8::Undefined(); } if (!result) return v8::Null(); @@ -3130,10 +3131,10 @@ CALLBACK_FUNC_DECL(TreeWalkerPreviousSibling) { TreeWalker* treeWalker = V8Proxy::ToNativeObject<TreeWalker>( V8ClassIndex::TREEWALKER, args.Holder()); - JSC::ExecState exec; - RefPtr<Node> result = treeWalker->previousSibling(&exec); - if (exec.hadException()) { - v8::ThrowException(exec.exception()); + ScriptState state; + RefPtr<Node> result = treeWalker->previousSibling(&state); + if (state.hadException()) { + v8::ThrowException(state.exception()); return v8::Undefined(); } if (!result) return v8::Null(); @@ -3146,14 +3147,14 @@ CALLBACK_FUNC_DECL(NodeIteratorNextNode) { V8ClassIndex::NODEITERATOR, args.Holder()); ExceptionCode ec = 0; - JSC::ExecState exec; - RefPtr<Node> result = nodeIterator->nextNode(&exec, ec); + ScriptState state; + RefPtr<Node> result = nodeIterator->nextNode(&state, ec); if (ec != 0) { V8Proxy::SetDOMException(ec); return v8::Null(); } - if (exec.hadException()) { - v8::ThrowException(exec.exception()); + if (state.hadException()) { + v8::ThrowException(state.exception()); return v8::Undefined(); } if (!result) return v8::Null(); @@ -3166,14 +3167,14 @@ CALLBACK_FUNC_DECL(NodeIteratorPreviousNode) { V8ClassIndex::NODEITERATOR, args.Holder()); ExceptionCode ec = 0; - JSC::ExecState exec; - RefPtr<Node> result = nodeIterator->previousNode(&exec, ec); + ScriptState state; + RefPtr<Node> result = nodeIterator->previousNode(&state, ec); if (ec != 0) { V8Proxy::SetDOMException(ec); return v8::Null(); } - if (exec.hadException()) { - v8::ThrowException(exec.exception()); + if (state.hadException()) { + v8::ThrowException(state.exception()); return v8::Undefined(); } if (!result) return v8::Null(); diff --git a/webkit/port/bindings/v8/v8_nodefilter.cpp b/webkit/port/bindings/v8/v8_nodefilter.cpp index 9df8b2b..7a01f5b 100644 --- a/webkit/port/bindings/v8/v8_nodefilter.cpp +++ b/webkit/port/bindings/v8/v8_nodefilter.cpp @@ -33,7 +33,7 @@ #include "v8_proxy.h" #include "NodeFilter.h" #include "Node.h" -#include <interpreter/CallFrame.h> +#include "ScriptState.h" namespace WebCore { @@ -52,7 +52,7 @@ V8NodeFilterCondition::~V8NodeFilterCondition() { m_filter.Clear(); } -short V8NodeFilterCondition::acceptNode(JSC::ExecState* exec, +short V8NodeFilterCondition::acceptNode(ScriptState* state, Node* node) const { ASSERT(v8::Context::InContext()); @@ -74,7 +74,7 @@ short V8NodeFilterCondition::acceptNode(JSC::ExecState* exec, delete[] args; if (exception_catcher.HasCaught()) { - exec->setException(exception_catcher.Exception()); + state->setException(exception_catcher.Exception()); return NodeFilter::FILTER_REJECT; } diff --git a/webkit/port/bindings/v8/v8_nodefilter.h b/webkit/port/bindings/v8/v8_nodefilter.h index 96ea520..e9598d8 100644 --- a/webkit/port/bindings/v8/v8_nodefilter.h +++ b/webkit/port/bindings/v8/v8_nodefilter.h @@ -8,14 +8,11 @@ #include <v8.h> #include "NodeFilterCondition.h" -namespace JSC { - class ExecState; -} - // NodeFilter is a JavaScript function that takes a Node as parameter // and returns a short (ACCEPT, SKIP, REJECT) as the result. namespace WebCore { class Node; +class ScriptState; // NodeFilterCondition is a wrapper around a NodeFilter JS function. class V8NodeFilterCondition : public NodeFilterCondition { @@ -23,7 +20,7 @@ class V8NodeFilterCondition : public NodeFilterCondition { explicit V8NodeFilterCondition(v8::Handle<v8::Value> filter); virtual ~V8NodeFilterCondition(); - virtual short acceptNode(JSC::ExecState*, Node*) const; + virtual short acceptNode(ScriptState*, Node*) const; private: mutable v8::Persistent<v8::Value> m_filter; diff --git a/webkit/webkit.xcodeproj/project.pbxproj b/webkit/webkit.xcodeproj/project.pbxproj index 0107c2d..3a02fe8 100644 --- a/webkit/webkit.xcodeproj/project.pbxproj +++ b/webkit/webkit.xcodeproj/project.pbxproj @@ -1444,6 +1444,7 @@ 04C3AFC50EF1E45F0046D578 /* WorkerNavigator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WorkerNavigator.cpp; sourceTree = "<group>"; }; 04C3AFC70EF1E4650046D578 /* WorkerNavigator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WorkerNavigator.h; sourceTree = "<group>"; }; 416F45210ED7697D008215B6 /* FrameLoaderClient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FrameLoaderClient.cpp; sourceTree = "<group>"; }; + 419106470EF2D6D500BFDCC5 /* ScriptState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptState.h; sourceTree = "<group>"; }; 41AF32C40EE5E6ED00BF6361 /* ScriptInstance.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScriptInstance.cpp; sourceTree = "<group>"; }; 41AF32C50EE5E6ED00BF6361 /* ScriptInstance.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptInstance.h; sourceTree = "<group>"; }; 4D1637C30EBFA49E008F024E /* SQLiteAuthorizer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SQLiteAuthorizer.cpp; sourceTree = "<group>"; }; @@ -4187,8 +4188,6 @@ B58831290E9BD6D800CEC344 /* StringBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StringBuilder.cpp; sourceTree = "<group>"; }; B5B0D4190EC8FE4900EA3314 /* JSDOMBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMBinding.h; sourceTree = "<group>"; }; B5B0D41A0EC8FE4900EA3314 /* JSDOMBinding.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDOMBinding.cpp; sourceTree = "<group>"; }; - B5B0D41D0EC8FE6300EA3314 /* ExecState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExecState.h; sourceTree = "<group>"; }; - B5B0D41E0EC8FE6300EA3314 /* JSLock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSLock.h; sourceTree = "<group>"; }; B5B0D6870EC91D3D00EA3314 /* autofill_form.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = autofill_form.h; sourceTree = "<group>"; }; B5B0D6880EC91D3D00EA3314 /* autofill_form.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = autofill_form.cc; sourceTree = "<group>"; }; B5C180740E95816D006EAF87 /* StringHash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StringHash.h; sourceTree = "<group>"; }; @@ -4509,12 +4508,12 @@ 7B0095DA0DAFF0DC00F72082 /* npruntime_priv.h */, 934CC2270EDCC37600A658F2 /* RGBColor.cpp */, 934CC2290EDCC38400A658F2 /* RGBColor.h */, - B5B0D41C0EC8FE6300EA3314 /* runtime */, E40063600EA907510055B38E /* ScriptCallContextV8.cpp */, E40060D90EA69E0B0055B38E /* ScriptController.h */, E40060DA0EA69E0B0055B38E /* ScriptController.cpp */, 41AF32C50EE5E6ED00BF6361 /* ScriptInstance.h */, 41AF32C40EE5E6ED00BF6361 /* ScriptInstance.cpp */, + 419106470EF2D6D500BFDCC5 /* ScriptState.h */, 934CC3570EDCCEFE00A658F2 /* ScriptValue.cpp */, 934CC3580EDCCEFE00A658F2 /* ScriptValue.h */, 7B0095DB0DAFF0DC00F72082 /* v8_binding.h */, @@ -7678,15 +7677,6 @@ name = cf; sourceTree = "<group>"; }; - B5B0D41C0EC8FE6300EA3314 /* runtime */ = { - isa = PBXGroup; - children = ( - B5B0D41D0EC8FE6300EA3314 /* ExecState.h */, - B5B0D41E0EC8FE6300EA3314 /* JSLock.h */, - ); - path = runtime; - sourceTree = "<group>"; - }; B5C180A00E958E85006EAF87 /* style */ = { isa = PBXGroup; children = ( |
