Skip to content

Commit

Permalink
feat: added support for image styles
Browse files Browse the repository at this point in the history
  • Loading branch information
CatHood0 committed Jul 11, 2024
1 parent 4083c8c commit f3d6ae4
Show file tree
Hide file tree
Showing 8 changed files with 100 additions and 14 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
## 1.3.0

* Feat: added support for padding-left and padding-right
* Feat: added support for image styles and align
* Chore: removed support for `<iframe>`
* Fix: code-block isn't parsed as a block
* Fix: blockquote isn't parsed as a block

## 1.2.8

* Fix: indent level is invalid for Delta format
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@ This is a **Dart** package that converts **HTML** input into Quill **Delta** for
<a>: Hyperlinks with support for the href attribute

<!--Images-->
<img>: Images with support for the src
<img>: Images with support for the src, align, and styles

<!--div-->
<div>: HTML tag containers

<!--Videos -->
<iframe>, <video>: Videos with support for the src
<video>: Videos with support for the src

<!--Blockquotes-->
<blockquote>: Block quotations
Expand All @@ -61,7 +61,7 @@ Add the dependency to your pubspec.yaml:

```yaml
dependencies:
flutter_quill_delta_from_html: ^1.2.8
flutter_quill_delta_from_html: ^1.3.0
```
Then, import the package and use it in your Flutter application:
Expand Down
1 change: 1 addition & 0 deletions lib/flutter_quill_delta_from_html.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
library flutter_quill_delta_from_html;

