1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-02-15 04:42:04 +00:00
srs/trunk/research/console/js/bravo_popover/popover.js

233 lines
No EOL
9.9 KiB
JavaScript
Executable file
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

angular.module('bravoUiPopover', [])
.directive("bravoPopover", function($compile, $position, $sce){
// $parse : ng表达式 {{1+2}} {{text}}
// $compile : 编译一段html字符串可以包括ng表达式
return {
restrict: "A",
scope: {
confirm: '&bravoPopoverConfirm'
},
compile: function (elem, attr) {
var confirm_template = attr['bravoPopoverConfirm'] ? '<span>' +
'<a class="btn btn-danger" ng-click="on_confirm()">Confirm</a> ' +
'<a class="btn btn-info" ng-click="on_cancel()">Cancel</a>' +
'</span>' : '';
var template =
'<div class="popover fade {{placement}} in" ng-show="popoover_show == \'in\'">' +
'<div class="arrow"></div>' +
'<h3 class="popover-title">{{title}}</h3>' +
'<div class="popover-content" ng-bind-html="content">' +
'</div>' +
'<div class="popover-content" ng-show="show_confirm_template">' +
confirm_template +
'</div>' +
'</div>';
var linker = $compile(template);
return function (scope, elem, attr) {
scope.popoover_show = "";
scope.title = attr['title'];
scope.content = $sce.trustAsHtml(attr['content']);
scope.placement = attr['placement'] ? attr['placement'] : 'top';
scope.trigger = attr['bravoPopoverConfirm'] ? 'click' : attr['trigger'];
scope.show_confirm_template = attr['bravoPopoverConfirm'] ? true : false;
var tooltip = linker(scope, function (o) {
elem.after(o);
});
tooltip.css({ top: 0, left: 0, display: 'block' });
if (!scope.trigger || scope.trigger == 'click') {
elem.on('click', function (event) {
toggle();
});
} else {
var eventIn = scope.trigger == 'hover' ? 'mouseenter' : 'focus';
var eventOut = scope.trigger == 'hover' ? 'mouseleave' : 'blur';
elem.on(eventIn, function (event) {
show_popover();
});
elem.on(eventOut, function () {
hide_popover();
});
}
var toggle = function() {
scope.popoover_show == 'in'? hide_popover() : show_popover();
render_css(tooltip);
};
var show_popover = function() {
scope.popoover_show = "in";
scope.$apply();
render_css(tooltip);
};
var hide_popover = function() {
scope.popoover_show = "";
scope.$apply();
};
var render_css = function (scope_element) {
var ttPosition = $position.positionElements(elem, scope_element, scope.placement, false);
ttPosition.top += 'px';
ttPosition.left += 'px';
// Now set the calculated positioning.
scope_element.css( ttPosition );
};
render_css(tooltip);
scope.on_cancel = function () {
scope.popoover_show = "";
};
scope.on_confirm = function () {
scope.confirm();
scope.popoover_show = "";
};
}
}
};
})
.factory('$position', ['$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;
};
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 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)
};
},
/**
* Provides coordinates for the targetEl in relation to hostEl
*/
positionElements: function (hostEl, targetEl, positionStr, appendToBody) {
var positionStrParts = positionStr.split('-');
var pos0 = positionStrParts[0], pos1 = positionStrParts[1] || 'center';
var hostElPos,
targetElWidth,
targetElHeight,
targetElPos;
hostElPos = appendToBody ? this.offset(hostEl) : this.position(hostEl);
targetElWidth = targetEl.prop('offsetWidth');
targetElHeight = targetEl.prop('offsetHeight');
var shiftWidth = {
center: function () {
return hostElPos.left + hostElPos.width / 2 - targetElWidth / 2;
},
left: function () {
return hostElPos.left;
},
right: function () {
return hostElPos.left + hostElPos.width;
}
};
var shiftHeight = {
center: function () {
return hostElPos.top + hostElPos.height / 2 - targetElHeight / 2;
},
top: function () {
return hostElPos.top;
},
bottom: function () {
return hostElPos.top + hostElPos.height;
}
};
switch (pos0) {
case 'right':
targetElPos = {
top: shiftHeight[pos1](),
left: shiftWidth[pos0]()
};
break;
case 'left':
targetElPos = {
top: shiftHeight[pos1](),
left: hostElPos.left - targetElWidth
};
break;
case 'bottom':
targetElPos = {
top: shiftHeight[pos0](),
left: shiftWidth[pos1]()
};
break;
default:
targetElPos = {
top: hostElPos.top - targetElHeight,
left: shiftWidth[pos1]()
};
break;
}
return targetElPos;
}
};
}]);