2012-07-19 00:11:26 +00:00
|
|
|
/**
|
|
|
|
* VisualEditor Position class.
|
2012-07-19 21:25:16 +00:00
|
|
|
*
|
2012-07-19 00:11:26 +00:00
|
|
|
* @copyright 2011-2012 VisualEditor Team and others; see AUTHORS.txt
|
|
|
|
* @license The MIT License (MIT); see LICENSE.txt
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
2011-11-02 21:00:55 +00:00
|
|
|
/**
|
|
|
|
* Pixel position.
|
2012-06-20 01:20:28 +00:00
|
|
|
*
|
2011-11-02 21:00:55 +00:00
|
|
|
* This can also support an optional bottom field, to represent a vertical line, such as a cursor.
|
2012-06-20 01:20:28 +00:00
|
|
|
*
|
2011-11-02 21:00:55 +00:00
|
|
|
* @class
|
|
|
|
* @constructor
|
Object management: Object create/inherit/clone utilities
* For the most common case:
- replace ve.extendClass with ve.inheritClass (chose slightly
different names to detect usage of the old/new one, and I
like 'inherit' better).
- move it up to below the constructor, see doc block for why.
* Cases where more than 2 arguments were passed to
ve.extendClass are handled differently depending on the case.
In case of a longer inheritance tree, the other arguments
could be omitted (like in "ve.ce.FooBar, ve.FooBar,
ve.Bar". ve.ce.FooBar only needs to inherit from ve.FooBar,
because ve.ce.FooBar inherits from ve.Bar).
In the case of where it previously had two mixins with
ve.extendClass(), either one becomes inheritClass and one
a mixin, both to mixinClass().
No visible changes should come from this commit as the
instances still all have the same visible properties in the
end. No more or less than before.
* Misc.:
- Be consistent in calling parent constructors in the
same order as the inheritance.
- Add missing @extends and @param documentation.
- Replace invalid {Integer} type hint with {Number}.
- Consistent doc comments order:
@class, @abstract, @constructor, @extends, @params.
- Fix indentation errors
A fairly common mistake was a superfluous space before the
identifier on the assignment line directly below the
documentation comment.
$ ack "^ [^*]" --js modules/ve
- Typo "Inhertiance" -> "Inheritance".
- Replacing the other confusing comment "Inheritance" (inside
the constructor) with "Parent constructor".
- Add missing @abstract for ve.ui.Tool.
- Corrected ve.FormatDropdownTool to ve.ui.FormatDropdownTool.js
- Add function names to all @constructor functions. Now that we
have inheritance it is important and useful to have these
functions not be anonymous.
Example of debug shot: http://cl.ly/image/1j3c160w3D45
Makes the difference between
< documentNode;
> ve_dm_DocumentNode
...
: ve_dm_BranchNode
...
: ve_dm_Node
...
: ve_dm_Node
...
: Object
...
without names (current situation):
< documentNode;
> Object
...
: Object
...
: Object
...
: Object
...
: Object
...
though before this commit, it really looks like this
(flattened since ve.extendClass really did a mixin):
< documentNode;
> Object
...
...
...
Pattern in Sublime (case-sensitive) to find nameless
constructor functions:
"^ve\..*\.([A-Z])([^\.]+) = function \("
Change-Id: Iab763954fb8cf375900d7a9a92dec1c755d5407e
2012-09-05 06:07:47 +00:00
|
|
|
* @param left {Number} Horizontal position
|
|
|
|
* @param top {Number} Vertical top position
|
|
|
|
* @param bottom {Number} Vertical bottom position of bottom (optional, default: top)
|
|
|
|
* @property left {Number} Horizontal position
|
|
|
|
* @property top {Number} Vertical top position
|
|
|
|
* @property bottom {Number} Vertical bottom position of bottom
|
2011-11-02 21:00:55 +00:00
|
|
|
*/
|
Object management: Object create/inherit/clone utilities
* For the most common case:
- replace ve.extendClass with ve.inheritClass (chose slightly
different names to detect usage of the old/new one, and I
like 'inherit' better).
- move it up to below the constructor, see doc block for why.
* Cases where more than 2 arguments were passed to
ve.extendClass are handled differently depending on the case.
In case of a longer inheritance tree, the other arguments
could be omitted (like in "ve.ce.FooBar, ve.FooBar,
ve.Bar". ve.ce.FooBar only needs to inherit from ve.FooBar,
because ve.ce.FooBar inherits from ve.Bar).
In the case of where it previously had two mixins with
ve.extendClass(), either one becomes inheritClass and one
a mixin, both to mixinClass().
No visible changes should come from this commit as the
instances still all have the same visible properties in the
end. No more or less than before.
* Misc.:
- Be consistent in calling parent constructors in the
same order as the inheritance.
- Add missing @extends and @param documentation.
- Replace invalid {Integer} type hint with {Number}.
- Consistent doc comments order:
@class, @abstract, @constructor, @extends, @params.
- Fix indentation errors
A fairly common mistake was a superfluous space before the
identifier on the assignment line directly below the
documentation comment.
$ ack "^ [^*]" --js modules/ve
- Typo "Inhertiance" -> "Inheritance".
- Replacing the other confusing comment "Inheritance" (inside
the constructor) with "Parent constructor".
- Add missing @abstract for ve.ui.Tool.
- Corrected ve.FormatDropdownTool to ve.ui.FormatDropdownTool.js
- Add function names to all @constructor functions. Now that we
have inheritance it is important and useful to have these
functions not be anonymous.
Example of debug shot: http://cl.ly/image/1j3c160w3D45
Makes the difference between
< documentNode;
> ve_dm_DocumentNode
...
: ve_dm_BranchNode
...
: ve_dm_Node
...
: ve_dm_Node
...
: Object
...
without names (current situation):
< documentNode;
> Object
...
: Object
...
: Object
...
: Object
...
: Object
...
though before this commit, it really looks like this
(flattened since ve.extendClass really did a mixin):
< documentNode;
> Object
...
...
...
Pattern in Sublime (case-sensitive) to find nameless
constructor functions:
"^ve\..*\.([A-Z])([^\.]+) = function \("
Change-Id: Iab763954fb8cf375900d7a9a92dec1c755d5407e
2012-09-05 06:07:47 +00:00
|
|
|
ve.Position = function ve_Position( left, top, bottom ) {
|
2011-11-02 21:00:55 +00:00
|
|
|
this.left = left || 0;
|
|
|
|
this.top = top || 0;
|
|
|
|
this.bottom = bottom || this.top;
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Static Methods */
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates position object from the page position of an element.
|
2012-06-20 01:20:28 +00:00
|
|
|
*
|
2011-11-02 21:00:55 +00:00
|
|
|
* @static
|
|
|
|
* @method
|
|
|
|
* @param $element {jQuery} Element to get offset from
|
2012-02-06 23:50:56 +00:00
|
|
|
* @returns {ve.Position} Position with element data applied
|
2011-11-02 21:00:55 +00:00
|
|
|
*/
|
2012-08-07 01:50:44 +00:00
|
|
|
ve.Position.newFromElementPagePosition = function ( $element ) {
|
2011-11-02 21:00:55 +00:00
|
|
|
var offset = $element.offset();
|
2012-02-06 23:50:56 +00:00
|
|
|
return new ve.Position( offset.left, offset.top );
|
2011-11-02 21:00:55 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates position object from the layer position of an element.
|
2012-06-20 01:20:28 +00:00
|
|
|
*
|
2011-11-02 21:00:55 +00:00
|
|
|
* @static
|
|
|
|
* @method
|
|
|
|
* @param $element {jQuery} Element to get position from
|
2012-02-06 23:50:56 +00:00
|
|
|
* @returns {ve.Position} Position with element data applied
|
2011-11-02 21:00:55 +00:00
|
|
|
*/
|
2012-08-07 01:50:44 +00:00
|
|
|
ve.Position.newFromElementLayerPosition = function ( $element ) {
|
2011-11-02 21:00:55 +00:00
|
|
|
var position = $element.position();
|
2012-02-06 23:50:56 +00:00
|
|
|
return new ve.Position( position.left, position.top );
|
2011-11-02 21:00:55 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates position object from the screen position data in an Event object.
|
2012-06-20 01:20:28 +00:00
|
|
|
*
|
2011-11-02 21:00:55 +00:00
|
|
|
* @static
|
|
|
|
* @method
|
|
|
|
* @param event {Event} Event to get position data from
|
2012-02-06 23:50:56 +00:00
|
|
|
* @returns {ve.Position} Position with event data applied
|
2011-11-02 21:00:55 +00:00
|
|
|
*/
|
2012-08-07 01:50:44 +00:00
|
|
|
ve.Position.newFromEventScreenPosition = function ( event ) {
|
2012-02-06 23:50:56 +00:00
|
|
|
return new ve.Position( event.screenX, event.screenY );
|
2011-11-02 21:00:55 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates position object from the page position data in an Event object.
|
2012-06-20 01:20:28 +00:00
|
|
|
*
|
2011-11-02 21:00:55 +00:00
|
|
|
* @static
|
|
|
|
* @method
|
|
|
|
* @param event {Event} Event to get position data from
|
2012-02-06 23:50:56 +00:00
|
|
|
* @returns {ve.Position} Position with event data applied
|
2011-11-02 21:00:55 +00:00
|
|
|
*/
|
2012-08-07 01:50:44 +00:00
|
|
|
ve.Position.newFromEventPagePosition = function ( event ) {
|
2012-02-06 23:50:56 +00:00
|
|
|
return new ve.Position( event.pageX, event.pageY );
|
2011-11-02 21:00:55 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates position object from the layer position data in an Event object.
|
2012-06-20 01:20:28 +00:00
|
|
|
*
|
2011-11-02 21:00:55 +00:00
|
|
|
* @static
|
|
|
|
* @method
|
|
|
|
* @param event {Event} Event to get position data from
|
2012-02-06 23:50:56 +00:00
|
|
|
* @returns {ve.Position} Position with event data applied
|
2011-11-02 21:00:55 +00:00
|
|
|
*/
|
2012-08-07 01:50:44 +00:00
|
|
|
ve.Position.newFromEventLayerPosition = function ( event ) {
|
2012-02-06 23:50:56 +00:00
|
|
|
return new ve.Position( event.layerX, event.layerY );
|
2011-11-02 21:00:55 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/* Methods */
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Adds the values of a given position to this one.
|
2012-06-20 01:20:28 +00:00
|
|
|
*
|
2011-11-02 21:00:55 +00:00
|
|
|
* @method
|
2012-02-06 23:50:56 +00:00
|
|
|
* @param position {ve.Position} Position to add values from
|
2011-11-02 21:00:55 +00:00
|
|
|
*/
|
2012-08-07 01:50:44 +00:00
|
|
|
ve.Position.prototype.add = function ( position ) {
|
2011-11-02 21:00:55 +00:00
|
|
|
this.top += position.top;
|
|
|
|
this.bottom += position.bottom;
|
|
|
|
this.left += position.left;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Subtracts the values of a given position to this one.
|
2012-06-20 01:20:28 +00:00
|
|
|
*
|
2011-11-02 21:00:55 +00:00
|
|
|
* @method
|
2012-02-06 23:50:56 +00:00
|
|
|
* @param position {ve.Position} Position to subtract values from
|
2011-11-02 21:00:55 +00:00
|
|
|
*/
|
2012-08-07 01:50:44 +00:00
|
|
|
ve.Position.prototype.subtract = function ( position ) {
|
2011-11-02 21:00:55 +00:00
|
|
|
this.top -= position.top;
|
|
|
|
this.bottom -= position.bottom;
|
|
|
|
this.left -= position.left;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks if this position is the same as another one.
|
2012-06-20 01:20:28 +00:00
|
|
|
*
|
2011-11-02 21:00:55 +00:00
|
|
|
* @method
|
2012-02-06 23:50:56 +00:00
|
|
|
* @param position {ve.Position} Position to compare with
|
2011-11-02 21:00:55 +00:00
|
|
|
* @returns {Boolean} If positions have the same left and top values
|
|
|
|
*/
|
2012-08-07 01:50:44 +00:00
|
|
|
ve.Position.prototype.at = function ( position ) {
|
2011-11-02 21:00:55 +00:00
|
|
|
return this.left === position.left && this.top === position.top;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks if this position perpendicular with another one, sharing either a top or left value.
|
2012-06-20 01:20:28 +00:00
|
|
|
*
|
2011-11-02 21:00:55 +00:00
|
|
|
* @method
|
2012-02-06 23:50:56 +00:00
|
|
|
* @param position {ve.Position} Position to compare with
|
2011-11-02 21:00:55 +00:00
|
|
|
* @returns {Boolean} If positions share a top or a left value
|
|
|
|
*/
|
2012-08-07 01:50:44 +00:00
|
|
|
ve.Position.prototype.perpendicularWith = function ( position ) {
|
2011-11-02 21:00:55 +00:00
|
|
|
return this.left === position.left || this.top === position.top;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks if this position is level with another one, having the same top value.
|
2012-06-20 01:20:28 +00:00
|
|
|
*
|
2011-11-02 21:00:55 +00:00
|
|
|
* @method
|
2012-02-06 23:50:56 +00:00
|
|
|
* @param position {ve.Position} Position to compare with
|
2011-11-02 21:00:55 +00:00
|
|
|
* @returns {Boolean} If positions have the same top value
|
|
|
|
*/
|
2012-08-07 01:50:44 +00:00
|
|
|
ve.Position.prototype.levelWith = function ( position ) {
|
2011-11-02 21:00:55 +00:00
|
|
|
return this.top === position.top;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks if this position is plumb with another one, having the same left value.
|
2012-06-20 01:20:28 +00:00
|
|
|
*
|
2011-11-02 21:00:55 +00:00
|
|
|
* @method
|
2012-02-06 23:50:56 +00:00
|
|
|
* @param position {ve.Position} Position to compare with
|
2011-11-02 21:00:55 +00:00
|
|
|
* @returns {Boolean} If positions have the same left value
|
|
|
|
*/
|
2012-08-07 01:50:44 +00:00
|
|
|
ve.Position.prototype.plumbWith = function ( position ) {
|
2011-11-02 21:00:55 +00:00
|
|
|
return this.left === position.left;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks if this position is nearby another one.
|
2012-06-20 01:20:28 +00:00
|
|
|
*
|
2011-11-02 21:00:55 +00:00
|
|
|
* Distance is measured radially.
|
2012-06-20 01:20:28 +00:00
|
|
|
*
|
2011-11-02 21:00:55 +00:00
|
|
|
* @method
|
2012-02-06 23:50:56 +00:00
|
|
|
* @param position {ve.Position} Position to compare with
|
Object management: Object create/inherit/clone utilities
* For the most common case:
- replace ve.extendClass with ve.inheritClass (chose slightly
different names to detect usage of the old/new one, and I
like 'inherit' better).
- move it up to below the constructor, see doc block for why.
* Cases where more than 2 arguments were passed to
ve.extendClass are handled differently depending on the case.
In case of a longer inheritance tree, the other arguments
could be omitted (like in "ve.ce.FooBar, ve.FooBar,
ve.Bar". ve.ce.FooBar only needs to inherit from ve.FooBar,
because ve.ce.FooBar inherits from ve.Bar).
In the case of where it previously had two mixins with
ve.extendClass(), either one becomes inheritClass and one
a mixin, both to mixinClass().
No visible changes should come from this commit as the
instances still all have the same visible properties in the
end. No more or less than before.
* Misc.:
- Be consistent in calling parent constructors in the
same order as the inheritance.
- Add missing @extends and @param documentation.
- Replace invalid {Integer} type hint with {Number}.
- Consistent doc comments order:
@class, @abstract, @constructor, @extends, @params.
- Fix indentation errors
A fairly common mistake was a superfluous space before the
identifier on the assignment line directly below the
documentation comment.
$ ack "^ [^*]" --js modules/ve
- Typo "Inhertiance" -> "Inheritance".
- Replacing the other confusing comment "Inheritance" (inside
the constructor) with "Parent constructor".
- Add missing @abstract for ve.ui.Tool.
- Corrected ve.FormatDropdownTool to ve.ui.FormatDropdownTool.js
- Add function names to all @constructor functions. Now that we
have inheritance it is important and useful to have these
functions not be anonymous.
Example of debug shot: http://cl.ly/image/1j3c160w3D45
Makes the difference between
< documentNode;
> ve_dm_DocumentNode
...
: ve_dm_BranchNode
...
: ve_dm_Node
...
: ve_dm_Node
...
: Object
...
without names (current situation):
< documentNode;
> Object
...
: Object
...
: Object
...
: Object
...
: Object
...
though before this commit, it really looks like this
(flattened since ve.extendClass really did a mixin):
< documentNode;
> Object
...
...
...
Pattern in Sublime (case-sensitive) to find nameless
constructor functions:
"^ve\..*\.([A-Z])([^\.]+) = function \("
Change-Id: Iab763954fb8cf375900d7a9a92dec1c755d5407e
2012-09-05 06:07:47 +00:00
|
|
|
* @param radius {Number} Pixel distance from this position to consider "near-by"
|
2011-11-02 21:00:55 +00:00
|
|
|
* @returns {Boolean} If positions are near-by each other
|
|
|
|
*/
|
2012-08-07 01:50:44 +00:00
|
|
|
ve.Position.prototype.near = function ( position, radius ) {
|
2011-11-02 21:00:55 +00:00
|
|
|
return Math.sqrt(
|
|
|
|
Math.pow( this.left - position.left, 2 ),
|
|
|
|
Math.pow( this.top - position.top )
|
|
|
|
) <= radius;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks if this position is above another one.
|
2012-06-20 01:20:28 +00:00
|
|
|
*
|
2011-11-02 21:00:55 +00:00
|
|
|
* This method utilizes the bottom property.
|
2012-06-20 01:20:28 +00:00
|
|
|
*
|
2011-11-02 21:00:55 +00:00
|
|
|
* @method
|
2012-02-06 23:50:56 +00:00
|
|
|
* @param position {ve.Position} Position to compare with
|
2011-11-02 21:00:55 +00:00
|
|
|
* @returns {Boolean} If this position is above the other
|
|
|
|
*/
|
2012-08-07 01:50:44 +00:00
|
|
|
ve.Position.prototype.above = function ( position ) {
|
2011-11-02 21:00:55 +00:00
|
|
|
return this.bottom < position.top;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks if this position is below another one.
|
2012-06-20 01:20:28 +00:00
|
|
|
*
|
2011-11-02 21:00:55 +00:00
|
|
|
* This method utilizes the bottom property.
|
2012-06-20 01:20:28 +00:00
|
|
|
*
|
2011-11-02 21:00:55 +00:00
|
|
|
* @method
|
2012-02-06 23:50:56 +00:00
|
|
|
* @param position {ve.Position} Position to compare with
|
2011-11-02 21:00:55 +00:00
|
|
|
* @returns {Boolean} If this position is below the other
|
|
|
|
*/
|
2012-08-07 01:50:44 +00:00
|
|
|
ve.Position.prototype.below = function ( position ) {
|
2011-11-02 21:00:55 +00:00
|
|
|
return this.top > position.bottom;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks if this position is to the left of another one.
|
2012-06-20 01:20:28 +00:00
|
|
|
*
|
2011-11-02 21:00:55 +00:00
|
|
|
* @method
|
2012-02-06 23:50:56 +00:00
|
|
|
* @param position {ve.Position} Position to compare with
|
2011-11-02 21:00:55 +00:00
|
|
|
* @returns {Boolean} If this position is the left the other
|
|
|
|
*/
|
2012-08-07 01:50:44 +00:00
|
|
|
ve.Position.prototype.leftOf = function ( left ) {
|
2011-11-02 21:00:55 +00:00
|
|
|
return this.left < left;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks if this position is to the right of another one.
|
2012-06-20 01:20:28 +00:00
|
|
|
*
|
2011-11-02 21:00:55 +00:00
|
|
|
* @method
|
2012-02-06 23:50:56 +00:00
|
|
|
* @param position {ve.Position} Position to compare with
|
2011-11-02 21:00:55 +00:00
|
|
|
* @returns {Boolean} If this position is the right the other
|
|
|
|
*/
|
2012-08-07 01:50:44 +00:00
|
|
|
ve.Position.prototype.rightOf = function ( left ) {
|
2011-11-02 21:00:55 +00:00
|
|
|
return this.left > left;
|
|
|
|
};
|