Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,19 @@ class _HtmlEditorExampleState extends State<HtmlEditorExample> {
String result = '';
final HtmlEditorController controller = HtmlEditorController();

static const String initialText = '''
<div><br><br></div>
''';

static const String customInternalCSS = '''
<style>
p {
margin: 0;
}
</style>
''';


@override
Widget build(BuildContext context) {
return GestureDetector(
Expand Down Expand Up @@ -73,7 +86,8 @@ class _HtmlEditorExampleState extends State<HtmlEditorExample> {
htmlEditorOptions: const HtmlEditorOptions(
hint: 'Your text here...',
shouldEnsureVisible: true,
//initialText: "<p>text content initial, if any</p>",
initialText: initialText,
customInternalCSS: customInternalCSS,
),
htmlToolbarOptions: HtmlToolbarOptions(
toolbarPosition: ToolbarPosition.aboveEditor, //by default
Expand Down
38 changes: 4 additions & 34 deletions lib/src/html_editor_controller_mobile.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,38 +7,6 @@ import 'package:html_editor_enhanced/src/html_editor_controller_unsupported.dart

/// Controller for mobile
class HtmlEditorController extends unsupported.HtmlEditorController {
HtmlEditorController({
this.processInputHtml = true,
this.processNewLineAsBr = false,
this.processOutputHtml = true,
});

/// Toolbar widget state to call various methods. For internal use only.
@override
ToolbarWidgetState? toolbar;

/// Determines whether text processing should happen on input HTML, e.g.
/// whether a new line should be converted to a <br>.
///
/// The default value is false.
@override
final bool processInputHtml;

/// Determines whether newlines (\n) should be written as <br>. This is not
/// recommended for HTML documents.
///
/// The default value is false.
@override
final bool processNewLineAsBr;

/// Determines whether text processing should happen on output HTML, e.g.
/// whether <p><br></p> is returned as "". For reference, Summernote uses
/// that HTML as the default HTML (when no text is in the editor).
///
/// The default value is true.
@override
final bool processOutputHtml;

/// Manages the [InAppWebViewController] for the [HtmlEditorController]
InAppWebViewController? _editorController;

Expand Down Expand Up @@ -73,7 +41,9 @@ class HtmlEditorController extends unsupported.HtmlEditorController {
text.isEmpty ||
text == '<p></p>' ||
text == '<p><br></p>' ||
text == '<p><br/></p>')) text = '';
text == '<p><br/></p>')) {
text = '';
}
return text ?? '';
}

Expand Down Expand Up @@ -228,7 +198,7 @@ class HtmlEditorController extends unsupported.HtmlEditorController {
void addNotification(String html, NotificationType notificationType) async {
await _evaluateJavascript(source: """
\$('.note-status-output').html(
'<div class="alert alert-${describeEnum(notificationType)}">$html</div>'
'<div class="alert alert-${notificationType.name}">$html</div>'
);
""");
recalculateHeight();
Expand Down
42 changes: 7 additions & 35 deletions lib/src/html_editor_controller_web.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,38 +10,6 @@ import 'package:meta/meta.dart';

/// Controller for web
class HtmlEditorController extends unsupported.HtmlEditorController {
HtmlEditorController({
this.processInputHtml = true,
this.processNewLineAsBr = false,
this.processOutputHtml = true,
});

/// Toolbar widget state to call various methods. For internal use only.
@override
ToolbarWidgetState? toolbar;

/// Determines whether text processing should happen on input HTML, e.g.
/// whether a new line should be converted to a <br>.
///
/// The default value is true.
@override
final bool processInputHtml;

/// Determines whether newlines (\n) should be written as <br>. This is not
/// recommended for HTML documents.
///
/// The default value is false.
@override
final bool processNewLineAsBr;

/// Determines whether text processing should happen on output HTML, e.g.
/// whether <p><br></p> is returned as "". For reference, Summernote uses
/// that HTML as the default HTML (when no text is in the editor).
///
/// The default value is true.
@override
final bool processOutputHtml;

/// Manages the view ID for the [HtmlEditorController] on web
String? _viewId;

Expand All @@ -62,7 +30,9 @@ class HtmlEditorController extends unsupported.HtmlEditorController {
(text.isEmpty ||
text == '<p></p>' ||
text == '<p><br></p>' ||
text == '<p><br/></p>')) text = '';
text == '<p><br/></p>')) {
text = '';
}
return text;
}

Expand All @@ -77,7 +47,9 @@ class HtmlEditorController extends unsupported.HtmlEditorController {
(text.isEmpty ||
text == '<p></p>' ||
text == '<p><br></p>' ||
text == '<p><br/></p>')) text = '';
text == '<p><br/></p>')) {
text = '';
}
return text;
}

