Is there a cross-browser solution for getSelection()? - javascript

I need to make a comment mechanism in which user highlights a piece of text, clicks "comment this", and then does something. The Javascript code has to know not only the selected text (this is trivial), but also the anchorOffset, to know exactly from which to which character the text was selected.
I've found a cross-browser solution that gives you the text. Is there a reliable way to get a selection object as it's described in DOM specs?

You could try IERange, which creates a selection-like object in IE and adds a getSelection() method to window. I don't think it's perfect but it's about the best standalone Range/selection library there is that I've seen.
Update
I've been working on a Range/selection library called Rangy that goes beyond what IERange provides. There's an early release available at http://code.google.com/p/rangy.

Related

Iframes and Deprecated methods in javascript

I am building a classic post related cms on LAMP stack, as a project to show at future interviews and land a job potentially. I want to build a rich text editor. After some research both in r/javascript and stack overflow I drew some conclusions.
Don't use "contentEditable=true" flag because according to one of
CKEditor's devs https://stackoverflow.com/a/11479435/10245890 is not optimal
The general consensus is to use iframe because of the isolation it
provides.
Yes I know I will not build the next CKEditor on my own, it takes
years of far more experienced people than me, I just want to learn
about the Javascript APIs.
Generally I want to use vanilla version of the languages in the
stack in order to get a better understanding of them.
The 'easy' way out to get a simple rich text editor going is to use execCommand but it is obselete. What I came up with goes like this:
function formatBold(){
var selection = document.getSelection().toString();
var originalString = document.getElementById("post-body-editor").innerHTML;
document.getElementById("post-body-editor").focus();
document.getElementById("post-body-editor").innerHTML = originalString.replace(selection, '<b>'+ selection +'</b>');
return;
}
document.addEventListener('keydown', function(event) {
if(event.ctrlKey && event.key === 'b'){
formatBold();
return;
}
return;
});
The function is called with a HTML button or key press. I saw in MDN that there is a method to implement insert Link, format a text with bold etc. Question is. I see some, if not many ,methods flagged as deprecated but they seem to be working. Should I use them or make it work on my own as shown above? I realize its not the most elegant solution but I believe it works fine for my level. Also any articles or other reading material is appreciated ofc.
EDIT:Formatting
If the question is just about using deprecated/obsolete features, the answer is: don't use. Though, I doubt execCommand would never really be removed from the browsers, that would break tons of existing pages ... If you really want to create a WYSIWYG editor, you've to dive deep in the world of DOM. In that world use of innerHTML is exceptional, you would work with Nodes and ShadowRoot etc.
Answered by Teemu in comment above.

JavaScript Document Exec Command

Perhaps you have heard about JavaScript Document's execCommand() function, which we often use to make rich text editors. It had a bad reputation before as Internet Explorer worked differently with it. Here are my questions.
Today, do all the elements of execCommand work on all browsers? Like save as, bold, italic, etc...?
If you want to make a rich text editor, is execCommand the appropriate choice today?
Can you give me a website where I can find all the elements this function offers? Because I visited some, but they are just showing bold, italic and others. I want the complete updated lists.
Quirksmode has an (oldish) compatibility table of document.execCommand.
I think the best would be to mix execCommand with selection/range & DOM manipulation for a rich-text editor.
Edit:
window.getSelection()
document.selection
Related questions:
how to modify the document selection in javascript?
JavaScript selection/range framework
I had a similar requirement and came across a rich source of such commands. This list is exhaustive, IMO, and also provides compatibility with various browsers.
http://help.dottoro.com/larpvnhw.php
I've not been able to make it work with Chrome at all, while some work with IE and all the commands run smoothly with Firefox.
Hope this helps.

Is there something better than document.execCommand?

