OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (c) 2013, Google 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 are | |
6 * met: | |
7 * | |
8 * * Redistributions of source code must retain the above copyright | |
9 * notice, this list of conditions and the following disclaimer. | |
10 * * Redistributions in binary form must reproduce the above | |
11 * copyright notice, this list of conditions and the following disclaimer | |
12 * in the documentation and/or other materials provided with the | |
13 * distribution. | |
14 * * Neither the name of Google Inc. nor the names of its | |
15 * contributors may be used to endorse or promote products derived from | |
16 * this software without specific prior written permission. | |
17 * | |
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
29 */ | |
30 | |
31 #include "config.h" | |
32 #include "core/page/ImageBitmapFactories.h" | |
33 | |
34 #include "RuntimeEnabledFeatures.h" | |
35 #include "V8ImageBitmap.h" | |
36 #include "bindings/v8/ExceptionState.h" | |
37 #include "core/dom/ExceptionCode.h" | |
38 #include "core/html/HTMLCanvasElement.h" | |
39 #include "core/html/HTMLImageElement.h" | |
40 #include "core/html/HTMLVideoElement.h" | |
41 #include "core/html/ImageData.h" | |
42 #include "core/html/canvas/CanvasRenderingContext2D.h" | |
43 #include "core/page/DOMWindow.h" | |
44 #include "core/page/ImageBitmap.h" | |
45 | |
46 namespace WebCore { | |
47 | |
48 namespace ImageBitmapFactories { | |
49 | |
50 static LayoutSize sizeFor(HTMLImageElement* image) | |
51 { | |
52 if (ImageResource* cachedImage = image->cachedImage()) | |
53 return cachedImage->imageSizeForRenderer(image->renderer(), 1.0f); // FI
XME: Not sure about this. | |
54 return IntSize(); | |
55 } | |
56 | |
57 static IntSize sizeFor(HTMLVideoElement* video) | |
58 { | |
59 if (MediaPlayer* player = video->player()) | |
60 return player->naturalSize(); | |
61 return IntSize(); | |
62 } | |
63 | |
64 static ScriptObject resolveImageBitmap(PassRefPtr<ImageBitmap> imageBitmap) | |
65 { | |
66 // Promises must be enabled. | |
67 ASSERT(RuntimeEnabledFeatures::promiseEnabled()); | |
68 | |
69 RefPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(); | |
70 resolver->fulfill(imageBitmap); | |
71 return resolver->promise(); | |
72 } | |
73 | |
74 ScriptObject createImageBitmap(EventTarget* eventTarget, HTMLImageElement* image
, ExceptionState& es) | |
75 { | |
76 LayoutSize s = sizeFor(image); | |
77 return createImageBitmap(eventTarget, image, 0, 0, s.width(), s.height(), es
); | |
78 } | |
79 | |
80 ScriptObject createImageBitmap(EventTarget* eventTarget, HTMLImageElement* image
, int sx, int sy, int sw, int sh, ExceptionState& es) | |
81 { | |
82 if (!image) { | |
83 es.throwTypeError(); | |
84 return ScriptObject(); | |
85 } | |
86 if (!image->cachedImage()) { | |
87 es.throwDOMException(InvalidStateError); | |
88 return ScriptObject(); | |
89 } | |
90 if (image->cachedImage()->image()->isSVGImage()) { | |
91 es.throwDOMException(InvalidStateError); | |
92 return ScriptObject(); | |
93 } | |
94 if (!sw || !sh) { | |
95 es.throwDOMException(IndexSizeError); | |
96 return ScriptObject(); | |
97 } | |
98 if (!image->cachedImage()->image()->hasSingleSecurityOrigin()) { | |
99 es.throwDOMException(SecurityError); | |
100 return ScriptObject(); | |
101 } | |
102 if (!image->cachedImage()->passesAccessControlCheck(eventTarget->toDOMWindow
()->document()->securityOrigin()) | |
103 && eventTarget->toDOMWindow()->document()->securityOrigin()->taintsCanvas(im
age->src())) { | |
104 es.throwDOMException(SecurityError); | |
105 return ScriptObject(); | |
106 } | |
107 // FIXME: make ImageBitmap creation asynchronous crbug.com/258082 | |
108 return resolveImageBitmap(ImageBitmap::create(image, IntRect(sx, sy, sw, sh)
)); | |
109 } | |
110 | |
111 ScriptObject createImageBitmap(EventTarget* eventTarget, HTMLVideoElement* video
, ExceptionState& es) | |
112 { | |
113 IntSize s = sizeFor(video); | |
114 return createImageBitmap(eventTarget, video, 0, 0, s.width(), s.height(), es
); | |
115 } | |
116 | |
117 ScriptObject createImageBitmap(EventTarget* eventTarget, HTMLVideoElement* video
, int sx, int sy, int sw, int sh, ExceptionState& es) | |
118 { | |
119 if (!video) { | |
120 es.throwTypeError(); | |
121 return ScriptObject(); | |
122 } | |
123 if (!video->player()) { | |
124 es.throwDOMException(InvalidStateError); | |
125 return ScriptObject(); | |
126 } | |
127 if (video->networkState() == HTMLMediaElement::NETWORK_EMPTY) { | |
128 es.throwDOMException(InvalidStateError); | |
129 return ScriptObject(); | |
130 } | |
131 if (video->player()->readyState() <= MediaPlayer::HaveMetadata) { | |
132 es.throwDOMException(InvalidStateError); | |
133 return ScriptObject(); | |
134 } | |
135 if (!sw || !sh) { | |
136 es.throwDOMException(IndexSizeError); | |
137 return ScriptObject(); | |
138 } | |
139 if (!video->hasSingleSecurityOrigin()) { | |
140 es.throwDOMException(SecurityError); | |
141 return ScriptObject(); | |
142 } | |
143 if (!video->player()->didPassCORSAccessCheck() && eventTarget->toDOMWindow()
->document()->securityOrigin()->taintsCanvas(video->currentSrc())) { | |
144 es.throwDOMException(SecurityError); | |
145 return ScriptObject(); | |
146 } | |
147 // FIXME: make ImageBitmap creation asynchronous crbug.com/258082 | |
148 return resolveImageBitmap(ImageBitmap::create(video, IntRect(sx, sy, sw, sh)
)); | |
149 } | |
150 | |
151 ScriptObject createImageBitmap(EventTarget* eventTarget, CanvasRenderingContext2
D* context, ExceptionState& es) | |
152 { | |
153 return createImageBitmap(eventTarget, context->canvas(), es); | |
154 } | |
155 | |
156 ScriptObject createImageBitmap(EventTarget* eventTarget, CanvasRenderingContext2
D* context, int sx, int sy, int sw, int sh, ExceptionState& es) | |
157 { | |
158 return createImageBitmap(eventTarget, context->canvas(), sx, sy, sw, sh, es)
; | |
159 } | |
160 | |
161 ScriptObject createImageBitmap(EventTarget* eventTarget, HTMLCanvasElement* canv
as, ExceptionState& es) | |
162 { | |
163 return createImageBitmap(eventTarget, canvas, 0, 0, canvas->width(), canvas-
>height(), es); | |
164 } | |
165 | |
166 ScriptObject createImageBitmap(EventTarget* eventTarget, HTMLCanvasElement* canv
as, int sx, int sy, int sw, int sh, ExceptionState& es) | |
167 { | |
168 if (!canvas) { | |
169 es.throwTypeError(); | |
170 return ScriptObject(); | |
171 } | |
172 if (!canvas->originClean()) { | |
173 es.throwDOMException(InvalidStateError); | |
174 return ScriptObject(); | |
175 } | |
176 if (!sw || !sh) { | |
177 es.throwDOMException(IndexSizeError); | |
178 return ScriptObject(); | |
179 } | |
180 // FIXME: make ImageBitmap creation asynchronous crbug.com/258082 | |
181 return resolveImageBitmap(ImageBitmap::create(canvas, IntRect(sx, sy, sw, sh
))); | |
182 } | |
183 | |
184 ScriptObject createImageBitmap(EventTarget* eventTarget, ImageData* data, Except
ionState& es) | |
185 { | |
186 return createImageBitmap(eventTarget, data, 0, 0, data->width(), data->heigh
t(), es); | |
187 } | |
188 | |
189 ScriptObject createImageBitmap(EventTarget* eventTarget, ImageData* data, int sx
, int sy, int sw, int sh, ExceptionState& es) | |
190 { | |
191 if (!data) { | |
192 es.throwTypeError(); | |
193 return ScriptObject(); | |
194 } | |
195 if (!sw || !sh) { | |
196 es.throwDOMException(IndexSizeError); | |
197 return ScriptObject(); | |
198 } | |
199 // FIXME: make ImageBitmap creation asynchronous crbug.com/258082 | |
200 return resolveImageBitmap(ImageBitmap::create(data, IntRect(sx, sy, sw, sh))
); | |
201 } | |
202 | |
203 ScriptObject createImageBitmap(EventTarget* eventTarget, ImageBitmap* bitmap, Ex
ceptionState& es) | |
204 { | |
205 return createImageBitmap(eventTarget, bitmap, 0, 0, bitmap->width(), bitmap-
>height(), es); | |
206 } | |
207 | |
208 ScriptObject createImageBitmap(EventTarget* eventTarget, ImageBitmap* bitmap, in
t sx, int sy, int sw, int sh, ExceptionState& es) | |
209 { | |
210 if (!bitmap) { | |
211 es.throwTypeError(); | |
212 return ScriptObject(); | |
213 } | |
214 if (!sw || !sh) { | |
215 es.throwDOMException(IndexSizeError); | |
216 return ScriptObject(); | |
217 } | |
218 // FIXME: make ImageBitmap creation asynchronous crbug.com/258082 | |
219 return resolveImageBitmap(ImageBitmap::create(bitmap, IntRect(sx, sy, sw, sh
))); | |
220 } | |
221 | |
222 } // namespace ImageBitmapFactories | |
223 } // namespace WebCore | |
OLD | NEW |