Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .github/workflows/runtime.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,12 @@ jobs:
matrix:
platform:
- os-name: MacOS-x86_64
runs-on: macOS-latest
runs-on: macos-15-intel
target: x86_64-apple-darwin

- os-name: MacOS-aarch64
runs-on: macOS-latest
target: aarch64-apple-darwin
# - os-name: MacOS-aarch64
# runs-on: macos-15
# target: aarch64-apple-darwin

- os-name: Linux-x86_64
runs-on: ubuntu-22.04
Expand All @@ -50,7 +50,7 @@ jobs:
target: aarch64-unknown-linux-gnu

- os-name: Windows-x86_64
runs-on: windows-latest
runs-on: windows-2025
target: x86_64-pc-windows-msvc

runs-on: ${{ matrix.platform.runs-on }}
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ javascript
node_modules
.dart_tool
.idea
dist

**/pubspec_overrides.yaml
*.iml
106 changes: 106 additions & 0 deletions examples/mjml/bin/main.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import 'dart:io';
import 'package:globe_runtime/globe_runtime.dart';
import 'package:mjml_bridge/mjml_bridge.dart';

const mjml = r'''
<mjml>
<mj-body background-color="#F4F4F4">
<mj-section background-color="#ffffff" background-repeat="repeat" padding-bottom="0px" padding-top="30px" padding="20px 0" text-align="center">
<mj-column>
<mj-image align="center" padding="10px 25px" src="https://static.mailjet.com/mjml-website/templates/christmas-logo.png" target="_blank" width="214px"></mj-image>
<mj-text align="left" color="#55575d" font-family="Arial, sans-serif" font-size="13px" line-height="22px" padding-bottom="15px" padding-top="0px" padding="10px 25px">
<p style="text-align: center; margin: 10px 0;color:#151e23;font-size:14px;font-family:Georgia,Helvetica,Arial,sans-serif">Product | Concept | Contact</p>
</mj-text>
</mj-column>
</mj-section>
<mj-section background-repeat="repeat" padding-bottom="0px" padding-top="0px" padding="20px 0" text-align="center">
<mj-column>
<mj-image align="center" padding-bottom="0px" padding-left="0px" padding-right="0px" padding-top="0px" padding="10px 25px" src="https://static.mailjet.com/mjml-website/templates/christmas-hero.jpg" target="_blank" width="600px"></mj-image>
</mj-column>
</mj-section>
<mj-section background-color="#ffffff" background-repeat="repeat" background-size="auto" padding-bottom="0px" padding-top="30px" padding="20px 0" text-align="center">
<mj-column>
<mj-text align="left" color="#55575d" font-family="Arial, sans-serif" font-size="30px" line-height="22px" padding-bottom="10px" padding-top="10px" padding="10px 25px">
<p style="line-height: 30px; margin: 10px 0; text-align: center; color:#151e23; font-size:30p; font-family:Georgia,Helvetica,Arial,sans-serif">- Our Holiday Recipes -</p>
</mj-text>
</mj-column>
</mj-section>
<mj-section background-color="#ffffff" background-repeat="repeat" padding-bottom="0px" padding="20px 0" text-align="center">
<mj-column>
<mj-image align="center" padding-bottom="20px" padding-left="30px" padding-right="30px" padding-top="0px" padding="10px 25px" src="https://static.mailjet.com/mjml-website/templates/christmas-product-1.jpg" target="_blank" width="1200px"></mj-image>
</mj-column>
<mj-column>
<mj-text align="left" color="#55575d" font-family="Arial, sans-serif" font-size="13px" line-height="22px" padding-bottom="0px" padding-left="40px" padding-right="40px" padding-top="0px" padding="10px 25px">
<p style="margin: 10px 0; color:#151e23; font-size:16px; font-family:Georgia,Helvetica,Arial,sans-serif"><b>Cake Title</b></p>
<p style="line-height: 16px; margin: 10px 0;font-size:14px; color:#151e23; font-family:Georgia,Helvetica,Arial,sans-serif; color:#354552">Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.</p>
<p style="line-height: 16px; margin: 10px 0; color:#354552; font-size:14px; font-family:Georgia,Helvetica,Arial,sans-serif"><u>Choose me</u> &gt;</p>
</mj-text>
</mj-column>
</mj-section>
<mj-section background-color="#ffffff" background-repeat="repeat" direction="rtl" padding-bottom="0px" padding-top="0px" padding="20px 0" text-align="center">
<mj-column>
<mj-image align="center" padding-bottom="20px" padding-left="30px" padding-right="30px" padding-top="20px" padding="10px 25px" src="https://static.mailjet.com/mjml-website/templates/christmas-product-2.jpg" target="_blank" width="1200px"></mj-image>
</mj-column>
<mj-column>
<mj-text align="left" color="#55575d" font-family="Arial, sans-serif" font-size="13px" line-height="22px" padding-bottom="0px" padding-left="40px" padding-right="40px" padding-top="0px" padding="10px 25px">
<p style="margin: 10px 0; color:#151e23; font-size:16px; font-family:Georgia,Helvetica,Arial,sans-serif"><b>Cake Title</b></p>
<p style="line-height: 16px; margin: 10px 0;font-size:14px; color:#151e23; font-family:Georgia,Helvetica,Arial,sans-serif; color:#354552">Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.</p>
<p style="line-height: 16px; margin: 10px 0; color:#354552; font-size:14px; font-family:Georgia,Helvetica,Arial,sans-serif"><u>Choose me</u> &gt;</p>
</mj-text>
</mj-column>
</mj-section>
<mj-section background-color="#ffffff" background-repeat="repeat" padding-bottom="0px" padding-top="0px" padding="20px 0" text-align="center">
<mj-column>
<mj-image align="center" padding-bottom="20px" padding-left="30px" padding-right="30px" padding-top="20px" padding="10px 25px" src="https://static.mailjet.com/mjml-website/templates/christmas-product-3.jpg" target="_blank" width="1200px"></mj-image>
</mj-column>
<mj-column>
<mj-text align="left" color="#55575d" font-family="Arial, sans-serif" font-size="13px" line-height="22px" padding-bottom="0px" padding-left="40px" padding-right="40px" padding-top="0px" padding="10px 25px">
<p style="margin: 10px 0; color:#151e23; font-size:16px; font-family:Georgia,Helvetica,Arial,sans-serif"><b>Cake Title</b></p>
<p style="line-height: 16px; margin: 10px 0;font-size:14px; color:#151e23; font-family:Georgia,Helvetica,Arial,sans-serif; color:#354552">Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.</p>
<p style="line-height: 16px; margin: 10px 0; color:#354552; font-size:14px; font-family:Georgia,Helvetica,Arial,sans-serif"><u>Choose me</u> &gt;</p>
</mj-text>
</mj-column>
</mj-section>
<mj-section background-color="#ffffff" background-repeat="repeat" padding-top="0px" padding="20px 0" text-align="center">
<mj-column>
<mj-button align="center" background-color="#354552" border-radius="3px" color="#ffffff" font-family="Georgia, Helvetica, Arial, sans-serif" font-size="14px" font-weight="normal" inner-padding="10px 25px" padding="10px 25px" text-decoration="none" text-transform="none" vertical-align="middle">Discover all desserts</mj-button>
</mj-column>
</mj-section>
<mj-section background-color="#ffffff" background-repeat="repeat" padding-bottom="0px" padding-top="0px" padding="20px 0" text-align="center">
<mj-column>
<mj-image align="center" padding-bottom="0px" padding-left="0px" padding-right="0px" padding-top="0px" padding="10px 25px" src="https://static.mailjet.com/mjml-website/templates/christmas-footer.jpg" target="_blank" width="600px"></mj-image>
</mj-column>
</mj-section>
<mj-section background-color="#ffffff" background-repeat="repeat" padding="20px 0" text-align="center">
<mj-column>
<mj-image align="center" padding="10px 25px" src="https://static.mailjet.com/mjml-website/templates/christmas-logo.png" target="_blank" width="202px"></mj-image>
<mj-social align="center">
<mj-social-element name="facebook"></mj-social-element>
<mj-social-element name="pinterest"></mj-social-element>
<mj-social-element name="instagram"></mj-social-element>
</mj-social>
</mj-column>
</mj-section>
</mj-body>
</mjml>
''';

