Skip to content
This repository has been archived by the owner on May 30, 2022. It is now read-only.

Commit

Permalink
refactor(macModal): Refactored modal directive and service.
Browse files Browse the repository at this point in the history
Converted modal directive to isolated scope but transcluded content is using parent scope instead. This prevent modal `close` function ending up in parent scope.
Cleaned up modal stylus.
Removed modal service from modal scope.
Fixed modal test.
adrianlee44 committed Nov 27, 2013
1 parent 6687e1d commit 658ea76
Showing 6 changed files with 68 additions and 57 deletions.
8 changes: 3 additions & 5 deletions src/css/modal.styl
Original file line number Diff line number Diff line change
@@ -6,13 +6,11 @@
right 0
bottom 0
opacity 0
visibility hidden
overflow-y auto
z-index 3

&.visible, &.visible-add-active
visibility visible
opacity 1.0
opacity 1.0

.modal
top 50%
@@ -21,8 +19,7 @@
transition 0.2s ease-out all

&.visible-remove-active
visibility hidden
opacity 0
opacity 0

.modal
position absolute
@@ -35,6 +32,7 @@
box-shadow 0 4px 10px rgba(0,0,0,0.15)
transition all 0.2s ease-out
border-radius 3px
transform rotateX(0) rotateY(0)

&:after
content ""
83 changes: 47 additions & 36 deletions src/directives/modal.coffee
Original file line number Diff line number Diff line change
@@ -1,49 +1,60 @@
#
# @chalk overview
# @name mac-modal (element)
# @description
# Element directive to define the modal dialog. Modal content is transcluded into a
# modal template
#
# @param {Boolean} mac-modal-keyboard Allow closing modal with keyboard (default false)
# @param {Boolean} mac-modal-overlay-close Allow closing modal when clicking on overlay (default false)
# @param {Boolean} mac-modal-resize Allow modal to resize on window resize event (default true)
# @param {Function} mac-modal-open Callback when the modal is opened
# @param {Integer} mac-modal-topOffset Top offset when the modal is larger than window height (default 20)
#
###
@chalk overview
@name mac-modal (element)
@description
Element directive to define the modal dialog. Modal content is transcluded into a
modal template
@param {Boolean} mac-modal-keyboard Allow closing modal with keyboard (default false)
@param {Boolean} mac-modal-overlay-close Allow closing modal when clicking on overlay (default false)
@param {Boolean} mac-modal-resize Allow modal to resize on window resize event (default true)
@param {Expr} mac-modal-open Callback when the modal is opened
@param {Integer} mac-modal-topOffset Top offset when the modal is larger than window height (default 20)
###
angular.module("Mac").directive("macModal", [
"$rootScope"
"$parse"
"modal"
"modalViews"
"util"
($rootScope, $parse, modal, modalViews, util) ->
restrict: "E"
templateUrl: "template/modal.html"
replace: true
transclude: true
($parse, modal, modalViews, util) ->
restrict: "E"
template: modal.modalTemplate
replace: true
transclude: true

# NOTE: Isolated scope to prevent adding `close` function to parent
# scope. Transcluded content is currently using parent scope.
scope:
open: "&macModalOpen"

compile: (element, attrs, transclude) ->
($scope, element, attrs) ->
opts = util.extendAttributes "macModal", modalViews.defaults, attrs
# NOTE: As of AngularJS 1.2.2, transclude function is on the link
# function instead of compile
link: ($scope, element, attrs, controller, transclude) ->
# NOTE: Similiar to ngTransclude directive but the scope is
# parent scope
transclude $scope.$parent, (clone) ->
wrapper = angular.element(
element[0].getElementsByClassName "modal-content-wrapper"
)
wrapper.html ""
wrapper.append clone

registerModal = (id) ->
if id? and id
opts.callback = ->
$parse(opts.open) $scope if opts.open?
opts = util.extendAttributes "macModal", modalViews.defaults, attrs

modal.register id, element, opts
registerModal = (id) ->
if id? and id
opts.callback = $scope.open
modal.register id, element, opts

$scope.modal = modal
$scope.closeOverlay = ($event) ->
if opts.overlayClose and
angular.element($event.target).hasClass("modal-overlay")
modal.hide()
$scope.close = ($event, force = false) ->
if force or (opts.overlayClose and
angular.element($event.target).hasClass("modal-overlay"))
modal.hide()

if attrs.id
registerModal attrs.id
else
attrs.$observe "macModal", (id) -> registerModal id
if attrs.id
registerModal attrs.id
else
attrs.$observe "macModal", (id) -> registerModal id
]).

#
1 change: 1 addition & 0 deletions src/index.jade
Original file line number Diff line number Diff line change
@@ -85,6 +85,7 @@ block append content
.docs-example
mac-modal#test-modal(
mac-modal-keyboard
ng-cloak
)
.modal-content(ng-controller="modalController")
h1 Just another modal
20 changes: 14 additions & 6 deletions src/services/modal.coffee
Original file line number Diff line number Diff line change
@@ -52,7 +52,14 @@ angular.module("Mac").service("modal", [
# Current opened modal
opened: null

modalTemplate: '<div ng-click="closeOverlay($event)" class="modal-overlay hide"><div class="modal"><a ng-click="modal.hide()" class="close-modal"></a><div class="modal-content-wrapper"></div></div></div>'
modalTemplate: """
<div ng-click="close($event)" class="modal-overlay hide">
<div class="modal">
<a ng-click="close($event, true)" class="close-modal"></a>
<div class="modal-content-wrapper"></div>
</div>
</div>
"""

#
# @name show
@@ -91,10 +98,9 @@ angular.module("Mac").service("modal", [
renderModal = (template) =>
viewScope =
if options.scope then options.scope.$new() else $rootScope.$new(true)
viewScope.modal = this
viewScope.closeOverlay = ($event) =>
if options.overlayClose and
angular.element($event.target).hasClass("modal-overlay")
viewScope.close = ($event, force = false) =>
if force or (options.overlayClose and
angular.element($event.target).hasClass("modal-overlay"))
@hide()

if options.controller
@@ -103,7 +109,9 @@ angular.module("Mac").service("modal", [

angular.extend options.attributes, {id}
element = angular.element(@modalTemplate).attr options.attributes
wrapper = angular.element element[0].getElementsByClassName("modal-content-wrapper")
wrapper = angular.element(
element[0].getElementsByClassName("modal-content-wrapper")
)
wrapper.html template

$animate.enter element, angular.element(document.body)
6 changes: 3 additions & 3 deletions src/template/modal.jade
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.modal-overlay.hide(ng-click="closeOverlay($event)")
.modal-overlay.hide(ng-click="close($event)")
.modal
a.close-modal(ng-click="modal.hide()")
.modal-content-wrapper(ng-transclude)
a.close-modal(ng-click="close($event, true)")
.modal-content-wrapper
7 changes: 0 additions & 7 deletions test/unit/modal.spec.coffee
Original file line number Diff line number Diff line change
@@ -208,13 +208,6 @@ describe "Mac modal", ->
contentText = angular.element(".modal-content-wrapper").text()
expect(contentText).toBe "Test Modal Content"

it "should have modal service on scope", ->
modal.show "testing"
$timeout.flush()

scope = angular.element(".modal-overlay").scope()
expect(scope.modal).toBeDefined()

it "should remove modal on hide", ->
modal.show "testing"
$timeout.flush()

0 comments on commit 658ea76

Please sign in to comment.