CodeMirror: Particular lines readonly - javascript

Can I set a particular number of lines (sucessive or not) to read-only mode?
For example: I have a document where I don't want the contents of some sections to be changed (like in Word, where you can set Header and Footer sections and you can lock them).
Anyone know if CodeMirror supports that feature?
Thanks in advance!

There is also markText with the readOnly option, which might map more directly to your use case. See http://codemirror.net/doc/manual.html#markText

With codemirror version 3 support for on and beforeChange was added; simply catching the change before it happens and canceling should do the trick:
// the line numbers to be "readonly"
var readOnlyLines = [0,1,2,3];
// create the CodeMirror instance
var editor = CodeMirror.fromTextArea(document.getElementById('input'));
// listen for the beforeChange event, test the changed line number, and cancel
editor.on('beforeChange',function(cm,change) {
if ( ~readOnlyLines.indexOf(change.from.line) ) {
change.cancel();
}
});

For CodeMirror6
I just released codemirror-readonly-ranges extension that easy allow to work with read-only ranges.
For anyone who is interested on the solution:
package: https://www.npmjs.com/package/codemirror-readonly-ranges
full documentation: https://andrebnassis.github.io/codemirror-readonly-ranges

Related

Ace Editor: Disable shadowed line where the cursor is

I am using Ace editor and I want to disable shadowed line where the cursor is.
Example
I have tried changing themes availables in Ace Mode Creator but all have this line shadowed.
Thanks!
This is a standard setting that doesn't require changing the theme
// e = active editor
e.setHighlightActiveLine(boolean)
Most themes have it set active by default. It should be a standard configurable setting to enable or disable it.
Hi I found the boolean attribute from the Ace demo here (https://ace.c9.io/build/kitchen-sink.html).
Is called Highlight Active Line
I hope it works for you :)
You're looking for:
i.e in chrome theme (https://ace.c9.io/lib/ace/theme/chrome.css) its
.ace-chrome .ace_marker-layer .ace_active-line {
background: none
}
in vuejs just add readonly="true" and I think it's

Listen to specific changes on contenteditable?

Warning: not duplicate with existing questions, read through
I know I can have an event listen on changes on an contenteditable element.
What I would like is to be able to know what the changes are.
For example:
inserted "This is a sentence." at position X.
deleted from position X to Y.
formatted from X to Y with <strong>
Is that possible? (other than by doing a diff I mean)
The reason for this is to make a WYSIWYG editor of other languages than HTML, for example Markdown.
So I'd like to apply the changes to the Markdown source (instead of having to go from HTML to Markdown).
You may be able to do something with MutationObservers (falling back to DOM Mutation events in older browsers, although IE <= 8 supports neither) but I suspect it will still be hard work to achieve what you want.
Here's a simple example using MutationObservers:
http://jsfiddle.net/timdown/4n2Gz/
Sorry, but there is no way to find out what the changes are without doing a diff between the original content and the modified one when changes occur.
Are you looking for this
var strong=document.createElement("strong");
var range=window.getSelection().toString().getRangeAt(0);
range.surroundContents(strong);
this was for third part
You just need to select what you want to surround using real User interaction.
If you wanna do it dynamically
var range=document.createRange();
range.setStart(parentNode[textNode],index to start[X])
range.setEnd(parentNode[textNode],index to end[Y])
range.surroundContents(strong);
For 2nd Part
range.deleteContents()
1st part can be done by using simple iteration
var textnode=// node of the Element you are working with
textnode.splitText(offset)
offset- position about which text node splitting takes place[here==X]
Two child Nodes have been created of the parent editable Element
Now use simple insertBefore() on parent editable Element Node.
hope you will find it useful
The API you're looking for does not exist, as DOM nodes do not store their previous states.
The data / events you're wishing to get back are not native implementations in any browser Ive come across, and I struggle to think of a datatype that would be able to generically handle all those cases. perhaps something like this:
function getChanges() {
/* do stuff here to analyse changes */
var change = {
changeType : 'contentAdded',
changeStart : 50, /* beginning character */
changeContent : 'This is a sentence'
}
return change;
}
Since you're trying to get custom events / data, you're probably going to need a custom module or micro-library. Either way, to look at the changes of something, you need somehow be aware of what has changed, which can only be done by comparing what it was to what it is now.

Detect if browser supports contentEditable?

There's this question, but the solution posted is browser sniffing, which I'm trying to avoid.
I need to make my website compatible with the iPad and perhaps newer Androids. I've been using an old version of the FCKEditor (now CK Editor) for my WYSIWYG editors, but that doesn't work on mobile, so I want to swap it out for a simple textarea with something like markdown, if it's not supported.
Supposedly it won't work because mobile devices tend not to support this contentEditable property, which means the on-screen keyboard won't pop up when you click on it.
How can I detect if the browser supports contentEditable? It's been suggested that I just check the div in question with something like mydiv.contentElement === undefined or something like that, but the div (if it's using one) is all built into the FCK Editor and buried somewhere in an iframe.
Isn't there another way to detect if a browser supports contentEditable in general?
Just tried this:
var contentEditableSupport = typeof $('<div contenteditable="true">')[0].contentEditable !== 'undefined';
Says "true" on my iPad...... I don't think it should.
Edit: It's returning "string" because all attributes are strings.... it's just reading the attribute. How else am I supposed to do this?
You could create an anonymous editable div, check it for contentEditable, then remove the div.
Here is the test I use and is also used in Modernizr. It will give false positives in iOS 4 (and possibly earlier) but unfortunately it's impossible to detect in those environments.
var contentEditableSupport = "contentEditable" in document.documentElement;
I was able to accomplish this by checking the default value of the contentEditable property rather than the presence or type. The W3 spec indicates that the missing value default for contentEditable is "inherit", but in older browsers (e.g. Android/Gingerbread) the default value is "false". Thanks to fudgey for the comment on the OP that pointed me in the right direction!
This test works for me:
var contentEditableSupport = $('<div/>')[0].contentEditable == 'inherit';
Check for execCommand
if (document.execCommand) {
... browser supports contentEditable
} else {
... browser doesn't support contentEditable
}
To check if any propery exits for a element. You can do this
var element = document.createElement('__ELEMENT__');
if ('__PROPERTY__' in element ) {
// property supported in the browser
}
or
if ('__PROPERTY__' in document.createElement('__ELEMENT__') ) {
// property supported in the browser
}
The below link contains it all.
https://github.com/Modernizr/Modernizr/issues/570
http://diveintohtml5.info/everything.html#contenteditable

