getting indices to locate items in the dom

This commit is contained in:
Danny Yoo 2011-08-26 16:16:16 -04:00
parent cf152bddcf
commit 60530bf759
3 changed files with 98 additions and 47 deletions

View File

@ -170,11 +170,11 @@
(source-name (first sources)))) (source-name (first sources))))
(hash-set! visited (first sources) #t) (hash-set! visited (first sources) #t)
(let*-values ([(this-source) (let*-values ([(this-source)
((current-module-source-compiling-hook) ((current-module-source-compiling-hook)
(first sources))] (first sources))]
[(ast stmts) [(ast stmts)
(get-ast-and-statements this-source)]) (get-ast-and-statements this-source)])
(log-debug "visiting") (log-debug (format "visiting ~a\n" (source-name this-source)))
(on-module-statements this-source ast stmts) (on-module-statements this-source ast stmts)
(loop (append (map wrap-source (collect-new-dependencies this-source ast)) (loop (append (map wrap-source (collect-new-dependencies this-source ast))
(rest sources))) (rest sources)))

View File

@ -1,6 +1,6 @@
<html> <html>
<head><title>Animation</title> <head><title>Animation</title>
<link rel="stylesheet" href="res/style.css"/> <link rel="stylesheet" href="style.css"/>
</head> </head>
<body> <body>
<p> <p>

View File

@ -69,6 +69,10 @@
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// A MockView provides a functional interface to the DOM. It
// includes a cursor to the currently focused dom, the pending
// actions to perform on the actual view, and a nonce to detect
// freshness of the MockView.
var MockView = function(cursor, pendingActions, nonce) { var MockView = function(cursor, pendingActions, nonce) {
this.cursor = cursor; this.cursor = cursor;
this.pendingActions = pendingActions; this.pendingActions = pendingActions;
@ -221,6 +225,10 @@
} }
}; };
View.prototype.addEventHandler = function(handler) {
this.eventHandlers.push(handler);
};
// Return a list of the event sources from the view. // Return a list of the event sources from the view.
// fixme: may need to apply the pending actions to get the real set. // fixme: may need to apply the pending actions to get the real set.
View.prototype.getEventHandlers = function() { View.prototype.getEventHandlers = function() {
@ -355,6 +363,8 @@
// An EventHandler combines a EventSource with a racketWorldCallback.
var EventHandler = function(name, eventSource, racketWorldCallback) { var EventHandler = function(name, eventSource, racketWorldCallback) {
WorldHandler.call(this); WorldHandler.call(this);
this.name = name; this.name = name;
@ -395,7 +405,9 @@
/* Event sources. /* Event sources.
An event source are the inputs to a web world program. An event source is a way to send input to a web-world program.
An event source may be started or stopped.
Pause and Unpause are semantically meant to be cheaper than start, stop, so Pause and Unpause are semantically meant to be cheaper than start, stop, so
@ -421,7 +433,8 @@
// Clock ticks.
// TickEventSource sends tick events.
var TickEventSource = function(delay) { var TickEventSource = function(delay) {
this.delay = delay; // delay in milliseconds. this.delay = delay; // delay in milliseconds.
@ -449,15 +462,17 @@
var BindEventSource = function(type, element) { // A DomEventSource allows DOM elements to send events over to
// web-world.
var DomEventSource = function(type, element) {
this.type = type; this.type = type;
this.element = element; this.element = element;
this.handler = undefined; this.handler = undefined;
}; };
BindEventSource.prototype = plt.baselib.heir(EventSource.prototype); DomEventSource.prototype = plt.baselib.heir(EventSource.prototype);
BindEventSource.prototype.onStart = function(fireEvent) { DomEventSource.prototype.onStart = function(fireEvent) {
this.handler = this.handler =
function(evt) { function(evt) {
fireEvent(evt); fireEvent(evt);
@ -466,7 +481,7 @@
this.handler); this.handler);
}; };
BindEventSource.prototype.onStop = function() { DomEventSource.prototype.onStop = function() {
if (this.handler !== undefined) { if (this.handler !== undefined) {
$(this.element).unbind(this.type, this.handler); $(this.element).unbind(this.type, this.handler);
this.handler = undefined; this.handler = undefined;
@ -526,16 +541,16 @@
var eventQueue = new EventQueue(); var eventQueue = new EventQueue();
var top = $("<div/>"); var top = $("<div/>");
var eventHandlers = filter(handlers, isEventHandler).concat(view.getEventHandlers());
MACHINE.params.currentDisplayer(MACHINE, top); MACHINE.params.currentDisplayer(MACHINE, top);
PAUSE(function(restart) { PAUSE(function(restart) {
var i;
var onCleanRestart = function() { var onCleanRestart = function() {
running = false; running = false;
var i; stopEventHandlers();
for (i = 0; i < eventHandlers.length; i++) {
stopEventHandler(eventHandlers[i]);
}
restart(function(MACHINE) { restart(function(MACHINE) {
MACHINE.argcount = oldArgcount; MACHINE.argcount = oldArgcount;
finalizeClosureCall(MACHINE, world); finalizeClosureCall(MACHINE, world);
@ -544,15 +559,47 @@
var onMessyRestart = function(exn) { var onMessyRestart = function(exn) {
running = false; running = false;
var i; stopEventHandlers();
for (i = 0; i < eventHandlers.length; i++) {
stopEventHandler(eventHandlers[i]);
}
restart(function(MACHINE) { restart(function(MACHINE) {
plt.baselib.exceptions.raise(MACHINE, exn); plt.baselib.exceptions.raise(MACHINE, exn);
}); });
}; };
var startEventHandlers = function() {
var i;
for (i = 0; i < eventHandlers.length; i++) {
startEventHandler(eventHandlers[i]);
}
};
var stopEventHandlers = function() {
var i;
for (i = 0; i < eventHandlers.length; i++) {
stopEventHandler(eventHandlers[i]);
}
};
var startEventHandler = function(handler) {
var fireEvent = function() {
if (! running) { return; }
var args = [].slice.call(arguments, 0);
eventQueue.queue(new EventQueueElement(handler, args));
if (! dispatchingEvents) {
dispatchingEvents = true;
setTimeout(dispatchEventsInQueue, 0);
}
//
// fixme: if we see too many events accumulating, throttle
// the ones that are marked as throttleable.
};
handler.eventSource.onStart(fireEvent);
};
var stopEventHandler = function(handler) {
handler.eventSource.onStop();
};
var dispatchEventsInQueue = function() { var dispatchEventsInQueue = function() {
// Apply all the events on the queue, call toDraw, and then stop. // Apply all the events on the queue, call toDraw, and then stop.
// If the world ever satisfies stopWhen, stop immediately and quit. // If the world ever satisfies stopWhen, stop immediately and quit.
@ -627,36 +674,8 @@
}) })
}; };
var startEventHandler = function(handler) {
var fireEvent = function() {
if (! running) { return; }
var args = [].slice.call(arguments, 0);
eventQueue.queue(new EventQueueElement(handler, args));
if (! dispatchingEvents) {
setTimeout(dispatchEventsInQueue, 0);
}
//
// fixme: if we see too many events accumulating, throttle
// the ones that are marked as throttleable.
};
handler.eventSource.onStart(fireEvent);
};
var stopEventHandler = function(handler) {
handler.eventSource.onStop();
};
view.initialRender(top); view.initialRender(top);
startEventHandlers();
var eventHandlers = filter(handlers, isEventHandler).concat(view.getEventHandlers());
var i;
for (i = 0; i < eventHandlers.length; i++) {
startEventHandler(eventHandlers[i]);
}
}); });
}; };
@ -675,6 +694,38 @@
// findDomNodeLocation: dom-node dom-node -> arrayof number
// Given a node, returns the child indices we need to follow to reach
// it from the top.
// Assumption: top must be an ancestor of the node. Otherwise, the
// result is partial.
var findDomNodeLocation = function(node, top) {
var locator = [];
var parent, i;
while(node !== top && node.parentNode !== null) {
parent = node.parentNode;
for (i = 0; i < parent.childNodes.length; i++) {
if (parent.childNodes[i] === node) {
locator.push(i);
break;
}
}
node = parent;
}
return locator.reverse();
};
var findNodeFromLocation = function(top, location) {
var i = 0;
var node = top;
for (i = 0; i < location.length; i++) {
node = node.childNodes[location[i]];
}
return node;
};
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
var checkReal = plt.baselib.check.checkReal; var checkReal = plt.baselib.check.checkReal;