diff --git a/quill_html_converter/lib/quill_html_converter.dart b/quill_html_converter/lib/quill_html_converter.dart index 460b74dc..6c685f75 100644 --- a/quill_html_converter/lib/quill_html_converter.dart +++ b/quill_html_converter/lib/quill_html_converter.dart @@ -2,7 +2,15 @@ library quill_html_converter; import 'package:dart_quill_delta/dart_quill_delta.dart'; import 'package:vsc_quill_delta_to_html/vsc_quill_delta_to_html.dart' - as converter show ConverterOptions, QuillDeltaToHtmlConverter; + as converter + show + ConverterOptions, + QuillDeltaToHtmlConverter, + OpAttributeSanitizerOptions, + OpConverterOptions, + InlineStyles, + InlineStyleType, + defaultInlineFonts; typedef ConverterOptions = converter.ConverterOptions; @@ -21,7 +29,66 @@ extension DeltaHtmlExt on Delta { final json = toJson(); final html = converter.QuillDeltaToHtmlConverter( List.castFrom(json), - options, + options ?? + ConverterOptions( + orderedListTag: 'ol', + bulletListTag: 'ul', + multiLineBlockquote: true, + multiLineHeader: true, + multiLineCodeblock: true, + multiLineParagraph: true, + multiLineCustomBlock: true, + sanitizerOptions: converter.OpAttributeSanitizerOptions( + allow8DigitHexColors: true), + converterOptions: converter.OpConverterOptions( + customCssStyles: (op) { + ///if found line-height apply this as a inline style + if (op.attributes['line-height'] != null) { + return ['line-height: ${op.attributes['line-height']}px']; + } + //here is where us pass the necessary + //code to validate if our attributes exist in [DeltaInsertOp] + //and return the necessary html style + if (op.isImage()) { + // Fit images within restricted parent width. + return ['max-width: 100%', 'object-fit: contain']; + } + if (op.isBlockquote()) { + return ['border-left: 4px solid #ccc', 'padding-left: 16px']; + } + return null; + }, + inlineStylesFlag: true, //This let inlineStyles work + inlineStyles: converter.InlineStyles( + { + 'font': converter.InlineStyleType( + fn: (value, _) => + converter.defaultInlineFonts[value] ?? + 'font-family: $value'), + 'size': converter.InlineStyleType(fn: (value, _) { + //default sizes + if (value == 'small') return 'font-size: 0.75em'; + if (value == 'large') return 'font-size: 1.5em'; + if (value == 'huge') return 'font-size: 2.5em'; + //accept any int or double type size + return 'font-size: ${value}px'; + }), + 'indent': converter.InlineStyleType(fn: (value, op) { + final indentSize = + (double.tryParse(value) ?? double.nan) * 3; + final side = + op.attributes['direction'] == 'rtl' ? 'right' : 'left'; + return 'padding-$side:${indentSize}em'; + }), + 'list': converter.InlineStyleType(map: { + 'checked': "list-style-type:'\\2611';padding-left: 0.5em;", + 'unchecked': + "list-style-type:'\\2610';padding-left: 0.5em;", + }), + }, + ), + ), + ), ).convert(); return html; } diff --git a/quill_html_converter/test/quill_html_converter_test.dart b/quill_html_converter/test/quill_html_converter_test.dart index 3be46c15..aefe3822 100644 --- a/quill_html_converter/test/quill_html_converter_test.dart +++ b/quill_html_converter/test/quill_html_converter_test.dart @@ -4,7 +4,7 @@ import 'package:test/test.dart'; void main() { group('Quill HTML Converter', () { - test('Example of toHtml', () { + test('should parser delta heading to html', () { const html = '



'; final quillDelta = [ {'insert': '\n'}, @@ -15,5 +15,32 @@ void main() { ]; expect(Delta.fromJson(quillDelta).toHtml().trim(), html.trim()); }); + + test('should parse line-height attribute to html', () { + const html = '

hello

'; + final quillDelta = [ + { + 'insert': 'hello', + 'attributes': {'line-height': 1.5} + }, + {'insert': '\n'} + ]; + expect(Delta.fromJson(quillDelta).toHtml().trim(), html.trim()); + }); + + test('should parse block image embed to html', () { + const html = + '

'; + final quillDelta = [ + { + 'insert': { + 'image': + 'https://img.freepik.com/foto-gratis/belleza-otonal-abstracta-patron-venas-hoja-multicolor-generado-ia_188544-9871.jpg' + }, + }, + {'insert': '\n'} + ]; + expect(Delta.fromJson(quillDelta).toHtml().trim(), html.trim()); + }); }); }