Edit in JSFiddle

(function (app) {
    'use strict';

    app.config([
        'triDialogManagerProvider',
        function (dialogManagerProvider) {
            dialogManagerProvider.config({
                rootClass: 'dialog-root',
                maskClass: 'dialog-mask',
                dialogClass: 'dialog-itself'
            }).when('dialog440', {
                controller: 'DialogSimpleCtrl',
                templateUrl: 'partials/dialog.html',
                dialogClass: 'dialog-440'
            });
        }
    ]);

    app.controller('DialogSimpleCtrl', [
        '$scope',
        '$log',
        '$dialog', // from 'locals' passed to $controller
        function ($scope, $log, $dialog) {
            $scope.$dialog = $dialog;
            $scope.$on('triDialogTemplateRequested', $log.log.bind($log));
            $scope.$on('triDialogTemplateLoaded', $log.log.bind($log));
            $scope.$on('triDialogTemplateError', $log.log.bind($log));
        }
    ]);

    app.controller('DialogTriggersList', [
        '$scope',
        'triDialog',
        function ($scope, triDialog) {

            $scope.dialog440 = function () {
                console.log('dialog440');
                triDialog('dialog440', {
                    anotherDialog: function () {
                        $scope.dialog800();
                    }
                }).promise.then(function (a) {
                    console.log('resolve', a);
                }, function (a) {
                    console.log('reject', a);
                }, function (a) {
                    console.log('notify', a);
                });
            };

            $scope.dialog800 = function () {
                console.log('dialog800');
                triDialog({
                    controller: 'DialogSimpleCtrl',
                    templateUrl: 'partials/dialog.html',
                    dialogClass: 'dialog-600',
                    topOffset: '33px',
                    modal: true
                }, {
                    anotherDialog: function () {
                        $scope.dialog440();
                    }
                }).promise.then(function (a) {
                    console.log('resolve', a);
                }, function (a) {
                    console.log('reject', a);
                }, function (a) {
                    console.log('notify', a);
                });
            };

            $scope.dialogFail = function () {
                console.log('dialogFail');
                triDialog({
                    controller: 'DialogSimpleCtrl',
                    templateUrl: 'partials/dia_XXX_g.html',
                    dialogClass: 'dialog-440',
                    topOffset: '50%'
                }).promise.then(function (a) {
                    console.log('resolve', a);
                }, function (a) {
                    console.log('reject', a);
                }, function (a) {
                    console.log('notify', a);
                });
            };
            
            $scope.dialogConfigFail = function () {
                console.log('dialogFail');
                triDialog('dialogFail');
            };
        }
    ]);

}(angular.module('demoApp', ['triNgDialog'])));

