diff options
-rw-r--r-- | conf/httpd.conf | 4 | ||||
-rw-r--r-- | web/build/YAHOO.js | 63 | ||||
-rw-r--r-- | web/build/animation.js | 907 | ||||
-rw-r--r-- | web/build/dom.js | 433 | ||||
-rw-r--r-- | web/build/dragdrop-debug.js | 2517 | ||||
-rw-r--r-- | web/build/dragdrop.js | 2426 | ||||
-rw-r--r-- | web/build/event.js | 901 | ||||
-rwxr-xr-x | web/confirm.cgi | 8 | ||||
-rwxr-xr-x | web/contact.cgi | 6 | ||||
-rw-r--r-- | web/css.css | 7 | ||||
-rwxr-xr-x | web/index.cgi | 67 |
11 files changed, 51 insertions, 7288 deletions
diff --git a/conf/httpd.conf b/conf/httpd.conf index d151abcfa..55a5a8087 100644 --- a/conf/httpd.conf +++ b/conf/httpd.conf @@ -20,7 +20,7 @@ # Copyright (c) 2006 UK Citizens Online Democracy. All rights reserved. # Email: francis@mysociety.org; WWW: http://www.mysociety.org # -# $Id: httpd.conf,v 1.3 2006-09-25 22:59:06 matthew Exp $ +# $Id: httpd.conf,v 1.4 2006-09-27 23:51:40 matthew Exp $ DirectoryIndex index.cgi @@ -28,7 +28,7 @@ RewriteEngine on #RewriteLog /var/log/apache/rewrite.log #RewriteLogLevel 3 -RewriteRule ^/[Cc]/([0-9A-Za-z]{16}).*$ /confirm.cgi?type=comment;token=$1 +RewriteRule ^/[Cc]/([0-9A-Za-z]{16}).*$ /confirm.cgi?type=update;token=$1 RewriteRule ^/[Pp]/([0-9A-Za-z]{16}).*$ /confirm.cgi?type=problem;token=$1 # CGI files can be referred without CGI diff --git a/web/build/YAHOO.js b/web/build/YAHOO.js deleted file mode 100644 index 33e3ff47d..000000000 --- a/web/build/YAHOO.js +++ /dev/null @@ -1,63 +0,0 @@ -/* -Copyright (c) 2006 Yahoo! Inc. All rights reserved. -version 0.9.0 -*/ - -/** - * @class The Yahoo global namespace - */ -var YAHOO = function() { - - return { - - /** - * Yahoo presentation platform utils namespace - */ - util: {}, - - /** - * Yahoo presentation platform widgets namespace - */ - widget: {}, - - /** - * Yahoo presentation platform examples namespace - */ - example: {}, - - /** - * Returns the namespace specified and creates it if it doesn't exist - * - * YAHOO.namespace("property.package"); - * YAHOO.namespace("YAHOO.property.package"); - * - * Either of the above would create YAHOO.property, then - * YAHOO.property.package - * - * @param {String} sNameSpace String representation of the desired - * namespace - * @return {Object} A reference to the namespace object - */ - namespace: function( sNameSpace ) { - - if (!sNameSpace || !sNameSpace.length) { - return null; - } - - var levels = sNameSpace.split("."); - - var currentNS = YAHOO; - - // YAHOO is implied, so it is ignored if it is included - for (var i=(levels[0] == "YAHOO") ? 1 : 0; i<levels.length; ++i) { - currentNS[levels[i]] = currentNS[levels[i]] || {}; - currentNS = currentNS[levels[i]]; - } - - return currentNS; - - } - }; - -} (); - diff --git a/web/build/animation.js b/web/build/animation.js deleted file mode 100644 index 05c92eede..000000000 --- a/web/build/animation.js +++ /dev/null @@ -1,907 +0,0 @@ -/*
-Copyright (c) 2006 Yahoo! Inc. All rights reserved.
-version 0.9.0
-*/
-
-/**
- *
- * Base class for animated DOM objects.
- * @class Base animation class that provides the interface for building animated effects.
- * <p>Usage: var myAnim = new YAHOO.util.Anim(el, { width: { from: 10, to: 100 } }, 1, YAHOO.util.Easing.easeOut);</p>
- * @requires YAHOO.util.AnimMgr
- * @requires YAHOO.util.Easing
- * @requires YAHOO.util.Dom
- * @requires YAHOO.util.Event
- * @constructor
- * @param {HTMLElement | String} el Reference to the element that will be animated
- * @param {Object} attributes The attribute(s) to be animated.
- * Each attribute is an object with at minimum a "to" or "by" member defined.
- * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").
- * All attribute names use camelCase.
- * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
- * @param {Function} method (optional, defaults to YAHOO.util.Easing.easeNone) Computes the values that are applied to the attributes per frame (generally a YAHOO.util.Easing method)
- */
-
-YAHOO.util.Anim = function(el, attributes, duration, method)
-{
- if (el) {
- this.init(el, attributes, duration, method);
- }
-};
-
-YAHOO.util.Anim.prototype = {
- /**
- * Returns the value computed by the animation's "method".
- * @param {String} attribute The name of the attribute.
- * @param {Number} start The value this attribute should start from for this animation.
- * @param {Number} end The value this attribute should end at for this animation.
- * @return {Number} The Value to be applied to the attribute.
- */
- doMethod: function(attribute, start, end) {
- return this.method(this.currentFrame, start, end - start, this.totalFrames);
- },
-
- /**
- * Applies a value to an attribute
- * @param {String} attribute The name of the attribute.
- * @param {Number} val The value to be applied to the attribute.
- * @param {String} unit The unit ('px', '%', etc.) of the value.
- */
- setAttribute: function(attribute, val, unit) {
- YAHOO.util.Dom.setStyle(this.getEl(), attribute, val + unit);
- },
-
- /**
- * Returns current value of the attribute.
- * @param {String} attribute The name of the attribute.
- * @return {Number} val The current value of the attribute.
- */
- getAttribute: function(attribute) {
- return parseFloat( YAHOO.util.Dom.getStyle(this.getEl(), attribute));
- },
-
- /**
- * Per attribute units that should be used by default.
- * @type {Object}
- */
- defaultUnits: {
- opacity: ' '
- },
-
- /**
- * The default unit to use for all attributes if not defined per attribute.
- * @type {String}
- */
- defaultUnit: 'px',
-
- /**
- * @param {HTMLElement | String} el Reference to the element that will be animated
- * @param {Object} attributes The attribute(s) to be animated.
- * Each attribute is an object with at minimum a "to" or "by" member defined.
- * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").
- * All attribute names use camelCase.
- * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
- * @param {Function} method (optional, defaults to YAHOO.util.Easing.easeNone) Computes the values that are applied to the attributes per frame (generally a YAHOO.util.Easing method)
- */
- init: function(el, attributes, duration, method) {
-
- /**
- * Whether or not the animation is running.
- * @private
- * @type {Boolen}
- */
- var isAnimated = false;
-
- /**
- * A Date object that is created when the animation begins.
- * @private
- * @type {Date}
- */
- var startTime = null;
-
- /**
- * A Date object that is created when the animation ends.
- * @private
- * @type {Date}
- */
- var endTime = null;
-
- /**
- * The number of frames this animation was able to execute.
- * @private
- * @type {Int}
- */
- var actualFrames = 0;
-
- /**
- * The attribute values that will be used if no "from" is supplied.
- * @private
- * @type {Object}
- */
- var defaultValues = {};
-
- /**
- * The element to be animated.
- * @private
- * @type {HTMLElement}
- */
- el = YAHOO.util.Dom.get(el);
-
- /**
- * The collection of attributes to be animated.
- * Each attribute must have at least a "to" or "by" defined in order to animate.
- * If "to" is supplied, the animation will end with the attribute at that value.
- * If "by" is supplied, the animation will end at that value plus its starting value.
- * If both are supplied, "to" is used, and "by" is ignored.
- * Optional additional member include "from" (the value the attribute should start animating from, defaults to current value), and "unit" (the units to apply to the values).
- * @type {Object}
- */
- this.attributes = attributes || {};
-
- /**
- * The length of the animation. Defaults to "1" (second).
- * @type {Number}
- */
- this.duration = duration || 1;
-
- /**
- * The method that will provide values to the attribute(s) during the animation.
- * Defaults to "YAHOO.util.Easing.easeNone".
- * @type {Function}
- */
- this.method = method || YAHOO.util.Easing.easeNone;
-
- /**
- * Whether or not the duration should be treated as seconds.
- * Defaults to true.
- * @type {Boolean}
- */
- this.useSeconds = true; // default to seconds
-
- /**
- * The location of the current animation on the timeline.
- * In time-based animations, this is used by AnimMgr to ensure the animation finishes on time.
- * @type {Int}
- */
- this.currentFrame = 0;
-
- /**
- * The total number of frames to be executed.
- * In time-based animations, this is used by AnimMgr to ensure the animation finishes on time.
- * @type {Int}
- */
- this.totalFrames = YAHOO.util.AnimMgr.fps;
-
-
- /**
- * Returns a reference to the animated element.
- * @return {HTMLElement}
- */
- this.getEl = function() { return el; };
-
-
- /**
- * Sets the default value to be used when "from" is not supplied.
- * @param {String} attribute The attribute being set.
- * @param {Number} val The default value to be applied to the attribute.
- */
- this.setDefault = function(attribute, val) {
- if ( val == 'auto' ) { // if 'auto' set defaults for well known attributes, zero for others
- switch(attribute) {
- case'width':
- val = el.clientWidth || el.offsetWidth; // computed width
- break;
- case 'height':
- val = el.clientHeight || el.offsetHeight; // computed height
- break;
- case 'left':
- if (YAHOO.util.Dom.getStyle(el, 'position') == 'absolute') {
- val = el.offsetLeft; // computed left
- } else {
- val = 0;
- }
- break;
- case 'top':
- if (YAHOO.util.Dom.getStyle(el, 'position') == 'absolute') {
- val = el.offsetTop; // computed top
- } else {
- val = 0;
- }
- break;
- default:
- val = 0;
- }
- }
-
- defaultValues[attribute] = val;
- }
-
- /**
- * Returns the default value for the given attribute.
- * @param {String} attribute The attribute whose value will be returned.
- */
- this.getDefault = function(attribute) {
- return defaultValues[attribute];
- };
-
- /**
- * Checks whether the element is currently animated.
- * @return {Boolean} current value of isAnimated.
- */
- this.isAnimated = function() {
- return isAnimated;
- };
-
- /**
- * Returns the animation start time.
- * @return {Date} current value of startTime.
- */
- this.getStartTime = function() {
- return startTime;
- };
-
- /**
- * Starts the animation by registering it with the animation manager.
- */
- this.animate = function() {
- this.onStart.fire();
- this._onStart.fire();
-
- this.totalFrames = ( this.useSeconds ) ? Math.ceil(YAHOO.util.AnimMgr.fps * this.duration) : this.duration;
- YAHOO.util.AnimMgr.registerElement(this);
-
- // get starting values or use defaults
- var attributes = this.attributes;
- var el = this.getEl();
- var val;
-
- for (var attribute in attributes) {
- val = this.getAttribute(attribute);
- this.setDefault(attribute, val);
- }
-
- isAnimated = true;
- actualFrames = 0;
- startTime = new Date();
- };
-
- /**
- * Stops the animation. Normally called by AnimMgr when animation completes.
- */
- this.stop = function() {
- this.currentFrame = 0;
-
- endTime = new Date();
-
- var data = {
- time: endTime,
- duration: endTime - startTime,
- frames: actualFrames,
- fps: actualFrames / this.duration
- };
-
- isAnimated = false;
- actualFrames = 0;
-
- this.onComplete.fire(data);
- };
-
- /**
- * Feeds the starting and ending values for each animated attribute to doMethod once per frame, then applies the resulting value to the attribute(s).
- * @private
- */
- var onTween = function() {
- var start;
- var end = null;
- var val;
- var unit;
- var attributes = this['attributes'];
-
- for (var attribute in attributes) {
- unit = attributes[attribute]['unit'] || this.defaultUnits[attribute] || this.defaultUnit;
-
- if (typeof attributes[attribute]['from'] != 'undefined') {
- start = attributes[attribute]['from'];
- } else {
- start = this.getDefault(attribute);
- }
-
- // To beats by, per SMIL 2.1 spec
- if (typeof attributes[attribute]['to'] != 'undefined') {
- end = attributes[attribute]['to'];
- } else if (typeof attributes[attribute]['by'] != 'undefined') {
- end = start + attributes[attribute]['by'];
- }
-
- // if end is null, dont change value
- if (end !== null && typeof end != 'undefined') {
-
- val = this.doMethod(attribute, start, end);
-
- // negative not allowed for these (others too, but these are most common)
- if ( (attribute == 'width' || attribute == 'height' || attribute == 'opacity') && val < 0 ) {
- val = 0;
- }
-
- this.setAttribute(attribute, val, unit);
- }
- }
-
- actualFrames += 1;
- };
-
- /**
- * Custom event that fires after onStart, useful in subclassing
- * @private
- */
- this._onStart = new YAHOO.util.CustomEvent('_onStart', this);
-
- /**
- * Custom event that fires when animation begins
- * Listen via subscribe method
- */
- this.onStart = new YAHOO.util.CustomEvent('start', this);
-
- /**
- * Custom event that fires between each frame
- * Listen via subscribe method
- */
- this.onTween = new YAHOO.util.CustomEvent('tween', this);
-
- /**
- * Custom event that fires after onTween
- * @private
- */
- this._onTween = new YAHOO.util.CustomEvent('_tween', this);
-
- /**
- * Custom event that fires when animation ends
- * Listen via subscribe method
- */
- this.onComplete = new YAHOO.util.CustomEvent('complete', this);
-
- this._onTween.subscribe(onTween);
- }
-};
-
-/**
- * @class Handles animation queueing and threading.
- * Used by Anim and subclasses.
- */
-YAHOO.util.AnimMgr = new function() {
- /**
- * Reference to the animation Interval
- * @private
- * @type Int
- */
- var thread = null;
-
- /**
- * The current queue of registered animation objects.
- * @private
- * @type Array
- */
- var queue = [];
-
- /**
- * The number of active animations.
- * @private
- * @type Int
- */
- var tweenCount = 0;
-
- /**
- * Base frame rate (frames per second).
- * Arbitrarily high for better x-browser calibration (slower browsers drop more frames).
- * @type Int
- *
- */
- this.fps = 200;
-
- /**
- * Interval delay in milliseconds, defaults to fastest possible.
- * @type Int
- *
- */
- this.delay = 1;
-
- /**
- * Adds an animation instance to the animation queue.
- * All animation instances must be registered in order to animate.
- * @param {object} tween The Anim instance to be be registered
- */
- this.registerElement = function(tween) {
- if ( tween.isAnimated() ) { return false; }// but not if already animating
-
- queue[queue.length] = tween;
- tweenCount += 1;
-
- this.start();
- };
-
- /**
- * Starts the animation thread.
- * Only one thread can run at a time.
- */
- this.start = function() {
- if (thread === null) { thread = setInterval(this.run, this.delay); }
- };
-
- /**
- * Stops the animation thread or a specific animation instance.
- * @param {object} tween A specific Anim instance to stop (optional)
- * If no instance given, Manager stops thread and all animations.
- */
- this.stop = function(tween) {
- if (!tween)
- {
- clearInterval(thread);
- for (var i = 0, len = queue.length; i < len; ++i) {
- if (queue[i].isAnimated()) {
- queue[i].stop();
- }
- }
- queue = [];
- thread = null;
- tweenCount = 0;
- }
- else {
- tween.stop();
- tweenCount -= 1;
-
- if (tweenCount <= 0) { this.stop(); }
- }
- };
-
- /**
- * Called per Interval to handle each animation frame.
- */
- this.run = function() {
- for (var i = 0, len = queue.length; i < len; ++i) {
- var tween = queue[i];
- if ( !tween || !tween.isAnimated() ) { continue; }
-
- if (tween.currentFrame < tween.totalFrames || tween.totalFrames === null)
- {
- tween.currentFrame += 1;
-
- if (tween.useSeconds) {
- correctFrame(tween);
- }
-
- tween.onTween.fire();
- tween._onTween.fire();
- }
- else { YAHOO.util.AnimMgr.stop(tween); }
- }
- };
-
- /**
- * On the fly frame correction to keep animation on time.
- * @private
- * @param {Object} tween The Anim instance being corrected.
- */
- var correctFrame = function(tween) {
- var frames = tween.totalFrames;
- var frame = tween.currentFrame;
- var expected = (tween.currentFrame * tween.duration * 1000 / tween.totalFrames);
- var elapsed = (new Date() - tween.getStartTime());
- var tweak = 0;
-
- if (elapsed < tween.duration * 1000) { // check if falling behind
- tweak = Math.round((elapsed / expected - 1) * tween.currentFrame);
- } else { // went over duration, so jump to end
- tweak = frames - (frame + 1);
- }
- if (tweak > 0 && isFinite(tweak)) { // adjust if needed
- if (tween.currentFrame + tweak >= frames) {// dont go past last frame
- tweak = frames - (frame + 1);
- }
-
- tween.currentFrame += tweak;
- }
- };
-}
-
-/**
- *
- * @class Used to calculate Bezier splines for any number of control points.
- *
- */
-YAHOO.util.Bezier = new function()
-{
- /**
- * Get the current position of the animated element based on t.
- * @param {array} points An array containing Bezier points.
- * Each point is an array of "x" and "y" values (0 = x, 1 = y)
- * At least 2 points are required (start and end).
- * First point is start. Last point is end.
- * Additional control points are optional.
- * @param {float} t Basis for determining current position (0 < t < 1)
- * @return {object} An object containing int x and y member data
- */
- this.getPosition = function(points, t)
- {
- var n = points.length;
- var tmp = [];
-
- for (var i = 0; i < n; ++i){
- tmp[i] = [points[i][0], points[i][1]]; // save input
- }
-
- for (var j = 1; j < n; ++j) {
- for (i = 0; i < n - j; ++i) {
- tmp[i][0] = (1 - t) * tmp[i][0] + t * tmp[parseInt(i + 1, 10)][0];
- tmp[i][1] = (1 - t) * tmp[i][1] + t * tmp[parseInt(i + 1, 10)][1];
- }
- }
-
- return [ tmp[0][0], tmp[0][1] ];
-
- };
-};
-
-/**
- * @class Class for defining the acceleration rate and path of animations.
- */
-YAHOO.util.Easing = new function() {
-
- /**
- * Uniform speed between points.
- * @param {Number} t Time value used to compute current value.
- * @param {Number} b Starting value.
- * @param {Number} c Delta between start and end values.
- * @param {Number} d Total length of animation.
- * @return {Number} The computed value for the current animation frame.
- */
- this.easeNone = function(t, b, c, d) {
- return b+c*(t/=d);
- };
-
- /**
- * Begins slowly and accelerates towards end.
- * @param {Number} t Time value used to compute current value.
- * @param {Number} b Starting value.
- * @param {Number} c Delta between start and end values.
- * @param {Number} d Total length of animation.
- * @return {Number} The computed value for the current animation frame.
- */
- this.easeIn = function(t, b, c, d) {
- return b+c*((t/=d)*t*t);
- };
-
- /**
- * Begins quickly and decelerates towards end.
- * @param {Number} t Time value used to compute current value.
- * @param {Number} b Starting value.
- * @param {Number} c Delta between start and end values.
- * @param {Number} d Total length of animation.
- * @return {Number} The computed value for the current animation frame.
- */
- this.easeOut = function(t, b, c, d) {
- var ts=(t/=d)*t;
- var tc=ts*t;
- return b+c*(tc + -3*ts + 3*t);
- };
-
- /**
- * Begins slowly and decelerates towards end.
- * @param {Number} t Time value used to compute current value.
- * @param {Number} b Starting value.
- * @param {Number} c Delta between start and end values.
- * @param {Number} d Total length of animation.
- * @return {Number} The computed value for the current animation frame.
- */
- this.easeBoth = function(t, b, c, d) {
- var ts=(t/=d)*t;
- var tc=ts*t;
- return b+c*(-2*tc + 3*ts);
- };
-
- /**
- * Begins by going below staring value.
- * @param {Number} t Time value used to compute current value.
- * @param {Number} b Starting value.
- * @param {Number} c Delta between start and end values.
- * @param {Number} d Total length of animation.
- * @return {Number} The computed value for the current animation frame.
- */
- this.backIn = function(t, b, c, d) {
- var ts=(t/=d)*t;
- var tc=ts*t;
- return b+c*(-3.4005*tc*ts + 10.2*ts*ts + -6.2*tc + 0.4*ts);
- };
-
- /**
- * End by going beyond ending value.
- * @param {Number} t Time value used to compute current value.
- * @param {Number} b Starting value.
- * @param {Number} c Delta between start and end values.
- * @param {Number} d Total length of animation.
- * @return {Number} The computed value for the current animation frame.
- */
- this.backOut = function(t, b, c, d) {
- var ts=(t/=d)*t;
- var tc=ts*t;
- return b+c*(8.292*tc*ts + -21.88*ts*ts + 22.08*tc + -12.69*ts + 5.1975*t);
- };
-
- /**
- * Starts by going below staring value, and ends by going beyond ending value.
- * @param {Number} t Time value used to compute current value.
- * @param {Number} b Starting value.
- * @param {Number} c Delta between start and end values.
- * @param {Number} d Total length of animation.
- * @return {Number} The computed value for the current animation frame.
- */
- this.backBoth = function(t, b, c, d) {
- var ts=(t/=d)*t;
- var tc=ts*t;
- return b+c*(0.402*tc*ts + -2.1525*ts*ts + -3.2*tc + 8*ts + -2.05*t);
- };
-};
-
-/**
- * @class Anim subclass for moving elements along a path defined by the "points" member of "attributes". All "points" are arrays with x, y coordinates.
- * <p>Usage: <code>var myAnim = new YAHOO.util.Motion(el, { points: { to: [800, 800] } }, 1, YAHOO.util.Easing.easeOut);</code></p>
- * @requires YAHOO.util.Anim
- * @requires YAHOO.util.AnimMgr
- * @requires YAHOO.util.Easing
- * @requires YAHOO.util.Bezier
- * @requires YAHOO.util.Dom
- * @requires YAHOO.util.Event
- * @constructor
- * @param {HTMLElement | String} el Reference to the element that will be animated
- * @param {Object} attributes The attribute(s) to be animated.
- * Each attribute is an object with at minimum a "to" or "by" member defined.
- * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").
- * All attribute names use camelCase.
- * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
- * @param {Function} method (optional, defaults to YAHOO.util.Easing.easeNone) Computes the values that are applied to the attributes per frame (generally a YAHOO.util.Easing method)
- */
-YAHOO.util.Motion = function(el, attributes, duration, method) {
- if (el) {
- this.initMotion(el, attributes, duration, method);
- }
-};
-
-YAHOO.util.Motion.prototype = new YAHOO.util.Anim();
-
-/**
- * Per attribute units that should be used by default.
- * Motion points default to 'px' units.
- * @type Object
- */
-YAHOO.util.Motion.prototype.defaultUnits.points = 'px';
-
-/**
- * Returns the value computed by the animation's "method".
- * @param {String} attribute The name of the attribute.
- * @param {Number} start The value this attribute should start from for this animation.
- * @param {Number} end The value this attribute should end at for this animation.
- * @return {Number} The Value to be applied to the attribute.
- */
-YAHOO.util.Motion.prototype.doMethod = function(attribute, start, end) {
- var val = null;
-
- if (attribute == 'points') {
- var translatedPoints = this.getTranslatedPoints();
- var t = this.method(this.currentFrame, 0, 100, this.totalFrames) / 100;
-
- if (translatedPoints) {
- val = YAHOO.util.Bezier.getPosition(translatedPoints, t);
- }
-
- } else {
- val = this.method(this.currentFrame, start, end - start, this.totalFrames);
- }
-
- return val;
-};
-
-/**
- * Returns current value of the attribute.
- * @param {String} attribute The name of the attribute.
- * @return {Number} val The current value of the attribute.
- */
-YAHOO.util.Motion.prototype.getAttribute = function(attribute) {
- var val = null;
-
- if (attribute == 'points') {
- val = [ this.getAttribute('left'), this.getAttribute('top') ];
- if ( isNaN(val[0]) ) { val[0] = 0; }
- if ( isNaN(val[1]) ) { val[1] = 0; }
- } else {
- val = parseFloat( YAHOO.util.Dom.getStyle(this.getEl(), attribute) );
- }
-
- return val;
-};
-
-/**
- * Applies a value to an attribute
- * @param {String} attribute The name of the attribute.
- * @param {Number} val The value to be applied to the attribute.
- * @param {String} unit The unit ('px', '%', etc.) of the value.
- */
-YAHOO.util.Motion.prototype.setAttribute = function(attribute, val, unit) {
- if (attribute == 'points') {
- YAHOO.util.Dom.setStyle(this.getEl(), 'left', val[0] + unit);
- YAHOO.util.Dom.setStyle(this.getEl(), 'top', val[1] + unit);
- } else {
- YAHOO.util.Dom.setStyle(this.getEl(), attribute, val + unit);
- }
-};
-
-/**
- * @param {HTMLElement | String} el Reference to the element that will be animated
- * @param {Object} attributes The attribute(s) to be animated.
- * Each attribute is an object with at minimum a "to" or "by" member defined.
- * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").
- * All attribute names use camelCase.
- * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
- * @param {Function} method (optional, defaults to YAHOO.util.Easing.easeNone) Computes the values that are applied to the attributes per frame (generally a YAHOO.util.Easing method)
- */
-YAHOO.util.Motion.prototype.initMotion = function(el, attributes, duration, method) {
- YAHOO.util.Anim.call(this, el, attributes, duration, method);
-
- attributes = attributes || {};
- attributes.points = attributes.points || {};
- attributes.points.control = attributes.points.control || [];
-
- this.attributes = attributes;
-
- var start;
- var end = null;
- var translatedPoints = null;
-
- this.getTranslatedPoints = function() { return translatedPoints; };
-
- var translateValues = function(val, self) {
- var pageXY = YAHOO.util.Dom.getXY(self.getEl());
- val = [ val[0] - pageXY[0] + start[0], val[1] - pageXY[1] + start[1] ];
-
- return val;
- };
-
- var onStart = function() {
- start = this.getAttribute('points');
- var attributes = this.attributes;
- var control = attributes['points']['control'] || [];
-
- if (control.length > 0 && control[0].constructor != Array) { // could be single point or array of points
- control = [control];
- }
-
- if (YAHOO.util.Dom.getStyle(this.getEl(), 'position') == 'static') { // default to relative
- YAHOO.util.Dom.setStyle(this.getEl(), 'position', 'relative');
- }
-
- if (typeof attributes['points']['from'] != 'undefined') {
- YAHOO.util.Dom.setXY(this.getEl(), attributes['points']['from']); // set to from point
- start = this.getAttribute('points'); // get actual offset values
- }
- else if ((start[0] === 0 || start[1] === 0)) { // these sometimes up when auto
- YAHOO.util.Dom.setXY(this.getEl(), YAHOO.util.Dom.getXY(this.getEl())); // set it to current position, giving offsets
- start = this.getAttribute('points'); // get actual offset values
- }
-
- var i, len;
- // TO beats BY, per SMIL 2.1 spec
- if (typeof attributes['points']['to'] != 'undefined') {
- end = translateValues(attributes['points']['to'], this);
-
- for (i = 0, len = control.length; i < len; ++i) {
- control[i] = translateValues(control[i], this);
- }
-
- } else if (typeof attributes['points']['by'] != 'undefined') {
- end = [ start[0] + attributes['points']['by'][0], start[1] + attributes['points']['by'][1]];
-
- for (i = 0, len = control.length; i < len; ++i) {
- control[i] = [ start[0] + control[i][0], start[1] + control[i][1] ];
- }
- }
-
- if (end) {
- translatedPoints = [start];
-
- if (control.length > 0) { translatedPoints = translatedPoints.concat(control); }
-
- translatedPoints[translatedPoints.length] = end;
- }
- };
-
- this._onStart.subscribe(onStart);
-};
-
-/**
- * @class Anim subclass for scrolling elements to a position defined by the "scroll" member of "attributes". All "scroll" members are arrays with x, y scroll positions.
- * <p>Usage: <code>var myAnim = new YAHOO.util.Scroll(el, { scroll: { to: [0, 800] } }, 1, YAHOO.util.Easing.easeOut);</code></p>
- * @requires YAHOO.util.Anim
- * @requires YAHOO.util.AnimMgr
- * @requires YAHOO.util.Easing
- * @requires YAHOO.util.Bezier
- * @requires YAHOO.util.Dom
- * @requires YAHOO.util.Event
- * @constructor
- * @param {HTMLElement | String} el Reference to the element that will be animated
- * @param {Object} attributes The attribute(s) to be animated.
- * Each attribute is an object with at minimum a "to" or "by" member defined.
- * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").
- * All attribute names use camelCase.
- * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
- * @param {Function} method (optional, defaults to YAHOO.util.Easing.easeNone) Computes the values that are applied to the attributes per frame (generally a YAHOO.util.Easing method)
- */
-YAHOO.util.Scroll = function(el, attributes, duration, method) {
- if (el) {
- YAHOO.util.Anim.call(this, el, attributes, duration, method);
- }
-};
-
-YAHOO.util.Scroll.prototype = new YAHOO.util.Anim();
-
-/**
- * Per attribute units that should be used by default.
- * Scroll positions default to no units.
- * @type Object
- */
-YAHOO.util.Scroll.prototype.defaultUnits.scroll = ' ';
-
-/**
- * Returns the value computed by the animation's "method".
- * @param {String} attribute The name of the attribute.
- * @param {Number} start The value this attribute should start from for this animation.
- * @param {Number} end The value this attribute should end at for this animation.
- * @return {Number} The Value to be applied to the attribute.
- */
-YAHOO.util.Scroll.prototype.doMethod = function(attribute, start, end) {
- var val = null;
-
- if (attribute == 'scroll') {
- val = [
- this.method(this.currentFrame, start[0], end[0] - start[0], this.totalFrames),
- this.method(this.currentFrame, start[1], end[1] - start[1], this.totalFrames)
- ];
-
- } else {
- val = this.method(this.currentFrame, start, end - start, this.totalFrames);
- }
- return val;
-}
-
-/**
- * Returns current value of the attribute.
- * @param {String} attribute The name of the attribute.
- * @return {Number} val The current value of the attribute.
- */
-YAHOO.util.Scroll.prototype.getAttribute = function(attribute) {
- var val = null;
- var el = this.getEl();
-
- if (attribute == 'scroll') {
- val = [ el.scrollLeft, el.scrollTop ];
- } else {
- val = parseFloat( YAHOO.util.Dom.getStyle(el, attribute) );
- }
-
- return val;
-};
-
-/**
- * Applies a value to an attribute
- * @param {String} attribute The name of the attribute.
- * @param {Number} val The value to be applied to the attribute.
- * @param {String} unit The unit ('px', '%', etc.) of the value.
- */
-YAHOO.util.Scroll.prototype.setAttribute = function(attribute, val, unit) {
- var el = this.getEl();
-
- if (attribute == 'scroll') {
- el.scrollLeft = val[0];
- el.scrollTop = val[1];
- } else {
- YAHOO.util.Dom.setStyle(el, attribute, val + unit);
- }
-};
-
diff --git a/web/build/dom.js b/web/build/dom.js deleted file mode 100644 index acea31f0d..000000000 --- a/web/build/dom.js +++ /dev/null @@ -1,433 +0,0 @@ -/*
-Copyright (c) 2006 Yahoo! Inc. All rights reserved.
-version 0.9.0
-*/
-
-/**
- * @class Provides helper methods for DOM elements.
- */
-YAHOO.util.Dom = new function() {
-
- /**
- * Returns an HTMLElement reference
- * @param {String | HTMLElement} Accepts either a string to use as an ID for getting a DOM reference, or an actual DOM reference.
- * @return {HTMLElement} A DOM reference to an HTML element.
- */
- this.get = function(el) {
- if (typeof el == 'string') { // accept object or id
- el = document.getElementById(el);
- }
-
- return el;
- };
-
- /**
- * Normalizes currentStyle and ComputedStyle.
- * @param {String | HTMLElement} Accepts either a string to use as an ID for getting a DOM reference, or an actual DOM reference.
- * @param {String} property The style property whose value is returned.
- * @return {String} The current value of the style property.
- */
- this.getStyle = function(el, property) {
- var value = null;
- var dv = document.defaultView;
-
- el = this.get(el);
-
- if (property == 'opacity' && el.filters) {// IE opacity
- value = 1;
- try {
- value = el.filters.item('DXImageTransform.Microsoft.Alpha').opacity / 100;
- } catch(e) {
- try {
- value = el.filters.item('alpha').opacity / 100;
- } catch(e) {}
- }
- }
- else if (el.style[property]) {
- value = el.style[property];
- }
- else if (el.currentStyle && el.currentStyle[property]) {
- value = el.currentStyle[property];
- }
- else if ( dv && dv.getComputedStyle )
- { // convert camelCase to hyphen-case
-
- var converted = '';
- for(i = 0, len = property.length;i < len; ++i) {
- if (property.charAt(i) == property.charAt(i).toUpperCase()) {
- converted = converted + '-' + property.charAt(i).toLowerCase();
- } else {
- converted = converted + property.charAt(i);
- }
- }
-
- if (dv.getComputedStyle(el, '').getPropertyValue(converted)) {
- value = dv.getComputedStyle(el, '').getPropertyValue(converted);
- }
- }
-
- return value;
- };
-
- /**
- * Wrapper for setting style properties of HTMLElements. Normalizes "opacity" across modern browsers.
- * @param {String | HTMLElement} Accepts either a string to use as an ID for getting a DOM reference, or an actual DOM reference.
- * @param {String} property The style property to be set.
- * @param {String} val The value to apply to the given property.
- */
- this.setStyle = function(el, property, val) {
- el = this.get(el);
- switch(property) {
- case 'opacity' :
- if (el.filters) {
- el.style.filter = 'alpha(opacity=' + val * 100 + ')';
-
- if (!el.currentStyle.hasLayout) {
- el.style.zoom = 1;
- }
- } else {
- el.style.opacity = val;
- el.style['-moz-opacity'] = val;
- el.style['-khtml-opacity'] = val;
- }
- break;
- default :
- el.style[property] = val;
- }
- };
-
- /**
- * Gets the current position of an element based on page coordinates. Element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
- * @param {String | HTMLElement} Accepts either a string to use as an ID for getting a DOM reference, or an actual DOM reference.
- */
- this.getXY = function(el) {
- el = this.get(el);
-
- // has to be part of document to have pageXY
- if (el.parentNode === null || this.getStyle(el, 'display') == 'none') {
- return false;
- }
-
- /**
- * Position of the html element (x, y)
- * @private
- * @type Array
- */
- var parent = null;
- var pos = [];
- var box;
-
- if (el.getBoundingClientRect) { // IE
- box = el.getBoundingClientRect();
- var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
- var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft;
-
- return [box.left + scrollLeft, box.top + scrollTop];
- }
- else if (document.getBoxObjectFor) { // gecko
- box = document.getBoxObjectFor(el);
- pos = [box.x, box.y];
- }
- else { // safari/opera
- pos = [el.offsetLeft, el.offsetTop];
- parent = el.offsetParent;
- if (parent != el) {
- while (parent) {
- pos[0] += parent.offsetLeft;
- pos[1] += parent.offsetTop;
- parent = parent.offsetParent;
- }
- }
-
- // opera & (safari absolute) incorrectly account for body offsetTop
- var ua = navigator.userAgent.toLowerCase();
- if (
- ua.indexOf('opera') != -1
- || ( ua.indexOf('safari') != -1 && this.getStyle(el, 'position') == 'absolute' )
- ) {
- pos[1] -= document.body.offsetTop;
- }
- }
-
- if (el.parentNode) { parent = el.parentNode; }
- else { parent = null; }
-
- while (parent && parent.tagName != 'BODY' && parent.tagName != 'HTML') {
- pos[0] -= parent.scrollLeft;
- pos[1] -= parent.scrollTop;
-
- if (parent.parentNode) { parent = parent.parentNode; }
- else { parent = null; }
- }
-
- return pos;
- };
-
- /**
- * Gets the current X position of an element based on page coordinates. The element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
- * @param {String | HTMLElement} Accepts either a string to use as an ID for getting a DOM reference, or an actual DOM reference.
- */
- this.getX = function(el) {
- return this.getXY(el)[0];
- };
-
- /**
- * Gets the current Y position of an element based on page coordinates. Element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
- * @param {String | HTMLElement} Accepts either a string to use as an ID for getting a DOM reference, or an actual DOM reference.
- */
- this.getY = function(el) {
- return this.getXY(el)[1];
- };
-
- /**
- * Set the position of an html element in page coordinates, regardless of how the element is positioned.
- * The element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
- * @param {String | HTMLElement} Accepts either a string to use as an ID for getting a DOM reference, or an actual DOM reference.
- * @param {array} pos Contains X & Y values for new position (coordinates are page-based)
- */
- this.setXY = function(el, pos, noRetry) {
- el = this.get(el);
- var pageXY = YAHOO.util.Dom.getXY(el);
- if (pageXY === false) { return false; } // has to be part of doc to have pageXY
-
- if (this.getStyle(el, 'position') == 'static') { // default to relative
- this.setStyle(el, 'position', 'relative');
- }
-
- var delta = [
- parseInt( YAHOO.util.Dom.getStyle(el, 'left'), 10 ),
- parseInt( YAHOO.util.Dom.getStyle(el, 'top'), 10 )
- ];
-
- if ( isNaN(delta[0]) ) { delta[0] = 0; } // defalts to 'auto'
- if ( isNaN(delta[1]) ) { delta[1] = 0; }
-
- if (pos[0] !== null) { el.style.left = pos[0] - pageXY[0] + delta[0] + 'px'; }
- if (pos[1] !== null) { el.style.top = pos[1] - pageXY[1] + delta[1] + 'px'; }
-
- var newXY = this.getXY(el);
-
- // if retry is true, try one more time if we miss
- if (!noRetry && (newXY[0] != pos[0] || newXY[1] != pos[1]) ) {
- this.setXY(el, pos, true);
- }
-
- return true;
- };
-
- /**
- * Set the X position of an html element in page coordinates, regardless of how the element is positioned.
- * The element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
- * @param {String | HTMLElement} Accepts either a string to use as an ID for getting a DOM reference, or an actual DOM reference.
- * @param {Int} x to use as the X coordinate.
- */
- this.setX = function(el, x) {
- return this.setXY(el, [x, null]);
- };
-
- /**
- * Set the Y position of an html element in page coordinates, regardless of how the element is positioned.
- * The element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
- * @param {String | HTMLElement} Accepts either a string to use as an ID for getting a DOM reference, or an actual DOM reference.
- * @param {Int} Value to use as the Y coordinate.
- */
- this.setY = function(el, y) {
- return this.setXY(el, [null, y]);
- };
-
- /**
- * Returns the region position of the given element.
- * The element must be part of the DOM tree to have a region (display:none or elements not appended return false).
- * @param {String | HTMLElement} Accepts either a string to use as an ID for getting a DOM reference, or an actual DOM reference.
- * @return {Region} A Region instance containing "top, left, bottom, right" member data.
- */
- this.getRegion = function(el) {
- el = this.get(el);
- return new YAHOO.util.Region.getRegion(el);
- };
-
- /**
- * Returns the width of the client (viewport).
- * @return {Int} The width of the viewable area of the page.
- */
- this.getClientWidth = function() {
- return (
- document.documentElement.offsetWidth
- || document.body.offsetWidth
- );
- };
-
- /**
- * Returns the height of the client (viewport).
- * @return {Int} The height of the viewable area of the page.
- */
- this.getClientHeight = function() {
- return (
- self.innerHeight
- || document.documentElement.clientHeight
- || document.body.clientHeight
- );
- };
-};
-
-/**
- * @class A region is a representation of an object on a grid. It is defined
- * by the top, right, bottom, left extents, so is rectangular by default. If
- * other shapes are required, this class could be extended to support it.
- *
- * @param {int} t the top extent
- * @param {int} r the right extent
- * @param {int} b the bottom extent
- * @param {int} l the left extent
- * @constructor
- */
-YAHOO.util.Region = function(t, r, b, l) {
-
- /**
- * The region's top extent
- * @type int
- */
- this.top = t;
-
- /**
- * The region's right extent
- * @type int
- */
- this.right = r;
-
- /**
- * The region's bottom extent
- * @type int
- */
- this.bottom = b;
-
- /**
- * The region's left extent
- * @type int
- */
- this.left = l;
-};
-
-/**
- * Returns true if this region contains the region passed in
- *
- * @param {Region} region The region to evaluate
- * @return {boolean} True if the region is contained with this region,
- * else false
- */
-YAHOO.util.Region.prototype.contains = function(region) {
- return ( region.left >= this.left &&
- region.right <= this.right &&
- region.top >= this.top &&
- region.bottom <= this.bottom );
-};
-
-/**
- * Returns the area of the region
- *
- * @return {int} the region's area
- */
-YAHOO.util.Region.prototype.getArea = function() {
- return ( (this.bottom - this.top) * (this.right - this.left) );
-};
-
-/**
- * Returns the region where the passed in region overlaps with this one
- *
- * @param {Region} region The region that intersects
- * @return {Region} The overlap region, or null if there is no overlap
- */
-YAHOO.util.Region.prototype.intersect = function(region) {
- var t = Math.max( this.top, region.top );
- var r = Math.min( this.right, region.right );
- var b = Math.min( this.bottom, region.bottom );
- var l = Math.max( this.left, region.left );
-
- if (b >= t && r >= l) {
- return new YAHOO.util.Region(t, r, b, l);
- } else {
- return null;
- }
-};
-
-/**
- * Returns the region representing the smallest region that can contain both
- * the passed in region and this region.
- *
- * @param {Region} region The region that to create the union with
- * @return {Region} The union region
- */
-YAHOO.util.Region.prototype.union = function(region) {
- var t = Math.min( this.top, region.top );
- var r = Math.max( this.right, region.right );
- var b = Math.max( this.bottom, region.bottom );
- var l = Math.min( this.left, region.left );
-
- return new YAHOO.util.Region(t, r, b, l);
-};
-
-/**
- * toString
- * @return string the region properties
- */
-YAHOO.util.Region.prototype.toString = function() {
- return ( "Region {" +
- " t: " + this.top +
- ", r: " + this.right +
- ", b: " + this.bottom +
- ", l: " + this.left +
- "}" );
-}
-
-/**
- * Returns a region that is occupied by the DOM element
- *
- * @param {HTMLElement} el The element
- * @return {Region} The region that the element occupies
- * @static
- */
-YAHOO.util.Region.getRegion = function(el) {
- var p = YAHOO.util.Dom.getXY(el);
-
- var t = p[1];
- var r = p[0] + el.offsetWidth;
- var b = p[1] + el.offsetHeight;
- var l = p[0];
-
- return new YAHOO.util.Region(t, r, b, l);
-};
-
-/////////////////////////////////////////////////////////////////////////////
-
-
-/**
- * @class
- *
- * A point is a region that is special in that it represents a single point on
- * the grid.
- *
- * @param {int} x The X position of the point
- * @param {int} y The Y position of the point
- * @constructor
- * @extends Region
- */
-YAHOO.util.Point = function(x, y) {
- /**
- * The X position of the point
- * @type int
- */
- this.x = x;
-
- /**
- * The Y position of the point
- * @type int
- */
- this.y = y;
-
- this.top = y;
- this.right = x;
- this.bottom = y;
- this.left = x;
-};
-
-YAHOO.util.Point.prototype = new YAHOO.util.Region();
diff --git a/web/build/dragdrop-debug.js b/web/build/dragdrop-debug.js deleted file mode 100644 index 25d1c3c3d..000000000 --- a/web/build/dragdrop-debug.js +++ /dev/null @@ -1,2517 +0,0 @@ -/* -Copyright (c) 2006 Yahoo! Inc. All rights reserved. -version 0.9.0 -*/ - -/** - * @class Defines the interface and base operation of items that that can be - * dragged or can be drop targets. It was designed to be extended, overriding - * the event handlers for startDrag, onDrag, onDragOver, onDragOut. - * Up to three html elements can be associated with a DragDrop instance: - * <ul> - * <li>linked element: the element that is passed into the constructor. - * This is the element which defines the boundaries for interaction with - * other DragDrop objects.</li> - * <li>handle element(s): The drag operation only occurs if the element that - * was clicked matches a handle element. By default this is the linked - * element, but there are times that you will want only a portion of the - * linked element to initiate the drag operation, and the setHandleElId() - * method provides a way to define this.</li> - * <li>drag element: this represents an the element that would be moved along - * with the cursor during a drag operation. By default, this is the linked - * element itself as in {@link YAHOO.util.DD}. setDragElId() lets you define - * a separate element that would be moved, as in {@link YAHOO.util.DDProxy} - * </li> - * </ul> - * This class should not be instantiated until the onload event to ensure that - * the associated elements are available. - * The following would define a DragDrop obj that would interact with any - * other * DragDrop obj in the "group1" group: - * <pre> - * dd = new YAHOO.util.DragDrop("div1", "group1"); - * </pre> - * Since none of the event handlers have been implemented, nothing would - * actually happen if you were to run the code above. Normally you would - * override this class or one of the default implementations, but you can - * also override the methods you want on an instance of the class... - * <pre> - * dd.onDragDrop = function(e, id) { - * alert("dd was dropped on " + id); - * } - * </pre> - * @constructor - * @param {String} id of the element that is linked to this instance - * @param {String} sGroup the group of related DragDrop objects - */ -YAHOO.util.DragDrop = function(id, sGroup) { - if (id) { - this.init(id, sGroup); - } -}; - -YAHOO.util.DragDrop.prototype = { - - /** - * The id of the element associated with this object. This is what we - * refer to as the "linked element" because the size and position of - * this element is used to determine when the drag and drop objects have - * interacted. - * - * @type String - */ - id: null, - - /** - * The id of the element that will be dragged. By default this is same - * as the linked element , but could be changed to another element. Ex: - * YAHOO.util.DDProxy - * - * @type String - * @private - */ - dragElId: null, - - /** - * the id of the element that initiates the drag operation. By default - * this is the linked element, but could be changed to be a child of this - * element. This lets us do things like only starting the drag when the - * header element within the linked html element is clicked. - * - * @type String - * @private - */ - handleElId: null, - - /** - * An array of HTML tags that will be ignored if clicked. - */ - invalidHandleTypes: null, - - /** - * The linked element's absolute X position at the time the drag was - * started - * - * @type int - * @private - */ - startPageX: 0, - - /** - * The linked element's absolute X position at the time the drag was - * started - * - * @type int - * @private - */ - startPageY: 0, - - /** - * The group defines a logical collection of DragDrop objects that are - * related. Instances only get events when interacting with other - * DragDrop object in the same group. This lets us define multiple - * groups using a single DragDrop subclass if we want. - * - */ - groups: null, - - /** - * Individual drag/drop instances can be locked. This will prevent - * onmousedown start drag. - * - * @type boolean - * @private - */ - locked: false, - - /** - * Lock this instance - */ - lock: function() { this.locked = true; }, - - /** - * Unlock this instace - */ - unlock: function() { this.locked = false; }, - - /** - * By default, all insances can be a drop target. This can be disabled by - * setting isTarget to false. - * - * @type boolean - */ - isTarget: true, - - /** - * The padding configured for this drag and drop object for calculating - * the drop zone intersection with this object. - */ - padding: null, - - /** - * @private - */ - _domRef: null, - - /** - * Internal typeof flag - * @private - */ - __ygDragDrop: true, - - /** - * Set to true when horizontal contraints are applied - * - * @type boolean - * @private - */ - constrainX: false, - - /** - * Set to true when vertical contraints are applied - * - * @type boolean - * @private - */ - constrainY: false, - - /** - * The left constraint - * - * @type int - * @private - */ - minX: 0, - - /** - * The right constraint - * - * @type int - * @private - */ - maxX: 0, - - /** - * The up constraint - * - * @type int - * @private - */ - minY: 0, - - /** - * The down constraint - * - * @type int - * @private - */ - maxY: 0, - - /** - * Maintain offsets when we resetconstraints. Used to maintain the - * slider thumb value, and this needs to be fixed. - * @type boolean - */ - maintainOffset: false, - - /** - * Array of pixel locations the element will snap to if we specified a - * horizontal graduation/interval. This array is generated automatically - * when you define a tick interval. - * @type int[] - */ - xTicks: null, - - /** - * Array of pixel locations the element will snap to if we specified a - * vertical graduation/interval. This array is generated automatically - * when you define a tick interval. - * @type int[] - */ - yTicks: null, - - /** - * By default the drag and drop instance will only respond to the primary - * button click (left button for a right-handed mouse). Set to true to - * allow drag and drop to start with any mouse click that is propogated - * by the browser - * @type boolean - */ - primaryButtonOnly: true, - - /** - * Code that executes immediately before the startDrag event - * @private - */ - b4StartDrag: function(x, y) { }, - - /** - * Abstract method called after a drag/drop object is clicked - * and the drag or mousedown time thresholds have beeen met. - * - * @param {int} X click location - * @param {int} Y click location - */ - startDrag: function(x, y) { /* override this */ }, - - /** - * Code that executes immediately before the onDrag event - * @private - */ - b4Drag: function(e) { }, - - /** - * Abstract method called during the onMouseMove event while dragging an - * object. - * - * @param {Event} e - */ - onDrag: function(e) { /* override this */ }, - - /** - * Code that executes immediately before the onDragEnter event - * @private - */ - // b4DragEnter: function(e) { }, - - /** - * Abstract method called when this element fist begins hovering over - * another DragDrop obj - * - * @param {Event} e - * @param {String || YAHOO.util.DragDrop[]} id In POINT mode, the element - * id this is hovering over. In INTERSECT mode, an array of one or more - * dragdrop items being hovered over. - */ - onDragEnter: function(e, id) { /* override this */ }, - - /** - * Code that executes immediately before the onDragOver event - * @private - */ - b4DragOver: function(e) { }, - - /** - * Abstract method called when this element is hovering over another - * DragDrop obj - * - * @param {Event} e - * @param {String || YAHOO.util.DragDrop[]} id In POINT mode, the element - * id this is hovering over. In INTERSECT mode, an array of dd items - * being hovered over. - */ - onDragOver: function(e, id) { /* override this */ }, - - /** - * Code that executes immediately before the onDragOut event - * @private - */ - b4DragOut: function(e) { }, - - /** - * Abstract method called when we are no longer hovering over an element - * - * @param {Event} e - * @param {String || YAHOO.util.DragDrop[]} id In POINT mode, the element - * id this was hovering over. In INTERSECT mode, an array of dd items - * that the mouse is no longer over. - */ - onDragOut: function(e, id) { /* override this */ }, - - /** - * Code that executes immediately before the onDragDrop event - * @private - */ - b4DragDrop: function(e) { }, - - /** - * Abstract method called when this item is dropped on another DragDrop - * obj - * - * @param {Event} e - * @param {String || YAHOO.util.DragDrop[]} id In POINT mode, the element - * id this was dropped on. In INTERSECT mode, an array of dd items this - * was dropped on. - */ - onDragDrop: function(e, id) { /* override this */ }, - - /** - * Code that executes immediately before the endDrag event - * @private - */ - b4EndDrag: function(e) { }, - - /** - * Fired when we are done dragging the object - * - * @param {Event} e - */ - endDrag: function(e) { /* override this */ }, - - /** - * Code executed immediately before the onMouseDown event - - * @param {Event} e - * @private - */ - b4MouseDown: function(e) { }, - - /** - * Event handler that fires when a drag/drop obj gets a mousedown - * @param {Event} e - */ - onMouseDown: function(e) { /* override this */ }, - - /** - * Event handler that fires when a drag/drop obj gets a mouseup - * @param {Event} e - */ - onMouseUp: function(e) { /* override this */ }, - - /** - * Returns a reference to the linked element - * - * @return {Object} the html element - */ - getEl: function() { - if (!this._domRef) { - this._domRef = this.DDM.getElement(this.id); - } - - return this._domRef; - }, - - /** - * Returns a reference to the actual element to drag. By default this is - * the same as the html element, but it can be assigned to another - * element. An example of this can be found in YAHOO.util.DDProxy - * - * @return {Object} the html element - */ - getDragEl: function() { - return this.DDM.getElement(this.dragElId); - }, - - /** - * Sets up the DragDrop object. Must be called in the constructor of any - * YAHOO.util.DragDrop subclass - * - * @param id the id of the linked element - * @param {String} sGroup the group of related items - * element is supposed to be a target only, set to false. - */ - init: function(id, sGroup) { - this.initTarget(id, sGroup); - YAHOO.util.Event.addListener(id, "mousedown", - this.handleMouseDown, this, true); - }, - - /** - * Initializes Targeting functionality only... the object does not - * get a mousedown handler. - * - * @param id the id of the linked element - * @param {String} sGroup the group of related items - * element is supposed to be a target only, set to false. - */ - initTarget: function(id, sGroup) { - - // create a local reference to the drag and drop manager - this.DDM = YAHOO.util.DDM; - - // create a logger instance - this.logger = new ygLogger("DragDrop"); - - // set the default padding - this.padding = [0, 0, 0, 0]; - - // initialize the groups array - this.groups = {}; - - // set the id - this.id = id; - - // the element is a drag handle by default - this.setDragElId(id); - - // by default, clicked anchors will not start drag operations - this.invalidHandleTypes = {a : "a"}; - - // We don't want to register this as the handle with the manager - // so we just set the id rather than calling the setter - this.handleElId = id; - - // cache the position of the element if we can - if (document && document.body) { - this.setInitPosition(); - } - - // add to an interaction group - this.addToGroup((sGroup) ? sGroup : "default"); - - }, - - /** - * Configures the padding for the target zone in px. Effectively expands - * (or reduces) the virtual object size for targeting calculations. - * Supports css-style shorthand; if only one parameter is passed, all sides - * will have that padding, and if only two are passed, the top and bottom - * will have the first param, the left and right the second. - * @param {int} iTop Top pad - * @param {int} iRight Right pad - * @param {int} iBot Bot pad - * @param {int} iLeft Left pad - */ - setPadding: function(iTop, iRight, iBot, iLeft) { - // this.padding = [iLeft, iRight, iTop, iBot]; - if (!iRight && 0 !== iRight) { - this.padding = [iTop, iTop, iTop, iTop]; - } else if (!iBot && 0 !== iBot) { - this.padding = [iTop, iRight, iTop, iRight]; - } else { - this.padding = [iTop, iRight, iBot, iLeft]; - } - }, - - /** - * Stores the initial placement of the dd element - */ - setInitPosition: function(diffX, diffY) { - var el = this.getEl(); - - if (!this.DDM.verifyEl(el)) { - this.logger.debug(this.id + " element is broken"); - return; - } - - var dx = diffX || 0; - var dy = diffY || 0; - - var p = YAHOO.util.Dom.getXY( el ); - - this.initPageX = p[0] - dx; - this.initPageY = p[1] - dy; - - this.lastPageX = p[0]; - this.lastPageY = p[1]; - - this.setStartPosition(p); - }, - - /** - * Sets the start position of the element. This is set when the obj - * is initialized, the reset when a drag is started. - * @param pos current position (from previous lookup) - * @private - */ - setStartPosition: function(pos) { - - var p = pos || YAHOO.util.Dom.getXY( this.getEl() ); - - this.startPageX = p[0]; - this.startPageY = p[1]; - }, - - /** - * Add this instance to a group of related drag/drop objects. All - * instances belong to at least one group, and can belong to as many - * groups as needed. - * - * @param sGroup {string} the name of the group - */ - addToGroup: function(sGroup) { - this.groups[sGroup] = true; - this.DDM.regDragDrop(this, sGroup); - }, - - /** - * Allows you to specify that an element other than the linked element - * will be moved with the cursor during a drag - * - * @param id the id of the element that will be used to initiate the drag - */ - setDragElId: function(id) { - this.dragElId = id; - }, - - /** - * Allows you to specify a child of the linked element that should be - * used to initiate the drag operation. An example of this would be if - * you have a content div with text and links. Clicking anywhere in the - * content area would normally start the drag operation. Use this method - * to specify that an element inside of the content div is the element - * that starts the drag operation. - * - * @param id the id of the element that will be used to initiate the drag - */ - setHandleElId: function(id) { - this.handleElId = id; - this.DDM.regHandle(this.id, id); - }, - - /** - * Allows you to set an element outside of the linked element as a drag - * handle - */ - setOuterHandleElId: function(id) { - this.logger.debug("Adding outer handle event: " + id); - YAHOO.util.Event.addListener(id, "mousedown", - this.handleMouseDown, this, true); - this.setHandleElId(id); - }, - - /** - * Remove all drag and drop hooks for this element - */ - unreg: function() { - this.logger.debug("DragDrop obj cleanup " + this.id); - YAHOO.util.Event.removeListener(this.id, "mousedown", - this.handleMouseDown); - this._domRef = null; - this.DDM._remove(this); - }, - - /** - * Returns true if this instance is locked, or the drag drop mgr is locked - * (meaning that all drag/drop is disabled on the page.) - * - * @return {boolean} true if this obj or all drag/drop is locked, else - * false - */ - isLocked: function() { - return (this.DDM.isLocked() || this.locked); - }, - - /** - * Fired when this object is clicked - * - * @param {Event} e - * @param {YAHOO.util.DragDrop} oDD the clicked dd object (this dd obj) - * @private - */ - handleMouseDown: function(e, oDD) { - - this.logger.debug("isLocked: " + this.isLocked()); - - var EU = YAHOO.util.Event; - - - var button = e.which || e.button; - this.logger.debug("button: " + button); - - if (this.primaryButtonOnly && button > 1) { - this.logger.debug("Mousedown was not produced by the primary button"); - return; - } - - if (this.isLocked()) { - this.logger.debug("Drag and drop is disabled, aborting"); - return; - } - - this.logger.debug("mousedown " + this.id); - - this.DDM.refreshCache(this.groups); - - // Only process the event if we really clicked within the linked - // element. The reason we make this check is that in the case that - // another element was moved between the clicked element and the - // cursor in the time between the mousedown and mouseup events. When - // this happens, the element gets the next mousedown event - // regardless of where on the screen it happened. - var pt = new YAHOO.util.Point(EU.getPageX(e), EU.getPageY(e)); - if ( this.DDM.isOverTarget(pt, this) ) { - - this.logger.debug("click is legit"); - - // check to see if the handle was clicked - var srcEl = EU.getTarget(e); - - if (this.isValidHandleChild(srcEl) && - (this.id == this.handleElId || - this.DDM.handleWasClicked(srcEl, this.id)) ) { - - // set the initial element position - this.setStartPosition(); - - this.logger.debug("firing onMouseDown events"); - - - this.b4MouseDown(e); - this.onMouseDown(e); - this.DDM.handleMouseDown(e, this); - - this.DDM.stopEvent(e); - } - } - }, - - /** - * Allows you to specify a tag name that should not start a drag operation - * when clicked. This is designed to facilitate embedding links within a - * drag handle that do something other than start the drag. - * - * @param {string} tagName the type of element to exclude - */ - addInvalidHandleType: function(tagName) { - var type = tagName.toUpperCase(); - this.invalidHandleTypes[type] = type; - }, - - /** - * Unsets an excluded tag name set by addInvalidHandleType - * - * @param {string} tagName the type of element to unexclude - */ - removeInvalidHandleType: function(tagName) { - var type = tagName.toUpperCase(); - this.invalidHandleTypes[type] = null; - }, - - /** - * Checks the tag exclusion list to see if this click should be ignored - * - * @param {ygNode} node - * @return {boolean} true if this is a valid tag type, false if not - */ - isValidHandleChild: function(node) { - var type = node.nodeName; - - if (type == "#text") { - // this.logger.debug("text node, getting parent node type"); - type = node.parentNode.nodeName; - } - - return (!this.invalidHandleTypes[type]); - }, - - /** - * Create the array of horizontal tick marks if an interval was specified - * in setXConstraint(). - * - * @private - */ - setXTicks: function(iStartX, iTickSize) { - this.xTicks = []; - this.xTickSize = iTickSize; - - var tickMap = {}; - - for (var i = this.initPageX; i >= this.minX; i = i - iTickSize) { - if (!tickMap[i]) { - this.xTicks[this.xTicks.length] = i; - tickMap[i] = true; - } - } - - for (i = this.initPageX; i <= this.maxX; i = i + iTickSize) { - if (!tickMap[i]) { - this.xTicks[this.xTicks.length] = i; - tickMap[i] = true; - } - } - - this.xTicks.sort(this.DDM.numericSort) ; - this.logger.debug("xTicks: " + this.xTicks.join()); - }, - - /** - * Create the array of vertical tick marks if an interval was specified in - * setYConstraint(). - * - * @private - */ - setYTicks: function(iStartY, iTickSize) { - this.yTicks = []; - this.yTickSize = iTickSize; - - var tickMap = {}; - - for (var i = this.initPageY; i >= this.minY; i = i - iTickSize) { - if (!tickMap[i]) { - this.yTicks[this.yTicks.length] = i; - tickMap[i] = true; - } - } - - for (i = this.initPageY; i <= this.maxY; i = i + iTickSize) { - if (!tickMap[i]) { - this.yTicks[this.yTicks.length] = i; - tickMap[i] = true; - } - } - - this.yTicks.sort(this.DDM.numericSort) ; - this.logger.debug("yTicks: " + this.yTicks.join()); - }, - - /** - * By default, the element can be dragged any place on the screen. Use - * this method to limit the horizontal travel of the element. Pass in - * 0,0 for the parameters if you want to lock the drag to the y axis. - * - * @param {int} iLeft the number of pixels the element can move to the left - * @param {int} iRight the number of pixels the element can move to the - * right - * @param {int} iTickSize optional parameter for specifying that the - * element - * should move iTickSize pixels at a time. - */ - setXConstraint: function(iLeft, iRight, iTickSize) { - this.leftConstraint = iLeft; - this.rightConstraint = iRight; - - this.minX = this.initPageX - iLeft; - this.maxX = this.initPageX + iRight; - if (iTickSize) { this.setXTicks(this.initPageX, iTickSize); } - - this.constrainX = true; - this.logger.debug("initPageX:" + this.initPageX + " minX:" + this.minX + - " maxX:" + this.maxX); - }, - - /** - * By default, the element can be dragged any place on the screen. Set - * this to limit the vertical travel of the element. Pass in 0,0 for the - * parameters if you want to lock the drag to the x axis. - * - * @param {int} iUp the number of pixels the element can move up - * @param {int} iDown the number of pixels the element can move down - * @param {int} iTickSize optional parameter for specifying that the - * element should move iTickSize pixels at a time. - */ - setYConstraint: function(iUp, iDown, iTickSize) { - this.topConstraint = iUp; - this.bottomConstraint = iDown; - - this.minY = this.initPageY - iUp; - this.maxY = this.initPageY + iDown; - if (iTickSize) { this.setYTicks(this.initPageY, iTickSize); } - - this.constrainY = true; - - this.logger.debug("initPageY:" + this.initPageY + " minY:" + this.minY + - " maxY:" + this.maxY); - }, - - /** - * resetConstraints must be called if you manually reposition a dd element. - * @param {boolean} maintainOffset - */ - resetConstraints: function() { - - // this.logger.debug("init pagexy: " + this.initPageX + ", " + - // this.initPageY); - // this.logger.debug("last pagexy: " + this.lastPageX + ", " + - // this.lastPageY); - - // figure out how much this thing has moved - var dx = (this.maintainOffset) ? this.lastPageX - this.initPageX : 0; - var dy = (this.maintainOffset) ? this.lastPageY - this.initPageY : 0; - - // this.logger.debug("diff: " + dx + ", " + dy); - - // reset the initial location - this.setInitPosition(dx, dy); - - if (this.constrainX) { - this.setXConstraint( this.leftConstraint, - this.rightConstraint, - this.xTickSize ); - } - - if (this.constrainY) { - this.setYConstraint( this.topConstraint, - this.bottomConstraint, - this.yTickSize ); - } - }, - - /** - * Normally the drag element is moved pixel by pixel, but we can specify - * that it move a number of pixels at a time. This method resolves the - * location when we have it set up like this. - * - * @param {int} val where we want to place the object - * @param {int[]} tickArray sorted array of valid points - * @return {int} the closest tick - * @private - */ - getTick: function(val, tickArray) { - - if (!tickArray) { - // If tick interval is not defined, it is effectively 1 pixel, - // so we return the value passed to us. - return val; - } else if (tickArray[0] >= val) { - // The value is lower than the first tick, so we return the first - // tick. - return tickArray[0]; - } else { - for (var i = 0; i < tickArray.length; ++i) { - var next = i + 1; - if (tickArray[next] && tickArray[next] >= val) { - var diff1 = val - tickArray[i]; - var diff2 = tickArray[next] - val; - return (diff2 > diff1) ? tickArray[i] : tickArray[next]; - } - } - - // The value is larger than the last tick, so we return the last - // tick. - return tickArray[tickArray.length - 1]; - } - }, - - /** - * toString method - * @return {string} string representation of the dd obj - */ - toString: function(val, tickArray) { - return ("YAHOO.util.DragDrop {" + this.id + "}"); - } - -}; - -/* Copyright (c) 2006 Yahoo! Inc. All rights reserved. */ - -// Only load the library once. Rewriting the manager class would orphan -// existing drag and drop instances. -if (!YAHOO.util.DragDropMgr) { - - /** - * @class Handles the element interaction for all DragDrop items in the - * window. Generally, you will not call this class directly, but it does - * have helper methods that could be useful in your DragDrop - * implementations. This class should not be instantiated; all methods - * are are static. - * - * @constructor - */ - YAHOO.util.DragDropMgr = new function() { - - /** - * utility package shorthand - * @private - */ - var UTIL = YAHOO.util; - - /** - * Two dimensional Array of registered DragDrop objects. The first - * dimension is the DragDrop item group, the second the DragDrop - * object. - * - * @private - */ - this.ids = {}; - - /** - * Array of element ids defined as drag handles. Used to determine - * if the element that generated the mousedown event is actually the - * handle and not the html element itself. - * - * @private - */ - this.handleIds = {}; - - /** - * the DragDrop object that is currently being dragged - * - * @type DragDrop - * @private - **/ - this.dragCurrent = null; - - /** - * the DragDrop object(s) that are being hovered over - * - * @type Array - * @private - */ - this.dragOvers = {}; - - /** - * @private - */ - this.logger = null; - - /** - * the X distance between the cursor and the object being dragged - * - * @type int - * @private - */ - this.deltaX = 0; - - /** - * the Y distance between the cursor and the object being dragged - * - * @type int - * @private - */ - this.deltaY = 0; - - /** - * Flag to determine if we should prevent the default behavior of the - * events we define. By default this is true, but this can be set to - * false if you need the default behavior (not recommended) - * - * @type boolean - */ - this.preventDefault = true; - - /** - * Flag to determine if we should stop the propagation of the events - * we generate. This is true by default but you may want to set it to - * false if the html element contains other features that require the - * mouse click. - * - * @type boolean - */ - this.stopPropagation = true; - - /** - * @private - */ - this.initalized = false; - - /** - * All drag and drop can be disabled. - * - * @private - */ - this.locked = false; - - /** - * Called the first time an element is registered. - * - * @private - */ - this.init = function() { - this.logger = new ygLogger("DragDropMgr"); - }; - - /** - * In point mode, drag and drop interaction is defined by the - * location of the cursor during the drag/drop - * @type int - */ - this.POINT = 0; - - /** - * In intersect mode, drag and drop interactio nis defined by the - * overlap of two or more drag and drop objects. - * @type int - */ - this.INTERSECT = 1; - - /** - * The current drag and drop mode. Default it point mode - * @type int - */ - this.mode = this.POINT; - - /** - * Runs method on all drag and drop objects - * @private - */ - this._execOnAll = function(sMethod, args) { - for (var i in this.ids) { - for (var j in this.ids[i]) { - var oDD = this.ids[i][j]; - if (! this.isTypeOfDD(oDD)) { - continue; - } - oDD[sMethod].apply(oDD, args); - } - } - }; - - /** - * Drag and drop initialization. Sets up the global event handlers - * @private - */ - this._onLoad = function() { - - this._execOnAll("setInitPosition", []); - - this.logger = new ygLogger("DragDropMgr"); - this.logger.debug("DDM onload"); - - var EU = UTIL.Event; - - EU.addListener(document, "mouseup", this.handleMouseUp, this, true); - EU.addListener(document, "mousemove", this.handleMouseMove, this, true); - EU.addListener(window, "unload", this._onUnload, this, true); - EU.addListener(window, "resize", this._onResize, this, true); - // EU.addListener(window, "mouseout", this._test); - - this.initalized = true; - - }; - - /** - * Reset constraints on all drag and drop objs - * @private - */ - this._onResize = function(e) { - this.logger.debug("window resize"); - this._execOnAll("resetConstraints", []); - }; - - /** - * Lock all drag and drop functionality - */ - this.lock = function() { this.locked = true; }; - - /** - * Unlock all drag and drop functionality - */ - this.unlock = function() { this.locked = false; }; - - /** - * Is drag and drop locked? - * - * @return {boolean} True if drag and drop is locked, false otherwise. - */ - this.isLocked = function() { return this.locked; }; - - /** - * Location cache that is set for all drag drop objects when a drag is - * initiated, cleared when the drag is finished. - * - * @private - */ - this.locationCache = {}; - - /** - * Set useCache to false if you want to force object the lookup of each - * drag and drop linked element constantly during a drag. - * @type boolean - */ - this.useCache = true; - - /** - * The number of pixels that the mouse needs to move after the - * mousedown before the drag is initiated. Default=3; - * @type int - */ - this.clickPixelThresh = 3; - - /** - * The number of milliseconds after the mousedown event to initiate the - * drag if we don't get a mouseup event. Default=1000 - * @type int - */ - this.clickTimeThresh = 1000; - - /** - * Flag that indicates that either the drag pixel threshold or the - * mousdown time threshold has been met - * @type boolean - * @private - */ - this.dragThreshMet = false; - - /** - * Timeout used for the click time threshold - * @type Object - * @private - */ - this.clickTimeout = null; - - /** - * The X position of the mousedown event stored for later use when a - * drag threshold is met. - * @type int - * @private - */ - this.startX = 0; - - /** - * The Y position of the mousedown event stored for later use when a - * drag threshold is met. - * @type int - * @private - */ - this.startY = 0; - - /** - * Each DragDrop instance must be registered with the DragDropMgr. - * This is executed in ygDragDrop.init() - * - * @param {DragDrop} oDD the DragDrop object to register - * @param {String} sGroup the name of the group this element belongs to - */ - this.regDragDrop = function(oDD, sGroup) { - if (!this.initialized) { this.init(); } - - if (!this.ids[sGroup]) { - this.ids[sGroup] = {}; - } - this.ids[sGroup][oDD.id] = oDD; - }; - - /** - * Unregisters a drag and drop item. This is executed in - * ygDragDrop.unreg, use that method instead of calling this directly. - * @private - */ - this._remove = function(oDD) { - for (var g in oDD.groups) { - if (g && this.ids[g][oDD.id]) { - delete this.ids[g][oDD.id]; - } - } - delete this.handleIds[oDD.id]; - }; - - /** - * Each DragDrop handle element must be registered. This is done - * automatically when executing ygDragDrop.setHandleElId() - * - * @param {String} sDDId the DragDrop id this element is a handle for - * @param {String} sHandleId the id of the element that is the drag - * handle - */ - this.regHandle = function(sDDId, sHandleId) { - if (!this.handleIds[sDDId]) { - this.handleIds[sDDId] = {}; - } - this.handleIds[sDDId][sHandleId] = sHandleId; - }; - - /** - * Utility function to determine if a given element has been - * registered as a drag drop item. - * - * @param {String} id the element id to check - * @return {boolean} true if this element is a DragDrop item, - * false otherwise - */ - this.isDragDrop = function(id) { - return ( this.getDDById(id) ) ? true : false; - }; - - /** - * Returns the drag and drop instances that are in all groups the - * passed in instance belongs to. - * - * @param {ygDragDrop} p_oDD the obj to get related data for - * @param {boolean} bTargetsOnly if true, only return targetable objs - * @return {ygDragDrop[]} the related instances - */ - this.getRelated = function(p_oDD, bTargetsOnly) { - var oDDs = []; - for (var i in p_oDD.groups) { - for (j in this.ids[i]) { - var dd = this.ids[i][j]; - if (! this.isTypeOfDD(dd)) { - continue; - } - if (!bTargetsOnly || dd.isTarget) { - oDDs[oDDs.length] = dd; - } - } - } - - return oDDs; - }; - - /** - * Returns true if the specified dd target is a legal target for - * the specifice drag obj - * - * @param {ygDragDrop} the drag obj - * @param {ygDragDrop) the target - * @return {boolean} true if the target is a legal target for the - * dd obj - */ - this.isLegalTarget = function (oDD, oTargetDD) { - var targets = this.getRelated(oDD); - for (var i =0;i<targets.length;++i) { - if (targets[i].id == oTargetDD.id) { - return true; - } - } - - return false; - }; - - /** - * My goal is to be able to transparently determine if an object is - * typeof ygDragDrop, and the exact subclass of ygDragDrop. typeof - * returns "object", oDD.constructor.toString() always returns - * "ygDragDrop" and not the name of the subclass. So for now it just - * evaluates a well-known variable in ygDragDrop. - * - * @param {Object} the object to evaluate - * @return {boolean} true if typeof oDD = ygDragDrop - */ - this.isTypeOfDD = function (oDD) { - return (oDD && oDD.__ygDragDrop); - }; - - /** - * Utility function to determine if a given element has been - * registered as a drag drop handle for the given Drag Drop object. - * - * @param {String} id the element id to check - * @return {boolean} true if this element is a DragDrop handle, false - * otherwise - */ - this.isHandle = function(sDDId, sHandleId) { - return ( this.handleIds[sDDId] && - this.handleIds[sDDId][sHandleId] ); - }; - - /** - * Returns the DragDrop instance for a given id - * - * @param {String} id the id of the DragDrop object - * @return {DragDrop} the drag drop object, null if it is not found - */ - this.getDDById = function(id) { - for (var i in this.ids) { - if (this.ids[i][id]) { - return this.ids[i][id]; - } - } - return null; - }; - - /** - * Fired after a registered DragDrop object gets the mousedown event. - * Sets up the events required to track the object being dragged - * - * @param {Event} e the event - * @param oDD the DragDrop object being dragged - * @private - */ - this.handleMouseDown = function(e, oDD) { - this.logger.debug("mousedown - adding event handlers"); - this.dragCurrent = oDD; - - var el = oDD.getEl(); - - // track start position - this.startX = UTIL.Event.getPageX(e); - this.startY = UTIL.Event.getPageY(e); - - this.deltaX = this.startX - el.offsetLeft; - this.deltaY = this.startY - el.offsetTop; - - this.dragThreshMet = false; - - this.clickTimeout = setTimeout( - "var DDM=YAHOO.util.DDM;DDM.startDrag(DDM.startX, DDM.startY)", - this.clickTimeThresh ); - }; - - /** - * Fired when either the drag pixel threshol or the mousedown hold - * time threshold has been met. - * - * @param x {int} the X position of the original mousedown - * @param y {int} the Y position of the original mousedown - */ - this.startDrag = function(x, y) { - this.logger.debug("firing drag start events"); - clearTimeout(this.clickTimeout); - if (this.dragCurrent) { - this.dragCurrent.b4StartDrag(x, y); - this.dragCurrent.startDrag(x, y); - } - this.dragThreshMet = true; - }; - - /** - * Internal function to handle the mouseup event. Will be invoked - * from the context of the document. - * - * @param {Event} e the event - * @private - */ - this.handleMouseUp = function(e) { - - if (! this.dragCurrent) { - return; - } - - clearTimeout(this.clickTimeout); - - if (this.dragThreshMet) { - this.logger.debug("mouseup detected - completing drag"); - this.fireEvents(e, true); - } else { - this.logger.debug("drag threshold not met"); - } - - this.stopDrag(e); - - this.stopEvent(e); - }; - - /** - * Utility to stop event propagation and event default, if these - * features are turned on. - * - * @param {Event} e the event as returned by this.getEvent() - */ - this.stopEvent = function(e) { - if (this.stopPropagation) { - UTIL.Event.stopPropagation(e); - } - - if (this.preventDefault) { - UTIL.Event.preventDefault(e); - } - }; - - /** - * Internal function to clean up event handlers after the drag - * operation is complete - * - * @param {Event} e the event - * @private - */ - this.stopDrag = function(e) { - // this.logger.debug("mouseup - removing event handlers"); - - // Fire the drag end event for the item that was dragged - if (this.dragCurrent) { - if (this.dragThreshMet) { - this.logger.debug("firing endDrag events"); - this.dragCurrent.b4EndDrag(e); - this.dragCurrent.endDrag(e); - } - - this.logger.debug("firing onMouseUp event"); - this.dragCurrent.onMouseUp(e); - } - - this.dragCurrent = null; - this.dragOvers = {}; - }; - - - /** - * Internal function to handle the mousemove event. Will be invoked - * from the context of the html element. - * - * @TODO figure out what we can do about mouse events lost when the - * user drags objects beyond the window boundary. Currently we can - * detect this in internet explorer by verifying that the mouse is - * down during the mousemove event. Firefox doesn't give us the - * button state on the mousemove event. - * - * @param {Event} e the event - * @private - */ - this.handleMouseMove = function(e) { - if (! this.dragCurrent) { - // this.logger.debug("no current drag obj"); - return; - } - - // var button = e.which || e.button; - - this.logger.debug("which: " + e.which + ", button: "+ e.button); - - - // check for IE mouseup outside of page boundary - if (UTIL.Event.isIE && !e.button) { - this.stopEvent(e); - return this.handleMouseUp(e); - // this.logger.debug("button failure"); - } - - if (!this.dragThreshMet) { - var diffX = Math.abs(this.startX - UTIL.Event.getPageX(e)); - var diffY = Math.abs(this.startY - UTIL.Event.getPageY(e)); - // this.logger.debug("diffX: " + diffX + "diffY: " + diffY); - if (diffX > this.clickPixelThresh || - diffY > this.clickPixelThresh) { - this.logger.debug("pixel threshold met"); - this.startDrag(this.startX, this.startY); - } - } - - if (this.dragThreshMet) { - this.dragCurrent.b4Drag(e); - this.dragCurrent.onDrag(e); - this.fireEvents(e, false); - } - - this.stopEvent(e); - }; - - /** - * Iterates over all of the DragDrop elements to find ones we are - * hovering over or dropping on - * - * @param {Event} e the event - * @param {boolean} isDrop is this a drop op or a mouseover op? - * @private - */ - this.fireEvents = function(e, isDrop) { - var dc = this.dragCurrent; - - // If the user did the mouse up outside of the window, we could - // get here even though we have ended the drag. - if (!dc || dc.isLocked()) { - return; - } - - var x = UTIL.Event.getPageX(e); - var y = UTIL.Event.getPageY(e); - var pt = new YAHOO.util.Point(x,y); - - // cache the previous dragOver array - var oldOvers = []; - - var outEvts = []; - var overEvts = []; - var dropEvts = []; - var enterEvts = []; - - // Check to see if the object we were hovering over is no longer - // being hovered over so we can fire the onDragOut event - for (var i in this.dragOvers) { - - var ddo = this.dragOvers[i]; - - if (! this.isTypeOfDD(ddo)) { - continue; - } - - if (! this.isOverTarget(pt, ddo, this.mode)) { - outEvts.push( ddo ); - } - - oldOvers[i] = true; - delete this.dragOvers[i]; - } - - for (var sGroup in dc.groups) { - // this.logger.debug("Processing group " + sGroup); - - if ("string" != typeof sGroup) { - continue; - } - - for (i in this.ids[sGroup]) { - var oDD = this.ids[sGroup][i]; - if (! this.isTypeOfDD(oDD)) { - continue; - } - - if (oDD.isTarget && !oDD.isLocked() && oDD != dc) { - if (this.isOverTarget(pt, oDD, this.mode)) { - // look for drop interactions - if (isDrop) { - dropEvts.push( oDD ); - // look for drag enter and drag over interactions - } else { - - // initial drag over: dragEnter fires - if (!oldOvers[oDD.id]) { - enterEvts.push( oDD ); - // subsequent drag overs: dragOver fires - } else { - overEvts.push( oDD ); - } - - this.dragOvers[oDD.id] = oDD; - } - } - } - } - } - - if (this.mode) { - if (outEvts.length > 0) { - dc.b4DragOut(e, outEvts); - dc.onDragOut(e, outEvts); - } - - if (enterEvts.length > 0) { - dc.onDragEnter(e, enterEvts); - } - - if (overEvts.length > 0) { - dc.b4DragOver(e, overEvts); - dc.onDragOver(e, overEvts); - } - - if (dropEvts.length > 0) { - dc.b4DragDrop(e, dropEvts); - dc.onDragDrop(e, dropEvts); - } - - } else { - // fire dragout events - for (i=0; i < outEvts.length; ++i) { - this.logger.debug(dc.id+" onDragOut: " + outEvts[i].id); - dc.b4DragOut(e, outEvts[i].id); - dc.onDragOut(e, outEvts[i].id); - } - - // fire enter events - for (i=0; i < enterEvts.length; ++i) { - this.logger.debug(dc.id + " dragEnter " + enterEvts[i].id); - // dc.b4DragEnter(e, oDD.id); - dc.onDragEnter(e, enterEvts[i].id); - } - - // fire over events - for (i=0; i < overEvts.length; ++i) { - this.logger.debug(dc.id + " dragOver " + overEvts[i].id); - dc.b4DragOver(e, overEvts[i].id); - dc.onDragOver(e, overEvts[i].id); - } - - // fire drop events - for (i=0; i < dropEvts.length; ++i) { - this.logger.debug(dc.id + " dragDrop " + dropEvts[i].id); - dc.b4DragDrop(e, dropEvts[i].id); - dc.onDragDrop(e, dropEvts[i].id); - } - - } - - }; - - /** - * Helper function for getting the best match from the list of drag - * and drop objects returned by the drag and drop events when we are - * in INTERSECT mode. It returns either the first object that the - * cursor is over, or the object that has the greatest overlap with - * the dragged element. - * - * @param {ygDragDrop[]} dds The array of drag and drop objects - * targeted - * @return {ygDragDrop} The best single match - */ - this.getBestMatch = function(dds) { - var winner = null; - // Return null if the input is not what we expect - //if (!dds || !dds.length || dds.length == 0) { - // winner = null; - // If there is only one item, it wins - //} else if (dds.length == 1) { - - if (dds.length == 1) { - winner = dds[0]; - } else { - // Loop through the targeted items - for (var i=0; i<dds.length; ++i) { - var dd = dds[i]; - // If the cursor is over the object, it wins. If the - // cursor is over multiple matches, the first one we come - // to wins. - if (dd.cursorIsOver) { - winner = dd; - break; - // Otherwise the object with the most overlap wins - } else { - if (!winner || - winner.overlap.getArea() < dd.overlap.getArea()) { - winner = dd; - } - } - } - } - - return winner; - }; - - /** - * Refreshes the cache of the top-left and bottom-right points of the - * drag and drop objects in the specified groups - * - * @param {Array} aGroups an associative array of groups to refresh - */ - this.refreshCache = function(aGroups) { - this.logger.debug("refreshing element location cache"); - for (sGroup in aGroups) { - if ("string" != typeof sGroup) { - continue; - } - for (i in this.ids[sGroup]) { - var oDD = this.ids[sGroup][i]; - - if (this.isTypeOfDD(oDD)) { - var loc = this.getLocation(oDD); - if (loc) { - this.locationCache[oDD.id] = loc; - } else { - delete this.locationCache[oDD.id]; - this.logger.debug("something is wrong with the element"); - // this will unregister the drag and drop object if - // the element is not in a usable state - oDD.unreg(); - } - } - } - } - }; - - /** - * This checks to make sure an element exists and is in the DOM. The - * main purpose is to handle cases where innerHTML is used to remove - * drag and drop objects from the DOM. IE provides an 'unspecified - * error' when trying to access the offsetParent of such an element - * @param {HTMLElement} el the element to check - * @return {boolean} true if the element looks usable - */ - this.verifyEl = function(el) { - try { - if (el) { - var parent = el.offsetParent; - if (parent) { - return true; - } - } - } catch(e) { - this.logger.debug("detected problem with an element"); - } - - return false; - }; - - /** - * Returns the an array containing the drag and drop element's position - * and size, including the ygDragDrop.padding configured for it - * - * @param {ygDragDrop} oDD the drag and drop object to get the - * location for - * @return array containing the top left and bottom right points of the - * element - */ - this.getLocation = function(oDD) { - if (! this.isTypeOfDD(oDD)) { - this.logger.debug(oDD + " is not a DD obj"); - return null; - } - - var el = oDD.getEl(); - - if (!this.verifyEl(el)) { - this.logger.debug(oDD + " element is not usable"); - return null; - } - - // this.logger.debug(oDD.id + " padding: " + oDD.padding); - - // var aPos = ygPos.getPos(el); - var aPos = YAHOO.util.Dom.getXY(el); - - x1 = aPos[0]; - x2 = x1 + el.offsetWidth; - - y1 = aPos[1]; - y2 = y1 + el.offsetHeight; - - var t = y1 - oDD.padding[0]; - var r = x2 + oDD.padding[1]; - var b = y2 + oDD.padding[2]; - var l = x1 - oDD.padding[3]; - - return new YAHOO.util.Region( t, r, b, l ); - - }; - - /** - * Checks the cursor location to see if it over the target - * - * @param {YAHOO.util.Point} pt The point to evaluate - * @param {ygDragDrop} oDDTarget the DragDrop object we are inspecting - * @return {boolean} true if the mouse is over the target - * @private - */ - this.isOverTarget = function(pt, oDDTarget, intersect) { - // use cache if available - var loc = this.locationCache[oDDTarget.id]; - if (!loc || !this.useCache) { - this.logger.debug("cache not populated"); - loc = this.getLocation(oDDTarget); - this.locationCache[oDDTarget.id] = loc; - - this.logger.debug("cache: " + loc); - } - - // this.logger.debug("isOverTarget: " + x + "," + y + ", " + loc); - - // var cursorIsOver = (x >= loc[3] && x <= loc[1] && y >= loc[0] && y <= loc[2]); - //oDDTarget.cursorIsOver = loc.contains( new YAHOO.util.Point(x, y) ); - oDDTarget.cursorIsOver = loc.contains( pt ); - oDDTarget.overlap = null; - - // if (this.INTERSECT == this.mode) { - if (intersect) { - - var curRegion = - YAHOO.util.Region.getRegion(this.dragCurrent.getDragEl()); - var overlap = curRegion.intersect(loc); - - if (overlap) { - oDDTarget.overlap = overlap; - return true; - } else { - return false; - } - - } else { - return oDDTarget.cursorIsOver; - } - }; - - /** - * @private - */ - this._onUnload = function(e, me) { - this.unregAll(); - }; - - /** - * Cleans up the drag and drop events and objects. - * - * @private - */ - this.unregAll = function() { - this.logger.debug("unregister all"); - - if (this.dragCurrent) { - this.stopDrag(); - this.dragCurrent = null; - } - - this._execOnAll("unreg", []); - - for (i in this.elementCache) { - delete this.elementCache[i]; - } - - this.elementCache = {}; - this.ids = {}; - }; - - /** - * A cache of DOM elements - * - * @private - */ - this.elementCache = {}; - - /** - * Get the wrapper for the DOM element specified - * - * @param {String} id the id of the elment to get - * @return {YAHOO.util.DDM.ElementWrapper} the wrapped element - * @private - */ - this.getElWrapper = function(id) { - var oWrapper = this.elementCache[id]; - if (!oWrapper || !oWrapper.el) { - // this.logger.debug("adding element cache: " + id); - oWrapper = this.elementCache[id] = - new this.ElementWrapper(document.getElementById(id)); - } - return oWrapper; - }; - - /** - * Returns the actual DOM element - * - * @param {String} id the id of the elment to get - * @return {Object} The element - */ - this.getElement = function(id) { - // return this.getElWrapper(id).el; - return document.getElementById(id); - }; - - /** - * Returns the style property for the DOM element (i.e., - * document.getElById(id).style) - * - * @param {String} id the id of the elment to get - * @return {Object} The style property of the element - */ - this.getCss = function(id) { - // return this.getElWrapper(id).css; - var css = null; - var el = document.getElementById(id); - if (el) { - css = el.style; - } - - return css; - }; - - /** - * Inner class for cached elements - */ - this.ElementWrapper = function(el) { - /** - * @private - */ - this.el = el || null; - /** - * @private - */ - this.id = this.el && el.id; - /** - * @private - */ - this.css = this.el && el.style; - }; - - /** - * Returns the X position of an html element - * @param el the element for which to get the position - * @return {int} the X coordinate - */ - this.getPosX = function(el) { - return YAHOO.util.Dom.getX(el); - }; - - /** - * Returns the Y position of an html element - * @param el the element for which to get the position - * @return {int} the Y coordinate - */ - this.getPosY = function(el) { - return YAHOO.util.Dom.getY(el); - }; - - /** - * Swap two nodes. In IE, we use the native method, for others we - * emulate the IE behavior - * - * @param n1 the first node to swap - * @param n2 the other node to swap - */ - this.swapNode = function(n1, n2) { - if (n1.swapNode) { - n1.swapNode(n2); - } else { - // the node reference order for the swap is a little tricky. - var p = n2.parentNode; - var s = n2.nextSibling; - n1.parentNode.replaceChild(n2,n1); - p.insertBefore(n1,s); - } - }; - - /** - * @private - */ - this.getScroll = function () { - var t, l; - if (document.documentElement && document.documentElement.scrollTop) { - t = document.documentElement.scrollTop; - l = document.documentElement.scrollLeft; - } else if (document.body) { - t = document.body.scrollTop; - l = document.body.scrollLeft; - } - return { top: t, left: l }; - }; - - /** - * Returns the specified element style property - * @param {HTMLElement} el the element - * @param {string} styleProp the style property - * @return {string} The value of the style property - */ - this.getStyle = function(el, styleProp) { - if (el.style.styleProp) { - return el.style.styleProp; - } else if (el.currentStyle) { - return el.currentStyle[styleProp]; - } else if (document.defaultView) { - return document.defaultView.getComputedStyle(el, null). - getPropertyValue(styleProp); - } - }; - - /** - * Gets the scrollTop - * - * @return {int} the document's scrollTop - */ - this.getScrollTop = function () { return this.getScroll().top; }; - - /** - * Gets the scrollLeft - * - * @return {int} the document's scrollTop - */ - this.getScrollLeft = function () { return this.getScroll().left; }; - - this.moveToEl = function (moveEl, targetEl) { - var aCoord = YAHOO.util.Dom.getXY(targetEl); - this.logger.debug("moveToEl: " + aCoord); - YAHOO.util.Dom.setXY(moveEl, aCoord); - }; - - /** - * Gets the client height - * - * @return {int} client height in px - */ - this.getClientHeight = function() { - return (window.innerHeight) ? window.innerHeight : - (document.documentElement && document.documentElement.clientHeight) ? - document.documentElement.clientHeight : document.body.offsetHeight; - }; - - /** - * Gets the client width - * - * @return {int} client width in px - */ - this.getClientWidth = function() { - return (window.innerWidth) ? window.innerWidth : - (document.documentElement && document.documentElement.clientWidth) ? - document.documentElement.clientWidth : document.body.offsetWidth; - }; - - /** - * numeric array sort function - */ - this.numericSort = function(a, b) { return (a - b); }; - - /** - * @private - */ - this._timeoutCount = 0; - - /** - * @private - * Trying to make the load order less important. Without this we get - * an error if this file is loaded before the Event Utility. - */ - this._addListeners = function() { - if ( UTIL.Event && - document && - document.body ) { - - this._onLoad(); - } else { - if (this._timeoutCount > 500) { - this.logger.debug("DragDrop requires the Event Utility"); - } else { - setTimeout("YAHOO.util.DDM._addListeners()", 10); - this._timeoutCount += 1; - } - } - - }; - - /** - * Recursively searches the immediate parent and all child nodes for - * the handle element in order to determine wheter or not it was - * clicked. - * - * @param node the html element to inspect - */ - this.handleWasClicked = function(node, id) { - if (this.isHandle(id, node.id)) { - this.logger.debug("clicked node is a handle"); - return true; - } else { - // check to see if this is a text node child of the one we want - var p = node.parentNode; - // this.logger.debug("p: " + p); - - while (p) { - if (this.isHandle(id, p.id)) { - return true; - } else { - this.logger.debug(p.id + " is not a handle"); - p = p.parentNode; - } - } - } - - return false; - }; - - }; - - // shorter alias, save a few bytes - YAHOO.util.DDM = YAHOO.util.DragDropMgr; - YAHOO.util.DDM._addListeners(); - -} - -/* Copyright (c) 2006 Yahoo! Inc. All rights reserved. */ - -/** - * @class a DragDrop implementation where the linked element follows the - * mouse cursor. - * - * @extends DragDrop - * @constructor - * @param {String} id the id of the linked element - * @param {String} sGroup the group of related DragDrop items - */ -YAHOO.util.DD = function(id, sGroup) { - if (id) { - this.init(id, sGroup); - this.logger.setModuleName("DD"); - } -}; - -YAHOO.util.DD.prototype = new YAHOO.util.DragDrop(); - -/** - * Should we auto-scroll? Defaults to true - * - * @type boolean - */ -YAHOO.util.DD.prototype.scroll = true; - -/** - * Sets the pointer offset to the distance between the linked element's top - * left corner and the location the element was clicked - * - * @param {int} iPageX the X coordinate of the click - * @param {int} iPageY the Y coordinate of the click - */ -YAHOO.util.DD.prototype.autoOffset = function(iPageX, iPageY) { - var el = this.getEl(); - var aCoord = YAHOO.util.Dom.getXY(el); - var x = iPageX - aCoord[0]; - var y = iPageY - aCoord[1]; - this.setDelta(x, y); - this.logger.debug("autoOffset el pos: " + aCoord + ", delta: " + x + "," + y); -}; - -/** - * Sets the pointer offset. You can call this directly to force the offset to - * be in a particular location (e.g., pass in 0,0 to set it to the center of the - * object, as done in ygDDSliderBG) - * - * @param {int} iDeltaX the distance from the left - * @param {int} iDeltaY the distance from the top - */ -YAHOO.util.DD.prototype.setDelta = function(iDeltaX, iDeltaY) { - this.deltaX = iDeltaX; - this.deltaY = iDeltaY; - this.logger.debug("deltaX:" + this.deltaX + ", deltaY:" + this.deltaY); -}; - -/** - * Sets the drag element to the location of the mousedown or click event, - * maintaining the cursor location relative to the location on the element - * that was clicked. Override this if you want to place the element in a - * location other than where the cursor is. - * - * @param {int} iPageX the X coordinate of the mousedown or drag event - * @param {int} iPageY the Y coordinate of the mousedown or drag event - */ - -YAHOO.util.DD.prototype.setDragElPos = function(iPageX, iPageY) { - this.alignElWithMouse(this.getDragEl(), iPageX, iPageY); -}; - -/** - * Sets the element to the location of the mousedown or click event, - * maintaining the cursor location relative to the location on the element - * that was clicked. Override this if you want to place the element in a - * location other than where the cursor is. - * - * @param {HTMLElement} el the element to move - * @param {int} iPageX the X coordinate of the mousedown or drag event - * @param {int} iPageY the Y coordinate of the mousedown or drag event - */ -YAHOO.util.DD.prototype.alignElWithMouse = function(el, iPageX, iPageY) { - var oCoord = this.getTargetCoord(iPageX, iPageY); - var aCoord = [oCoord.x, oCoord.y]; - // this.logger.debug("****alignElWithMouse : " + el.id + ", " + aCoord + ", " + el.style.display); - YAHOO.util.Dom.setXY(el, aCoord); - - this.cachePosition(oCoord.x, oCoord.y); - - this.autoScroll(oCoord.x, oCoord.y, el.offsetHeight, el.offsetWidth); -}; - -/** - * Saves the most recent position so that we can reset the constraints and - * tick marks on-demand. We need to know this so that we can calculate the - * number of pixels the element is offset from its original position. - */ -YAHOO.util.DD.prototype.cachePosition = function(iPageX, iPageY) { - if (iPageX) { - this.lastPageX = iPageX; - this.lastPageY = iPageY; - } else { - var aCoord = YAHOO.util.Dom.getXY(this.getEl()); - this.lastPageX = aCoord[0]; - this.lastPageY = aCoord[1]; - } -}; - -/** - * Auto-scroll the window if the dragged object has been moved beyond the - * visible window boundary. - * - * @param {int} x the drag element's x position - * @param {int} y the drag element's y position - * @param {int} h the height of the drag element - * @param {int} w the width of the drag element - * @private - */ -YAHOO.util.DD.prototype.autoScroll = function(x, y, h, w) { - - if (this.scroll) { - // The client height - var clientH = this.DDM.getClientHeight(); - - // The client width - var clientW = this.DDM.getClientWidth(); - - // The amt scrolled down - var st = this.DDM.getScrollTop(); - - // The amt scrolled right - var sl = this.DDM.getScrollLeft(); - - // Location of the bottom of the element - var bot = h + y; - - // Location of the right of the element - var right = w + x; - - // The distance from the cursor to the bottom of the visible area, - // adjusted so that we don't scroll if the cursor is beyond the - // element drag constraints - var toBot = (clientH + st - y - this.deltaY); - - // The distance from the cursor to the right of the visible area - var toRight = (clientW + sl - x - this.deltaX); - - // this.logger.debug( " x: " + x + " y: " + y + " h: " + h + - // " clientH: " + clientH + " clientW: " + clientW + - // " st: " + st + " sl: " + sl + " bot: " + bot + - // " right: " + right + " toBot: " + toBot + " toRight: " + toRight); - - // How close to the edge the cursor must be before we scroll - // var thresh = (document.all) ? 100 : 40; - var thresh = 40; - - // How many pixels to scroll per autoscroll op. This helps to reduce - // clunky scrolling. IE is more sensitive about this ... it needs this - // value to be higher. - var scrAmt = (document.all) ? 80 : 30; - - // Scroll down if we are near the bottom of the visible page and the - // obj extends below the crease - if ( bot > clientH && toBot < thresh ) { - window.scrollTo(sl, st + scrAmt); - } - - // Scroll up if the window is scrolled down and the top of the object - // goes above the top border - if ( y < st && st > 0 && y - st < thresh ) { - window.scrollTo(sl, st - scrAmt); - } - - // Scroll right if the obj is beyond the right border and the cursor is - // near the border. - if ( right > clientW && toRight < thresh ) { - window.scrollTo(sl + scrAmt, st); - } - - // Scroll left if the window has been scrolled to the right and the obj - // extends past the left border - if ( x < sl && sl > 0 && x - sl < thresh ) { - window.scrollTo(sl - scrAmt, st); - } - } -}; - -/** - * Finds the location the element should be placed if we want to move - * it to where the mouse location less the click offset would place us. - * - * @param {int} iPageX the X coordinate of the click - * @param {int} iPageY the Y coordinate of the click - * @return an object that contains the coordinates (Object.x and Object.y) - * @private - */ -YAHOO.util.DD.prototype.getTargetCoord = function(iPageX, iPageY) { - - // this.logger.debug("getTargetCoord: " + iPageX + ", " + iPageY); - - var x = iPageX - this.deltaX; - var y = iPageY - this.deltaY; - - if (this.constrainX) { - if (x < this.minX) { x = this.minX; } - if (x > this.maxX) { x = this.maxX; } - } - - if (this.constrainY) { - if (y < this.minY) { y = this.minY; } - if (y > this.maxY) { y = this.maxY; } - } - - x = this.getTick(x, this.xTicks); - y = this.getTick(y, this.yTicks); - - // this.logger.debug("getTargetCoord " + - // " iPageX: " + iPageX + - // " iPageY: " + iPageY + - // " x: " + x + ", y: " + y); - - return {x:x, y:y}; -}; - -// overrides YAHOO.util.DragDrop -YAHOO.util.DD.prototype.b4MouseDown = function(e) { - // this.resetConstraints(); - this.autoOffset(YAHOO.util.Event.getPageX(e), - YAHOO.util.Event.getPageY(e)); -}; - -// overrides YAHOO.util.DragDrop -YAHOO.util.DD.prototype.b4Drag = function(e) { - this.setDragElPos(YAHOO.util.Event.getPageX(e), - YAHOO.util.Event.getPageY(e)); -}; - - -/////////////////////////////////////////////////////////////////////////////// -// Debugging ygDragDrop events that can be overridden -/////////////////////////////////////////////////////////////////////////////// -/* -YAHOO.util.DD.prototype.startDrag = function(x, y) { - this.logger.debug(this.id.toString() + " startDrag"); -}; - -YAHOO.util.DD.prototype.onDrag = function(e) { - this.logger.debug(this.id.toString() + " onDrag"); -}; - -YAHOO.util.DD.prototype.onDragEnter = function(e, id) { - this.logger.debug(this.id.toString() + " onDragEnter: " + id); -}; - -YAHOO.util.DD.prototype.onDragOver = function(e, id) { - this.logger.debug(this.id.toString() + " onDragOver: " + id); -}; - -YAHOO.util.DD.prototype.onDragOut = function(e, id) { - this.logger.debug(this.id.toString() + " onDragOut: " + id); -}; - -YAHOO.util.DD.prototype.onDragDrop = function(e, id) { - this.logger.debug(this.id.toString() + " onDragDrop: " + id); -}; - -YAHOO.util.DD.prototype.endDrag = function(e) { - this.logger.debug(this.id.toString() + " endDrag"); -}; -*/ - -/* Copyright (c) 2006 Yahoo! Inc. All rights reserved. */ - -/** - * @class a DragDrop implementation that inserts an empty, bordered div into - * the document that follows the cursor during drag operations. At the time of - * the click, the frame div is resized to the dimensions of the linked html - * element, and moved to the exact location of the linked element. - * - * @extends YAHOO.util.DD - * @constructor - * @param {String} id the id of the linked html element - * @param {String} sGroup the group of related DragDrop objects - */ -YAHOO.util.DDProxy = function(id, sGroup) { - if (id) { - this.init(id, sGroup); - this.initFrame(); - this.logger.setModuleName("DDProxy"); - } -}; - -YAHOO.util.DDProxy.prototype = new YAHOO.util.DD(); - -/** - * A reference to the one div element we create for all instances of this class - * - * @type Object - */ -YAHOO.util.DDProxy.frameDiv = null; - -/** - * the drag frame div id - * - * @type String - */ -YAHOO.util.DDProxy.dragElId = "ygddfdiv"; - -/** - * The border width of the frame. This is used when we resize the frame to - * the size of the linked element. We substract the border width to make - * the div the correct size. - * - * @TODO find a better way to handle this - * - * @type int - */ -YAHOO.util.DDProxy.prototype.borderWidth = 2; - -/** - * By default we resize the drag frame to be the same size as the element - * we want to drag (this is to get the frame effect). We can turn it off - * if we want a different behavior (ex: ygDDMy2) - * - * @type boolean - */ -YAHOO.util.DDProxy.prototype.resizeFrame = true; - -/** - * By default the frame is positioned exactly where the drag element is, so - * we use the cursor offset provided by YAHOO.util.DD. Another option that works only if - * you do not have constraints on the obj is to have the drag frame centered - * around the cursor. Set centerFrame to true for this effect. Ex: - * ygDDMy2 - * - * @type boolean - */ -YAHOO.util.DDProxy.prototype.centerFrame = false; - -/** - * Create the drag frame if needed - */ -YAHOO.util.DDProxy.createFrame = function() { - var THIS = YAHOO.util.DDProxy; - - if (!document || !document.body) { - setTimeout(THIS.createFrame, 50); - return; - } - - if (!THIS.frameDiv) { - THIS.frameDiv = document.createElement("div"); - THIS.frameDiv.id = THIS.dragElId; - var s = THIS.frameDiv.style; - s.position = "absolute"; - s.visibility = "hidden"; - s.cursor = "move"; - s.border = "2px solid #aaa"; - s.zIndex = 999; - - document.body.appendChild(THIS.frameDiv); - } -}; - -/** - * Initialization for the drag frame element. Must be called in the - * constructor of all subclasses - */ -YAHOO.util.DDProxy.prototype.initFrame = function() { - YAHOO.util.DDProxy.createFrame(); - this.setDragElId(YAHOO.util.DDProxy.dragElId); - this.useAbsMath = true; -}; - -/** - * Resizes the drag frame to the dimensions of the clicked object, positions - * it over the object, and finally displays it - * - * @param {int} iPageX X click position - * @param {int} iPageY Y click position - * @private - */ -YAHOO.util.DDProxy.prototype.showFrame = function(iPageX, iPageY) { - var el = this.getEl(); - - var s = this.getDragEl().style; - - if (this.resizeFrame) { - s.width = (parseInt(el.offsetWidth) - (2*this.borderWidth)) + "px"; - s.height = (parseInt(el.offsetHeight) - (2*this.borderWidth)) + "px"; - } - - if (this.centerFrame) { - this.setDelta(Math.round(parseInt(s.width)/2), - Math.round(parseInt(s.width)/2)); - } - - this.setDragElPos(iPageX, iPageY); - - s.visibility = ""; -}; - -// overrides YAHOO.util.DragDrop -YAHOO.util.DDProxy.prototype.b4MouseDown = function(e) { - var x = YAHOO.util.Event.getPageX(e); - var y = YAHOO.util.Event.getPageY(e); - this.autoOffset(x, y); - this.setDragElPos(x, y); -}; - -// overrides YAHOO.util.DragDrop -YAHOO.util.DDProxy.prototype.b4StartDrag = function(x, y) { - // show the drag frame - this.logger.debug("start drag show frame, x: " + x + ", y: " + y); - this.showFrame(x, y); -}; - -// overrides YAHOO.util.DragDrop -YAHOO.util.DDProxy.prototype.b4EndDrag = function(e) { - this.logger.debug(this.id + " b4EndDrag"); - - // hide the drag frame - var s = this.getDragEl().style; - s.visibility = "hidden"; -}; - -// overrides YAHOO.util.DragDrop -// By default we try to move the element to the last location of the frame. -// This is so that the default behavior mirrors that of YAHOO.util.DD. -YAHOO.util.DDProxy.prototype.endDrag = function(e) { - this.logger.debug(this.id + " endDrag"); - var lel = this.getEl(); - var del = this.getDragEl(); - - // Show the drag frame briefly so we can get its position - del.style.visibility = ""; - - // Hide the linked element before the move to get around a Safari - // rendering bug. - lel.style.visibility = "hidden"; - YAHOO.util.DDM.moveToEl(lel, del); - del.style.visibility = "hidden"; - lel.style.visibility = ""; -}; - -/* Copyright (c) 2006 Yahoo! Inc. All rights reserved. */ - -/** - * @class a DragDrop implementation that does not move, but can be a drop - * target. You would get the same result by simply omitting implementation - * for the event callbacks, but this way we reduce the processing cost of the - * event listener and the callbacks. - * - * @extends YAHOO.util.DragDrop - * @constructor - * @param {String} id the id of the element that is a drop target - * @param {String} sGroup the group of related DragDrop objects - */ - -YAHOO.util.DDTarget = function(id, sGroup) { - if (id) { - this.initTarget(id, sGroup); - this.logger.setModuleName("DDTarget"); - } -}; - -YAHOO.util.DDTarget.prototype = new YAHOO.util.DragDrop(); - diff --git a/web/build/dragdrop.js b/web/build/dragdrop.js deleted file mode 100644 index 7d0e3e8ec..000000000 --- a/web/build/dragdrop.js +++ /dev/null @@ -1,2426 +0,0 @@ -/* -Copyright (c) 2006 Yahoo! Inc. All rights reserved. -version 0.9.0 -*/ - -/** - * @class Defines the interface and base operation of items that that can be - * dragged or can be drop targets. It was designed to be extended, overriding - * the event handlers for startDrag, onDrag, onDragOver, onDragOut. - * Up to three html elements can be associated with a DragDrop instance: - * <ul> - * <li>linked element: the element that is passed into the constructor. - * This is the element which defines the boundaries for interaction with - * other DragDrop objects.</li> - * <li>handle element(s): The drag operation only occurs if the element that - * was clicked matches a handle element. By default this is the linked - * element, but there are times that you will want only a portion of the - * linked element to initiate the drag operation, and the setHandleElId() - * method provides a way to define this.</li> - * <li>drag element: this represents an the element that would be moved along - * with the cursor during a drag operation. By default, this is the linked - * element itself as in {@link YAHOO.util.DD}. setDragElId() lets you define - * a separate element that would be moved, as in {@link YAHOO.util.DDProxy} - * </li> - * </ul> - * This class should not be instantiated until the onload event to ensure that - * the associated elements are available. - * The following would define a DragDrop obj that would interact with any - * other * DragDrop obj in the "group1" group: - * <pre> - * dd = new YAHOO.util.DragDrop("div1", "group1"); - * </pre> - * Since none of the event handlers have been implemented, nothing would - * actually happen if you were to run the code above. Normally you would - * override this class or one of the default implementations, but you can - * also override the methods you want on an instance of the class... - * <pre> - * dd.onDragDrop = function(e, id) { - * alert("dd was dropped on " + id); - * } - * </pre> - * @constructor - * @param {String} id of the element that is linked to this instance - * @param {String} sGroup the group of related DragDrop objects - */ -YAHOO.util.DragDrop = function(id, sGroup) { - if (id) { - this.init(id, sGroup); - } -}; - -YAHOO.util.DragDrop.prototype = { - - /** - * The id of the element associated with this object. This is what we - * refer to as the "linked element" because the size and position of - * this element is used to determine when the drag and drop objects have - * interacted. - * - * @type String - */ - id: null, - - /** - * The id of the element that will be dragged. By default this is same - * as the linked element , but could be changed to another element. Ex: - * YAHOO.util.DDProxy - * - * @type String - * @private - */ - dragElId: null, - - /** - * the id of the element that initiates the drag operation. By default - * this is the linked element, but could be changed to be a child of this - * element. This lets us do things like only starting the drag when the - * header element within the linked html element is clicked. - * - * @type String - * @private - */ - handleElId: null, - - /** - * An array of HTML tags that will be ignored if clicked. - */ - invalidHandleTypes: null, - - /** - * The linked element's absolute X position at the time the drag was - * started - * - * @type int - * @private - */ - startPageX: 0, - - /** - * The linked element's absolute X position at the time the drag was - * started - * - * @type int - * @private - */ - startPageY: 0, - - /** - * The group defines a logical collection of DragDrop objects that are - * related. Instances only get events when interacting with other - * DragDrop object in the same group. This lets us define multiple - * groups using a single DragDrop subclass if we want. - * - */ - groups: null, - - /** - * Individual drag/drop instances can be locked. This will prevent - * onmousedown start drag. - * - * @type boolean - * @private - */ - locked: false, - - /** - * Lock this instance - */ - lock: function() { this.locked = true; }, - - /** - * Unlock this instace - */ - unlock: function() { this.locked = false; }, - - /** - * By default, all insances can be a drop target. This can be disabled by - * setting isTarget to false. - * - * @type boolean - */ - isTarget: true, - - /** - * The padding configured for this drag and drop object for calculating - * the drop zone intersection with this object. - */ - padding: null, - - /** - * @private - */ - _domRef: null, - - /** - * Internal typeof flag - * @private - */ - __ygDragDrop: true, - - /** - * Set to true when horizontal contraints are applied - * - * @type boolean - * @private - */ - constrainX: false, - - /** - * Set to true when vertical contraints are applied - * - * @type boolean - * @private - */ - constrainY: false, - - /** - * The left constraint - * - * @type int - * @private - */ - minX: 0, - - /** - * The right constraint - * - * @type int - * @private - */ - maxX: 0, - - /** - * The up constraint - * - * @type int - * @private - */ - minY: 0, - - /** - * The down constraint - * - * @type int - * @private - */ - maxY: 0, - - /** - * Maintain offsets when we resetconstraints. Used to maintain the - * slider thumb value, and this needs to be fixed. - * @type boolean - */ - maintainOffset: false, - - /** - * Array of pixel locations the element will snap to if we specified a - * horizontal graduation/interval. This array is generated automatically - * when you define a tick interval. - * @type int[] - */ - xTicks: null, - - /** - * Array of pixel locations the element will snap to if we specified a - * vertical graduation/interval. This array is generated automatically - * when you define a tick interval. - * @type int[] - */ - yTicks: null, - - /** - * By default the drag and drop instance will only respond to the primary - * button click (left button for a right-handed mouse). Set to true to - * allow drag and drop to start with any mouse click that is propogated - * by the browser - * @type boolean - */ - primaryButtonOnly: true, - - /** - * Code that executes immediately before the startDrag event - * @private - */ - b4StartDrag: function(x, y) { }, - - /** - * Abstract method called after a drag/drop object is clicked - * and the drag or mousedown time thresholds have beeen met. - * - * @param {int} X click location - * @param {int} Y click location - */ - startDrag: function(x, y) { /* override this */ }, - - /** - * Code that executes immediately before the onDrag event - * @private - */ - b4Drag: function(e) { }, - - /** - * Abstract method called during the onMouseMove event while dragging an - * object. - * - * @param {Event} e - */ - onDrag: function(e) { /* override this */ }, - - /** - * Code that executes immediately before the onDragEnter event - * @private - */ - // b4DragEnter: function(e) { }, - - /** - * Abstract method called when this element fist begins hovering over - * another DragDrop obj - * - * @param {Event} e - * @param {String || YAHOO.util.DragDrop[]} id In POINT mode, the element - * id this is hovering over. In INTERSECT mode, an array of one or more - * dragdrop items being hovered over. - */ - onDragEnter: function(e, id) { /* override this */ }, - - /** - * Code that executes immediately before the onDragOver event - * @private - */ - b4DragOver: function(e) { }, - - /** - * Abstract method called when this element is hovering over another - * DragDrop obj - * - * @param {Event} e - * @param {String || YAHOO.util.DragDrop[]} id In POINT mode, the element - * id this is hovering over. In INTERSECT mode, an array of dd items - * being hovered over. - */ - onDragOver: function(e, id) { /* override this */ }, - - /** - * Code that executes immediately before the onDragOut event - * @private - */ - b4DragOut: function(e) { }, - - /** - * Abstract method called when we are no longer hovering over an element - * - * @param {Event} e - * @param {String || YAHOO.util.DragDrop[]} id In POINT mode, the element - * id this was hovering over. In INTERSECT mode, an array of dd items - * that the mouse is no longer over. - */ - onDragOut: function(e, id) { /* override this */ }, - - /** - * Code that executes immediately before the onDragDrop event - * @private - */ - b4DragDrop: function(e) { }, - - /** - * Abstract method called when this item is dropped on another DragDrop - * obj - * - * @param {Event} e - * @param {String || YAHOO.util.DragDrop[]} id In POINT mode, the element - * id this was dropped on. In INTERSECT mode, an array of dd items this - * was dropped on. - */ - onDragDrop: function(e, id) { /* override this */ }, - - /** - * Code that executes immediately before the endDrag event - * @private - */ - b4EndDrag: function(e) { }, - - /** - * Fired when we are done dragging the object - * - * @param {Event} e - */ - endDrag: function(e) { /* override this */ }, - - /** - * Code executed immediately before the onMouseDown event - - * @param {Event} e - * @private - */ - b4MouseDown: function(e) { }, - - /** - * Event handler that fires when a drag/drop obj gets a mousedown - * @param {Event} e - */ - onMouseDown: function(e) { /* override this */ }, - - /** - * Event handler that fires when a drag/drop obj gets a mouseup - * @param {Event} e - */ - onMouseUp: function(e) { /* override this */ }, - - /** - * Returns a reference to the linked element - * - * @return {Object} the html element - */ - getEl: function() { - if (!this._domRef) { - this._domRef = this.DDM.getElement(this.id); - } - - return this._domRef; - }, - - /** - * Returns a reference to the actual element to drag. By default this is - * the same as the html element, but it can be assigned to another - * element. An example of this can be found in YAHOO.util.DDProxy - * - * @return {Object} the html element - */ - getDragEl: function() { - return this.DDM.getElement(this.dragElId); - }, - - /** - * Sets up the DragDrop object. Must be called in the constructor of any - * YAHOO.util.DragDrop subclass - * - * @param id the id of the linked element - * @param {String} sGroup the group of related items - * element is supposed to be a target only, set to false. - */ - init: function(id, sGroup) { - this.initTarget(id, sGroup); - YAHOO.util.Event.addListener(id, "mousedown", - this.handleMouseDown, this, true); - }, - - /** - * Initializes Targeting functionality only... the object does not - * get a mousedown handler. - * - * @param id the id of the linked element - * @param {String} sGroup the group of related items - * element is supposed to be a target only, set to false. - */ - initTarget: function(id, sGroup) { - - // create a local reference to the drag and drop manager - this.DDM = YAHOO.util.DDM; - - - // set the default padding - this.padding = [0, 0, 0, 0]; - - // initialize the groups array - this.groups = {}; - - // set the id - this.id = id; - - // the element is a drag handle by default - this.setDragElId(id); - - // by default, clicked anchors will not start drag operations - this.invalidHandleTypes = {a : "a"}; - - // We don't want to register this as the handle with the manager - // so we just set the id rather than calling the setter - this.handleElId = id; - - // cache the position of the element if we can - if (document && document.body) { - this.setInitPosition(); - } - - // add to an interaction group - this.addToGroup((sGroup) ? sGroup : "default"); - - }, - - /** - * Configures the padding for the target zone in px. Effectively expands - * (or reduces) the virtual object size for targeting calculations. - * Supports css-style shorthand; if only one parameter is passed, all sides - * will have that padding, and if only two are passed, the top and bottom - * will have the first param, the left and right the second. - * @param {int} iTop Top pad - * @param {int} iRight Right pad - * @param {int} iBot Bot pad - * @param {int} iLeft Left pad - */ - setPadding: function(iTop, iRight, iBot, iLeft) { - // this.padding = [iLeft, iRight, iTop, iBot]; - if (!iRight && 0 !== iRight) { - this.padding = [iTop, iTop, iTop, iTop]; - } else if (!iBot && 0 !== iBot) { - this.padding = [iTop, iRight, iTop, iRight]; - } else { - this.padding = [iTop, iRight, iBot, iLeft]; - } - }, - - /** - * Stores the initial placement of the dd element - */ - setInitPosition: function(diffX, diffY) { - var el = this.getEl(); - - if (!this.DDM.verifyEl(el)) { - return; - } - - var dx = diffX || 0; - var dy = diffY || 0; - - var p = YAHOO.util.Dom.getXY( el ); - - this.initPageX = p[0] - dx; - this.initPageY = p[1] - dy; - - this.lastPageX = p[0]; - this.lastPageY = p[1]; - - this.setStartPosition(p); - }, - - /** - * Sets the start position of the element. This is set when the obj - * is initialized, the reset when a drag is started. - * @param pos current position (from previous lookup) - * @private - */ - setStartPosition: function(pos) { - - var p = pos || YAHOO.util.Dom.getXY( this.getEl() ); - - this.startPageX = p[0]; - this.startPageY = p[1]; - }, - - /** - * Add this instance to a group of related drag/drop objects. All - * instances belong to at least one group, and can belong to as many - * groups as needed. - * - * @param sGroup {string} the name of the group - */ - addToGroup: function(sGroup) { - this.groups[sGroup] = true; - this.DDM.regDragDrop(this, sGroup); - }, - - /** - * Allows you to specify that an element other than the linked element - * will be moved with the cursor during a drag - * - * @param id the id of the element that will be used to initiate the drag - */ - setDragElId: function(id) { - this.dragElId = id; - }, - - /** - * Allows you to specify a child of the linked element that should be - * used to initiate the drag operation. An example of this would be if - * you have a content div with text and links. Clicking anywhere in the - * content area would normally start the drag operation. Use this method - * to specify that an element inside of the content div is the element - * that starts the drag operation. - * - * @param id the id of the element that will be used to initiate the drag - */ - setHandleElId: function(id) { - this.handleElId = id; - this.DDM.regHandle(this.id, id); - }, - - /** - * Allows you to set an element outside of the linked element as a drag - * handle - */ - setOuterHandleElId: function(id) { - YAHOO.util.Event.addListener(id, "mousedown", - this.handleMouseDown, this, true); - this.setHandleElId(id); - }, - - /** - * Remove all drag and drop hooks for this element - */ - unreg: function() { - YAHOO.util.Event.removeListener(this.id, "mousedown", - this.handleMouseDown); - this._domRef = null; - this.DDM._remove(this); - }, - - /** - * Returns true if this instance is locked, or the drag drop mgr is locked - * (meaning that all drag/drop is disabled on the page.) - * - * @return {boolean} true if this obj or all drag/drop is locked, else - * false - */ - isLocked: function() { - return (this.DDM.isLocked() || this.locked); - }, - - /** - * Fired when this object is clicked - * - * @param {Event} e - * @param {YAHOO.util.DragDrop} oDD the clicked dd object (this dd obj) - * @private - */ - handleMouseDown: function(e, oDD) { - - - var EU = YAHOO.util.Event; - - - var button = e.which || e.button; - - if (this.primaryButtonOnly && button > 1) { - return; - } - - if (this.isLocked()) { - return; - } - - - this.DDM.refreshCache(this.groups); - - // Only process the event if we really clicked within the linked - // element. The reason we make this check is that in the case that - // another element was moved between the clicked element and the - // cursor in the time between the mousedown and mouseup events. When - // this happens, the element gets the next mousedown event - // regardless of where on the screen it happened. - var pt = new YAHOO.util.Point(EU.getPageX(e), EU.getPageY(e)); - if ( this.DDM.isOverTarget(pt, this) ) { - - - // check to see if the handle was clicked - var srcEl = EU.getTarget(e); - - if (this.isValidHandleChild(srcEl) && - (this.id == this.handleElId || - this.DDM.handleWasClicked(srcEl, this.id)) ) { - - // set the initial element position - this.setStartPosition(); - - - this.b4MouseDown(e); - this.onMouseDown(e); - this.DDM.handleMouseDown(e, this); - - this.DDM.stopEvent(e); - } - } - }, - - /** - * Allows you to specify a tag name that should not start a drag operation - * when clicked. This is designed to facilitate embedding links within a - * drag handle that do something other than start the drag. - * - * @param {string} tagName the type of element to exclude - */ - addInvalidHandleType: function(tagName) { - var type = tagName.toUpperCase(); - this.invalidHandleTypes[type] = type; - }, - - /** - * Unsets an excluded tag name set by addInvalidHandleType - * - * @param {string} tagName the type of element to unexclude - */ - removeInvalidHandleType: function(tagName) { - var type = tagName.toUpperCase(); - this.invalidHandleTypes[type] = null; - }, - - /** - * Checks the tag exclusion list to see if this click should be ignored - * - * @param {ygNode} node - * @return {boolean} true if this is a valid tag type, false if not - */ - isValidHandleChild: function(node) { - var type = node.nodeName; - - if (type == "#text") { - type = node.parentNode.nodeName; - } - - return (!this.invalidHandleTypes[type]); - }, - - /** - * Create the array of horizontal tick marks if an interval was specified - * in setXConstraint(). - * - * @private - */ - setXTicks: function(iStartX, iTickSize) { - this.xTicks = []; - this.xTickSize = iTickSize; - - var tickMap = {}; - - for (var i = this.initPageX; i >= this.minX; i = i - iTickSize) { - if (!tickMap[i]) { - this.xTicks[this.xTicks.length] = i; - tickMap[i] = true; - } - } - - for (i = this.initPageX; i <= this.maxX; i = i + iTickSize) { - if (!tickMap[i]) { - this.xTicks[this.xTicks.length] = i; - tickMap[i] = true; - } - } - - this.xTicks.sort(this.DDM.numericSort) ; - }, - - /** - * Create the array of vertical tick marks if an interval was specified in - * setYConstraint(). - * - * @private - */ - setYTicks: function(iStartY, iTickSize) { - this.yTicks = []; - this.yTickSize = iTickSize; - - var tickMap = {}; - - for (var i = this.initPageY; i >= this.minY; i = i - iTickSize) { - if (!tickMap[i]) { - this.yTicks[this.yTicks.length] = i; - tickMap[i] = true; - } - } - - for (i = this.initPageY; i <= this.maxY; i = i + iTickSize) { - if (!tickMap[i]) { - this.yTicks[this.yTicks.length] = i; - tickMap[i] = true; - } - } - - this.yTicks.sort(this.DDM.numericSort) ; - }, - - /** - * By default, the element can be dragged any place on the screen. Use - * this method to limit the horizontal travel of the element. Pass in - * 0,0 for the parameters if you want to lock the drag to the y axis. - * - * @param {int} iLeft the number of pixels the element can move to the left - * @param {int} iRight the number of pixels the element can move to the - * right - * @param {int} iTickSize optional parameter for specifying that the - * element - * should move iTickSize pixels at a time. - */ - setXConstraint: function(iLeft, iRight, iTickSize) { - this.leftConstraint = iLeft; - this.rightConstraint = iRight; - - this.minX = this.initPageX - iLeft; - this.maxX = this.initPageX + iRight; - if (iTickSize) { this.setXTicks(this.initPageX, iTickSize); } - - this.constrainX = true; - }, - - /** - * By default, the element can be dragged any place on the screen. Set - * this to limit the vertical travel of the element. Pass in 0,0 for the - * parameters if you want to lock the drag to the x axis. - * - * @param {int} iUp the number of pixels the element can move up - * @param {int} iDown the number of pixels the element can move down - * @param {int} iTickSize optional parameter for specifying that the - * element should move iTickSize pixels at a time. - */ - setYConstraint: function(iUp, iDown, iTickSize) { - this.topConstraint = iUp; - this.bottomConstraint = iDown; - - this.minY = this.initPageY - iUp; - this.maxY = this.initPageY + iDown; - if (iTickSize) { this.setYTicks(this.initPageY, iTickSize); } - - this.constrainY = true; - - }, - - /** - * resetConstraints must be called if you manually reposition a dd element. - * @param {boolean} maintainOffset - */ - resetConstraints: function() { - - - // figure out how much this thing has moved - var dx = (this.maintainOffset) ? this.lastPageX - this.initPageX : 0; - var dy = (this.maintainOffset) ? this.lastPageY - this.initPageY : 0; - - - // reset the initial location - this.setInitPosition(dx, dy); - - if (this.constrainX) { - this.setXConstraint( this.leftConstraint, - this.rightConstraint, - this.xTickSize ); - } - - if (this.constrainY) { - this.setYConstraint( this.topConstraint, - this.bottomConstraint, - this.yTickSize ); - } - }, - - /** - * Normally the drag element is moved pixel by pixel, but we can specify - * that it move a number of pixels at a time. This method resolves the - * location when we have it set up like this. - * - * @param {int} val where we want to place the object - * @param {int[]} tickArray sorted array of valid points - * @return {int} the closest tick - * @private - */ - getTick: function(val, tickArray) { - - if (!tickArray) { - // If tick interval is not defined, it is effectively 1 pixel, - // so we return the value passed to us. - return val; - } else if (tickArray[0] >= val) { - // The value is lower than the first tick, so we return the first - // tick. - return tickArray[0]; - } else { - for (var i = 0; i < tickArray.length; ++i) { - var next = i + 1; - if (tickArray[next] && tickArray[next] >= val) { - var diff1 = val - tickArray[i]; - var diff2 = tickArray[next] - val; - return (diff2 > diff1) ? tickArray[i] : tickArray[next]; - } - } - - // The value is larger than the last tick, so we return the last - // tick. - return tickArray[tickArray.length - 1]; - } - }, - - /** - * toString method - * @return {string} string representation of the dd obj - */ - toString: function(val, tickArray) { - return ("YAHOO.util.DragDrop {" + this.id + "}"); - } - -}; - -/* Copyright (c) 2006 Yahoo! Inc. All rights reserved. */ - -// Only load the library once. Rewriting the manager class would orphan -// existing drag and drop instances. -if (!YAHOO.util.DragDropMgr) { - - /** - * @class Handles the element interaction for all DragDrop items in the - * window. Generally, you will not call this class directly, but it does - * have helper methods that could be useful in your DragDrop - * implementations. This class should not be instantiated; all methods - * are are static. - * - * @constructor - */ - YAHOO.util.DragDropMgr = new function() { - - /** - * utility package shorthand - * @private - */ - var UTIL = YAHOO.util; - - /** - * Two dimensional Array of registered DragDrop objects. The first - * dimension is the DragDrop item group, the second the DragDrop - * object. - * - * @private - */ - this.ids = {}; - - /** - * Array of element ids defined as drag handles. Used to determine - * if the element that generated the mousedown event is actually the - * handle and not the html element itself. - * - * @private - */ - this.handleIds = {}; - - /** - * the DragDrop object that is currently being dragged - * - * @type DragDrop - * @private - **/ - this.dragCurrent = null; - - /** - * the DragDrop object(s) that are being hovered over - * - * @type Array - * @private - */ - this.dragOvers = {}; - - /** - * @private - */ - - /** - * the X distance between the cursor and the object being dragged - * - * @type int - * @private - */ - this.deltaX = 0; - - /** - * the Y distance between the cursor and the object being dragged - * - * @type int - * @private - */ - this.deltaY = 0; - - /** - * Flag to determine if we should prevent the default behavior of the - * events we define. By default this is true, but this can be set to - * false if you need the default behavior (not recommended) - * - * @type boolean - */ - this.preventDefault = true; - - /** - * Flag to determine if we should stop the propagation of the events - * we generate. This is true by default but you may want to set it to - * false if the html element contains other features that require the - * mouse click. - * - * @type boolean - */ - this.stopPropagation = true; - - /** - * @private - */ - this.initalized = false; - - /** - * All drag and drop can be disabled. - * - * @private - */ - this.locked = false; - - /** - * Called the first time an element is registered. - * - * @private - */ - this.init = function() { - }; - - /** - * In point mode, drag and drop interaction is defined by the - * location of the cursor during the drag/drop - * @type int - */ - this.POINT = 0; - - /** - * In intersect mode, drag and drop interactio nis defined by the - * overlap of two or more drag and drop objects. - * @type int - */ - this.INTERSECT = 1; - - /** - * The current drag and drop mode. Default it point mode - * @type int - */ - this.mode = this.POINT; - - /** - * Runs method on all drag and drop objects - * @private - */ - this._execOnAll = function(sMethod, args) { - for (var i in this.ids) { - for (var j in this.ids[i]) { - var oDD = this.ids[i][j]; - if (! this.isTypeOfDD(oDD)) { - continue; - } - oDD[sMethod].apply(oDD, args); - } - } - }; - - /** - * Drag and drop initialization. Sets up the global event handlers - * @private - */ - this._onLoad = function() { - - this._execOnAll("setInitPosition", []); - - - var EU = UTIL.Event; - - EU.addListener(document, "mouseup", this.handleMouseUp, this, true); - EU.addListener(document, "mousemove", this.handleMouseMove, this, true); - EU.addListener(window, "unload", this._onUnload, this, true); - EU.addListener(window, "resize", this._onResize, this, true); - // EU.addListener(window, "mouseout", this._test); - - this.initalized = true; - - }; - - /** - * Reset constraints on all drag and drop objs - * @private - */ - this._onResize = function(e) { - this._execOnAll("resetConstraints", []); - }; - - /** - * Lock all drag and drop functionality - */ - this.lock = function() { this.locked = true; }; - - /** - * Unlock all drag and drop functionality - */ - this.unlock = function() { this.locked = false; }; - - /** - * Is drag and drop locked? - * - * @return {boolean} True if drag and drop is locked, false otherwise. - */ - this.isLocked = function() { return this.locked; }; - - /** - * Location cache that is set for all drag drop objects when a drag is - * initiated, cleared when the drag is finished. - * - * @private - */ - this.locationCache = {}; - - /** - * Set useCache to false if you want to force object the lookup of each - * drag and drop linked element constantly during a drag. - * @type boolean - */ - this.useCache = true; - - /** - * The number of pixels that the mouse needs to move after the - * mousedown before the drag is initiated. Default=3; - * @type int - */ - this.clickPixelThresh = 3; - - /** - * The number of milliseconds after the mousedown event to initiate the - * drag if we don't get a mouseup event. Default=1000 - * @type int - */ - this.clickTimeThresh = 1000; - - /** - * Flag that indicates that either the drag pixel threshold or the - * mousdown time threshold has been met - * @type boolean - * @private - */ - this.dragThreshMet = false; - - /** - * Timeout used for the click time threshold - * @type Object - * @private - */ - this.clickTimeout = null; - - /** - * The X position of the mousedown event stored for later use when a - * drag threshold is met. - * @type int - * @private - */ - this.startX = 0; - - /** - * The Y position of the mousedown event stored for later use when a - * drag threshold is met. - * @type int - * @private - */ - this.startY = 0; - - /** - * Each DragDrop instance must be registered with the DragDropMgr. - * This is executed in ygDragDrop.init() - * - * @param {DragDrop} oDD the DragDrop object to register - * @param {String} sGroup the name of the group this element belongs to - */ - this.regDragDrop = function(oDD, sGroup) { - if (!this.initialized) { this.init(); } - - if (!this.ids[sGroup]) { - this.ids[sGroup] = {}; - } - this.ids[sGroup][oDD.id] = oDD; - }; - - /** - * Unregisters a drag and drop item. This is executed in - * ygDragDrop.unreg, use that method instead of calling this directly. - * @private - */ - this._remove = function(oDD) { - for (var g in oDD.groups) { - if (g && this.ids[g][oDD.id]) { - delete this.ids[g][oDD.id]; - } - } - delete this.handleIds[oDD.id]; - }; - - /** - * Each DragDrop handle element must be registered. This is done - * automatically when executing ygDragDrop.setHandleElId() - * - * @param {String} sDDId the DragDrop id this element is a handle for - * @param {String} sHandleId the id of the element that is the drag - * handle - */ - this.regHandle = function(sDDId, sHandleId) { - if (!this.handleIds[sDDId]) { - this.handleIds[sDDId] = {}; - } - this.handleIds[sDDId][sHandleId] = sHandleId; - }; - - /** - * Utility function to determine if a given element has been - * registered as a drag drop item. - * - * @param {String} id the element id to check - * @return {boolean} true if this element is a DragDrop item, - * false otherwise - */ - this.isDragDrop = function(id) { - return ( this.getDDById(id) ) ? true : false; - }; - - /** - * Returns the drag and drop instances that are in all groups the - * passed in instance belongs to. - * - * @param {ygDragDrop} p_oDD the obj to get related data for - * @param {boolean} bTargetsOnly if true, only return targetable objs - * @return {ygDragDrop[]} the related instances - */ - this.getRelated = function(p_oDD, bTargetsOnly) { - var oDDs = []; - for (var i in p_oDD.groups) { - for (j in this.ids[i]) { - var dd = this.ids[i][j]; - if (! this.isTypeOfDD(dd)) { - continue; - } - if (!bTargetsOnly || dd.isTarget) { - oDDs[oDDs.length] = dd; - } - } - } - - return oDDs; - }; - - /** - * Returns true if the specified dd target is a legal target for - * the specifice drag obj - * - * @param {ygDragDrop} the drag obj - * @param {ygDragDrop) the target - * @return {boolean} true if the target is a legal target for the - * dd obj - */ - this.isLegalTarget = function (oDD, oTargetDD) { - var targets = this.getRelated(oDD); - for (var i =0;i<targets.length;++i) { - if (targets[i].id == oTargetDD.id) { - return true; - } - } - - return false; - }; - - /** - * My goal is to be able to transparently determine if an object is - * typeof ygDragDrop, and the exact subclass of ygDragDrop. typeof - * returns "object", oDD.constructor.toString() always returns - * "ygDragDrop" and not the name of the subclass. So for now it just - * evaluates a well-known variable in ygDragDrop. - * - * @param {Object} the object to evaluate - * @return {boolean} true if typeof oDD = ygDragDrop - */ - this.isTypeOfDD = function (oDD) { - return (oDD && oDD.__ygDragDrop); - }; - - /** - * Utility function to determine if a given element has been - * registered as a drag drop handle for the given Drag Drop object. - * - * @param {String} id the element id to check - * @return {boolean} true if this element is a DragDrop handle, false - * otherwise - */ - this.isHandle = function(sDDId, sHandleId) { - return ( this.handleIds[sDDId] && - this.handleIds[sDDId][sHandleId] ); - }; - - /** - * Returns the DragDrop instance for a given id - * - * @param {String} id the id of the DragDrop object - * @return {DragDrop} the drag drop object, null if it is not found - */ - this.getDDById = function(id) { - for (var i in this.ids) { - if (this.ids[i][id]) { - return this.ids[i][id]; - } - } - return null; - }; - - /** - * Fired after a registered DragDrop object gets the mousedown event. - * Sets up the events required to track the object being dragged - * - * @param {Event} e the event - * @param oDD the DragDrop object being dragged - * @private - */ - this.handleMouseDown = function(e, oDD) { - this.dragCurrent = oDD; - - var el = oDD.getEl(); - - // track start position - this.startX = UTIL.Event.getPageX(e); - this.startY = UTIL.Event.getPageY(e); - - this.deltaX = this.startX - el.offsetLeft; - this.deltaY = this.startY - el.offsetTop; - - this.dragThreshMet = false; - - this.clickTimeout = setTimeout( - "var DDM=YAHOO.util.DDM;DDM.startDrag(DDM.startX, DDM.startY)", - this.clickTimeThresh ); - }; - - /** - * Fired when either the drag pixel threshol or the mousedown hold - * time threshold has been met. - * - * @param x {int} the X position of the original mousedown - * @param y {int} the Y position of the original mousedown - */ - this.startDrag = function(x, y) { - clearTimeout(this.clickTimeout); - if (this.dragCurrent) { - this.dragCurrent.b4StartDrag(x, y); - this.dragCurrent.startDrag(x, y); - } - this.dragThreshMet = true; - }; - - /** - * Internal function to handle the mouseup event. Will be invoked - * from the context of the document. - * - * @param {Event} e the event - * @private - */ - this.handleMouseUp = function(e) { - - if (! this.dragCurrent) { - return; - } - - clearTimeout(this.clickTimeout); - - if (this.dragThreshMet) { - this.fireEvents(e, true); - } else { - } - - this.stopDrag(e); - - this.stopEvent(e); - }; - - /** - * Utility to stop event propagation and event default, if these - * features are turned on. - * - * @param {Event} e the event as returned by this.getEvent() - */ - this.stopEvent = function(e) { - if (this.stopPropagation) { - UTIL.Event.stopPropagation(e); - } - - if (this.preventDefault) { - UTIL.Event.preventDefault(e); - } - }; - - /** - * Internal function to clean up event handlers after the drag - * operation is complete - * - * @param {Event} e the event - * @private - */ - this.stopDrag = function(e) { - - // Fire the drag end event for the item that was dragged - if (this.dragCurrent) { - if (this.dragThreshMet) { - this.dragCurrent.b4EndDrag(e); - this.dragCurrent.endDrag(e); - } - - this.dragCurrent.onMouseUp(e); - } - - this.dragCurrent = null; - this.dragOvers = {}; - }; - - /** - * Internal function to handle the mousemove event. Will be invoked - * from the context of the html element. - * - * @TODO figure out what we can do about mouse events lost when the - * user drags objects beyond the window boundary. Currently we can - * detect this in internet explorer by verifying that the mouse is - * down during the mousemove event. Firefox doesn't give us the - * button state on the mousemove event. - * - * @param {Event} e the event - * @private - */ - this.handleMouseMove = function(e) { - if (! this.dragCurrent) { - return; - } - - // var button = e.which || e.button; - - - // check for IE mouseup outside of page boundary - if (UTIL.Event.isIE && !e.button) { - this.stopEvent(e); - return this.handleMouseUp(e); - } - - if (!this.dragThreshMet) { - var diffX = Math.abs(this.startX - UTIL.Event.getPageX(e)); - var diffY = Math.abs(this.startY - UTIL.Event.getPageY(e)); - if (diffX > this.clickPixelThresh || - diffY > this.clickPixelThresh) { - this.startDrag(this.startX, this.startY); - } - } - - if (this.dragThreshMet) { - this.dragCurrent.b4Drag(e); - this.dragCurrent.onDrag(e); - this.fireEvents(e, false); - } - - this.stopEvent(e); - }; - - /** - * Iterates over all of the DragDrop elements to find ones we are - * hovering over or dropping on - * - * @param {Event} e the event - * @param {boolean} isDrop is this a drop op or a mouseover op? - * @private - */ - this.fireEvents = function(e, isDrop) { - var dc = this.dragCurrent; - - // If the user did the mouse up outside of the window, we could - // get here even though we have ended the drag. - if (!dc || dc.isLocked()) { - return; - } - - var x = UTIL.Event.getPageX(e); - var y = UTIL.Event.getPageY(e); - var pt = new YAHOO.util.Point(x,y); - - // cache the previous dragOver array - var oldOvers = []; - - var outEvts = []; - var overEvts = []; - var dropEvts = []; - var enterEvts = []; - - // Check to see if the object we were hovering over is no longer - // being hovered over so we can fire the onDragOut event - for (var i in this.dragOvers) { - - var ddo = this.dragOvers[i]; - - if (! this.isTypeOfDD(ddo)) { - continue; - } - - if (! this.isOverTarget(pt, ddo, this.mode)) { - outEvts.push( ddo ); - } - - oldOvers[i] = true; - delete this.dragOvers[i]; - } - - for (var sGroup in dc.groups) { - - if ("string" != typeof sGroup) { - continue; - } - - for (i in this.ids[sGroup]) { - var oDD = this.ids[sGroup][i]; - if (! this.isTypeOfDD(oDD)) { - continue; - } - - if (oDD.isTarget && !oDD.isLocked() && oDD != dc) { - if (this.isOverTarget(pt, oDD, this.mode)) { - // look for drop interactions - if (isDrop) { - dropEvts.push( oDD ); - // look for drag enter and drag over interactions - } else { - - // initial drag over: dragEnter fires - if (!oldOvers[oDD.id]) { - enterEvts.push( oDD ); - // subsequent drag overs: dragOver fires - } else { - overEvts.push( oDD ); - } - - this.dragOvers[oDD.id] = oDD; - } - } - } - } - } - - if (this.mode) { - if (outEvts.length > 0) { - dc.b4DragOut(e, outEvts); - dc.onDragOut(e, outEvts); - } - - if (enterEvts.length > 0) { - dc.onDragEnter(e, enterEvts); - } - - if (overEvts.length > 0) { - dc.b4DragOver(e, overEvts); - dc.onDragOver(e, overEvts); - } - - if (dropEvts.length > 0) { - dc.b4DragDrop(e, dropEvts); - dc.onDragDrop(e, dropEvts); - } - - } else { - // fire dragout events - for (i=0; i < outEvts.length; ++i) { - dc.b4DragOut(e, outEvts[i].id); - dc.onDragOut(e, outEvts[i].id); - } - - // fire enter events - for (i=0; i < enterEvts.length; ++i) { - // dc.b4DragEnter(e, oDD.id); - dc.onDragEnter(e, enterEvts[i].id); - } - - // fire over events - for (i=0; i < overEvts.length; ++i) { - dc.b4DragOver(e, overEvts[i].id); - dc.onDragOver(e, overEvts[i].id); - } - - // fire drop events - for (i=0; i < dropEvts.length; ++i) { - dc.b4DragDrop(e, dropEvts[i].id); - dc.onDragDrop(e, dropEvts[i].id); - } - - } - - }; - - /** - * Helper function for getting the best match from the list of drag - * and drop objects returned by the drag and drop events when we are - * in INTERSECT mode. It returns either the first object that the - * cursor is over, or the object that has the greatest overlap with - * the dragged element. - * - * @param {ygDragDrop[]} dds The array of drag and drop objects - * targeted - * @return {ygDragDrop} The best single match - */ - this.getBestMatch = function(dds) { - var winner = null; - // Return null if the input is not what we expect - //if (!dds || !dds.length || dds.length == 0) { - // winner = null; - // If there is only one item, it wins - //} else if (dds.length == 1) { - - if (dds.length == 1) { - winner = dds[0]; - } else { - // Loop through the targeted items - for (var i=0; i<dds.length; ++i) { - var dd = dds[i]; - // If the cursor is over the object, it wins. If the - // cursor is over multiple matches, the first one we come - // to wins. - if (dd.cursorIsOver) { - winner = dd; - break; - // Otherwise the object with the most overlap wins - } else { - if (!winner || - winner.overlap.getArea() < dd.overlap.getArea()) { - winner = dd; - } - } - } - } - - return winner; - }; - - /** - * Refreshes the cache of the top-left and bottom-right points of the - * drag and drop objects in the specified groups - * - * @param {Array} aGroups an associative array of groups to refresh - */ - this.refreshCache = function(aGroups) { - for (sGroup in aGroups) { - if ("string" != typeof sGroup) { - continue; - } - for (i in this.ids[sGroup]) { - var oDD = this.ids[sGroup][i]; - - if (this.isTypeOfDD(oDD)) { - var loc = this.getLocation(oDD); - if (loc) { - this.locationCache[oDD.id] = loc; - } else { - delete this.locationCache[oDD.id]; - // this will unregister the drag and drop object if - // the element is not in a usable state - oDD.unreg(); - } - } - } - } - }; - - /** - * This checks to make sure an element exists and is in the DOM. The - * main purpose is to handle cases where innerHTML is used to remove - * drag and drop objects from the DOM. IE provides an 'unspecified - * error' when trying to access the offsetParent of such an element - * @param {HTMLElement} el the element to check - * @return {boolean} true if the element looks usable - */ - this.verifyEl = function(el) { - try { - if (el) { - var parent = el.offsetParent; - if (parent) { - return true; - } - } - } catch(e) { - } - - return false; - }; - - /** - * Returns the an array containing the drag and drop element's position - * and size, including the ygDragDrop.padding configured for it - * - * @param {ygDragDrop} oDD the drag and drop object to get the - * location for - * @return array containing the top left and bottom right points of the - * element - */ - this.getLocation = function(oDD) { - if (! this.isTypeOfDD(oDD)) { - return null; - } - - var el = oDD.getEl(); - - if (!this.verifyEl(el)) { - return null; - } - - - // var aPos = ygPos.getPos(el); - var aPos = YAHOO.util.Dom.getXY(el); - - x1 = aPos[0]; - x2 = x1 + el.offsetWidth; - - y1 = aPos[1]; - y2 = y1 + el.offsetHeight; - - var t = y1 - oDD.padding[0]; - var r = x2 + oDD.padding[1]; - var b = y2 + oDD.padding[2]; - var l = x1 - oDD.padding[3]; - - return new YAHOO.util.Region( t, r, b, l ); - - }; - - /** - * Checks the cursor location to see if it over the target - * - * @param {YAHOO.util.Point} pt The point to evaluate - * @param {ygDragDrop} oDDTarget the DragDrop object we are inspecting - * @return {boolean} true if the mouse is over the target - * @private - */ - this.isOverTarget = function(pt, oDDTarget, intersect) { - // use cache if available - var loc = this.locationCache[oDDTarget.id]; - if (!loc || !this.useCache) { - loc = this.getLocation(oDDTarget); - this.locationCache[oDDTarget.id] = loc; - - } - - - // var cursorIsOver = (x >= loc[3] && x <= loc[1] && y >= loc[0] && y <= loc[2]); - //oDDTarget.cursorIsOver = loc.contains( new YAHOO.util.Point(x, y) ); - oDDTarget.cursorIsOver = loc.contains( pt ); - oDDTarget.overlap = null; - - // if (this.INTERSECT == this.mode) { - if (intersect) { - - var curRegion = - YAHOO.util.Region.getRegion(this.dragCurrent.getDragEl()); - var overlap = curRegion.intersect(loc); - - if (overlap) { - oDDTarget.overlap = overlap; - return true; - } else { - return false; - } - - } else { - return oDDTarget.cursorIsOver; - } - }; - - /** - * @private - */ - this._onUnload = function(e, me) { - this.unregAll(); - }; - - /** - * Cleans up the drag and drop events and objects. - * - * @private - */ - this.unregAll = function() { - - if (this.dragCurrent) { - this.stopDrag(); - this.dragCurrent = null; - } - - this._execOnAll("unreg", []); - - for (i in this.elementCache) { - delete this.elementCache[i]; - } - - this.elementCache = {}; - this.ids = {}; - }; - - /** - * A cache of DOM elements - * - * @private - */ - this.elementCache = {}; - - /** - * Get the wrapper for the DOM element specified - * - * @param {String} id the id of the elment to get - * @return {YAHOO.util.DDM.ElementWrapper} the wrapped element - * @private - */ - this.getElWrapper = function(id) { - var oWrapper = this.elementCache[id]; - if (!oWrapper || !oWrapper.el) { - oWrapper = this.elementCache[id] = - new this.ElementWrapper(document.getElementById(id)); - } - return oWrapper; - }; - - /** - * Returns the actual DOM element - * - * @param {String} id the id of the elment to get - * @return {Object} The element - */ - this.getElement = function(id) { - // return this.getElWrapper(id).el; - return document.getElementById(id); - }; - - /** - * Returns the style property for the DOM element (i.e., - * document.getElById(id).style) - * - * @param {String} id the id of the elment to get - * @return {Object} The style property of the element - */ - this.getCss = function(id) { - // return this.getElWrapper(id).css; - var css = null; - var el = document.getElementById(id); - if (el) { - css = el.style; - } - - return css; - }; - - /** - * Inner class for cached elements - */ - this.ElementWrapper = function(el) { - /** - * @private - */ - this.el = el || null; - /** - * @private - */ - this.id = this.el && el.id; - /** - * @private - */ - this.css = this.el && el.style; - }; - - /** - * Returns the X position of an html element - * @param el the element for which to get the position - * @return {int} the X coordinate - */ - this.getPosX = function(el) { - return YAHOO.util.Dom.getX(el); - }; - - /** - * Returns the Y position of an html element - * @param el the element for which to get the position - * @return {int} the Y coordinate - */ - this.getPosY = function(el) { - return YAHOO.util.Dom.getY(el); - }; - - /** - * Swap two nodes. In IE, we use the native method, for others we - * emulate the IE behavior - * - * @param n1 the first node to swap - * @param n2 the other node to swap - */ - this.swapNode = function(n1, n2) { - if (n1.swapNode) { - n1.swapNode(n2); - } else { - // the node reference order for the swap is a little tricky. - var p = n2.parentNode; - var s = n2.nextSibling; - n1.parentNode.replaceChild(n2,n1); - p.insertBefore(n1,s); - } - }; - - /** - * @private - */ - this.getScroll = function () { - var t, l; - if (document.documentElement && document.documentElement.scrollTop) { - t = document.documentElement.scrollTop; - l = document.documentElement.scrollLeft; - } else if (document.body) { - t = document.body.scrollTop; - l = document.body.scrollLeft; - } - return { top: t, left: l }; - }; - - /** - * Returns the specified element style property - * @param {HTMLElement} el the element - * @param {string} styleProp the style property - * @return {string} The value of the style property - */ - this.getStyle = function(el, styleProp) { - if (el.style.styleProp) { - return el.style.styleProp; - } else if (el.currentStyle) { - return el.currentStyle[styleProp]; - } else if (document.defaultView) { - return document.defaultView.getComputedStyle(el, null). - getPropertyValue(styleProp); - } - }; - - /** - * Gets the scrollTop - * - * @return {int} the document's scrollTop - */ - this.getScrollTop = function () { return this.getScroll().top; }; - - /** - * Gets the scrollLeft - * - * @return {int} the document's scrollTop - */ - this.getScrollLeft = function () { return this.getScroll().left; }; - - this.moveToEl = function (moveEl, targetEl) { - var aCoord = YAHOO.util.Dom.getXY(targetEl); - YAHOO.util.Dom.setXY(moveEl, aCoord); - }; - - /** - * Gets the client height - * - * @return {int} client height in px - */ - this.getClientHeight = function() { - return (window.innerHeight) ? window.innerHeight : - (document.documentElement && document.documentElement.clientHeight) ? - document.documentElement.clientHeight : document.body.offsetHeight; - }; - - /** - * Gets the client width - * - * @return {int} client width in px - */ - this.getClientWidth = function() { - return (window.innerWidth) ? window.innerWidth : - (document.documentElement && document.documentElement.clientWidth) ? - document.documentElement.clientWidth : document.body.offsetWidth; - }; - - /** - * numeric array sort function - */ - this.numericSort = function(a, b) { return (a - b); }; - - /** - * @private - */ - this._timeoutCount = 0; - - /** - * @private - * Trying to make the load order less important. Without this we get - * an error if this file is loaded before the Event Utility. - */ - this._addListeners = function() { - if ( UTIL.Event && - document && - document.body ) { - - this._onLoad(); - } else { - if (this._timeoutCount > 500) { - } else { - setTimeout("YAHOO.util.DDM._addListeners()", 10); - this._timeoutCount += 1; - } - } - - }; - - /** - * Recursively searches the immediate parent and all child nodes for - * the handle element in order to determine wheter or not it was - * clicked. - * - * @param node the html element to inspect - */ - this.handleWasClicked = function(node, id) { - if (this.isHandle(id, node.id)) { - return true; - } else { - // check to see if this is a text node child of the one we want - var p = node.parentNode; - - while (p) { - if (this.isHandle(id, p.id)) { - return true; - } else { - p = p.parentNode; - } - } - } - - return false; - }; - - }; - - // shorter alias, save a few bytes - YAHOO.util.DDM = YAHOO.util.DragDropMgr; - YAHOO.util.DDM._addListeners(); - -} - -/* Copyright (c) 2006 Yahoo! Inc. All rights reserved. */ - -/** - * @class a DragDrop implementation where the linked element follows the - * mouse cursor. - * - * @extends DragDrop - * @constructor - * @param {String} id the id of the linked element - * @param {String} sGroup the group of related DragDrop items - */ -YAHOO.util.DD = function(id, sGroup) { - if (id) { - this.init(id, sGroup); - } -}; - -YAHOO.util.DD.prototype = new YAHOO.util.DragDrop(); - -/** - * Should we auto-scroll? Defaults to true - * - * @type boolean - */ -YAHOO.util.DD.prototype.scroll = true; - -/** - * Sets the pointer offset to the distance between the linked element's top - * left corner and the location the element was clicked - * - * @param {int} iPageX the X coordinate of the click - * @param {int} iPageY the Y coordinate of the click - */ -YAHOO.util.DD.prototype.autoOffset = function(iPageX, iPageY) { - var el = this.getEl(); - var aCoord = YAHOO.util.Dom.getXY(el); - var x = iPageX - aCoord[0]; - var y = iPageY - aCoord[1]; - this.setDelta(x, y); -}; - -/** - * Sets the pointer offset. You can call this directly to force the offset to - * be in a particular location (e.g., pass in 0,0 to set it to the center of the - * object, as done in ygDDSliderBG) - * - * @param {int} iDeltaX the distance from the left - * @param {int} iDeltaY the distance from the top - */ -YAHOO.util.DD.prototype.setDelta = function(iDeltaX, iDeltaY) { - this.deltaX = iDeltaX; - this.deltaY = iDeltaY; -}; - -/** - * Sets the drag element to the location of the mousedown or click event, - * maintaining the cursor location relative to the location on the element - * that was clicked. Override this if you want to place the element in a - * location other than where the cursor is. - * - * @param {int} iPageX the X coordinate of the mousedown or drag event - * @param {int} iPageY the Y coordinate of the mousedown or drag event - */ - -YAHOO.util.DD.prototype.setDragElPos = function(iPageX, iPageY) { - this.alignElWithMouse(this.getDragEl(), iPageX, iPageY); -}; - -/** - * Sets the element to the location of the mousedown or click event, - * maintaining the cursor location relative to the location on the element - * that was clicked. Override this if you want to place the element in a - * location other than where the cursor is. - * - * @param {HTMLElement} el the element to move - * @param {int} iPageX the X coordinate of the mousedown or drag event - * @param {int} iPageY the Y coordinate of the mousedown or drag event - */ -YAHOO.util.DD.prototype.alignElWithMouse = function(el, iPageX, iPageY) { - var oCoord = this.getTargetCoord(iPageX, iPageY); - var aCoord = [oCoord.x, oCoord.y]; - YAHOO.util.Dom.setXY(el, aCoord); - - this.cachePosition(oCoord.x, oCoord.y); - - this.autoScroll(oCoord.x, oCoord.y, el.offsetHeight, el.offsetWidth); -}; - -/** - * Saves the most recent position so that we can reset the constraints and - * tick marks on-demand. We need to know this so that we can calculate the - * number of pixels the element is offset from its original position. - */ -YAHOO.util.DD.prototype.cachePosition = function(iPageX, iPageY) { - if (iPageX) { - this.lastPageX = iPageX; - this.lastPageY = iPageY; - } else { - var aCoord = YAHOO.util.Dom.getXY(this.getEl()); - this.lastPageX = aCoord[0]; - this.lastPageY = aCoord[1]; - } -}; - -/** - * Auto-scroll the window if the dragged object has been moved beyond the - * visible window boundary. - * - * @param {int} x the drag element's x position - * @param {int} y the drag element's y position - * @param {int} h the height of the drag element - * @param {int} w the width of the drag element - * @private - */ -YAHOO.util.DD.prototype.autoScroll = function(x, y, h, w) { - - if (this.scroll) { - // The client height - var clientH = this.DDM.getClientHeight(); - - // The client width - var clientW = this.DDM.getClientWidth(); - - // The amt scrolled down - var st = this.DDM.getScrollTop(); - - // The amt scrolled right - var sl = this.DDM.getScrollLeft(); - - // Location of the bottom of the element - var bot = h + y; - - // Location of the right of the element - var right = w + x; - - // The distance from the cursor to the bottom of the visible area, - // adjusted so that we don't scroll if the cursor is beyond the - // element drag constraints - var toBot = (clientH + st - y - this.deltaY); - - // The distance from the cursor to the right of the visible area - var toRight = (clientW + sl - x - this.deltaX); - - - // How close to the edge the cursor must be before we scroll - // var thresh = (document.all) ? 100 : 40; - var thresh = 40; - - // How many pixels to scroll per autoscroll op. This helps to reduce - // clunky scrolling. IE is more sensitive about this ... it needs this - // value to be higher. - var scrAmt = (document.all) ? 80 : 30; - - // Scroll down if we are near the bottom of the visible page and the - // obj extends below the crease - if ( bot > clientH && toBot < thresh ) { - window.scrollTo(sl, st + scrAmt); - } - - // Scroll up if the window is scrolled down and the top of the object - // goes above the top border - if ( y < st && st > 0 && y - st < thresh ) { - window.scrollTo(sl, st - scrAmt); - } - - // Scroll right if the obj is beyond the right border and the cursor is - // near the border. - if ( right > clientW && toRight < thresh ) { - window.scrollTo(sl + scrAmt, st); - } - - // Scroll left if the window has been scrolled to the right and the obj - // extends past the left border - if ( x < sl && sl > 0 && x - sl < thresh ) { - window.scrollTo(sl - scrAmt, st); - } - } -}; - -/** - * Finds the location the element should be placed if we want to move - * it to where the mouse location less the click offset would place us. - * - * @param {int} iPageX the X coordinate of the click - * @param {int} iPageY the Y coordinate of the click - * @return an object that contains the coordinates (Object.x and Object.y) - * @private - */ -YAHOO.util.DD.prototype.getTargetCoord = function(iPageX, iPageY) { - - - var x = iPageX - this.deltaX; - var y = iPageY - this.deltaY; - - if (this.constrainX) { - if (x < this.minX) { x = this.minX; } - if (x > this.maxX) { x = this.maxX; } - } - - if (this.constrainY) { - if (y < this.minY) { y = this.minY; } - if (y > this.maxY) { y = this.maxY; } - } - - x = this.getTick(x, this.xTicks); - y = this.getTick(y, this.yTicks); - - - return {x:x, y:y}; -}; - -// overrides YAHOO.util.DragDrop -YAHOO.util.DD.prototype.b4MouseDown = function(e) { - // this.resetConstraints(); - this.autoOffset(YAHOO.util.Event.getPageX(e), - YAHOO.util.Event.getPageY(e)); -}; - -// overrides YAHOO.util.DragDrop -YAHOO.util.DD.prototype.b4Drag = function(e) { - this.setDragElPos(YAHOO.util.Event.getPageX(e), - YAHOO.util.Event.getPageY(e)); -}; - -/////////////////////////////////////////////////////////////////////////////// -// Debugging ygDragDrop events that can be overridden -/////////////////////////////////////////////////////////////////////////////// -/* -YAHOO.util.DD.prototype.startDrag = function(x, y) { -}; - -YAHOO.util.DD.prototype.onDrag = function(e) { -}; - -YAHOO.util.DD.prototype.onDragEnter = function(e, id) { -}; - -YAHOO.util.DD.prototype.onDragOver = function(e, id) { -}; - -YAHOO.util.DD.prototype.onDragOut = function(e, id) { -}; - -YAHOO.util.DD.prototype.onDragDrop = function(e, id) { -}; - -YAHOO.util.DD.prototype.endDrag = function(e) { -}; -*/ - -/* Copyright (c) 2006 Yahoo! Inc. All rights reserved. */ - -/** - * @class a DragDrop implementation that inserts an empty, bordered div into - * the document that follows the cursor during drag operations. At the time of - * the click, the frame div is resized to the dimensions of the linked html - * element, and moved to the exact location of the linked element. - * - * @extends YAHOO.util.DD - * @constructor - * @param {String} id the id of the linked html element - * @param {String} sGroup the group of related DragDrop objects - */ -YAHOO.util.DDProxy = function(id, sGroup) { - if (id) { - this.init(id, sGroup); - this.initFrame(); - } -}; - -YAHOO.util.DDProxy.prototype = new YAHOO.util.DD(); - -/** - * A reference to the one div element we create for all instances of this class - * - * @type Object - */ -YAHOO.util.DDProxy.frameDiv = null; - -/** - * the drag frame div id - * - * @type String - */ -YAHOO.util.DDProxy.dragElId = "ygddfdiv"; - -/** - * The border width of the frame. This is used when we resize the frame to - * the size of the linked element. We substract the border width to make - * the div the correct size. - * - * @TODO find a better way to handle this - * - * @type int - */ -YAHOO.util.DDProxy.prototype.borderWidth = 2; - -/** - * By default we resize the drag frame to be the same size as the element - * we want to drag (this is to get the frame effect). We can turn it off - * if we want a different behavior (ex: ygDDMy2) - * - * @type boolean - */ -YAHOO.util.DDProxy.prototype.resizeFrame = true; - -/** - * By default the frame is positioned exactly where the drag element is, so - * we use the cursor offset provided by YAHOO.util.DD. Another option that works only if - * you do not have constraints on the obj is to have the drag frame centered - * around the cursor. Set centerFrame to true for this effect. Ex: - * ygDDMy2 - * - * @type boolean - */ -YAHOO.util.DDProxy.prototype.centerFrame = false; - -/** - * Create the drag frame if needed - */ -YAHOO.util.DDProxy.createFrame = function() { - var THIS = YAHOO.util.DDProxy; - - if (!document || !document.body) { - setTimeout(THIS.createFrame, 50); - return; - } - - if (!THIS.frameDiv) { - THIS.frameDiv = document.createElement("div"); - THIS.frameDiv.id = THIS.dragElId; - var s = THIS.frameDiv.style; - s.position = "absolute"; - s.visibility = "hidden"; - s.cursor = "move"; - s.border = "2px solid #aaa"; - s.zIndex = 999; - - document.body.appendChild(THIS.frameDiv); - } -}; - -/** - * Initialization for the drag frame element. Must be called in the - * constructor of all subclasses - */ -YAHOO.util.DDProxy.prototype.initFrame = function() { - YAHOO.util.DDProxy.createFrame(); - this.setDragElId(YAHOO.util.DDProxy.dragElId); - this.useAbsMath = true; -}; - -/** - * Resizes the drag frame to the dimensions of the clicked object, positions - * it over the object, and finally displays it - * - * @param {int} iPageX X click position - * @param {int} iPageY Y click position - * @private - */ -YAHOO.util.DDProxy.prototype.showFrame = function(iPageX, iPageY) { - var el = this.getEl(); - - var s = this.getDragEl().style; - - if (this.resizeFrame) { - s.width = (parseInt(el.offsetWidth) - (2*this.borderWidth)) + "px"; - s.height = (parseInt(el.offsetHeight) - (2*this.borderWidth)) + "px"; - } - - if (this.centerFrame) { - this.setDelta(Math.round(parseInt(s.width)/2), - Math.round(parseInt(s.width)/2)); - } - - this.setDragElPos(iPageX, iPageY); - - s.visibility = ""; -}; - -// overrides YAHOO.util.DragDrop -YAHOO.util.DDProxy.prototype.b4MouseDown = function(e) { - var x = YAHOO.util.Event.getPageX(e); - var y = YAHOO.util.Event.getPageY(e); - this.autoOffset(x, y); - this.setDragElPos(x, y); -}; - -// overrides YAHOO.util.DragDrop -YAHOO.util.DDProxy.prototype.b4StartDrag = function(x, y) { - // show the drag frame - this.showFrame(x, y); -}; - -// overrides YAHOO.util.DragDrop -YAHOO.util.DDProxy.prototype.b4EndDrag = function(e) { - - // hide the drag frame - var s = this.getDragEl().style; - s.visibility = "hidden"; -}; - -// overrides YAHOO.util.DragDrop -// By default we try to move the element to the last location of the frame. -// This is so that the default behavior mirrors that of YAHOO.util.DD. -YAHOO.util.DDProxy.prototype.endDrag = function(e) { - var lel = this.getEl(); - var del = this.getDragEl(); - - // Show the drag frame briefly so we can get its position - del.style.visibility = ""; - - // Hide the linked element before the move to get around a Safari - // rendering bug. - lel.style.visibility = "hidden"; - YAHOO.util.DDM.moveToEl(lel, del); - del.style.visibility = "hidden"; - lel.style.visibility = ""; -}; - -/* Copyright (c) 2006 Yahoo! Inc. All rights reserved. */ - -/** - * @class a DragDrop implementation that does not move, but can be a drop - * target. You would get the same result by simply omitting implementation - * for the event callbacks, but this way we reduce the processing cost of the - * event listener and the callbacks. - * - * @extends YAHOO.util.DragDrop - * @constructor - * @param {String} id the id of the element that is a drop target - * @param {String} sGroup the group of related DragDrop objects - */ - -YAHOO.util.DDTarget = function(id, sGroup) { - if (id) { - this.initTarget(id, sGroup); - } -}; - -YAHOO.util.DDTarget.prototype = new YAHOO.util.DragDrop(); - diff --git a/web/build/event.js b/web/build/event.js deleted file mode 100644 index 9bca02e4e..000000000 --- a/web/build/event.js +++ /dev/null @@ -1,901 +0,0 @@ -/* -Copyright (c) 2006 Yahoo! Inc. All rights reserved. -version 0.9.0 -*/ - -/** - * @class The CustomEvent class lets you define events for your application - * that can be subscribed to by one or more independent component. - * @param {String} type The type of event, which is passed to the callback - * when the event fires - * @param {Object} oScope The context the event will fire from. "this" will - * refer to this object in the callback. Default value: - * the window object. The listener can override this. - * @constructor - */ -YAHOO.util.CustomEvent = function(type, oScope) { - /** - * The type of event, returned to subscribers when the event fires - * @type string - */ - this.type = type; - - /** - * The scope the the event will fire from. Defaults to the window obj - * @type object - */ - this.scope = oScope || window; - - /** - * The subscribers to this event - * @type array - */ - this.subscribers = []; - - // Register with the event utility for automatic cleanup. Made optional - // so that CustomEvent can be used independently of pe.event - if (YAHOO.util["Event"]) { - YAHOO.util.Event.regCE(this); - } -}; - -YAHOO.util.CustomEvent.prototype = { - /** - * Subscribes the caller to this event - * @param {Function} fn The function to execute - * @param {Object} obj An object to be passed along when the event fires - * @param {boolean} bOverride If true, the obj passed in becomes the execution - * scope of the listener - */ - subscribe: function(fn, obj, bOverride) { - this.subscribers.push( new YAHOO.util.Subscriber(fn, obj, bOverride) ); - }, - - /** - * Unsubscribes the caller from this event - * @param {Function} fn The function to execute - * @param {Object} obj An object to be passed along when the event fires - * @return {boolean} True if the subscriber was found and detached. - */ - unsubscribe: function(fn, obj) { - var found = false; - for (var i=0; i<this.subscribers.length; ++i) { - var s = this.subscribers[i]; - if (s && s.contains(fn, obj)) { - this._delete(i); - found = true; - } - } - - return found; - }, - - /** - * Notifies the subscribers. The callback functions will be executed - * from the scope specified when the event was created, and with the following - * parameters: - * <pre> - * - The type of event - * - All of the arguments fire() was executed with as an array - * - The custom object (if any) that was passed into the subscribe() method - * </pre> - * - * @param {Array} an arbitrary set of parameters to pass to the handler - */ - fire: function() { - for (var i=0; i<this.subscribers.length; ++i) { - var s = this.subscribers[i]; - if (s) { - var scope = (s.override) ? s.obj : this.scope; - s.fn.call(scope, this.type, arguments, s.obj); - } - } - }, - - /** - * Removes all listeners - */ - unsubscribeAll: function() { - for (var i=0; i<this.subscribers.length; ++i) { - this._delete(i); - } - }, - - /** - * @private - */ - _delete: function(index) { - var s = this.subscribers[index]; - if (s) { - delete s.fn; - delete s.obj; - } - - delete this.subscribers[index]; - } -}; - -///////////////////////////////////////////////////////////////////// - -/** - * @class - * @param {Function} fn The function to execute - * @param {Object} obj An object to be passed along when the event fires - * @param {boolean} bOverride If true, the obj passed in becomes the execution - * scope of the listener - * @constructor - */ -YAHOO.util.Subscriber = function(fn, obj, bOverride) { - /** - * The callback that will be execute when the event fires - * @type function - */ - this.fn = fn; - - /** - * An optional custom object that will passed to the callback when - * the event fires - * @type object - */ - this.obj = obj || null; - - /** - * The default execution scope for the event listener is defined when the - * event is created (usually the object which contains the event). - * By setting override to true, the execution scope becomes the custom - * object passed in by the subscriber - * @type boolean - */ - this.override = (bOverride); -}; - -/** - * Returns true if the fn and obj match this objects properties. - * Used by the unsubscribe method to match the right subscriber. - * - * @param {Function} fn the function to execute - * @param {Object} obj an object to be passed along when the event fires - * @return {boolean} true if the supplied arguments match this - * subscriber's signature. - */ -YAHOO.util.Subscriber.prototype.contains = function(fn, obj) { - return (this.fn == fn && this.obj == obj); -}; - -/* Copyright (c) 2006 Yahoo! Inc. All rights reserved. */ - -// Only load this library once. If it is loaded a second time, existing -// events cannot be detached. -if (!YAHOO.util.Event) { - -/** - * The event utility provides functions to add and remove event listeners, - * event cleansing. It also tries to automatically remove listeners it - * registers during the unload event. - * @class - * @constructor - */ - YAHOO.util.Event = function() { - - /** - * True after the onload event has fired - * @type boolean - * @private - */ - var loadComplete = false; - - /** - * Cache of wrapped listeners - * @type array - * @private - */ - var listeners = []; - - /** - * Listeners that will be attached during the onload event - * @type array - * @private - */ - var delayedListeners = []; - - /** - * User-defined unload function that will be fired before all events - * are detached - * @type array - * @private - */ - var unloadListeners = []; - - /** - * Cache of the custom events that have been defined. Used for - * automatic cleanup - * @type array - * @private - */ - var customEvents = []; - - /** - * Cache of DOM0 event handlers to work around issues with DOM2 events - * in Safari - * @private - */ - var legacyEvents = []; - - /** - * Listener stack for DOM0 events - * @private - */ - var legacyHandlers = []; - - return { // PREPROCESS - - /** - * Element to bind, int constant - * @type int - */ - EL: 0, - - /** - * Type of event, int constant - * @type int - */ - TYPE: 1, - - /** - * Function to execute, int constant - * @type int - */ - FN: 2, - - /** - * Function wrapped for scope correction and cleanup, int constant - * @type int - */ - WFN: 3, - - /** - * Object passed in by the user that will be returned as a - * parameter to the callback, int constant - * @type int - */ - SCOPE: 3, - - /** - * Adjusted scope, either the element we are registering the event - * on or the custom object passed in by the listener, int constant - * @type int - */ - ADJ_SCOPE: 4, - - /** - * Safari detection is necessary to work around the preventDefault - * bug that makes it so you can't cancel a href click from the - * handler. There is not a capabilities check we can use here. - * @private - */ - isSafari: (navigator.userAgent.match(/safari/gi)), - - /** - * @private - * IE detection needed to properly calculate pageX and pageY. - * capabilities checking didn't seem to work because another - * browser that does not provide the properties have the values - * calculated in a different manner than IE. - */ - isIE: (!this.isSafari && navigator.userAgent.match(/msie/gi)), - - /** - * Appends an event handler - * - * @param {Object} el The html element to assign the - * event to - * @param {String} sType The type of event to append - * @param {Function} fn The method the event invokes - * @param {Object} oScope An arbitrary object that will be - * passed as a parameter to the handler - * @param {boolean} bOverride If true, the obj passed in becomes - * the execution scope of the listener - * @return {boolean} True if the action was successful or defered, - * false if one or more of the elements - * could not have the event bound to it. - */ - addListener: function(el, sType, fn, oScope, bOverride) { - - // The el argument can be an array of elements or element ids. - if ( this._isValidCollection(el)) { - var ok = true; - for (var i=0; i< el.length; ++i) { - ok = ( this.on(el[i], - sType, - fn, - oScope, - bOverride) && ok ); - } - return ok; - - } else if (typeof el == "string") { - // If the el argument is a string, we assume it is - // actually the id of the element. If the page is loaded - // we convert el to the actual element, otherwise we - // defer attaching the event until onload event fires - - // check to see if we need to delay hooking up the event - // until after the page loads. - if (loadComplete) { - el = this.getEl(el); - } else { - // defer adding the event until onload fires - delayedListeners[delayedListeners.length] = - [el, sType, fn, oScope, bOverride]; - - return true; - } - } - - // Element should be an html element or an array if we get - // here. - if (!el) { - return false; - } - - // we need to make sure we fire registered unload events - // prior to automatically unhooking them. So we hang on to - // these instead of attaching them to the window and fire the - // handles explicitly during our one unload event. - if ("unload" == sType && oScope !== this) { - unloadListeners[unloadListeners.length] = - [el, sType, fn, oScope, bOverride]; - return true; - } - - - // if the user chooses to override the scope, we use the custom - // object passed in, otherwise the executing scope will be the - // HTML element that the event is registered on - var scope = (bOverride) ? oScope : el; - - // wrap the function so we can return the oScope object when - // the event fires; - var wrappedFn = function(e) { - return fn.call(scope, YAHOO.util.Event.getEvent(e), - oScope); - }; - - var li = [el, sType, fn, wrappedFn, scope]; - var index = listeners.length; - // cache the listener so we can try to automatically unload - listeners[index] = li; - - if (this.useLegacyEvent(el, sType)) { - var legacyIndex = this.getLegacyIndex(el, sType); - if (legacyIndex == -1) { - - legacyIndex = legacyEvents.length; - // cache the signature for the DOM0 event, and - // include the existing handler for the event, if any - legacyEvents[legacyIndex] = - [el, sType, el["on" + sType]]; - legacyHandlers[legacyIndex] = []; - - el["on" + sType] = - function(e) { - YAHOO.util.Event.fireLegacyEvent( - YAHOO.util.Event.getEvent(e), legacyIndex); - }; - } - - // add a reference to the wrapped listener to our custom - // stack of events - legacyHandlers[legacyIndex].push(index); - - // DOM2 Event model - } else if (el.addEventListener) { - el.addEventListener(sType, wrappedFn, false); - // Internet Explorer abstraction - } else if (el.attachEvent) { - el.attachEvent("on" + sType, wrappedFn); - } - - return true; - - }, - - /** - * Shorthand for YAHOO.util.Event.addListener - * @type function - */ - // on: this.addListener, - - /** - * When using legacy events, the handler is routed to this object - * so we can fire our custom listener stack. - * @private - */ - fireLegacyEvent: function(e, legacyIndex) { - // alert("fireLegacyEvent " + legacyIndex); - var ok = true; - - // var el = legacyEvents[YAHOO.util.Event.EL]; - - /* this is not working because the property may get populated - // fire the event we replaced, if it exists - var origHandler = legacyEvents[2]; - alert(origHandler); - if (origHandler && origHandler.call) { - var ret = origHandler.call(el, e); - ok = (ret); - } - */ - - var le = legacyHandlers[legacyIndex]; - for (i=0; i < le.length; ++i) { - var index = le[i]; - // alert(index); - if (index) { - var li = listeners[index]; - var scope = li[this.ADJ_SCOPE]; - var ret = li[this.WFN].call(scope, e); - ok = (ok && ret); - // alert(ok); - } - } - - return ok; - }, - - /** - * Returns the legacy event index that matches the supplied - * signature - * @private - */ - getLegacyIndex: function(el, sType) { - for (var i=0; i < legacyEvents.length; ++i) { - var le = legacyEvents[i]; - if (le && le[0] == el && le[1] == sType) { - return i; - } - } - - return -1; - }, - - /** - * Logic that determines when we should automatically use legacy - * events instead of DOM2 events. - * @private - */ - useLegacyEvent: function(el, sType) { - - return ( (!el.addEventListener && !el.attachEvent) || - (sType == "click" && this.isSafari) ); - }, - - /** - * Removes an event handler - * - * @param {Object} el the html element or the id of the element to - * assign the event to. - * @param {String} sType the type of event to remove - * @param {Function} fn the method the event invokes - * @return {boolean} true if the unbind was successful, false - * otherwise - */ - removeListener: function(el, sType, fn) { - - // The el argument can be a string - if (typeof el == "string") { - el = this.getEl(el); - // The el argument can be an array of elements or element ids. - } else if ( this._isValidCollection(el)) { - var ok = true; - for (var i=0; i< el.length; ++i) { - ok = ( this.removeListener(el[i], sType, fn) && ok ); - } - return ok; - } - - var cacheItem = null; - var index = this._getCacheIndex(el, sType, fn); - - if (index >= 0) { - cacheItem = listeners[index]; - } - - if (!el || !cacheItem) { - return false; - } - - - if (el.removeEventListener) { - el.removeEventListener(sType, cacheItem[this.WFN], false); - // alert("adsf"); - } else if (el.detachEvent) { - el.detachEvent("on" + sType, cacheItem[this.WFN]); - } - - // removed the wrapped handler - delete listeners[index][this.WFN]; - delete listeners[index][this.FN]; - delete listeners[index]; - - return true; - - }, - - /** - * Returns the event's target element - * @param {Event} ev the event - * @param {boolean} resolveTextNode when set to true the target's - * parent will be returned if the target is a - * text node - * @return {HTMLElement} the event's target - */ - getTarget: function(ev, resolveTextNode) { - var t = ev.target || ev.srcElement; - - if (resolveTextNode && t && "#text" == t.nodeName) { - return t.parentNode; - } else { - return t; - } - }, - - /** - * Returns the event's pageX - * @param {Event} ev the event - * @return {int} the event's pageX - */ - getPageX: function(ev) { - var x = ev.pageX; - if (!x && 0 !== x) { - x = ev.clientX || 0; - - if ( this.isIE ) { - x += this._getScrollLeft(); - } - } - - return x; - }, - - /** - * Returns the event's pageY - * @param {Event} ev the event - * @return {int} the event's pageY - */ - getPageY: function(ev) { - var y = ev.pageY; - if (!y && 0 !== y) { - y = ev.clientY || 0; - - if ( this.isIE ) { - y += this._getScrollTop(); - } - } - - return y; - }, - - /** - * Returns the event's related target - * @param {Event} ev the event - * @return {HTMLElement} the event's relatedTarget - */ - getRelatedTarget: function(ev) { - var t = ev.relatedTarget; - if (!t) { - if (ev.type == "mouseout") { - t = ev.toElement; - } else if (ev.type == "mouseover") { - t = ev.fromElement; - } - } - - return t; - }, - - /** - * Returns the time of the event. If the time is not included, the - * event is modified using the current time. - * @param {Event} ev the event - * @return {Date} the time of the event - */ - getTime: function(ev) { - if (!ev.time) { - var t = new Date().getTime(); - try { - ev.time = t; - } catch(e) { - // can't set the time property - return t; - } - } - - return ev.time; - }, - - /** - * Convenience method for stopPropagation + preventDefault - * @param {Event} ev the event - */ - stopEvent: function(ev) { - this.stopPropagation(ev); - this.preventDefault(ev); - }, - - /** - * Stops event propagation - * @param {Event} ev the event - */ - stopPropagation: function(ev) { - if (ev.stopPropagation) { - ev.stopPropagation(); - } else { - ev.cancelBubble = true; - } - }, - - /** - * Prevents the default behavior of the event - * @param {Event} ev the event - */ - preventDefault: function(ev) { - if (ev.preventDefault) { - ev.preventDefault(); - } else { - ev.returnValue = false; - } - }, - - /** - * Returns the event, should not be necessary for user to call - * @param {Event} the event parameter from the handler - * @return {Event} the event - */ - getEvent: function(e) { - var ev = e || window.event; - - if (!ev) { - var c = this.getEvent.caller; - while (c) { - ev = c.arguments[0]; - if (ev && Event == ev.constructor) { - break; - } - c = c.caller; - } - } - - return ev; - }, - - /** - * Returns the charcode for an event - * @param {Event} ev the event - * @return {int} the event's charCode - */ - getCharCode: function(ev) { - return ev.charCode || (ev.type == "keypress") ? ev.keyCode : 0; - }, - - /** - * @private - * Locating the saved event handler data by function ref - */ - _getCacheIndex: function(el, sType, fn) { - for (var i=0; i< listeners.length; ++i) { - var li = listeners[i]; - if ( li && - li[this.FN] == fn && - li[this.EL] == el && - li[this.TYPE] == sType ) { - return i; - } - } - - return -1; - }, - - /** - * We want to be able to use getElementsByTagName as a collection - * to attach a group of events to. Unfortunately, different - * browsers return different types of collections. This function - * tests to determine if the object is array-like. It will also - * fail if the object is an array, but is empty. - * @param o the object to test - * @return {boolean} true if the object is array-like and populated - */ - _isValidCollection: function(o) { - // alert(o.constructor.toString()) - // alert(typeof o) - - return ( o && // o is something - o.length && // o is indexed - typeof o != "string" && // o is not a string - !o.tagName && // o is not an HTML element - !o.alert && // o is not a window - typeof o[0] != "undefined" ); - - }, - - /** - * @private - * DOM element cache - */ - elCache: {}, - - /** - * We cache elements bound by id because when the unload event - * fires, we can no longer use document.getElementById - * @private - */ - getEl: function(id) { - /* - // this is a problem when replaced via document.getElementById - if (! this.elCache[id]) { - try { - var el = document.getElementById(id); - if (el) { - this.elCache[id] = el; - } - } catch (er) { - } - } - return this.elCache[id]; - */ - - return document.getElementById(id); - }, - - /** - * Clears the element cache - */ - clearCache: function() { - for (i in this.elCache) { - delete this.elCache[i]; - } - }, - - /** - * Called by CustomEvent instances to provide a handle to the - * event * that can be removed later on. Should be package - * protected. - * @private - */ - regCE: function(ce) { - customEvents.push(ce); - }, - - /** - * @private - * hook up any deferred listeners - */ - _load: function(e) { - loadComplete = true; - }, - - /** - * Polling function that runs before the onload event fires, - * attempting * to attach to DOM Nodes as soon as they are - * available - * @private - */ - _tryPreloadAttach: function() { - - // keep trying until after the page is loaded. We need to - // check the page load state prior to trying to bind the - // elements so that we can be certain all elements have been - // tested appropriately - var tryAgain = !loadComplete; - - for (var i=0; i < delayedListeners.length; ++i) { - var d = delayedListeners[i]; - // There may be a race condition here, so we need to - // verify the array element is usable. - if (d) { - - // el will be null if document.getElementById did not - // work - var el = this.getEl(d[this.EL]); - - if (el) { - this.on(el, d[this.TYPE], d[this.FN], - d[this.SCOPE], d[this.ADJ_SCOPE]); - delete delayedListeners[i]; - } - } - } - - if (tryAgain) { - setTimeout("YAHOO.util.Event._tryPreloadAttach()", 50); - } - }, - - /** - * Removes all listeners registered by pe.event. Called - * automatically during the unload event. - */ - _unload: function(e, me) { - for (var i=0; i < unloadListeners.length; ++i) { - var l = unloadListeners[i]; - if (l) { - var scope = (l[this.ADJ_SCOPE]) ? l[this.SCOPE]: window; - l[this.FN].call(scope, this.getEvent(e), l[this.SCOPE] ); - } - } - - if (listeners && listeners.length > 0) { - for (i = 0; i < listeners.length; ++i) { - l = listeners[i]; - if (l) { - this.removeListener(l[this.EL], l[this.TYPE], - l[this.FN]); - } - } - - this.clearCache(); - } - - for (i = 0; i < customEvents.length; ++i) { - customEvents[i].unsubscribeAll(); - delete customEvents[i]; - } - - for (i = 0; i < legacyEvents.length; ++i) { - // dereference the element - delete legacyEvents[i][0]; - // delete the array item - delete legacyEvents[i]; - } - }, - - /** - * Returns scrollLeft - * @private - */ - _getScrollLeft: function() { - return this._getScroll()[1]; - }, - - /** - * Returns scrollTop - * @private - */ - _getScrollTop: function() { - return this._getScroll()[0]; - }, - - /** - * Returns the scrollTop and scrollLeft. Used to calculate the - * pageX and pageY in Internet Explorer - * @private - */ - _getScroll: function() { - var dd = document.documentElement; db = document.body; - if (dd && dd.scrollTop) { - return [dd.scrollTop, dd.scrollLeft]; - } else if (db) { - return [db.scrollTop, db.scrollLeft]; - } else { - return [0, 0]; - } - } - }; - } (); - - YAHOO.util.Event.on = YAHOO.util.Event.addListener; - - if (document && document.body) { - YAHOO.util.Event._load(); - } else { - YAHOO.util.Event.on(window, "load", YAHOO.util.Event._load, - YAHOO.util.Event, true); - } - - YAHOO.util.Event.on(window, "unload", YAHOO.util.Event._unload, - YAHOO.util.Event, true); - - YAHOO.util.Event._tryPreloadAttach(); - -} - diff --git a/web/confirm.cgi b/web/confirm.cgi index 6867169ac..706100d7e 100755 --- a/web/confirm.cgi +++ b/web/confirm.cgi @@ -6,7 +6,7 @@ # Copyright (c) 2006 UK Citizens Online Democracy. All rights reserved. # Email: matthew@mysociety.org. WWW: http://www.mysociety.org # -# $Id: confirm.cgi,v 1.2 2006-09-26 16:11:51 matthew Exp $ +# $Id: confirm.cgi,v 1.3 2006-09-27 23:51:45 matthew Exp $ use strict; require 5.8.0; @@ -40,11 +40,11 @@ sub main { my $type = $q->param('type'); my $id = mySociety::AuthToken::retrieve($type, $token); if ($id) { - if ($type eq 'comment') { + if ($type eq 'update') { dbh()->do("update comment set state='confirmed' where id=?", {}, $id); my $id = dbh()->selectrow_array("select problem_id from comment where id=?", {}, $id); $out = <<EOF; -<p>You have successfully confirmed your comment and you can now <a href="/?id=$id">view it on the site</a>.</p> +<p>You have successfully confirmed your update and you can now <a href="/?id=$id">view it on the site</a>.</p> EOF } elsif ($type eq 'problem') { dbh()->do("update problem set state='confirmed' where id=?", {}, $id); @@ -55,7 +55,7 @@ EOF dbh()->commit(); } else { $out = <<EOF; -<p>Thank you for trying to confirm your comment or problem. We seem to have a +<p>Thank you for trying to confirm your update or problem. We seem to have a problem ourselves though, so <a href="/contact">please let us know what went on</a> and we'll look into it. EOF diff --git a/web/contact.cgi b/web/contact.cgi index f108b50e5..263b7239b 100755 --- a/web/contact.cgi +++ b/web/contact.cgi @@ -6,7 +6,7 @@ # Copyright (c) 2006 UK Citizens Online Democracy. All rights reserved. # Email: matthew@mysociety.org. WWW: http://www.mysociety.org # -# $Id: contact.cgi,v 1.4 2006-09-26 17:20:19 matthew Exp $ +# $Id: contact.cgi,v 1.5 2006-09-27 23:51:45 matthew Exp $ use strict; require 5.8.0; @@ -27,7 +27,7 @@ BEGIN { # Main code for index.cgi sub main { my $q = shift; - print Page::header($q, 'Contact'); + print Page::header($q, 'Contact Us'); my $out = ''; if ($q->param('submit_form')) { $out = contact_submit($q); @@ -75,7 +75,7 @@ sub contact_page { my %input = map { $_ => $q->param($_) } @vars; my %input_h = map { $_ => $q->param($_) ? ent($q->param($_)) : '' } @vars; - my $out = '<h1>Contact</h1>'; + my $out = '<h1>Contact the team</h1>'; if (@errors) { $out .= '<ul id="error"><li>' . join('</li><li>', @errors) . '</li></ul>'; } diff --git a/web/css.css b/web/css.css index a7fd61458..74c20748b 100644 --- a/web/css.css +++ b/web/css.css @@ -26,8 +26,8 @@ form { margin: 0; } -input { - font-size: 100%; +select, input, textarea { + font-size: 99%; } label { @@ -193,6 +193,9 @@ fieldset div.checkbox label { #map input { cursor: crosshair; } +#map input, #map img { + position: absolute; +} #compass { background-color: #ffffff; diff --git a/web/index.cgi b/web/index.cgi index a503c2552..88d8091e0 100755 --- a/web/index.cgi +++ b/web/index.cgi @@ -6,10 +6,11 @@ # Copyright (c) 2006 UK Citizens Online Democracy. All rights reserved. # Email: matthew@mysociety.org. WWW: http://www.mysociety.org # -# $Id: index.cgi,v 1.30 2006-09-27 13:51:23 matthew Exp $ +# $Id: index.cgi,v 1.31 2006-09-27 23:51:45 matthew Exp $ # TODO # Nothing is done about the update checkboxes - not stored anywhere on anything! +# Nothing is done with fixed checkbox either use strict; require 5.8.0; @@ -63,9 +64,9 @@ sub main { if ($q->param('submit_problem')) { $title = 'Submitting your problem'; $out = submit_problem($q); - } elsif ($q->param('submit_comment')) { - $title = 'Submitting your comment'; - $out = submit_comment($q); + } elsif ($q->param('submit_update')) { + $title = 'Submitting your update'; + $out = submit_update($q); } elsif ($q->param('map')) { $title = 'Reporting a problem'; $out = display_form($q); @@ -116,27 +117,27 @@ EOF return $out; } -sub submit_comment { +sub submit_update { my $q = shift; - my @vars = qw(id name email comment updates); + my @vars = qw(id name email update updates); my %input = map { $_ => $q->param($_) || '' } @vars; my @errors; - push(@errors, 'Please enter a comment') unless $input{comment}; + push(@errors, 'Please enter a message') unless $input{update}; push(@errors, 'Please enter your name') unless $input{name}; push(@errors, 'Please enter your email') unless $input{email}; return display_problem($q, @errors) if (@errors); - my $template = File::Slurp::read_file("$FindBin::Bin/../templates/emails/comment-confirm"); + my $template = File::Slurp::read_file("$FindBin::Bin/../templates/emails/update-confirm"); my $id = dbh()->selectrow_array("select nextval('comment_id_seq');"); dbh()->do("insert into comment (id, problem_id, name, email, website, text, state) values (?, ?, ?, ?, ?, ?, 'unconfirmed')", {}, - $id, $input{id}, $input{name}, $input{email}, '', $input{comment}); + $id, $input{id}, $input{name}, $input{email}, '', $input{update}); my %h = (); - $h{comment} = $input{comment}; + $h{update} = $input{update}; $h{name} = $input{name}; - $h{url} = mySociety::Config::get('BASE_URL') . '/C/' . mySociety::AuthToken::store('comment', $id); + $h{url} = mySociety::Config::get('BASE_URL') . '/C/' . mySociety::AuthToken::store('update', $id); dbh()->commit(); my $email = mySociety::Email::construct_email({ @@ -153,8 +154,8 @@ sub submit_comment { <p>The confirmation email <strong>may</strong> take a few minutes to arrive — <em>please</em> be patient.</p> <p>If you use web-based email or have 'junk mail' filters, you may wish to check your bulk/spam mail folders: sometimes, our messages are marked that way.</p> <p>You must now click on the link within the email we've just sent you - -<br>if you do not, your comment will not be posted.</p> -<p>(Don't worry - we'll hang on to your comment while you're checking your email.)</p> +<br>if you do not, your update will not be posted.</p> +<p>(Don't worry - we'll hang on to your update while you're checking your email.)</p> EOF } else { $out = <<EOF; @@ -261,6 +262,8 @@ EOF } # XXX: How to do this for not London? # And needs to use polygon, not box + # Needs to return all council types, so passing in an array of types would be good + # And then display choice to user my $council = mySociety::MaPit::get_voting_area_by_location_en($easting, $northing, 'box', 'LBO'); my $areas_info = mySociety::MaPit::get_voting_areas_info($council); $council = join(', ', map { $areas_info->{$_}->{name} } @$council); @@ -292,7 +295,7 @@ exact location of the problem (ie. on a wall or the floor), and so on.</p>'; <div><label for="form_email">Email:</label> <input type="text" value="$input_h{email}" name="email" id="form_email" size="30"></div> <div class="checkbox"><input type="checkbox" name="updates" id="form_updates" value="1"$updates> -<label for="form_updates">Receive updates about this problem</label></div> +<label for="form_updates">Receive email when updates are left on this problem</label></div> <div class="checkbox"><input type="submit" name="submit_problem" value="Submit"></div> </fieldset> @@ -390,6 +393,7 @@ EOF } $out .= <<EOF; </ul> + <h2>Recent updates to problems?</h2> <h2>Recently fixed problems</h2> <ul> EOF @@ -421,13 +425,13 @@ sub display_pin { my ($px, $py, $col) = @_; $col = 'red' unless $col; return '' if ($px<0 || $px>508 || $py<0 || $py>508); - return '<img src="/i/pin_'.$col.'.png" alt="Problem" style="top:' . ($py-20) . 'px; right:' . ($px-6) . 'px; position: absolute;">'; + return '<img class="pin" src="/i/pin_'.$col.'.png" alt="Problem" style="top:' . ($py-20) . 'px; right:' . ($px-6) . 'px; position: absolute;">'; } sub display_problem { my ($q, @errors) = @_; - my @vars = qw(id name email comment updates x y); + my @vars = qw(id name email update updates x y); my %input = map { $_ => $q->param($_) || '' } @vars; my %input_h = map { $_ => $q->param($_) ? ent($q->param($_)) : '' } @vars; $input{x} += 0; @@ -463,20 +467,20 @@ sub display_problem { my $back = NewURL($q, id=>undef); $out .= '<p align="right"><a href="' . $back . '">Back to listings</a></p>'; - # Display comments - my $comments = select_all( + # Display updates + my $updates = select_all( "select id, name, extract(epoch from whenposted) as whenposted, text from comment where problem_id = ? and state='confirmed' order by whenposted desc", $input{id}); - if (@$comments) { - $out .= '<div id="comments"> <h3>Comments</h3>'; - foreach my $row (@$comments) { + if (@$updates) { + $out .= '<div id="updates"> <h2>Updates</h2>'; + foreach my $row (@$updates) { $out .= "<div><em>Posted by $row->{name} at " . prettify_epoch($row->{whenposted}) . '</em>'; $out .= '<br>' . $row->{text} . '</div>'; } $out .= '</div>'; } - $out .= '<h3>Add Comment</h3>'; + $out .= '<h2>Provide an update</h2>'; if (@errors) { $out .= '<ul id="error"><li>' . join('</li><li>', @errors) . '</li></ul>'; } @@ -485,16 +489,18 @@ sub display_problem { $out .= <<EOF; <form method="post" action="./"> <fieldset> -<input type="hidden" name="submit_comment" value="1"> +<input type="hidden" name="submit_update" value="1"> <input type="hidden" name="id" value="$input_h{id}"> <div><label for="form_name">Name:</label> <input type="text" name="name" id="form_name" value="$input_h{name}" size="30"></div> <div><label for="form_email">Email:</label> <input type="text" name="email" id="form_email" value="$input_h{email}" size="30"> (needed?)</div> -<div><label for="form_comment">Comment:</label> -<textarea name="comment" id="form_comment" rows="7" cols="30">$input_h{comment}</textarea></div> +<div><label for="form_update">Update:</label> +<textarea name="updatet" id="form_update" rows="7" cols="30">$input_h{update}</textarea></div> +<div class="checkbox"><input type="checkbox" name="fixed" id="form_fixed" value="1"> +<label for="form_fixed">Has the problem been fixed?</label></div> <div class="checkbox"><input type="checkbox" name="updates" id="form_updates" value="1"$updates> -<label for="form_updates">Receive updates about this problem</label></div> +<label for="form_updates">Receive email when updates are left on this problem</label></div> <div class="checkbox"><input type="submit" value="Post"></div> </fieldset> </form> @@ -528,7 +534,7 @@ sub display_map { if ($type) { my $pc_enc = ent($q->param('pc')); $out .= <<EOF; -<form action="./" method="get"> +<form action="./" method="get" id="mapForm"> <input type="hidden" name="map" value="1"> <input type="hidden" name="x" value="$x"> <input type="hidden" name="y" value="$y"> @@ -539,9 +545,9 @@ EOF $img_type = '<img'; } $out .= <<EOF; - <div id="map"> - $img_type id="2.2" name="tile_$tl" src="$tl_src" style="top:0px; left:0px;">$img_type id="3.2" name="tile_$tr" src="$tr_src" style="top:0px; left:254px;"><br>$img_type id="2.3" name="tile_$bl" src="$bl_src" style="top:254px; left:0px;">$img_type id="3.3" name="tile_$br" src="$br_src" style="top:254px; left:254px;"> - </div> + <div id="map"><div id="drag"> + $img_type id="2.2" name="tile_$tl" src="$tl_src" style="top:0px; left:0px;">$img_type id="2.3" name="tile_$tr" src="$tr_src" style="top:0px; left:254px;"><br>$img_type id="3.2" name="tile_$bl" src="$bl_src" style="top:254px; left:0px;">$img_type id="3.3" name="tile_$br" src="$br_src" style="top:254px; left:254px;"> + </div></div> EOF $out .= Page::compass($q, $x, $y) if $compass; $out .= '<div id="side">'; @@ -578,6 +584,7 @@ sub postcode_check { } throw Error::Simple("I'm afraid that postcode isn't yet covered by us.\n") unless $areas && @councils; + # XXX: Pick first council, hmm my $council = $areas->{$councils[0]}; throw Error::Simple("I'm afraid that postcode isn't in our covered London boroughs.\n") if (@councils_allowed && !vec($valid_councils, $council, 1)); |