@@ -24,6 +24,7 @@ class TextLine extends StatefulWidget {
2424 const TextLine ({
2525 required this .line,
2626 required this .embedBuilder,
27+ required this .textSpanBuilder,
2728 required this .styles,
2829 required this .readOnly,
2930 required this .controller,
@@ -40,6 +41,7 @@ class TextLine extends StatefulWidget {
4041 final Line line;
4142 final TextDirection ? textDirection;
4243 final EmbedsBuilder embedBuilder;
44+ final TextSpanBuilder textSpanBuilder;
4345 final DefaultStyles styles;
4446 final bool readOnly;
4547 final QuillController controller;
@@ -192,7 +194,12 @@ class _TextLineState extends State<TextLine> {
192194 InlineSpan _getTextSpanForWholeLine () {
193195 var lineStyle = _getLineStyle (widget.styles);
194196 if (! widget.line.hasEmbed) {
195- return _buildTextSpan (widget.styles, widget.line.children, lineStyle);
197+ return _buildTextSpan (
198+ widget.styles,
199+ widget.line.children,
200+ lineStyle,
201+ widget.textSpanBuilder,
202+ );
196203 }
197204
198205 // The line could contain more than one Embed & more than one Text
@@ -201,8 +208,12 @@ class _TextLineState extends State<TextLine> {
201208 for (var child in widget.line.children) {
202209 if (child is Embed ) {
203210 if (textNodes.isNotEmpty) {
204- textSpanChildren
205- .add (_buildTextSpan (widget.styles, textNodes, lineStyle));
211+ textSpanChildren.add (_buildTextSpan (
212+ widget.styles,
213+ textNodes,
214+ lineStyle,
215+ widget.textSpanBuilder,
216+ ));
206217 textNodes = LinkedList <Node >();
207218 }
208219 // Creates correct node for custom embed
@@ -243,7 +254,12 @@ class _TextLineState extends State<TextLine> {
243254 }
244255
245256 if (textNodes.isNotEmpty) {
246- textSpanChildren.add (_buildTextSpan (widget.styles, textNodes, lineStyle));
257+ textSpanChildren.add (_buildTextSpan (
258+ widget.styles,
259+ textNodes,
260+ lineStyle,
261+ widget.textSpanBuilder,
262+ ));
247263 }
248264
249265 return TextSpan (style: lineStyle, children: textSpanChildren);
@@ -263,10 +279,11 @@ class _TextLineState extends State<TextLine> {
263279 return TextAlign .start;
264280 }
265281
266- TextSpan _buildTextSpan (
282+ InlineSpan _buildTextSpan (
267283 DefaultStyles defaultStyles,
268284 LinkedList <Node > nodes,
269285 TextStyle lineStyle,
286+ TextSpanBuilder textSpanBuilder,
270287 ) {
271288 if (nodes.isEmpty && kIsWeb) {
272289 nodes = LinkedList <Node >()..add (leaf.QuillText ('\u {200B}' ));
@@ -280,20 +297,28 @@ class _TextLineState extends State<TextLine> {
280297
281298 if (isComposingRangeOutOfLine) {
282299 final children = nodes
283- .map ((node) =>
284- _getTextSpanFromNode (defaultStyles, node, widget.line.style))
300+ .map ((node) => _getTextSpanFromNode (
301+ defaultStyles,
302+ node,
303+ widget.line.style,
304+ textSpanBuilder,
305+ ))
285306 .toList (growable: false );
286307 return TextSpan (children: children, style: lineStyle);
287308 }
288309
289310 final children = nodes.expand ((node) {
290- final child =
291- _getTextSpanFromNode (defaultStyles, node, widget.line.style);
311+ final child = _getTextSpanFromNode (
312+ defaultStyles,
313+ node,
314+ widget.line.style,
315+ textSpanBuilder,
316+ );
292317 final isNodeInComposingRange =
293318 node.documentOffset <= widget.composingRange.start &&
294319 widget.composingRange.end <= node.documentOffset + node.length;
295320 if (isNodeInComposingRange) {
296- return _splitAndApplyComposingStyle (node, child);
321+ return _splitAndApplyComposingStyle (node, child, textSpanBuilder );
297322 } else {
298323 return [child];
299324 }
@@ -304,7 +329,11 @@ class _TextLineState extends State<TextLine> {
304329
305330 // split the text nodes into composing and non-composing nodes
306331 // and apply the composing style to the composing nodes
307- List <InlineSpan > _splitAndApplyComposingStyle (Node node, InlineSpan child) {
332+ List <InlineSpan > _splitAndApplyComposingStyle (
333+ Node node,
334+ InlineSpan child,
335+ TextSpanBuilder textSpanBuilder,
336+ ) {
308337 assert (widget.composingRange.isValid && ! widget.composingRange.isCollapsed);
309338
310339 final composingStart = widget.composingRange.start - node.documentOffset;
@@ -319,18 +348,33 @@ class _TextLineState extends State<TextLine> {
319348 ? .merge (const TextStyle (decoration: TextDecoration .underline)) ??
320349 const TextStyle (decoration: TextDecoration .underline);
321350
351+ final isLink = node.style.attributes[Attribute .link.key]? .value != null ;
352+ final recognizer = _getRecognizer (node, isLink);
353+
322354 return [
323- TextSpan (
324- text: textBefore,
325- style: child.style,
355+ textSpanBuilder (
356+ context,
357+ node,
358+ 0 ,
359+ textBefore,
360+ child.style,
361+ recognizer,
326362 ),
327- TextSpan (
328- text: textComposing,
329- style: composingStyle,
363+ textSpanBuilder (
364+ context,
365+ node,
366+ composingStart,
367+ textComposing,
368+ composingStyle,
369+ recognizer,
330370 ),
331- TextSpan (
332- text: textAfter,
333- style: child.style,
371+ textSpanBuilder (
372+ context,
373+ node,
374+ composingEnd,
375+ textAfter,
376+ child.style,
377+ recognizer,
334378 ),
335379 ];
336380 }
@@ -461,7 +505,11 @@ class _TextLineState extends State<TextLine> {
461505 }
462506
463507 InlineSpan _getTextSpanFromNode (
464- DefaultStyles defaultStyles, Node node, Style lineStyle) {
508+ DefaultStyles defaultStyles,
509+ Node node,
510+ Style lineStyle,
511+ TextSpanBuilder textSpanBuilder,
512+ ) {
465513 final textNode = node as leaf.QuillText ;
466514 final nodeStyle = textNode.style;
467515 final isLink = nodeStyle.containsKey (Attribute .link.key) &&
@@ -480,11 +528,13 @@ class _TextLineState extends State<TextLine> {
480528 }
481529
482530 final recognizer = _getRecognizer (node, isLink);
483- return TextSpan (
484- text: textNode.value,
485- style: style,
486- recognizer: recognizer,
487- mouseCursor: (recognizer != null ) ? SystemMouseCursors .click : null ,
531+ return textSpanBuilder (
532+ context,
533+ textNode,
534+ 0 ,
535+ textNode.value,
536+ style,
537+ recognizer,
488538 );
489539 }
490540
0 commit comments