Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PR#64 (for coverage check) #67

Closed
wants to merge 11 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions angularDrop.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
angularDropFiles = {
'angularDropSrc': [
'src/utils.js',
'src/dndDOM.js',
'src/draggable.js',
'src/droppable.js',
'src/provider.js',
Expand Down
175 changes: 175 additions & 0 deletions src/dndDOM.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
'use strict';

/**
* @ngdoc object
* @module ui.drop
* @name ui.drop.$dndDOM
* @requires $document
* @requires $window
*
* @description
*
* A set of utility methods that can be use to retrieve and manipulate DOM properties.
*
* (based on https://github.com/angular-ui/bootstrap/blob/master/src/position/position.js)
*
*/
var $dndDOMFactory = ['$document', '$window', function ($document, $window) {

function getStyle(el, cssprop) {
if (el.currentStyle) { //IE
return el.currentStyle[cssprop];
} else if ($window.getComputedStyle) {
return $window.getComputedStyle(el)[cssprop];
}
// finally try and get inline style
return el.style[cssprop];
}

/**
* Checks if a given element is statically positioned
* @param element - raw DOM element
*/
function isStaticPositioned(element) {
return (getStyle(element, 'position') || 'static' ) === 'static';
}

/**
* returns the closest, non-statically positioned parentOffset of a given element
* @param element
*/
var parentOffsetEl = function (element) {
var docDomEl = $document[0];
var offsetParent = element.offsetParent || docDomEl;
while (offsetParent && offsetParent !== docDomEl && isStaticPositioned(offsetParent) ) {
offsetParent = offsetParent.offsetParent;
}
return offsetParent || docDomEl;
};

function contains(a, b) {
var adown = a.nodeType === 9 ? a.documentElement : a,
bup = b && b.parentNode;
return a === bup || !!( bup && bup.nodeType === 1 && contains(adown, bup) );
};

function swapCss(element, css, callback, args) {
var ret, prop, old = {};
for (prop in css) {
old[prop] = element.style[prop];
element.style[prop] = css[prop];
}

ret = callback.apply(element, args || []);

for (prop in css) {
element.style[prop] = old[prop];
}

return ret;
};

var swapDisplay = /^(none|table(?!-c[ea]).+)/;

var cssShow = {
position: 'absolute',
visibility: 'hidden',
display: 'block'
};

return {
/**
* Provides read-only equivalent of jQuery's position function:
* http://api.jquery.com/position/
*/
position: function (element) {
var elBCR = this.offset(element);
var offsetParentBCR = { top: 0, left: 0 };
var offsetParentEl = parentOffsetEl(element[0]);
if (offsetParentEl != $document[0]) {
offsetParentBCR = this.offset(angular.element(offsetParentEl));
offsetParentBCR.top += offsetParentEl.clientTop - offsetParentEl.scrollTop;
offsetParentBCR.left += offsetParentEl.clientLeft - offsetParentEl.scrollLeft;
}

var boundingClientRect = element[0].getBoundingClientRect();
return {
width: boundingClientRect.width || element.prop('offsetWidth'),
height: boundingClientRect.height || element.prop('offsetHeight'),
top: elBCR.top - offsetParentBCR.top,
left: elBCR.left - offsetParentBCR.left
};
},

/**
* Provides read-only equivalent of jQuery's offset function:
* http://api.jquery.com/offset/
*/
offset: function (element) {

var doc = element[0] && element[0].ownerDocument;

if (!doc) {
return;
}

doc = doc.documentElement;

if (!contains(doc, element[0])) {
return { top: 0, left: 0 };
}

var boundingClientRect = element[0].getBoundingClientRect();
return {
width: boundingClientRect.width || element.prop('offsetWidth'),
height: boundingClientRect.height || element.prop('offsetHeight'),
top: boundingClientRect.top + ($window.pageYOffset || $document[0].documentElement.scrollTop),
left: boundingClientRect.left + ($window.pageXOffset || $document[0].documentElement.scrollLeft)
};
},

/**
* Partial implementation of https://api.jquery.com/closest/
* @param element
* @param value
* @returns {angular.element}
*/
closest: function(element, value) {
element = angular.element(element);
if ($.fn && angular.isFunction($.fn.closest)) {
return element.closest(value);
}
// Otherwise, assume it's a tag name...
element = element[0];
value = value.toLowerCase();
do {
if (element.nodeName.toLowerCase() === value) {
return angular.element(element);
}
} while (element = element.parentNode);
},

size: function(element) {
var jq = angular.element(element);
element = element.nodeName ? element : element[0];
if (element.offsetWidth === 0 && swapDisplay.test(jq.css('display'))) {
return swapCss(element, cssShow, getHeightAndWidth, [element]);
}
return getHeightAndWidth(element);

function getHeightAndWidth(element) {
return {
width: element.offsetWidth,
height: element.offsetHeight
};
}
},

keepSize: function(element) {
var css = this.size(element);
css.width = css.width + 'px';
css.height = css.height + 'px';
return css;
}
};
}];
66 changes: 33 additions & 33 deletions src/draggable.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ var $dragProvider = function() {
* a mechanism to drag-enable any arbitrary element, which allows it to be used in
* custom directives, so that custom dragging behaviour can be achieved.
*/
this.$get = ['$document', '$drop', function($document, $drop) {
this.$get = ['$document', '$drop', '$dndDOM', function($document, $drop, $dndDOM) {
var $drag = {
/**
* @ngdoc method
Expand Down Expand Up @@ -197,7 +197,7 @@ var $dragProvider = function() {
currentDrag = self;

self.cssDisplay = self.element.css('display');
self.dimensions = DOM.size(self.element);
self.dimensions = $dndDOM.size(self.element);
if (!self.hanging) {
self.cssPosition = self.element.css("position");

Expand All @@ -206,23 +206,23 @@ var $dragProvider = function() {
width: self.element[0].style['width'],
height: self.element[0].style['height']
};
self.element.css(DOM.keepSize(self.element));
self.element.css($dndDOM.keepSize(self.element));
}
}

if (typeof self.options.dragWithin === 'string') {
self.constraints = dragConstraints(self.options.dragWithin, self.element);
}

self.offset = self.positionAbs = DOM.offset(self.element);
self.offset = $dndDOM.position(self.element);

self.offset.scroll = false;

angular.extend(self.offset, {
click: {
top: event.pageY - self.offset.top,
left: event.pageX - self.offset.left
},
}
});

self.lastMouseY = event.pageY;
Expand All @@ -232,8 +232,8 @@ var $dragProvider = function() {

self.element.css({
position: 'absolute',
left: self.offset.left,
top: self.offset.top
left: self.offset.left + 'px', //jqlite does not support raw Number
top: self.offset.top + 'px'
});

$document.on("mousemove", self.drag);
Expand Down Expand Up @@ -354,6 +354,32 @@ var $dragProvider = function() {
}
};

function dragConstraints(value, element) {
if (value.length === '') {
return;
}
if (/^(\.|#)/.test(value) && $.fn && angular.isFunction($.fn.closest)) {
// Find nearest element matching class
return constraintsFor(element.parent().closest(value));
}
if (/^(\^|parent)$/.test(value)) {
return constraintsFor(element.parent());
}
return constraintsFor($dndDOM.closest(element.parent(), value));
};

function constraintsFor(element) {
if (typeof element === 'undefined' || element.length === 0) {
return;
}
// Use offset + width/height for now?
var constraints = $dndDOM.offset(element),
dimensions = $dndDOM.size(element);
constraints.right = constraints.left + dimensions.width;
constraints.bottom = constraints.top + dimensions.height;
return constraints;
};

/**
* @ngdoc property
* @module ui.drop
Expand Down Expand Up @@ -409,32 +435,6 @@ var $dragProvider = function() {
return angular.isObject(thing) && thing.constructor === Draggable;
}

function dragConstraints(value, element) {
if (value.length === '') {
return;
}
if (/^(\.|#)/.test(value) && $.fn && angular.isFunction($.fn.closest)) {
// Find nearest element matching class
return constraintsFor(element.parent().closest(value));
}
if (/^(\^|parent)$/.test(value)) {
return constraintsFor(element.parent());
}
return constraintsFor(DOM.closest(element.parent(), value));
}

function constraintsFor(element) {
if (typeof element === 'undefined' || element.length === 0) {
return;
}
// Use offset + width/height for now?
var constraints = DOM.offset(element),
dimensions = DOM.size(element);
constraints.right = constraints.left + dimensions.width;
constraints.bottom = constraints.top + dimensions.height;
return constraints;
}

function withinConstraints(c, x, y, w, h) {
return x >= c.left && (x+w) <= c.right && y >= c.top && (y+h) <= c.bottom;
}
Expand Down
2 changes: 2 additions & 0 deletions src/public.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,7 @@ function publishExternalAPI() {
}]).directive({
draggable: draggableDirective,
droppable: droppableDirective
}).factory({
$dndDOM: $dndDOMFactory
});
}
Loading