diff --git a/CHANGELOG.md b/CHANGELOG.md index e312efc51..5d7353455 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - Fixed `View.of(context)` calls throwing when used with the `screenshot` package [#2662](https://github.com/singerdmx/flutter-quill/pull/2662). +- Fixed support for html named colors [#2675](https://github.com/singerdmx/flutter-quill/pull/2675) ### Added diff --git a/lib/src/common/utils/color.dart b/lib/src/common/utils/color.dart index 06724af61..19ad4a222 100644 --- a/lib/src/common/utils/color.dart +++ b/lib/src/common/utils/color.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'web_colors.dart'; import '../../editor/widgets/default_styles.dart'; @@ -115,7 +116,12 @@ Color stringToColor(String? s, return Colors.brown; } - if (s!.startsWith('rgba')) { + // is it an html named color? + if (WebColors.namedColors.containsKey(s!.toLowerCase())) { + return WebColors.namedColors[s.toLowerCase()]!; + } + + if (s.startsWith('rgba')) { s = s.substring(5); // trim left 'rgba(' s = s.substring(0, s.length - 1); // trim right ')' final arr = s.split(',').map((e) => e.trim()).toList(); @@ -129,7 +135,7 @@ Color stringToColor(String? s, } if (!s.startsWith('#')) { - throw UnsupportedError('Color code not supported'); + throw UnsupportedError('Color code not supported: $s'); } var hex = s.replaceFirst('#', ''); diff --git a/lib/src/common/utils/web_colors.dart b/lib/src/common/utils/web_colors.dart new file mode 100644 index 000000000..07e49000d --- /dev/null +++ b/lib/src/common/utils/web_colors.dart @@ -0,0 +1,475 @@ +// This list of color constants is based on the Kolors package: +// https://github.com/vincevargadev/kolors_flutter + +import 'dart:ui'; +import 'package:flutter/foundation.dart'; + +/// All the named web colors. +class WebColors { + static const indianRed = Color(0xFFCD5C5C); + static const lightCoral = Color(0xFFF08080); + static const salmon = Color(0xFFFA8072); + static const darkSalmon = Color(0xFFE9967A); + static const lightSalmon = Color(0xFFFFA07A); + static const crimson = Color(0xFFDC143C); + static const red = Color(0xFFFF0000); + static const fireBrick = Color(0xFFB22222); + static const darkRed = Color(0xFF8B0000); + static const pink = Color(0xFFFFC0CB); + static const lightPink = Color(0xFFFFB6C1); + static const hotPink = Color(0xFFFF69B4); + static const deepPink = Color(0xFFFF1493); + static const mediumVioletRed = Color(0xFFC71585); + static const paleVioletRed = Color(0xFFDB7093); + static const coral = Color(0xFFFF7F50); + static const tomato = Color(0xFFFF6347); + static const orangeRed = Color(0xFFFF4500); + static const darkOrange = Color(0xFFFF8C00); + static const orange = Color(0xFFFFA500); + static const gold = Color(0xFFFFD700); + static const yellow = Color(0xFFFFFF00); + static const lightYellow = Color(0xFFFFFFE0); + static const lemonChiffon = Color(0xFFFFFACD); + static const lightGoldenrodYellow = Color(0xFFFAFAD2); + static const papayaWhip = Color(0xFFFFEFD5); + static const moccasin = Color(0xFFFFE4B5); + static const peachPuff = Color(0xFFFFDAB9); + static const paleGoldenrod = Color(0xFFEEE8AA); + static const khaki = Color(0xFFF0E68C); + static const darkKhaki = Color(0xFFBDB76B); + static const lavender = Color(0xFFE6E6FA); + static const thistle = Color(0xFFD8BFD8); + static const plum = Color(0xFFDDA0DD); + static const violet = Color(0xFFEE82EE); + static const orchid = Color(0xFFDA70D6); + static const fuchsia = Color(0xFFFF00FF); + static const magenta = Color(0xFFFF00FF); + static const mediumOrchid = Color(0xFFBA55D3); + static const mediumPurple = Color(0xFF9370DB); + static const rebeccaPurple = Color(0xFF663399); + static const blueViolet = Color(0xFF8A2BE2); + static const darkViolet = Color(0xFF9400D3); + static const darkOrchid = Color(0xFF9932CC); + static const darkMagenta = Color(0xFF8B008B); + static const purple = Color(0xFF800080); + static const indigo = Color(0xFF4B0082); + static const slateBlue = Color(0xFF6A5ACD); + static const darkSlateBlue = Color(0xFF483D8B); + static const mediumSlateBlue = Color(0xFF7B68EE); + static const greenYellow = Color(0xFFADFF2F); + static const chartreuse = Color(0xFF7FFF00); + static const lawnGreen = Color(0xFF7CFC00); + static const lime = Color(0xFF00FF00); + static const limeGreen = Color(0xFF32CD32); + static const paleGreen = Color(0xFF98FB98); + static const lightGreen = Color(0xFF90EE90); + static const mediumSpringGreen = Color(0xFF00FA9A); + static const springGreen = Color(0xFF00FF7F); + static const mediumSeaGreen = Color(0xFF3CB371); + static const seaGreen = Color(0xFF2E8B57); + static const forestGreen = Color(0xFF228B22); + static const green = Color(0xFF008000); + static const darkGreen = Color(0xFF006400); + static const yellowGreen = Color(0xFF9ACD32); + static const oliveDrab = Color(0xFF6B8E23); + static const olive = Color(0xFF808000); + static const darkOliveGreen = Color(0xFF556B2F); + static const mediumAquamarine = Color(0xFF66CDAA); + static const darkSeaGreen = Color(0xFF8FBC8B); + static const lightSeaGreen = Color(0xFF20B2AA); + static const darkCyan = Color(0xFF008B8B); + static const teal = Color(0xFF008080); + static const aqua = Color(0xFF00FFFF); + static const cyan = Color(0xFF00FFFF); + static const lightCyan = Color(0xFFE0FFFF); + static const paleTurquoise = Color(0xFFAFEEEE); + static const aquamarine = Color(0xFF7FFFD4); + static const turquoise = Color(0xFF40E0D0); + static const mediumTurquoise = Color(0xFF48D1CC); + static const darkTurquoise = Color(0xFF00CED1); + static const cadetBlue = Color(0xFF5F9EA0); + static const steelBlue = Color(0xFF4682B4); + static const lightSteelBlue = Color(0xFFB0C4DE); + static const powderBlue = Color(0xFFB0E0E6); + static const lightBlue = Color(0xFFADD8E6); + static const skyBlue = Color(0xFF87CEEB); + static const lightSkyBlue = Color(0xFF87CEFA); + static const deepSkyBlue = Color(0xFF00BFFF); + static const dodgerBlue = Color(0xFF1E90FF); + static const cornflowerBlue = Color(0xFF6495ED); + static const royalBlue = Color(0xFF4169E1); + static const blue = Color(0xFF0000FF); + static const mediumBlue = Color(0xFF0000CD); + static const darkBlue = Color(0xFF00008B); + static const navy = Color(0xFF000080); + static const midnightBlue = Color(0xFF191970); + static const cornsilk = Color(0xFFFFF8DC); + static const blanchedAlmond = Color(0xFFFFEBCD); + static const bisque = Color(0xFFFFE4C4); + static const navajoWhite = Color(0xFFFFDEAD); + static const wheat = Color(0xFFF5DEB3); + static const burlyWood = Color(0xFFDEB887); + static const tan = Color(0xFFD2B48C); + static const rosyBrown = Color(0xFFBC8F8F); + static const sandyBrown = Color(0xFFF4A460); + static const goldenrod = Color(0xFFDAA520); + static const darkGoldenrod = Color(0xFFB8860B); + static const peru = Color(0xFFCD853F); + static const chocolate = Color(0xFFD2691E); + static const saddleBrown = Color(0xFF8B4513); + static const sienna = Color(0xFFA0522D); + static const brown = Color(0xFFA52A2A); + static const maroon = Color(0xFF800000); + static const white = Color(0xFFFFFFFF); + static const snow = Color(0xFFFFFAFA); + static const honeyDew = Color(0xFFF0FFF0); + static const mintCream = Color(0xFFF5FFFA); + static const azure = Color(0xFFF0FFFF); + static const aliceBlue = Color(0xFFF0F8FF); + static const ghostWhite = Color(0xFFF8F8FF); + static const whiteSmoke = Color(0xFFF5F5F5); + static const seaShell = Color(0xFFFFF5EE); + static const beige = Color(0xFFF5F5DC); + static const oldLace = Color(0xFFFDF5E6); + static const floralWhite = Color(0xFFFFFAF0); + static const ivory = Color(0xFFFFFFF0); + static const antiqueWhite = Color(0xFFFAEBD7); + static const linen = Color(0xFFFAF0E6); + static const lavenderBlush = Color(0xFFFFF0F5); + static const mistyRose = Color(0xFFFFE4E1); + static const gainsboro = Color(0xFFDCDCDC); + static const lightGray = Color(0xFFD3D3D3); + static const silver = Color(0xFFC0C0C0); + static const darkGray = Color(0xFFA9A9A9); + static const gray = Color(0xFF808080); + static const dimGray = Color(0xFF696969); + static const lightSlateGray = Color(0xFF778899); + static const slateGray = Color(0xFF708090); + static const darkSlateGray = Color(0xFF2F4F4F); + static const black = Color(0xFF000000); + static const transparent = Color(0); + + static const values = [ + indianRed, + lightCoral, + salmon, + darkSalmon, + lightSalmon, + crimson, + red, + fireBrick, + darkRed, + pink, + lightPink, + hotPink, + deepPink, + mediumVioletRed, + paleVioletRed, + coral, + tomato, + orangeRed, + darkOrange, + orange, + gold, + yellow, + lightYellow, + lemonChiffon, + lightGoldenrodYellow, + papayaWhip, + moccasin, + peachPuff, + paleGoldenrod, + khaki, + darkKhaki, + lavender, + thistle, + plum, + violet, + orchid, + fuchsia, + magenta, + mediumOrchid, + mediumPurple, + rebeccaPurple, + blueViolet, + darkViolet, + darkOrchid, + darkMagenta, + purple, + indigo, + slateBlue, + darkSlateBlue, + mediumSlateBlue, + greenYellow, + chartreuse, + lawnGreen, + lime, + limeGreen, + paleGreen, + lightGreen, + mediumSpringGreen, + springGreen, + mediumSeaGreen, + seaGreen, + forestGreen, + green, + darkGreen, + yellowGreen, + oliveDrab, + olive, + darkOliveGreen, + mediumAquamarine, + darkSeaGreen, + lightSeaGreen, + darkCyan, + teal, + aqua, + cyan, + lightCyan, + paleTurquoise, + aquamarine, + turquoise, + mediumTurquoise, + darkTurquoise, + cadetBlue, + steelBlue, + lightSteelBlue, + powderBlue, + lightBlue, + skyBlue, + lightSkyBlue, + deepSkyBlue, + dodgerBlue, + cornflowerBlue, + royalBlue, + blue, + mediumBlue, + darkBlue, + navy, + midnightBlue, + cornsilk, + blanchedAlmond, + bisque, + navajoWhite, + wheat, + burlyWood, + tan, + rosyBrown, + sandyBrown, + goldenrod, + darkGoldenrod, + peru, + chocolate, + saddleBrown, + sienna, + brown, + maroon, + white, + snow, + honeyDew, + mintCream, + azure, + aliceBlue, + ghostWhite, + whiteSmoke, + seaShell, + beige, + oldLace, + floralWhite, + ivory, + antiqueWhite, + linen, + lavenderBlush, + mistyRose, + gainsboro, + lightGray, + silver, + darkGray, + gray, + dimGray, + lightSlateGray, + slateGray, + darkSlateGray, + black, + ]; + + /// All web colors as a Map. + static const namedColors = { + 'indianred': indianRed, + 'lightcoral': lightCoral, + 'salmon': salmon, + 'darksalmon': darkSalmon, + 'lightsalmon': lightSalmon, + 'crimson': crimson, + 'red': red, + 'firebrick': fireBrick, + 'darkred': darkRed, + 'pink': pink, + 'lightpink': lightPink, + 'hotpink': hotPink, + 'deeppink': deepPink, + 'mediumvioletred': mediumVioletRed, + 'palevioletred': paleVioletRed, + 'coral': coral, + 'tomato': tomato, + 'orangered': orangeRed, + 'darkorange': darkOrange, + 'orange': orange, + 'gold': gold, + 'yellow': yellow, + 'lightyellow': lightYellow, + 'lemonchiffon': lemonChiffon, + 'lightgoldenrodyellow': lightGoldenrodYellow, + 'papayawhip': papayaWhip, + 'moccasin': moccasin, + 'peachpuff': peachPuff, + 'palegoldenrod': paleGoldenrod, + 'khaki': khaki, + 'darkkhaki': darkKhaki, + 'lavender': lavender, + 'thistle': thistle, + 'plum': plum, + 'violet': violet, + 'orchid': orchid, + 'fuchsia': fuchsia, + 'magenta': magenta, + 'mediumorchid': mediumOrchid, + 'mediumpurple': mediumPurple, + 'rebeccapurple': rebeccaPurple, + 'blueviolet': blueViolet, + 'darkviolet': darkViolet, + 'darkorchid': darkOrchid, + 'darkmagenta': darkMagenta, + 'purple': purple, + 'indigo': indigo, + 'slateblue': slateBlue, + 'darkslateblue': darkSlateBlue, + 'mediumslateblue': mediumSlateBlue, + 'greenyellow': greenYellow, + 'chartreuse': chartreuse, + 'lawngreen': lawnGreen, + 'lime': lime, + 'limegreen': limeGreen, + 'palegreen': paleGreen, + 'lightgreen': lightGreen, + 'mediumspringgreen': mediumSpringGreen, + 'springgreen': springGreen, + 'mediumseagreen': mediumSeaGreen, + 'seagreen': seaGreen, + 'forestgreen': forestGreen, + 'green': green, + 'darkgreen': darkGreen, + 'yellowgreen': yellowGreen, + 'olivedrab': oliveDrab, + 'olive': olive, + 'darkolivegreen': darkOliveGreen, + 'mediumaquamarine': mediumAquamarine, + 'darkseagreen': darkSeaGreen, + 'lightseagreen': lightSeaGreen, + 'darkcyan': darkCyan, + 'teal': teal, + 'aqua': aqua, + 'cyan': cyan, + 'lightcyan': lightCyan, + 'paleturquoise': paleTurquoise, + 'aquamarine': aquamarine, + 'turquoise': turquoise, + 'mediumturquoise': mediumTurquoise, + 'darkturquoise': darkTurquoise, + 'cadetblue': cadetBlue, + 'steelblue': steelBlue, + 'lightsteelblue': lightSteelBlue, + 'powderblue': powderBlue, + 'lightblue': lightBlue, + 'skyblue': skyBlue, + 'lightskyblue': lightSkyBlue, + 'deepskyblue': deepSkyBlue, + 'dodgerblue': dodgerBlue, + 'cornflowerblue': cornflowerBlue, + 'royalblue': royalBlue, + 'blue': blue, + 'mediumblue': mediumBlue, + 'darkblue': darkBlue, + 'navy': navy, + 'midnightblue': midnightBlue, + 'cornsilk': cornsilk, + 'blanchedalmond': blanchedAlmond, + 'bisque': bisque, + 'navajowhite': navajoWhite, + 'wheat': wheat, + 'burlywood': burlyWood, + 'tan': tan, + 'rosybrown': rosyBrown, + 'sandybrown': sandyBrown, + 'goldenrod': goldenrod, + 'darkgoldenrod': darkGoldenrod, + 'peru': peru, + 'chocolate': chocolate, + 'saddlebrown': saddleBrown, + 'sienna': sienna, + 'brown': brown, + 'maroon': maroon, + 'white': white, + 'snow': snow, + 'honeydew': honeyDew, + 'mintcream': mintCream, + 'azure': azure, + 'aliceblue': aliceBlue, + 'ghostwhite': ghostWhite, + 'whitesmoke': whiteSmoke, + 'seashell': seaShell, + 'beige': beige, + 'oldlace': oldLace, + 'floralwhite': floralWhite, + 'ivory': ivory, + 'antiquewhite': antiqueWhite, + 'linen': linen, + 'lavenderblush': lavenderBlush, + 'mistyrose': mistyRose, + 'gainsboro': gainsboro, + 'lightgray': lightGray, + 'silver': silver, + 'darkgray': darkGray, + 'gray': gray, + 'dimgray': dimGray, + 'lightslategray': lightSlateGray, + 'slategray': slateGray, + 'darkslategray': darkSlateGray, + 'black': black, + + // the follow colors were part of the CSS2 standard, but have since been removed. + // however these names tend to show up when copy/pasting from Microsoft products + // into Quill on web. W3C recommends using a default color for these. + // + // For more info, see here + // http://w3.org/TR/CSS2/ui.html#system-colors + 'activeborder': black, + 'activecaption': black, + 'appworkspace': transparent, + 'background': transparent, + 'buttonface': transparent, + 'buttonhighlight': transparent, + 'buttonshadow': transparent, + 'buttontext': black, + 'captiontext': black, + 'graytext': gray, + 'highlight': gray, + 'highlighttext': black, + 'inactiveborder': black, + 'inactivecaption': black, + 'inactivecaptiontext': black, + 'infobackground': transparent, + 'infotext': black, + 'menu': transparent, + 'menutext': black, + 'scrollbar': transparent, + 'threeddarkshadow': transparent, + 'threedface': transparent, + 'threedhighlight': transparent, + 'threedlightshadow': transparent, + 'threedshadow': transparent, + 'window': transparent, + 'windowframe': black, + 'windowtext': black, + }; +} diff --git a/test/common/utils/color_test.dart b/test/common/utils/color_test.dart new file mode 100644 index 000000000..583c77e76 --- /dev/null +++ b/test/common/utils/color_test.dart @@ -0,0 +1,31 @@ +import 'package:flutter_quill/src/common/utils/color.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + group('Colors', () { + test('Can resolve html named colors', () { + // test some web colors to make sure they resolve correctly + expect(stringToColor('lightGoldenrodYellow').toARGB32(), 0xFFFAFAD2); + expect(stringToColor('navajoWhite').toARGB32(), 0xFFFFDEAD); + expect(stringToColor('mistyRose').toARGB32(), 0xFFFFE4E1); + expect(stringToColor('darkSlateGray').toARGB32(), 0xFF2F4F4F); + + // case insensitive + expect(stringToColor('lightgoldenrodyellow').toARGB32(), 0xFFFAFAD2); + expect(stringToColor('LIGHTGOLDENRODYELLOW').toARGB32(), 0xFFFAFAD2); + }); + test('Obsolete CSS2 color names pasted from word resolve to a value', () { + // test some web colors to make sure they resolve correctly + expect(stringToColor('windowtext').toARGB32(), 0xff000000); + }); + test('Can resolve transparent', () { + // test some web colors to make sure they resolve correctly + expect(stringToColor('transparent').toARGB32(), 0); + }); + test('Throws an exception if the color name cannot be converted', () { + // test some web colors to make sure they resolve correctly + expect( + () => stringToColor('not a color'), throwsA(isA())); + }); + }); +}