Skip to content

Commit

Permalink
3++++
Browse files Browse the repository at this point in the history
  • Loading branch information
Ellet committed Dec 5, 2023
1 parent 59ada7f commit 8792025
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,7 @@ final quillImagesSample = [
{'insert': '\n'},
{
'insert': {'image': Assets.images.screenshot1.path},
'attributes': {
'width': '200',
'height': '500',
'style': 'width:500px; height:350px; margin: 20px;'
}
'attributes': {'style': 'width: 40vh; height:350px; margin: 20px;'}
},
{'insert': '\n'},
{'insert': 'Here is a network image: \n'},
Expand Down
1 change: 1 addition & 0 deletions flutter_quill_extensions/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ All notable changes to this project will be documented in this file.
* Fix a bug in the example when inserting an image from url
* Flutter Quill Extensions:
* Add support for copying the image to the system cliboard
* Add support for other CSS units like (vh, vw) and more

## 9.0.0-dev-2
* An attemp to fix CI automated publishing
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@ class QuillEditorImageEmbedBuilder extends EmbedBuilder {
// assert(!kIsWeb, 'Please provide image EmbedBuilder for Web');

final imageSource = standardizeImageUrl(node.value.data);
final ((imageSize), margin, alignment) = getElementAttributes(node);
final ((imageSize), margin, alignment) = getElementAttributes(
node,
context,
);

final width = imageSize.width;
final height = imageSize.height;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@ class QuillEditorVideoEmbedBuilder extends EmbedBuilder {
readOnly: readOnly,
);
}
final ((elementSize), margin, alignment) = getElementAttributes(node);
final ((elementSize), margin, alignment) = getElementAttributes(
node,
context,
);

final width = elementSize.width;
final height = elementSize.height;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'package:flutter/widgets.dart' show BuildContext, MediaQuery;

Map<String, String> parseCssString(String cssString) {
final result = <String, String>{};
final declarations = cssString.split(';');
Expand All @@ -14,16 +16,71 @@ Map<String, String> parseCssString(String cssString) {
return result;
}

double? parseCssPropertyAsDouble(String value) {
enum _CssUnit {
px('px'),
percentage('%'),
viewportWidth('vw'),
viewportHeight('vh'),
em('em'),
rem('rem'),
invalid('invalid');

const _CssUnit(this.cssName);

final String cssName;
}

double? parseCssPropertyAsDouble(
String value, {
required BuildContext context,
}) {
if (value.trim().isEmpty) {
return null;
}
final list = [
'px',
// '%', 'vw', 'vh', 'em', 'rem'
];
for (final element in list) {
value = value.replaceFirst(element, '');

// Try to parse it in case it's a valid double already
var doubleValue = double.tryParse(value);

if (doubleValue != null) {
return doubleValue;
}

// If not then if it's a css numberic value then we will try to parse it
final unit = _CssUnit.values
.where((element) => value.endsWith(element.cssName))
.firstOrNull;
if (unit == null) {
return null;
}
value = value.replaceFirst(unit.cssName, '');
doubleValue = double.tryParse(value);
if (doubleValue != null) {
switch (unit) {
case _CssUnit.px:
// Do nothing
break;
case _CssUnit.percentage:
// Not supported yet
doubleValue = null;
break;
case _CssUnit.viewportWidth:
doubleValue = (doubleValue / 100) * MediaQuery.sizeOf(context).width;
break;
case _CssUnit.viewportHeight:
doubleValue = (doubleValue / 100) * MediaQuery.sizeOf(context).height;
break;
case _CssUnit.em:
doubleValue = MediaQuery.textScalerOf(context).scale(doubleValue);
break;
case _CssUnit.rem:
// Not fully supported yet
doubleValue = MediaQuery.textScalerOf(context).scale(doubleValue);
break;
case _CssUnit.invalid:
// Ignore
doubleValue = null;
break;
}
}
return double.tryParse(value);
return doubleValue;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import 'package:flutter/foundation.dart' show immutable;
import 'package:flutter/widgets.dart' show Alignment;
import 'package:flutter/widgets.dart' show Alignment, BuildContext;
import 'package:flutter_quill/extensions.dart';
import 'package:flutter_quill/flutter_quill.dart' show Attribute, Node;

Expand All @@ -18,15 +18,20 @@ enum ExtraElementProperties {
Alignment alignment,
) getElementAttributes(
Node node,
BuildContext context,
) {
var elementSize = const ElementSize(null, null);
var elementAlignment = Alignment.center;
double? elementMargin;

final heightValue = parseCssPropertyAsDouble(
node.style.attributes[Attribute.height.key]?.value.toString() ?? '');
node.style.attributes[Attribute.height.key]?.value.toString() ?? '',
context: context,
);
final widthValue = parseCssPropertyAsDouble(
node.style.attributes[Attribute.width.key]?.value.toString() ?? '');
node.style.attributes[Attribute.width.key]?.value.toString() ?? '',
context: context,
);

if (heightValue != null) {
elementSize = elementSize.copyWith(
Expand All @@ -47,10 +52,14 @@ enum ExtraElementProperties {
final cssAttrs = parseCssString(cssStyle.value.toString());

// todo: This could be improved much better
final cssHeightValue =
parseCssPropertyAsDouble((cssAttrs[Attribute.height.key]) ?? '');
final cssWidthValue =
parseCssPropertyAsDouble((cssAttrs[Attribute.width.key]) ?? '');
final cssHeightValue = parseCssPropertyAsDouble(
(cssAttrs[Attribute.height.key]) ?? '',
context: context,
);
final cssWidthValue = parseCssPropertyAsDouble(
(cssAttrs[Attribute.width.key]) ?? '',
context: context,
);

// cssHeightValue != null && elementSize.height == null
if (cssHeightValue != null) {
Expand Down
9 changes: 7 additions & 2 deletions flutter_quill_extensions/lib/utils/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,13 @@ Future<Uint8List?> convertImageToUint8List(String image) async {
}
return null;
}
final file = XFile(image);
return await file.readAsBytes();
// TODO: Add support for all image providers like AssetImage
try {
final file = XFile(image);
return await file.readAsBytes();
} catch (e) {
return null;
}
}

Future<SaveImageResult> saveImage({
Expand Down

0 comments on commit 8792025

Please sign in to comment.