Reviewed by Adam.
[WebKit-https.git] / WebKit / win / WebScriptScope.cpp
index 788545f12121531fa6989c7bda24f9cf157a6e06..d7228db3f3ebf6eace7f8b906b794e22bb5adabf 100644 (file)
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include "config.h"
 #include "WebKitDLL.h"
-
 #include "WebScriptScope.h"
 
+#include "COMEnumVariant.h"
+#include "WebScriptCallFrame.h"
+
+#include <memory>
+#include <JavaScriptCore/PropertyNameArray.h>
 #include <wtf/Assertions.h>
+#include <wtf/OwnPtr.h>
+
+#pragma warning(push, 0)
+#include <WebCore/BString.h>
+#include <WebCore/PlatformString.h>
+#pragma warning(pop)
+
+using namespace KJS;
+using namespace std;
 
 // WebScriptScope ------------------------------------------------------------
 
-WebScriptScope::WebScriptScope()
-: m_refCount(0)
+WebScriptScope::WebScriptScope(JSObject* scope)
+    : m_refCount(0)
+    , m_scope(scope)
 {
     gClassCount++;
 }
@@ -45,6 +60,13 @@ WebScriptScope::~WebScriptScope()
     gClassCount--;
 }
 
+WebScriptScope* WebScriptScope::createInstance(JSObject* scope)
+{
+    WebScriptScope* instance = new WebScriptScope(scope);
+    instance->AddRef();
+    return instance;
+}
+
 // IUnknown -------------------------------------------------------------------
 
 HRESULT STDMETHODCALLTYPE WebScriptScope::QueryInterface(REFIID riid, void** ppvObject)
@@ -75,19 +97,81 @@ ULONG STDMETHODCALLTYPE WebScriptScope::Release(void)
     return newRef;
 }
 
+template<> struct COMVariantSetter<Identifier>
+{
+    static void setVariant(VARIANT* variant, const Identifier& value)
+    {
+        ASSERT(V_VT(variant) == VT_EMPTY);
+
+        V_VT(variant) = VT_BSTR;
+        V_BSTR(variant) = WebCore::BString(reinterpret_cast<const wchar_t*>(value.data()), value.size()).release();
+    }
+};
+
 // WebScriptScope ------------------------------------------------------------
 
 HRESULT STDMETHODCALLTYPE WebScriptScope::variableNames(
-    /* [out, retval] */ IEnumVARIANT**)
+    /* [in] */ IWebScriptCallFrame* frame,
+    /* [out, retval] */ IEnumVARIANT** variableNames)
 {
-    ASSERT_NOT_REACHED();
-    return E_NOTIMPL;
+    if (!variableNames)
+        return E_POINTER;
+
+    *variableNames = 0;
+
+    if (!frame)
+        return E_FAIL;
+
+    PropertyNameArray propertyNames;
+    m_scope->getPropertyNames(frame->impl()->state(), propertyNames);
+
+    *variableNames = COMEnumVariant<PropertyNameArray>::adopt(propertyNames);
+
+    return S_OK;
 }
 
 HRESULT STDMETHODCALLTYPE WebScriptScope::valueForVariable(
-    /* [in] */ BSTR /*key*/,
-    /* [out, retval] */ BSTR* /*value*/)
+    /* [in] */ IWebScriptCallFrame* frame,
+    /* [in] */ BSTR key,
+    /* [out, retval] */ BSTR* value)
 {
-    ASSERT_NOT_REACHED();
-    return E_NOTIMPL;
+    if (!frame || !key)
+        return E_FAIL;
+
+    if (!value)
+        return E_POINTER;
+
+    *value = 0;
+
+    Identifier identKey(reinterpret_cast<KJS::UChar*>(key), SysStringLen(key));
+
+    JSValue* jsvalue = m_scope->get(frame->impl()->state(), identKey);
+
+    UString string;
+    const JSType type = jsvalue->type();
+    switch (type) {
+        case NullType:
+        case UndefinedType:
+        case UnspecifiedType:
+        case GetterSetterType:
+            break;
+        case StringType:
+            string = jsvalue->getString();
+            break;
+        case NumberType:
+            string = UString::from(jsvalue->getNumber());
+            break;
+        case BooleanType:
+            string = jsvalue->getBoolean() ? "True" : "False";
+            break;
+        case ObjectType: {
+            JSObject* jsobject = jsvalue->getObject();
+            jsvalue = jsobject->defaultValue(frame->impl()->state(), StringType);
+            string = jsvalue->getString();
+            break;
+        }
+    }
+
+    *value = WebCore::BString(string).release();
+    return S_OK;
 }