void main() async {
final result = await render(mjml);

final server = await HttpServer.bind(InternetAddress.loopbackIPv4, 8080);
server.listen((request) {
request.response.headers.contentType = ContentType.html;
request.response
..write(result.html)
..close();
});

if (Platform.isWindows) {
await Process.run('cmd', ['/c', 'start', 'http://localhost:8080']);
} else if (Platform.isMacOS) {
await Process.run('open', ['http://localhost:8080']);
} else if (Platform.isLinux) {
await Process.run('xdg-open', ['http://localhost:8080']);
}
}
68 changes: 68 additions & 0 deletions examples/mjml/lib/mjml_bridge.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import 'dart:async';
import 'dart:convert';

import 'package:globe_runtime/globe_runtime.dart';
import 'package:mjml_bridge/mjml_bridge_source.dart';

const module = InlinedModule(name: 'mjml_bridge', sourceCode: packageSource);

Future<MJMLResult> render(String mjml, {MJMLOptions? options}) async {
final completer = Completer<MJMLResult>();

await module.register();

module.callFunction(
'render',
args: [
mjml.toFFIType,
(options?.toJson() ?? {}).toFFIType,
],
onData: (data) {
if (data.hasError()) {
completer.completeError(data.error);
} else {
final json = data.data.unpack();
completer.complete(MJMLResult.fromJson(json));
}
return true;
},
);
return completer.future;
}

class MJMLOptions {
final bool? keepComments;
final bool? socialIconPath;
final String? fonts;
final String? validationLevel;

const MJMLOptions({
this.keepComments,
this.socialIconPath,
this.fonts,
this.validationLevel,
});

Map<String, dynamic> toJson() {
return {
if (keepComments != null) 'keepComments': keepComments,
if (socialIconPath != null) 'socialIconPath': socialIconPath,
if (fonts != null) 'fonts': fonts,
if (validationLevel != null) 'validationLevel': validationLevel,
};
}
}

class MJMLResult {
final String html;
final List<dynamic> errors;

const MJMLResult({required this.html, required this.errors});

factory MJMLResult.fromJson(Map<dynamic, dynamic> json) {
return MJMLResult(
html: json['html'] ?? '',
errors: json['errors'] ?? [],
);
}
}
13 changes: 13 additions & 0 deletions examples/mjml/lib/mjml_bridge.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import mjml2html from "mjml-browser";

function render(_: any, mjml: string, options: any, callbackId: number) {
const result = mjml2html(mjml, options);
const encoded = JsonPayload.encode(result);
Dart.send_value(callbackId, encoded);
}

export default {
functions: {
render,
},
};
Loading
Loading