Merge pull request #2423 from ether/fix/reimplement-ace-getAttributeOnSelection
Re-implement ace_getAttributeOnSelectionpull/2509/merge
commit
70fdc7dcd7
|
@ -2322,93 +2322,72 @@ function Ace2Inner(){
|
||||||
}
|
}
|
||||||
editorInfo.ace_setAttributeOnSelection = setAttributeOnSelection;
|
editorInfo.ace_setAttributeOnSelection = setAttributeOnSelection;
|
||||||
|
|
||||||
|
|
||||||
function getAttributeOnSelection(attributeName){
|
function getAttributeOnSelection(attributeName){
|
||||||
if (!(rep.selStart && rep.selEnd)) return;
|
if (!(rep.selStart && rep.selEnd)) return
|
||||||
|
|
||||||
// get the previous/next characters formatting when we have nothing selected
|
|
||||||
// To fix this we just change the focus area, we don't actually check anything yet.
|
|
||||||
if(rep.selStart[1] == rep.selEnd[1]){
|
|
||||||
// if we're at the beginning of a line bump end forward so we get the right attribute
|
|
||||||
if(rep.selStart[1] == 0 && rep.selEnd[1] == 0){
|
|
||||||
rep.selEnd[1] = 1;
|
|
||||||
}
|
|
||||||
if(rep.selStart[1] < 0){
|
|
||||||
rep.selStart[1] = 0;
|
|
||||||
}
|
|
||||||
var line = rep.lines.atIndex(rep.selStart[0]);
|
|
||||||
// if we're at the end of the line bmp the start back 1 so we get hte attribute
|
|
||||||
if(rep.selEnd[1] == line.text.length){
|
|
||||||
rep.selStart[1] = rep.selStart[1] -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do the detection
|
|
||||||
var selectionAllHasIt = true;
|
|
||||||
var withIt = Changeset.makeAttribsString('+', [
|
var withIt = Changeset.makeAttribsString('+', [
|
||||||
[attributeName, 'true']
|
[attributeName, 'true']
|
||||||
], rep.apool);
|
], rep.apool);
|
||||||
var withItRegex = new RegExp(withIt.replace(/\*/g, '\\*') + "(\\*|$)");
|
var withItRegex = new RegExp(withIt.replace(/\*/g, '\\*') + "(\\*|$)");
|
||||||
|
|
||||||
function hasIt(attribs)
|
function hasIt(attribs)
|
||||||
{
|
{
|
||||||
return withItRegex.test(attribs);
|
return withItRegex.test(attribs);
|
||||||
}
|
}
|
||||||
|
|
||||||
var selStartLine = rep.selStart[0];
|
return rangeHasAttrib(rep.selStart, rep.selEnd)
|
||||||
var selEndLine = rep.selEnd[0];
|
|
||||||
for (var n = selStartLine; n <= selEndLine; n++)
|
function rangeHasAttrib(selStart, selEnd) {
|
||||||
{
|
// if range is collapsed -> no attribs in range
|
||||||
var opIter = Changeset.opIterator(rep.alines[n]);
|
if(selStart[1] == selEnd[1] && selStart[0] == selEnd[0]) return false
|
||||||
var indexIntoLine = 0;
|
|
||||||
var selectionStartInLine = 0;
|
if(selStart[0] != selEnd[0]) { // -> More than one line selected
|
||||||
var selectionEndInLine = rep.lines.atIndex(n).text.length; // exclude newline
|
var hasAttrib = true
|
||||||
if(rep.lines.atIndex(n).text.length == 0){
|
|
||||||
return false; // If the line length is 0 we basically treat it as having no formatting
|
// from selStart to the end of the first line
|
||||||
|
hasAttrib = hasAttrib && rangeHasAttrib(selStart, [selStart[0], rep.lines.atIndex(selStart[0]).text.length])
|
||||||
|
|
||||||
|
// for all lines in between
|
||||||
|
for(var n=selStart[0]+1; n < selEnd[0]; n++) {
|
||||||
|
hasAttrib = hasAttrib && rangeHasAttrib([n, 0], [n, rep.lines.atIndex(n).text.length])
|
||||||
|
}
|
||||||
|
|
||||||
|
// for the last, potentially partial, line
|
||||||
|
hasAttrib = hasAttrib && rangeHasAttrib([selEnd[0], 0], [selEnd[0], selEnd[1]])
|
||||||
|
|
||||||
|
return hasAttrib
|
||||||
}
|
}
|
||||||
if(rep.selStart[1] == rep.selEnd[1] && rep.selStart[1] == rep.lines.atIndex(n).text.length){
|
|
||||||
return false; // If we're at the end of a line we treat it as having no formatting
|
// Logic tells us we now have a range on a single line
|
||||||
}
|
|
||||||
if(rep.selStart[1] == 0 && rep.selEnd[1] == 0){
|
var lineNum = selStart[0]
|
||||||
rep.selEnd[1] == 1;
|
, start = selStart[1]
|
||||||
}
|
, end = selEnd[1]
|
||||||
if(rep.selEnd[1] == -1){
|
, hasAttrib = true
|
||||||
rep.selEnd[1] = 1; // sometimes rep.selEnd is -1, not sure why.. When it is we should look at the first char
|
|
||||||
}
|
// Iterate over attribs on this line
|
||||||
if (n == selStartLine)
|
|
||||||
{
|
var opIter = Changeset.opIterator(rep.alines[lineNum])
|
||||||
selectionStartInLine = rep.selStart[1];
|
, indexIntoLine = 0
|
||||||
}
|
|
||||||
if (n == selEndLine)
|
while (opIter.hasNext()) {
|
||||||
{
|
|
||||||
selectionEndInLine = rep.selEnd[1];
|
|
||||||
}
|
|
||||||
while (opIter.hasNext())
|
|
||||||
{
|
|
||||||
var op = opIter.next();
|
var op = opIter.next();
|
||||||
var opStartInLine = indexIntoLine;
|
var opStartInLine = indexIntoLine;
|
||||||
var opEndInLine = opStartInLine + op.chars;
|
var opEndInLine = opStartInLine + op.chars;
|
||||||
if (!hasIt(op.attribs))
|
if (!hasIt(op.attribs)) {
|
||||||
{
|
|
||||||
// does op overlap selection?
|
// does op overlap selection?
|
||||||
if (!(opEndInLine <= selectionStartInLine || opStartInLine >= selectionEndInLine))
|
if (!(opEndInLine <= start || opStartInLine >= end)) {
|
||||||
{
|
hasAttrib = false; // since it's overlapping but hasn't got the attrib -> range hasn't got it
|
||||||
selectionAllHasIt = false;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
indexIntoLine = opEndInLine;
|
indexIntoLine = opEndInLine;
|
||||||
}
|
}
|
||||||
if (!selectionAllHasIt)
|
|
||||||
{
|
return hasAttrib
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(selectionAllHasIt){
|
|
||||||
return true;
|
|
||||||
}else{
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
editorInfo.ace_getAttributeOnSelection = getAttributeOnSelection;
|
editorInfo.ace_getAttributeOnSelection = getAttributeOnSelection;
|
||||||
|
|
||||||
function toggleAttributeOnSelection(attributeName)
|
function toggleAttributeOnSelection(attributeName)
|
||||||
|
|
Loading…
Reference in New Issue