Created
March 26, 2026 23:50
-
-
Save Frityet/fd1d3f7056506bd2015e84396c1bf078 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #import "jsobjc.h" | |
| #import "dom.generated.h" | |
| #include <emscripten/emscripten.h> | |
| EM_JS(void, install_demo_interop, (), { | |
| class BaseGreeter { | |
| constructor(name) { | |
| this.name = name; | |
| } | |
| print() { | |
| globalThis.console.log("BaseGreeter:", this.name); | |
| } | |
| } | |
| globalThis.BaseGreeter = BaseGreeter; | |
| globalThis.doSomething = function(cl) { | |
| const value = new cl("bob"); | |
| value.print(); | |
| return value.name; | |
| }; | |
| globalThis.makeJSSubclassInstance = function(cl) { | |
| class JSGreeter extends cl { | |
| print() { | |
| super.print(); | |
| globalThis.console.log("JS subclass:", this.name); | |
| } | |
| } | |
| return new JSGreeter("jane"); | |
| }; | |
| globalThis.useObjCSubclassOfJS = function(cl) { | |
| const value = new cl("erin"); | |
| value.print(); | |
| return value.name; | |
| }; | |
| }); | |
| @class MyClass; | |
| @class ObjCGreeter; | |
| @interface Window (DemoInterop) | |
| - (String *)doSomething:(Class)classValue; | |
| - (MyClass *)makeJSSubclassInstance:(Class)classValue; | |
| - (String *)useObjCSubclassOfJS:(Class)classValue; | |
| @end | |
| @interface Window (DemoCompat) | |
| @property (nonatomic, readonly, strong) XMLHttpRequest *XMLHTTPRequest; | |
| @end | |
| @interface MyClass : JSObject { | |
| String *_name; | |
| } | |
| @property (nonatomic, readonly, strong) String *name; | |
| + (instancetype)newWithName:(String *)nm; | |
| - (void)print; | |
| @end | |
| @interface BaseGreeter : JSObject | |
| + (instancetype)new:(String *)name; | |
| - (String *)name; | |
| - (void)print; | |
| @end | |
| @interface ObjCGreeter : BaseGreeter | |
| - (void)print; | |
| @end | |
| @implementation MyClass | |
| @synthesize name = _name; | |
| + (instancetype)newWithName:(String *)nm { | |
| auto instance = [super new]; | |
| instance->_name = nm; | |
| return instance; | |
| } | |
| - (void)print { | |
| [js.window.console log:@"Hello, " :_name]; | |
| } | |
| @end | |
| @implementation BaseGreeter | |
| @end | |
| @implementation ObjCGreeter | |
| - (void)print { | |
| [super print]; | |
| [js.window.console log:@"ObjC subclass:" :self.name]; | |
| } | |
| @end | |
| @implementation Window (DemoCompat) | |
| - (XMLHttpRequest *)XMLHTTPRequest { | |
| return self.XMLHttpRequest; | |
| } | |
| @end | |
| int main() { | |
| install_demo_interop(); | |
| auto window = js.window; | |
| auto console = window.console; | |
| [console log:@"hello, world!"]; | |
| auto response = [window fetch: @"./demo/data.json"].await; | |
| auto data = response.json.await; | |
| window.document.title = data[@"title"]; | |
| auto request = [js.window.XMLHTTPRequest new]; | |
| [request open:@"GET" url:@"./demo/data.json" async:false]; | |
| [request send]; | |
| [console log:@"xhr response:" :request.responseText]; | |
| auto createdName = [window doSomething:MyClass.class]; | |
| [console log:@"objc class result:" :createdName]; | |
| auto jsSubclassInstance = [window makeJSSubclassInstance:MyClass.class]; | |
| [jsSubclassInstance print]; | |
| [console log:@"js subclass result:" :jsSubclassInstance.name]; | |
| auto objcSubclassClass = ObjCGreeter.class; | |
| auto objcSubclassName = [window useObjCSubclassOfJS:objcSubclassClass]; | |
| [console log:@"objc subclass of js result:" :objcSubclassName]; | |
| window.document.body.textContent = objcSubclassName; | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment