Closed xiaochengh closed 1 year ago
Good point. What do you propose concretely in terms of standardizing? Would a mentioning among the types of available contenteditable types [1] together with some prose about how it "only allows for the input of plaintext and ignores any formatting commands" be enough to start with, or should we also define some more of the behavior, possible standardize differences between existign implementations?
[1] http://w3c.github.io/editing/contentEditable.html#editing-states
A brief mentioning seems good enough. I don't see any need to make it lengthy.
Btw, it should also ignore any format in pasted/dropped text.
contentEdtiable=plaintext-only is used a fair bit, so I think the only choice available is to standardize it. We had previously discussed this with other browser vendors. IIRC, there was general support, but there were some open questions that never ended up getting resolved.
<br>, <div>, <p>
like contentEditable? Should it depend on your white-space value? Browsers are pretty inconsistent here with regular contentEditable.In either case, I think speccing something and having unresolved notes in the spec for the above three issues is better than having nothing.
+1.
Just ran into this (thanks for teaching me that plaintext-only
exists!), because I'm doing a <style contenteditable style="display:block">
to make some "editable CSS" for a talk, and it was inserting markup into the <style>
and messing things up when I pressed Enter. Our current behavior for plaintext-only
is to insert a \n
, which is exactly what I needed, yay!
I tested this on safari, and it seems that they insert <br>
on enter instead of \n
.
I think this definitely needs to be standardized, and it seems like it's in the process, but it seems like its not a high priority and thats a shame, since content editors are the core of the web, and every single one of them could be improved by this draft:
https://w3c.github.io/editing/contentEditable.html
@samuelgozi seems like the link is broken ;/
@edgarascom I can only find it by using Internet archive. https://web.archive.org/web/20191003035115/https://w3c.github.io/editing/contentEditable.html
But I was specifically referring to the contentEditable
states. In the linked draft there are 4 new states: events
, caret
, typing
and plaintext-only
.
Since I'm currently working on a rich text editor I'll explain a little bit what are the pain points I'm encountering.
When using contentEditable=true
, each browser has the freedom of choosing how to render some things that are not specified in the specification. For example, there are different elements in different browsers to display bold text, different fonts, new lines, etc. And also there seem to be differences in what each browser supports.
Because of this, we, the developers can't rely on the representation of the text/document of the DOM. Accounting for all of the differences is way too hard and results in too much boilerplate code. And on the web, every byte counts, more so when its JS because it needs to be parsed and executed. And text editors do a lot of stuff behind the scenes, so making a rich text editor work fast(60fps) on mobile devices is very hard when taking all of this into account.
There are two kinds of rich text editors on the web right now, the ones that gave up, and just try to parse the DOM representation into something good enough, and the ones that try to build all the logic from zero, and use the DOM just to render the output.
I choose the second path because I wanted to control exactly how things are rendered. And I want the source of truth to be controlled by my app.
I thought about rendering using canvas. But then you need to create a caret that will work on all devices and look and feel native, and also create copy/paste functionality, and edit menus that will look native, and on mobile it's practically impossible.
Your only option is to use contentEditable
because there is no other text input that allows you to manipulate how the text looks, and insert other elements/styles while taking care of caret/commands/menus.
A good solution would be to make an input that takes care of text editing part of things, but let us decide how to render everything. So all events are passed to us, and there is no default functionality at all. So if the user hits the "bold" button on the native menu, an event will be dispatched, but nothing will happen. the same should be true for character insertions, deletions, pasting etc.
Another missing feature is to tell the OS which actions the editor supports. For example on iPhone, if you have text selected inside a content editable "input", then the OS will show a menu with "bold", "italic", "undo", "copy" etc. But what if the editor doesn't support "bold"? we should have a way of specifying that too.
I think that the draft I linked to offers good solutions for some of these problems. And it should be higher priority. I actually think that it needs to be the highest priority. Rich content is literally the essence of the web, and its time to fix how its created.
Hey,
yes so 3 of the states in that draft were made for editors as the one you describe @samuelgozi . The reason we had 3 and not just 1 was that IME and some other features like mobile browsing meant that it was difficult for us to choose just one of those states and so we kept all three for now. The last one, plaintext-only
, could possibly also be used as part of a general editor, but it was really invented by Safari/Chrome to be used by their browser native tools for web developers like the "edit as HTML" feature. So if I recall correctly we left that one alone for the time being as it's being might be dictated by the needs of the browser-specific development consoles and cannot be adjusted to work well in other contexts.
@johanneswilm Thanks for replying and for the clarification. Where can I find the current state of these proposals?
@johanneswilm I also would use plaintext-only no only for a code, but also because I don't want formatted text/pictures to be pasted into the area. Is there another easy way to prevent pasting any mismatching text style?
@samuelgozi We are now part of a new Working Group which no longer allows us to have documents here that do not yet have implementation insurances from browser makers in our main repository. We are now only allowed to have these sit in pull requests. For this reason, everything was removed in this pull request: https://github.com/w3c/contentEditable/commit/ae454fc84c784cd507a1e2f9a226d01f7ac519d4
The document before that PR still represents the current state of the discussion though, so if we can get implementation commitments, we may put them back some time in the future.
The existence of plaintext-only has been moved to the HTML spec. It does not specify anything about its behavior though.
@edgarascom What you describe sounds like something we wanted to enable with input events in combination with really any of the contenteditable states. Unfortunately also those were only half-implemented. As I said, I am not sure if we can get browser makers to agree on specific behavior for plaintext-only, because that would then mean that they would also need to change how their development tools work. But maybe it is possible.
In the meantime, what you can do given the current state of things, if you need to write an editor right now, is to use a contenteditable element like this:
Use a schema system and keep a copy of the document that is being edited in JavaScript.
Translate that document to HTML and put that HTML as the innerHTML of the contenteditable element.
With every user initated change to the contents of the contenteditable element, translate the current HTML of that element back to the format that you have the document stored in Javascript in.
Diff the old and the new document, find out what has changed, store that change.
Translate the new document back to HTML, see if there is any difference to the innerHTML of the contenteditable element, and if that is the case diff and patch the contenteditable element.
Very roughly described, that should get you around all the various bugs and inconsistencies in browsers and it should work even when browsers change. However, I hope you are not planning on writing such an editor as a one-person hobby project during a week or two, as it has proven it takes years to get it right. For most use-cases it is probably currently recommendable to use one of the existing JavaScript libraries and not try to write a contenteditable editor from scratch.
@johanneswilm Thank you very much for clearing that up.
@johanneswilm Thank you for the detailed explanation!
That's what I was afraid of, to aim for something that will be very hard to finish for me alone, taking into account my intermediate coding skills. But what I am trying to code is quite simple, that's the reason I though I could use the contenteditable. It's a simple app as an internal strategic design tool. I want to be able to write sentences in a table cells. All the sentences from cells then gets mirrored and joined to a narrative story below using s. And I want to be able to edit text in both places. Also later I want to add drag and drop functionality to reorder sentences if needed.
So far it works quite well, but the problem was the copy/paste(able) rich text. Which I fixed with plaintext-only for now (but yeah, it has a super limited support). I will have to try your described method. Also, another problem is, if I edit a sentence in a and delete all of it, the cursor jumps to top above all other sentences. I will have to do something with that, give a min-width somehow... But I need to keep it as an inline element.
By the way what do you mean by "schema system"?
By the way what do you mean by "schema system"?
Basically just a register of how to translate the HTML into the format you store it in and vice versa. CKEditor 5 for example has this [1]. ProseMirror has this [2].
[1] https://ckeditor.com/docs/ckeditor5/latest/framework/guides/deep-dive/schema.html
This was added in https://github.com/w3c/editing/pull/407
This is a blocking issue of removing webkit-user-modify from Blink.
There seems to be an important use case of contenteditable=plaintext-only in Chrome DevTools:
In the "Elements" panel, we can modify a tag (tag name, style, class and other attributes) by doubleclicking at the tag, which turns certain part of the tag plaintext editable (as shown by the attachment ). When we finish editing, we can click outside or press Esc to switch the editable part back to uneditable.
DevTools currently implements this functionality by making certain element switch between "-webkit-user-modify: read-only" and "-webkit-user-modify: read-write-plaintext-only". There doesn't seem to be an easy way to convert the implementation to follow the standards, as the standards do not provide any means for plaintext editing other than and
If contenteditable=plaintext-only can be standardized, then the above use case can be well supported.