From 22c2bf6ea84890031a1dbb3787bd29f64ae58e97 Mon Sep 17 00:00:00 2001 From: David Martos Date: Mon, 29 Sep 2025 01:23:35 +0200 Subject: [PATCH 1/5] Emoji support --- .../packages/mustache_template/lib/src/scanner.dart | 9 ++++++--- .../packages/mustache_template/test/mustache_test.dart | 6 ++++++ .../packages/mustache_template/test/parser_test.dart | 9 +++++++++ 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/third_party/packages/mustache_template/lib/src/scanner.dart b/third_party/packages/mustache_template/lib/src/scanner.dart index b046c7897a2..3f06c69d733 100644 --- a/third_party/packages/mustache_template/lib/src/scanner.dart +++ b/third_party/packages/mustache_template/lib/src/scanner.dart @@ -7,7 +7,8 @@ import 'token.dart'; class Scanner { Scanner(String source, this._templateName, String? delimiters) : _source = source, - _itr = source.runes.iterator { + _itr = source.runes.iterator, + _runes = source.runes.toList() { if (source == '') { _c = _EOF; } else { @@ -40,6 +41,7 @@ class Scanner { final String _source; final Iterator _itr; + final List _runes; int _offset = 0; int _c = 0; @@ -130,8 +132,9 @@ class Scanner { while (_peek() != _EOF && test(_peek())) { _read(); } - final int end = _peek() == _EOF ? _source.length : _offset; - return _source.substring(start, end); + final int end = _peek() == _EOF ? _runes.length : _offset; + final String part = String.fromCharCodes(_runes.sublist( start, end)); + return part; } void _expect(int expectedCharCode) { diff --git a/third_party/packages/mustache_template/test/mustache_test.dart b/third_party/packages/mustache_template/test/mustache_test.dart index 086247bab56..ace3119fb0b 100644 --- a/third_party/packages/mustache_template/test/mustache_test.dart +++ b/third_party/packages/mustache_template/test/mustache_test.dart @@ -24,6 +24,12 @@ void main() { ).renderString({}); expect(output, equals('__')); }); + test('Emoji', () { + final String output = parse( + 'Hello! 🖖👍🏽\nBye! 🏳️‍🌈', + ).renderString({}); + expect(output, equals('Hello! 🖖👍🏽\nBye! 🏳️‍🌈')); + }); }); group('Section', () { test('Map', () { diff --git a/third_party/packages/mustache_template/test/parser_test.dart b/third_party/packages/mustache_template/test/parser_test.dart index 27ccadf96b6..d9ffd8515c3 100644 --- a/third_party/packages/mustache_template/test/parser_test.dart +++ b/third_party/packages/mustache_template/test/parser_test.dart @@ -302,6 +302,15 @@ void main() { ]); }); + test('emoji', () { + const String source = 'Hello! 🖖👍🏽🏳️‍🌈\nEmoji'; + final Parser parser = Parser(source, 'foo', '{{ }}'); + final List nodes = parser.parse(); + expectNodes(nodes, [ + TextNode('Hello! 🖖👍🏽🏳️‍🌈\nEmoji', 0, 20), // End offset includes emoji sizes + ]); + }); + test('toString', () { TextNode('foo', 1, 3).toString(); VariableNode('foo', 1, 3).toString(); From 341404bdf257fc2b829d6411520b28b0e1711c88 Mon Sep 17 00:00:00 2001 From: David Martos Date: Mon, 29 Sep 2025 01:36:29 +0200 Subject: [PATCH 2/5] changelog --- third_party/packages/mustache_template/CHANGELOG.md | 4 ++++ third_party/packages/mustache_template/pubspec.yaml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/third_party/packages/mustache_template/CHANGELOG.md b/third_party/packages/mustache_template/CHANGELOG.md index fd1da851da5..9159b7dc491 100644 --- a/third_party/packages/mustache_template/CHANGELOG.md +++ b/third_party/packages/mustache_template/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.2 + +* Emoji support. + ## 2.0.1 * Transfers the package source from https://github.com/jonahwilliams/mustache diff --git a/third_party/packages/mustache_template/pubspec.yaml b/third_party/packages/mustache_template/pubspec.yaml index fd0de9f377d..9927217dd94 100644 --- a/third_party/packages/mustache_template/pubspec.yaml +++ b/third_party/packages/mustache_template/pubspec.yaml @@ -2,7 +2,7 @@ name: mustache_template description: A templating library that implements the Mustache template specification repository: https://github.com/flutter/packages/tree/main/third_party/packages/mustache_template issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+mustache_template%22 -version: 2.0.1 +version: 2.0.2 environment: sdk: ^3.7.0 From 74be3336e76d618a3ce2f63e84d44d872d9cf346 Mon Sep 17 00:00:00 2001 From: David Martos Date: Mon, 29 Sep 2025 01:37:30 +0200 Subject: [PATCH 3/5] format --- third_party/packages/mustache_template/lib/src/scanner.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/packages/mustache_template/lib/src/scanner.dart b/third_party/packages/mustache_template/lib/src/scanner.dart index 3f06c69d733..ec18fd49498 100644 --- a/third_party/packages/mustache_template/lib/src/scanner.dart +++ b/third_party/packages/mustache_template/lib/src/scanner.dart @@ -133,7 +133,7 @@ class Scanner { _read(); } final int end = _peek() == _EOF ? _runes.length : _offset; - final String part = String.fromCharCodes(_runes.sublist( start, end)); + final String part = String.fromCharCodes(_runes.sublist(start, end)); return part; } From beb909a25848474f9d68553c62acc74f9b6656cf Mon Sep 17 00:00:00 2001 From: David Martos Date: Mon, 29 Sep 2025 12:35:40 +0200 Subject: [PATCH 4/5] format --- third_party/packages/mustache_template/test/parser_test.dart | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/third_party/packages/mustache_template/test/parser_test.dart b/third_party/packages/mustache_template/test/parser_test.dart index d9ffd8515c3..7f849aab282 100644 --- a/third_party/packages/mustache_template/test/parser_test.dart +++ b/third_party/packages/mustache_template/test/parser_test.dart @@ -306,9 +306,8 @@ void main() { const String source = 'Hello! 🖖👍🏽🏳️‍🌈\nEmoji'; final Parser parser = Parser(source, 'foo', '{{ }}'); final List nodes = parser.parse(); - expectNodes(nodes, [ - TextNode('Hello! 🖖👍🏽🏳️‍🌈\nEmoji', 0, 20), // End offset includes emoji sizes - ]); + // End offset includes emoji sizes + expectNodes(nodes, [TextNode('Hello! 🖖👍🏽🏳️‍🌈\nEmoji', 0, 20)]); }); test('toString', () { From 9d3412774f768e9b78d62d846886e0dfe169e8a5 Mon Sep 17 00:00:00 2001 From: David Martos Date: Mon, 29 Sep 2025 12:38:28 +0200 Subject: [PATCH 5/5] improve _readWhile performance --- .../packages/mustache_template/lib/src/scanner.dart | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/third_party/packages/mustache_template/lib/src/scanner.dart b/third_party/packages/mustache_template/lib/src/scanner.dart index ec18fd49498..7f889545cef 100644 --- a/third_party/packages/mustache_template/lib/src/scanner.dart +++ b/third_party/packages/mustache_template/lib/src/scanner.dart @@ -7,8 +7,7 @@ import 'token.dart'; class Scanner { Scanner(String source, this._templateName, String? delimiters) : _source = source, - _itr = source.runes.iterator, - _runes = source.runes.toList() { + _itr = source.runes.iterator { if (source == '') { _c = _EOF; } else { @@ -41,7 +40,6 @@ class Scanner { final String _source; final Iterator _itr; - final List _runes; int _offset = 0; int _c = 0; @@ -128,13 +126,12 @@ class Scanner { if (_c == _EOF) { return ''; } - final int start = _offset; + + final StringBuffer buffer = StringBuffer(); while (_peek() != _EOF && test(_peek())) { - _read(); + buffer.writeCharCode(_read()); } - final int end = _peek() == _EOF ? _runes.length : _offset; - final String part = String.fromCharCodes(_runes.sublist(start, end)); - return part; + return buffer.toString(); } void _expect(int expectedCharCode) {