
// NOTES
//  maybe we can use selection.modify() to know if we are at a boundary or not
//  depending on where the cursor ends up afterwards, we can guess that we are at a
//  boundary (especially if by luck it does not move)
//
//  if we can cancel the default behaviour for up and down, maybe we can handle it ourselves?

(function () {
    var top = NaN, savedRange;
    function details (ev) {
        var kc = ev.keyCode
        ,   ret = {
                sel:    window.getSelection()
            ,   range:  window.getSelection().getRangeAt(0)
            ,   up:     kc === 38
            ,   down:   kc === 40
            ,   left:   kc === 37
            ,   right:  kc === 39
            }
        ;
        ret.arrow = ret.up || ret.down || ret.left || ret.right;
        ret.upDown = ret.up || ret.down;
        return ret;
    }
    function rangeDown (ev) {
        var d = details(ev);
        if (d.upDown) {
            top = d.range.getBoundingClientRect().top;
            savedRange = d.range.cloneRange();
            d.sel.modify("move", d.up ? "backward" : "forward", "line");
        }
    }
    function rangePress (ev) {
        var d = details(ev)
        ,   atBoundary = (top - d.range.getBoundingClientRect().top) === 0
        ;
        if (d.upDown && atBoundary) {
            console.log("at boundary", d.up ? "top" : "bottom");
            // XXX
            //  fire an event indicating direction
            //  the default behaviour is to go to start/end of line (well, do the modify again)
            //  but it can be cancelled
            //  turn this into a proper implementation of the idea from the Substance guys
            //  see if this works on other browsers too
            //  apply to all data-cursorable
            d.sel.removeAllRanges();
            d.sel.addRange(savedRange);
        }
        if (d.upDown || !d.arrow) ev.preventDefault();
    }
    
    var x2 = document.getElementById("x2");
    x2.addEventListener("keydown", rangeDown, false);
    x2.addEventListener("keypress", rangePress, false);


    // x2.addEventListener("keypress", showRange, false);
    // x2.addEventListener("keydown", showRange, false);
    //
    // x2.addEventListener("keyup", position, false);
    // x2.addEventListener("keypress", position, false);

}());

@@ -1,328 +1,4 @@
-%0A// NOTES%0A//  maybe we can use selection.modify() to know if we are at a boundary or not%0A//  depending on where the cursor ends up afterwards, we can guess that we are at a%0A//  boundary (especially if by luck it does not move)%0A//%0A//  if we can cancel the default behaviour for up and down, maybe we can handle it ourselves?%0A
 %0A(fu
@@ -38,16 +38,30 @@
 vedRange
+, wasCollapsed
 ;%0A    fu
@@ -607,16 +607,53 @@
 d.upDown
+ && !ev.shiftKey && d.range.collapsed
 ) %7B%0A    
@@ -703,16 +703,62 @@
 ().top;%0A
+            wasCollapsed = d.range.collapsed;%0A
         
@@ -1019,16 +1019,81 @@
 ) === 0%0A
+        ,   collapseChanged = !wasCollapsed && d.range.collapsed%0A
         
@@ -1128,16 +1128,36 @@
 Boundary
+ && !collapseChanged
 ) %7B%0A    
@@ -1615,16 +1615,421 @@
 sorable%0A
+            //  check that we properly handle keyboard-based selections:%0A            //      - by and large we do, except when going up/down. We need to handle that%0A            //        by checking on Shift and letting the default happen then with no boundary%0A            //        detection or manipulation. Or ideally we want boundary detection anyway, if%0A            //        we can get away with it%0A
         
@@ -2110,32 +2110,33 @@
    %7D%0A        if 
+(
 (d.upDown %7C%7C !d.
@@ -2128,16 +2128,53 @@
 d.upDown
+ && !ev.shiftKey && !collapseChanged)
  %7C%7C !d.a
@@ -2369,246 +2369,174 @@
 e);%0A
-%0A%0A    // x2.addEventListener(%22keypress%22, showRange, false);%0A    // x2.addEventListener(%22keydown%22, showRange, false);%0A    //%0A    // x2.addEventListener(%22keyup%22, position, false);%0A    // x2.addEventListener(%22keypress%22, position, false);%0A%0A%7D());
+%7D());%0A%0A%0A// Processing%0A//  if not up/down return from both%0A//  if shift key return from both%0A%0A%0A//  IF range collapsed and was collapsed and and up/down and not shift%0A%0A%0A%0A%0A
 %0A

taking selections into account is painful