Closed EmilStenstrom closed 4 months ago
This is a pretty technically costly feature to add to Quill so there'd have to be a large need from the community for it to become a priority.
Thanks for all of your work on quill.js!
I'm in full support of this and hope it can be prioritized. Inserting <br>
s into line <div>
s with shift + enter would help my company's content editors. We use line <div>
s for denoting paragraphs, but they frequently need a way to just to do a break-line without denoting a separation of paragraphs. Inserting <br>
s into line <div>
s with shift + enter would achieve this perfectly.
Is there any current workaround to get the functionality I want? I've tried every hack I could think of to no avail.
:+1:
I have tried to change DEFAULT_BLOCK_TAG to <p>
but realised that it has no sense without line breaks by shift+enter
Just wondering if there is anymore progress on this? In my editor I'm using the divs as a paragraph so having shift+editor would work great for newlines.
This is not currently being worked on as it still lacks a compelling real world use case.
From a user of an editor / word processor perspective, it's incredibly confusing to have two ways to have newlines, especially when one looks like two (<br>
vs <p>
with padding). I can see why a developer might find this convenient to have richer semantic organization as @davejachimiak mentions, but convenient is a long ways from a need. Furthermore Quill is a WYSIWYG editor, not an HTML editor, and having complete control over the HTML markup it generates is not a project goal.
So there is no way for the user to enter a newline if <div>
s are treated as paragraphs?
A user inserts a newline by hitting enter. If the user hits enter again (leaving the new line blank), they have just created what most readers would consider a new paragraph.
But only if <div>
s are not treated as paragraph (as in Quill's example). But in my case we are treating the <div>
s as paragraphs (i.e. they have margin-bottom: 30px) as we don't want the user to have to press enter twice. The vast majority of the time they want paragraphs so that is our default, occasionally they want a new line which we currently can't provide them with Quill (we are actually using ReactQuill which wraps Quill).
Just thought I'll let you know my use case for it.
+1
a very useful feature!
+1
:+1:
We're building an internal document editor which should act similar to Word. This doesn't :(
@jbrooksuk It doesn't claim to act similar to word. Though, the next update and inclusion of Parchment may provide you with an experience closer to what you're hoping for.
It doesn't claim to act similar to word.
I know that :)
Using shift + enter in a document and bolding text across the two divs created by shift + enter causes the selected text to "jump" or simply doesn't bold the text. Is this a known bug in Quill? Removing the linebreak allows the user to unbold the text.
Console output:
The given range isn't in document.
@cydrobolt I'm assuming you've made some modification to add shift+enter? On the quilljs.com editor shift+enter is the same as enter but in either case bolding across the line does not error.
@jhchen : I can give you a real world use case. We are writing novels. When we are finished, we have to export the text somehow, so finally a designer can work on this and at least we get a book. The problem is, without shift-enter, everything becomes paragraph
. In the designers software, paragraphs will be formatted like for example text-indent: 30px
. because every first line of a paragraph should be intented. But often a writer, doesn't want to have a new paragraph which is intented, but just a new line within the actual paragraph starting at the very left margin. By inserting two normal Returns for a real paragraph and only one for a newline, post production becomes much more complicated, since designers doesn't care about the content.
furtheron, I also have a css which says:
.ql-editor p {
text-indent: 30px;
}
to make reading easier. We are editing our whole books in one document( more then 400 pages when printed). But unfortunatly everything is a new paragraph. By the way, I hoped to get this result with
let Break = Quill.import('blots/break');
Quill.register(Break)
and define a keybord binding like: (here for Ctrl-Return)
linebreak: {
key: 13,
ctrlKey: true,
handler: function (range, context) {
this.quill.insertEmbed(range.index, 'break', true, 'user');
quill.setSelection(range.index + 1, Quill.sources.SILENT);
}
}
but can't get any result. But by th way, nevertheless, Quill is the best WYSIWYG Editor for creating huge docs, I have seen so far
This is an essential feature of any text editor, whether the output is html or books; there is a clear difference between paragraphs and line breaks, and a text editor not supporting both is severely limiting proper content handling.
I'd love to use Quill over other editors, but this is a deal breaker for us.
@tdolsen : as well as for us. but a found a nice workaround and with this we can live quite good:
javascript:
var Parchment = Quill.import('parchment');
var LineBreakClass = new Parchment.Attributor.Class('linebreak', 'linebreak', {
scope: Parchment.Scope.BLOCK
});
Quill.register('formats/linebreak', LineBreakClass);
then inside your keyboard handlers:
...
smartbreak: {
key: 13,
shiftKey: true,
handler: function (range, context) {
this.quill.setSelection(range.index,'silent');
this.quill.insertText(range.index, '\n', 'user')
this.quill.setSelection(range.index +1,'silent');
this.quill.format('linebreak', true,'user');
}
},
paragraph: {
key: 13,
handler: function (range, context) {
this.quill.setSelection(range.index,'silent');
this.quill.insertText(range.index, '\n', 'user')
this.quill.setSelection(range.index +1,'silent');
let f = this.quill.getFormat(range.index +1);
if(f.hasOwnProperty('linebreak')) {
delete(f.linebreak)
this.quill.removeFormat(range.index +1)
for(let key in f){
this.quill.formatText(range.index +1,key,f[key])
}
}
}
....
and finally css:
.ql-editor p {
text-indent: 30px;
margin-top: 10px;
}
p.linebreak-true {
text-indent: 0px;
margin-top: 0px;
}
this causes that shift-enter inserts a new line which is a <p< in quill, but it gets a class linebreak.
the css causes, that normal paragraphs appear with a line indent and a top margin, p.linebreak not. so the writer gets the right feeling.
when exporting quills content to a dektop wordprocessor, just handle the linebreak attribute as a normal linefeed and process all others as normal paragraphs.
hope this helps
@robert-boulanger: Very much. That should be a workable solution, until native support is added. Thanks!
@tdolsen : be welcome ;)
+1 for this feature
We're looking at moving from Trix to Quill for an (e)book editor we're building, as its more stable, and more flexible with regards to attaching random code in the document. But both Trix and Quill suffer for not handling paragraphs/line breaks in this (correct?!) manner. @robert-boulanger : Thanks, your code will let us work around this for now.
But +1 for adding this behaviour to Quill to make it less susceptible to changes/breakage. Many users who are used to professional writing tools are familiar with this UX pattern.
If I understand correct from the documentations, paragraphs are used to mimic linebreaks and linebreaks are rendered as paragraphs. If I really understand it correct and this is by design then I believe there's a fundamental problem with the domain definition...
A document does not consist of lines and line-breaks, it consists of paragraphs (and headings)... Inside the paragraphs you might want to "break" the line and that's where linebreaks comes into play.
...at least for hypertext documents. For plain text the simplest way to mimic a paragraph is to use double line-breaks since you're limited to ASCII characters. But that was the case before hypertext was invented!?
In the current case you have no control on how paragraphs are displayed, you cannot adjust spacing between elements or you cannot indent the text as @robert-boulanger stated. Or as in my case you have to find a hack to get rid of these empty paragraphs after headings :\
If you still think that this is the correct behaviour, it would be nice to have some notice on the quickstart documentation describing this behaviour to save some hours of the programmers maybe...
Jason,
Here you have excellent text editor and I hope you will continue your great work on this. Community that is build around Quill is also great, you have really high quality inputs.
Difference between SHIFT+ENTER
and ENTER
are widely known and used - this is real life scenario.
If you do not accept that journalist, writers, bloggers use paragraphs that can contain brake-line your are wrong. If user hits enter twice is not solution, as code generated is simply wrong -> there are now three paragraphs instead one.
Than think on programmers perspective, ENTER
generates <p></p>
there are 7 chars, and SHIFT+ENTER
should generate <br/>
is 5 chars now. Should we consider now such optimization obsolete ?
Hope you decide to add this high valuable feature.
Just to add an additional reason/use for this feature. We style paragraphs such that the first paragraph after certain elements (e.g. headings, certain embedded blots) has a different styling (usually not indented and a higher margin-top) to subsequent ones, however in some cases the user wants to put line breaks after those elements to format some content which makes styling much harder when everything is a p.
Can anyone explain how Word and Docs survived and thrived to become the most ubiquitous writing tools in the world without adding this?
Keep in mind what's being discussed here is not if you can add this. The answer is yes--Parchment granted this ability. The question is if Quill should build and support this in core.
Because they are general purpose word processors. No one is going to create/compete with them with a quill based editor. Where quill can compete is in more specialised (but still widely used, particularly professional) editors such as those used in publishing. Will quill survive without such a feature? sure. Will quill get wider adoption with such a feature? we think so.
My wife (who is a big Word user) has just mentioned that in fact word does have this distinction. Googling for it yielded discussions such as :
http://superuser.com/questions/453555/how-to-get-word-to-do-line-break-on-enter-rather-than-paragraph-break (in particular, see the comments (not answers) on the question itself to see the rational/benefits)
I guess Word just hides it better than pro tools.
Yeah word, google docs and macos pages has this ability but it's not visible since there's no spacing around paragraphs by default so you get the same result if you do "enter" or "shift+enter".
Try this for google docs: Add some text and select "Format / Line Spacing / Add spacing before + after paragraph", then experiment with "shift + enter" and "enter" to see the difference.
For Pages in mac you can set the amount of spacing by setting "Before Paragraph" and "After Paragraph" under Format / Style tab.
I'm not using word for some years so cannot remember the exact location but I know that you can customize it through "styles" and apply it to all paragraphs, I did it countless times.
+1 for this feature
Outside of the points about paragraphs, the line break is frequently used to add additional lines in a bulleted list, so you begin a list and then hold shift to create the extra content.
I'm trying to implement this functionality, but I'm afraid I'll get the same errors as @cydrobolt (have you found a solution/workaround?), and then have to drop Quill altogether after more than 50h working on it...
@jhchen Even if you don't want to implement this yourself, do you mind just giving some pointers as to how we can implement it ourselves? As you can see, it's a feature A LOT of us desperately need...
Thank you very much. Quill is an amazing library :-)
Here's an approach that worked for me:
Instead of swimming against the current and modifying the existent Break
blot and whatnot (which I spent hours trying to do and couldn't.. 😞 ), I just did some pre and post processing on the HTML itself.
Remove the margins around <p>
tags
Regex to replace </p><p>
with a <br>
(I also added a regex for to replace a blockquote tag per line to just put everything in one with `
Now do the other way around: regex to add again the empty lines between paragraphs (quill seems to automatically add a new blockquote tag per line, so I didn't bother with that one)
???
profit
We end up with the HTML that we all want, with the nice breaks and all, and when it comes time to render that HTML in Quill, we just bend to its will, and format it back the way Quill likes.
HTML Out - <p>no<br>margins<br>here</p><p>double paragraph</p>
HTML In - <p>no<p>margins</p><p>here</p><p><br></br><p>double paragraph</p>
Hope this helps! Good luck!
Just to add a further use case, if you enter an address it is essential to have line breaks. At present, I'm looking at 5 paragraphs, like the below:
Address line 1
Address line 2
Address line 3
Rather than
Address line 1 Address line 2 Address line 3
Really hope this could be looked at at some point!
+1 for this feature.
Just wasted a few hours integrating Quill into my project only to realise shift+enter is not supported.
+1 as well.
And since I am working with the Delta format, I cannot use the hack that @rpmonteiro suggested. Currently the paragraphs are simply represented as \n within the format. So I think we need to make up some design decisions on how to reflect and differentiate between simple line-breaks a.k.a. newlines and a new paragraph.
@BastiOfBerlin I agree with you. By design newline is used to adjust spacing, for example a newline is added after headings to leave a space before the next paragraph. Adjusting the spacing should be the job of styles IMO...
👍 Using this on a site which allows the users to enter poems, the lack of soft enter is crucial for such cases.
Google docs inserts a \u000b
character rather than a \n
- char code 11 instead of 13.
Maybe this could done using custom Break
blot
let Parchment = Quill.import('parchment');
let Break = Quill.import('blots/break');
let Embed = Quill.import('blots/embed');
Break.prototype.insertInto = function(parent, ref) {
Embed.prototype.insertInto.call(this, parent, ref)
};
Break.prototype.length= function() {
return 1;
}
Break.prototype.value= function() {
return '\n';
}
Quill.register(Break)
and bindings like this
handleEnter: {
key: 13,
handler: function (range, context) {
if (range.length > 0) {
this.quill.scroll.deleteAt(range.index, range.length); // So we do not trigger text-change
}
let lineFormats = Object.keys(context.format).reduce(function(lineFormats, format) {
if (Parchment.query(format, Parchment.Scope.BLOCK) && !Array.isArray(context.format[format])) {
lineFormats[format] = context.format[format];
}
return lineFormats;
}, {});
var previousChar = this.quill.getText(range.index - 1, 1);
// Earlier scroll.deleteAt might have messed up our selection,
// so insertText's built in selection preservation is not reliable
this.quill.insertText(range.index, '\n', lineFormats, Quill.sources.USER);
if (previousChar == '' || previousChar == '\n') {
this.quill.setSelection(range.index + 2, Quill.sources.SILENT);
} else {
this.quill.setSelection(range.index + 1, Quill.sources.SILENT);
}
this.quill.selection.scrollIntoView();
Object.keys(context.format).forEach((name) => {
if (lineFormats[name] != null) return;
if (Array.isArray(context.format[name])) return;
if (name === 'link') return;
this.quill.format(name, context.format[name], Quill.sources.USER);
});
}
},
linebreak: {
key: 13,
shiftKey: true,
handler: function (range, context) {
var nextChar = this.quill.getText(range.index + 1, 1)
var ee = this.quill.insertEmbed(range.index, 'break', true, 'user');
if (nextChar.length == 0) {
// second line break inserts only at the end of parent element
var ee = this.quill.insertEmbed(range.index, 'break', true, 'user');
}
this.quill.setSelection(range.index + 1, Quill.sources.SILENT);
}
}
@farnabaz Thank you very much for sharing this. I'm now working on it and fixing some issues that occur when quill first loads the HTML (as I'm saving it in the DB).
I'll post my findings here once I get this working properly!
I got it working great.
The code @farnabaz posted worked great, just had some minor tweaks I had to do specific to my use case.
For me, using Quill with React, I was before injecting the HTML into quill's container. But now that we have our fancy linebreaks, the solution was to instead send the HTML via the dangerouslyPasteHTML method of the clipboard module. With that, you can then write a little matcher for our new <br>
friend
And this concludes dozens and dozens of hours for me of doing RegExp work that can now be replaced by a handful of lines of code.
Thank you very much once again farnabaz, you saved my week! 👍 🍺
@rpmonteiro I'm glad to hear it 👍 I updated DEMO with your custom matcher
Just FYI, I really need this to format poems correctly, where there are often line breaks that are not paragraph breaks. Reading through this, there are obviously many use cases for this feature (which is also present in Word, Google Docs), so I hope the Quill team steps up and supports this. I will have to try one of the work-arounds, but if they don't work I'm going to have to drop Quill - this really is a deal beaker.
hy @ollyfg this one works fine for me: http://codepen.io/farnabaz/pen/VpdaGW . but as you said: should definitely be possible without a workaround ;)
@nhunzaker and I had a couple issues with the above codepen solutions:
<p>
tag to insert a newline.We've forked and updated the codepen with our solution here: http://codepen.io/mackermedia/pen/gmNwZP
Notable additions:
var length = quill.getLength()
var text = quill.getText(length - 2, 2)
// Remove extraneous new lines if (text === '\n\n') { quill.deleteText(quill.getLength() - 2, 2) }
2. handling the double shift+enter bug:
keyboard: { bindings: { linebreak: { key: 13, shiftKey: true, handler: (range) => { let currentLeaf = this.editor.getLeaf(range.index)[0] let nextLeaf = this.editor.getLeaf(range.index + 1)[0]
this.editor.insertEmbed(range.index, 'break', true, 'user')
// Insert a second break if:
// At the end of the editor, OR next leaf has a different parent (<p>)
if (nextLeaf === null || (currentLeaf.parent !== nextLeaf.parent)) {
this.editor.insertEmbed(range.index, 'break', true, 'user')
}
// Now that we've inserted a line break, move the cursor forward
this.editor.setSelection(range.index + 1, Quill.sources.SILENT)
}
}
} }
We're using Quill as an email composer, trying to replicate Gmail as much as possible. Gmail's default line break is the single br
, which IMO is much more flexible. If you need a new paragraph, tap twice.
Is it possible to optionally convert Quill's p
default to the br
?
@jhchen, what @RobAley said. All word processors support shift+Enter for BR:s, but if your copy of Word doesn't have margins on its P:s configured, you won't see it.
If you were to configure margins on your Word document, you'd see what you see on the web.
In MS Word terms, it's called a soft carriage return (or just Soft Return), see here: https://www.computerhope.com/jargon/s/softretu.htm
I've sure noticed i've wrote a duplicate - issue #1511. I'll just mention that implementing this will solve the issue and adding a break line within a list item.
@farnabaz, your code works well but I have an issue when setting content to the editor.
I use this code to set the editor content :
document.querySelector(".ql-editor").innerHTML = content
but the <br>
tags are removed in the editor.
Is it the right way to set HTML content to Quill?
I believe supporting shift + enter should be a a priority. If you want to use div, that's fine, but
<div>text</div><div>text</div>
should be output with an enter, and<div>text<br>text</div>
with shift + enter.