1/*
2 * Copyright (C) 2008 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1.  Redistributions of source code must retain the above copyright
9 *     notice, this list of conditions and the following disclaimer.
10 * 2.  Redistributions in binary form must reproduce the above copyright
11 *     notice, this list of conditions and the following disclaimer in the
12 *     documentation and/or other materials provided with the distribution.
13 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14 *     its contributors may be used to endorse or promote products derived
15 *     from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include "config.h"
30#include "JSClipboard.h"
31
32#include "Clipboard.h"
33#include "Element.h"
34#include "HTMLImageElement.h"
35#include "HTMLNames.h"
36#include "IntPoint.h"
37#include "JSNode.h"
38#include "Node.h"
39#include "PlatformString.h"
40#include <runtime/ArrayPrototype.h>
41#include <runtime/Error.h>
42#include <wtf/HashSet.h>
43#include <wtf/text/StringHash.h>
44
45using namespace JSC;
46
47namespace WebCore {
48
49using namespace HTMLNames;
50
51JSValue JSClipboard::types(ExecState* exec) const
52{
53    Clipboard* clipboard = impl();
54
55    HashSet<String> types = clipboard->types();
56    if (types.isEmpty())
57        return jsNull();
58
59    MarkedArgumentBuffer list;
60    HashSet<String>::const_iterator end = types.end();
61    for (HashSet<String>::const_iterator it = types.begin(); it != end; ++it)
62        list.append(jsString(exec, stringToUString(*it)));
63    return constructArray(exec, list);
64}
65
66JSValue JSClipboard::clearData(ExecState* exec)
67{
68    Clipboard* clipboard = impl();
69
70    if (!exec->argumentCount()) {
71        clipboard->clearAllData();
72        return jsUndefined();
73    }
74
75    if (exec->argumentCount() == 1) {
76        clipboard->clearData(ustringToString(exec->argument(0).toString(exec)));
77        return jsUndefined();
78    }
79
80    // FIXME: It does not match the rest of the JS bindings to throw on invalid number of arguments.
81    return throwError(exec, createSyntaxError(exec, "clearData: Invalid number of arguments"));
82}
83
84JSValue JSClipboard::getData(ExecState* exec)
85{
86    // FIXME: It does not match the rest of the JS bindings to throw on invalid number of arguments.
87    if (exec->argumentCount() != 1)
88        return throwError(exec, createSyntaxError(exec, "getData: Invalid number of arguments"));
89
90    Clipboard* clipboard = impl();
91
92    bool success;
93    String result = clipboard->getData(ustringToString(exec->argument(0).toString(exec)), success);
94    if (!success)
95        return jsUndefined();
96
97    return jsString(exec, result);
98}
99
100JSValue JSClipboard::setDragImage(ExecState* exec)
101{
102    Clipboard* clipboard = impl();
103
104    if (!clipboard->isForDragAndDrop())
105        return jsUndefined();
106
107    // FIXME: It does not match the rest of the JS bindings to throw on invalid number of arguments.
108    if (exec->argumentCount() != 3)
109        return throwError(exec, createSyntaxError(exec, "setDragImage: Invalid number of arguments"));
110
111    int x = exec->argument(1).toInt32(exec);
112    int y = exec->argument(2).toInt32(exec);
113
114    // See if they passed us a node
115    Node* node = toNode(exec->argument(0));
116    if (!node)
117        return throwTypeError(exec);
118
119    // FIXME: This should probably be a TypeError.
120    if (!node->isElementNode())
121        return throwError(exec, createSyntaxError(exec, "setDragImageFromElement: Invalid first argument"));
122
123    if (static_cast<Element*>(node)->hasLocalName(imgTag) && !node->inDocument())
124        clipboard->setDragImage(static_cast<HTMLImageElement*>(node)->cachedImage(), IntPoint(x, y));
125    else
126        clipboard->setDragImageElement(node, IntPoint(x, y));
127
128    return jsUndefined();
129}
130
131} // namespace WebCore
132