Unreviewed, rolling out r224863.
[WebKit-https.git] / Source / WebCore / inspector / WebInjectedScriptHost.cpp
1 /*
2  * Copyright (C) 2013-2017 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  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "WebInjectedScriptHost.h"
28
29 #include "DOMException.h"
30 #include "JSDOMException.h"
31 #include "JSHTMLAllCollection.h"
32 #include "JSHTMLCollection.h"
33 #include "JSNode.h"
34 #include "JSNodeList.h"
35
36 #if ENABLE(PAYMENT_REQUEST)
37 #include "JSPaymentRequest.h"
38 #include "JSPaymentShippingType.h"
39 #include "PaymentOptions.h"
40 #include "PaymentRequest.h"
41 #endif
42
43 namespace WebCore {
44
45 using namespace JSC;
46
47 JSValue WebInjectedScriptHost::subtype(ExecState* exec, JSValue value)
48 {
49     VM& vm = exec->vm();
50     if (value.inherits(vm, JSNode::info()))
51         return jsNontrivialString(exec, ASCIILiteral("node"));
52     if (value.inherits(vm, JSNodeList::info()))
53         return jsNontrivialString(exec, ASCIILiteral("array"));
54     if (value.inherits(vm, JSHTMLCollection::info()))
55         return jsNontrivialString(exec, ASCIILiteral("array"));
56     if (value.inherits(vm, JSDOMException::info()))
57         return jsNontrivialString(exec, ASCIILiteral("error"));
58
59     return jsUndefined();
60 }
61
62 #if ENABLE(PAYMENT_REQUEST)
63 static JSObject* constructInternalProperty(VM& vm, ExecState* exec, const String& name, JSValue value)
64 {
65     auto* object = constructEmptyObject(exec);
66     object->putDirect(vm, Identifier::fromString(exec, "name"), jsString(exec, name));
67     object->putDirect(vm, Identifier::fromString(exec, "value"), value);
68     return object;
69 }
70
71 static JSObject* objectForPaymentOptions(VM& vm, ExecState* exec, const PaymentOptions& paymentOptions)
72 {
73     auto* object = constructEmptyObject(exec);
74     object->putDirect(vm, Identifier::fromString(exec, "requestPayerName"), jsBoolean(paymentOptions.requestPayerName));
75     object->putDirect(vm, Identifier::fromString(exec, "requestPayerEmail"), jsBoolean(paymentOptions.requestPayerEmail));
76     object->putDirect(vm, Identifier::fromString(exec, "requestPayerPhone"), jsBoolean(paymentOptions.requestPayerPhone));
77     object->putDirect(vm, Identifier::fromString(exec, "requestShipping"), jsBoolean(paymentOptions.requestShipping));
78     object->putDirect(vm, Identifier::fromString(exec, "shippingType"), jsNontrivialString(exec, convertEnumerationToString(paymentOptions.shippingType)));
79     return object;
80 }
81
82 static JSObject* objectForPaymentCurrencyAmount(VM& vm, ExecState* exec, const PaymentCurrencyAmount& paymentCurrencyAmount)
83 {
84     auto* object = constructEmptyObject(exec);
85     object->putDirect(vm, Identifier::fromString(exec, "currency"), jsString(exec, paymentCurrencyAmount.currency));
86     object->putDirect(vm, Identifier::fromString(exec, "value"), jsString(exec, paymentCurrencyAmount.value));
87     object->putDirect(vm, Identifier::fromString(exec, "currencySystem"), jsString(exec, paymentCurrencyAmount.currencySystem));
88     return object;
89 }
90
91 static JSObject* objectForPaymentItem(VM& vm, ExecState* exec, const PaymentItem& paymentItem)
92 {
93     auto* object = constructEmptyObject(exec);
94     object->putDirect(vm, Identifier::fromString(exec, "label"), jsString(exec, paymentItem.label));
95     object->putDirect(vm, Identifier::fromString(exec, "amount"), objectForPaymentCurrencyAmount(vm, exec, paymentItem.amount));
96     object->putDirect(vm, Identifier::fromString(exec, "pending"), jsBoolean(paymentItem.pending));
97     return object;
98 }
99
100 static JSObject* objectForPaymentShippingOption(VM& vm, ExecState* exec, const PaymentShippingOption& paymentShippingOption)
101 {
102     auto* object = constructEmptyObject(exec);
103     object->putDirect(vm, Identifier::fromString(exec, "id"), jsString(exec, paymentShippingOption.id));
104     object->putDirect(vm, Identifier::fromString(exec, "label"), jsString(exec, paymentShippingOption.label));
105     object->putDirect(vm, Identifier::fromString(exec, "amount"), objectForPaymentCurrencyAmount(vm, exec, paymentShippingOption.amount));
106     object->putDirect(vm, Identifier::fromString(exec, "selected"), jsBoolean(paymentShippingOption.selected));
107     return object;
108 }
109
110 static JSObject* objectForPaymentDetailsModifier(VM& vm, ExecState* exec, const PaymentDetailsModifier& modifier)
111 {
112     auto* additionalDisplayItems = constructEmptyArray(exec, nullptr);
113     for (unsigned i = 0; i < modifier.additionalDisplayItems.size(); ++i)
114         additionalDisplayItems->putDirectIndex(exec, i, objectForPaymentItem(vm, exec, modifier.additionalDisplayItems[i]));
115
116     auto* object = constructEmptyObject(exec);
117     object->putDirect(vm, Identifier::fromString(exec, "supportedMethods"), jsString(exec, modifier.supportedMethods));
118     object->putDirect(vm, Identifier::fromString(exec, "total"), !modifier.total ? jsNull() : objectForPaymentItem(vm, exec, *modifier.total));
119     object->putDirect(vm, Identifier::fromString(exec, "additionalDisplayItems"), additionalDisplayItems);
120     object->putDirect(vm, Identifier::fromString(exec, "data"), !modifier.data ? jsNull() : modifier.data.get());
121     return object;
122 }
123
124 static JSObject* objectForPaymentDetails(VM& vm, ExecState* exec, const PaymentDetailsInit& paymentDetails)
125 {
126     auto* displayItems = constructEmptyArray(exec, nullptr);
127     for (unsigned i = 0; i < paymentDetails.displayItems.size(); ++i)
128         displayItems->putDirectIndex(exec, i, objectForPaymentItem(vm, exec, paymentDetails.displayItems[i]));
129
130     auto* shippingOptions = constructEmptyArray(exec, nullptr);
131     for (unsigned i = 0; i < paymentDetails.shippingOptions.size(); ++i)
132         shippingOptions->putDirectIndex(exec, i, objectForPaymentShippingOption(vm, exec, paymentDetails.shippingOptions[i]));
133
134     auto* modifiers = constructEmptyArray(exec, nullptr);
135     for (unsigned i = 0; i < paymentDetails.modifiers.size(); ++i)
136         modifiers->putDirectIndex(exec, i, objectForPaymentDetailsModifier(vm, exec, paymentDetails.modifiers[i]));
137
138     auto* object = constructEmptyObject(exec);
139     object->putDirect(vm, Identifier::fromString(exec, "id"), jsString(exec, paymentDetails.id));
140     object->putDirect(vm, Identifier::fromString(exec, "total"), objectForPaymentItem(vm, exec, paymentDetails.total));
141     object->putDirect(vm, Identifier::fromString(exec, "displayItems"), displayItems);
142     object->putDirect(vm, Identifier::fromString(exec, "shippingOptions"), shippingOptions);
143     object->putDirect(vm, Identifier::fromString(exec, "modifiers"), modifiers);
144     return object;
145 }
146
147 static JSString* jsStringForPaymentRequestState(VM& vm, ExecState* exec, PaymentRequest::State state)
148 {
149     switch (state) {
150     case PaymentRequest::State::Created:
151         return jsNontrivialString(exec, ASCIILiteral("created"));
152     case PaymentRequest::State::Interactive:
153         return jsNontrivialString(exec, ASCIILiteral("interactive"));
154     case PaymentRequest::State::Closed:
155         return jsNontrivialString(exec, ASCIILiteral("closed"));
156     }
157
158     ASSERT_NOT_REACHED();
159     return jsEmptyString(&vm);
160 }
161 #endif
162
163 JSValue WebInjectedScriptHost::getInternalProperties(VM& vm, ExecState* exec, JSC::JSValue value)
164 {
165 #if ENABLE(PAYMENT_REQUEST)
166     auto scope = DECLARE_THROW_SCOPE(vm);
167
168     if (PaymentRequest* paymentRequest = JSPaymentRequest::toWrapped(vm, value)) {
169         unsigned index = 0;
170         auto* array = constructEmptyArray(exec, nullptr);
171         array->putDirectIndex(exec, index++, constructInternalProperty(vm, exec, ASCIILiteral("options"), objectForPaymentOptions(vm, exec, paymentRequest->paymentOptions())));
172         array->putDirectIndex(exec, index++, constructInternalProperty(vm, exec, ASCIILiteral("details"), objectForPaymentDetails(vm, exec, paymentRequest->paymentDetails())));
173         array->putDirectIndex(exec, index++, constructInternalProperty(vm, exec, ASCIILiteral("state"), jsStringForPaymentRequestState(vm, exec, paymentRequest->state())));
174         RETURN_IF_EXCEPTION(scope, { });
175         return array;
176     }
177 #else
178     UNUSED_PARAM(vm);
179     UNUSED_PARAM(exec);
180     UNUSED_PARAM(value);
181 #endif
182
183     return { };
184 }
185
186 bool WebInjectedScriptHost::isHTMLAllCollection(JSC::VM& vm, JSC::JSValue value)
187 {
188     return value.inherits(vm, JSHTMLAllCollection::info());
189 }
190
191 } // namespace WebCore