var tri;!function(t){var e;!function(t){"use strict";!function(t){t[t.Accepted=0]="Accepted",t[t.Cancelled=1]="Cancelled",t[t.Closed=2]="Closed",t[t.Closing=3]="Closing",t[t.ClosingEsc=4]="ClosingEsc",t[t.ClosingMask=5]="ClosingMask",t[t.Open=6]="Open",t[t.Opening=7]="Opening",t[t.TemplateError=8]="TemplateError",t[t.TemplateLoaded=9]="TemplateLoaded"}(t.noty||(t.noty={}));var e=t.noty;t.conf={baseZindex:3e3,rootClass:"dialog-root",maskClass:"dialog-mask",dialogClass:"dialog",mainNamespace:"main",processTopOffset:!1,eventCore:"TriDialog",eventPrefix:"triDialog",eventOpen:"Open",eventClosing:"Closing",eventClose:"Close",eventLoaded:"Loaded",eventError:"Error",eventRequested:"Requested",eventTemplate:"Template"},t.definitions={},t.mod=angular.module("triNgDialog",["ngAnimate"]).constant("triDialogNoty",e).constant("triDialogConfig",t.conf)}(e=t.dialog||(t.dialog={}))}(tri||(tri={}));var tri;!function(t){var e;!function(t){"use strict";t.mod.directive("triDialogMask",["$animate","triDialogConfig","triDialogManager",function(t,e,o){var i=function(i,n,r,a,s){var l=n.parent(),c=null,g=null,d=function(t){t.css("z-index",e.baseZindex+2*o.dialogs.length-1)},u=function(){o.hasAny(a.namespace)?g?d(g):g=s(function(e){t.enter(e,l,n),d(e),c&&(c.remove(),c=null)}):g&&(t.leave(g,function(){c=null}),c=g,g=null)};i.$on(a.namespace+e.eventCore+e.eventOpen,u),i.$on(a.namespace+e.eventCore+e.eventClosing,u),t.leave(g)};return{link:i,priority:100,require:"^triDialogRoot",restrict:"A",terminal:!0,transclude:"element"}}]),t.mod.directive("triDialogMask",["triDialogManager","triDialogConfig",function(e,o){var i=function(t,e,i,n){e.addClass(n.maskClass+" "+o.maskClass)},n=function(i,n,r,a){n.on("click",function(){var n=e.getUpperDialog();n&&!n.modal&&(a.broadcast(o.eventClose,{accepted:!1,dialog:n.notify(t.noty.ClosingMask),reason:"maskClick"}),i.$digest())})};return{link:{pre:i,post:n},priority:-100,require:"^triDialogRoot",restrict:"A"}}])}(e=t.dialog||(t.dialog={}))}(tri||(tri={}));var tri;!function(t){var e;!function(t){"use strict";t.mod.run(["$rootScope","$document","triDialogManager",function(e,o,i){o.on("keydown keypress",function(o){var n;27===o.which&&i.dialogs.length&&(n=i.getUpperDialog(),!n.blockedDialog&&i.hasRoot(n.namespace)&&(i.getRoot(n.namespace).broadcast(t.conf.eventClose,{accepted:!1,dialog:n.notify(t.noty.ClosingEsc),reason:"esc"}),e.$digest()))})}]),t.mod.directive("triDialogRoot",["triDialogManager",function(e){var o=function(e,o,i){var n=this;this.namespace=o.triDialogRoot||t.conf.mainNamespace,i.registerRoot(this),e.$on("$destroy",function(){i.unRegisterRoot(n)}),angular.extend(this,{maskClass:this.namespace+"-"+t.conf.maskClass,rootClass:this.namespace+"-"+t.conf.rootClass,dialogs:{},broadcast:function(o,i){e.$broadcast(this.namespace+t.conf.eventCore+o,i)},listen:function(o,i){e.$on(this.namespace+t.conf.eventCore+o,i)}})},i=function(o,i,n,r){r.listen(t.conf.eventOpen,function(){i.addClass(t.conf.rootClass+" "+t.conf.rootClass)}),r.listen(t.conf.eventClosing,function(){e.hasAny(r.namespace)||i.removeClass(r.rootClass+" "+t.conf.rootClass)})},n=function(t){t.append("<div tri:dialog-mask/><div tri:dialog/>")};return{controller:["$scope","$attrs","triDialogManager",o],link:i,require:"triDialogRoot",restrict:"A",template:n}}])}(e=t.dialog||(t.dialog={}))}(tri||(tri={}));var tri;!function(t){var e;!function(t){"use strict";function e(e,o,i,n,r,a,s){var l=function(l,c,g,d,u){d.listen(a.eventOpen,function(r,l){var g=function(t,e){var o=i(l.controller,{$dialog:l,$data:l.data,$scope:e});l.controllerAs&&(e[l.controllerAs]=o),t.data("$triDialogController",o)},p=function(){var t={zIndex:a.baseZindex+2*(l.label+1)};return(a.processTopOffset||null!=l.topOffset)&&(t.top=s.getTopOffset(l.topOffset)),t};u(o.$new(),function(o,i){l.controller?g(o,i):i.$dialog=l,o.data("$triDialog",l).css(p()).addClass(a.dialogClass+" "+l.dialogClass),d.dialogs[l.label]=o,n(function(){l.notify(t.noty.Opening)},1),e.enter(o,c.parent(),c,function(){l.notify(t.noty.Open)})})}),d.listen(a.eventClose,function(o,i){var n,s=i.dialog,l=d.dialogs[s.label];l&&l.data("$triDialog")===s&&(n=l.scope(),e.leave(l,function(){s.notify(t.noty.Closed),n.$destroy(),l.removeData().children().removeData(),s.destroy(i),s=l=null}),delete d.dialogs[s.label],r.unRegisterDialog(s.label),d.broadcast(a.eventClosing,s))})};return{link:l,require:"^triDialogRoot",restrict:"A",scope:!0,transclude:"element",priority:600}}function o(e,o,i,n,r){var a=function(a,s){var l=s.data("$triDialog"),c=s.data("$triDialogController");o.get(l.templateUrl,{cache:n}).success(function(e){var o;s.html(e),o=i(s.contents()),c&&s.children().data("$triDialogController",c),o(a),l.notify(t.noty.TemplateLoaded),a.$broadcast(r.eventPrefix+r.eventTemplate+r.eventLoaded)}).error(function(){a.$broadcast(r.eventPrefix+r.eventTemplate+r.eventError),l.notify(t.noty.TemplateError),e.error(new Error("triDialog: could not load template!"))}),a.$broadcast(r.eventPrefix+r.eventTemplate+r.eventRequested)};return{link:a,require:"^triDialogRoot",restrict:"A"}}e.$inject=["$animate","$rootScope","$controller","$timeout","triDialogManager","triDialogConfig","triDialogUtilities"],o.$inject=["$log","$http","$compile","$templateCache","triDialogConfig"],t.mod.directive("triDialog",o),t.mod.directive("triDialog",e)}(e=t.dialog||(t.dialog={}))}(tri||(tri={}));var tri;!function(t){var e;!function(t){"use strict";var e=function(){function e(){this.dialogs=[],this.roots={}}return e.prototype.hasAny=function(t){return this.dialogs.some(function(e){return e.namespace===t})},e.prototype.hasRoot=function(t){return this.roots.hasOwnProperty(t)},e.prototype.getRoot=function(t){return this.roots[t]},e.prototype.getUpperDialog=function(){var t=this.dialogs.length;return t>0&&this.dialogs[t-1]},e.prototype.registerDialog=function(t){return t.label=this.dialogs.push(t)-1,t},e.prototype.unRegisterDialog=function(t){var e=this.dialogs[t];return e&&e.label===t?(this.dialogs.splice(t,1),!0):!1},e.prototype.triggerDialog=function(e){if(!this.roots.hasOwnProperty(e.namespace))throw new Error("TriDialog: rootCtrl "+e.namespace+" is not registered!");return this.roots[e.namespace].broadcast(t.conf.eventOpen,this.registerDialog(e)),this},e.prototype.closeDialog=function(e){if(!this.roots.hasOwnProperty(e.dialog.namespace))throw new Error("TriDialog: rootCtrl "+e.dialog.namespace+" is not registered!");return this.roots[e.dialog.namespace].broadcast(t.conf.eventClose,e),this},e.prototype.registerRoot=function(t){if(!t.namespace)throw new Error("TriDialog: rootCtrl has no namespace assigned!");if(this.roots.hasOwnProperty(t.namespace))throw new Error("TriDialog: rootCtrl "+t.namespace+" already registered!");return this.roots[t.namespace]=t,this},e.prototype.unRegisterRoot=function(t){if(!this.roots.hasOwnProperty(t.namespace))throw new Error("TriDialog: rootCtrl "+t.namespace+" is not registered!");return delete this.roots[t.namespace],this},e}();t.mod.provider("triDialogManager",["triDialogConfig",function(o){return{config:function(t){return angular.extend(o,t),this},when:function(e,o){return t.definitions[e]=o,this},$get:function(){return new e}}}])}(e=t.dialog||(t.dialog={}))}(tri||(tri={}));var tri;!function(t){var e;!function(t){"use strict";var e=document.body,o=document.documentElement,i={isW3C:"undefined"!=typeof window.innerWidth,isIE:"undefined"!=typeof o&&"undefined"!=typeof o.clientWidth&&0!=o.clientWidth},n=function(){function t(){}return t.prototype.getViewportSize=function(){return i.isW3C?{width:window.innerWidth,height:window.innerHeight}:i.isIE?{width:o.clientWidth,height:o.clientHeight}:{width:e.clientWidth,height:e.clientHeight}},t.prototype.getTopScroll=function(){return e.scrollTop||o.scrollTop},t.prototype.getTopOffset=function(t){var e=this.getViewportSize().height,o=this.getTopScroll(),i=parseInt(t,10);return null==t?o+e/5+"px":isNaN(i)?o+"px":angular.isString(t)&&"%"===t.charAt(t.length-1)?o+e*i/100+"px":o+i+"px"},t}();t.mod.service("triDialogUtilities",n)}(e=t.dialog||(t.dialog={}))}(tri||(tri={}));var tri;!function(t){var e;!function(t){"use strict";var e=function(){function e(e,o){if(angular.extend(this,{blockedDialog:!1,controller:null,controllerAs:null,dialogClass:"",topOffset:null,modal:!1,namespace:t.conf.mainNamespace,templateUrl:null,$_deferred:this.$_$q.defer()}),!e.templateUrl)throw new Error('triNgDialog.DialogData() - initialData must contain defined "templateUrl"');angular.extend(this,e,{data:o,modal:e.blockedDialog||e.modal||this.modal,promise:this.$_deferred.promise})}return e.prototype.accept=function(t){return this.close(t,!1)},e.prototype.cancel=function(t){return this.close(t,!0)},e.prototype.close=function(e,o){return this.$_dialogManager.closeDialog({accepted:!o,dialog:this,reason:e}),null!=o&&this.notify(o===!0?t.noty.Cancelled:t.noty.Accepted),this.notify(t.noty.Closing)},e.prototype.destroy=function(t){var e;t.accepted?this.$_deferred.resolve(t.reason):this.$_deferred.reject(t.reason);for(e in this)this.hasOwnProperty(e)&&delete this[e]},e.prototype.notify=function(e){return this.$_deferred.notify({dialog:this,status:t.noty[e]}),this},e.prototype.trigger=function(){return this.$_dialogManager.triggerDialog(this),this},e}();t.mod.factory("triDialog",["$q","triDialogManager",function(o,i){return angular.extend(e.prototype,{$_$q:o,$_dialogManager:i}),function(o,i){if(angular.isString(o)&&(o=t.definitions[o]),!o||!angular.isObject(o))throw new TypeError("First argument passed to triDialog service should be valid string or object");return new e(o,i).trigger()}}])}(e=t.dialog||(t.dialog={}))}(tri||(tri={}));


