How to add <span> within CodeMirror editor? - javascript

No jQuery please!
I'd like to add a styled span within the body of a CodeMirror editor. This is for the purposes of a mail merge like application where you can for instance do: (From Zapier)
I believe this may be possible using a CodeMirror Widget but I'm lost as to what direction to go in. I found an example of something similar (albeit far more complicated) here.
I also tried tagify which is extremely similar to what I'm after but doesn't have multi-line inputs, which is a requirement.
All I need is the ability to add and remove (via backspace with the caret just behind the tag) these spans but there doesn't appear to be a simple solution.
Also if there is a convenient library or some other direction I can go in not involving CodeMirror that'd also be fine.

CodeMirror is actually well suited for this.
First insert some placeholder into the document, such as [[tag]].
var lineNumber = 0;
var charNumber = 0;
var snippet = "[[tag]]"
editor.doc.replaceRange(snippet, {line:lineNumber, from: charNumber});
Then create your DOM element, I recommend a span.
var htmlNode = document.createElement("span");
//Style and add what you like to the span
Then use doc.markText to replace it with that node.
editor.doc.markText({line: lineNumber,ch: charNumber}, {line: lineNumber,ch: charNumber + snippet.length}, {
replacedWith: htmlNode
})

Related

how to retrieve a line of text from ACE editor?

I integrated ACE editor in my site. I want to retrieve the text in a certain line. I've searched and found This and This. But unfortunately, I can't understand those, as I'm a newbie to the subject. Can anyone give an example for it ?
I got the lines to an array using the following code.
var line = document.getElementsByClassName("ace_line");
Are there any methods like
line[count].getValue
Which can return the string of the text in that line ?
You need to call
line0 = editor.session.getLine(0);
using getElementsByClassName("ace_line") or similar won't work since
ace creates DOM elements only for visible lines.
text content of the DOM element is different from the text in document since tabs and some other characters are replaced by spaces.
line[count] already returns the DOM element of that line. So all you have to do is to extract the plain text from that element. if you are using jQuery you could do:
To get the text of the first line for example (line[0])
var lineText = line[0].text();
If you are not using jQuery and want to do that in javascipt:
var lineText = line[0].innerHTML.replace(/<[^>]*>/g, "");

Dynamic syntax highlighting in Javascript

I'm creating javascript editor with syntax highlighter based on contentEditable html element. I wrote a class that manages the editor and works like this:
function Editor() {
this.setContent = function(content) {
var pos = //Computes cursor position in current dom scope (number of characters from begining)
editor.innerHTML = content;
/* Here I set the cursor back, again, it is complicated and slow process*/
}
this.highlight = function() {
this.setContent(someHighlighter.highlight(this.getTextContent())); //Slow - highlights whole innerText of editor DOM and sets it as innerHTML
}
}
The code above is just concept. But even so, you can see that it is not effective and you may understand I'm looking for beter alternative.
On the other side I dont want to spend the rest of my life doing this editor.
Is there some javascript syntax highlighter that works with DOM instead of pure text?
Is there some better way how to change element content without loosing cursor position?

Color coding within contentEditable?

I've been trying to breakdown how WYSIWYG editors work, but am having problems figuring it out (and do not need even 5% of that versatility).
My own problem is simple.
Insides a contentEditable div, I have a bunch of text. I want to color code any text that matches a simple pattern. So I may have this text:
"this is is a text we [can ignore] this earlier one, but anything that [ref=xxxxxx|aaa|bnbb] that fits the ref has to be color coded."
I want any mention that follows the pattern of [ref=<whatever>] made slightly smaller/colored.
Any idea on how to do that?
One way is using the fabulous http://alexgorbatchev.com/SyntaxHighlighter/ plugin and writing a custom brush for your syntax, which shouldn't be too difficult since your syntax coloring requirements are rather simple.
If you add a keyup event listener to your contenteditable, you can perform your regex replacements there to add $1 in the contenteditable's innerHTML.
Doing so will reset the caret position, but you can preserve it using Rangy.
function highlight(){
var selection = rangy.saveSelection();
contenteditable.innerHTML = contenteditable.innerHTML.replace(/(\[ref=[^\]]*\])([^<])/g, '<span class="ref">$1</span>$2');
rangy.restoreSelection(selection);
}
The regex may not be perfect, but if not, it should get you started.

Apply span to selected text in javascript

I would to apply a span class to selected text on browser window in Javascript (like an highlight feature).
I've tried with
function replaceSelectedTextWithHTMLString(newstring) {
var range = window.getSelection().getRangeAt(0);
range.deleteContents();
range.innerHTML = newstring;
}
but it does not work. If i try to insert as newstring= "< span = "myspan" > text < / span >" I can't look anything and the 'text' does not appear. Seems it does not like the HTML code. How can I solve it?
How easy this is depends on what exactly you need to achieve. If all you need is basic highlighting using a background colour, your best bet is document.execCommand(). See the following for code to do this: Change CSS of selected text using Javascript
If you need to apply more styling than document.execCommand() can provide (there are also various other formatting commands for things like bold and italic, but the markup this produces varies between browsers and isn't always CSS based), it's much trickier: in general, you need to surround every text node within the selection in a span with the desired class. I would suggest using Rangy and its CSS class applier module to do this in a cross-browser way. Disclaimer: this is a plug for my own library.

Highlight/Format textareas

I'm looking to implement a live diff inside a webpage that preserves whitespace.
I've done something similar in the past using a combination of TinyMCE and JQuery in IE6 (required for that project) but it didn't preserve whitespace. (It wasn't supposed to, but I didn't add anything to make it do that, it just did). TinyMCE wasn't ideal as I was dealing with plain text, and TinyMCE is a WYSIWYG style editor supporting rich text. Most of it's functionality wasn't being used and is/was hard to disable.
I've looked through most of the projects listed at http://en.wikipedia.org/wiki/Comparison_of_JavaScript-based_source_code_editors. EditArea seemed promising, but I cannot seem to determine which elements are actually being used to display the text.
$('#frame_modified').contents().find('#editor').text()
displays a lot of the line information (123456789101112 and so on) along with the line the cursor is under, but not the rest. I haven't figured out how to apply/modify the styles associated with that.
Lets say the user types foo, I'd like to wrap it so it displays as <span class="bar">foo</span> on the fly. What's the simplest solution to go about getting this sort of functionality?
IE8 is the target browser for this project.
You could do some action on the onKeyDown event (in one of your own plugins). If your cursor is already in a new span add the character just typed in else create a new span with the character entered. Something like this:
ed.onKeyDown.add(function(ed,evt){
char = getChar(evt.keyCode); // your function to get the character to be inserted depending on evt.keyCode
// if span already exists
node = ed.selection.getNode();
if (node.nodeName.toLowerCase() == 'span' && node.className == 'myclass'){
node.innerHTML += char;
}
// new span
else {
doc = ed.getDoc();
new_element = doc.createElement('span');
new_element.className = "myclass";
new_element.innerHTML = char;
tinymce.activeEditor.mceInsertContent(new_element);
}
})

Categories

Resources