Needing an ExtJS bug workaround

I have a web application that uses Ext-JS 2.2. In a certain component, we have an empty toolbar that we are trying to add a button to using
myPanel.getTopToolbar().insertButton(0, [...array of buttons...]);
However, in IE6/7 this fails because of lines 20241-20242 in ext-all-debug.js:
var td = document.createElement("td");
this.tr.insertBefore(td, this.tr.childNodes[index]);
Since "this.tr.childNodes([0])" does not yet exist in IE, this fails with "Invalid argument".
THE REAL QUESTION:
Can I, using CSS similar to the below add a child to every toolbar <tr> so that this.tr.childNodes[0] is found:
div.x-toolbar tr:after { content: " "; }
I totally realize this is a hack, but for legal reasons I cannot change any Javascript, not even to add an empty button ({}) to each toolbar. Major kudos to anyone that can figure this out.
What I've had to do in the past was include an empty toolbar in my element config:
tbar:[]
Then (and only after the element has completely rendered) use the .add() method for injecting buttons.
Order of events will get you every time. It takes a while to get a handle on it.
If all you are doing is adding to a empty panel
myPanel.getTopToolbar().add(buttons etc);
Or
myPanel.getTopToolbar().addButton(..);
Either should work. It looks like purpose of insertButton is for putting a button within a non-empty toolbar.
Did you look into adding the button after the panel has been rendered? Maybe something like:
myPanel.on('render', function() {
this.getTopToolbar().insertButton(0, [...array of buttons...]);
}, true);
I didn't think there was a CSS-only solution.
For the record, I ended up injecting javascript into the page that overrides the Ext.Toolbar prototype for the insertButton() function to check for the existance of "this.tr.childNodes([0])" and default to addButton() if it didn't exist.

Adding an input field to the dom and focusing it in IE

I am trying to make a div, that when you click it turns into an input box, and focuses it. I am using prototype to achieve this. This works in both Chrome and Firefox, but not in IE. IE refuses to focus the newly added input field, even if I set a 1 second timeout.
Basically the code works like this:
var viewElement = new Element("div").update("text");
var editElement = new Element("input", {"type":"text"});
root.update(viewElement);
// pseudo shortcut for the sake of information:
viewElementOnClick = function(event) {
root.update(editElement);
editElement.focus();
}
The above example is a shortened version of the actual code, the actual code works fine except the focus bit in IE.
Are there limitations on the focus function in IE? Do I need to place the input in a form?
My guess is that IE hasn't updated the DOM yet when you make the call to focus(). Sometimes browsers will wait until a script has finished executing before updating the DOM.
I would try doing the update, then doing
setTimeout("setFocus", 0);
function setFocus()
{
editElement.focus();
}
Your other option would be to have both items present in the DOM at all times and just swap the style.display on them depending on what you need hidden/shown at a given time.
What version IE? What's your DocType set to? is it strict, standards or quirks mode? Any javascript errors appearing (check the status bar bottom left for a little yellow warning sign) ? Enable error announcing for all errors via Tools > Options > Advanced.
Oisin
The question is already answered by 17 of 26. I just want to point out, that Prototype has native mechanism for this: Function.defer()

Categories

Resources