From dee2dab7c43059e2cb7081f0c9adfa576359efcb Mon Sep 17 00:00:00 2001 From: John McLear Date: Thu, 28 Nov 2013 17:27:52 +0000 Subject: [PATCH 1/9] getAttributeOnSelection function --- src/static/js/ace2_inner.js | 58 +++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/src/static/js/ace2_inner.js b/src/static/js/ace2_inner.js index c4ad8117f..5d67b205f 100644 --- a/src/static/js/ace2_inner.js +++ b/src/static/js/ace2_inner.js @@ -2372,6 +2372,64 @@ function Ace2Inner(){ } editorInfo.ace_setAttributeOnSelection = setAttributeOnSelection; + function getAttributeOnSelection(attributeName){ + if (!(rep.selStart && rep.selEnd)) return; + var selectionAllHasIt = true; + var withIt = Changeset.makeAttribsString('+', [ + [attributeName, 'true'] + ], rep.apool); + var withItRegex = new RegExp(withIt.replace(/\*/g, '\\*') + "(\\*|$)"); + + function hasIt(attribs) + { + return withItRegex.test(attribs); + } + + var selStartLine = rep.selStart[0]; + var selEndLine = rep.selEnd[0]; + for (var n = selStartLine; n <= selEndLine; n++) + { + var opIter = Changeset.opIterator(rep.alines[n]); + var indexIntoLine = 0; + var selectionStartInLine = 0; + var selectionEndInLine = rep.lines.atIndex(n).text.length; // exclude newline + if (n == selStartLine) + { + selectionStartInLine = rep.selStart[1]; + } + if (n == selEndLine) + { + selectionEndInLine = rep.selEnd[1]; + } + while (opIter.hasNext()) + { + var op = opIter.next(); + var opStartInLine = indexIntoLine; + var opEndInLine = opStartInLine + op.chars; + if (!hasIt(op.attribs)) + { + // does op overlap selection? + if (!(opEndInLine <= selectionStartInLine || opStartInLine >= selectionEndInLine)) + { + selectionAllHasIt = false; + break; + } + } + indexIntoLine = opEndInLine; + } + if (!selectionAllHasIt) + { + break; + } + } + if(selectionAllHasIt){ + return true; + }else{ + return false; + } + } + editorInfo.ace_getAttributeOnSelection = getAttributeOnSelection; + function toggleAttributeOnSelection(attributeName) { if (!(rep.selStart && rep.selEnd)) return; From e9f7583793308b46ec7a58e3c6aea1ec7182b880 Mon Sep 17 00:00:00 2001 From: John McLear Date: Thu, 28 Nov 2013 17:44:37 +0000 Subject: [PATCH 2/9] some nice css to that reflect when a button is active --- src/static/css/pad.css | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/static/css/pad.css b/src/static/css/pad.css index 467d50632..0c1153fde 100644 --- a/src/static/css/pad.css +++ b/src/static/css/pad.css @@ -1067,3 +1067,14 @@ input[type=checkbox] { } /* End of gritter stuff */ +.activeButton{ + background: #eee; + background: -webkit-linear-gradient(#ddd, #fff); + background: -moz-linear-gradient(#ddd, #fff); + background: -o-linear-gradient(#ddd, #fff); + background: -ms-linear-gradient(#ddd, #fff); + background: linear-gradient(#ddd, #fff); + -webkit-box-shadow: 0 0 8px rgba(0,0,0,.1) inset; + -moz-box-shadow: 0 0 8px rgba(0,0,0,.1) inset; + box-shadow: 0 0 8px rgba(0,0,0,.1) inset; +} From b4877f002dfd905b4606c4bf9c390eca15591719 Mon Sep 17 00:00:00 2001 From: John McLear Date: Sun, 1 Dec 2013 18:06:56 +0000 Subject: [PATCH 3/9] handle logic for line lengths with 0 --- src/static/js/ace2_inner.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/static/js/ace2_inner.js b/src/static/js/ace2_inner.js index 5d67b205f..3749a8586 100644 --- a/src/static/js/ace2_inner.js +++ b/src/static/js/ace2_inner.js @@ -2393,6 +2393,9 @@ function Ace2Inner(){ var indexIntoLine = 0; var selectionStartInLine = 0; var selectionEndInLine = rep.lines.atIndex(n).text.length; // exclude newline + if(rep.lines.atIndex(n).text.length == 0){ + return false; // If the line length is 0 we basically treat it as having no formatting + } if (n == selStartLine) { selectionStartInLine = rep.selStart[1]; From 3791ad41860d5174c0fb890f613028a2007d2eab Mon Sep 17 00:00:00 2001 From: John McLear Date: Sun, 1 Dec 2013 18:54:46 +0000 Subject: [PATCH 4/9] ends of line shouldn't show incorrect formatted status --- src/static/js/ace2_inner.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/static/js/ace2_inner.js b/src/static/js/ace2_inner.js index 3749a8586..736fba5a6 100644 --- a/src/static/js/ace2_inner.js +++ b/src/static/js/ace2_inner.js @@ -498,6 +498,15 @@ function Ace2Inner(){ finally { var cs = currentCallStack; + + hooks.callAll('acePostEditEvent', { + callstack: cs, + editorInfo: editorInfo, + rep: rep, + documentAttributeManager: documentAttributeManager + }); + + //console.log("Finished action for: "+type); if (cleanExit) { @@ -2396,6 +2405,9 @@ function Ace2Inner(){ if(rep.lines.atIndex(n).text.length == 0){ return false; // If the line length is 0 we basically treat it as having no formatting } + 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 + } if (n == selStartLine) { selectionStartInLine = rep.selStart[1]; From 39f81fdb9ed21a24d418034cc4ad854578f9b86e Mon Sep 17 00:00:00 2001 From: John McLear Date: Sun, 1 Dec 2013 18:55:42 +0000 Subject: [PATCH 5/9] remove post ace event --- src/static/js/ace2_inner.js | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/static/js/ace2_inner.js b/src/static/js/ace2_inner.js index 736fba5a6..b46c36200 100644 --- a/src/static/js/ace2_inner.js +++ b/src/static/js/ace2_inner.js @@ -499,14 +499,6 @@ function Ace2Inner(){ { var cs = currentCallStack; - hooks.callAll('acePostEditEvent', { - callstack: cs, - editorInfo: editorInfo, - rep: rep, - documentAttributeManager: documentAttributeManager - }); - - //console.log("Finished action for: "+type); if (cleanExit) { From 95db100f1222a52cd57502f0ecd2464d13f5a3d2 Mon Sep 17 00:00:00 2001 From: John McLear Date: Sun, 1 Dec 2013 18:56:05 +0000 Subject: [PATCH 6/9] remove white space --- src/static/js/ace2_inner.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/static/js/ace2_inner.js b/src/static/js/ace2_inner.js index b46c36200..05ac2cb20 100644 --- a/src/static/js/ace2_inner.js +++ b/src/static/js/ace2_inner.js @@ -498,7 +498,6 @@ function Ace2Inner(){ finally { var cs = currentCallStack; - //console.log("Finished action for: "+type); if (cleanExit) { From 30f577e8f41e6e4107c139d253a9083ea19a06a7 Mon Sep 17 00:00:00 2001 From: John McLear Date: Sun, 1 Dec 2013 20:01:17 +0000 Subject: [PATCH 7/9] dont assume formatting is on the start of any line --- src/static/js/ace2_inner.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/static/js/ace2_inner.js b/src/static/js/ace2_inner.js index 05ac2cb20..4ff0efcf7 100644 --- a/src/static/js/ace2_inner.js +++ b/src/static/js/ace2_inner.js @@ -2399,6 +2399,9 @@ function Ace2Inner(){ 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 } + if(rep.selStart[1] == 1 && rep.selEnd[1] == 1){ + return false; // If we're at the start of a line we treat it as having no formatting + } if (n == selStartLine) { selectionStartInLine = rep.selStart[1]; From 8a547b24ba2500b27b433070a1e8019548103b09 Mon Sep 17 00:00:00 2001 From: John McLear Date: Sat, 7 Dec 2013 17:37:52 +0000 Subject: [PATCH 8/9] resolve issue where first char showed all formatting --- src/static/js/ace2_inner.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/static/js/ace2_inner.js b/src/static/js/ace2_inner.js index 4ff0efcf7..56d8cc19b 100644 --- a/src/static/js/ace2_inner.js +++ b/src/static/js/ace2_inner.js @@ -2399,8 +2399,8 @@ function Ace2Inner(){ 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 } - if(rep.selStart[1] == 1 && rep.selEnd[1] == 1){ - return false; // If we're at the start of a line we treat it as having no formatting + if(rep.selStart[1] == 0 && rep.selEnd[1] == 0){ + return false; // If we're at the start of a line attributes get confused.. } if (n == selStartLine) { From d9ef40f9d70f31c88945eeb9d3e3f82393ec39bf Mon Sep 17 00:00:00 2001 From: John McLear Date: Sat, 7 Dec 2013 17:48:06 +0000 Subject: [PATCH 9/9] docs but not sure how to specify the verison this was introduced --- doc/api/editorInfo.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/api/editorInfo.md b/doc/api/editorInfo.md index 05656bce7..31361a750 100644 --- a/doc/api/editorInfo.md +++ b/doc/api/editorInfo.md @@ -39,6 +39,13 @@ Returns the `rep` object. ## editorInfo.ace_performDocumentApplyAttributesToCharRange(?) ## editorInfo.ace_setAttributeOnSelection(?) ## editorInfo.ace_toggleAttributeOnSelection(?) +## editorInfo.ace_getAttributeOnSelection(attribute) +Returns a boolean if an attribute exists on a selected range. +The attribute should be the string name of the attribute applied to the selection IE subscript +Example usage: Apply the activeButton Class to a button if an attribute is on a highlighted/selected caret position or range. +Example: `call.editorInfo.ace_getAttributeOnSelection("subscript");` // call here is the callstack from aceEditEvent. +See the ep_subscript plugin for an example of this function in action. +Notes: Does not work on first or last character of a line. Suffers from a race condition if called with aceEditEvent. ## editorInfo.ace_performSelectionChange(?) ## editorInfo.ace_doIndentOutdent(?) ## editorInfo.ace_doUndoRedo(?)