export 'package:flutter_quill_delta_from_html/parser/font_size_parser.dart';
export 'package:flutter_quill_delta_from_html/parser/indent_parser.dart';
export 'package:flutter_quill_delta_from_html/parser/line_height_parser.dart';
export 'package:flutter_quill_delta_from_html/parser/html_to_delta.dart';
export 'package:flutter_quill_delta_from_html/parser/colors.dart';
Expand Down
2 changes: 1 addition & 1 deletion lib/parser/extensions/node_ext.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ extension NodeExt on Element {
localName == 'li' || localName == 'ul' || localName == 'ol' || querySelector('input[type="checkbox"]') != null;

///Ensure to detect video html tags
bool get isVideo => localName == 'video' || localName == 'iframe';
bool get isVideo => localName == 'video';

///Ensure to detect a html tags
bool get isLink => localName == 'a';
Expand Down
27 changes: 20 additions & 7 deletions lib/parser/html_to_operation.dart
Original file line number Diff line number Diff line change
Expand Up @@ -332,9 +332,22 @@ class DefaultHtmlToOperations extends HtmlOperations {
@override
List<Operation> imgToOp(dom.Element element) {
final String src = element.attributes['src'] ?? '';
final String styles = element.attributes['style'] ?? '';
final String align = element.attributes['align'] ?? '';
final attributes = parseImageStyleAttribute(styles);
if (align.isNotEmpty) {
attributes['alignment'] = align;
}
if (src.isNotEmpty) {
return [
Operation.insert({'image': src})
Operation.insert(
{'image': src},
styles.isEmpty && align.isEmpty
? null
: {
'style': attributes.entries.map((entry) => '${entry.key}:${entry.value}').toList().join(';'),
},
)
];
}
return [];
Expand Down Expand Up @@ -363,27 +376,27 @@ class DefaultHtmlToOperations extends HtmlOperations {
@override
List<Operation> blockquoteToOp(dom.Element element) {
final Delta delta = Delta();
Map<String, dynamic> attributes = {'blockquote': true};
Map<String, dynamic> blockAttributes = {'blockquote': true};

for (final node in element.nodes) {
processNode(node, attributes, delta);
processNode(node, {}, delta);
}

delta.insert('\n', attributes);
delta.insert('\n', blockAttributes);

return delta.toList();
}

@override
List<Operation> codeblockToOp(dom.Element element) {
final Delta delta = Delta();
Map<String, dynamic> attributes = {'code-block': true};
Map<String, dynamic> blockAttributes = {'code-block': true};

for (final node in element.nodes) {
processNode(node, attributes, delta);
processNode(node, {}, delta);
}

delta.insert('\n', attributes);
delta.insert('\n', blockAttributes);

return delta.toList();
}
Expand Down
46 changes: 46 additions & 0 deletions lib/parser/html_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,52 @@ Map<String, dynamic> parseStyleAttribute(String style) {
return attributes;
}

/// Parses a CSS `<img>` style attribute string into Delta attributes.
///
/// Converts CSS styles (like 'width', 'height', 'margin') from [style]
/// into Quill Delta attributes suitable for image rich text formatting.
///
/// Parameters:
/// - [style]: The CSS style attribute string to parse.
///
/// Returns:
/// A map of Delta attributes derived from the CSS styles.
///
/// Example:
/// ```dart
/// final style = 'width: 50px; height: 250px;';
/// print(parseStyleAttribute(style)); // Output: {'width': '50px', 'height': '250px'}
/// ```
Map<String, dynamic> parseImageStyleAttribute(String style) {
Map<String, dynamic> attributes = {};

final styles = style.split(';');
for (var style in styles) {
final parts = style.split(':');
if (parts.length == 2) {
final key = parts[0].trim();
final value = parts[1].trim();

switch (key) {
case 'width':
attributes['width'] = value;
break;
case 'height':
attributes['height'] = value;
break;
case 'margin':
attributes['margin'] = value;
break;
default:
// Ignore other styles
break;
}
}
}

return attributes;
}

/// Processes a DOM [node], converting it into Quill Delta operations.
///
/// Recursively processes the DOM nodes, converting text nodes, inline styles,
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: flutter_quill_delta_from_html
description: "Convert easily HTML inputs content to Quill Delta format"
version: 1.2.8
version: 1.3.0
homepage:
repository: https://github.com/CatHood0/flutter_quill_delta_from_html
issue_tracker: https://github.com/CatHood0/flutter_quill_delta_from_html/issues
Expand Down
22 changes: 20 additions & 2 deletions test/flutter_quill_delta_from_html_test.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:dart_quill_delta/dart_quill_delta.dart';
import 'package:flutter/material.dart';
import 'package:flutter_quill_delta_from_html/flutter_quill_delta_from_html.dart';
import 'package:flutter_quill_delta_from_html/parser/pullquote_block_example.dart';
import 'package:flutter_test/flutter_test.dart';
Expand Down Expand Up @@ -202,13 +203,29 @@ void main() {
expect(delta, expectedDelta);
});

test('Image with styles', () {
const html =
'<p>This is an image:</p><img align="center" style="width: 50px;height: 250px;margin: 5px;" src="https://example.com/image.png" />';
final converter = HtmlToDelta();
final delta = converter.convert(html);

final expectedDelta = Delta()
..insert('This is an image:')
..insert({'image': 'https://example.com/image.png'},
{"style": "width:50px;height:250px;margin:5px;alignment:center"})
..insert('\n');

expect(delta, expectedDelta);
});

test('Code block', () {
const html = '<pre><code>console.log(\'Hello, world!\');</code></pre>';
final converter = HtmlToDelta();
final delta = converter.convert(html);

final expectedDelta = Delta()
..insert("console.log('Hello, world!');\n", {'code-block': true})
..insert("console.log('Hello, world!');")
..insert('\n', {'code-block': true})
..insert('\n');

expect(delta, expectedDelta);
Expand All @@ -220,7 +237,8 @@ void main() {
final delta = converter.convert(html);

final expectedDelta = Delta()
..insert('This is a blockquote\n', {'blockquote': true})
..insert('This is a blockquote')
..insert('\n', {'blockquote': true})
..insert('\n');

expect(delta, expectedDelta);
Expand Down

0 comments on commit f3d6ae4

Please sign in to comment.