|
@@ -17,7 +17,9 @@
|
|
#include <LibWeb/Bindings/MainThreadVM.h>
|
|
#include <LibWeb/Bindings/MainThreadVM.h>
|
|
#include <LibWeb/Fetch/FetchMethod.h>
|
|
#include <LibWeb/Fetch/FetchMethod.h>
|
|
#include <LibWeb/Forward.h>
|
|
#include <LibWeb/Forward.h>
|
|
|
|
+#include <LibWeb/HTML/CanvasRenderingContext2D.h>
|
|
#include <LibWeb/HTML/EventLoop/EventLoop.h>
|
|
#include <LibWeb/HTML/EventLoop/EventLoop.h>
|
|
|
|
+#include <LibWeb/HTML/ImageBitmap.h>
|
|
#include <LibWeb/HTML/Scripting/ClassicScript.h>
|
|
#include <LibWeb/HTML/Scripting/ClassicScript.h>
|
|
#include <LibWeb/HTML/Scripting/Environments.h>
|
|
#include <LibWeb/HTML/Scripting/Environments.h>
|
|
#include <LibWeb/HTML/Scripting/ExceptionReporter.h>
|
|
#include <LibWeb/HTML/Scripting/ExceptionReporter.h>
|
|
@@ -32,6 +34,8 @@
|
|
#include <LibWeb/PerformanceTimeline/EntryTypes.h>
|
|
#include <LibWeb/PerformanceTimeline/EntryTypes.h>
|
|
#include <LibWeb/PerformanceTimeline/PerformanceObserver.h>
|
|
#include <LibWeb/PerformanceTimeline/PerformanceObserver.h>
|
|
#include <LibWeb/PerformanceTimeline/PerformanceObserverEntryList.h>
|
|
#include <LibWeb/PerformanceTimeline/PerformanceObserverEntryList.h>
|
|
|
|
+#include <LibWeb/Platform/EventLoopPlugin.h>
|
|
|
|
+#include <LibWeb/Platform/ImageCodecPlugin.h>
|
|
#include <LibWeb/UserTiming/PerformanceMark.h>
|
|
#include <LibWeb/UserTiming/PerformanceMark.h>
|
|
#include <LibWeb/UserTiming/PerformanceMeasure.h>
|
|
#include <LibWeb/UserTiming/PerformanceMeasure.h>
|
|
#include <LibWeb/WebIDL/AbstractOperations.h>
|
|
#include <LibWeb/WebIDL/AbstractOperations.h>
|
|
@@ -155,6 +159,92 @@ void WindowOrWorkerGlobalScopeMixin::queue_microtask(WebIDL::CallbackType& callb
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#dom-createimagebitmap
|
|
|
|
+JS::NonnullGCPtr<JS::Promise> WindowOrWorkerGlobalScopeMixin::create_image_bitmap(ImageBitmapSource image, Optional<ImageBitmapOptions> options) const
|
|
|
|
+{
|
|
|
|
+ return create_image_bitmap_impl(image, {}, {}, {}, {}, options);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#dom-createimagebitmap
|
|
|
|
+JS::NonnullGCPtr<JS::Promise> WindowOrWorkerGlobalScopeMixin::create_image_bitmap(ImageBitmapSource image, WebIDL::Long sx, WebIDL::Long sy, WebIDL::Long sw, WebIDL::Long sh, Optional<ImageBitmapOptions> options) const
|
|
|
|
+{
|
|
|
|
+ return create_image_bitmap_impl(image, sx, sy, sw, sh, options);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+JS::NonnullGCPtr<JS::Promise> WindowOrWorkerGlobalScopeMixin::create_image_bitmap_impl(ImageBitmapSource& image, Optional<WebIDL::Long> sx, Optional<WebIDL::Long> sy, Optional<WebIDL::Long> sw, Optional<WebIDL::Long> sh, Optional<ImageBitmapOptions>& options) const
|
|
|
|
+{
|
|
|
|
+ // 1. If either sw or sh is given and is 0, then return a promise rejected with a RangeError.
|
|
|
|
+ if (sw == 0 || sh == 0) {
|
|
|
|
+ auto promise = JS::Promise::create(this_impl().realm());
|
|
|
|
+ auto error_message = MUST(String::formatted("{} is an invalid value for {}", sw == 0 ? *sw : *sh, sw == 0 ? "sw"sv : "sh"sv));
|
|
|
|
+ promise->reject(JS::RangeError::create(this_impl().realm(), move(error_message)));
|
|
|
|
+ return promise;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // FIXME:
|
|
|
|
+ // 2. If either options's resizeWidth or options's resizeHeight is present and is 0, then return a promise rejected with an "InvalidStateError" DOMException.
|
|
|
|
+ (void)options;
|
|
|
|
+
|
|
|
|
+ // 3. Check the usability of the image argument. If this throws an exception or returns bad, then return a promise rejected with an "InvalidStateError" DOMException.
|
|
|
|
+ // FIXME: "Check the usability of the image argument" is only defined for CanvasImageSource, let's skip it for other types
|
|
|
|
+ if (image.has<CanvasImageSource>()) {
|
|
|
|
+ if (auto usability = check_usability_of_image(image.get<CanvasImageSource>()); usability.is_error() or usability.value() == CanvasImageSourceUsability::Bad) {
|
|
|
|
+ auto promise = JS::Promise::create(this_impl().realm());
|
|
|
|
+ promise->reject(WebIDL::InvalidStateError::create(this_impl().realm(), "image argument is not usable"_string));
|
|
|
|
+ return promise;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 4. Let p be a new promise.
|
|
|
|
+ auto p = JS::Promise::create(this_impl().realm());
|
|
|
|
+
|
|
|
|
+ // 5. Let imageBitmap be a new ImageBitmap object.
|
|
|
|
+ auto image_bitmap = ImageBitmap::create(this_impl().realm());
|
|
|
|
+
|
|
|
|
+ // 6. Switch on image:
|
|
|
|
+ image.visit(
|
|
|
|
+ [&](JS::Handle<FileAPI::Blob>& blob) {
|
|
|
|
+ // Run these step in parallel:
|
|
|
|
+ Platform::EventLoopPlugin::the().deferred_invoke([=, this]() {
|
|
|
|
+ // 1. Let imageData be the result of reading image's data. If an error occurs during reading of the
|
|
|
|
+ // object, then reject p with an "InvalidStateError" DOMException and abort these steps.
|
|
|
|
+ // FIXME: I guess this is always fine for us as the data is already read.
|
|
|
|
+ auto const image_data = blob->bytes();
|
|
|
|
+
|
|
|
|
+ // FIXME:
|
|
|
|
+ // 2. Apply the image sniffing rules to determine the file format of imageData, with MIME type of
|
|
|
|
+ // image (as given by image's type attribute) giving the official type.
|
|
|
|
+
|
|
|
|
+ // 3. If imageData is not in a supported image file format (e.g., it's not an image at all), or if
|
|
|
|
+ // imageData is corrupted in some fatal way such that the image dimensions cannot be obtained
|
|
|
|
+ // (e.g., a vector graphic with no natural size), then reject p with an "InvalidStateError" DOMException
|
|
|
|
+ // and abort these steps.
|
|
|
|
+ auto result = Web::Platform::ImageCodecPlugin::the().decode_image(image_data);
|
|
|
|
+ if (!result.has_value()) {
|
|
|
|
+ p->reject(WebIDL::InvalidStateError::create(this_impl().realm(), "image does not contain a supported image format"_string));
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 4. Set imageBitmap's bitmap data to imageData, cropped to the source rectangle with formatting.
|
|
|
|
+ // If this is an animated image, imageBitmap's bitmap data must only be taken from the default image
|
|
|
|
+ // of the animation (the one that the format defines is to be used when animation is not supported
|
|
|
|
+ // or is disabled), or, if there is no such image, the first frame of the animation.
|
|
|
|
+ image_bitmap->set_bitmap(result.value().frames.take_first().bitmap);
|
|
|
|
+
|
|
|
|
+ // 5. Resolve p with imageBitmap.
|
|
|
|
+ p->fulfill(image_bitmap);
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ [&](auto&) {
|
|
|
|
+ dbgln("(STUBBED) createImageBitmap() for non-blob types");
|
|
|
|
+ (void)sx;
|
|
|
|
+ (void)sy;
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ // 7. Return p.
|
|
|
|
+ return p;
|
|
|
|
+}
|
|
|
|
+
|
|
// https://html.spec.whatwg.org/multipage/structured-data.html#dom-structuredclone
|
|
// https://html.spec.whatwg.org/multipage/structured-data.html#dom-structuredclone
|
|
WebIDL::ExceptionOr<JS::Value> WindowOrWorkerGlobalScopeMixin::structured_clone(JS::Value value, StructuredSerializeOptions const& options) const
|
|
WebIDL::ExceptionOr<JS::Value> WindowOrWorkerGlobalScopeMixin::structured_clone(JS::Value value, StructuredSerializeOptions const& options) const
|
|
{
|
|
{
|