(function(window, angular, undefined){
'use strict';
var module = angular.module('nsPopover', []);
var $el = angular.element;
var isDef = angular.isDefined;
var forEach = angular.forEach;
/**
* Extends the destination objec 'dst' by copying all of the properties from the 'src' object(s)
* to 'dst'. Multiple src objects could be specified. 'undefined' values are not copied.
*
* @param {Object} dst The destination object.
* @param {Object} src The spurce object.
* @returns {Object} Reference to 'dst'.
*/
var extend_ = function extend(dst, src) {
forEach(arguments, function(obj) {
if (obj !== src) {
forEach(obj, function(value, key) {
if (isDef(value)) {
dst[key] = value;
}
});
}
});
};
/*module.provider('nsPopover', function() {
var defaults_ = this.default_ = {
placement: 'right',
plain: false
};
var globalId_ = 0;
this.$get('$document','$templateCache', '$compile', '$q', '$http', '$rootScope', '$timeout',
function ($document, $templateCache, $compile, $q, $http, $rootScope, $timeout) {
var $body = $document.find('body');
var methods_ = {
show: function(opts) {
var options = angular.copy(defaults_);
opts = opts || {};
extend_(options, opts);
globalId_ += 1;
var scope = angular.isObject(options.scope) ? options.scope : $rootScope.$new();
var $popover;
$q.when(loadTemplate(options.template)).then(function(template) {
template = angular.isString(template) ?
template :
template.data && angular.isString(template.data) ?
template.data :
'';
$popover = $el('
class="ns-popover" id="ns-popover' + globalId_ + '">
');
$popover.html(template);
if (options.theme) {
$popover.addClass(options.theme);
}
$timeout(function() {
$compile($popover)(scope);
});
scope.$on('$destroy', function() {
$popover.remove();
});
$body.append($popover);
return methods_;
});
function loadTemplate(template) {
if (!template) {
return 'Empty template';
}
if (angular.isString(template) && options.plain) {
return template;
}
return $templateCache.get(template) || $http.get(template, { cache : true });
}
}
}
});
});*/
module.directive('nsPopover', function($timeout, $templateCache, $q, $http, $compile, $document) {
return {
restrict: 'A',
link: function(scope, elm, attrs) {
var options = {
template: attrs.nsPopoverTemplate,
theme: attrs.nsPopoverTheme || 'ns-popover-default-theme',
plain: attrs.nsPopoverPlain,
trigger: attrs.nsPopoverTrigger || 'click',
container: attrs.nsPopoverContainer
};
var timeoutId_ = {};
var $container = $el(options.container);
if (!$container.length) {
$container = $document.find('body');
}
var $popover = $el('');
$q.when(loadTemplate(options.template)).then(function(template) {
template = angular.isString(template) ?
template :
template.data && angular.isString(template.data) ?
template.data :
'';
$popover.html(template);
if (options.theme) {
$popover.addClass(options.theme);
}
$timeout(function() {
$compile($popover)(scope);
});
scope.$on('$destroy', function() {
$popover.remove();
});
$popover
.css('position', 'absolute')
.css('display', 'none');
$container.append($popover);
});
elm.on(options.trigger, function(e) {
e.preventDefault();
$timeout.cancel(timeoutId_);
var rect = elm[0].getBoundingClientRect();
$popover
.css('display', 'block')
.css('top', rect.bottom + 1 + 'px')
.css('left', rect.left + 'px');
$popover.on('click', function() {
timeoutId_ = hide(0);
});
});
$popover
.on('mouseout', function(e) {
timeoutId_ = hide();
})
.on('mouseover', function() {
$timeout.cancel(timeoutId_);
});
function hide(delay) {
$timeout.cancel(timeoutId_);
// delay the hide to 1.5s by default.
if (!isDef(delay)) {
delay = 1500;
}
return $timeout(function() {
$popover.css('display', 'none');
}, delay);
}
function loadTemplate(template) {
if (!template) {
return '';
}
if (angular.isString(template) && options.plain) {
return template;
}
return $templateCache.get(template) || $http.get(template, { cache : true });
}
}
};
});
})(window, window.angular);