webogram-i2p/app/vendor/ui-bootstrap/ui-bootstrap-custom-tpls-0.7.0.js
Igor Zhukov d9447f6224 Lots of bug fixes
EmojiMenu click scroll fix
EmojiMenu tail
Emojiarea improve paste hadling
Emoji, attach icons styles (opacity + color on active state)
Message better placeholder styles
Notifications click improve (now focus field)
Send message from modal now closes all modals
Send message now scrolls down
Message drafts now support line breaks
Correct display ‘f’, ’n’, ‘no’ messages
Group info click causes double modal window fixed
Document is now downloaded on icon click
2014-01-29 18:37:18 +04:00

354 lines
11 KiB
JavaScript

angular.module("ui.bootstrap", ["ui.bootstrap.tpls", "ui.bootstrap.modal"]);
angular.module("ui.bootstrap.tpls", ["template/modal/backdrop.html","template/modal/window.html"]);
angular.module('ui.bootstrap.modal', [])
/**
* A helper, internal data structure that acts as a map but also allows getting / removing
* elements in the LIFO order
*/
.factory('$$stackedMap', function () {
return {
createNew: function () {
var stack = [];
return {
add: function (key, value) {
stack.push({
key: key,
value: value
});
},
get: function (key) {
for (var i = 0; i < stack.length; i++) {
if (key == stack[i].key) {
return stack[i];
}
}
},
keys: function() {
var keys = [];
for (var i = 0; i < stack.length; i++) {
keys.push(stack[i].key);
}
return keys;
},
top: function () {
return stack[stack.length - 1];
},
remove: function (key) {
var idx = -1;
for (var i = 0; i < stack.length; i++) {
if (key == stack[i].key) {
idx = i;
break;
}
}
return stack.splice(idx, 1)[0];
},
removeTop: function () {
return stack.splice(stack.length - 1, 1)[0];
},
length: function () {
return stack.length;
}
};
}
};
})
/**
* A helper directive for the $modal service. It creates a backdrop element.
*/
.directive('modalBackdrop', ['$modalStack', '$timeout', function ($modalStack, $timeout) {
return {
restrict: 'EA',
replace: true,
templateUrl: 'template/modal/backdrop.html',
link: function (scope, element, attrs) {
//trigger CSS transitions
$timeout(function () {
scope.animate = true;
});
scope.close = function (evt) {
var modal = $modalStack.getTop();
if (modal && modal.value.backdrop && modal.value.backdrop != 'static') {
evt.preventDefault();
evt.stopPropagation();
$modalStack.dismiss(modal.key, 'backdrop click');
}
};
}
};
}])
.directive('modalWindow', ['$modalStack', '$timeout', function ($modalStack, $timeout) {
return {
restrict: 'EA',
scope: {
index: '@'
},
replace: true,
transclude: true,
templateUrl: 'template/modal/window.html',
link: function (scope, element, attrs) {
scope.windowClass = attrs.windowClass || '';
//trigger CSS transitions
$timeout(function () {
scope.animate = true;
});
scope.close = function (evt) {
var modal = $modalStack.getTop();
if (modal) {
evt.preventDefault();
evt.stopPropagation();
$modalStack.dismiss(modal.key, 'backdrop click');
}
};
}
};
}])
.factory('$modalStack', ['$document', '$compile', '$rootScope', '$$stackedMap',
function ($document, $compile, $rootScope, $$stackedMap) {
var backdropjqLiteEl, backdropDomEl;
var backdropScope = $rootScope.$new(true);
var body = $document.find('body').eq(0);
var openedWindows = $$stackedMap.createNew();
var $modalStack = {};
function backdropIndex() {
var topBackdropIndex = -1;
var opened = openedWindows.keys();
for (var i = 0; i < opened.length; i++) {
if (openedWindows.get(opened[i]).value.backdrop) {
topBackdropIndex = i;
}
}
return topBackdropIndex;
}
$rootScope.$watch(backdropIndex, function(newBackdropIndex){
backdropScope.index = newBackdropIndex;
});
function removeModalWindow(modalInstance) {
var modalWindow = openedWindows.get(modalInstance).value;
//clean up the stack
openedWindows.remove(modalInstance);
//remove window DOM element
modalWindow.modalDomEl.remove();
//remove backdrop if no longer needed
if (backdropDomEl && backdropIndex() == -1) {
backdropDomEl.remove();
backdropDomEl = undefined;
}
//destroy scope
modalWindow.modalScope.$destroy();
}
$document.bind('keydown', function (evt) {
var modal;
if (evt.which === 27) {
modal = openedWindows.top();
if (modal && modal.value.keyboard) {
$rootScope.$apply(function () {
$modalStack.dismiss(modal.key);
});
}
}
});
$modalStack.open = function (modalInstance, modal) {
openedWindows.add(modalInstance, {
deferred: modal.deferred,
modalScope: modal.scope,
backdrop: modal.backdrop,
keyboard: modal.keyboard
});
var angularDomEl = angular.element('<div modal-window></div>');
angularDomEl.attr('window-class', modal.windowClass);
angularDomEl.attr('index', openedWindows.length() - 1);
angularDomEl.html(modal.content);
var modalDomEl = $compile(angularDomEl)(modal.scope);
openedWindows.top().value.modalDomEl = modalDomEl;
body.append(modalDomEl);
if (backdropIndex() >= 0 && !backdropDomEl) {
backdropjqLiteEl = angular.element('<div modal-backdrop></div>');
backdropDomEl = $compile(backdropjqLiteEl)(backdropScope);
body.append(backdropDomEl);
}
};
$modalStack.close = function (modalInstance, result) {
var modal = openedWindows.get(modalInstance);
if (modal) {
modal.value.deferred.resolve(result);
removeModalWindow(modalInstance);
}
};
$modalStack.dismiss = function (modalInstance, reason) {
var modalWindow = openedWindows.get(modalInstance).value;
if (modalWindow) {
modalWindow.deferred.reject(reason);
removeModalWindow(modalInstance);
}
};
$modalStack.dismissAll = function () {
var modal;
while (openedWindows.length()) {
if (modal = openedWindows.top()) {
$modalStack.dismiss(modal.key);
}
}
}
$modalStack.getTop = function () {
return openedWindows.top();
};
return $modalStack;
}])
.provider('$modal', function () {
var $modalProvider = {
options: {
backdrop: true, //can be also false or 'static'
keyboard: true
},
$get: ['$injector', '$rootScope', '$q', '$http', '$templateCache', '$controller', '$modalStack',
function ($injector, $rootScope, $q, $http, $templateCache, $controller, $modalStack) {
var $modal = {};
function getTemplatePromise(options) {
return options.template ? $q.when(options.template) :
$http.get(options.templateUrl, {cache: $templateCache}).then(function (result) {
return result.data;
});
}
function getResolvePromises(resolves) {
var promisesArr = [];
angular.forEach(resolves, function (value, key) {
if (angular.isFunction(value) || angular.isArray(value)) {
promisesArr.push($q.when($injector.invoke(value)));
}
});
return promisesArr;
}
$modal.open = function (modalOptions) {
var modalResultDeferred = $q.defer();
var modalOpenedDeferred = $q.defer();
//prepare an instance of a modal to be injected into controllers and returned to a caller
var modalInstance = {
result: modalResultDeferred.promise,
opened: modalOpenedDeferred.promise,
close: function (result) {
$modalStack.close(modalInstance, result);
},
dismiss: function (reason) {
$modalStack.dismiss(modalInstance, reason);
}
};
//merge and clean up options
modalOptions = angular.extend({}, $modalProvider.options, modalOptions);
modalOptions.resolve = modalOptions.resolve || {};
//verify options
if (!modalOptions.template && !modalOptions.templateUrl) {
throw new Error('One of template or templateUrl options is required.');
}
var templateAndResolvePromise =
$q.all([getTemplatePromise(modalOptions)].concat(getResolvePromises(modalOptions.resolve)));
templateAndResolvePromise.then(function resolveSuccess(tplAndVars) {
var modalScope = (modalOptions.scope || $rootScope).$new();
modalScope.$close = modalInstance.close;
modalScope.$dismiss = modalInstance.dismiss;
var ctrlInstance, ctrlLocals = {};
var resolveIter = 1;
//controllers
if (modalOptions.controller) {
ctrlLocals.$scope = modalScope;
ctrlLocals.$modalInstance = modalInstance;
angular.forEach(modalOptions.resolve, function (value, key) {
ctrlLocals[key] = tplAndVars[resolveIter++];
});
ctrlInstance = $controller(modalOptions.controller, ctrlLocals);
}
$modalStack.open(modalInstance, {
scope: modalScope,
deferred: modalResultDeferred,
content: tplAndVars[0],
backdrop: modalOptions.backdrop,
keyboard: modalOptions.keyboard,
windowClass: modalOptions.windowClass
});
}, function resolveError(reason) {
modalResultDeferred.reject(reason);
});
templateAndResolvePromise.then(function () {
modalOpenedDeferred.resolve(true);
}, function () {
modalOpenedDeferred.reject(false);
});
return modalInstance;
};
return $modal;
}]
};
return $modalProvider;
});
angular.module("template/modal/backdrop.html", []).run(["$templateCache", function($templateCache) {
$templateCache.put("template/modal/backdrop.html",
"<div class=\"modal-backdrop fade\" ng-class=\"{in: animate}\" ng-style=\"{'z-index': 1040 + index*10}\" ng-click=\"close($event)\"></div>");
}]);
angular.module("template/modal/window.html", []).run(["$templateCache", function($templateCache) {
$templateCache.put("template/modal/window.html",
"<div class=\"modal fade {{ windowClass }}\" tabindex=\"-1\" role=\"dialog\" ng-class=\"{in: animate}\" ng-style=\"{'z-index': 1050 + index*10, display: 'block'}\">\
<div class=\"modal_close_wrap\" ng-click=\"close($event)\">\
<div class=\"modal_close\"></div>\
</div>\
<div class=\"modal-dialog\">\
<div class=\"modal-content\" ng-transclude>\
</div>\
</div>\
</div>");
}]);