diff --git a/.gitignore b/.gitignore index af56f6105..0406f9349 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ +.idea/ +packages/zefyr/example/ios/Flutter/flutter_export_environment.sh .DS_Store .idea/ diff --git a/doc/concepts/attributes.md b/doc/concepts/attributes.md index fe3d10c97..5c4877474 100644 --- a/doc/concepts/attributes.md +++ b/doc/concepts/attributes.md @@ -19,7 +19,8 @@ attribute can be either *inline-scoped* or *line-scoped*, but not both. A good example of an inline-scoped attribute is "bold" attribute. Bold style can be applied to any character within a line, but not to the line itself. Similarly "heading" style is line-scoped and has effect -only on the line as a whole. +only on the line as a whole. A custom *inline-scoped* attributes can be +added for tracking of non-UI based attributes. Below table summarizes information about all currently supported attributes in Zefyr: @@ -32,6 +33,7 @@ attributes in Zefyr: | Heading | `heading` | `line` | `int` | `1`, `2` and `3` | | Block | `block` | `line` | `String` | `"ul"`, `"ol"`, `"code"` and `"quote"` | | Embed | `embed` | `inline` | `Map` | `"hr"`, `"image"` | +| Custom | `custom` | `inline` | `String` | Non-empty string | Removing a specific style is as simple as setting corresponding attribute to `null`. @@ -68,6 +70,9 @@ void makeItPretty(NotusDocument document) { // Remove heading style from the first line. All attributes // have `unset` property which can be used the same way. document.format(0, 0, NotusAttribute.heading.unset); + + // Add a custom attribute that does not reflect in the UI + document.format(15, 23, NotusAttribute.custom.withValue('customAttribute')); } ``` diff --git a/packages/notus/example/main.dart b/packages/notus/example/main.dart index 854e771a1..eeb0161b4 100644 --- a/packages/notus/example/main.dart +++ b/packages/notus/example/main.dart @@ -11,6 +11,7 @@ void main() { 0, 'Notus package provides rich text document model for Zefyr editor'); doc.format(0, 5, NotusAttribute.bold); // Makes first word bold. doc.format(0, 0, NotusAttribute.h1); // Makes first line a heading. + doc.format(15, 23, NotusAttribute.custom.withValue('customAttribute')); // Adds a non-UI custom attribute doc.delete(23, 10); // Deletes "rich text " segment. // Collects style attributes at 1 character in this document. diff --git a/packages/notus/lib/src/document/attributes.dart b/packages/notus/lib/src/document/attributes.dart index a5ebaacfa..0ea49d639 100644 --- a/packages/notus/lib/src/document/attributes.dart +++ b/packages/notus/lib/src/document/attributes.dart @@ -77,6 +77,7 @@ class NotusAttribute implements NotusAttributeBuilder { NotusAttribute.heading.key: NotusAttribute.heading, NotusAttribute.block.key: NotusAttribute.block, NotusAttribute.embed.key: NotusAttribute.embed, + NotusAttribute.custom.key: NotusAttribute.custom, }; // Inline attributes @@ -126,6 +127,9 @@ class NotusAttribute implements NotusAttributeBuilder { // ignore: const_eval_throws_exception static const embed = EmbedAttributeBuilder._(); + /// Custom attribute. + static final custom = CustomAttributeBuilder._(); + static NotusAttribute _fromKeyValue(String key, dynamic value) { if (!_registry.containsKey(key)) { throw ArgumentError.value( @@ -454,3 +458,16 @@ class EmbedAttribute extends NotusAttribute> { return hashObjects(objects); } } + +/// Builder for custom attributes that do not necessarily need styling. +/// +/// There is no need to use this class directly, consider using +/// [NotusAttribute.custom] instead. +class CustomAttributeBuilder extends NotusAttributeBuilder { + static const _kCustom = 'custom'; + + const CustomAttributeBuilder._() : super._(_kCustom, NotusAttributeScope.inline); + + NotusAttribute withValue(String value) => NotusAttribute._(key, scope, value); +} +