<section tri-dialog-root>
<header>
    <h1>AngularJS - triAngular - dialog</h1>
</header>
<ul ng-controller="DialogTriggersList">
    <li><button ng-click="dialog440()">Trigger 440px wide dialog</button></li>
    <li><button ng-click="dialog800()">Trigger 600px wide dialog</button></li>
    <li><button ng-click="dialogFail()">Trigger dialog with bad template url</button></li>
    <li><button ng-click="dialogConfigFail()">Trigger dialog with bad config key</button></li>
</ul>
<footer>
    <small>(d)WTF License</small>
</footer>
</section>

<script id="partials/dialog.html" type="text/ng-template">
    <header>
        <h2>Some dialog :)</h2>
    </header>
    <p>asj dnfoasdnf aosdjnf aosdnf aosdnf aosdn faosdnf oasdn foasdn foasdngfoasnd fgoasjfngasjfg</p>
    <p>asjo fansdfoj nasdof jnasdgjdfkhs ynsroae 5gnoi4w9 nsdkzdfkdvd djlsfaksdjgagasdf gkvjasgf d</p>
    <footer>
        <button ng-click="$dialog.data.anotherDialog()">another dialog</button>
        <button ng-click="$dialog.close()">close dialog</button>
        <button ng-click="$dialog.accept('ok')">ok</button>
        <button ng-click="$dialog.cancel('cancel')">cancel</button>
    </footer>
