var app = angular.module('plunker', ['ngDialog']);
app.controller('MainCtrl', function($scope, ngDialog) {
$scope.openDialog = function() {
ngDialog.open({ template: 'dialogTemplate', scope: $scope });
}
});
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<link rel="stylesheet" href="ngDialog.css" />
<link rel="stylesheet" href="ngDialog-theme-default.css" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" />
<script data-require="angular.js@1.3.x" src="https://code.angularjs.org/1.3.15/angular.js" data-semver="1.3.15"></script>
<script src="ngDialog.js"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<h2>UI Repaint Issue</h2>
<p>Steps to reproduce:</p>
<ul>
<li>Test with a recent Chrome Version</li>
<li>Make sure, this plunker is shown in embedded view <strong>(important)</strong></li>
<li>Open Chrome developer tools</li>
<li>Click "Toggle device mode" (smartphone icon) <strong>(important)</strong></li>
<li>Limit the vertical resolution to about 600px in height</li>
<li>Click "open dialog" and scroll down to the bottom</li>
<li>Can you read "Hello, do you see me?"?</li>
<li>If not, press on one of the panels on top or below the textbox, this will cause a repaint and you can see the text.</li>
</ul>
<a href="" ng-click="openDialog()" style="font-size: 20px">open dialog</a>
<script type="text/ng-template" id="dialogTemplate">
<div class="list-group cardify">
<a href="#" class="list-group-item cardify">
<div>just a card</div>
</a>
</div>
<div class="just-a-div">just a div</div>
<div class="just-a-div">just a div</div>
<div class="just-a-div">just a div</div>
<div class="just-a-div">just a div</div>
<div class="just-a-div">just a div</div>
<div class="just-a-div">just a div</div>
<div class="just-a-div">just a div</div>
<div class="just-a-div">just a div</div>
<div class="just-a-div">just a div</div>
<div class="just-a-div">just a div</div>
<div class="just-a-div">just a div</div>
<div class="just-a-div">just a div</div>
<div class="just-a-div">just a div</div>
<p>Can you see the content on the following div when your viewport requires you scroll down to this place? If not, click on the area below, the text will appear.</p>
<div class="list-group cardify">
<a href="#" class="list-group-item cardify" >
<div>hello, do you see me?</div>
</a>
</div>
<div class="list-group cardify">
<div class="list-group cardify">
<input type="text" value="an input field"/>
</div>
<div class="list-group cardify">
<a href="#" class="list-group-item cardify">
<div>hello, do you see me?</div>
</a>
</div>
</div>
</script>
</body>
</html>
/* Put your css in here */
.just-a-div {
background-color: #2c3e50;
margin: 10px;
height: 100px;
color: white;
}
.list-group.cardify {
margin: 0 0 10px 0;
box-shadow: 0 2px 1px rgba(0, 0, 0, 0.1), 0 0 1px rgba(0, 0, 0, 0.1);
border-radius: 2px; }
.list-group.cardify .accordion-item > .list-group-item.cardify {
border-top: 1px solid #ebebeb;
border-top-left-radius: 0;
border-top-right-radius: 0; }
.list-group.cardify .accordion-item:first-child > .list-group-item.cardify {
border-top: 0;
border-top-left-radius: 2px;
border-top-right-radius: 2px; }
.list-group.cardify + .app-card-section {
margin-top: 15px; }
.list-group-item.cardify {
padding: 11px;
border: 0 solid #ddd;
border-top: 1px solid #ebebeb; }
.list-group-item.cardify:first-child {
border-top: 0;
border-top-right-radius: 2px;
border-top-left-radius: 2px; }
.list-group-item.cardify:last-child {
border-bottom-right-radius: 2px;
border-bottom-left-radius: 2px; }
/*
* ngDialog - easy modals and popup windows
* http://github.com/likeastore/ngDialog
* (c) 2013-2015 MIT License, https://likeastore.com
*/
(function (root, factory) {
if (typeof module !== 'undefined' && module.exports) {
// CommonJS
module.exports = factory(require('angular'));
} else if (typeof define === 'function' && define.amd) {
// AMD
define(['angular'], factory);
} else {
// Global Variables
factory(root.angular);
}
}(this, function (angular) {
'use strict';
var m = angular.module('ngDialog', []);
var $el = angular.element;
var isDef = angular.isDefined;
var style = (document.body || document.documentElement).style;
var animationEndSupport = isDef(style.animation) || isDef(style.WebkitAnimation) || isDef(style.MozAnimation) || isDef(style.MsAnimation) || isDef(style.OAnimation);
var animationEndEvent = 'animationend webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend';
var focusableElementSelector = 'a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, *[tabindex], *[contenteditable]';
var forceBodyReload = false;
var scopes = {};
var openIdStack = [];
var keydownIsBound = false;
m.provider('ngDialog', function () {
var defaults = this.defaults = {
className: 'ngdialog-theme-default',
plain: false,
showClose: true,
closeByDocument: true,
closeByEscape: true,
closeByNavigation: false,
appendTo: false,
preCloseCallback: false,
overlay: true,
cache: true,
trapFocus: true,
preserveFocus: true,
ariaAuto: true,
ariaRole: null,
ariaLabelledById: null,
ariaLabelledBySelector: null,
ariaDescribedById: null,
ariaDescribedBySelector: null
};
this.setForceBodyReload = function (_useIt) {
forceBodyReload = _useIt || false;
};
this.setDefaults = function (newDefaults) {
angular.extend(defaults, newDefaults);
};
var globalID = 0, dialogsCount = 0, closeByDocumentHandler, defers = {};
this.$get = ['$document', '$templateCache', '$compile', '$q', '$http', '$rootScope', '$timeout', '$window', '$controller', '$injector',
function ($document, $templateCache, $compile, $q, $http, $rootScope, $timeout, $window, $controller, $injector) {
var $body = $document.find('body');
if (forceBodyReload) {
$rootScope.$on('$locationChangeSuccess', function () {
$body = $document.find('body');
});
}
var privateMethods = {
onDocumentKeydown: function (event) {
if (event.keyCode === 27) {
publicMethods.close('$escape');
}
},
activate: function($dialog) {
var options = $dialog.data('$ngDialogOptions');
if (options.trapFocus) {
$dialog.on('keydown', privateMethods.onTrapFocusKeydown);
// Catch rogue changes (eg. after unfocusing everything by clicking a non-focusable element)
$body.on('keydown', privateMethods.onTrapFocusKeydown);
}
},
deactivate: function ($dialog) {
$dialog.off('keydown', privateMethods.onTrapFocusKeydown);
$body.off('keydown', privateMethods.onTrapFocusKeydown);
},
deactivateAll: function () {
angular.forEach(function(el) {
var $dialog = angular.element(el);
privateMethods.deactivate($dialog);
});
},
setBodyPadding: function (width) {
var originalBodyPadding = parseInt(($body.css('padding-right') || 0), 10);
$body.css('padding-right', (originalBodyPadding + width) + 'px');
$body.data('ng-dialog-original-padding', originalBodyPadding);
},
resetBodyPadding: function () {
var originalBodyPadding = $body.data('ng-dialog-original-padding');
if (originalBodyPadding) {
$body.css('padding-right', originalBodyPadding + 'px');
} else {
$body.css('padding-right', '');
}
},
performCloseDialog: function ($dialog, value) {
var id = $dialog.attr('id');
var scope = scopes[id];
if (!scope) {
// Already closed
return;
}
if (typeof $window.Hammer !== 'undefined') {
var hammerTime = scope.hammerTime;
hammerTime.off('tap', closeByDocumentHandler);
hammerTime.destroy && hammerTime.destroy();
delete scope.hammerTime;
} else {
$dialog.unbind('click');
}
if (dialogsCount === 1) {
$body.unbind('keydown');
}
if (!$dialog.hasClass('ngdialog-closing')){
dialogsCount -= 1;
}
var previousFocus = $dialog.data('$ngDialogPreviousFocus');
if (previousFocus) {
previousFocus.focus();
}
$rootScope.$broadcast('ngDialog.closing', $dialog);
dialogsCount = dialogsCount < 0 ? 0 : dialogsCount;
if (animationEndSupport) {
scope.$destroy();
$dialog.unbind(animationEndEvent).bind(animationEndEvent, function () {
$dialog.remove();
if (dialogsCount === 0) {
$body.removeClass('ngdialog-open');
privateMethods.resetBodyPadding();
}
$rootScope.$broadcast('ngDialog.closed', $dialog);
}).addClass('ngdialog-closing');
} else {
scope.$destroy();
$dialog.remove();
if (dialogsCount === 0) {
$body.removeClass('ngdialog-open');
privateMethods.resetBodyPadding();
}
$rootScope.$broadcast('ngDialog.closed', $dialog);
}
if (defers[id]) {
defers[id].resolve({
id: id,
value: value,
$dialog: $dialog,
remainingDialogs: dialogsCount
});
delete defers[id];
}
if (scopes[id]) {
delete scopes[id];
}
openIdStack.splice(openIdStack.indexOf(id), 1);
if (!openIdStack.length) {
$body.unbind('keydown', privateMethods.onDocumentKeydown);
keydownIsBound = false;
}
},
closeDialog: function ($dialog, value) {
var preCloseCallback = $dialog.data('$ngDialogPreCloseCallback');
if (preCloseCallback && angular.isFunction(preCloseCallback)) {
var preCloseCallbackResult = preCloseCallback.call($dialog, value);
if (angular.isObject(preCloseCallbackResult)) {
if (preCloseCallbackResult.closePromise) {
preCloseCallbackResult.closePromise.then(function () {
privateMethods.performCloseDialog($dialog, value);
});
} else {
preCloseCallbackResult.then(function () {
privateMethods.performCloseDialog($dialog, value);
}, function () {
return;
});
}
} else if (preCloseCallbackResult !== false) {
privateMethods.performCloseDialog($dialog, value);
}
} else {
privateMethods.performCloseDialog($dialog, value);
}
},
onTrapFocusKeydown: function(ev) {
var el = angular.element(ev.currentTarget);
var $dialog;
if (el.hasClass('ngdialog')) {
$dialog = el;
} else {
$dialog = privateMethods.getActiveDialog();
if ($dialog === null) {
return;
}
}
var isTab = (ev.keyCode === 9);
var backward = (ev.shiftKey === true);
if (isTab) {
privateMethods.handleTab($dialog, ev, backward);
}
},
handleTab: function($dialog, ev, backward) {
var focusableElements = privateMethods.getFocusableElements($dialog);
if (focusableElements.length === 0) {
if (document.activeElement) {
document.activeElement.blur();
}
return;
}
var currentFocus = document.activeElement;
var focusIndex = Array.prototype.indexOf.call(focusableElements, currentFocus);
var isFocusIndexUnknown = (focusIndex === -1);
var isFirstElementFocused = (focusIndex === 0);
var isLastElementFocused = (focusIndex === focusableElements.length - 1);
var cancelEvent = false;
if (backward) {
if (isFocusIndexUnknown || isFirstElementFocused) {
focusableElements[focusableElements.length - 1].focus();
cancelEvent = true;
}
} else {
if (isFocusIndexUnknown || isLastElementFocused) {
focusableElements[0].focus();
cancelEvent = true;
}
}
if (cancelEvent) {
ev.preventDefault();
ev.stopPropagation();
}
},
autoFocus: function($dialog) {
var dialogEl = $dialog[0];
// Browser's (Chrome 40, Forefix 37, IE 11) don't appear to honor autofocus on the dialog, but we should
var autoFocusEl = dialogEl.querySelector('*[autofocus]');
if (autoFocusEl !== null) {
autoFocusEl.focus();
if (document.activeElement === autoFocusEl) {
return;
}
// Autofocus element might was display: none, so let's continue
}
var focusableElements = privateMethods.getFocusableElements($dialog);
if (focusableElements.length > 0) {
focusableElements[0].focus();
return;
}
// We need to focus something for the screen readers to notice the dialog
var contentElements = privateMethods.filterVisibleElements(dialogEl.querySelectorAll('h1,h2,h3,h4,h5,h6,p,span'));
if (contentElements.length > 0) {
var contentElement = contentElements[0];
$el(contentElement).attr('tabindex', '-1').css('outline', '0');
contentElement.focus();
}
},
getFocusableElements: function ($dialog) {
var dialogEl = $dialog[0];
var rawElements = dialogEl.querySelectorAll(focusableElementSelector);
return privateMethods.filterVisibleElements(rawElements);
},
filterVisibleElements: function (els) {
var visibleFocusableElements = [];
for (var i = 0; i < els.length; i++) {
var el = els[i];
if (el.offsetWidth > 0 || el.offsetHeight > 0) {
visibleFocusableElements.push(el);
}
}
return visibleFocusableElements;
},
getActiveDialog: function () {
var dialogs = document.querySelectorAll('.ngdialog');
if (dialogs.length === 0) {
return null;
}
// TODO: This might be incorrect if there are a mix of open dialogs with different 'appendTo' values
return $el(dialogs[dialogs.length - 1]);
},
applyAriaAttributes: function ($dialog, options) {
if (options.ariaAuto) {
if (!options.ariaRole) {
var detectedRole = (privateMethods.getFocusableElements($dialog).length > 0) ?
'dialog' :
'alertdialog';
options.ariaRole = detectedRole;
}
if (!options.ariaLabelledBySelector) {
options.ariaLabelledBySelector = 'h1,h2,h3,h4,h5,h6';
}
if (!options.ariaDescribedBySelector) {
options.ariaDescribedBySelector = 'article,section,p';
}
}
if (options.ariaRole) {
$dialog.attr('role', options.ariaRole);
}
privateMethods.applyAriaAttribute(
$dialog, 'aria-labelledby', options.ariaLabelledById, options.ariaLabelledBySelector);
privateMethods.applyAriaAttribute(
$dialog, 'aria-describedby', options.ariaDescribedById, options.ariaDescribedBySelector);
},
applyAriaAttribute: function($dialog, attr, id, selector) {
if (id) {
$dialog.attr(attr, id);
}
if (selector) {
var dialogId = $dialog.attr('id');
var firstMatch = $dialog[0].querySelector(selector);
if (!firstMatch) {
return;
}
var generatedId = dialogId + '-' + attr;
$el(firstMatch).attr('id', generatedId);
$dialog.attr(attr, generatedId);
return generatedId;
}
}
};
var publicMethods = {
/*
* @param {Object} options:
* - template {String} - id of ng-template, url for partial, plain string (if enabled)
* - plain {Boolean} - enable plain string templates, default false
* - scope {Object}
* - controller {String}
* - controllerAs {String}
* - className {String} - dialog theme class
* - showClose {Boolean} - show close button, default true
* - closeByEscape {Boolean} - default true
* - closeByDocument {Boolean} - default true
* - preCloseCallback {String|Function} - user supplied function name/function called before closing dialog (if set)
*
* @return {Object} dialog
*/
open: function (opts) {
var options = angular.copy(defaults);
var localID = ++globalID;
var dialogID = 'ngdialog' + localID;
openIdStack.push(dialogID);
opts = opts || {};
angular.extend(options, opts);
var defer;
defers[dialogID] = defer = $q.defer();
var scope;
scopes[dialogID] = scope = angular.isObject(options.scope) ? options.scope.$new() : $rootScope.$new();
var $dialog, $dialogParent;
var resolve = angular.extend({}, options.resolve);
angular.forEach(resolve, function (value, key) {
resolve[key] = angular.isString(value) ? $injector.get(value) : $injector.invoke(value, null, null, key);
});
$q.all({
template: loadTemplate(options.template || options.templateUrl),
locals: $q.all(resolve)
}).then(function (setup) {
var template = setup.template,
locals = setup.locals;
$templateCache.put(options.template || options.templateUrl, template);
if (options.showClose) {
template += '<div class="ngdialog-close"></div>';
}
$dialog = $el('<div id="ngdialog' + localID + '" class="ngdialog"></div>');
$dialog.html((options.overlay ?
'<div class="ngdialog-overlay"></div><div class="ngdialog-content" role="document">' + template + '</div>' :
'<div class="ngdialog-content" role="document">' + template + '</div>'));
$dialog.data('$ngDialogOptions', options);
if (options.data && angular.isString(options.data)) {
var firstLetter = options.data.replace(/^\s*/, '')[0];
scope.ngDialogData = (firstLetter === '{' || firstLetter === '[') ? angular.fromJson(options.data) : options.data;
} else if (options.data && angular.isObject(options.data)) {
scope.ngDialogData = options.data;
}
if (options.controller && (angular.isString(options.controller) || angular.isArray(options.controller) || angular.isFunction(options.controller))) {
var ctrl = options.controller;
if (options.controllerAs && angular.isString(options.controllerAs)) {
ctrl += ' as ' + options.controllerAs;
}
var controllerInstance = $controller(ctrl, angular.extend(
locals,
{
$scope: scope,
$element: $dialog
}
));
$dialog.data('$ngDialogControllerController', controllerInstance);
}
if (options.className) {
$dialog.addClass(options.className);
}
if (options.appendTo && angular.isString(options.appendTo)) {
$dialogParent = angular.element(document.querySelector(options.appendTo));
} else {
$dialogParent = $body;
}
privateMethods.applyAriaAttributes($dialog, options);
if (options.preCloseCallback) {
var preCloseCallback;
if (angular.isFunction(options.preCloseCallback)) {
preCloseCallback = options.preCloseCallback;
} else if (angular.isString(options.preCloseCallback)) {
if (scope) {
if (angular.isFunction(scope[options.preCloseCallback])) {
preCloseCallback = scope[options.preCloseCallback];
} else if (scope.$parent && angular.isFunction(scope.$parent[options.preCloseCallback])) {
preCloseCallback = scope.$parent[options.preCloseCallback];
} else if ($rootScope && angular.isFunction($rootScope[options.preCloseCallback])) {
preCloseCallback = $rootScope[options.preCloseCallback];
}
}
}
if (preCloseCallback) {
$dialog.data('$ngDialogPreCloseCallback', preCloseCallback);
}
}
scope.closeThisDialog = function (value) {
privateMethods.closeDialog($dialog, value);
};
$timeout(function () {
var $activeDialogs = document.querySelectorAll('.ngdialog');
privateMethods.deactivateAll($activeDialogs);
$compile($dialog)(scope);
var widthDiffs = $window.innerWidth - $body.prop('clientWidth');
$body.addClass('ngdialog-open');
var scrollBarWidth = widthDiffs - ($window.innerWidth - $body.prop('clientWidth'));
if (scrollBarWidth > 0) {
privateMethods.setBodyPadding(scrollBarWidth);
}
$dialogParent.append($dialog);
privateMethods.activate($dialog);
if (options.trapFocus) {
privateMethods.autoFocus($dialog);
}
if (options.name) {
$rootScope.$broadcast('ngDialog.opened', {dialog: $dialog, name: options.name});
} else {
$rootScope.$broadcast('ngDialog.opened', $dialog);
}
});
if (!keydownIsBound) {
$body.bind('keydown', privateMethods.onDocumentKeydown);
keydownIsBound = true;
}
if (options.closeByNavigation) {
$rootScope.$on('$locationChangeSuccess', function () {
privateMethods.closeDialog($dialog);
});
}
if (options.preserveFocus) {
$dialog.data('$ngDialogPreviousFocus', document.activeElement);
}
closeByDocumentHandler = function (event) {
var isOverlay = options.closeByDocument ? $el(event.target).hasClass('ngdialog-overlay') : false;
var isCloseBtn = $el(event.target).hasClass('ngdialog-close');
if (isOverlay || isCloseBtn) {
publicMethods.close($dialog.attr('id'), isCloseBtn ? '$closeButton' : '$document');
}
};
if (typeof $window.Hammer !== 'undefined') {
var hammerTime = scope.hammerTime = $window.Hammer($dialog[0]);
hammerTime.on('tap', closeByDocumentHandler);
} else {
$dialog.bind('click', closeByDocumentHandler);
}
dialogsCount += 1;
return publicMethods;
});
return {
id: dialogID,
closePromise: defer.promise,
close: function (value) {
privateMethods.closeDialog($dialog, value);
}
};
function loadTemplateUrl (tmpl, config) {
return $http.get(tmpl, (config || {})).then(function(res) {
return res.data || '';
});
}
function loadTemplate (tmpl) {
if (!tmpl) {
return 'Empty template';
}
if (angular.isString(tmpl) && options.plain) {
return tmpl;
}
if (typeof options.cache === 'boolean' && !options.cache) {
return loadTemplateUrl(tmpl, {cache: false});
}
return $templateCache.get(tmpl) || loadTemplateUrl(tmpl, {cache: true});
}
},
/*
* @param {Object} options:
* - template {String} - id of ng-template, url for partial, plain string (if enabled)
* - plain {Boolean} - enable plain string templates, default false
* - name {String}
* - scope {Object}
* - controller {String}
* - controllerAs {String}
* - className {String} - dialog theme class
* - showClose {Boolean} - show close button, default true
* - closeByEscape {Boolean} - default false
* - closeByDocument {Boolean} - default false
* - preCloseCallback {String|Function} - user supplied function name/function called before closing dialog (if set); not called on confirm
*
* @return {Object} dialog
*/
openConfirm: function (opts) {
var defer = $q.defer();
var options = {
closeByEscape: false,
closeByDocument: false
};
angular.extend(options, opts);
options.scope = angular.isObject(options.scope) ? options.scope.$new() : $rootScope.$new();
options.scope.confirm = function (value) {
defer.resolve(value);
var $dialog = $el(document.getElementById(openResult.id));
privateMethods.performCloseDialog($dialog, value);
};
var openResult = publicMethods.open(options);
openResult.closePromise.then(function (data) {
if (data) {
return defer.reject(data.value);
}
return defer.reject();
});
return defer.promise;
},
isOpen: function(id) {
var $dialog = $el(document.getElementById(id));
return $dialog.length > 0;
},
/*
* @param {String} id
* @return {Object} dialog
*/
close: function (id, value) {
var $dialog = $el(document.getElementById(id));
if ($dialog.length) {
privateMethods.closeDialog($dialog, value);
} else {
if (id === '$escape') {
var topDialogId = openIdStack[openIdStack.length - 1];
$dialog = $el(document.getElementById(topDialogId));
if ($dialog.data('$ngDialogOptions').closeByEscape) {
privateMethods.closeDialog($dialog, value);
}
}
}
return publicMethods;
},
closeAll: function (value) {
var $all = document.querySelectorAll('.ngdialog');
// Reverse order to ensure focus restoration works as expected
for (var i = $all.length - 1; i >= 0; i--) {
var dialog = $all[i];
privateMethods.closeDialog($el(dialog), value);
}
},
getDefaults: function () {
return defaults;
}
};
return publicMethods;
}];
});
m.directive('ngDialog', ['ngDialog', function (ngDialog) {
return {
restrict: 'A',
scope: {
ngDialogScope: '='
},
link: function (scope, elem, attrs) {
elem.on('click', function (e) {
e.preventDefault();
var ngDialogScope = angular.isDefined(scope.ngDialogScope) ? scope.ngDialogScope : 'noScope';
angular.isDefined(attrs.ngDialogClosePrevious) && ngDialog.close(attrs.ngDialogClosePrevious);
var defaults = ngDialog.getDefaults();
ngDialog.open({
template: attrs.ngDialog,
className: attrs.ngDialogClass || defaults.className,
controller: attrs.ngDialogController,
controllerAs: attrs.ngDialogControllerAs,
scope: ngDialogScope,
data: attrs.ngDialogData,
showClose: attrs.ngDialogShowClose === 'false' ? false : (attrs.ngDialogShowClose === 'true' ? true : defaults.showClose),
closeByDocument: attrs.ngDialogCloseByDocument === 'false' ? false : (attrs.ngDialogCloseByDocument === 'true' ? true : defaults.closeByDocument),
closeByEscape: attrs.ngDialogCloseByEscape === 'false' ? false : (attrs.ngDialogCloseByEscape === 'true' ? true : defaults.closeByEscape),
preCloseCallback: attrs.ngDialogPreCloseCallback || defaults.preCloseCallback
});
});
}
};
}]);
return m;
}));
@-webkit-keyframes ngdialog-fadeout {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
@keyframes ngdialog-fadeout {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
@-webkit-keyframes ngdialog-fadein {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
@keyframes ngdialog-fadein {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
.ngdialog {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
/*-webkit-transform: translate3d(0,0,0);*/
}
.ngdialog *,
.ngdialog *:before,
.ngdialog *:after {
-webkit-box-sizing: inherit;
-moz-box-sizing: inherit;
box-sizing: inherit;
}
.ngdialog {
position: fixed;
overflow: auto;
/*-webkit-transform: translate3d(0,0,0);*/
-webkit-overflow-scrolling: touch;
z-index: 10000;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.ngdialog-overlay {
position: fixed;
background: rgba(0, 0, 0, 0.4);
top: 0;
right: 0;
bottom: 0;
left: 0;
-webkit-backface-visibility: hidden;
-webkit-animation: ngdialog-fadein 0.5s;
/nimation: ngdialog-fadein 0.5s;
}
.ngdialog.ngdialog-closing .ngdialog-overlay {
-webkit-backface-visibility: hidden;
-webkit-animation: ngdialog-fadeout 0.5s;
animation: ngdialog-fadeout 0.5s;
}
.ngdialog-content {
background: white;
-webkit-backface-visibility: hidden;
-webkit-animation: ngdialog-fadein 0.5s;
animation: ngdialog-fadein 0.5s;
}
.ngdialog.ngdialog-closing .ngdialog-content {
-webkit-backface-visibility: hidden;
-webkit-animation: ngdialog-fadeout 0.5s;
animation: ngdialog-fadeout 0.5s;
}
.ngdialog-close:before {
font-family: 'Helvetica', Arial, sans-serif;
content: '\00D7';
cursor: pointer;
}
body.ngdialog-open {
overflow: hidden;
/*-webkit-transform: translate3d(0,0,0);*/
}
@-webkit-keyframes ngdialog-flyin {
0% {
opacity: 0;
-webkit-transform: translateY(-40px);
transform: translateY(-40px);
}
100% {
opacity: 1;
-webkit-transform: translateY(0);
transform: translateY(0);
}
}
@keyframes ngdialog-flyin {
0% {
opacity: 0;
-webkit-transform: translateY(-40px);
-ms-transform: translateY(-40px);
transform: translateY(-40px);
}
100% {
opacity: 1;
-webkit-transform: translateY(0);
-ms-transform: translateY(0);
transform: translateY(0);
}
}
@-webkit-keyframes ngdialog-flyout {
0% {
opacity: 1;
-webkit-transform: translateY(0);
transform: translateY(0);
}
100% {
opacity: 0;
-webkit-transform: translateY(-40px);
transform: translateY(-40px);
}
}
@keyframes ngdialog-flyout {
0% {
opacity: 1;
-webkit-transform: translateY(0);
-ms-transform: translateY(0);
transform: translateY(0);
}
100% {
opacity: 0;
-webkit-transform: translateY(-40px);
-ms-transform: translateY(-40px);
transform: translateY(-40px);
}
}
.ngdialog.ngdialog-theme-default {
padding-bottom: 160px;
padding-top: 160px;
}
.ngdialog.ngdialog-theme-default.ngdialog-closing .ngdialog-content {
-webkit-animation: ngdialog-flyout .5s;
animation: ngdialog-flyout .5s;
}
.ngdialog.ngdialog-theme-default .ngdialog-content {
-webkit-animation: ngdialog-flyin .5s;
animation: ngdialog-flyin .5s;
background: #f0f0f0;
border-radius: 5px;
color: #444;
font-family: 'Helvetica',sans-serif;
font-size: 1.1em;
line-height: 1.5em;
margin: 0 auto;
max-width: 100%;
padding: 1em;
position: relative;
width: 450px;
}
.ngdialog.ngdialog-theme-default .ngdialog-close {
border-radius: 5px;
cursor: pointer;
position: absolute;
right: 0;
top: 0;
}
.ngdialog.ngdialog-theme-default .ngdialog-close:before {
background: transparent;
border-radius: 3px;
color: #bbb;
content: '\00D7';
font-size: 26px;
font-weight: 400;
height: 30px;
line-height: 26px;
position: absolute;
right: 3px;
text-align: center;
top: 3px;
width: 30px;
}
.ngdialog.ngdialog-theme-default .ngdialog-close:hover:before,
.ngdialog.ngdialog-theme-default .ngdialog-close:active:before {
color: #777;
}
.ngdialog.ngdialog-theme-default .ngdialog-message {
margin-bottom: .5em;
}
.ngdialog.ngdialog-theme-default .ngdialog-input {
margin-bottom: 1em;
}
.ngdialog.ngdialog-theme-default .ngdialog-input textarea,
.ngdialog.ngdialog-theme-default .ngdialog-input input[type="text"],
.ngdialog.ngdialog-theme-default .ngdialog-input input[type="password"],
.ngdialog.ngdialog-theme-default .ngdialog-input input[type="email"],
.ngdialog.ngdialog-theme-default .ngdialog-input input[type="url"] {
background: #fff;
border: 0;
border-radius: 3px;
font-family: inherit;
font-size: inherit;
font-weight: inherit;
margin: 0 0 .25em;
min-height: 2.5em;
padding: .25em .67em;
width: 100%;
}
.ngdialog.ngdialog-theme-default .ngdialog-input textarea:focus,
.ngdialog.ngdialog-theme-default .ngdialog-input input[type="text"]:focus,
.ngdialog.ngdialog-theme-default .ngdialog-input input[type="password"]:focus,
.ngdialog.ngdialog-theme-default .ngdialog-input input[type="email"]:focus,
.ngdialog.ngdialog-theme-default .ngdialog-input input[type="url"]:focus {
-webkit-box-shadow: inset 0 0 0 2px #8dbdf1;
box-shadow: inset 0 0 0 2px #8dbdf1;
outline: none;
}
.ngdialog.ngdialog-theme-default .ngdialog-buttons {
*zoom: 1;
}
.ngdialog.ngdialog-theme-default .ngdialog-buttons:after {
content: '';
display: table;
clear: both;
}
.ngdialog.ngdialog-theme-default .ngdialog-button {
border: 0;
border-radius: 3px;
cursor: pointer;
float: right;
font-family: inherit;
font-size: .8em;
letter-spacing: .1em;
line-height: 1em;
margin: 0 0 0 .5em;
padding: .75em 2em;
text-transform: uppercase;
}
.ngdialog.ngdialog-theme-default .ngdialog-button:focus {
-webkit-animation: ngdialog-pulse 1.1s infinite;
animation: ngdialog-pulse 1.1s infinite;
outline: none;
}
@media (max-width: 568px) {
.ngdialog.ngdialog-theme-default .ngdialog-button:focus {
-webkit-animation: none;
animation: none;
}
}
.ngdialog.ngdialog-theme-default .ngdialog-button.ngdialog-button-primary {
background: #3288e6;
color: #fff;
}
.ngdialog.ngdialog-theme-default .ngdialog-button.ngdialog-button-secondary {
background: #e0e0e0;
color: #777;
}