How to insert a node after a selection? - javascript

I need to wrap a selection in comment nodes so that it can be parsed later on.
This script is executing within a CK-Editor plugin, but I believe the way selection and range works is native to JavaScript.
I'm able to insert the comment node at the beginning of the range just fine, but I can't figure out how to add a comment node to the end of the selection.
My current code is:
var selection = editor.getSelection();
var ranges = selection.getRanges();
var start_node = 'parsing_start';
var end_node = 'parsing_end';
var start_comment = new CKEDITOR.dom.comment(start_node);
var end_comment = new CKEDITOR.dom.comment(end_node);
ranges[0].insertNode(start_comment);
ranges[0].nextSibling().insertNode(end_comment); // how to do this???

Try this to select a new empty range after the original selection. The only disadvantage is that you lose the original selection.
var selection = editor.getSelection();
var range = selection.getRanges()[0];
var start_node = 'parsing_start';
var end_node = 'parsing_end';
var start_comment = new CKEDITOR.dom.comment(start_node);
var end_comment = new CKEDITOR.dom.comment(end_node);
range.insertNode(start_comment);
var endNode = range.endContainer;
var endOffset = range.endOffset;
range.setStart(endNode, endOffset);
range.setEnd(endNode, endOffset);
selection.selectRanges([range]);
range.insertNode(end_comment);
editor.focus();

Related

Google Apps Script (Spreadsheet) - selecting an array in spreadsheet based on a condition in cells

I am trying to select an array from google sheets to create google calendar events based on that. The code chunk below runs just fine and gets the job done. But I want to be able to only select the range that has value of "select" in their column D.
I know it is probably a very easy answer but I am new to JS.
function calendarSync() {
var spreadSheet = SpreadsheetApp.getActiveSheet;
var eventCal = CalendarApp.getCalendarById(calendarId);
// Below instead of selecting the entire range I only need the rows that have a value of "select" in their D cell.
var eventArray = spreadSheet.getRange("A1:D100").getValues();
for (x=0; x<eventMatrix.length; x++){
var calEvent = eventArray[x];
var eventName = calEvent[0]
var startTime = calEvent[1];
var endTime = calEvent[2];
eventCal.createEvent(eventName, startTime, endTime);
}
In your situation, how about the following modification?
From:
var spreadSheet = SpreadsheetApp.getActiveSheet;
var eventCal = CalendarApp.getCalendarById(calendarId);
// Below instead of selecting the entire range I only need the rows that have a value of "select" in their D cell.
var eventArray = spreadSheet.getRange("A1:D100").getValues();
To:
var spreadSheet = SpreadsheetApp.getActiveSheet(); // Please add ()
var eventCal = CalendarApp.getCalendarById(calendarId);
var eventArray = spreadSheet.getRange("A1:D100").getValues().filter(r => r[3] == "select");
By this modification, eventArray has the values that select is included in the column "D".
Reference:
filter()

How to get current cursor position when editing fabric.Textbox

How to get current cursor position on text in fabric.Textbox
for example, the following should return = 6
I sort of figured it out. selectionStart and selectionEnd did the trick:
var activeObj = canvas.getActiveObject();
var caretPositionStart = activeObj.selectionStart;
var caretPositionEnd = activeObj.selectionEnd;
activeObj.enterEditing();
activeObj.insertChars("HI", null, caretPositionStart, caretPositionEnd);

Inserting an HTML element after text selection

I am trying to insert some HTML after the user has selected some text on the page. I have it working but not optimally and there is one problem in particular:
It relies on the element being on the page, but I don't want it to be. I want to do it all in the code, I am sure it's something relatively simple but need some help :)
I also welcome any other tips/suggestions/feedback!
The code canbe seen working here: http://jsfiddle.net/shE58/ (The selectionchange library is to make this work in FF).
document.addEventListener('selectionchange', function (event) {
var sel = this.getSelection();
// If text is being selected by drag, to wait for them to finish selecting.
jQuery("body").mouseup(function() {
// Ensure there is some text selected and that it is more than one character.
if (sel.toString().length > 1) {
// We only want one #element on the page at a time.
$("#element").remove();
// #TODO: Remove dependency on this:
var el = document.getElementById('selection');
el.innerHTML = '<div id="element"></div>';
var frag = document.createDocumentFragment(), node;
frag.appendChild(el.firstChild);
var range = sel.getRangeAt(0)
var startNode = range.startContainer, startOffset = range.startOffset;
var boundaryRange = range.cloneRange();
boundaryRange.collapse(false);
boundaryRange.insertNode(frag);
boundaryRange.setStart(startNode, startOffset);
boundaryRange.collapse(true);
// Clean up
sel = '';
}
});
});
Solution 1
Remove frag variable and directly add value in insertNode function like this :
boundaryRange.insertNode($('<div id="element"></div>')[0]);
http://jsfiddle.net/N6zz8/
Fix issue when to select right to left :
With a condition check if endOffset is smaller than startOffset.
var startNode = range.startContainer, startOffset = range.startOffset;
if (range.endOffset < range.startOffset) {
startNode = range.endContainer;
startOffset = range.endOffset;
}
http://jsfiddle.net/2c4qw/
Solution 2
Remove unnecessary code, remove 'el' variable like this :
// #TODO: Remove dependency on this:
var frag = document.createDocumentFragment(), node;
$(frag).append($('<div id="element"></div>'));
http://jsfiddle.net/zYSH4/
Solution 3
Declare your variable like this var el = $("<div></div>")[0];. To get this :
// #TODO: Remove dependency on this:
var el = $("<div></div>")[0];
el.innerHTML = '<div id="element"></div>';
var frag = document.createDocumentFragment(), node;
frag.appendChild(el.firstChild);
http://jsfiddle.net/7L3Kf/

Compare caretPositionFromPoint, which is bigger?

I get the caretPositionFromPoint for two elements:
var start = doc.caretPositionFromPoint(someX, someY);
var end = doc.caretPositionFromPoint(otherX, otherY);
How can I check whether start is later in the document than end?
Solved it by making a Range which has methods for this.
var sr = document.createRange();
sr.setStart(start.offsetNode, start.offset);
sr.setEnd(start.offsetNode, start.offset);
if (sr.comparePoint(end.offsetNode, end.offset) === -1) {
// end is before start
}

How to get the coordinates of the end of selected text with javascript?

My problem is similar to this, but I need a way to get the coordinates of the right side of the selection with Javascript in Firefox. I made a small example to show what I mean:
The code I got from the other post is the following:
var range = window.getSelection().getRangeAt(0);
var dummy = document.createElement("span");
range.insertNode(dummy);
var box = document.getBoxObjectFor(dummy);
var x = box.x, y = box.y;
dummy.parentNode.removeChild(dummy);
This gives me the coordinates of the beginning of the selection. Is there any way to retrieve the coordinates of the end of the selection?
Yes. That bit's quite simple: you just need to call collapse(false) on the Range obtained from the selection. Be aware that document.getBoxObjectFor() has now been removed from Mozilla, so you need the dummy element's getBoundingClientRect() method instead:
var range = window.getSelection().getRangeAt(0);
range.collapse(false);
var dummy = document.createElement("span");
range.insertNode(dummy);
var rect = dummy.getBoundingClientRect();
var x = rect.left, y = rect.top;
dummy.parentNode.removeChild(dummy);
var r = range.cloneRange();
r.collapse(false); // collapses range clone to end of original range
r.insertNode(dummy);
// document.getBoxObjectFor(dummy), etc.

Categories

Resources