</script>
body {
    position: relative;
}

/*
 * base
 */

.dialog-mask {
    background-color: #515a5d;
    bottom: 0;
    left: 0;
    opacity: 0.9;
    position: fixed;
    right: 0;
    top: 0;
}

.dialog-itself {
    background-color: #fff;
    border-radius: 4px;
    box-shadow: 0 0 7px 2px rgba(0, 0, 0, .3);
    left: 50%;
    padding: 25px;
    position: absolute;
}

.dialog-mask,
.dialog-itself {
    transition: opacity 0.5s ease;
}

/*
 * ng animations
 */
.dialog-itself.ng-enter,
.dialog-itself.ng-leave.ng-leave-active,
.dialog-mask.ng-enter,
.dialog-mask.ng-leave.ng-leave-active {
    opacity: 0;
}

.dialog-itself.ng-leave,
.dialog-itself.ng-enter.ng-enter-active {
    opacity: 1;
}

.dialog-mask.ng-leave,
.dialog-mask.ng-enter.ng-enter-active  {
    opacity: 0.9;
}


/*
 * single dialog styles
 */
.dialog-itself header {
    padding-bottom: 30px;
}

.dialog-itself footer {
    padding-top: 30px;
}

.dialog-600 {
    margin-left: -300px;
    width: 600px;
}

.dialog-440 {
    margin-left: -220px;
    width: 390px;
}