diff --git a/CMakeLists.txt b/CMakeLists.txt index d94ff32..0ccf7a7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,6 +36,7 @@ set(SOURCES src/application_cache.cc src/event_target.cc src/export.cc src/external.cc + src/file_reader.cc src/float32_array.cc src/float64_array.cc src/history.cc @@ -93,6 +94,7 @@ set(SOURCES src/application_cache.cc src/range.cc src/regexp.cc src/rendering_context.cc + src/response.cc src/storage.cc src/string.cc src/style_sheet.cc diff --git a/examples/promise.cc b/examples/promise.cc index 7ebeb9d..b8fbd27 100644 --- a/examples/promise.cc +++ b/examples/promise.cc @@ -10,10 +10,39 @@ static void promiseTest() }); promise->then([](const std::string &value) { html5::window->console->log(value); + return html5::Promise::resolve("bar"); + })->then([](const std::string &value) { + html5::window->console->log(value); + return html5::Promise::resolve(0.0); }); html5::window->console->log(promise); } +static void fetchImageTest(const std::string &imageURL) +{ + HTML5_INIT(); + html5::fetch(imageURL)->then([](html5::Response *response) { + return response->blob(); + })->then([](html5::Blob *blob) { + auto reader = html5::FileReader::create(); + reader->onload = [reader](html5::Event *event) { + std::string data = reader->result; + auto image = html5::HTMLImageElement::create(); + image->src = data; + html5::window->document->body->appendChild(image); + }; + reader->readAsDataURL(blob); + return nullptr; + })->catchError([]{ + html5::window->console->log("catch"); + return nullptr; + })->finally([]{ + html5::window->console->log("finally"); + return nullptr; + }); +} + EMSCRIPTEN_BINDINGS(Promise) { emscripten::function("promiseTest", &promiseTest); + emscripten::function("fetchImageTest", &fetchImageTest); } diff --git a/include/class.h b/include/class.h index c598a54..85b3b75 100644 --- a/include/class.h +++ b/include/class.h @@ -31,6 +31,7 @@ #include "event.h" #include "event_target.h" #include "external.h" +#include "file_reader.h" #include "float32_array.h" #include "float64_array.h" #include "history.h" @@ -84,6 +85,7 @@ #include "processing_instruction.h" #include "promise.h" #include "range.h" +#include "response.h" #include "rendering_context.h" #include "storage.h" #include "style_sheet.h" diff --git a/include/export.h b/include/export.h index aec0378..23e523f 100644 --- a/include/export.h +++ b/include/export.h @@ -51,6 +51,7 @@ extern Promise *createImageBitmap(Blob *image, long sx, long sy, long sw, long s extern Promise *createImageBitmap(ImageData *image, long sx, long sy, long sw, long sh); extern Promise *createImageBitmap(CanvasRenderingContext2D *image, long sx, long sy, long sw, long sh); extern Promise *createImageBitmap(ImageBitmap *image, long sx, long sy, long sw, long sh); +extern Promise *fetch(const std::string &url); extern void focus(); extern CSSStyleDeclaration *getComputedStyle(Element *elt, std::string pseudoElt); extern WindowProxy *getter(void *indexName); diff --git a/include/file_reader.h b/include/file_reader.h new file mode 100644 index 0000000..a96e149 --- /dev/null +++ b/include/file_reader.h @@ -0,0 +1,37 @@ +#pragma once + +#include "event_target.h" + +NAMESPACE_HTML5_BEGIN; + +class Blob; +class File; +class ArrayBuffer; + +class FileReader : public EventTarget { +public: + struct { + FileReader &self; + operator ArrayBuffer *() { return self.resultArrayBuffer(); }; + operator std::string () { return self.resultString(); }; + } result{*this}; + HTML5_EVENT_HANDLER_PROPERTY(FileReader, EventHandler, onload); + + FileReader(emscripten::val v); + virtual ~FileReader(); + static FileReader *create(); + void abort(); + void readAsArrayBuffer(Blob *blob); + void readAsArrayBuffer(File *file); + void readAsBinaryString(Blob *blob); + void readAsBinaryString(File *file); + void readAsDataURL(Blob *blob); + void readAsDataURL(File *file); + void readAsText(Blob *blob, const std::string &encoding = "utf-8"); + void readAsText(File *file, const std::string &encoding = "utf-8"); + + ArrayBuffer *resultArrayBuffer() const; + std::string resultString() const; +}; + +NAMESPACE_HTML5_END; \ No newline at end of file diff --git a/include/libhtml5.h b/include/libhtml5.h index 1199b54..b08193d 100644 --- a/include/libhtml5.h +++ b/include/libhtml5.h @@ -373,6 +373,33 @@ template std::vector toObjectArray(emscripten::val v) } \ HTML5_BIND_METHOD(klass, callback_ ## name); +#define HTML5_EVENT_HANDLER_PROPERTY_IMPL_NEW(klass, type, name) \ + type klass::get_ ## name() const \ + { \ + HTML5_PROPERTY_TRACE_GETTER(name); \ + return this->_ ## name; \ + } \ + \ + void klass::set_ ## name(type value) \ + { \ + HTML5_PROPERTY_TRACE_SETTER(name); \ + this->_ ## name = value; \ + const char *key = __to_text__(to ## klass); \ + const char *callbackFnName = __to_text__(callback_ ## name); \ + EM_ASM_({ \ + var key = Module['toString']($1); \ + var callbackFnName = Module['toString']($2); \ + var elem = Module[key]($0); \ + elem['_value'][#name] = function(e) { elem[callbackFnName](e); }; \ + }, this, key, callbackFnName); \ + } \ + void klass::callback_ ## name(emscripten::val e) \ + { \ + if (!this->_ ## name) return; \ + (this->_ ## name)(Event::create(e)); \ + } \ + HTML5_BIND_METHOD(klass, callback_ ## name); + #define HTML5_ERROR_HANDLER_PROPERTY_IMPL(klass, type, name) \ type klass::get_ ## name() const \ { \ diff --git a/include/promise.h b/include/promise.h index 97c079a..d2d0404 100644 --- a/include/promise.h +++ b/include/promise.h @@ -5,12 +5,35 @@ NAMESPACE_HTML5_BEGIN; -typedef std::function chainVoid; -typedef std::function chainString; +typedef std::function PromiseVoidFunction; +typedef std::function PromiseDoubleFunction; +typedef std::function PromiseStringFunction; +typedef std::function PromiseObjectFunction; -typedef std::function executor; -typedef std::function executorString; +typedef std::function PromiseVoidPromiseFunction; +typedef std::function PromiseDoublePromiseFunction; +typedef std::function PromiseStringPromiseFunction; +typedef std::function PromiseObjectPromiseFunction; +typedef std::function PromiseVoidVoidPairFunction; +typedef std::function PromiseVoidDoublePairFunction; +typedef std::function PromiseVoidStringPairFunction; +typedef std::function PromiseVoidObjectPairFunction; + +typedef std::function PromiseDoubleVoidPairFunction; +typedef std::function PromiseDoubleDoublePairFunction; +typedef std::function PromiseDoubleStringPairFunction; +typedef std::function PromiseDoubleObjectPairFunction; + +typedef std::function PromiseStringVoidPairFunction; +typedef std::function PromiseStringDoublePairFunction; +typedef std::function PromiseStringStringPairFunction; +typedef std::function PromiseStringObjectPairFunction; + +typedef std::function PromiseObjectVoidPairFunction; +typedef std::function PromiseObjectDoublePairFunction; +typedef std::function PromiseObjectStringPairFunction; +typedef std::function PromiseObjectObjectPairFunction; class Promise : public Object { public: @@ -19,21 +42,210 @@ class Promise : public Object { Promise(emscripten::val v); virtual ~Promise(); - static Promise *create(executor fn); - static Promise *create(executorString fn); + static Promise *create(PromiseVoidVoidPairFunction fn); + static Promise *create(PromiseVoidDoublePairFunction fn); + static Promise *create(PromiseVoidStringPairFunction fn); + static Promise *create(PromiseVoidObjectPairFunction fn); + static Promise *create(PromiseDoubleVoidPairFunction fn); + static Promise *create(PromiseDoubleDoublePairFunction fn); + static Promise *create(PromiseDoubleStringPairFunction fn); + static Promise *create(PromiseDoubleObjectPairFunction fn); + static Promise *create(PromiseStringVoidPairFunction fn); + static Promise *create(PromiseStringDoublePairFunction fn); + static Promise *create(PromiseStringStringPairFunction fn); + static Promise *create(PromiseStringObjectPairFunction fn); + static Promise *create(PromiseObjectVoidPairFunction fn); + static Promise *create(PromiseObjectDoublePairFunction fn); + static Promise *create(PromiseObjectStringPairFunction fn); + static Promise *create(PromiseObjectObjectPairFunction fn); static Promise *create(emscripten::val v); - Promise *all(std::vector iterable); - Promise *race(std::vector iterable); - Promise *reject(std::string reason); - Promise *resolve(void *value); - Promise *pcatch(std::function onRejected); - Promise *then(chainString onFulfilled); - - executorString execStr; - std::vector chainFns; - - void executeString(emscripten::val resolve, emscripten::val reject); - void callbackThenString(emscripten::val resolve); + Promise *then(PromiseVoidPromiseFunction onFulfilled); + Promise *then(PromiseVoidPromiseFunction onFulfilled, PromiseVoidPromiseFunction onRejected); + Promise *then(PromiseVoidPromiseFunction onFulfilled, PromiseDoublePromiseFunction onRejected); + Promise *then(PromiseVoidPromiseFunction onFulfilled, PromiseStringPromiseFunction onRejected); + Promise *then(PromiseVoidPromiseFunction onFulfilled, PromiseObjectPromiseFunction onRejected); + Promise *then(PromiseDoublePromiseFunction onFulfilled); + Promise *then(PromiseDoublePromiseFunction onFulfilled, PromiseVoidPromiseFunction onRejected); + Promise *then(PromiseDoublePromiseFunction onFulfilled, PromiseDoublePromiseFunction onRejected); + Promise *then(PromiseDoublePromiseFunction onFulfilled, PromiseStringPromiseFunction onRejected); + Promise *then(PromiseDoublePromiseFunction onFulfilled, PromiseObjectPromiseFunction onRejected); + Promise *then(PromiseStringPromiseFunction onFulfilled); + Promise *then(PromiseStringPromiseFunction onFulfilled, PromiseVoidPromiseFunction onRejected); + Promise *then(PromiseStringPromiseFunction onFulfilled, PromiseDoublePromiseFunction onRejected); + Promise *then(PromiseStringPromiseFunction onFulfilled, PromiseStringPromiseFunction onRejected); + Promise *then(PromiseStringPromiseFunction onFulfilled, PromiseObjectPromiseFunction onRejected); + template Promise *then(std::function onFulfilled) { + auto fn = new PromiseChainFunction(); + PromiseObjectPromiseFunction f = [onFulfilled](const Object &o) { + return onFulfilled((T)(&o)); + }; + fn->onFulfilled.op = f; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then(function(v) { return elem.callbackThenOP(v); }); + }, this); + return this; + }; + template Promise *then(std::function onFulfilled, PromiseVoidPromiseFunction onRejected) { + auto fn = new PromiseChainFunction(); + PromiseObjectPromiseFunction f = [onFulfilled](const Object &o) { + return onFulfilled((T)(&o)); + }; + fn->onFulfilled.op = f; + fn->onRejected.vp = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function(v) { return elem.callbackThenOP(v); }, + function() { return elem.callbackRejectVP(); } + ); + }, this); + return this; + }; + template Promise *then(std::function onFulfilled, PromiseDoublePromiseFunction onRejected) { + auto fn = new PromiseChainFunction(); + PromiseObjectPromiseFunction f = [onFulfilled](const Object &o) { + return onFulfilled((T)(&o)); + }; + fn->onFulfilled.op = f; + fn->onRejected.dp = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function(v) { return elem.callbackThenOP(v); }, + function(v) { return elem.callbackRejectDP(v); } + ); + }, this); + return this; + }; + template Promise *then(std::function onFulfilled, PromiseStringPromiseFunction onRejected) { + auto fn = new PromiseChainFunction(); + PromiseObjectPromiseFunction f = [onFulfilled](const Object &o) { + return onFulfilled((T)(&o)); + }; + fn->onFulfilled.op = f; + fn->onRejected.sp = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function(v) { return elem.callbackThenOP(v); }, + function(v) { return elem.callbackRejectSP(v); } + ); + }, this); + return this; + }; + template Promise *then(std::function onFulfilled, PromiseObjectPromiseFunction onRejected) { + auto fn = new PromiseChainFunction(); + PromiseObjectPromiseFunction f = [onFulfilled](const Object &o) { + return onFulfilled((T)(&o)); + }; + fn->onFulfilled.op = f; + fn->onRejected.op = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function(v) { return elem.callbackThenOP(); }, + function(v) { return elem.callbackRejectOP(v); } + ); + }, this); + return this; + }; + Promise *catchError(PromiseVoidPromiseFunction onRejected); + Promise *catchError(PromiseDoublePromiseFunction onRejected); + Promise *catchError(PromiseStringPromiseFunction onRejected); + Promise *catchError(PromiseObjectPromiseFunction onRejected); + Promise *finally(PromiseVoidPromiseFunction onFinally); + + static Promise *all(std::vector iterable); + static Promise *race(std::vector iterable); + static Promise *reject(); + static Promise *reject(double value); + static Promise *reject(const std::string &value); + static Promise *reject(Object *value); + static Promise *resolve(); + static Promise *resolve(double value); + static Promise *resolve(const std::string &value); + static Promise *resolve(Object *value); + + PromiseVoidVoidPairFunction vvPairFn; + PromiseVoidDoublePairFunction vdPairFn; + PromiseVoidStringPairFunction vsPairFn; + PromiseVoidObjectPairFunction voPairFn; + PromiseDoubleVoidPairFunction dvPairFn; + PromiseDoubleDoublePairFunction ddPairFn; + PromiseDoubleStringPairFunction dsPairFn; + PromiseDoubleObjectPairFunction doPairFn; + PromiseStringVoidPairFunction svPairFn; + PromiseStringDoublePairFunction sdPairFn; + PromiseStringStringPairFunction ssPairFn; + PromiseStringObjectPairFunction soPairFn; + PromiseObjectVoidPairFunction ovPairFn; + PromiseObjectDoublePairFunction odPairFn; + PromiseObjectStringPairFunction osPairFn; + PromiseObjectObjectPairFunction ooPairFn; + + union PromiseFunction { + PromiseVoidPromiseFunction vp; + PromiseDoublePromiseFunction dp; + PromiseStringPromiseFunction sp; + PromiseObjectPromiseFunction op; + PromiseFunction() : vp([]{return nullptr;}) {}; + ~PromiseFunction(){}; + }; + + class PromiseChainFunction { + public: + PromiseFunction onFulfilled; + PromiseFunction onRejected; + PromiseChainFunction(){}; + ~PromiseChainFunction(){}; + }; + + std::vector chains; + PromiseFunction catchErrorFn; + PromiseFunction finallyFn; + void callbackVV(emscripten::val resolve, emscripten::val reject); + void callbackVD(emscripten::val resolve, emscripten::val reject); + void callbackVS(emscripten::val resolve, emscripten::val reject); + void callbackVO(emscripten::val resolve, emscripten::val reject); + void callbackDV(emscripten::val resolve, emscripten::val reject); + void callbackDD(emscripten::val resolve, emscripten::val reject); + void callbackDS(emscripten::val resolve, emscripten::val reject); + void callbackDO(emscripten::val resolve, emscripten::val reject); + void callbackSV(emscripten::val resolve, emscripten::val reject); + void callbackSD(emscripten::val resolve, emscripten::val reject); + void callbackSS(emscripten::val resolve, emscripten::val reject); + void callbackSO(emscripten::val resolve, emscripten::val reject); + void callbackOV(emscripten::val resolve, emscripten::val reject); + void callbackOD(emscripten::val resolve, emscripten::val reject); + void callbackOS(emscripten::val resolve, emscripten::val reject); + void callbackOO(emscripten::val resolve, emscripten::val reject); + void callbackThenV(); + void callbackThenD(emscripten::val v); + void callbackThenS(emscripten::val v); + void callbackThenO(emscripten::val v); + void callbackRejectV(); + void callbackRejectD(emscripten::val v); + void callbackRejectS(emscripten::val v); + void callbackRejectO(emscripten::val v); + emscripten::val callbackThenVP(); + emscripten::val callbackThenDP(emscripten::val v); + emscripten::val callbackThenSP(emscripten::val v); + emscripten::val callbackThenOP(emscripten::val v); + emscripten::val callbackRejectVP(); + emscripten::val callbackRejectDP(emscripten::val v); + emscripten::val callbackRejectSP(emscripten::val v); + emscripten::val callbackRejectOP(emscripten::val v); + emscripten::val callbackCatchVP(); + emscripten::val callbackCatchDP(emscripten::val v); + emscripten::val callbackCatchSP(emscripten::val v); + emscripten::val callbackCatchOP(emscripten::val v); + emscripten::val callbackFinally(); }; NAMESPACE_HTML5_END; diff --git a/include/response.h b/include/response.h new file mode 100644 index 0000000..c692053 --- /dev/null +++ b/include/response.h @@ -0,0 +1,36 @@ +#pragma once + +#include "libhtml5.h" + +NAMESPACE_HTML5_BEGIN; + +class Headers; +class ReadableStream; + +class Response : public Object { +public: + + HTML5_READONLY_PROPERTY_OBJECT(Response, Headers, headers); + HTML5_READONLY_PROPERTY(Response, bool, ok); + HTML5_READONLY_PROPERTY(Response, bool, redirected); + HTML5_READONLY_PROPERTY(Response, int, status); + HTML5_READONLY_PROPERTY(Response, std::string, type); + HTML5_READONLY_PROPERTY(Response, std::string, url); + HTML5_PROPERTY(Response, bool, useFinalURL); + HTML5_READONLY_PROPERTY_OBJECT(Response, ReadableStream, body); + HTML5_READONLY_PROPERTY(Response, bool, bodyUsed); + + Response(emscripten::val v); + virtual ~Response(); + static Response *create(emscripten::val v); + Response *clone(); + Response *error(); + Response *redirect(const std::string &url, int status = 0); + Promise *arrayBuffer(); + Promise *blob(); + Promise *formData(); + Promise *json(); + Promise *text(); +}; + +NAMESPACE_HTML5_END; diff --git a/include/window.h b/include/window.h index 17c493c..f3f96ea 100644 --- a/include/window.h +++ b/include/window.h @@ -155,6 +155,7 @@ class Window : public EventTarget { Promise *createImageBitmap(ImageData *image, long sx, long sy, long sw, long sh); Promise *createImageBitmap(CanvasRenderingContext2D *image, long sx, long sy, long sw, long sh); Promise *createImageBitmap(ImageBitmap *image, long sx, long sy, long sw, long sh); + Promise *fetch(const std::string &url); void focus(); CSSStyleDeclaration *getComputedStyle(Element *elt, std::string pseudoElt); WindowProxy *getter(void *indexName); diff --git a/src/export.cc b/src/export.cc index 38db19d..be0ee41 100644 --- a/src/export.cc +++ b/src/export.cc @@ -83,6 +83,11 @@ Promise *createImageBitmap(ImageBitmap *image, long sx, long sy, long sw, long s return window->createImageBitmap(image, sx, sy, sw, sh); } +Promise *fetch(const std::string &url) +{ + return window->fetch(url); +} + void focus() { window->focus(); diff --git a/src/file_reader.cc b/src/file_reader.cc new file mode 100644 index 0000000..7eca7eb --- /dev/null +++ b/src/file_reader.cc @@ -0,0 +1,80 @@ +#include "file_reader.h" +#include "blob.h" +#include "array_buffer.h" + +USING_NAMESPACE_HTML5; + +HTML5_BIND_CLASS(FileReader); + +FileReader::FileReader(emscripten::val v) : + EventTarget(v) +{ +} + +FileReader::~FileReader() +{ +} + +FileReader *FileReader::create() +{ + auto reader = new FileReader(HTML5_NEW_PRIMITIVE_INSTANCE(FileReader)); + reader->autorelease(); + return reader; +} + +void FileReader::abort() +{ + HTML5_CALL(this->v, abort); +} + +void FileReader::readAsArrayBuffer(Blob *blob) +{ + HTML5_CALL(this->v, readAsArrayBuffer, blob->v); +} + +void FileReader::readAsArrayBuffer(File *file) +{ +// HTML5_CALL(this->v, readAsArrayBuffer, file->v); +} + +void FileReader::readAsBinaryString(Blob *blob) +{ + HTML5_CALL(this->v, readAsBinaryString, blob->v); +} + +void FileReader::readAsBinaryString(File *file) +{ + //HTML5_CALL(this->v, readAsBinaryString, file->v); +} + +void FileReader::readAsDataURL(Blob *blob) +{ + HTML5_CALL(this->v, readAsDataURL, blob->v); +} + +void FileReader::readAsDataURL(File *file) +{ + //HTML5_CALL(this->v, readAsDataURL, file->v); +} + +void FileReader::readAsText(Blob *blob, const std::string &encoding) +{ + HTML5_CALL(this->v, readAsText, blob->v, encoding); +} + +void FileReader::readAsText(File *file, const std::string &encoding) +{ + //HTML5_CALL(this->v, readAsText, file->v, encoding); +} + +ArrayBuffer *FileReader::resultArrayBuffer() const +{ + return ArrayBuffer::create(this->v["result"]); +} + +std::string FileReader::resultString() const +{ + return this->v["result"].as(); +} + +HTML5_EVENT_HANDLER_PROPERTY_IMPL_NEW(FileReader, EventHandler, onload); \ No newline at end of file diff --git a/src/promise.cc b/src/promise.cc index 4c8bc14..9a286af 100644 --- a/src/promise.cc +++ b/src/promise.cc @@ -22,59 +22,940 @@ Promise *Promise::create(emscripten::val v) return p; } -Promise *Promise::create(executor fn) +Promise *Promise::create(PromiseVoidVoidPairFunction fn) { Promise *p = new Promise(emscripten::val(0)); - EM_ASM_({ + p->vvPairFn = fn; + EM_ASM_({ + var elem = Module['toPromise']($0); + elem['_value'] = new Promise(function(resolve, reject) { + elem.callbackVV({call: resolve}, {call: reject}); + }); + }, p); + p->autorelease(); + return p; +} + +Promise *Promise::create(PromiseVoidDoublePairFunction fn) +{ + Promise *p = new Promise(emscripten::val(0)); + p->vdPairFn = fn; + EM_ASM_({ + var elem = Module['toPromise']($0); + elem['_value'] = new Promise(function(resolve, reject) { + elem.callbackVD({call: resolve}, {call: reject}); + }); + }, p); + p->autorelease(); + return p; +} + +Promise *Promise::create(PromiseVoidStringPairFunction fn) +{ + Promise *p = new Promise(emscripten::val(0)); + p->vsPairFn = fn; + EM_ASM_({ + var elem = Module['toPromise']($0); + elem['_value'] = new Promise(function(resolve, reject) { + elem.callbackVS({call: resolve}, {call: reject}); + }); + }, p); + p->autorelease(); + return p; +} + +Promise *Promise::create(PromiseVoidObjectPairFunction fn) +{ + Promise *p = new Promise(emscripten::val(0)); + p->voPairFn = fn; + EM_ASM_({ + var elem = Module['toPromise']($0); + elem['_value'] = new Promise(function(resolve, reject) { + elem.callbackVO({call: resolve}, {call: reject}); + }); + }, p); + p->autorelease(); + return p; +} + +Promise *Promise::create(PromiseDoubleVoidPairFunction fn) +{ + Promise *p = new Promise(emscripten::val(0)); + p->dvPairFn = fn; + EM_ASM_({ + var elem = Module['toPromise']($0); + elem['_value'] = new Promise(function(resolve, reject) { + elem.callbackDV({call: resolve}, {call: reject}); + }); + }, p); + p->autorelease(); + return p; +} + +Promise *Promise::create(PromiseDoubleDoublePairFunction fn) +{ + Promise *p = new Promise(emscripten::val(0)); + p->ddPairFn = fn; + EM_ASM_({ + var elem = Module['toPromise']($0); + elem['_value'] = new Promise(function(resolve, reject) { + elem.callbackDD({call: resolve}, {call: reject}); + }); + }, p); + p->autorelease(); + return p; +} + +Promise *Promise::create(PromiseDoubleStringPairFunction fn) +{ + Promise *p = new Promise(emscripten::val(0)); + p->dsPairFn = fn; + EM_ASM_({ + var elem = Module['toPromise']($0); + elem['_value'] = new Promise(function(resolve, reject) { + elem.callbackDS({call: resolve}, {call: reject}); + }); + }, p); + p->autorelease(); + return p; +} + +Promise *Promise::create(PromiseDoubleObjectPairFunction fn) +{ + Promise *p = new Promise(emscripten::val(0)); + p->doPairFn = fn; + EM_ASM_({ var elem = Module['toPromise']($0); - elem['_value'] = new Promise(function(resolve, reject) { elem.callbackThen(resolve, reject); }); + elem['_value'] = new Promise(function(resolve, reject) { + elem.callbackDO({call: resolve}, {call: reject}); + }); }, p); p->autorelease(); return p; } -Promise *Promise::create(executorString fn) +Promise *Promise::create(PromiseStringVoidPairFunction fn) { Promise *p = new Promise(emscripten::val(0)); - p->execStr = fn; - EM_ASM_({ + p->svPairFn = fn; + EM_ASM_({ var elem = Module['toPromise']($0); elem['_value'] = new Promise(function(resolve, reject) { - elem.executeString({call: resolve}, reject); + elem.callbackSV({call: resolve}, {call: reject}); }); }, p); p->autorelease(); return p; } -HTML5_BIND_METHOD(Promise, executeString); +Promise *Promise::create(PromiseStringDoublePairFunction fn) +{ + Promise *p = new Promise(emscripten::val(0)); + p->sdPairFn = fn; + EM_ASM_({ + var elem = Module['toPromise']($0); + elem['_value'] = new Promise(function(resolve, reject) { + elem.callbackSD({call: resolve}, {call: reject}); + }); + }, p); + p->autorelease(); + return p; +} + +Promise *Promise::create(PromiseStringStringPairFunction fn) +{ + Promise *p = new Promise(emscripten::val(0)); + p->ssPairFn = fn; + EM_ASM_({ + var elem = Module['toPromise']($0); + elem['_value'] = new Promise(function(resolve, reject) { + elem.callbackSS({call: resolve}, {call: reject}); + }); + }, p); + p->autorelease(); + return p; +} + +Promise *Promise::create(PromiseStringObjectPairFunction fn) +{ + Promise *p = new Promise(emscripten::val(0)); + p->soPairFn = fn; + EM_ASM_({ + var elem = Module['toPromise']($0); + elem['_value'] = new Promise(function(resolve, reject) { + elem.callbackSO({call: resolve}, {call: reject}); + }); + }, p); + p->autorelease(); + return p; +} + +Promise *Promise::create(PromiseObjectVoidPairFunction fn) +{ + Promise *p = new Promise(emscripten::val(0)); + p->ovPairFn = fn; + EM_ASM_({ + var elem = Module['toPromise']($0); + elem['_value'] = new Promise(function(resolve, reject) { + elem.callbackOV({call: resolve}, {call: reject}); + }); + }, p); + p->autorelease(); + return p; +} + +Promise *Promise::create(PromiseObjectDoublePairFunction fn) +{ + Promise *p = new Promise(emscripten::val(0)); + p->odPairFn = fn; + EM_ASM_({ + var elem = Module['toPromise']($0); + elem['_value'] = new Promise(function(resolve, reject) { + elem.callbackOD({call: resolve}, {call: reject}); + }); + }, p); + p->autorelease(); + return p; +} + +Promise *Promise::create(PromiseObjectStringPairFunction fn) +{ + Promise *p = new Promise(emscripten::val(0)); + p->osPairFn = fn; + EM_ASM_({ + var elem = Module['toPromise']($0); + elem['_value'] = new Promise(function(resolve, reject) { + elem.callbackOS({call: resolve}, {call: reject}); + }); + }, p); + p->autorelease(); + return p; +} + +Promise *Promise::create(PromiseObjectObjectPairFunction fn) +{ + Promise *p = new Promise(emscripten::val(0)); + p->ooPairFn = fn; + EM_ASM_({ + var elem = Module['toPromise']($0); + elem['_value'] = new Promise(function(resolve, reject) { + elem.callbackOO({call: resolve}, {call: reject}); + }); + }, p); + p->autorelease(); + return p; +} + +void Promise::callbackVV(emscripten::val resolve, emscripten::val reject) +{ + PromiseVoidFunction resolver = [resolve]{ + HTML5_CALL(resolve, call); + }; + PromiseVoidFunction rejector = [reject]{ + HTML5_CALL(reject, call); + }; + this->vvPairFn(resolver, rejector); +} + +void Promise::callbackVD(emscripten::val resolve, emscripten::val reject) +{ + PromiseVoidFunction resolver = [resolve]{ + HTML5_CALL(resolve, call); + }; + PromiseDoubleFunction rejector = [reject](double v){ + HTML5_CALL(reject, call, v); + }; + this->vdPairFn(resolver, rejector); +} + +void Promise::callbackVS(emscripten::val resolve, emscripten::val reject) +{ + PromiseVoidFunction resolver = [resolve]{ + HTML5_CALL(resolve, call); + }; + PromiseStringFunction rejector = [reject](const std::string &v){ + HTML5_CALL(reject, call, v); + }; + this->vsPairFn(resolver, rejector); +} + +void Promise::callbackVO(emscripten::val resolve, emscripten::val reject) +{ + PromiseVoidFunction resolver = [resolve]{ + HTML5_CALL(resolve, call); + }; + PromiseObjectFunction rejector = [reject](const Object &v){ + HTML5_CALL(reject, call, v.v); + }; + this->voPairFn(resolver, rejector); +} + +void Promise::callbackDV(emscripten::val resolve, emscripten::val reject) +{ + PromiseDoubleFunction resolver = [resolve](double v){ + HTML5_CALL(resolve, call, v); + }; + PromiseVoidFunction rejector = [reject]{ + HTML5_CALL(reject, call); + }; + this->dvPairFn(resolver, rejector); +} + +void Promise::callbackDD(emscripten::val resolve, emscripten::val reject) +{ + PromiseDoubleFunction resolver = [resolve](double v){ + HTML5_CALL(resolve, call, v); + }; + PromiseDoubleFunction rejector = [reject](double v){ + HTML5_CALL(reject, call, v); + }; + this->ddPairFn(resolver, rejector); +} + +void Promise::callbackDS(emscripten::val resolve, emscripten::val reject) +{ + PromiseDoubleFunction resolver = [resolve](double v){ + HTML5_CALL(resolve, call, v); + }; + PromiseStringFunction rejector = [reject](const std::string &v){ + HTML5_CALL(reject, call, v); + }; + this->dsPairFn(resolver, rejector); +} + +void Promise::callbackDO(emscripten::val resolve, emscripten::val reject) +{ + PromiseDoubleFunction resolver = [resolve](double v){ + HTML5_CALL(resolve, call, v); + }; + PromiseObjectFunction rejector = [reject](const Object &v){ + HTML5_CALL(reject, call, v.v); + }; + this->doPairFn(resolver, rejector); +} + +void Promise::callbackSV(emscripten::val resolve, emscripten::val reject) +{ + PromiseStringFunction resolver = [resolve](const std::string &v){ + HTML5_CALL(resolve, call, v); + }; + PromiseVoidFunction rejector = [reject]{ + HTML5_CALL(reject, call); + }; + this->svPairFn(resolver, rejector); +} + +void Promise::callbackSD(emscripten::val resolve, emscripten::val reject) +{ + PromiseStringFunction resolver = [resolve](const std::string &v){ + HTML5_CALL(resolve, call, v); + }; + PromiseDoubleFunction rejector = [reject](double v){ + HTML5_CALL(reject, call, v); + }; + this->sdPairFn(resolver, rejector); +} + +void Promise::callbackSS(emscripten::val resolve, emscripten::val reject) +{ + PromiseStringFunction resolver = [resolve](const std::string &v){ + HTML5_CALL(resolve, call, v); + }; + PromiseStringFunction rejector = [reject](const std::string &v){ + HTML5_CALL(reject, call, v); + }; + this->ssPairFn(resolver, rejector); +} + +void Promise::callbackSO(emscripten::val resolve, emscripten::val reject) +{ + PromiseStringFunction resolver = [resolve](const std::string &v){ + HTML5_CALL(resolve, call, v); + }; + PromiseObjectFunction rejector = [reject](const Object &v){ + HTML5_CALL(reject, call, v.v); + }; + this->soPairFn(resolver, rejector); +} + +void Promise::callbackOV(emscripten::val resolve, emscripten::val reject) +{ + PromiseObjectFunction resolver = [resolve](const Object &v){ + HTML5_CALL(resolve, call, v.v); + }; + PromiseVoidFunction rejector = [reject]{ + HTML5_CALL(reject, call); + }; + this->ovPairFn(resolver, rejector); +} + +void Promise::callbackOD(emscripten::val resolve, emscripten::val reject) +{ + PromiseObjectFunction resolver = [resolve](const Object &v){ + HTML5_CALL(resolve, call, v.v); + }; + PromiseDoubleFunction rejector = [reject](double v){ + HTML5_CALL(reject, call, v); + }; + this->odPairFn(resolver, rejector); +} + +void Promise::callbackOS(emscripten::val resolve, emscripten::val reject) +{ + PromiseObjectFunction resolver = [resolve](const Object &v){ + HTML5_CALL(resolve, call, v.v); + }; + PromiseStringFunction rejector = [reject](const std::string &v){ + HTML5_CALL(reject, call, v); + }; + this->osPairFn(resolver, rejector); +} -void Promise::executeString(emscripten::val resolve, emscripten::val reject) +void Promise::callbackOO(emscripten::val resolve, emscripten::val reject) { - std::function resolver = [resolve](const std::string &s){ - HTML5_CALL(resolve, call, s); + PromiseObjectFunction resolver = [resolve](const Object &v){ + HTML5_CALL(resolve, call, v.v); + }; + PromiseObjectFunction rejector = [reject](const Object &v){ + HTML5_CALL(reject, call, v.v); }; - std::function rejector = []{}; - this->execStr(resolver, rejector); + this->ooPairFn(resolver, rejector); +} + +HTML5_BIND_METHOD(Promise, callbackVV); +HTML5_BIND_METHOD(Promise, callbackVD); +HTML5_BIND_METHOD(Promise, callbackVS); +HTML5_BIND_METHOD(Promise, callbackVO); +HTML5_BIND_METHOD(Promise, callbackDV); +HTML5_BIND_METHOD(Promise, callbackDD); +HTML5_BIND_METHOD(Promise, callbackDS); +HTML5_BIND_METHOD(Promise, callbackDO); +HTML5_BIND_METHOD(Promise, callbackSV); +HTML5_BIND_METHOD(Promise, callbackSD); +HTML5_BIND_METHOD(Promise, callbackSS); +HTML5_BIND_METHOD(Promise, callbackSO); +HTML5_BIND_METHOD(Promise, callbackOV); +HTML5_BIND_METHOD(Promise, callbackOD); +HTML5_BIND_METHOD(Promise, callbackOS); +HTML5_BIND_METHOD(Promise, callbackOO); + +Promise *Promise::then(PromiseVoidPromiseFunction onFulfilled) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.vp = onFulfilled; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then(function() { return elem.callbackThenVP(); }); + }, this); + return this; +} + +Promise *Promise::then(PromiseVoidPromiseFunction onFulfilled, PromiseVoidPromiseFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.vp = onFulfilled; + fn->onRejected.vp = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function() { return elem.callbackThenVP(); }, + function() { return elem.callbackRejectVP(); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseVoidPromiseFunction onFulfilled, PromiseDoublePromiseFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.vp = onFulfilled; + fn->onRejected.dp = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function() { return elem.callbackThenVP(); }, + function(v) { return elem.callbackRejectDP(v); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseVoidPromiseFunction onFulfilled, PromiseStringPromiseFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.vp = onFulfilled; + fn->onRejected.sp = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function() { return elem.callbackThenVP(); }, + function(v) { return elem.callbackRejectSP(v); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseVoidPromiseFunction onFulfilled, PromiseObjectPromiseFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.vp = onFulfilled; + fn->onRejected.op = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function() { return elem.callbackThenVP(); }, + function(v) { return elem.callbackRejectOP(v); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseDoublePromiseFunction onFulfilled) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.dp = onFulfilled; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then(function(v) { return elem.callbackThenDP(v); }); + }, this); + return this; +} + +Promise *Promise::then(PromiseDoublePromiseFunction onFulfilled, PromiseVoidPromiseFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.dp = onFulfilled; + fn->onRejected.vp = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function(v) { return elem.callbackThenDP(v); }, + function() { return elem.callbackRejectVP(); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseDoublePromiseFunction onFulfilled, PromiseDoublePromiseFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.dp = onFulfilled; + fn->onRejected.dp = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function(v) { return elem.callbackThenDP(v); }, + function(v) { return elem.callbackRejectDP(v); } + ); + }, this); + return this; } -Promise *Promise::then(chainString onFulfilled) +Promise *Promise::then(PromiseDoublePromiseFunction onFulfilled, PromiseStringPromiseFunction onRejected) { - this->chainFns.push_back(onFulfilled); + auto fn = new PromiseChainFunction(); + fn->onFulfilled.dp = onFulfilled; + fn->onRejected.sp = onRejected; + this->chains.push_back(fn); EM_ASM_({ var elem = Module['toPromise']($0); - elem._value.then(function(resolve) { elem.callbackThenString(resolve); }); + elem._value = elem._value.then( + function(v) { return elem.callbackThenDP(v); }, + function(v) { return elem.callbackRejectSP(v); } + ); }, this); return this; } -HTML5_BIND_METHOD(Promise, callbackThenString); +Promise *Promise::then(PromiseDoublePromiseFunction onFulfilled, PromiseObjectPromiseFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.dp = onFulfilled; + fn->onRejected.op = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function(v) { return elem.callbackThenDP(v); }, + function(v) { return elem.callbackRejectOP(v); } + ); + }, this); + return this; +} -void Promise::callbackThenString(emscripten::val resolve) +Promise *Promise::then(PromiseStringPromiseFunction onFulfilled) { - const chainString &chain = this->chainFns[0]; - chain(resolve.as()); - this->chainFns.erase(this->chainFns.begin()); + auto fn = new PromiseChainFunction(); + fn->onFulfilled.sp = onFulfilled; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then(function(v) { return elem.callbackThenSP(v); }); + }, this); + return this; +} + + + +Promise *Promise::then(PromiseStringPromiseFunction onFulfilled, PromiseVoidPromiseFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.sp = onFulfilled; + fn->onRejected.vp = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function(v) { return elem.callbackThenSP(v); }, + function() { return elem.callbackRejectVP(); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseStringPromiseFunction onFulfilled, PromiseDoublePromiseFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.sp = onFulfilled; + fn->onRejected.dp = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function(v) { return elem.callbackThenSP(v); }, + function(v) { return elem.callbackRejectDP(v); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseStringPromiseFunction onFulfilled, PromiseStringPromiseFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.sp = onFulfilled; + fn->onRejected.sp = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function(v) { return elem.callbackThenSP(v); }, + function(v) { return elem.callbackRejectSP(v); } + ); + }, this); + return this; +} + +Promise *Promise::then(PromiseStringPromiseFunction onFulfilled, PromiseObjectPromiseFunction onRejected) +{ + auto fn = new PromiseChainFunction(); + fn->onFulfilled.sp = onFulfilled; + fn->onRejected.op = onRejected; + this->chains.push_back(fn); + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.then( + function(v) { return elem.callbackThenSP(v); }, + function(v) { return elem.callbackRejectOP(v); } + ); + }, this); + return this; +} + +emscripten::val Promise::callbackThenVP() +{ + PromiseChainFunction *chain = this->chains[0]; + auto func = chain->onFulfilled.vp; + Promise *p = func(); + this->chains.erase(this->chains.begin()); + delete chain; + if (p == nullptr) { + return emscripten::val(0); + } + return p->v; +} + +emscripten::val Promise::callbackThenDP(emscripten::val v) +{ + PromiseChainFunction *chain = this->chains[0]; + auto func = chain->onFulfilled.dp; + Promise *p = func(v.as()); + this->chains.erase(this->chains.begin()); + delete chain; + if (p == nullptr) { + return emscripten::val(0); + } + return p->v; +} + +emscripten::val Promise::callbackThenSP(emscripten::val v) +{ + PromiseChainFunction *chain = this->chains[0]; + auto func = chain->onFulfilled.sp; + Promise *p = func(v.as()); + this->chains.erase(this->chains.begin()); + delete chain; + if (p == nullptr) { + return emscripten::val(0); + } + return p->v; +} + +emscripten::val Promise::callbackThenOP(emscripten::val v) +{ + PromiseChainFunction *chain = this->chains[0]; + auto func = chain->onFulfilled.op; + Promise *p = func(Object(v)); + this->chains.erase(this->chains.begin()); + delete chain; + if (p == nullptr) { + return emscripten::val(0); + } + return p->v; +} + +emscripten::val Promise::callbackRejectVP() +{ + PromiseChainFunction *chain = this->chains[0]; + auto func = chain->onRejected.vp; + Promise *p = func(); + this->chains.erase(this->chains.begin()); + delete chain; + if (p == nullptr) { + return emscripten::val(0); + } + return p->v; +} + +emscripten::val Promise::callbackRejectDP(emscripten::val v) +{ + PromiseChainFunction *chain = this->chains[0]; + auto func = chain->onRejected.dp; + Promise *p = func(v.as()); + this->chains.erase(this->chains.begin()); + delete chain; + if (p == nullptr) { + return emscripten::val(0); + } + return p->v; +} + +emscripten::val Promise::callbackRejectSP(emscripten::val v) +{ + PromiseChainFunction *chain = this->chains[0]; + auto func = chain->onRejected.sp; + Promise *p = func(v.as()); + this->chains.erase(this->chains.begin()); + delete chain; + if (p == nullptr) { + return emscripten::val(0); + } + return p->v; +} + +emscripten::val Promise::callbackRejectOP(emscripten::val v) +{ + PromiseChainFunction *chain = this->chains[0]; + auto func = chain->onRejected.op; + Promise *p = func(Object(v)); + this->chains.erase(this->chains.begin()); + delete chain; + if (p == nullptr) { + return emscripten::val(0); + } + return p->v; +} + +HTML5_BIND_METHOD(Promise, callbackThenVP); +HTML5_BIND_METHOD(Promise, callbackThenDP); +HTML5_BIND_METHOD(Promise, callbackThenSP); +HTML5_BIND_METHOD(Promise, callbackThenOP); +HTML5_BIND_METHOD(Promise, callbackRejectVP); +HTML5_BIND_METHOD(Promise, callbackRejectDP); +HTML5_BIND_METHOD(Promise, callbackRejectSP); +HTML5_BIND_METHOD(Promise, callbackRejectOP); + + +Promise *Promise::catchError(PromiseVoidPromiseFunction onRejected) +{ + this->catchErrorFn.vp = onRejected; + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.catch( + function() { return elem.callbackCatchVP(); } + ); + }, this); + return this; +} + +Promise *Promise::catchError(PromiseDoublePromiseFunction onRejected) +{ + this->catchErrorFn.dp = onRejected; + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.catch( + function(v) { return elem.callbackCatchDP(v); } + ); + }, this); + return this; +} + +Promise *Promise::catchError(PromiseStringPromiseFunction onRejected) +{ + this->catchErrorFn.sp = onRejected; + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.catch( + function(v) { return elem.callbackCatchSP(v); } + ); + }, this); + return this; +} + +Promise *Promise::catchError(PromiseObjectPromiseFunction onRejected) +{ + this->catchErrorFn.op = onRejected; + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.catch( + function(v) { return elem.callbackCatchOP(v); } + ); + }, this); + return this; +} + +Promise *Promise::finally(PromiseVoidPromiseFunction onFinally) +{ + this->finallyFn.vp = onFinally; + EM_ASM_({ + var elem = Module['toPromise']($0); + elem._value = elem._value.finally( + function() { return elem.callbackFinally(); } + ); + }, this); + return this; +} + +emscripten::val Promise::callbackCatchVP() +{ + Promise *p = this->catchErrorFn.vp(); + if (p == nullptr) { + return emscripten::val(0); + } + return p->v; +} + +emscripten::val Promise::callbackCatchDP(emscripten::val v) +{ + Promise *p = this->catchErrorFn.dp(v.as()); + if (p == nullptr) { + return emscripten::val(0); + } + return p->v; +} + +emscripten::val Promise::callbackCatchSP(emscripten::val v) +{ + Promise *p = this->catchErrorFn.sp(v.as()); + if (p == nullptr) { + return emscripten::val(0); + } + return p->v; +} + +emscripten::val Promise::callbackCatchOP(emscripten::val v) +{ + Promise *p = this->catchErrorFn.op(Object(v)); + if (p == nullptr) { + return emscripten::val(0); + } + return p->v; +} + +emscripten::val Promise::callbackFinally() +{ + Promise *p = this->finallyFn.vp(); + if (p == nullptr) { + return emscripten::val(0); + } + return p->v; +} + +HTML5_BIND_METHOD(Promise, callbackCatchVP); +HTML5_BIND_METHOD(Promise, callbackCatchDP); +HTML5_BIND_METHOD(Promise, callbackCatchSP); +HTML5_BIND_METHOD(Promise, callbackCatchOP); +HTML5_BIND_METHOD(Promise, callbackFinally); + + +Promise *Promise::all(std::vector iterable) +{ + emscripten::val array = toJSArray(iterable); + auto promise = HTML5_STATIC_PRIMITIVE_INSTANCE(Promise); + return Promise::create(HTML5_CALLv(promise, all, array)); +} + +Promise *Promise::race(std::vector iterable) +{ + emscripten::val array = toJSArray(iterable); + auto promise = HTML5_STATIC_PRIMITIVE_INSTANCE(Promise); + return Promise::create(HTML5_CALLv(promise, race, array)); +} + +Promise *Promise::reject() +{ + auto promise = HTML5_STATIC_PRIMITIVE_INSTANCE(Promise); + return Promise::create(HTML5_CALLv(promise, reject)); +} + +Promise *Promise::reject(double value) +{ + auto promise = HTML5_STATIC_PRIMITIVE_INSTANCE(Promise); + return Promise::create(HTML5_CALLv(promise, reject, value)); +} + +Promise *Promise::reject(const std::string &value) +{ + auto promise = HTML5_STATIC_PRIMITIVE_INSTANCE(Promise); + return Promise::create(HTML5_CALLv(promise, reject, value)); +} + +Promise *Promise::reject(Object *value) +{ + auto promise = HTML5_STATIC_PRIMITIVE_INSTANCE(Promise); + return Promise::create(HTML5_CALLv(promise, reject, value->v)); +} + +Promise *Promise::resolve() +{ + auto promise = HTML5_STATIC_PRIMITIVE_INSTANCE(Promise); + return Promise::create(HTML5_CALLv(promise, resolve)); +} + +Promise *Promise::resolve(double value) +{ + auto promise = HTML5_STATIC_PRIMITIVE_INSTANCE(Promise); + return Promise::create(HTML5_CALLv(promise, resolve, value)); +} + +Promise *Promise::resolve(const std::string &value) +{ + auto promise = HTML5_STATIC_PRIMITIVE_INSTANCE(Promise); + return Promise::create(HTML5_CALLv(promise, resolve, value)); +} + +Promise *Promise::resolve(Object *value) +{ + auto promise = HTML5_STATIC_PRIMITIVE_INSTANCE(Promise); + return Promise::create(HTML5_CALLv(promise, resolve, value->v)); } HTML5_PROPERTY_IMPL(Promise, unsigned long, length); + diff --git a/src/response.cc b/src/response.cc new file mode 100644 index 0000000..ebc6029 --- /dev/null +++ b/src/response.cc @@ -0,0 +1,70 @@ +#include "response.h" +#include "promise.h" + +USING_NAMESPACE_HTML5; + +Response::Response(emscripten::val v) : + Object(v) +{ +} + +Response::~Response() +{ +} + +Response *Response::create(emscripten::val v) +{ + auto response = new Response(v); + response->autorelease(); + return response; +} + +Response *Response::clone() +{ + return Response::create(HTML5_CALLv(this->v, clone)); +} + +Response *Response::error() +{ + return Response::create(HTML5_CALLv(this->v, error)); +} + +Response *Response::redirect(const std::string &url, int status) +{ + return Response::create(HTML5_CALLv(this->v, redirect, url, status)); +} + +Promise *Response::arrayBuffer() +{ + return Promise::create(HTML5_CALLv(this->v, arrayBuffer)); +} + +Promise *Response::blob() +{ + return Promise::create(HTML5_CALLv(this->v, blob)); +} + +Promise *Response::formData() +{ + return Promise::create(HTML5_CALLv(this->v, formData)); +} + +Promise *Response::json() +{ + return Promise::create(HTML5_CALLv(this->v, json)); +} + +Promise *Response::text() +{ + return Promise::create(HTML5_CALLv(this->v, text)); +} + +//HTML5_READONLY_PROPERTY_OBJECT_IMPL(Response, Headers, headers); +HTML5_READONLY_PROPERTY_IMPL(Response, bool, ok); +HTML5_READONLY_PROPERTY_IMPL(Response, bool, redirected); +HTML5_READONLY_PROPERTY_IMPL(Response, int, status); +HTML5_READONLY_PROPERTY_IMPL(Response, std::string, type); +HTML5_READONLY_PROPERTY_IMPL(Response, std::string, url); +HTML5_PROPERTY_IMPL(Response, bool, useFinalURL); +//HTML5_READONLY_PROPERTY_OBJECT_IMPL(Response, ReadableStream, body); +HTML5_READONLY_PROPERTY_IMPL(Response, bool, bodyUsed); \ No newline at end of file diff --git a/src/window.cc b/src/window.cc index e7adf15..940da23 100644 --- a/src/window.cc +++ b/src/window.cc @@ -134,6 +134,11 @@ Promise *Window::createImageBitmap(ImageBitmap *image, long sx, long sy, long sw return Promise::create(HTML5_CALLv(this->v, createImageBitmap, image->v, sx, sy, sw, sh)); } +Promise *Window::fetch(const std::string &url) +{ + return Promise::create(HTML5_CALLv(this->v, fetch, url)); +} + void Window::focus() { HTML5_CALL(this->v, focus);