diff --git a/app/lib/widgets/field.dart b/app/lib/widgets/field.dart index dd8b4bf4..1358950d 100644 --- a/app/lib/widgets/field.dart +++ b/app/lib/widgets/field.dart @@ -24,7 +24,7 @@ class QuillField extends StatefulWidget { final InputDecoration decoration; final Widget toolbar; final EmbedBuilder embedBuilder; - + final StyleBuilder styleBuilder; QuillField({ Key key, @required this.controller, @@ -45,7 +45,7 @@ class QuillField extends StatefulWidget { this.onLaunchUrl, this.decoration, this.toolbar, - this.embedBuilder, + this.embedBuilder, this.styleBuilder, }) : super(key: key); @override @@ -98,6 +98,7 @@ class _QuillFieldState extends State { scrollPhysics: widget.scrollPhysics, onLaunchUrl: widget.onLaunchUrl, embedBuilder: widget.embedBuilder, + styleBuilder:widget.styleBuilder, ); if (widget.toolbar != null) { diff --git a/lib/widgets/delegate.dart b/lib/widgets/delegate.dart index aee7a058..2366be25 100644 --- a/lib/widgets/delegate.dart +++ b/lib/widgets/delegate.dart @@ -3,12 +3,13 @@ import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter_quill/models/documents/nodes/leaf.dart'; +import 'package:flutter_quill/models/documents/attribute.dart'; import 'package:flutter_quill/widgets/text_selection.dart'; import 'editor.dart'; typedef EmbedBuilder = Widget Function(BuildContext context, Embed node); - +typedef StyleBuilder = TextStyle Function(Attribute attribute); abstract class EditorTextSelectionGestureDetectorBuilderDelegate { GlobalKey getEditableTextKey(); diff --git a/lib/widgets/editor.dart b/lib/widgets/editor.dart index 018ef0b2..c35cd1ef 100644 --- a/lib/widgets/editor.dart +++ b/lib/widgets/editor.dart @@ -144,7 +144,7 @@ class QuillEditor extends StatefulWidget { final ScrollPhysics scrollPhysics; final ValueChanged onLaunchUrl; final EmbedBuilder embedBuilder; - + final StyleBuilder styleBuilder; QuillEditor( {@required this.controller, @required this.focusNode, @@ -164,7 +164,7 @@ class QuillEditor extends StatefulWidget { this.scrollPhysics, this.onLaunchUrl, this.embedBuilder = - kIsWeb ? _defaultEmbedBuilderWeb : _defaultEmbedBuilder}) + kIsWeb ? _defaultEmbedBuilderWeb : _defaultEmbedBuilder, this.styleBuilder}) : assert(controller != null), assert(scrollController != null), assert(scrollable != null), @@ -286,7 +286,9 @@ class _QuillEditorState extends State widget.keyboardAppearance, widget.enableInteractiveSelection, widget.scrollPhysics, - widget.embedBuilder), + widget.embedBuilder, + widget.styleBuilder, + ), ); } diff --git a/lib/widgets/raw_editor.dart b/lib/widgets/raw_editor.dart index 3ff24e55..4e890744 100644 --- a/lib/widgets/raw_editor.dart +++ b/lib/widgets/raw_editor.dart @@ -49,7 +49,7 @@ class RawEditor extends StatefulWidget { final bool enableInteractiveSelection; final ScrollPhysics scrollPhysics; final EmbedBuilder embedBuilder; - +final StyleBuilder styleBuilder; RawEditor( Key key, this.controller, @@ -74,7 +74,7 @@ class RawEditor extends StatefulWidget { this.keyboardAppearance, this.enableInteractiveSelection, this.scrollPhysics, - this.embedBuilder) + this.embedBuilder, this.styleBuilder) : assert(controller != null, 'controller cannot be null'), assert(focusNode != null, 'focusNode cannot be null'), assert(scrollable || scrollController != null, @@ -571,6 +571,7 @@ class RawEditorState extends EditorState line: node, textDirection: _textDirection, embedBuilder: widget.embedBuilder, + styleBuilder:widget.styleBuilder, styles: _styles, ); EditableTextLine editableTextLine = EditableTextLine( diff --git a/lib/widgets/text_line.dart b/lib/widgets/text_line.dart index 7f784d2b..102bcfc7 100644 --- a/lib/widgets/text_line.dart +++ b/lib/widgets/text_line.dart @@ -25,10 +25,16 @@ class TextLine extends StatelessWidget { final Line line; final TextDirection textDirection; final EmbedBuilder embedBuilder; + final StyleBuilder styleBuilder; final DefaultStyles styles; const TextLine( - {Key key, this.line, this.textDirection, this.embedBuilder, this.styles}) + {Key key, + this.line, + this.textDirection, + this.embedBuilder, + this.styles, + this.styleBuilder}) : assert(line != null), assert(embedBuilder != null), assert(styles != null), @@ -43,12 +49,12 @@ class TextLine extends StatelessWidget { return EmbedProxy(embedBuilder(context, embed)); } - TextSpan textSpan = _buildTextSpan(context); + TextSpan textSpan = _buildTextSpan(context, styleBuilder); StrutStyle strutStyle = StrutStyle.fromTextStyle(textSpan.style, forceStrutHeight: true); final textAlign = _getTextAlign(); RichText child = RichText( - text: _buildTextSpan(context), + text: TextSpan(children: [_buildTextSpan(context,styleBuilder)]), textAlign: textAlign, textDirection: textDirection, strutStyle: strutStyle, @@ -80,10 +86,10 @@ class TextLine extends StatelessWidget { return TextAlign.start; } - TextSpan _buildTextSpan(BuildContext context) { + TextSpan _buildTextSpan(BuildContext context, StyleBuilder styleBuilder) { DefaultStyles defaultStyles = styles; List children = line.children - .map((node) => _getTextSpanFromNode(defaultStyles, node)) + .map((node) => _getTextSpanFromNode(defaultStyles, node, styleBuilder)) .toList(growable: false); TextStyle textStyle = TextStyle(); @@ -112,7 +118,8 @@ class TextLine extends StatelessWidget { return TextSpan(children: children, style: textStyle); } - TextSpan _getTextSpanFromNode(DefaultStyles defaultStyles, Node node) { + TextSpan _getTextSpanFromNode( + DefaultStyles defaultStyles, Node node, StyleBuilder styleBuilder) { leaf.Text textNode = node as leaf.Text; Style style = textNode.style; TextStyle res = TextStyle(); @@ -137,7 +144,6 @@ class TextLine extends StatelessWidget { Attribute size = textNode.style.attributes[Attribute.size.key]; if (size != null && size.value != null) { - switch (size.value) { case 'small': res = res.merge(defaultStyles.sizeSmall); @@ -150,11 +156,10 @@ class TextLine extends StatelessWidget { break; default: double fontSize = double.tryParse(size.value); - if(fontSize!=null){ + if (fontSize != null) { res = res.merge(TextStyle(fontSize: fontSize)); - } - else - throw "Invalid size ${size.value}"; + } else + throw "Invalid size ${size.value}"; } } @@ -169,7 +174,16 @@ class TextLine extends StatelessWidget { final backgroundColor = stringToColor(background.value); res = res.merge(new TextStyle(backgroundColor: backgroundColor)); } - + if (styleBuilder != null) + textNode.style.attributes.keys.forEach((key) { + Attribute attribute = + Attribute.fromKeyValue(key, textNode.style.attributes[key]); + if (attribute == null) { + ///Unkown Attribute + TextStyle customStyle = styleBuilder( textNode.style.attributes[key]); + if (customStyle != null) res = res.merge(customStyle); + } + }); return TextSpan(text: textNode.value, style: res); }