-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support for Quill attributes and custom blocks
[Feat]: added support for subscript and superscript [Feat]: added support for color and background-color [Feat]: added support for custom blocks [Feat]: added support for custom parsed `DOM Document` using `HtmlToDelta.convertDocument(DOMDocument)` [Chore]: improved README [Chore]: improved documentation about project [Chore]: now `resolveCurrentElement` was moved to the interface to give the same functionality to all implementations
- Loading branch information
CatHood0
committed
Jul 7, 2024
1 parent
fbe255e
commit 95b481d
Showing
12 changed files
with
535 additions
and
118 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,8 @@ | ||
library flutter_quill_delta_from_html; | ||
|
||
export 'package:flutter_quill_delta_from_html/parser/html_to_delta.dart'; | ||
export 'package:flutter_quill_delta_from_html/parser/colors.dart'; | ||
export 'package:flutter_quill_delta_from_html/parser/custom_html_part.dart'; | ||
export 'package:flutter_quill_delta_from_html/parser/html_utils.dart'; | ||
export 'package:flutter_quill_delta_from_html/parser/html_to_operation.dart'; | ||
export 'package:flutter_quill_delta_from_html/parser/extensions/node_ext.dart'; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
///validate the string color to avoid unsupported colors | ||
String validateAndGetColor(String colorString) { | ||
if (colorString.startsWith('#')) return colorString; | ||
return colorToHex(colorString); | ||
} | ||
|
||
///Decide the color format type and parse to hex | ||
String colorToHex(String color) { | ||
// Detectar el tipo de color y llamar a la función correspondiente | ||
if (color.startsWith('rgb(')) { | ||
return rgbToHex(color); | ||
} else if (color.startsWith('rgba(')) { | ||
return rgbaToHex(color); | ||
} else if (color.startsWith('hsl(')) { | ||
return hslToHex(color); | ||
} else if (color.startsWith('hsla(')) { | ||
return hslaToHex(color); | ||
} else { | ||
throw ArgumentError('color format not supported: $color'); | ||
} | ||
} | ||
|
||
///Parse RGB to valid hex string | ||
String rgbToHex(String rgb) { | ||
rgb = rgb.replaceAll('rgb(', '').replaceAll(')', ''); | ||
List<String> rgbValues = rgb.split(','); | ||
int r = int.parse(rgbValues[0].trim()); | ||
int g = int.parse(rgbValues[1].trim()); | ||
int b = int.parse(rgbValues[2].trim()); | ||
return _toHex(r, g, b, 255); | ||
} | ||
|
||
///Parse RGBA to valid hex string | ||
String rgbaToHex(String rgba) { | ||
rgba = rgba.replaceAll('rgba(', '').replaceAll(')', ''); | ||
List<String> rgbaValues = rgba.split(','); | ||
int r = int.parse(rgbaValues[0].trim()); | ||
int g = int.parse(rgbaValues[1].trim()); | ||
int b = int.parse(rgbaValues[2].trim()); | ||
double a = double.parse(rgbaValues[3].trim()); | ||
int alpha = (a * 255).round(); | ||
return _toHex(r, g, b, alpha); | ||
} | ||
|
||
///Parse hsl to valid hex string | ||
String hslToHex(String hsl) { | ||
hsl = hsl.replaceAll('hsl(', '').replaceAll(')', ''); | ||
List<String> hslValues = hsl.split(','); | ||
double h = double.parse(hslValues[0].trim()); | ||
double s = double.parse(hslValues[1].replaceAll('%', '').trim()) / 100; | ||
double l = double.parse(hslValues[2].replaceAll('%', '').trim()) / 100; | ||
List<int> rgb = _hslToRgb(h, s, l); | ||
return _toHex(rgb[0], rgb[1], rgb[2], 255); | ||
} | ||
|
||
///Parse hsla to valid hex string | ||
String hslaToHex(String hsla) { | ||
hsla = hsla.replaceAll('hsla(', '').replaceAll(')', ''); | ||
List<String> hslaValues = hsla.split(','); | ||
double h = double.parse(hslaValues[0].trim()); | ||
double s = double.parse(hslaValues[1].replaceAll('%', '').trim()) / 100; | ||
double l = double.parse(hslaValues[2].replaceAll('%', '').trim()) / 100; | ||
double a = double.parse(hslaValues[3].trim()); | ||
int alpha = (a * 255).round(); | ||
List<int> rgb = _hslToRgb(h, s, l); | ||
return _toHex(rgb[0], rgb[1], rgb[2], alpha); | ||
} | ||
|
||
///Ensure parse hsl to rgb string to make more simple convertion to hex | ||
List<int> _hslToRgb(double h, double s, double l) { | ||
double c = (1 - (2 * l - 1).abs()) * s; | ||
double x = c * (1 - ((h / 60) % 2 - 1).abs()); | ||
double m = l - c / 2; | ||
double r = 0, g = 0, b = 0; | ||
|
||
if (h >= 0 && h < 60) { | ||
r = c; | ||
g = x; | ||
} else if (h >= 60 && h < 120) { | ||
r = x; | ||
g = c; | ||
} else if (h >= 120 && h < 180) { | ||
g = c; | ||
b = x; | ||
} else if (h >= 180 && h < 240) { | ||
g = x; | ||
b = c; | ||
} else if (h >= 240 && h < 300) { | ||
r = x; | ||
b = c; | ||
} else if (h >= 300 && h < 360) { | ||
r = c; | ||
b = x; | ||
} | ||
|
||
int red = ((r + m) * 255).round(); | ||
int green = ((g + m) * 255).round(); | ||
int blue = ((b + m) * 255).round(); | ||
|
||
return [red, green, blue]; | ||
} | ||
|
||
///Conver RGBA values to hex | ||
String _toHex(int r, int g, int b, int a) { | ||
String hexR = r.toRadixString(16).padLeft(2, '0'); | ||
String hexG = g.toRadixString(16).padLeft(2, '0'); | ||
String hexB = b.toRadixString(16).padLeft(2, '0'); | ||
String hexA = a.toRadixString(16).padLeft(2, '0'); | ||
return '#$hexR$hexG$hexB$hexA'; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import 'package:flutter_quill/quill_delta.dart'; | ||
import 'package:html/dom.dart' as dom; | ||
|
||
/// Interface for defining a custom block handler. | ||
abstract class CustomHtmlPart { | ||
/// Determines if this custom block handler matches the given HTML element. | ||
bool matches(dom.Element element); | ||
|
||
/// Converts the HTML element into Delta operations. | ||
List<Operation> convert(dom.Element element, | ||
{Map<String, dynamic>? currentAttributes}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,57 @@ | ||
import 'package:html/dom.dart'; | ||
|
||
///DOM Node extension to make more easy call certain operations or validations | ||
extension NodeExt on Element { | ||
///Ensure to detect italic html tags | ||
bool get isItalic => localName == 'em' || localName == 'i'; | ||
|
||
///Ensure to detect bold html tags | ||
bool get isStrong => localName == 'strong' || localName == 'b'; | ||
|
||
///Ensure to detect underline html tags | ||
bool get isUnderline => localName == 'ins' || localName == 'u'; | ||
|
||
///Ensure to detect strikethrough html tags | ||
bool get isStrike => localName == 's' || localName == 'del'; | ||
|
||
///Ensure to detect p html tags | ||
bool get isParagraph => localName == 'p'; | ||
|
||
///Ensure to detect sub html tags | ||
bool get isSubscript => localName == 'sub'; | ||
|
||
///Ensure to detect sup html tags | ||
bool get isSuperscript => localName == 'sup'; | ||
|
||
///Ensure to detect br html tags | ||
bool get isBreakLine => localName == 'br'; | ||
|
||
///Ensure to detect span html tags | ||
bool get isSpan => localName == 'span'; | ||
bool get isHeader => localName != null && localName!.contains(RegExp('h[1-6]')); | ||
|
||
///Ensure to detect h(1-6) html tags | ||
bool get isHeader => | ||
localName != null && localName!.contains(RegExp('h[1-6]')); | ||
|
||
///Ensure to detect img html tags | ||
bool get isImg => localName == 'img'; | ||
|
||
///Ensure to detect li,ul,ol,<input type=checkbox> html tags | ||
bool get isList => | ||
localName == 'li' || localName == 'ul' || localName == 'ol' || querySelector('input[type="checkbox"]') != null; | ||
localName == 'li' || | ||
localName == 'ul' || | ||
localName == 'ol' || | ||
querySelector('input[type="checkbox"]') != null; | ||
|
||
///Ensure to detect video html tags | ||
bool get isVideo => localName == 'video' || localName == 'iframe'; | ||
|
||
///Ensure to detect a html tags | ||
bool get isLink => localName == 'a'; | ||
|
||
///Ensure to detect blockquote html tags | ||
bool get isBlockquote => localName == 'blockquote'; | ||
|
||
///Ensure to detect pre,code html tags | ||
bool get isCodeBlock => localName == 'pre' || localName == 'code'; | ||
} |
Oops, something went wrong.