[ Mini Kiebo ]
Server: Windows NT DESKTOP-5B8S0D4 6.2 build 9200 (Windows 8 Professional Edition) i586
Path:
D:
/
xampp182
/
htdocs
/
simpeg
/
zapatec
/
zptime
/
utils
/
[
Home
]
File: resizable.js
//$Id: resizable.js 7453 2007-06-16 18:05:03Z vkulov $ /** * This is a set of functionality used for resizing object * and is implemented in interface (mixin) manner. */ Zapatec.Resizable = {}; /** * Makes the element resizable. This means attaching events, * and making some preparations. * @return {boolean} true if success, otherwise false. */ Zapatec.Resizable.makeResizable = function() { if (!this.requireInterface("Zapatec.Sizable")) { return false; } if (!this.requireInterface("Zapatec.CommandEvent")) { return false; } var hooks = Zapatec.Array(this._getResizableHooks()); var measurement = this.getSizableMeasurement(); var self = this, result = false; var config = this.getResizeConfig(); //if direction includes top and left resizing we need Zapatec.Movable interface if (/(vertical|horizontal|top|left|all)/.test(config.direction) && !this.hasInterface("Zapatec.Movable")) { Zapatec.Log({description : "The object with ID '" + this.id + "' has no Zapatec.Movable interface so can not be resizable!"}); return false; } //we need to save references to anonymous event listenrs var listenersObj = this._getRestorer().getSavedProps()["resizeListeners"] = { mousedown : function(ev) { return self.resizeStart(ev); }, hover : function(ev) { if (!self.isResizing() && self.canResize()) { self._toggleResizeCursor(ev); } }, mouseover : function(ev) { if (self.hasInterface("Zapatec.Draggable")) { self._setCanDrag(false); } }, mouseout : function(ev) { if (self.hasInterface("Zapatec.Draggable")) { self._setCanDrag(true); } } }; hooks.each(function(index, hook) { if (!Zapatec.isHtmlElement(hook)) { return; } //if we are here than there is at least one hook :) result = true; //this for disabling text selection on resize if (Zapatec.is_gecko) { hook.style.setProperty("-moz-user-select", "none", ""); } //adding resize start event Zapatec.Utils.addEvent(hook, 'mousedown', listenersObj.mousedown); Zapatec.Utils.addEvent(hook, 'mouseover', listenersObj.mouseover); Zapatec.Utils.addEvent(hook, 'mouseout', listenersObj.mouseout); }); //if there are no hooks, we use measurement border as trigger if (!result) { //if it is not an HTML element then we have no trigger if (!Zapatec.isHtmlElement(measurement)) { return false; } //result is true now result = true; //adding resize events Zapatec.Utils.addEvent(measurement, 'mousedown', listenersObj.mousedown); Zapatec.Utils.addEvent(measurement, 'mousemove', listenersObj.hover); } //returning result return result; }; /** * This method is used for determining cursor * for current mouse position if the resizing * trigger is elements border. * @param ev {object} event object. */ Zapatec.Resizable._toggleResizeCursor = function(ev) { ev = ev || window.event; var el = this.getSizableMeasurement(); //lets get the position of the mouse var config = this.getResizeConfig(); //mouse position var oPos = Zapatec.Utils.getMousePos(ev); var posX = oPos.pageX; var posY = oPos.pageY; //element boundaries var pos = Zapatec.Utils.getElementOffset(el); var left = pos.x, right = pos.x + Zapatec.Utils.getWidth(el); var top = pos.y, bottom = pos.y + Zapatec.Utils.getHeight(el); //resizing border thickness var borderThickness = config.borderThickness; var cornerThickness = config.cornerThickness; //checks if point is in rectangle function inRect(x, y, left, top, right, bottom) { if ((x > left) && (x < right) && (y > top) && (y < bottom)) { return true; } return false; } //checks if value is in range function inRange(value, minVal, maxVal) { if ((value > minVal) && (value < maxVal)) { return true; } return false; } //sets cursor and disables/enables dragging var self = this; function toggleResizing(cursor) { el.style.cursor = cursor; if (self.hasInterface("Zapatec.Draggable")) { self._setCanDrag((cursor === "") ? true : false); } } //getting the needed direction cursor and toggling drag switch (true) { case (inRect(posX, posY, left, top, left + borderThickness, top + borderThickness)) : { toggleResizing("nw-resize"); break; } case (inRect(posX, posY, right - cornerThickness, bottom - cornerThickness, right, bottom)) : { toggleResizing("se-resize"); break; } case (inRect(posX, posY, right - cornerThickness, top, right, top + borderThickness)) : { toggleResizing("ne-resize"); break; } case (inRect(posX, posY, left, bottom - cornerThickness, left + cornerThickness, bottom)) : { toggleResizing("sw-resize"); break; } case (inRange(posX, left, left + borderThickness)) : { toggleResizing("w-resize"); break; } case (inRange(posX, right - borderThickness, right)) : { toggleResizing("e-resize"); break; } case (inRange(posY, top, top + borderThickness)) : { toggleResizing("n-resize"); break; } case (inRange(posY, bottom - borderThickness, bottom)) : { toggleResizing("s-resize"); break; } default : { toggleResizing(""); break; } } //correcting direction el.style.cursor = this._correctDirection(el.style.cursor); if (el.style.cursor == "") { if (this.hasInterface("Zapatec.Draggable")) { this._setCanDrag(true); } } }; /** * Corrects the cursor value to fit the * direction config option. * @param direction {string} cursor value, * meaning the direction of resizing. * @return {string} new cursor, meaning the * enabled direction. */ Zapatec.Resizable._correctDirection = function(direction) { //getting config var config = this.getResizeConfig(); //taking direction part direction = direction.replace("-resize", ""); //excluding impossible action for (var i = 0; i < direction.length; ++i) { switch(direction.charAt(i)) { case "n" : { if (!/(all|vertical|top)/.test(config.direction)) { direction = direction.replace("n", ""); } } case "s" : { if (!/(all|vertical|bottom)/.test(config.direction)) { direction = direction.replace("s", ""); } } case "w" : { if (!/(all|horizontal|left)/.test(config.direction)) { direction = direction.replace("w", ""); } } case "e" : { if (!/(all|horizontal|right)/.test(config.direction)) { direction = direction.replace("e", ""); } } } } //returning new cursor if (direction != "") { return direction + "-resize"; } return ""; }; /** * This is an event handler for the mouse down event * of the hook element. * @param ev {MouseEvent} this is mouse event triggered by * mouse down action. * @return {false} false for stoping events in some browsers. */ Zapatec.Resizable.resizeStart = function(ev, deb) { if (!this.canResize()) { return true; } //getting event object ev = ev || window.event; //check mouse button, only left one is valid var iButton = ev.button || ev.which; if (iButton > 1) { return true; } var self = this; var config = this.getResizeConfig(); //getting the direction of resizement var target = ev.currentTarget || ev.srcElement; while(target != document.body && target.style.cursor.indexOf("resize") == -1) { target = target.parentNode; } //it is pointed in the cursor style property of trigger element if (target.style.cursor.indexOf("resize") == -1) { return true; } //correction direction var direction = this._correctDirection(target.style.cursor); if (direction == "") { return true; } //calling the handler if (this.fireEvent("beforeResizeInit", ev) === false) { return true; } //calling global event handler if (Zapatec.GlobalEvents.fireEvent("beforeResizeInit", ev, this) === false) { return true; } //now we started resizing! this._setResizing(true); //preparing elements this._proceedResizableElements("resizeStart"); //lets get the starting position of the mouse var oPos = Zapatec.Utils.getMousePos(ev); var mouseX = oPos.pageX; var mouseY = oPos.pageY; //making object sizable this.makeSizable(); //starting sizing this.startSizing(); if (/(vertical|horizontal|top|left|all)/.test(config.direction)) { //making object movable this.makeMovable(); //starting movement this.startMove(); } Zapatec.Utils.cover.show( 1000001, direction, function(ev) { return self.resizeMove(ev); }, function(ev) { return self.resizeEnd(ev); } ); this._setResizingPoint(mouseX, mouseY, direction.replace("-resize", "")); //calling the handler this.fireEvent("onResizeInit", ev); //calling the global handler Zapatec.GlobalEvents.fireEvent("onResizeInit", ev, this); if (config.stopEvent) { return Zapatec.Utils.stopEvent(ev); } else { return true; } }; /** * This is an event handler for the mouse move event * of the cover element. * @param ev {MouseEvent} this is mouse event triggered by * mouse move action. * @return {false} false for stoping events in some browsers. */ Zapatec.Resizable.resizeMove = function(ev){ if (!this.isResizing()) { return true; } //getting event object ev = ev || window.event; //calling the handler if (this.fireEvent("beforeResize", ev) === false) { return true; } //calling global event handler if (Zapatec.GlobalEvents.fireEvent("beforeResize", ev, this) === false) { return true; } //mouse position var oPos = Zapatec.Utils.getMousePos(ev); var x = oPos.pageX; var y = oPos.pageY; var movePoint = this.getResizingPoint(); var direction = Zapatec.Utils.cover.style.cursor; direction = direction.replace("-resize", ""); if (direction.indexOf("w") > -1) { var width = this.getWidth(); this.setWidth(width + (movePoint.x - x)); if (width != this.getWidth()) { this.moveFor(width - this.getWidth(), null); } } if (direction.indexOf("e") > -1) { this.setWidth(this.getWidth() + (x - movePoint.x)); } if (direction.indexOf("n") > -1) { var height = this.getHeight(); this.setHeight(height + (movePoint.y - y)); if (height != this.getHeight()) { this.moveFor(null, height - this.getHeight()); } } if (direction.indexOf("s") > -1) { this.setHeight(this.getHeight() + (y - movePoint.y)); } this._setResizingPoint(x, y, direction); //calling the handler this.fireEvent("onResize", ev); //calling global event handler Zapatec.GlobalEvents.fireEvent("onResize", ev, this); // Stop event return Zapatec.Utils.stopEvent(ev); }; /** * This is an event handler for the mouse up event * of the cover element. * @param ev {MouseEvent} this is mouse event triggered by * mouse up action. * @return {false} false for stoping events in some browsers. */ Zapatec.Resizable.resizeEnd = function(ev){ if (!this.isResizing()) { return true; } //getting event object ev = ev || window.event; var self = this; var config = this.getResizeConfig(); //calling the handler if (this.fireEvent("beforeResizeEnd", ev) === false) { return true; } //calling global event handler if (Zapatec.GlobalEvents.fireEvent("beforeResizeEnd", ev, this) === false) { return true; } //unprepareing elements this._proceedResizableElements("resizeEnd"); //hiding the cover Zapatec.Utils.cover.hide(); //clearing moving point this._setResizingPoint(null, null); //now we ended dragging! this._setResizing(false); //ending sizing this.endSizing(); if (/(vertical|horizontal|top|left|all)/.test(config.direction)) { //ending movement this.endMove(); } //calling the handler this.fireEvent("onResizeEnd", ev); //calling global event handler Zapatec.GlobalEvents.fireEvent("onResizeEnd", ev, this); // Stop event return Zapatec.Utils.stopEvent(ev); }; /** * Restores object from resizing. */ Zapatec.Resizable.restoreOfResize = function() { var config = this.getResizeConfig(); this.restoreOfSizing(); if (/(vertical|horizontal|top|left|all)/.test(config.direction)) { this.restoreOfMove(); } var hooks = Zapatec.Array(this._getResizableHooks()); var self = this; var result = false; //we need to save references to anonymous event listenrs var listenersObj = this._getRestorer().getSavedProps()["resizeListeners"]; hooks.each(function(index, hook) { if (!Zapatec.isHtmlElement(hook)) { return; } result = true; if (Zapatec.is_gecko) { hook.style.setProperty("-moz-user-select", "", ""); } Zapatec.Utils.removeEvent(hook, 'mousedown', listenersObj.mousedown); Zapatec.Utils.removeEvent(hook, 'mouseover', listenersObj.mouseover); Zapatec.Utils.removeEvent(hook, 'mouseout', listenersObj.mouseout); }); if (!result) { var measurement = this.getSizableMeasurement(); if (!Zapatec.isHtmlElement(measurement)) { return false } Zapatec.Utils.removeEvent(measurement, 'mousedown', listenersObj.mousedown); Zapatec.Utils.removeEvent(measurement, 'mousemove', listenersObj.hover); } return true; }; /** * This method should return the array of elements that * are handles for resizing. These are elements that * trigger resize start. This is almost empty method * that should be overwritten in implementing class. * @return {array} array of hook elements. */ Zapatec.Resizable._getResizableHooks = function() { if (this.getContainer) { return this.getContainer(); } else { return null; } }; /** * This method returns true if object started * resizing, otherwise false. * @return {boolean} true if object is resizing, * otherwise false. */ Zapatec.Resizable.isResizing = function() { return this.resizing; }; /** * This method returns true if resizing is enabled, * otherwise it should return false. * @return {boolean} true if resizing enabled, otherwise false. */ Zapatec.Resizable.canResize = function() { return this.canResize; }; /** * Turns on or off resizing. * @param on {boolean} whether we want to * turn on or off resizing. */ Zapatec.Resizable._setCanResize = function(on) { this.canResize = on; }; /** * Should returns the resizing configuration. * @return {object} configuration object. */ Zapatec.Resizable.getResizeConfig = function() { return this.getConfiguration(); }; /** * Sets the resizing configuration. * @param config {object} a set of new configuration. */ Zapatec.Resizable.setResizeConfig = function(config) { this.reconfigure(config); }; /** * Sets the flag of resizing to on or off. * @param on {boolean} true to turn on, otherwise false. */ Zapatec.Resizable._setResizing = function(on) { this.resizing = on; }; /** * This method handles overflow of the size. * @param limit {number} limit that was overflowed. * @param dimension {string} dimension of size. * @return {number or boolean} new size or false. */ Zapatec.Resizable._handleSizeOverflow = function(limit, dimension) { if (!this.isResizing()) { Zapatec.Sizable._handleSizeOverflow.call(this, limit, dimension); } return limit; }; /** * Returns the Zapatec.SRProp object. * It is used for saving and restoring * object properties. * @return {object} Zapatec.SRProp object. */ Zapatec.Resizable._getRestorer = function() { if (!this.restorer || this.restorer.constructor != Zapatec.SRProp) { this.restorer = new Zapatec.SRProp(this); } return this.restorer; }; /** * Proceeds the resizable elements, to create * a separate array for elements that are actually sizing. * This is used to handle method of resizing. * @param resizeState {string} "resizeStart" or "resizeEnd" string * to point the state of resizing. */ Zapatec.Resizable._proceedResizableElements = function(resizeState) { //drag configuration var config = this.getResizeConfig(), copy = null, measurement = null, self = this; switch (config.method) { case "copy" : { if (resizeState == "resizeStart") { var measurement = this.getSizableMeasurement(); if (!Zapatec.isHtmlElement(measurement)) { return false; } copy = measurement.cloneNode(false); measurement.parentNode.insertBefore(copy, measurement); //we substitute method of Zapatec.Sizable //interface to get needed result this._getRestorer().saveProp("getSizableElements"); //we need to move copy this.getSizableElements = function() { return copy; }; this._getRestorer().saveProp("getSizableMeasurement"); //we need to use copy as measurement this.getSizableMeasurement = function() { return copy; }; if (/(vertical|horizontal|top|left|all)/.test(config.direction)) { //we substitute method of Zapatec.Movable //interface to get needed result this._getRestorer().saveProp("getMovableElements"); //we need to move copy this.getMovableElements = function(resetArray) { return copy; }; this._getRestorer().saveProp("getMovableMeasurement"); //we need to use copy as measurement this.getMovableMeasurement = function() { return copy; }; } } else if (resizeState == "resizeEnd") { //destroying elements if needed copy = this.getMovableElements(); var width = this.getWidth(); var height = this.getHeight(); var pos = null; if (/(vertical|horizontal|top|left|all)/.test(config.direction)) { pos = this.getPosition(); } copy.parentNode.removeChild(copy); //returning old methods this._getRestorer().restoreProp("getSizableElements"); this._getRestorer().restoreProp("getSizableMeasurement"); this._getRestorer().restoreProp("getMovableElements"); this._getRestorer().restoreProp("getMovableMeasurement"); this.setWidth(width); this.setHeight(height); if (pos) { this.setPosition(pos.x, pos.y); } } break; } default : { break; } } }; /** * Sets the coordinates of the point which is thought as * the center of resizement of the object. * @param x {number} x coordinate of the point. * @param y {number} y coordinate of the point. * @param direction {string} direction of resizing. */ Zapatec.Resizable._setResizingPoint = function(x, y, direction) { var resizingPoint = this._getResizingPointObject(); //this means resize end, so we should reset the object if (x === null || y === null) { resizingPoint.x = null; resizingPoint.y = null; resizingPoint.offsetX = null; resizingPoint.offsetY = null; return; } //this means resize start, so we fill object if (resizingPoint.x === null || resizingPoint.y === null) { resizingPoint.x = x; resizingPoint.y = y; var width = this.getWidth(); var height = this.getHeight(); if (direction.match(/(n|w)/)) { var pos = this.getScreenPosition(); } if (direction.indexOf("n") != -1) { resizingPoint.offsetY = y - pos.y; } if (direction.indexOf("w") != -1) { resizingPoint.offsetX = x - pos.x; } if (direction.indexOf("e") != -1) { resizingPoint.offsetX = x - width; } if (direction.indexOf("s") != -1) { resizingPoint.offsetY = y - height; } resizingPoint.offsetX = resizingPoint.offsetX || 0; resizingPoint.offsetY = resizingPoint.offsetY || 0; } else {//changing point coordinates as this is drag move var diffX = 0; var diffY = 0; var width = this.getWidth(); var height = this.getHeight(); if (direction.match(/(n|w)/)) { var pos = this.getScreenPosition(); } if (direction.indexOf("n") != -1) { diffY = pos.y; } if (direction.indexOf("w") != -1) { diffX = pos.x; } if (direction.indexOf("e") != -1) { diffX = width; } if (direction.indexOf("s") != -1) { diffY = height; } resizingPoint.x = diffX + resizingPoint.offsetX; resizingPoint.y = diffY + resizingPoint.offsetY; } return; }; /** * Returns the coordinate of the resizing point. * Its the point which is thought to be the * center of resizement. * @return {object} object with x and y properties. */ Zapatec.Resizable.getResizingPoint = function() { var resizingPoint = this._getResizingPointObject(); return {x : resizingPoint.x, y : resizingPoint.y}; }; /** * Returns the object which holds the information about resizing point. * @return {object} object with x, y, offsetX and offsetY properties. */ Zapatec.Resizable._getResizingPointObject = function() { if (!this.resizingPoint || typeof this.resizingPoint != "object") { this.resizingPoint = {x : null, y : null, offsetX : null, offsetY : null}; } return this.resizingPoint; }; /** * This is Zapatec.Utils.Resizable object definition. * It represents most of the routines and * events connected to resizing of the object. * @param config {object} - all parameters are passed as the properties of this object. * * Constructor recognizes the following properties of the config object (rest options are inherited * from Zapatec.Utils.Sizable object, see sizable.js comments) * \code * prop. name | description * ------------------------------------------------------------------------------------------------- * method | {string} Method of resizing, can be "self" or "copy" (default "self"). * stopEvent | {boolean} Should we stop mousedown event of the handler (default true). * handlers | {array} Array of handles of resizing, otherwise container border will be * | used as a trigger (default null). * direction | {string} Direction in which you can resize. Can be "all", "vertical", * | "horizontal", "top", "left", "right", "bottom" and their combinations * | using "-" separator (default "all"). * borderThickness | {number} If there is no handler for resizing, this is the thickness of * | the container border which still triggers resizing. * cornerThickness | {number} If there is no handler for resizing, this is the thickness of * | the container corner which still triggers resizing. * * \endcode */ Zapatec.Utils.Resizable = function(config) { Zapatec.Utils.Resizable.SUPERconstructor.call(this, config); }; Zapatec.Utils.Resizable.id = "Zapatec.Utils.Resizable"; Zapatec.inherit(Zapatec.Utils.Resizable, Zapatec.Utils.Sizable); Zapatec.implement(Zapatec.Utils.Resizable, "Zapatec.Movable"); Zapatec.implement(Zapatec.Utils.Resizable, "Zapatec.Resizable"); /** * Inits the object with set of config options. * @param config {object} configuration parameters. */ Zapatec.Utils.Resizable.prototype.init = function(config) { //calling parent init Zapatec.Utils.Resizable.SUPERclass.init.call(this, config); this.restoreOfSizing(); //makes object resizable this.makeResizable(); }; /** * Sets the default configuration of the object and * inits it with user defined values. * @param config {object} configuration parameters. */ Zapatec.Utils.Resizable.prototype.configure = function(config) { //method of resizing this.defineConfigOption("method", "self"); //should we stop mouse down event! this.defineConfigOption("stopEvent", true); //the handlers for resizing this.defineConfigOption("handlers", null); //the border thickness for resizing, when no handler is ussed this.defineConfigOption("borderThickness", 10); //the corner thickness for resizing, when no handler is ussed this.defineConfigOption("cornerThickness", 10); //direction of resizing this.defineConfigOption("direction", "all"); // Call parent method Zapatec.Utils.Resizable.SUPERclass.configure.call(this, config); config = this.getConfiguration(); //correcting handlers option config.handlers = Zapatec.Array(config.handlers); config.handlers.each(function(index, handler) { handler = Zapatec.Widget.getElementById(handler); handler = Zapatec.Utils.img2div(handler); config.handlers[index] = handler; }); }; /** * Reconfigures the object with new parameters. * @param config {object} new configuration parameters. */ Zapatec.Utils.Resizable.prototype.reconfigure = function(config) { // Call parent method Zapatec.Utils.Resizable.SUPERclass.reconfigure.call(this, config); }; /** * Returns the handlers. * @return {array} handler elements. */ Zapatec.Utils.Resizable.prototype._getResizableHooks = function() { return this.getConfiguration().handlers; };