|
|
|
@ -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( |
|
|
|
|
<String, converter.InlineStyleType>{ |
|
|
|
|
'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: <String, String>{ |
|
|
|
|
'checked': "list-style-type:'\\2611';padding-left: 0.5em;", |
|
|
|
|
'unchecked': |
|
|
|
|
"list-style-type:'\\2610';padding-left: 0.5em;", |
|
|
|
|
}), |
|
|
|
|
}, |
|
|
|
|
), |
|
|
|
|
), |
|
|
|
|
), |
|
|
|
|
).convert(); |
|
|
|
|
return html; |
|
|
|
|
} |
|
|
|
|