tracked down bug that caused deviation between the dom tree and the cursor. Need to remember that jquery can be too convenient at times: it filters out text children, whereas the cursor does not.

This commit is contained in:
Danny Yoo 2011-09-12 15:21:49 -04:00
parent a39fb910ce
commit c9ccc36b5e
3 changed files with 77 additions and 71 deletions

View File

@ -8,9 +8,11 @@
(define (go-forward world dom) (define (go-forward world dom)
(add1 world)) (add1 world))
(define (go-backward world dom) (define (go-backward world dom)
(max (sub1 world) 0)) (max (sub1 world) 0))
(define (view-top a-view) (define (view-top a-view)
(if (view-up? a-view) (if (view-up? a-view)
(view-top (view-up a-view)) (view-top (view-up a-view))
@ -19,7 +21,7 @@
(define (clear-all a-view) (define (clear-all a-view)
(define (loop a-view n) (define (loop a-view n)
(define updated-view a-view) ;; (update-view-css a-view "border" "none")) (define updated-view (update-view-css a-view "background" ""))
(cond (cond
[(view-forward? updated-view) [(view-forward? updated-view)
(loop (view-forward updated-view) (add1 n))] (loop (view-forward updated-view) (add1 n))]
@ -27,19 +29,28 @@
(view-top updated-view)])) (view-top updated-view)]))
(loop a-view 0)) (loop a-view 0))
(define (iterate n f x) (define (iterate n f x)
(if (<= n 0) (if (<= n 0)
x x
(iterate (sub1 n) f (f x)))) (iterate (sub1 n) f (f x))))
(define (maybe-view-forward a-view)
(if (view-forward? a-view)
(view-forward a-view)
a-view))
(define (draw world dom) (define (draw world dom)
(define another-view (update-view-css (iterate world (define another-view (update-view-css (iterate world
view-forward maybe-view-forward
(clear-all dom)) (clear-all dom))
"border" "background"
"1px solid blue")) "orange"))
another-view)
(update-view-text (view-focus another-view "message")
(format "Highlighting element ~a\n" world)))
(define my-initial-view (view-bind (define my-initial-view (view-bind
(view-focus (view-focus

View File

@ -4,7 +4,7 @@
<h1>This is a test</h1> <h1>This is a test</h1>
<input type="button" id="forward" value="Forward"> <input type="button" id="forward" value="Forward">
<input type="button" id="backward" value="Backward"> <input type="button" id="backward" value="Backward">
<div id="message"></div>
<table> <table>
<tr><td>First Row</td></tr> <tr><td>First Row</td></tr>

View File

@ -180,7 +180,7 @@
}, },
function(eventHandlers) { return eventHandlers; }, function(eventHandlers) { return eventHandlers; },
function(view) { function(view) {
view.focus = $(document.getElementById(selector)); view.focus = document.getElementById(selector);
} }
); );
}; };
@ -198,7 +198,7 @@
}, },
function(eventHandlers) { return eventHandlers; }, function(eventHandlers) { return eventHandlers; },
function(view) { function(view) {
view.focus.text(text); $(view.focus).text(text);
} }
); );
}; };
@ -219,7 +219,7 @@
return eventHandlers; return eventHandlers;
}, },
function(view) { function(view) {
view.focus.attr(name, value); $(view.focus).attr(name, value);
}); });
}; };
@ -235,8 +235,6 @@
MockView.prototype.updateCss = function(name, value) { MockView.prototype.updateCss = function(name, value) {
return this.act( return this.act(
function(cursor) { function(cursor) {
console.log("functionally: ",
$(cursor.node[0].cloneNode(false)).css(name, value).get(0));
return cursor.replaceNode([$(cursor.node[0].cloneNode(false)) return cursor.replaceNode([$(cursor.node[0].cloneNode(false))
.css(name, value).get(0)] .css(name, value).get(0)]
.concat(cursor.node.slice(1))); .concat(cursor.node.slice(1)));
@ -245,19 +243,12 @@
return eventHandlers; return eventHandlers;
}, },
function(view) { function(view) {
if (view.focus.length === 0) { $(view.focus).css(name, value);
console.log('update css: empty focus?!');
}
console.log('css: updating:\n', view.focus);
view.focus.css(name, value);
}); });
}; };
MockView.prototype.getFormValue = function() { MockView.prototype.getFormValue = function() {
return $(this.cursor.node[0]).val(); return $(this.cursor.node[0]).val();
}; };
@ -273,7 +264,7 @@
return eventHandlers; return eventHandlers;
}, },
function(view) { function(view) {
view.focus.val(value); $(view.focus).val(value);
}); });
}; };
@ -288,7 +279,7 @@
return eventHandlers; return eventHandlers;
}, },
function(view) { function(view) {
view.focus = view.focus.prev(); view.focus = view.focus.previousSibling;
}); });
}; };
@ -301,7 +292,7 @@
return eventHandlers; return eventHandlers;
}, },
function(view) { function(view) {
view.focus = view.focus.next(); view.focus = view.focus.nextSibling;
}); });
}; };
@ -314,7 +305,7 @@
return eventHandlers; return eventHandlers;
}, },
function(view) { function(view) {
view.focus = view.focus.parent(); view.focus = view.focus.parentNode;
}); });
}; };
@ -327,7 +318,7 @@
return eventHandlers; return eventHandlers;
}, },
function(view) { function(view) {
view.focus = view.focus.children(':first'); view.focus = view.focus.firstChild;
}); });
}; };
@ -341,15 +332,15 @@
return eventHandlers; return eventHandlers;
}, },
function(view) { function(view) {
if (view.focus.children().length > 0) { if (view.focus.firstChild) {
view.focus = view.focus.children(':first'); view.focus = view.focus.firstChild;
} else if (view.focus.next().length > 0) { } else if (view.focus.nextSibling) {
view.focus = view.focus.next(); view.focus = view.focus.nextSibling;
} else { } else {
while (view.focus.get(0) !== view.top.get(0)) { while (view.focus !== view.top) {
view.focus = view.focus.parent(); view.focus = view.focus.parentNode;
if (view.focus.next().length > 0) { if (view.focus.nextSibling) {
view.focus = view.focus.next(); view.focus = view.focus.nextSibling;
return; return;
} }
} }
@ -366,13 +357,14 @@
return eventHandlers; return eventHandlers;
}, },
function(view) { function(view) {
if (view.focus.prev().length > 0) { if (view.focus.previousSibling) {
view.focus = view.focus.prev(); view.focus = view.focus.previousSibling;
while (view.focus.children().length > 0) { while (view.focus.children().length > 0) {
view.focus = view.focus.children(':last'); view.focus = view.focus.firstChild;
while(view.focus.nextSibling) { view.focus = view.focus.nextSibling; }
} }
} else { } else {
view.focus = view.focus.parent(); view.focus = view.focus.parentNode;
} }
}); });
@ -411,13 +403,13 @@
function(view) { function(view) {
// HACK: every node that is bound needs to have an id. We // HACK: every node that is bound needs to have an id. We
// enforce this by mutating the node. // enforce this by mutating the node.
if (! view.focus.get(0).id) { if (! view.focus.id) {
view.focus.get(0).id = ("__webWorldId_" + mockViewIdGensym++); view.focus.id = ("__webWorldId_" + mockViewIdGensym++);
} }
var handler = new EventHandler(name, var handler = new EventHandler(name,
new DomEventSource( new DomEventSource(
name, name,
view.focus.get(0).id), view.focus.id),
worldF); worldF);
view.addEventHandler(handler); view.addEventHandler(handler);
currentBigBangRecord.startEventHandler(handler); currentBigBangRecord.startEventHandler(handler);
@ -433,7 +425,7 @@
}, },
function(eventHandlers) { return eventHandlers; }, function(eventHandlers) { return eventHandlers; },
function(view) { function(view) {
view.focus.show(); $(view.focus).show();
} }
); );
}; };
@ -447,7 +439,7 @@
}, },
function(eventHandlers) { return eventHandlers; }, function(eventHandlers) { return eventHandlers; },
function(view) { function(view) {
view.focus.hide(); $(view.focus).hide();
} }
); );
}; };
@ -463,14 +455,14 @@
}, },
function(view) { function(view) {
var elt = view.focus; var elt = view.focus;
if (view.focus.next().length > 0) { if (view.focus.nextSibling) {
view.focus = view.focus.next(); view.focus = view.focus.nextSibling;
} else if (view.focus.prev().length > 0) { } else if (view.focus.previousSibling) {
view.focus = view.focus.prev(); view.focus = view.focus.previousSibling;
} else { } else {
view.focus = view.focus.parent(); view.focus = view.focus.parentNode;
} }
elt.remove(); $(elt).remove();
}); });
}; };
@ -491,8 +483,8 @@
function(eventHandlers) { return eventHandlers; }, function(eventHandlers) { return eventHandlers; },
function(view) { function(view) {
var clone = $(domNode).clone(true); var clone = $(domNode).clone(true);
clone.appendTo(view.focus); clone.appendTo($(view.focus));
view.focus = clone; view.focus = clone.get(0);
} }
); );
}; };
@ -505,8 +497,8 @@
function(eventHandlers) { return eventHandlers; }, function(eventHandlers) { return eventHandlers; },
function(view) { function(view) {
var clone = $(domNode).clone(true); var clone = $(domNode).clone(true);
clone.insertAfter(view.focus); clone.insertAfter($(view.focus));
view.focus = clone; view.focus = clone.get(0);
} }
); );
}; };
@ -519,8 +511,8 @@
function(eventHandlers) { return eventHandlers; }, function(eventHandlers) { return eventHandlers; },
function(view) { function(view) {
var clone = $(domNode).clone(true); var clone = $(domNode).clone(true);
clone.insertBefore(view.focus); clone.insertBefore($(view.focus));
view.focus = clone; view.focus = clone.get(0);
} }
); );
}; };
@ -566,6 +558,7 @@
var View = function(top, eventHandlers) { var View = function(top, eventHandlers) {
// top: dom node // top: dom node
this.top = top; this.top = top;
// focus: dom node
this.focus = top; this.focus = top;
this.eventHandlers = eventHandlers; this.eventHandlers = eventHandlers;
}; };
@ -573,16 +566,16 @@
View.prototype.toString = function() { return "#<View>"; }; View.prototype.toString = function() { return "#<View>"; };
View.prototype.initialRender = function(top) { View.prototype.initialRender = function(top) {
top.empty(); $(top).empty();
// Special case: if this.top is an html, we merge into the // Special case: if this.top is an html, we merge into the
// existing page. // existing page.
if (this.top.children("title").length !== 0) { if ($(this.top).children("title").length !== 0) {
$(document.head).find('title').remove(); $(document.head).find('title').remove();
} }
$(document.head).append(this.top.children("title")); $(document.head).append($(this.top).children("title"));
$(document.head).append(this.top.children("link")); $(document.head).append($(this.top).children("link"));
top.append(this.top); $(top).append(this.top);
}; };
View.prototype.addEventHandler = function(handler) { View.prototype.addEventHandler = function(handler) {
@ -641,13 +634,13 @@
} catch (exn1) { } catch (exn1) {
return onFail(exn1); return onFail(exn1);
} }
return onSuccess(new View(dom, [])); return onSuccess(new View(dom.get(0), []));
} else if (isMockView(x)) { } else if (isMockView(x)) {
return onSuccess(new View($(arrayTreeToDomNode(x.cursor.top().node)), return onSuccess(new View(arrayTreeToDomNode(x.cursor.top().node),
x.eventHandlers.slice(0))); x.eventHandlers.slice(0)));
} else { } else {
try { try {
dom = $(plt.baselib.format.toDomNode(x)); dom = plt.baselib.format.toDomNode(x);
} catch (exn2) { } catch (exn2) {
return onFail(exn2); return onFail(exn2);
} }
@ -669,14 +662,20 @@
} catch (exn1) { } catch (exn1) {
return onFail(exn1); return onFail(exn1);
} }
return onSuccess(new MockView(domToArrayTreeCursor(dom.get(0)), EMPTY_PENDING_ACTIONS, [], undefined)); return onSuccess(new MockView(domToArrayTreeCursor(dom.get(0)),
EMPTY_PENDING_ACTIONS,
[],
undefined));
} else { } else {
try { try {
dom = $(plt.baselib.format.toDomNode(x)); dom = plt.baselib.format.toDomNode(x);
} catch (exn2) { } catch (exn2) {
return onFail(exn2); return onFail(exn2);
} }
return onSuccess(new MockView(domToArrayTreeCursor(dom.get(0)), EMPTY_PENDING_ACTIONS, [], undefined)); return onSuccess(new MockView(domToArrayTreeCursor(dom),
EMPTY_PENDING_ACTIONS,
[],
undefined));
} }
}; };
@ -1083,7 +1082,7 @@
var running = true; var running = true;
var dispatchingEvents = false; var dispatchingEvents = false;
var top = $("<div/>"); var top = $("<div/>").get(0);
var view = (find(handlers, isInitialViewHandler) || { view : new View(top, []) }).view; var view = (find(handlers, isInitialViewHandler) || { view : new View(top, []) }).view;
var stopWhen = (find(handlers, isStopWhenHandler) || { stopWhen: defaultStopWhen }).stopWhen; var stopWhen = (find(handlers, isStopWhenHandler) || { stopWhen: defaultStopWhen }).stopWhen;
var toDraw = (find(handlers, isToDrawHandler) || {toDraw : defaultToDraw} ).toDraw; var toDraw = (find(handlers, isToDrawHandler) || {toDraw : defaultToDraw} ).toDraw;
@ -1230,7 +1229,6 @@
// update, and have to do it from scratch. // update, and have to do it from scratch.
var nonce = Math.random(); var nonce = Math.random();
var originalMockView = view.getMockAndResetFocus(nonce); var originalMockView = view.getMockAndResetFocus(nonce);
console.log("before: ", arrayTreeToDomNode(originalMockView.cursor.node));
toDraw(MACHINE, toDraw(MACHINE,
world, world,
originalMockView, originalMockView,
@ -1238,14 +1236,11 @@
if (newMockView.nonce === nonce) { if (newMockView.nonce === nonce) {
var i; var i;
var actions = newMockView.getPendingActions(); var actions = newMockView.getPendingActions();
console.log("this should match:",
view.focus.clone(true).get(0));
console.log("actions", actions.length);
for (i = 0; i < actions.length; i++) { for (i = 0; i < actions.length; i++) {
actions[i](view); actions[i](view);
} }
} else { } else {
view.top = $(arrayTreeToDomNode(newMockView.cursor.top().node)); view.top = arrayTreeToDomNode(newMockView.cursor.top().node);
view.initialRender(top); view.initialRender(top);
eventHandlers = newMockView.eventHandlers.slice(0); eventHandlers = newMockView.eventHandlers.slice(0);
view.eventHandlers = eventHandlers; view.eventHandlers = eventHandlers;