Expand Down Expand Up @@ -338,7 +310,7 @@ class HtmlEditorController extends unsupported.HtmlEditorController {
_evaluateJavascriptWeb(data: {
'type': 'toIframe: addNotification',
'html': html,
'alertType': 'alert alert-${describeEnum(notificationType)}'
'alertType': 'alert alert-${notificationType.name}'
});
}
recalculateHeight();
Expand Down
88 changes: 81 additions & 7 deletions lib/src/widgets/html_editor_widget_web.dart
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,68 @@ class _HtmlEditorWidgetWebState extends State<HtmlEditorWidget> {
void initSummernote() async {
var headString = '';
var summernoteCallbacks = '''callbacks: {
${widget.htmlEditorOptions.useDefaultFontSize
? '''
onInit: function() {
const editor = document.querySelector('.note-editable');
if (!editor) return;

editor.style.fontSize = "${widget.htmlEditorOptions.defaultFontSize}px";
editor.style.lineHeight = calcLineHeightPx(`${widget.htmlEditorOptions.defaultFontSize}`) + "px";
},
onChange: function(contents, \$editable) {
normalizeFontAndLineHeight(\$editable[0]);
},
onKeyup: function(e) {
if (e.which === 13) {
setTimeout(() => {
const sel = window.getSelection();
if (!sel.rangeCount) return;
let node = sel.anchorNode;

if (node.nodeType === 3) {
node = node.parentNode;
}

if (node) {
if (['H1', 'H2', 'H3', 'H4', 'H5', 'H6'].includes(node.tagName)) {
return;
}

if (node.tagName === "FONT" && node.style) {
node.style.removeProperty("line-height");
if (node.getAttribute("style") === "") {
node.removeAttribute("style");
}

const parent = node.parentElement;
if (parent && parent.tagName === "FONT") {
parent.replaceWith(node);
}
return;
}

if (node.style) {
const lh = node.style.lineHeight;
const currentLineHeight = calcLineHeightPx(activeFontSize) + "px";
if (lh !== currentLineHeight) {
node.style.lineHeight = currentLineHeight;
}
}

const parent = node.parentElement;
if (parent && parent.tagName === "FONT" && parent.style) {
parent.style.removeProperty("line-height");
if (parent.getAttribute("style") === "") {
parent.removeAttribute("style");
}
}
}
}, 0);
}
},
'''
: ''}
onKeydown: function(e) {
var chars = \$(".note-editable").text();
var totalChars = chars.length;
Expand Down Expand Up @@ -390,24 +452,30 @@ class _HtmlEditorWidgetWebState extends State<HtmlEditorWidget> {
\$('.note-status-output').empty();
}
if (data["type"].includes("execCommand")) {
var commandType = data["command"];
const commandType = data["command"];
const argument = data["argument"];

if (commandType === "hiliteColor") {
if (data["argument"] === null) {
if (argument === null) {
if (!document.execCommand("hiliteColor", false)) {
document.execCommand("backColor", false);
}
} else {
if (!document.execCommand("hiliteColor", false, data["argument"])) {
document.execCommand("backColor", false, data["argument"]);
if (!document.execCommand("hiliteColor", false, argument)) {
document.execCommand("backColor", false, argument);
}
}
} else {
if (data["argument"] === null) {
if (argument === null) {
document.execCommand(commandType, false);
} else {
document.execCommand(commandType, false, data["argument"]);
document.execCommand(commandType, false, argument);
}
}

if (commandType === "formatBlock") {
normalizeAllHeaderStyle(argument);
}
}
if (data["type"].includes("execSummernoteAPI")) {
var nameAPI = data["nameAPI"];
Expand All @@ -417,6 +485,9 @@ class _HtmlEditorWidgetWebState extends State<HtmlEditorWidget> {
} else {
\$('#summernote-2').summernote(nameAPI, value);
}
if (['formatPara', 'formatH1', 'formatH2', 'formatH3', 'formatH4', 'formatH5', 'formatH6'].includes(nameAPI)) {
normalizeAllHeaderStyle(value);
}
}
if (data["type"].includes("setFontSize")) {
setFontSize(data["size"]);
Expand Down Expand Up @@ -533,7 +604,10 @@ class _HtmlEditorWidgetWebState extends State<HtmlEditorWidget> {
${JavascriptUtils.jsHandleCreateSignature(createdViewId)}
${JavascriptUtils.jsHandleOnClickSignature}
${JavascriptUtils.jsDetectBrowser}
${JavascriptUtils.jsHandleSetFontSize}
${widget.htmlEditorOptions.useDefaultFontSize
? JavascriptUtils.jsHandleSetupDefaultFontSize(widget.htmlEditorOptions.defaultFontSize, widget.htmlEditorOptions.defaultLineHeight)
: ''}
${JavascriptUtils.jsHandleSetFontSize(widget.htmlEditorOptions.defaultFontSize)}
${JavascriptUtils.jsHandleInsertImageWithSafeSignature}

function onSelectionChange() {
Expand Down
Loading