how to mimic tinymce textarea behaviour with rendered html [duplicate] - javascript

I want to understand how tinymce functions.
the rich text editor contains an html document within an iframe. how are the nested DOM elements inside editable, In other word how am I able to type inside a <div> or a <p> layer when there is no textarea or input field involved (at least I dont see any)?
are the elements converted to input fields when they are active?
edit: If your going to vote down the question, please state why.

In tinyMCE's case (and most other editors) it's an <iframe> (as to not inherit styling from the parent page, among other reasons), but the magic is the contentEditable attribute being set to true.
You can read more detail in the working draft of HTML5 here.
You can test a very simplified demo here, the editors do much more of course with their toolbars, a backing <textarea> to store the markup for server-submission, etc...but your question seems to be how are you editing the elements, the core of that is contenteditable.

Related

What's the best practice for making an optionally editable text field in react?

So I am trying to make an interaction which is similar to the file browser in VSCode. I display a list of items, and click on an item to select it. I want to then be able to press enter when an item is selected to make that item editable.
My first attempt was to use the contentEditable property, as it seemed the easy way to turn editing on and off on my div:
...
render(
<div
contentEditable={this.state.isEditable}>
{this.state.text}
</div>
)
But when I use this method, I get this warning:
[Error] Warning: A component is contentEditable and contains children managed by React. It is now your responsibility to guarantee that none of those nodes are unexpectedly modified or duplicated. This is probably not intentional.
If I understand correctly, contentEditable is breaking the convention of React, and this may cause issues if I use this method.
As I have read more about contentEditable in general, I have also seen that there are some issues with the HTML generated inside being inconsistent across different browsers.
So my question is, what would be the standard/best practice to achieve something like this where I want to swap between a display-only element and an input element? Should I use an input tag instead and disable it instead of enabling it?
You can consider using input's native attributes, readonly/disabled, depends on your use-case, for example:
<input readOnly={!this.state.isEditable}/>
contenteditable will give you HTML, but you're not using this.state.text as HTML (just text), and as you've noted the HTML varies from browser to browser. I'd swap a styled input for the div:
return this.state.isEditable
? <input className="styling-class" type="text" value={this.state.text} />
: <div>{this.state.text}</div>
;

Chrome extension on text changed event on text field, then replace text

I'm working on a Chrome Extension which I want to replace certain characters in a specific text field on one specific website. It is basically to change emoticon text (like ":-D") into the proper emoji's, such as "😄". I tried a few things I found online (I'm not very good with JS):
- A MutationObserver and then look for all text fields with a certain name, then replace all emoticons by hand. Didn't really do the job properly and also kept firing up the print window for some reason
- Event listener added with event 'keyup' but it doesn't seem to fire up.
Hope you guys know a good solution!
This question does not give anywhere near enough information to answer. Are you using the program for input fields on the website? What solutions have you tried? Where is the code? Essentially, you are asking us to write the entire program for you. This forum is meant for programming help, NOT doing the entire program for you. You need to fix the question to be more specific.
If you just want to replace text elements, you would have to use the select elements by tag name to select all text elements on the page and then search through each of these for the sets of emoticons. Once finding these, you would have to change the elements inner html to fit the emoticon from UTF-8.

Tumblr's "data-ghostwriter"

On the sign up page for Tumblr, it has three boxes, one for password, one for email, and one for your url. What interests me is the URL bit. Whatever you type is followed by .tumblr.com. You can't put the cursor after it or highlight it or delete it. How does it do that?
I check the source and it has the attribute data-ghostwriter=".tumblr.com". I didn't recognize it, so I googled it, and still nothing. I'm assuming it's a custom attribute, even though that seems like something that HTML would have rules against, but I can't find anything about it in the linked javascript files.
So, two questions. How do they do it, and can you use custom HTML attributes?
edit: So html5 allows data- custom attributes and using jsbeautifier, the code their inputs is:
http://pastebin.com/b5Yd51Mi
How does this work though, I'm still a bit confused.
The "data-" attributes are explicitly allowed in HTML5. Anything can follow "data-" (well, anything within bounds of some reasonable syntactic rules for HTML attribute names). Generally you'd access the values with the "getAttribute()" method on HTML element nodes.
Now, while all that's true, it's a little fishy that tumblr is serving up those pages with an XHTML doctype :-)
This older SO question describes how the effect is done. They position a translucent box right over the input field. When you start typing, they make the box visible and fill it with two <span> elements: the first, with a copy of what you've typed, styled to be dark like text in the real input field, and the second, with the static ".tumblr.com" suffix, and styled to be light grey and "ghosty".

What are the cons of using a contentEditable div rather than a textarea?

Would I be shooting myself in the foot by using a div with attribute contentEditable="true" as a text field rather than a textarea?
It would work fine, but it'd be a little bit more difficult than a form, simply because you're going to have to wire up your own logic to make the button's click event track down the correct div, get its content, and then perform the submission. The advantage of a textarea is that the browser takes care of all that for you.
It's not the same thing. First semantically, the purpose of a textarea is to write/edit plain text whereas with contentEditable you can edit list for instance (see: htmldemo)
Second the behavior is also different. For example, in chrome when you test the link below and that you delete all the content you loose the focus (the div element disappear) which is not the expected behavior, or if it is it's idiot.
The Gmail's mail edit box is also a div with contenteditable="true". The major benefit is it has auto-adjust height as user input text/content. Also it supports rich text inside. You can mimic the Textarea by setting a max height if need.
On the other hand if you want auto height in Textarea, you might have to use js to bind some listener to the oninput hook.
In divs with contenteditable="true" the content can be html formatted, e.g. text with different colors.
See also https://stackoverflow.com/a/40898337/11769765.

Javascript rich text editor that allows locking regions

I'm looking for a rich text editor that allows for locking regions so that they can't be edited by the user. These locked regions would contain markup, not just plain text. TinyMCE has a plugin to support this but it is quite buggy.
Rather than having the RTE contain the content you don't want edited, why not just put multiple editors around only the areas you want users to edit?
The problem I see with doing it the other way is that you could have individual nodes within the editable text with contenteditable off, but those nodes could still be part of a larger edit (e.g., they could be deleted). To truly prevent them being edited you'd have to check the current selection whenever it changed and disable all user actions until the selection didn't include the locked content. Even if you did that, it would be tricky to make sure that a user didn't add content in a place they weren't supposed to (before the first node, say, assuming the first node was locked).

Categories