When implementing a web-based rich-text editor, I read that document.execCommand is useful for performing operations on an HTML document (like making a selection bold). However, I need something a bit better. Specifically, I need to know exactly what text is added or removed from the innerHTML, and in what location (as an offset into the entire document's HTML representation).
I considered using the built in document.execCommand along side DOM4's mutation observer, but execCommand doesn't seem up to the task:
I don't see a way to "un-bold" a selection
the generated html seems to vary from browser to browser. (I'd like < span > tags not < b >, but consistency is more important)
and there's no information on what it does to handle redundantly nested/adjacent < span > tags.
Also, using mutation observer seems a bit overkill based on my needs.
My motivation: I'm trying to transmit document changes to the server periodically without re-transmitting the whole document. I'm sending the data as a collection of insertions and deletions upon the HTML representation. If someone knows a way to get this functionality out of, say, CKEditor (so I don't have to start from scratch), then I would love you forever.
Note: Performing a text diff is not an option, due to its poor performance on very large documents.
Otherwise, I'm not exactly afraid of trying to write something that does this. The methods provided by the DOM's range object would handle a lot of the heavy lifting. I'd also appreciate advice regarding this possibility.
There is one alternative to using execCommand - implementing the whole interaction of an editor including blinking of a cursor. And it has been done. Google does it in docs, but there's something free and open-source too. Cloud9 IDE http://c9.io has an implementation.
AFAIK, github uses that editor for some time now. And you surely can do anything under that, because there's no native code involved - like in execCommand
The repo is here: https://github.com/ajaxorg/cloud9 (it contains the whole IDE, you will need to find the code for the editor. )
Also - dom mutation events are deprecated. If you can drop support for old browsers, try mutation observer. If not - try to avoid detecting DOM changes at all and intercept changes in the editor's implementation. It might be the way to go for the new browsers too.
There is Trix rich text editor, from their description it looks like avoiding inconsistent execCommand is the whole point of the project.
It seems the new standard will be Input Events Level 2. To me it looks like it will be a revised improved version of execCommand.

Filter selection on cut/copy with javascript?

On one of my sites, I used ­ liberally to provide better hyphenation in the web browser. Unfortunately, they get corrupted by copying or cutting and pasting, so when people copy from my website, the ar-tic-les ap-pear with ex-tra hy-phens which are really annoying. I exaggerated it a bit here, but you get the idea.
I'd love a way to filter the selection on copy - basically an opportunity to remove the ­'s before they get to the clipboard. I suspect this isn't possible, based on what I've read/researched, but thought I'd ask the collective wisdom here, in case I've missed something.
A pseudocode example of what would be beautiful:
element.oncopy = function (ev) {
ev.selection.replace(/­/g, '');
return true; // or ev, I suppose
}
Have a look at this article about the oncopy event. I think it is exactly what you need: http://help.dottoro.com/ljwexqxl.php.
Example #2 on the following page explains how to use the clipboard in a cross-browser friendly way (since only IE has access to the clipboardData object used in the first article): http://help.dottoro.com/ljxundda.php
That page also mentions that there are some cases where security restrictions may prevent the cross-browser method from working, which is why some sites use Flash to manipulate the clipboard. Here's an article which discusses that method, in case it sounds like what you want: http://www.jeffothy.com/weblog/clipboard-copy/
EDIT
Have a look at Hyphenator.js. It is a JavaScript method of hyphenating text intelligently on the client side. Quickly playing around with the demo (which can be found here), it appears to leave the hyphens out of copied text. It might be a pain to change your content to use this instead of ­, but it looks like it will achieve all of your goals.

reliable, cross-browser way to get selection's boundaries?

I need to make the user to be able to select some text, click a button and make the server remember the selection for the next time.
I've extensively read through SO's questions and answers, tried some libraries, but without luck: haven't found a reliable tool yet.
It isn't important how the selection's boundaries are identified: it could be "nth textNode, mth char", or "nth char of text", or "nth char of html", or whatever, as long as it allows the server to identify the points in the document; what really matter is that, selecting the same words of the same document must give the same result on chrome, safari, IE, firefox.
EDIT: I don't need it to work everywhere on the internet: just on one site, where the document's structure is fixed and only the content of a single div (or the like) will change.
Try my Rangy library and its Serializer module. I'm not convinced it's exactly what you want because you mentioned the server remembering the selection, whereas my suggestion uses cookies, and the serialized selection will vary between browsers. However, it does do as you described in the first paragraph.
On the other hand, it's pretty much impossible to write something that will work for all browsers and all pages, since browsers interpret HTML differently and build different DOMs.

Categories

Resources